aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am50
-rw-r--r--a11y/Makefile.am15
-rw-r--r--a11y/addressbook/Makefile.am35
-rw-r--r--a11y/calendar/Makefile.am56
-rw-r--r--a11y/e-table/Makefile.am44
-rw-r--r--a11y/e-text/Makefile.am15
-rw-r--r--a11y/widgets/Makefile.am36
-rw-r--r--a11y/widgets/ea-combo-button.c186
-rw-r--r--a11y/widgets/ea-combo-button.h51
-rw-r--r--addressbook/conduit/address-conduit.c8
-rw-r--r--addressbook/gui/Makefile.am2
-rw-r--r--addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in136
-rw-r--r--addressbook/gui/component/addressbook-component.c527
-rw-r--r--addressbook/gui/component/addressbook-component.h62
-rw-r--r--addressbook/gui/component/addressbook-view.c1533
-rw-r--r--addressbook/gui/component/addressbook-view.h63
-rw-r--r--addressbook/gui/component/autocompletion-config.c225
-rw-r--r--addressbook/gui/component/component-factory.c75
-rw-r--r--addressbook/gui/contact-editor/Makefile.am11
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.c99
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.h15
-rw-r--r--addressbook/gui/contact-editor/e-contact-quick-add.c31
-rw-r--r--addressbook/gui/contact-editor/eab-editor.c398
-rw-r--r--addressbook/gui/contact-editor/eab-editor.h101
-rw-r--r--addressbook/gui/contact-list-editor/Makefile.am1
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.c280
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.h3
-rw-r--r--addressbook/gui/merging/eab-contact-compare.c4
-rw-r--r--addressbook/gui/merging/eab-contact-merging.c14
-rw-r--r--addressbook/gui/widgets/Makefile.am34
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.c1049
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.h148
-rw-r--r--addressbook/gui/widgets/e-addressbook-reflow-adapter.c69
-rw-r--r--addressbook/gui/widgets/e-addressbook-reflow-adapter.h11
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.c443
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.h73
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.c36
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.h4
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c2490
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.h206
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.c38
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.h2
-rw-r--r--addressbook/gui/widgets/e-minicard-view.c60
-rw-r--r--addressbook/gui/widgets/e-minicard-view.h4
-rw-r--r--addressbook/gui/widgets/e-minicard.c78
-rw-r--r--addressbook/gui/widgets/e-minicard.h6
-rw-r--r--addressbook/gui/widgets/ea-addressbook-view.c (renamed from a11y/addressbook/ea-addressbook-view.c)17
-rw-r--r--addressbook/gui/widgets/ea-addressbook-view.h (renamed from a11y/addressbook/ea-addressbook-view.h)0
-rw-r--r--addressbook/gui/widgets/ea-addressbook.c (renamed from a11y/addressbook/ea-addressbook.c)4
-rw-r--r--addressbook/gui/widgets/ea-addressbook.h (renamed from a11y/addressbook/ea-addressbook.h)0
-rw-r--r--addressbook/gui/widgets/ea-minicard-view.c (renamed from a11y/addressbook/ea-minicard-view.c)13
-rw-r--r--addressbook/gui/widgets/ea-minicard-view.h (renamed from a11y/addressbook/ea-minicard-view.h)0
-rw-r--r--addressbook/gui/widgets/ea-minicard.c (renamed from a11y/addressbook/ea-minicard.c)0
-rw-r--r--addressbook/gui/widgets/ea-minicard.h (renamed from a11y/addressbook/ea-minicard.h)0
-rw-r--r--addressbook/gui/widgets/eab-config.c46
-rw-r--r--addressbook/gui/widgets/eab-config.h15
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c733
-rw-r--r--addressbook/gui/widgets/eab-contact-display.h56
-rw-r--r--addressbook/gui/widgets/eab-gui-util.c379
-rw-r--r--addressbook/gui/widgets/eab-gui-util.h30
-rw-r--r--addressbook/gui/widgets/eab-menu.c258
-rw-r--r--addressbook/gui/widgets/eab-menu.h104
-rw-r--r--addressbook/gui/widgets/eab-popup-control.c462
-rw-r--r--addressbook/gui/widgets/eab-popup-control.h84
-rw-r--r--addressbook/gui/widgets/eab-popup.c364
-rw-r--r--addressbook/gui/widgets/eab-popup.h195
-rw-r--r--addressbook/gui/widgets/gal-view-minicard.c290
-rw-r--r--addressbook/gui/widgets/gal-view-minicard.h65
-rw-r--r--addressbook/util/Makefile.am2
-rw-r--r--addressbook/util/addressbook.c (renamed from addressbook/gui/component/addressbook.c)0
-rw-r--r--addressbook/util/addressbook.h (renamed from addressbook/gui/component/addressbook.h)3
-rw-r--r--addressbook/util/eab-book-util.h2
-rw-r--r--calendar/conduits/calendar/calendar-conduit.c7
-rw-r--r--calendar/conduits/memo/memo-conduit.c7
-rw-r--r--calendar/conduits/todo/todo-conduit.c7
-rw-r--r--calendar/gui/Makefile.am226
-rw-r--r--calendar/gui/alarm-notify/Makefile.am6
-rw-r--r--calendar/gui/alarm-notify/alarm-queue.c19
-rw-r--r--calendar/gui/alarm-notify/notify-main.c6
-rw-r--r--calendar/gui/apps_evolution_calendar.schemas.in107
-rw-r--r--calendar/gui/cal-editor-utils.c21
-rw-r--r--calendar/gui/cal-editor-utils.h13
-rw-r--r--calendar/gui/cal-search-bar.c920
-rw-r--r--calendar/gui/cal-search-bar.h91
-rw-r--r--calendar/gui/calendar-commands.c334
-rw-r--r--calendar/gui/calendar-component.c970
-rw-r--r--calendar/gui/calendar-component.h8
-rw-r--r--calendar/gui/calendar-config-keys.h8
-rw-r--r--calendar/gui/calendar-config.c810
-rw-r--r--calendar/gui/calendar-config.h106
-rw-r--r--calendar/gui/calendar-view-factory.c6
-rw-r--r--calendar/gui/calendar-view-factory.h4
-rw-r--r--calendar/gui/comp-editor-factory.c642
-rw-r--r--calendar/gui/comp-editor-factory.h62
-rw-r--r--calendar/gui/control-factory.c79
-rw-r--r--calendar/gui/dialogs/cal-prefs-dialog.c405
-rw-r--r--calendar/gui/dialogs/cal-prefs-dialog.h37
-rw-r--r--calendar/gui/dialogs/comp-editor-util.c30
-rw-r--r--calendar/gui/dialogs/comp-editor-util.h7
-rw-r--r--calendar/gui/dialogs/comp-editor.c207
-rw-r--r--calendar/gui/dialogs/comp-editor.h6
-rw-r--r--calendar/gui/dialogs/event-editor.c56
-rw-r--r--calendar/gui/dialogs/event-editor.h1
-rw-r--r--calendar/gui/dialogs/event-page.c220
-rw-r--r--calendar/gui/dialogs/memo-editor.c14
-rw-r--r--calendar/gui/dialogs/memo-editor.h1
-rw-r--r--calendar/gui/dialogs/memo-page.c17
-rw-r--r--calendar/gui/dialogs/memo-page.glade1
-rw-r--r--calendar/gui/dialogs/recurrence-page.c51
-rw-r--r--calendar/gui/dialogs/schedule-page.c19
-rw-r--r--calendar/gui/dialogs/task-details-page.c14
-rw-r--r--calendar/gui/dialogs/task-details-page.glade190
-rw-r--r--calendar/gui/dialogs/task-editor.c60
-rw-r--r--calendar/gui/dialogs/task-editor.h1
-rw-r--r--calendar/gui/dialogs/task-page.c200
-rw-r--r--calendar/gui/e-attachment-handler-calendar.h65
-rw-r--r--calendar/gui/e-cal-component-memo-preview.c365
-rw-r--r--calendar/gui/e-cal-component-memo-preview.h66
-rw-r--r--calendar/gui/e-cal-component-preview.c319
-rw-r--r--calendar/gui/e-cal-component-preview.h64
-rw-r--r--calendar/gui/e-cal-config.c47
-rw-r--r--calendar/gui/e-cal-config.h15
-rw-r--r--calendar/gui/e-cal-event.c75
-rw-r--r--calendar/gui/e-cal-event.h33
-rw-r--r--calendar/gui/e-cal-list-view-config.c201
-rw-r--r--calendar/gui/e-cal-list-view-config.h56
-rw-r--r--calendar/gui/e-cal-list-view.c69
-rw-r--r--calendar/gui/e-cal-list-view.h37
-rw-r--r--calendar/gui/e-cal-menu.c293
-rw-r--r--calendar/gui/e-cal-menu.h121
-rw-r--r--calendar/gui/e-cal-model-calendar.c10
-rw-r--r--calendar/gui/e-cal-model-calendar.h43
-rw-r--r--calendar/gui/e-cal-model-memos.c10
-rw-r--r--calendar/gui/e-cal-model-memos.h43
-rw-r--r--calendar/gui/e-cal-model-tasks.c254
-rw-r--r--calendar/gui/e-cal-model-tasks.h65
-rw-r--r--calendar/gui/e-cal-model.c555
-rw-r--r--calendar/gui/e-cal-model.h249
-rw-r--r--calendar/gui/e-cal-popup.c501
-rw-r--r--calendar/gui/e-cal-popup.h214
-rw-r--r--calendar/gui/e-calendar-selector.c226
-rw-r--r--calendar/gui/e-calendar-selector.h66
-rw-r--r--calendar/gui/e-calendar-table-config.c244
-rw-r--r--calendar/gui/e-calendar-table-config.h56
-rw-r--r--calendar/gui/e-calendar-table.c1332
-rw-r--r--calendar/gui/e-calendar-table.h121
-rw-r--r--calendar/gui/e-calendar-view.c1244
-rw-r--r--calendar/gui/e-calendar-view.h70
-rw-r--r--calendar/gui/e-cell-date-edit-config.c321
-rw-r--r--calendar/gui/e-cell-date-edit-config.h57
-rw-r--r--calendar/gui/e-cell-date-edit-text.c220
-rw-r--r--calendar/gui/e-cell-date-edit-text.h66
-rw-r--r--calendar/gui/e-date-edit-config.c257
-rw-r--r--calendar/gui/e-date-edit-config.h56
-rw-r--r--calendar/gui/e-day-view-config.c462
-rw-r--r--calendar/gui/e-day-view-config.h56
-rw-r--r--calendar/gui/e-day-view-main-item.c8
-rw-r--r--calendar/gui/e-day-view-time-item.c9
-rw-r--r--calendar/gui/e-day-view-top-item.c7
-rw-r--r--calendar/gui/e-day-view.c683
-rw-r--r--calendar/gui/e-day-view.h89
-rw-r--r--calendar/gui/e-itip-control.c17
-rw-r--r--calendar/gui/e-meeting-list-view.c5
-rw-r--r--calendar/gui/e-meeting-store.c252
-rw-r--r--calendar/gui/e-meeting-store.h134
-rw-r--r--calendar/gui/e-meeting-time-sel.c378
-rw-r--r--calendar/gui/e-meeting-time-sel.h72
-rw-r--r--calendar/gui/e-memo-list-selector.c287
-rw-r--r--calendar/gui/e-memo-list-selector.h71
-rw-r--r--calendar/gui/e-memo-table-config.c245
-rw-r--r--calendar/gui/e-memo-table-config.h56
-rw-r--r--calendar/gui/e-memo-table.c1294
-rw-r--r--calendar/gui/e-memo-table.h109
-rw-r--r--calendar/gui/e-memos.c1229
-rw-r--r--calendar/gui/e-memos.h85
-rw-r--r--calendar/gui/e-mini-calendar-config.c235
-rw-r--r--calendar/gui/e-mini-calendar-config.h55
-rw-r--r--calendar/gui/e-month-view.c213
-rw-r--r--calendar/gui/e-month-view.h66
-rw-r--r--calendar/gui/e-task-list-selector.c288
-rw-r--r--calendar/gui/e-task-list-selector.h71
-rw-r--r--calendar/gui/e-tasks.c1569
-rw-r--r--calendar/gui/e-tasks.h91
-rw-r--r--calendar/gui/e-timezone-entry.c450
-rw-r--r--calendar/gui/e-timezone-entry.h63
-rw-r--r--calendar/gui/e-week-view-config.c286
-rw-r--r--calendar/gui/e-week-view-config.h55
-rw-r--r--calendar/gui/e-week-view-event-item.c5
-rw-r--r--calendar/gui/e-week-view.c927
-rw-r--r--calendar/gui/e-week-view.h198
-rw-r--r--calendar/gui/ea-cal-view-event.c (renamed from a11y/calendar/ea-cal-view-event.c)0
-rw-r--r--calendar/gui/ea-cal-view-event.h (renamed from a11y/calendar/ea-cal-view-event.h)0
-rw-r--r--calendar/gui/ea-cal-view.c (renamed from a11y/calendar/ea-cal-view.c)3
-rw-r--r--calendar/gui/ea-cal-view.h (renamed from a11y/calendar/ea-cal-view.h)0
-rw-r--r--calendar/gui/ea-calendar-helpers.c (renamed from a11y/calendar/ea-calendar-helpers.c)0
-rw-r--r--calendar/gui/ea-calendar-helpers.h (renamed from a11y/calendar/ea-calendar-helpers.h)0
-rw-r--r--calendar/gui/ea-calendar.c (renamed from a11y/calendar/ea-calendar.c)22
-rw-r--r--calendar/gui/ea-calendar.h (renamed from a11y/calendar/ea-calendar.h)0
-rw-r--r--calendar/gui/ea-day-view-cell.c (renamed from a11y/calendar/ea-day-view-cell.c)2
-rw-r--r--calendar/gui/ea-day-view-cell.h (renamed from a11y/calendar/ea-day-view-cell.h)0
-rw-r--r--calendar/gui/ea-day-view-main-item.c (renamed from a11y/calendar/ea-day-view-main-item.c)0
-rw-r--r--calendar/gui/ea-day-view-main-item.h (renamed from a11y/calendar/ea-day-view-main-item.h)0
-rw-r--r--calendar/gui/ea-day-view.c (renamed from a11y/calendar/ea-day-view.c)1
-rw-r--r--calendar/gui/ea-day-view.h (renamed from a11y/calendar/ea-day-view.h)0
-rw-r--r--calendar/gui/ea-gnome-calendar.c (renamed from a11y/calendar/ea-gnome-calendar.c)71
-rw-r--r--calendar/gui/ea-gnome-calendar.h (renamed from a11y/calendar/ea-gnome-calendar.h)0
-rw-r--r--calendar/gui/ea-jump-button.c (renamed from a11y/calendar/ea-jump-button.c)0
-rw-r--r--calendar/gui/ea-jump-button.h (renamed from a11y/calendar/ea-jump-button.h)0
-rw-r--r--calendar/gui/ea-week-view-cell.c (renamed from a11y/calendar/ea-week-view-cell.c)2
-rw-r--r--calendar/gui/ea-week-view-cell.h (renamed from a11y/calendar/ea-week-view-cell.h)0
-rw-r--r--calendar/gui/ea-week-view-main-item.c (renamed from a11y/calendar/ea-week-view-main-item.c)0
-rw-r--r--calendar/gui/ea-week-view-main-item.h (renamed from a11y/calendar/ea-week-view-main-item.h)0
-rw-r--r--calendar/gui/ea-week-view.c (renamed from a11y/calendar/ea-week-view.c)1
-rw-r--r--calendar/gui/ea-week-view.h (renamed from a11y/calendar/ea-week-view.h)0
-rw-r--r--calendar/gui/gnome-cal.c3061
-rw-r--r--calendar/gui/gnome-cal.h195
-rw-r--r--calendar/gui/goto.c19
-rw-r--r--calendar/gui/itip-bonobo-control.c264
-rw-r--r--calendar/gui/itip-bonobo-control.h34
-rw-r--r--calendar/gui/itip-utils.c3
-rw-r--r--calendar/gui/main.c193
-rw-r--r--calendar/gui/memos-component.c1222
-rw-r--r--calendar/gui/memos-component.h61
-rw-r--r--calendar/gui/memos-control.c404
-rw-r--r--calendar/gui/memos-control.h36
-rw-r--r--calendar/gui/migration.h35
-rw-r--r--calendar/gui/print.c40
-rw-r--r--calendar/gui/print.h4
-rw-r--r--calendar/gui/tasks-component.c1293
-rw-r--r--calendar/gui/tasks-component.h60
-rw-r--r--calendar/gui/tasks-control.c593
-rw-r--r--calendar/gui/tasks-control.h35
-rw-r--r--calendar/importers/main.c58
-rw-r--r--composer/Makefile.am7
-rw-r--r--composer/e-composer-actions.c35
-rw-r--r--composer/e-composer-from-header.c6
-rw-r--r--composer/e-composer-from-header.h4
-rw-r--r--composer/e-composer-header-table.c50
-rw-r--r--composer/e-composer-header-table.h5
-rw-r--r--composer/e-composer-header.c25
-rw-r--r--composer/e-composer-header.h6
-rw-r--r--composer/e-composer-name-header.c35
-rw-r--r--composer/e-composer-post-header.c91
-rw-r--r--composer/e-composer-post-header.h5
-rw-r--r--composer/e-composer-private.c15
-rw-r--r--composer/e-composer-private.h6
-rw-r--r--composer/e-msg-composer.c568
-rw-r--r--composer/e-msg-composer.h16
-rw-r--r--configure.ac431
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/devel/Makefile.am3
-rw-r--r--doc/devel/importer/Makefile.am197
-rw-r--r--doc/devel/importer/evolution-shell-importer-sections.txt79
-rw-r--r--doc/devel/importer/evolution-shell-importer.hierarchy7
-rw-r--r--doc/devel/importer/evolution-shell-importer.types9
-rw-r--r--doc/devel/importer/private-reference.sgml21
-rw-r--r--doc/devel/importer/public-reference.sgml20
-rw-r--r--doc/devel/importer/tmpl/evolution-importer.sgml96
-rw-r--r--doc/devel/importer/tmpl/evolution-shell-importer-unused.sgml10
-rw-r--r--doc/reference/Makefile.am3
-rw-r--r--doc/reference/shell/Makefile.am158
-rw-r--r--doc/reference/shell/eshell-docs.sgml43
-rw-r--r--doc/reference/shell/eshell-overrides.txt (renamed from doc/devel/importer/evolution-shell-importer.args)0
-rw-r--r--doc/reference/shell/eshell-sections.txt346
-rw-r--r--doc/reference/shell/eshell.types8
-rw-r--r--doc/reference/shell/tmpl/Evolution-DataServer.sgml1139
-rw-r--r--doc/reference/shell/tmpl/action-groups.sgml99
-rw-r--r--doc/reference/shell/tmpl/e-activity-handler.sgml19
-rw-r--r--doc/reference/shell/tmpl/e-config-upgrade.sgml32
-rw-r--r--doc/reference/shell/tmpl/e-shell-backend.sgml114
-rw-r--r--doc/reference/shell/tmpl/e-shell-common.sgml21
-rw-r--r--doc/reference/shell/tmpl/e-shell-constants.sgml140
-rw-r--r--doc/reference/shell/tmpl/e-shell-content.sgml370
-rw-r--r--doc/reference/shell/tmpl/e-shell-importer.sgml27
-rw-r--r--doc/reference/shell/tmpl/e-shell-marshal.sgml41
-rw-r--r--doc/reference/shell/tmpl/e-shell-module.sgml180
-rw-r--r--doc/reference/shell/tmpl/e-shell-settings.sgml150
-rw-r--r--doc/reference/shell/tmpl/e-shell-sidebar.sgml126
-rw-r--r--doc/reference/shell/tmpl/e-shell-switcher.sgml104
-rw-r--r--doc/reference/shell/tmpl/e-shell-taskbar.sgml79
-rw-r--r--doc/reference/shell/tmpl/e-shell-view.sgml284
-rw-r--r--doc/reference/shell/tmpl/e-shell-window-actions.sgml309
-rw-r--r--doc/reference/shell/tmpl/e-shell-window-private.sgml25
-rw-r--r--doc/reference/shell/tmpl/e-shell-window.sgml190
-rw-r--r--doc/reference/shell/tmpl/e-shell.sgml310
-rw-r--r--doc/reference/shell/tmpl/e-test-shell-view.sgml41
-rw-r--r--doc/reference/shell/tmpl/es-event.sgml147
-rw-r--r--doc/reference/shell/tmpl/eshell-unused.sgml2384
-rw-r--r--doc/reference/shell/tmpl/evolution-importer-client.sgml (renamed from doc/devel/importer/tmpl/evolution-importer-client.sgml)30
-rw-r--r--doc/reference/shell/tmpl/evolution-importer-listener.sgml56
-rw-r--r--doc/reference/shell/tmpl/evolution-importer.sgml117
-rw-r--r--doc/reference/shell/tmpl/evolution-intelligent-importer.sgml67
-rw-r--r--doc/reference/shell/tmpl/intelligent.sgml26
-rw-r--r--doc/reference/shell/tmpl/shell-actions.sgml291
-rw-r--r--e-util/Makefile.am26
-rw-r--r--e-util/e-account-utils.c96
-rw-r--r--e-util/e-account-utils.h35
-rw-r--r--e-util/e-charset.c255
-rw-r--r--e-util/e-charset.h (renamed from mail/em-migrate.h)18
-rw-r--r--e-util/e-config.c458
-rw-r--r--e-util/e-config.h25
-rw-r--r--e-util/e-corba-utils.h31
-rw-r--r--e-util/e-dialog-utils.c26
-rw-r--r--e-util/e-dialog-utils.h2
-rw-r--r--e-util/e-dialog-widgets.c14
-rw-r--r--e-util/e-error.c19
-rw-r--r--e-util/e-import.c4
-rw-r--r--e-util/e-import.h2
-rw-r--r--e-util/e-logger.c76
-rw-r--r--e-util/e-logger.h26
-rw-r--r--e-util/e-marshal.list2
-rw-r--r--e-util/e-menu.c925
-rw-r--r--e-util/e-menu.h319
-rw-r--r--e-util/e-module.c318
-rw-r--r--e-util/e-module.h81
-rw-r--r--e-util/e-non-intrusive-error-dialog.c1
-rw-r--r--e-util/e-non-intrusive-error-dialog.h2
-rw-r--r--e-util/e-plugin-ui.c438
-rw-r--r--e-util/e-plugin-ui.h9
-rw-r--r--e-util/e-plugin.c696
-rw-r--r--e-util/e-plugin.h118
-rw-r--r--e-util/e-popup.c953
-rw-r--r--e-util/e-popup.h305
-rw-r--r--e-util/e-request.c2
-rw-r--r--e-util/e-signature-utils.c351
-rw-r--r--e-util/e-signature-utils.h (renamed from mail/mail-config-factory.h)33
-rw-r--r--e-util/e-unicode.c (renamed from widgets/misc/e-unicode.c)0
-rw-r--r--e-util/e-unicode.h (renamed from widgets/misc/e-unicode.h)0
-rw-r--r--e-util/e-util-labels.c591
-rw-r--r--e-util/e-util-labels.h52
-rw-r--r--e-util/e-util.c59
-rw-r--r--e-util/e-util.h10
-rw-r--r--e-util/gconf-bridge.c6
-rw-r--r--em-format/Makefile.am28
-rw-r--r--em-format/em-format-quote.c (renamed from mail/em-format-quote.c)82
-rw-r--r--em-format/em-format-quote.h (renamed from mail/em-format-quote.h)2
-rw-r--r--em-format/em-format.c (renamed from mail/em-format.c)379
-rw-r--r--em-format/em-format.h (renamed from mail/em-format.h)136
-rw-r--r--em-format/em-stripsig-filter.c (renamed from mail/em-stripsig-filter.c)0
-rw-r--r--em-format/em-stripsig-filter.h (renamed from mail/em-stripsig-filter.h)0
-rw-r--r--evolution-plugin.pc.in2
-rw-r--r--evolution-shell.pc.in3
-rw-r--r--filter/Makefile.am1
-rw-r--r--filter/filter-datespec.c42
-rw-r--r--filter/filter-rule.c8
-rw-r--r--filter/rule-context.c4
-rw-r--r--filter/rule-editor.c17
-rw-r--r--m4/Makefile.am1
-rw-r--r--mail/Makefile.am376
-rw-r--r--mail/e-attachment-handler-mail.h65
-rw-r--r--mail/e-mail-attachment-bar.c3
-rw-r--r--mail/e-mail-browser.c745
-rw-r--r--mail/e-mail-browser.h72
-rw-r--r--mail/e-mail-display.c1072
-rw-r--r--mail/e-mail-display.h99
-rw-r--r--mail/e-mail-label-dialog.c323
-rw-r--r--mail/e-mail-label-dialog.h77
-rw-r--r--mail/e-mail-label-list-store.c513
-rw-r--r--mail/e-mail-label-list-store.h85
-rw-r--r--mail/e-mail-label-manager.c479
-rw-r--r--mail/e-mail-label-manager.h81
-rw-r--r--mail/e-mail-label-tree-view.c136
-rw-r--r--mail/e-mail-label-tree-view.h66
-rw-r--r--mail/e-mail-local.c130
-rw-r--r--mail/e-mail-local.h51
-rw-r--r--mail/e-mail-reader-utils.c587
-rw-r--r--mail/e-mail-reader-utils.h56
-rw-r--r--mail/e-mail-reader.c2752
-rw-r--r--mail/e-mail-reader.h129
-rw-r--r--mail/e-mail-store.c423
-rw-r--r--mail/e-mail-store.h (renamed from widgets/table/e-table-tree.h)36
-rw-r--r--mail/e-searching-tokenizer.c629
-rw-r--r--mail/e-searching-tokenizer.h81
-rw-r--r--mail/em-account-editor.c804
-rw-r--r--mail/em-account-editor.h89
-rw-r--r--mail/em-account-prefs.c571
-rw-r--r--mail/em-account-prefs.h84
-rw-r--r--mail/em-composer-prefs.c2
-rw-r--r--mail/em-composer-utils.c367
-rw-r--r--mail/em-composer-utils.h12
-rw-r--r--mail/em-config.c82
-rw-r--r--mail/em-config.h17
-rw-r--r--mail/em-event.c96
-rw-r--r--mail/em-event.h31
-rw-r--r--mail/em-filter-editor.c126
-rw-r--r--mail/em-filter-editor.h44
-rw-r--r--mail/em-filter-folder-element.c8
-rw-r--r--mail/em-folder-browser.c1580
-rw-r--r--mail/em-folder-properties.c65
-rw-r--r--mail/em-folder-properties.h6
-rw-r--r--mail/em-folder-selection-button.c528
-rw-r--r--mail/em-folder-selection-button.h82
-rw-r--r--mail/em-folder-selection.c65
-rw-r--r--mail/em-folder-selection.h13
-rw-r--r--mail/em-folder-selector.c137
-rw-r--r--mail/em-folder-selector.h27
-rw-r--r--mail/em-folder-tree-model.c1371
-rw-r--r--mail/em-folder-tree-model.h151
-rw-r--r--mail/em-folder-tree.c2039
-rw-r--r--mail/em-folder-tree.h65
-rw-r--r--mail/em-folder-utils.c113
-rw-r--r--mail/em-folder-utils.h10
-rw-r--r--mail/em-folder-view.c2612
-rw-r--r--mail/em-folder-view.h3
-rw-r--r--mail/em-format-hook.h2
-rw-r--r--mail/em-format-html-display.c1133
-rw-r--r--mail/em-format-html-display.h54
-rw-r--r--mail/em-format-html-print.c31
-rw-r--r--mail/em-format-html.c1461
-rw-r--r--mail/em-format-html.h64
-rw-r--r--mail/em-html-stream.c147
-rw-r--r--mail/em-html-stream.h42
-rw-r--r--mail/em-inline-filter.c3
-rw-r--r--mail/em-junk-hook.c440
-rw-r--r--mail/em-junk-hook.h102
-rw-r--r--mail/em-junk.c (renamed from widgets/table/table-test.h)14
-rw-r--r--mail/em-junk.h66
-rw-r--r--mail/em-menu.c354
-rw-r--r--mail/em-menu.h121
-rw-r--r--mail/em-message-browser.c421
-rw-r--r--mail/em-message-browser.h74
-rw-r--r--mail/em-popup.c888
-rw-r--r--mail/em-popup.h261
-rw-r--r--mail/em-search-context.c84
-rw-r--r--mail/em-search-context.h41
-rw-r--r--mail/em-subscribe-editor.c10
-rw-r--r--mail/em-subscribe-editor.h2
-rw-r--r--mail/em-utils.c534
-rw-r--r--mail/em-utils.h42
-rw-r--r--mail/em-vfolder-editor.c92
-rw-r--r--mail/em-vfolder-editor.h39
-rw-r--r--mail/em-vfolder-rule.c6
-rw-r--r--mail/evolution-mail.schemas.in237
-rw-r--r--mail/filtertypes.xml4
-rw-r--r--mail/importers/Makefile.am3
-rw-r--r--mail/importers/evolution-mbox-importer.c14
-rw-r--r--mail/importers/mail-importer.c35
-rw-r--r--mail/importers/mail-importer.h20
-rw-r--r--mail/mail-autofilter.c14
-rw-r--r--mail/mail-component-factory.c125
-rw-r--r--mail/mail-component.c1409
-rw-r--r--mail/mail-component.h2
-rw-r--r--mail/mail-config-factory.c63
-rw-r--r--mail/mail-config.c515
-rw-r--r--mail/mail-config.glade15495
-rw-r--r--mail/mail-config.h45
-rw-r--r--mail/mail-crypto.c53
-rw-r--r--mail/mail-folder-cache.c92
-rw-r--r--mail/mail-mt.c112
-rw-r--r--mail/mail-ops.c46
-rw-r--r--mail/mail-ops.h3
-rw-r--r--mail/mail-send-recv.c96
-rw-r--r--mail/mail-send-recv.h7
-rw-r--r--mail/mail-session.c43
-rw-r--r--mail/mail-session.h8
-rw-r--r--mail/mail-tools.c6
-rw-r--r--mail/mail-vfolder.c136
-rw-r--r--mail/mail-vfolder.h3
-rw-r--r--mail/message-list.c325
-rw-r--r--mail/message-list.h14
-rw-r--r--mail/message-tag-followup.c5
-rw-r--r--mail/searchtypes.xml36
-rw-r--r--mail/vfoldertypes.xml2
-rw-r--r--modules/Makefile.am11
-rw-r--r--modules/addressbook/Makefile.am (renamed from addressbook/gui/component/Makefile.am)69
-rw-r--r--modules/addressbook/addressbook-config.c (renamed from addressbook/gui/component/addressbook-config.c)7
-rw-r--r--modules/addressbook/addressbook-config.h (renamed from addressbook/gui/component/addressbook-config.h)3
-rw-r--r--modules/addressbook/apps_evolution_addressbook.schemas.in (renamed from addressbook/gui/component/apps_evolution_addressbook.schemas.in)38
-rw-r--r--modules/addressbook/autocompletion-config.c202
-rw-r--r--modules/addressbook/autocompletion-config.h (renamed from addressbook/gui/component/autocompletion-config.h)9
-rw-r--r--modules/addressbook/e-book-config-hook.c67
-rw-r--r--modules/addressbook/e-book-config-hook.h (renamed from mail/mail-crypto.h)16
-rw-r--r--modules/addressbook/e-book-shell-backend.c591
-rw-r--r--modules/addressbook/e-book-shell-backend.h70
-rw-r--r--modules/addressbook/e-book-shell-content.c541
-rw-r--r--modules/addressbook/e-book-shell-content.h110
-rw-r--r--modules/addressbook/e-book-shell-migrate.c (renamed from addressbook/gui/component/addressbook-migrate.c)63
-rw-r--r--modules/addressbook/e-book-shell-migrate.h (renamed from addressbook/gui/component/addressbook-migrate.h)20
-rw-r--r--modules/addressbook/e-book-shell-settings.c34
-rw-r--r--modules/addressbook/e-book-shell-settings.h33
-rw-r--r--modules/addressbook/e-book-shell-sidebar.c232
-rw-r--r--modules/addressbook/e-book-shell-sidebar.h79
-rw-r--r--modules/addressbook/e-book-shell-view-actions.c1093
-rw-r--r--modules/addressbook/e-book-shell-view-actions.h95
-rw-r--r--modules/addressbook/e-book-shell-view-private.c634
-rw-r--r--modules/addressbook/e-book-shell-view-private.h131
-rw-r--r--modules/addressbook/e-book-shell-view.c318
-rw-r--r--modules/addressbook/e-book-shell-view.h66
-rw-r--r--modules/addressbook/eab-composer-util.c197
-rw-r--r--modules/addressbook/eab-composer-util.h31
-rw-r--r--modules/addressbook/evolution-module-addressbook.c (renamed from shell/evolution-component.c)41
-rw-r--r--modules/addressbook/ldap-config.glade (renamed from addressbook/gui/component/ldap-config.glade)0
-rw-r--r--modules/addressbook/openldap-extract.h (renamed from addressbook/gui/component/openldap-extract.h)0
-rw-r--r--modules/calendar/Makefile.am84
-rw-r--r--modules/calendar/e-cal-attachment-handler.c (renamed from calendar/gui/e-attachment-handler-calendar.c)71
-rw-r--r--modules/calendar/e-cal-attachment-handler.h67
-rw-r--r--modules/calendar/e-cal-config-hook.c68
-rw-r--r--modules/calendar/e-cal-config-hook.h (renamed from calendar/gui/control-factory.h)18
-rw-r--r--modules/calendar/e-cal-event-hook.c72
-rw-r--r--modules/calendar/e-cal-event-hook.h33
-rw-r--r--modules/calendar/e-cal-shell-backend.c854
-rw-r--r--modules/calendar/e-cal-shell-backend.h70
-rw-r--r--modules/calendar/e-cal-shell-content.c768
-rw-r--r--modules/calendar/e-cal-shell-content.h108
-rw-r--r--modules/calendar/e-cal-shell-migrate.c (renamed from calendar/gui/migration.c)815
-rw-r--r--modules/calendar/e-cal-shell-migrate.h38
-rw-r--r--modules/calendar/e-cal-shell-settings.c742
-rw-r--r--modules/calendar/e-cal-shell-settings.h33
-rw-r--r--modules/calendar/e-cal-shell-sidebar.c757
-rw-r--r--modules/calendar/e-cal-shell-sidebar.h101
-rw-r--r--modules/calendar/e-cal-shell-view-actions.c1792
-rw-r--r--modules/calendar/e-cal-shell-view-actions.h153
-rw-r--r--modules/calendar/e-cal-shell-view-memopad.c526
-rw-r--r--modules/calendar/e-cal-shell-view-private.c1098
-rw-r--r--modules/calendar/e-cal-shell-view-private.h180
-rw-r--r--modules/calendar/e-cal-shell-view-taskpad.c654
-rw-r--r--modules/calendar/e-cal-shell-view.c219
-rw-r--r--modules/calendar/e-cal-shell-view.h66
-rw-r--r--modules/calendar/e-memo-shell-backend.c653
-rw-r--r--modules/calendar/e-memo-shell-backend.h70
-rw-r--r--modules/calendar/e-memo-shell-content.c721
-rw-r--r--modules/calendar/e-memo-shell-content.h96
-rw-r--r--modules/calendar/e-memo-shell-migrate.c268
-rw-r--r--modules/calendar/e-memo-shell-migrate.h38
-rw-r--r--modules/calendar/e-memo-shell-sidebar.c716
-rw-r--r--modules/calendar/e-memo-shell-sidebar.h97
-rw-r--r--modules/calendar/e-memo-shell-view-actions.c1019
-rw-r--r--modules/calendar/e-memo-shell-view-actions.h91
-rw-r--r--modules/calendar/e-memo-shell-view-private.c561
-rw-r--r--modules/calendar/e-memo-shell-view-private.h128
-rw-r--r--modules/calendar/e-memo-shell-view.c222
-rw-r--r--modules/calendar/e-memo-shell-view.h67
-rw-r--r--modules/calendar/e-task-shell-backend.c661
-rw-r--r--modules/calendar/e-task-shell-backend.h70
-rw-r--r--modules/calendar/e-task-shell-content.c744
-rw-r--r--modules/calendar/e-task-shell-content.h100
-rw-r--r--modules/calendar/e-task-shell-migrate.c675
-rw-r--r--modules/calendar/e-task-shell-migrate.h38
-rw-r--r--modules/calendar/e-task-shell-sidebar.c714
-rw-r--r--modules/calendar/e-task-shell-sidebar.h97
-rw-r--r--modules/calendar/e-task-shell-view-actions.c1222
-rw-r--r--modules/calendar/e-task-shell-view-actions.h109
-rw-r--r--modules/calendar/e-task-shell-view-private.c726
-rw-r--r--modules/calendar/e-task-shell-view-private.h141
-rw-r--r--modules/calendar/e-task-shell-view.c325
-rw-r--r--modules/calendar/e-task-shell-view.h72
-rw-r--r--modules/calendar/evolution-module-calendar.c75
-rw-r--r--modules/mail/Makefile.am60
-rw-r--r--modules/mail/e-mail-attachment-handler.c (renamed from mail/e-attachment-handler-mail.c)99
-rw-r--r--modules/mail/e-mail-attachment-handler.h67
-rw-r--r--modules/mail/e-mail-config-hook.c69
-rw-r--r--modules/mail/e-mail-config-hook.h33
-rw-r--r--modules/mail/e-mail-event-hook.c93
-rw-r--r--modules/mail/e-mail-event-hook.h33
-rw-r--r--modules/mail/e-mail-junk-hook.c323
-rw-r--r--modules/mail/e-mail-junk-hook.h66
-rw-r--r--modules/mail/e-mail-shell-backend.c987
-rw-r--r--modules/mail/e-mail-shell-backend.h75
-rw-r--r--modules/mail/e-mail-shell-content.c1029
-rw-r--r--modules/mail/e-mail-shell-content.h89
-rw-r--r--modules/mail/e-mail-shell-migrate.c (renamed from mail/em-migrate.c)662
-rw-r--r--modules/mail/e-mail-shell-migrate.h (renamed from mail/mail-types.h)20
-rw-r--r--modules/mail/e-mail-shell-settings.c229
-rw-r--r--modules/mail/e-mail-shell-settings.h33
-rw-r--r--modules/mail/e-mail-shell-sidebar.c657
-rw-r--r--modules/mail/e-mail-shell-sidebar.h81
-rw-r--r--modules/mail/e-mail-shell-view-actions.c1844
-rw-r--r--modules/mail/e-mail-shell-view-actions.h259
-rw-r--r--modules/mail/e-mail-shell-view-private.c1009
-rw-r--r--modules/mail/e-mail-shell-view-private.h173
-rw-r--r--modules/mail/e-mail-shell-view.c262
-rw-r--r--modules/mail/e-mail-shell-view.h72
-rw-r--r--modules/mail/em-account-prefs.c323
-rw-r--r--modules/mail/em-account-prefs.h69
-rw-r--r--modules/mail/em-composer-prefs.c567
-rw-r--r--modules/mail/em-composer-prefs.h (renamed from mail/em-composer-prefs.h)32
-rw-r--r--modules/mail/em-mailer-prefs.c (renamed from mail/em-mailer-prefs.c)868
-rw-r--r--modules/mail/em-mailer-prefs.h (renamed from mail/em-mailer-prefs.h)86
-rw-r--r--modules/mail/em-network-prefs.c (renamed from mail/em-network-prefs.c)2
-rw-r--r--modules/mail/em-network-prefs.h (renamed from mail/em-network-prefs.h)53
-rw-r--r--modules/mail/evolution-module-mail.c71
-rw-r--r--modules/plugin-lib/Makefile.am20
-rw-r--r--modules/plugin-lib/e-plugin-lib.c249
-rw-r--r--modules/plugin-lib/e-plugin-lib.h92
-rw-r--r--modules/plugin-lib/evolution-module-plugin-lib.c (renamed from e-util/e-corba-utils.c)28
-rw-r--r--modules/plugin-mono/Camel.cs (renamed from plugins/mono/Camel.cs)0
-rw-r--r--modules/plugin-mono/Evolution.cs (renamed from plugins/mono/Evolution.cs)0
-rw-r--r--modules/plugin-mono/Makefile.am22
-rw-r--r--modules/plugin-mono/e-plugin-mono.c261
-rw-r--r--modules/plugin-mono/e-plugin-mono.h69
-rw-r--r--modules/plugin-mono/evolution-module-plugin-mono.c (renamed from widgets/misc/e-config-page.c)31
-rw-r--r--modules/plugin-python/Makefile.am31
-rw-r--r--modules/plugin-python/e-plugin-python.c230
-rw-r--r--modules/plugin-python/e-plugin-python.h70
-rw-r--r--modules/plugin-python/evolution-module-plugin-python.c41
-rw-r--r--modules/plugin-python/example/Makefile.am (renamed from plugins/python/example/Makefile.am)3
-rw-r--r--modules/plugin-python/example/hello_python.py (renamed from plugins/python/example/hello_python.py)0
-rw-r--r--modules/plugin-python/example/org-gnome-hello-python-ui.xml (renamed from plugins/python/example/org-gnome-hello-python-ui.xml)0
-rw-r--r--modules/plugin-python/example/org-gnome-hello-python.eplug.xml (renamed from plugins/python/example/org-gnome-hello-python.eplug.xml)0
-rw-r--r--plugins/Makefile.am2
-rw-r--r--plugins/attachment-reminder/Makefile.am6
-rw-r--r--plugins/attachment-reminder/attachment-reminder.c4
-rw-r--r--plugins/audio-inline/Makefile.am8
-rw-r--r--plugins/audio-inline/org-gnome-audio-inline.eplug.xml105
-rw-r--r--plugins/backup-restore/Makefile.am17
-rw-r--r--plugins/backup-restore/backup-restore.c192
-rw-r--r--plugins/backup-restore/org-gnome-backup-restore.eplug.xml39
-rw-r--r--plugins/backup-restore/org-gnome-backup-restore.xml21
-rw-r--r--plugins/bbdb/Makefile.am6
-rw-r--r--plugins/bbdb/bbdb.c48
-rw-r--r--plugins/bogo-junk-plugin/Makefile.am6
-rw-r--r--plugins/bogo-junk-plugin/bf-junk-filter.c26
-rw-r--r--plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml13
-rw-r--r--plugins/caldav/caldav-source.c4
-rw-r--r--plugins/calendar-weather/Makefile.am24
-rw-r--r--plugins/calendar-weather/calendar-weather.c45
-rw-r--r--plugins/calendar-weather/category_weather_cloudy_16.pngbin597 -> 0 bytes
-rw-r--r--plugins/calendar-weather/category_weather_fog_16.pngbin217 -> 0 bytes
-rw-r--r--plugins/calendar-weather/category_weather_partly_cloudy_16.pngbin760 -> 0 bytes
-rw-r--r--plugins/calendar-weather/category_weather_rain_16.pngbin647 -> 0 bytes
-rw-r--r--plugins/calendar-weather/category_weather_snow_16.pngbin624 -> 0 bytes
-rw-r--r--plugins/calendar-weather/category_weather_sun_16.pngbin420 -> 0 bytes
-rw-r--r--plugins/calendar-weather/category_weather_tstorm_16.pngbin728 -> 0 bytes
-rw-r--r--plugins/copy-tool/ChangeLog67
-rw-r--r--plugins/copy-tool/Makefile.am20
-rw-r--r--plugins/copy-tool/copy-tool.c71
-rw-r--r--plugins/copy-tool/org-gnome-copy-tool.eplug.xml24
-rw-r--r--plugins/default-mailer/Makefile.am2
-rw-r--r--plugins/email-custom-header/Makefile.am3
-rw-r--r--plugins/email-custom-header/email-custom-header.c11
-rw-r--r--plugins/exchange-operations/exchange-account-setup.c4
-rw-r--r--plugins/exchange-operations/exchange-operations.c2
-rw-r--r--plugins/exchange-operations/exchange-user-dialog.c3
-rw-r--r--plugins/exchange-operations/org-gnome-exchange-operations.eplug.xml2
-rw-r--r--plugins/external-editor/Makefile.am11
-rw-r--r--plugins/external-editor/external-editor.c1
-rw-r--r--plugins/face/Makefile.am3
-rw-r--r--plugins/face/face.c1
-rw-r--r--plugins/folder-unsubscribe/ChangeLog58
-rw-r--r--plugins/folder-unsubscribe/Makefile.am18
-rw-r--r--plugins/folder-unsubscribe/folder-unsubscribe.c106
-rw-r--r--plugins/folder-unsubscribe/org-gnome-mail-folder-unsubscribe.eplug.xml20
-rw-r--r--plugins/google-account-setup/Makefile.am4
-rw-r--r--plugins/google-account-setup/google-source.c13
-rw-r--r--plugins/groupwise-account-setup/groupwise-account-setup.c4
-rw-r--r--plugins/groupwise-account-setup/org-gnome-gw-account-setup.eplug.xml2
-rw-r--r--plugins/groupwise-features/Makefile.am1
-rw-r--r--plugins/groupwise-features/install-shared.c46
-rw-r--r--plugins/groupwise-features/proxy-login.c3
-rw-r--r--plugins/groupwise-features/share-folder-common.c1
-rw-r--r--plugins/hula-account-setup/hula-account-setup.c4
-rw-r--r--plugins/hula-account-setup/org-gnome-evolution-hula-account-setup.eplug.xml2
-rw-r--r--plugins/imap-features/Makefile.am7
-rw-r--r--plugins/imap-features/imap-headers.c5
-rw-r--r--plugins/ipod-sync/Makefile.am2
-rw-r--r--plugins/itip-formatter/Makefile.am1
-rw-r--r--plugins/itip-formatter/itip-formatter.c17
-rw-r--r--plugins/mail-account-disable/ChangeLog62
-rw-r--r--plugins/mail-account-disable/Makefile.am24
-rw-r--r--plugins/mail-account-disable/mail-account-disable.c100
-rw-r--r--plugins/mail-account-disable/org-gnome-mail-account-disable.eplug.xml18
-rw-r--r--plugins/mail-notification/Makefile.am12
-rw-r--r--plugins/mail-notification/apps-evolution-mail-notification.schemas.in11
-rw-r--r--plugins/mail-notification/mail-notification.c471
-rw-r--r--plugins/mail-to-task/Makefile.am6
-rw-r--r--plugins/mail-to-task/mail-to-task.c261
-rw-r--r--plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml101
-rw-r--r--plugins/mail-to-task/org-gnome-mail-to-task.xml28
-rw-r--r--plugins/mark-all-read/Makefile.am4
-rw-r--r--plugins/mark-all-read/mark-all-read.c69
-rw-r--r--plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml31
-rw-r--r--plugins/mono/ChangeLog84
-rw-r--r--plugins/mono/Makefile.am22
-rw-r--r--plugins/mono/mono-plugin.c240
-rw-r--r--plugins/mono/mono-plugin.h51
-rw-r--r--plugins/mono/org-gnome-evolution-mono.eplug.xml11
-rw-r--r--plugins/plugin-manager/Makefile.am9
-rw-r--r--plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml23
-rw-r--r--plugins/plugin-manager/org-gnome-plugin-manager.xml15
-rw-r--r--plugins/plugin-manager/plugin-manager.c83
-rw-r--r--plugins/prefer-plain/prefer-plain.c16
-rw-r--r--plugins/profiler/Makefile.am2
-rw-r--r--plugins/profiler/profiler.c2
-rw-r--r--plugins/pst-import/Makefile.am6
-rw-r--r--plugins/pst-import/pst-importer.c28
-rw-r--r--plugins/python/ChangeLog38
-rw-r--r--plugins/python/Makefile.am30
-rw-r--r--plugins/python/org-gnome-evolution-python.eplug.xml10
-rw-r--r--plugins/python/python-plugin-loader.c192
-rw-r--r--plugins/python/python-plugin-loader.h47
-rw-r--r--plugins/sa-junk-plugin/Makefile.am6
-rw-r--r--plugins/sa-junk-plugin/em-junk-filter.c18
-rw-r--r--plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml16
-rw-r--r--plugins/select-one-source/ChangeLog64
-rw-r--r--plugins/select-one-source/Makefile.am21
-rw-r--r--plugins/select-one-source/org-gnome-select-one-source.eplug.xml21
-rw-r--r--plugins/select-one-source/select-one-source.c54
-rw-r--r--plugins/startup-wizard/Makefile.am5
-rw-r--r--plugins/startup-wizard/startup-wizard.c84
-rw-r--r--plugins/templates/org-gnome-templates.eplug.xml36
-rw-r--r--plugins/templates/templates.c392
-rw-r--r--plugins/tnef-attachments/Makefile.am5
-rw-r--r--plugins/tnef-attachments/tnef-plugin.c8
-rw-r--r--plugins/vcard-inline/Makefile.am11
-rw-r--r--plugins/vcard-inline/vcard-inline.c35
-rw-r--r--plugins/webdav-account-setup/webdav-contacts-source.c4
-rw-r--r--po/ChangeLog15
-rw-r--r--po/LINGUAS1
-rw-r--r--po/POTFILES.in215
-rw-r--r--po/et.po46
-rw-r--r--shell/Evolution-Component.idl137
-rw-r--r--shell/Evolution-ConfigControl.idl26
-rw-r--r--shell/Evolution-Shell.idl87
-rw-r--r--shell/Evolution.idl20
-rw-r--r--shell/GNOME_Evolution_Shell.server.in.in26
-rw-r--r--shell/Makefile.am147
-rw-r--r--shell/apps_evolution_shell.schemas.in48
-rw-r--r--shell/e-active-connection-dialog.glade193
-rw-r--r--shell/e-component-registry.c320
-rw-r--r--shell/e-component-registry.h93
-rw-r--r--shell/e-component-view.c151
-rw-r--r--shell/e-component-view.h73
-rw-r--r--shell/e-corba-config-page.c154
-rw-r--r--shell/e-corba-config-page.h63
-rw-r--r--shell/e-shell-backend.c403
-rw-r--r--shell/e-shell-backend.h139
-rw-r--r--shell/e-shell-common.h (renamed from shell/importer/intelligent.h)19
-rw-r--r--shell/e-shell-constants.h50
-rw-r--r--shell/e-shell-content.c1559
-rw-r--r--shell/e-shell-content.h148
-rw-r--r--shell/e-shell-importer.c330
-rw-r--r--shell/e-shell-importer.h15
-rw-r--r--shell/e-shell-migrate.c351
-rw-r--r--shell/e-shell-migrate.h (renamed from widgets/misc/e-info-label.h)48
-rw-r--r--shell/e-shell-nm.c71
-rw-r--r--shell/e-shell-settings-dialog.c355
-rw-r--r--shell/e-shell-settings-dialog.h60
-rw-r--r--shell/e-shell-settings.c702
-rw-r--r--shell/e-shell-settings.h114
-rw-r--r--shell/e-shell-sidebar.c683
-rw-r--r--shell/e-shell-sidebar.h97
-rw-r--r--shell/e-shell-switcher.c700
-rw-r--r--shell/e-shell-switcher.h92
-rw-r--r--shell/e-shell-taskbar.c421
-rw-r--r--shell/e-shell-taskbar.h87
-rw-r--r--shell/e-shell-view.c1173
-rw-r--r--shell/e-shell-view.h180
-rw-r--r--shell/e-shell-window-actions.c2242
-rw-r--r--shell/e-shell-window-actions.h123
-rw-r--r--shell/e-shell-window-commands.c1388
-rw-r--r--shell/e-shell-window-commands.h31
-rw-r--r--shell/e-shell-window-private.c602
-rw-r--r--shell/e-shell-window-private.h128
-rw-r--r--shell/e-shell-window.c1723
-rw-r--r--shell/e-shell-window.h136
-rw-r--r--shell/e-shell.c2276
-rw-r--r--shell/e-shell.h182
-rw-r--r--shell/e-sidebar.c785
-rw-r--r--shell/e-sidebar.h85
-rw-r--r--shell/e-user-creatable-items-handler.c907
-rw-r--r--shell/e-user-creatable-items-handler.h63
-rw-r--r--shell/es-event.c21
-rw-r--r--shell/es-event.h6
-rw-r--r--shell/es-menu.c185
-rw-r--r--shell/es-menu.h92
-rw-r--r--shell/evolution-component.h47
-rw-r--r--shell/evolution-config-control.c175
-rw-r--r--shell/evolution-config-control.h64
-rw-r--r--shell/evolution-listener.c71
-rw-r--r--shell/evolution-listener.h54
-rw-r--r--shell/evolution-shell-component-utils.c111
-rw-r--r--shell/evolution-shell-component-utils.h47
-rw-r--r--shell/import.glade124
-rw-r--r--shell/importer/GNOME_Evolution_Importer.idl97
-rw-r--r--shell/importer/Makefile.am68
-rw-r--r--shell/importer/evolution-importer-client.c267
-rw-r--r--shell/importer/evolution-importer-client.h69
-rw-r--r--shell/importer/evolution-importer-listener.c224
-rw-r--r--shell/importer/evolution-importer-listener.h66
-rw-r--r--shell/importer/evolution-importer.c249
-rw-r--r--shell/importer/evolution-importer.h94
-rw-r--r--shell/importer/evolution-intelligent-importer.c197
-rw-r--r--shell/importer/evolution-intelligent-importer.h69
-rw-r--r--shell/importer/import.glade124
-rw-r--r--shell/importer/intelligent.c469
-rw-r--r--shell/main.c468
-rw-r--r--shell/shell.error.xml27
-rw-r--r--shell/test/GNOME_Evolution_Test.server.in.in39
-rw-r--r--shell/test/Makefile.am34
-rw-r--r--shell/test/e-test-shell-backend.c222
-rw-r--r--shell/test/e-test-shell-backend.h67
-rw-r--r--shell/test/e-test-shell-view.c155
-rw-r--r--shell/test/e-test-shell-view.h66
-rw-r--r--shell/test/evolution-module-test.c41
-rw-r--r--shell/test/evolution-test-component.c176
-rw-r--r--shell/test/evolution-test-component.h53
-rw-r--r--smclient/Makefile.am44
-rw-r--r--smclient/README2
-rw-r--r--smclient/eggdesktopfile.c1508
-rw-r--r--smclient/eggdesktopfile.h158
-rw-r--r--smclient/eggsmclient-private.h52
-rw-r--r--smclient/eggsmclient-win32.c353
-rw-r--r--smclient/eggsmclient-xsmp.c1370
-rw-r--r--smclient/eggsmclient.c589
-rw-r--r--smclient/eggsmclient.h116
-rw-r--r--smime/gui/Makefile.am11
-rw-r--r--smime/gui/certificate-manager.c26
-rw-r--r--smime/gui/certificate-manager.h9
-rw-r--r--tools/killev.c10
-rw-r--r--ui/Makefile.am22
-rw-r--r--ui/evolution-addressbook.xml190
-rw-r--r--ui/evolution-calendar.xml107
-rw-r--r--ui/evolution-calendars.ui137
-rw-r--r--ui/evolution-contacts.ui92
-rw-r--r--ui/evolution-mail-global.xml149
-rw-r--r--ui/evolution-mail-list.xml154
-rw-r--r--ui/evolution-mail-message.xml426
-rw-r--r--ui/evolution-mail-messagedisplay.xml74
-rw-r--r--ui/evolution-mail-reader.ui138
-rw-r--r--ui/evolution-mail.ui127
-rw-r--r--ui/evolution-memos.ui75
-rw-r--r--ui/evolution-memos.xml56
-rw-r--r--ui/evolution-shell.ui82
-rw-r--r--ui/evolution-tasks.ui86
-rw-r--r--ui/evolution-tasks.xml81
-rw-r--r--ui/evolution.xml199
-rw-r--r--widgets/Makefile.am4
-rw-r--r--widgets/e-timezone-dialog/e-timezone-dialog.c2
-rw-r--r--widgets/menus/Makefile.am4
-rw-r--r--widgets/menus/gal-view-collection.c2
-rw-r--r--widgets/menus/gal-view-instance.c142
-rw-r--r--widgets/menus/gal-view-instance.h5
-rw-r--r--widgets/menus/gal-view-menus.c541
-rw-r--r--widgets/menus/gal-view-menus.h63
-rw-r--r--widgets/menus/gal-view-new-dialog.c2
-rw-r--r--widgets/misc/Makefile.am196
-rw-r--r--widgets/misc/e-account-combo-box.c1
-rw-r--r--widgets/misc/e-account-combo-box.h1
-rw-r--r--widgets/misc/e-account-manager.c454
-rw-r--r--widgets/misc/e-account-manager.h82
-rw-r--r--widgets/misc/e-account-tree-view.c632
-rw-r--r--widgets/misc/e-account-tree-view.h84
-rw-r--r--widgets/misc/e-action-combo-box.c582
-rw-r--r--widgets/misc/e-action-combo-box.h85
-rw-r--r--widgets/misc/e-activity-handler.c712
-rw-r--r--widgets/misc/e-activity-handler.h101
-rw-r--r--widgets/misc/e-activity-proxy.c346
-rw-r--r--widgets/misc/e-activity-proxy.h68
-rw-r--r--widgets/misc/e-activity.c605
-rw-r--r--widgets/misc/e-activity.h98
-rw-r--r--widgets/misc/e-alert-activity.c258
-rw-r--r--widgets/misc/e-alert-activity.h70
-rw-r--r--widgets/misc/e-attachment-button.c6
-rw-r--r--widgets/misc/e-calendar.c31
-rw-r--r--widgets/misc/e-calendar.h21
-rw-r--r--widgets/misc/e-charset-combo-box.c428
-rw-r--r--widgets/misc/e-charset-combo-box.h69
-rw-r--r--widgets/misc/e-charset-picker.c715
-rw-r--r--widgets/misc/e-charset-picker.h50
-rw-r--r--widgets/misc/e-combo-button.c625
-rw-r--r--widgets/misc/e-combo-button.h78
-rw-r--r--widgets/misc/e-config-page.h62
-rw-r--r--widgets/misc/e-dateedit.c336
-rw-r--r--widgets/misc/e-dropdown-button.c236
-rw-r--r--widgets/misc/e-dropdown-button.h65
-rw-r--r--widgets/misc/e-filter-bar.c1032
-rw-r--r--widgets/misc/e-filter-bar.h138
-rw-r--r--widgets/misc/e-hinted-entry.c298
-rw-r--r--widgets/misc/e-hinted-entry.h73
-rw-r--r--widgets/misc/e-icon-entry.c418
-rw-r--r--widgets/misc/e-icon-entry.h87
-rw-r--r--widgets/misc/e-image-chooser.c588
-rw-r--r--widgets/misc/e-image-chooser.h65
-rw-r--r--widgets/misc/e-info-label.c246
-rw-r--r--widgets/misc/e-menu-tool-button.c183
-rw-r--r--widgets/misc/e-menu-tool-button.h68
-rw-r--r--widgets/misc/e-multi-config-dialog.c368
-rw-r--r--widgets/misc/e-multi-config-dialog.h71
-rw-r--r--widgets/misc/e-online-button.c32
-rw-r--r--widgets/misc/e-paned.c310
-rw-r--r--widgets/misc/e-paned.h72
-rw-r--r--widgets/misc/e-popup-action.c285
-rw-r--r--widgets/misc/e-popup-action.h95
-rw-r--r--widgets/misc/e-preferences-window.c393
-rw-r--r--widgets/misc/e-preferences-window.h74
-rw-r--r--widgets/misc/e-search-bar.c1683
-rw-r--r--widgets/misc/e-search-bar.h194
-rw-r--r--widgets/misc/e-signature-combo-box.c1
-rw-r--r--widgets/misc/e-signature-combo-box.h1
-rw-r--r--widgets/misc/e-signature-editor.c (renamed from mail/mail-signature-editor.c)38
-rw-r--r--widgets/misc/e-signature-editor.h (renamed from mail/mail-signature-editor.h)10
-rw-r--r--widgets/misc/e-signature-manager.c753
-rw-r--r--widgets/misc/e-signature-manager.h100
-rw-r--r--widgets/misc/e-signature-preview.c349
-rw-r--r--widgets/misc/e-signature-preview.h81
-rw-r--r--widgets/misc/e-signature-script-dialog.c463
-rw-r--r--widgets/misc/e-signature-script-dialog.h76
-rw-r--r--widgets/misc/e-signature-tree-view.c448
-rw-r--r--widgets/misc/e-signature-tree-view.h78
-rw-r--r--widgets/misc/e-task-bar.c307
-rw-r--r--widgets/misc/e-task-bar.h76
-rw-r--r--widgets/misc/e-task-widget.c290
-rw-r--r--widgets/misc/e-task-widget.h77
-rw-r--r--widgets/misc/e-timeout-activity.c198
-rw-r--r--widgets/misc/e-timeout-activity.h73
-rw-r--r--widgets/misc/ea-calendar-cell.c (renamed from a11y/widgets/ea-calendar-cell.c)2
-rw-r--r--widgets/misc/ea-calendar-cell.h (renamed from a11y/widgets/ea-calendar-cell.h)0
-rw-r--r--widgets/misc/ea-calendar-item.c (renamed from a11y/widgets/ea-calendar-item.c)0
-rw-r--r--widgets/misc/ea-calendar-item.h (renamed from a11y/widgets/ea-calendar-item.h)0
-rw-r--r--widgets/misc/ea-cell-table.c (renamed from a11y/ea-cell-table.c)0
-rw-r--r--widgets/misc/ea-cell-table.h (renamed from a11y/ea-cell-table.h)0
-rw-r--r--widgets/misc/ea-widgets.c (renamed from a11y/widgets/ea-widgets.c)11
-rw-r--r--widgets/misc/ea-widgets.h (renamed from a11y/widgets/ea-widgets.h)1
-rw-r--r--widgets/misc/test-calendar.c2
-rw-r--r--widgets/misc/test-dropdown-button.c99
-rw-r--r--widgets/misc/test-error.c61
-rw-r--r--widgets/misc/test-info-label.c75
-rw-r--r--widgets/misc/test-preferences-window.c (renamed from widgets/misc/test-multi-config-dialog.c)49
-rw-r--r--widgets/table/Makefile.am58
-rw-r--r--widgets/table/e-cell-combo.c2
-rw-r--r--widgets/table/e-cell-date-edit.c (renamed from widgets/misc/e-cell-date-edit.c)6
-rw-r--r--widgets/table/e-cell-date-edit.h (renamed from widgets/misc/e-cell-date-edit.h)17
-rw-r--r--widgets/table/e-cell-date.c2
-rw-r--r--widgets/table/e-cell-hbox.c4
-rw-r--r--widgets/table/e-cell-percent.c (renamed from widgets/misc/e-cell-percent.c)0
-rw-r--r--widgets/table/e-cell-percent.h (renamed from widgets/misc/e-cell-percent.h)0
-rw-r--r--widgets/table/e-cell-popup.c4
-rw-r--r--widgets/table/e-cell-text.c6
-rw-r--r--widgets/table/e-cell-toggle.c4
-rw-r--r--widgets/table/e-cell-tree.c4
-rw-r--r--widgets/table/e-cell-vbox.c4
-rw-r--r--widgets/table/e-table-click-to-add.c2
-rw-r--r--widgets/table/e-table-config.c2
-rw-r--r--widgets/table/e-table-example-1.c305
-rw-r--r--widgets/table/e-table-group-container.c2
-rw-r--r--widgets/table/e-table-header-item.c5
-rw-r--r--widgets/table/e-table-header-utils.c2
-rw-r--r--widgets/table/e-table-item.c4
-rw-r--r--widgets/table/e-table-utils.c2
-rw-r--r--widgets/table/e-table.c4
-rw-r--r--widgets/table/e-tree.c2
-rw-r--r--widgets/table/gal-a11y-e-cell-popup.c (renamed from a11y/e-table/gal-a11y-e-cell-popup.c)0
-rw-r--r--widgets/table/gal-a11y-e-cell-popup.h (renamed from a11y/e-table/gal-a11y-e-cell-popup.h)2
-rw-r--r--widgets/table/gal-a11y-e-cell-registry.c (renamed from a11y/e-table/gal-a11y-e-cell-registry.c)0
-rw-r--r--widgets/table/gal-a11y-e-cell-registry.h (renamed from a11y/e-table/gal-a11y-e-cell-registry.h)0
-rw-r--r--widgets/table/gal-a11y-e-cell-text.c (renamed from a11y/e-table/gal-a11y-e-cell-text.c)0
-rw-r--r--widgets/table/gal-a11y-e-cell-text.h (renamed from a11y/e-table/gal-a11y-e-cell-text.h)2
-rw-r--r--widgets/table/gal-a11y-e-cell-toggle.c (renamed from a11y/e-table/gal-a11y-e-cell-toggle.c)0
-rw-r--r--widgets/table/gal-a11y-e-cell-toggle.h (renamed from a11y/e-table/gal-a11y-e-cell-toggle.h)0
-rw-r--r--widgets/table/gal-a11y-e-cell-tree.c (renamed from a11y/e-table/gal-a11y-e-cell-tree.c)0
-rw-r--r--widgets/table/gal-a11y-e-cell-tree.h (renamed from a11y/e-table/gal-a11y-e-cell-tree.h)0
-rw-r--r--widgets/table/gal-a11y-e-cell-vbox.c (renamed from a11y/e-table/gal-a11y-e-cell-vbox.c)0
-rw-r--r--widgets/table/gal-a11y-e-cell-vbox.h (renamed from a11y/e-table/gal-a11y-e-cell-vbox.h)0
-rw-r--r--widgets/table/gal-a11y-e-cell.c (renamed from a11y/e-table/gal-a11y-e-cell.c)0
-rw-r--r--widgets/table/gal-a11y-e-cell.h (renamed from a11y/e-table/gal-a11y-e-cell.h)0
-rw-r--r--widgets/table/gal-a11y-e-table-click-to-add-factory.c (renamed from a11y/e-table/gal-a11y-e-table-click-to-add-factory.c)0
-rw-r--r--widgets/table/gal-a11y-e-table-click-to-add-factory.h (renamed from a11y/e-table/gal-a11y-e-table-click-to-add-factory.h)0
-rw-r--r--widgets/table/gal-a11y-e-table-click-to-add.c (renamed from a11y/e-table/gal-a11y-e-table-click-to-add.c)0
-rw-r--r--widgets/table/gal-a11y-e-table-click-to-add.h (renamed from a11y/e-table/gal-a11y-e-table-click-to-add.h)0
-rw-r--r--widgets/table/gal-a11y-e-table-column-header.c (renamed from a11y/e-table/gal-a11y-e-table-column-header.c)0
-rw-r--r--widgets/table/gal-a11y-e-table-column-header.h (renamed from a11y/e-table/gal-a11y-e-table-column-header.h)0
-rw-r--r--widgets/table/gal-a11y-e-table-factory.c (renamed from a11y/e-table/gal-a11y-e-table-factory.c)0
-rw-r--r--widgets/table/gal-a11y-e-table-factory.h (renamed from a11y/e-table/gal-a11y-e-table-factory.h)0
-rw-r--r--widgets/table/gal-a11y-e-table-item-factory.c (renamed from a11y/e-table/gal-a11y-e-table-item-factory.c)0
-rw-r--r--widgets/table/gal-a11y-e-table-item-factory.h (renamed from a11y/e-table/gal-a11y-e-table-item-factory.h)0
-rw-r--r--widgets/table/gal-a11y-e-table-item.c (renamed from a11y/e-table/gal-a11y-e-table-item.c)0
-rw-r--r--widgets/table/gal-a11y-e-table-item.h (renamed from a11y/e-table/gal-a11y-e-table-item.h)0
-rw-r--r--widgets/table/gal-a11y-e-table.c (renamed from a11y/e-table/gal-a11y-e-table.c)0
-rw-r--r--widgets/table/gal-a11y-e-table.h (renamed from a11y/e-table/gal-a11y-e-table.h)0
-rw-r--r--widgets/table/gal-a11y-e-tree-factory.c (renamed from a11y/e-table/gal-a11y-e-tree-factory.c)0
-rw-r--r--widgets/table/gal-a11y-e-tree-factory.h (renamed from a11y/e-table/gal-a11y-e-tree-factory.h)0
-rw-r--r--widgets/table/gal-a11y-e-tree.c (renamed from a11y/e-table/gal-a11y-e-tree.c)0
-rw-r--r--widgets/table/gal-a11y-e-tree.h (renamed from a11y/e-table/gal-a11y-e-tree.h)0
-rw-r--r--widgets/text/Makefile.am17
-rw-r--r--widgets/text/e-reflow-model.c (renamed from widgets/misc/e-reflow-model.c)0
-rw-r--r--widgets/text/e-reflow-model.h (renamed from widgets/misc/e-reflow-model.h)0
-rw-r--r--widgets/text/e-reflow.c (renamed from widgets/misc/e-reflow.c)8
-rw-r--r--widgets/text/e-reflow.h (renamed from widgets/misc/e-reflow.h)2
-rw-r--r--widgets/text/e-text.c4
-rw-r--r--widgets/text/gal-a11y-e-text-factory.c (renamed from a11y/e-text/gal-a11y-e-text-factory.c)0
-rw-r--r--widgets/text/gal-a11y-e-text-factory.h (renamed from a11y/e-text/gal-a11y-e-text-factory.h)0
-rw-r--r--widgets/text/gal-a11y-e-text.c (renamed from a11y/e-text/gal-a11y-e-text.c)0
-rw-r--r--widgets/text/gal-a11y-e-text.h (renamed from a11y/e-text/gal-a11y-e-text.h)0
-rw-r--r--win32/Makefile.am7
984 files changed, 105994 insertions, 90104 deletions
diff --git a/Makefile.am b/Makefile.am
index d0af9763da..f79d67fbd8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,36 +30,43 @@ EXTRA_DIST = \
intltool-extract.in \
evolution-zip.in \
gnome-doc-utils.make \
+ gtk-doc.make \
$(pkgconfig_DATA:.pc=.pc.in)
if ENABLE_SMIME
-SMIME_DIR=smime
+SMIME_SUBDIR=smime
+endif
+
+if WITH_HELP
+HELP_SUBDIR=help
endif
SUBDIRS = \
+ m4 \
win32 \
- data \
- e-util \
+ data \
+ smclient \
+ e-util \
a11y \
- widgets \
- shell \
filter \
- $(SMIME_DIR) \
- addressbook \
- calendar \
- art \
+ widgets \
+ shell \
+ $(SMIME_SUBDIR) \
+ em-format \
composer \
+ addressbook \
mail \
+ calendar \
+ art \
plugins \
+ modules \
+ doc \
ui \
views \
tools \
po \
- sounds
-
-if WITH_HELP
-SUBDIRS += help
-endif
+ sounds \
+ $(HELP_SUBDIR)
DISTCLEANFILES = \
$(builddir)/doltcompile \
@@ -79,12 +86,23 @@ MAINTAINERCLEANFILES = \
$(srcdir)/ltmain.sh \
$(srcdir)/missing \
$(srcdir)/mkinstalldirs \
- $(srcdir)/gnome-doc-utils.make
+ $(srcdir)/gnome-doc-utils.make \
+ $(srcdir)/gtk-doc.make \
+ $(srcdir)/m4/gnome-doc-utils.m4 \
+ $(srcdir)/m4/gtk-doc.m4 \
+ $(srcdir)/m4/intltool.m4 \
+ $(srcdir)/m4/libtool.m4 \
+ $(srcdir)/m4/ltoptions.m4 \
+ $(srcdir)/m4/ltsugar.m4 \
+ $(srcdir)/m4/ltversion.m4 \
+ $(srcdir)/m4/lt~obsolete.m4
# Scrollkeeper must be disabled for distcheck to work because
# distcheck uses a custom prefix. See GNOME bug #354357.
DISTCHECK_CONFIGURE_FLAGS = \
+ --enable-gtk-doc \
--disable-scrollkeeper \
- --enable-test-component
+ --enable-test-component \
+ --with-help
-include $(top_srcdir)/git.mk
diff --git a/a11y/Makefile.am b/a11y/Makefile.am
index 72cd2c72a9..eeb7b50409 100644
--- a/a11y/Makefile.am
+++ b/a11y/Makefile.am
@@ -1,13 +1,3 @@
-# Somewhat odd looking to have "." in SUBDIRS, but apparently it works?
-SUBDIRS = e-text e-table . calendar widgets addressbook
-
-if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = \
- $(top_builddir)/win32/libemiscwidgets.la \
- $(top_builddir)/win32/libetable.la \
- $(top_builddir)/win32/libetext.la
-endif
-
# for debug
#A11Y_CFLAGS += -pedantic -ansi -DACC_DEBUG -Werror
@@ -18,8 +8,6 @@ AM_CPPFLAGS = \
libevolution_a11y_la_SOURCES = \
ea-factory.h \
- ea-cell-table.h \
- ea-cell-table.c \
gal-a11y-util.c \
gal-a11y-util.h \
gal-a11y-factory.h
@@ -27,9 +15,6 @@ libevolution_a11y_la_SOURCES = \
libevolution_a11y_la_LDFLAGS = $(NO_UNDEFINED)
libevolution_a11y_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- e-text/libgal-a11y-etext.la \
- e-table/libgal-a11y-etable.la \
$(top_builddir)/e-util/libeutil.la \
$(GNOME_PLATFORM_LIBS)
diff --git a/a11y/addressbook/Makefile.am b/a11y/addressbook/Makefile.am
deleted file mode 100644
index 4d127601c3..0000000000
--- a/a11y/addressbook/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = \
- $(top_builddir)/win32/libemiscwidgets.la \
- $(top_builddir)/win32/libevolution-addressbook.la
-endif
-
-privsolib_LTLIBRARIES = libevolution-addressbook-a11y.la
-
-AM_CPPFLAGS = \
- -DG_LOG_DOMAIN=\"evolution-a11y\" \
- -I$(top_srcdir) \
- -I$(top_srcdir)/a11y \
- -I$(top_srcdir)/widgets \
- -I$(top_srcdir)/shell \
- -I$(top_srcdir)/addressbook/gui/widgets \
- -DG_DISABLE_DEPRECATED \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
-
-libevolution_addressbook_a11y_la_SOURCES = \
- ea-minicard.c \
- ea-minicard.h \
- ea-minicard-view.c \
- ea-minicard-view.h \
- ea-addressbook-view.c \
- ea-addressbook-view.h \
- ea-addressbook.c \
- ea-addressbook.h
-
-libevolution_addressbook_a11y_la_LDFLAGS = $(NO_UNDEFINED)
-
-libevolution_addressbook_a11y_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
-
--include $(top_srcdir)/git.mk
diff --git a/a11y/calendar/Makefile.am b/a11y/calendar/Makefile.am
deleted file mode 100644
index 4605cb0a63..0000000000
--- a/a11y/calendar/Makefile.am
+++ /dev/null
@@ -1,56 +0,0 @@
-# Calendar IDL files
-
-# for debug
-#A11Y_CFLAGS += -pedantic -ansi -DACC_DEBUG -Werror
-
-if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = \
- $(top_builddir)/win32/libetext.la \
- $(top_builddir)/win32/libevolution-calendar.la
-endif
-
-privsolib_LTLIBRARIES = libevolution-calendar-a11y.la
-
-AM_CPPFLAGS = \
- -DG_LOG_DOMAIN=\"evolution-a11y\" \
- -I$(top_srcdir) \
- -I$(top_srcdir)/calendar/gui \
- -I$(top_srcdir)/widgets \
- -I$(top_srcdir)/widgets/misc \
- -I$(top_srcdir)/a11y \
- $(EVOLUTION_CALENDAR_CFLAGS)
-
-libevolution_calendar_a11y_la_SOURCES = \
- ea-calendar.c \
- ea-calendar.h \
- ea-calendar-helpers.c \
- ea-calendar-helpers.h \
- ea-cal-view.c \
- ea-cal-view.h \
- ea-cal-view-event.c \
- ea-cal-view-event.h \
- ea-day-view.c \
- ea-day-view.h \
- ea-day-view-main-item.c \
- ea-day-view-main-item.h \
- ea-day-view-cell.c \
- ea-day-view-cell.h \
- ea-week-view.c \
- ea-week-view.h \
- ea-week-view-main-item.c \
- ea-week-view-main-item.h \
- ea-week-view-cell.c \
- ea-week-view-cell.h \
- ea-jump-button.c \
- ea-jump-button.h \
- ea-gnome-calendar.c \
- ea-gnome-calendar.h
-
-libevolution_calendar_a11y_la_LDFLAGS = $(NO_UNDEFINED)
-
-libevolution_calendar_a11y_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(top_builddir)/a11y/libevolution-a11y.la \
- $(EVOLUTION_CALENDAR_LIBS)
-
--include $(top_srcdir)/git.mk
diff --git a/a11y/e-table/Makefile.am b/a11y/e-table/Makefile.am
deleted file mode 100644
index 2a8d0cb072..0000000000
--- a/a11y/e-table/Makefile.am
+++ /dev/null
@@ -1,44 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/widgets \
- $(E_UTIL_CFLAGS) \
- $(GNOME_PLATFORM_CFLAGS) \
- -DG_LOG_DOMAIN=\"e-table\"
-
-noinst_LTLIBRARIES = libgal-a11y-etable.la
-
-libgal_a11y_etable_la_SOURCES = \
- gal-a11y-e-tree.c \
- gal-a11y-e-tree-factory.c \
- gal-a11y-e-cell.c \
- gal-a11y-e-cell-text.c \
- gal-a11y-e-cell-tree.c \
- gal-a11y-e-cell-toggle.c \
- gal-a11y-e-cell-popup.c \
- gal-a11y-e-cell-registry.c \
- gal-a11y-e-cell-vbox.c \
- gal-a11y-e-table.c \
- gal-a11y-e-table-item.c \
- gal-a11y-e-table-item-factory.c \
- gal-a11y-e-table-click-to-add.c \
- gal-a11y-e-table-column-header.c \
- gal-a11y-e-table-click-to-add-factory.c \
- gal-a11y-e-table-factory.c \
- gal-a11y-e-tree.h \
- gal-a11y-e-tree-factory.h \
- gal-a11y-e-cell.h \
- gal-a11y-e-cell-text.h \
- gal-a11y-e-cell-tree.h \
- gal-a11y-e-cell-toggle.h \
- gal-a11y-e-cell-popup.h \
- gal-a11y-e-cell-registry.h \
- gal-a11y-e-cell-vbox.h \
- gal-a11y-e-table.h \
- gal-a11y-e-table-item.h \
- gal-a11y-e-table-click-to-add-factory.h \
- gal-a11y-e-table-click-to-add.h \
- gal-a11y-e-table-column-header.h \
- gal-a11y-e-table-item-factory.h \
- gal-a11y-e-table-factory.h
-
--include $(top_srcdir)/git.mk
diff --git a/a11y/e-text/Makefile.am b/a11y/e-text/Makefile.am
deleted file mode 100644
index 726b15157c..0000000000
--- a/a11y/e-text/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/widgets \
- $(GNOME_PLATFORM_CFLAGS) \
- -DG_LOG_DOMAIN=\"e-text\"
-
-noinst_LTLIBRARIES = libgal-a11y-etext.la
-
-libgal_a11y_etext_la_SOURCES = \
- gal-a11y-e-text-factory.c \
- gal-a11y-e-text.c \
- gal-a11y-e-text-factory.h \
- gal-a11y-e-text.h
-
--include $(top_srcdir)/git.mk
diff --git a/a11y/widgets/Makefile.am b/a11y/widgets/Makefile.am
deleted file mode 100644
index 663159c7b2..0000000000
--- a/a11y/widgets/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-
-# for debug
-#A11Y_CFLAGS += -pedantic -ansi -DACC_DEBUG -Werror
-
-if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libemiscwidgets.la
-endif
-
-privsolib_LTLIBRARIES = libevolution-widgets-a11y.la
-
-AM_CPPFLAGS = \
- -DG_LOG_DOMAIN=\"evolution-a11y\" \
- -I$(top_srcdir) \
- -I$(top_srcdir)/a11y \
- -I$(top_srcdir)/widgets \
- $(E_WIDGETS_CFLAGS)
-
-libevolution_widgets_a11y_la_SOURCES = \
- ea-calendar-item.c \
- ea-calendar-item.h \
- ea-calendar-cell.c \
- ea-calendar-cell.h \
- ea-combo-button.c \
- ea-combo-button.h \
- ea-widgets.c \
- ea-widgets.h
-
-libevolution_widgets_a11y_la_LDFLAGS = $(NO_UNDEFINED)
-
-libevolution_widgets_a11y_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(top_builddir)/a11y/libevolution-a11y.la \
- $(top_builddir)/e-util/libeutil.la \
- $(E_WIDGETS_LIBS)
-
--include $(top_srcdir)/git.mk
diff --git a/a11y/widgets/ea-combo-button.c b/a11y/widgets/ea-combo-button.c
deleted file mode 100644
index e25aa7f377..0000000000
--- a/a11y/widgets/ea-combo-button.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Harry Lu <harry.lu@sun.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <config.h>
-#include "ea-combo-button.h"
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-static AtkObjectClass *parent_class;
-static GType parent_type;
-
-/*Action IDs */
-enum {
- ACTIVATE_DEFAULT,
- POPUP_MENU,
- LAST_ACTION
-};
-
-/* Static functions */
-static G_CONST_RETURN gchar *
-ea_combo_button_get_name (AtkObject *a11y)
-{
- GtkWidget *widget;
- GtkWidget *label;
- EComboButton *button;
-
- widget = GTK_ACCESSIBLE (a11y)->widget;
- if (!widget)
- return NULL;
-
- button = E_COMBO_BUTTON (widget);
- label = e_combo_button_get_label (button);
- if (label)
- return gtk_label_get_text (GTK_LABEL (label));
-
- return _("Combo Button");
-}
-
-/* Action interface */
-static G_CONST_RETURN gchar *
-ea_combo_button_action_get_name (AtkAction *action, gint i)
-{
- switch (i)
- {
- case ACTIVATE_DEFAULT:
- return _("Activate Default");
- case POPUP_MENU:
- return _("Popup Menu");
- default:
- return NULL;
- }
-}
-
-static gboolean
-ea_combo_button_do_action (AtkAction *action,
- gint i)
-{
- GtkWidget *widget;
- EComboButton *button;
-
- widget = GTK_ACCESSIBLE (action)->widget;
- if (!widget || !GTK_WIDGET_IS_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget))
- return FALSE;
-
- button = E_COMBO_BUTTON (widget);
-
- switch (i)
- {
- case ACTIVATE_DEFAULT:
- g_signal_emit_by_name (button, "activate_default");
- return TRUE;
- case POPUP_MENU:
- return e_combo_button_popup_menu (button);
- default:
- return FALSE;
- }
-}
-
-static gint
-ea_combo_button_get_n_actions (AtkAction *action)
-{
- return LAST_ACTION;
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- g_return_if_fail (iface != NULL);
-
- iface->do_action = ea_combo_button_do_action;
- iface->get_n_actions = ea_combo_button_get_n_actions;
- iface->get_name = ea_combo_button_action_get_name;
-}
-
-static void
-ea_combo_button_class_init (EaComboButtonClass *klass)
-{
- AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_ref (parent_type);
-
- atk_object_class->get_name = ea_combo_button_get_name;
-}
-
-static void
-ea_combo_button_init (EaComboButton *a11y)
-{
- /* Empty for now */
-}
-
-GType
-ea_combo_button_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- AtkObjectFactory *factory;
- GTypeQuery query;
-
- GTypeInfo info = {
- sizeof (EaComboButtonClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) ea_combo_button_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EaComboButton),
- 0,
- (GInstanceInitFunc) ea_combo_button_init,
- NULL /* value_tree */
- };
-
- static const GInterfaceInfo atk_action_info = {
- (GInterfaceInitFunc) atk_action_interface_init,
- (GInterfaceFinalizeFunc) NULL,
- NULL
- };
-
- factory = atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_BUTTON);
- parent_type = atk_object_factory_get_accessible_type (factory);
- g_type_query (parent_type, &query);
-
- info.class_size = query.class_size;
- info.instance_size = query.instance_size;
-
- type = g_type_register_static (parent_type, "EaComboButton", &info, 0);
- g_type_add_interface_static (type, ATK_TYPE_ACTION,
- &atk_action_info);
-
- }
-
- return type;
-}
-
-AtkObject *
-ea_combo_button_new (GtkWidget *widget)
-{
- EaComboButton *a11y;
-
- a11y = g_object_new (ea_combo_button_get_type (), NULL);
-
- GTK_ACCESSIBLE (a11y)->widget = GTK_WIDGET (widget);
- ATK_OBJECT (a11y)->role = ATK_ROLE_PUSH_BUTTON;
-
- return ATK_OBJECT (a11y);
-}
diff --git a/a11y/widgets/ea-combo-button.h b/a11y/widgets/ea-combo-button.h
deleted file mode 100644
index e1482fbf32..0000000000
--- a/a11y/widgets/ea-combo-button.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Harry Lu <harry.lu@sun.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EA_COMBO_BUTTON_H_
-#define __EA_COMBO_BUTTON_H_
-
-#include <gtk/gtk.h>
-#include <misc/e-combo-button.h>
-
-#define EA_TYPE_COMBO_BUTTON (ea_combo_button_get_type ())
-#define EA_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_COMBO_BUTTON, EaComboButton))
-#define EA_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_COMBO_BUTTON, EaComboButtonClass))
-#define EA_IS_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_COMBO_BUTTON))
-#define EA_IS_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_COMBO_BUTTON))
-
-typedef struct _EaComboButton EaComboButton;
-typedef struct _EaComboButtonClass EaComboButtonClass;
-
-struct _EaComboButton {
- GtkAccessible object;
-};
-
-struct _EaComboButtonClass {
- GtkAccessibleClass parent_class;
-};
-
-/* Standard Glib function */
-GType ea_combo_button_get_type (void);
-AtkObject *ea_combo_button_new (GtkWidget *combo_button);
-
-#endif /* ! __EA_COMBO_BUTTON_H_ */
diff --git a/addressbook/conduit/address-conduit.c b/addressbook/conduit/address-conduit.c
index 172d45ee30..79c82cdb77 100644
--- a/addressbook/conduit/address-conduit.c
+++ b/addressbook/conduit/address-conduit.c
@@ -29,6 +29,14 @@
#define G_LOG_DOMAIN "eaddrconduit"
+/* Work around deprecated API usage in GnomePilot. */
+#ifdef GTK_DISABLE_DEPRECATED
+#include <glib-object.h>
+#define GTK_CHECK_CAST G_TYPE_CHECK_INSTANCE_CAST
+typedef GType GtkType;
+#endif
+
+#include <glib/gi18n.h>
#include <libxml/parser.h>
#include <pi-source.h>
#include <pi-socket.h>
diff --git a/addressbook/gui/Makefile.am b/addressbook/gui/Makefile.am
index 64bcd98356..7f08bf425d 100644
--- a/addressbook/gui/Makefile.am
+++ b/addressbook/gui/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = merging contact-editor contact-list-editor widgets component
+SUBDIRS = merging widgets contact-editor contact-list-editor
-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in b/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in
deleted file mode 100644
index 4000f01526..0000000000
--- a/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in
+++ /dev/null
@@ -1,136 +0,0 @@
-<oaf_info>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@"
- type="shlib"
- location="@COMPONENTDIR_IN_SERVER_FILE@/libevolution-addressbook@SOEXT@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Address Book"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_Control:@VERSION@"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:Bonobo/Control:1.0"/>
- <item value="IDL:Bonobo/PersistStream:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="bonobo:supported_mime_types" type="stringv">
- <item value="text/vcard"/>
- <item value="text/x-vcard"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Address Book card viewer"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Component:@VERSION@"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Component:@VERSION@"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Address Book component"/>
-
- <oaf_attribute name="evolution:component_alias" type="string" value="contacts"/>
-
- <oaf_attribute name="evolution:menu_label" type="string" _value="C_ontacts"/>
- <oaf_attribute name="evolution:menu_accelerator" type="string" value="*Control*2"/>
- <oaf_attribute name="evolution:button_label" type="string" _value="Contacts"/>
- <oaf_attribute name="evolution:button_tooltips" type="string" _value="Contacts"/>
- <oaf_attribute name="evolution:button_sort_order" type="string" value="-9"/>
- <oaf_attribute name="evolution:button_icon" type="string" value="x-office-address-book"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressWidget:@VERSION@"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:BonoboControl/address-widget:@VERSION@"/>
- <item value="IDL:GNOME/Control:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Address Book address viewer"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressPopup:@VERSION@"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:BonoboControl/address-widget:@VERSION@"/>
- <item value="IDL:GNOME/Control:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Address Book address popup"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_SMime_CertificateManager_ConfigControl:@VERSION@"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ConfigControl:@VERSION@"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution2:config_item:title" type="string"
- _value="Certificates"/>
-
- <oaf_attribute name="evolution2:config_item:description" type="string"
- _value="Manage your S/MIME certificates here"/>
-
- <oaf_attribute name="evolution2:config_item:icon_name" type="string"
- value="preferences-certificates"/>
-
- <oaf_attribute name="evolution2:config_item:priority" type="string" value="-6"/>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution S/MIME Certificate Management Control"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Autocompletion_ConfigControl:@VERSION@"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ConfigControl:@VERSION@"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution2:config_item:title" type="string"
- _value="Contacts"/>
-
- <oaf_attribute name="evolution2:config_item:description" type="string"
- _value="Configure contacts and autocompletion here"/>
-
- <oaf_attribute name="evolution2:config_item:icon_name" type="string"
- value="preferences-autocompletion"/>
-
- <oaf_attribute name="evolution2:config_item:type" type="stringv">
- <item value="contacts"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution2:config_item:priority" type="string" value="-9"/>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution folder settings configuration control"/>
-</oaf_server>
-
-</oaf_info>
diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c
deleted file mode 100644
index 9bf63376fb..0000000000
--- a/addressbook/gui/component/addressbook-component.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-/* EPFIXME: Add autocompletion setting. */
-
-#include <config.h>
-
-#include "addressbook-component.h"
-#include "addressbook-config.h"
-#include "addressbook-migrate.h"
-#include "addressbook-view.h"
-#include "addressbook/gui/contact-editor/eab-editor.h"
-#include "addressbook/gui/widgets/eab-gui-util.h"
-#include "e-util/e-plugin.h"
-#include "e-util/e-import.h"
-#include "addressbook/gui/widgets/eab-popup.h"
-#include "addressbook/gui/widgets/eab-menu.h"
-#include "addressbook/gui/widgets/eab-config.h"
-#include "addressbook/importers/evolution-addressbook-importers.h"
-
-#include "misc/e-task-bar.h"
-#include "misc/e-info-label.h"
-
-#include "shell/e-component-view.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n-lib.h>
-#include <gconf/gconf-client.h>
-#include <e-util/e-util.h>
-#include <libedataserver/e-url.h>
-
-#ifdef ENABLE_SMIME
-#include "smime/gui/component.h"
-#endif
-
-#define LDAP_BASE_URI "ldap://"
-#define PERSONAL_RELATIVE_URI "system"
-
-#define PARENT_TYPE bonobo_object_get_type ()
-static BonoboObjectClass *parent_class = NULL;
-
-struct _AddressbookComponentPrivate {
- GConfClient *gconf_client;
- gchar *base_directory;
- GList *views;
-};
-
-static void
-ensure_sources (AddressbookComponent *component)
-{
- ESourceList *source_list;
- ESourceGroup *on_this_computer;
- ESource *personal_source;
- gchar *base_uri, *base_uri_proto, base_uri_proto_seventh;
- const gchar *base_dir;
-
- personal_source = NULL;
-
- if (!e_book_get_addressbooks (&source_list, NULL)) {
- g_warning ("Could not get addressbook source list from GConf!");
- return;
- }
-
- base_dir = addressbook_component_peek_base_directory (component);
- base_uri = g_build_filename (base_dir, "local", NULL);
-
- base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
- if (strlen (base_uri_proto) >= 7) {
- /* compare only file:// part. If user home dir name changes we do not want to create
- one more group */
- base_uri_proto_seventh = base_uri_proto[7];
- base_uri_proto[7] = 0;
- } else {
- base_uri_proto_seventh = -1;
- }
-
- on_this_computer = e_source_list_ensure_group (source_list, _("On This Computer"), base_uri_proto, TRUE);
- e_source_list_ensure_group (source_list, _("On LDAP Servers"), LDAP_BASE_URI, FALSE);
-
- if (base_uri_proto_seventh != -1) {
- base_uri_proto[7] = base_uri_proto_seventh;
- }
-
- if (on_this_computer) {
- /* make sure "Personal" shows up as a source under
- this group */
- GSList *sources = e_source_group_peek_sources (on_this_computer);
- GSList *s;
- for (s = sources; s; s = s->next) {
- ESource *source = E_SOURCE (s->data);
- const gchar *relative_uri;
-
- relative_uri = e_source_peek_relative_uri (source);
- if (relative_uri == NULL)
- continue;
- if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
- personal_source = source;
- break;
- }
- }
- /* Make sure we have the correct base uri. This can change when user's
- homedir name changes */
- if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) {
- e_source_group_set_base_uri (on_this_computer, base_uri_proto);
-
- /* *sigh* . We shouldn't need this sync call here as set_base_uri
- call results in synching to gconf, but that happens in idle loop
- and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/
- e_source_list_sync (source_list,NULL);
- }
- }
-
- if (personal_source) {
- /* ensure the source name is in current locale, not read from configuration */
- e_source_set_name (personal_source, _("Personal"));
- } else {
- /* Create the default Person addressbook */
- ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
- e_source_group_add_source (on_this_computer, source, -1);
- g_object_unref (source);
-
- e_source_set_property (source, "completion", "true");
-
- personal_source = source;
- }
-
- g_object_unref (on_this_computer);
- g_free (base_uri_proto);
- g_free (base_uri);
-}
-
-static void
-view_destroyed_cb (gpointer data, GObject *where_the_object_was)
-{
- AddressbookComponent *addressbook_component = data;
- AddressbookComponentPrivate *priv;
- GList *l;
-
- priv = addressbook_component->priv;
-
- for (l = priv->views; l; l = l->next) {
- AddressbookView *view = l->data;
- if (G_OBJECT (view) == where_the_object_was) {
- priv->views = g_list_remove (priv->views, view);
- break;
- }
- }
-}
-
-/* Evolution::Component CORBA methods. */
-
-static GNOME_Evolution_ComponentView
-impl_createView (PortableServer_Servant servant,
- GNOME_Evolution_ShellView parent,
- CORBA_boolean select_item,
- CORBA_Environment *ev)
-{
- AddressbookComponent *addressbook_component = ADDRESSBOOK_COMPONENT (bonobo_object_from_servant (servant));
- AddressbookComponentPrivate *priv = addressbook_component->priv;
- AddressbookView *view = addressbook_view_new ();
- EComponentView *component_view;
-
- g_object_weak_ref (G_OBJECT (view), view_destroyed_cb, addressbook_component);
- priv->views = g_list_append (priv->views, view);
-
- component_view = e_component_view_new_controls (parent, "contacts",
- bonobo_control_new (addressbook_view_peek_sidebar (view)),
- addressbook_view_peek_folder_view (view),
- bonobo_control_new (addressbook_view_peek_statusbar (view)));
-
- return BONOBO_OBJREF(component_view);
-
-}
-
-static GNOME_Evolution_CreatableItemTypeList *
-impl__get_userCreatableItems (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
-
- list->_length = 3;
- list->_maximum = list->_length;
- list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
-
- CORBA_sequence_set_release (list, FALSE);
-
- list->_buffer[0].id = (gchar *) "contact";
- list->_buffer[0].description = _("New Contact");
- list->_buffer[0].menuDescription = (gchar *) C_("New", "_Contact");
- list->_buffer[0].tooltip = _("Create a new contact");
- list->_buffer[0].menuShortcut = 'c';
- list->_buffer[0].iconName = (gchar *) "contact-new";
- list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[1].id = (gchar *) "contact_list";
- list->_buffer[1].description = _("New Contact List");
- list->_buffer[1].menuDescription = (gchar *) C_("New", "Contact _List");
- list->_buffer[1].tooltip = _("Create a new contact list");
- list->_buffer[1].menuShortcut = 'l';
- list->_buffer[1].iconName = (gchar *) "stock_contact-list";
- list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[2].id = (gchar *) "address_book";
- list->_buffer[2].description = _("New Address Book");
- list->_buffer[2].menuDescription = (gchar *) C_("New", "Address _Book");
- list->_buffer[2].tooltip = _("Create a new address book");
- list->_buffer[2].menuShortcut = '\0';
- list->_buffer[2].iconName = (gchar *) "address-book-new";
- list->_buffer[2].type = GNOME_Evolution_CREATABLE_FOLDER;
-
- return list;
-}
-
-static void
-book_loaded_cb (EBook *book, EBookStatus status, gpointer data)
-{
- EContact *contact;
- gchar *item_type_name = data;
-
- if (status != E_BOOK_ERROR_OK) {
- /* XXX we really need a dialog here, but we don't have
- access to the ESource so we can't use
- eab_load_error_dialog. fun! */
- return;
- }
-
- contact = e_contact_new ();
-
- if (!strcmp (item_type_name, "contact")) {
- eab_show_contact_editor (book, contact, TRUE, TRUE);
- }
- else if (!strcmp (item_type_name, "contact_list")) {
- eab_show_contact_list_editor (book, contact, TRUE, TRUE);
- }
-
- g_object_unref (book);
- g_object_unref (contact);
-
- g_free (item_type_name);
-}
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
- const CORBA_char *item_type_name,
- CORBA_Environment *ev)
-{
- EBook *book;
- GConfClient *gconf_client;
- ESourceList *source_list;
- gchar *uid;
-
- if (!item_type_name ||
- (strcmp (item_type_name, "address_book") &&
- strcmp (item_type_name, "contact") &&
- strcmp (item_type_name, "contact_list"))) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UnknownType, NULL);
- return;
- }
-
- if (!strcmp (item_type_name, "address_book")) {
- addressbook_config_create_new_source (NULL);
- return;
- }
-
- gconf_client = gconf_client_get_default();
- uid = gconf_client_get_string (gconf_client, "/apps/evolution/addressbook/display/primary_addressbook",
- NULL);
- g_object_unref (gconf_client);
- if (!e_book_get_addressbooks (&source_list, NULL)) {
- g_warning ("Could not get addressbook source list from GConf!");
- g_free (uid);
- return;
- }
- if (uid) {
- ESource *source = e_source_list_peek_source_by_uid(source_list, uid);
- if (source) {
- book = e_book_new (source, NULL);
- }
- else {
- book = e_book_new_default_addressbook (NULL);
- }
- g_free (uid);
- }
- else {
- book = e_book_new_default_addressbook (NULL);
- }
-
- e_book_async_open (book, FALSE, book_loaded_cb, g_strdup (item_type_name));
-}
-
-static void
-impl_handleURI (PortableServer_Servant servant,
- const gchar * uri,
- CORBA_Environment *ev)
-{
- AddressbookComponent *addressbook_component = ADDRESSBOOK_COMPONENT (bonobo_object_from_servant (servant));
- AddressbookComponentPrivate *priv;
- AddressbookView *view = NULL;
-
- GList *l;
- gchar *src_uid = NULL;
- gchar *contact_uid = NULL;
-
- priv = addressbook_component->priv;
- l = g_list_last (priv->views);
- if (!l)
- return;
-
- view = l->data;
-
- if (!strncmp (uri, "contacts:", 9)) {
- EUri *euri = e_uri_new (uri);
- const gchar *p;
- gchar *header, *content;
- gsize len, clen;
-
- p = euri->query;
- if (p) {
- while (*p) {
- len = strcspn (p, "=&");
-
- /* If it's malformed, give up. */
- if (p[len] != '=')
- break;
-
- header = (gchar *) p;
- header[len] = '\0';
- p += len + 1;
-
- clen = strcspn (p, "&");
-
- content = g_strndup (p, clen);
-
- if (!g_ascii_strcasecmp (header, "source-uid")) {
- src_uid = g_strdup (content);
- } else if (!g_ascii_strcasecmp (header, "contact-uid")) {
- contact_uid = g_strdup (content);
- }
-
- g_free (content);
-
- p += clen;
- if (*p == '&') {
- p++;
- if (!strcmp (p, "amp;"))
- p += 4;
- }
- }
-
- addressbook_view_edit_contact (view, src_uid, contact_uid);
-
- g_free (src_uid);
- g_free (contact_uid);
- }
- e_uri_free (euri);
- }
-
-}
-
-static void
-impl_upgradeFromVersion (PortableServer_Servant servant, short major, short minor, short revision, CORBA_Environment *ev)
-{
- GError *err = NULL;
-
- if (!addressbook_migrate (addressbook_component_peek (), major, minor, revision, &err)) {
- GNOME_Evolution_Component_UpgradeFailed *failedex;
-
- failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
- failedex->what = CORBA_string_dup(_("Failed upgrading Address Book settings or folders."));
- failedex->why = CORBA_string_dup(err->message);
- CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
- }
-
- if (err)
- g_error_free(err);
-}
-
-static CORBA_boolean
-impl_requestQuit (PortableServer_Servant servant, CORBA_Environment *ev)
-{
- return eab_editor_request_close_all ();
-}
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- AddressbookComponentPrivate *priv = ADDRESSBOOK_COMPONENT (object)->priv;
- GList *l;
-
- if (priv->gconf_client != NULL) {
- g_object_unref (priv->gconf_client);
- priv->gconf_client = NULL;
- }
-
- for (l = priv->views; l; l = l->next) {
- AddressbookView *view = l->data;
- g_object_weak_unref (G_OBJECT (view), view_destroyed_cb, ADDRESSBOOK_COMPONENT (object));
- }
- g_list_free (priv->views);
- priv->views = NULL;
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- AddressbookComponentPrivate *priv = ADDRESSBOOK_COMPONENT (object)->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-/* Initialization. */
-
-static void
-addressbook_component_class_init (AddressbookComponentClass *class)
-{
- POA_GNOME_Evolution_Component__epv *epv = &class->epv;
- GObjectClass *object_class = G_OBJECT_CLASS (class);
-
- bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- epv->createView = impl_createView;
- epv->_get_userCreatableItems = impl__get_userCreatableItems;
- epv->requestCreateItem = impl_requestCreateItem;
- epv->upgradeFromVersion = impl_upgradeFromVersion;
- epv->requestQuit = impl_requestQuit;
- epv->handleURI = impl_handleURI;
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- parent_class = g_type_class_peek_parent (class);
-}
-
-static void
-addressbook_component_init (AddressbookComponent *component)
-{
- AddressbookComponentPrivate *priv;
- static gint first = TRUE;
-
- priv = g_new0 (AddressbookComponentPrivate, 1);
-
- /* EPFIXME: Should use a custom one instead? */
- priv->gconf_client = gconf_client_get_default ();
-
- priv->base_directory = g_build_filename (e_get_user_data_dir (), "addressbook", NULL);
-
- component->priv = priv;
-
- ensure_sources (component);
-
-#ifdef ENABLE_SMIME
- smime_component_init ();
-#endif
-
- if (first) {
- EImportClass *klass;
-
- first = FALSE;
- e_plugin_hook_register_type(eab_popup_hook_get_type());
- e_plugin_hook_register_type(eab_menu_hook_get_type());
- e_plugin_hook_register_type(eab_config_hook_get_type());
-
- klass = g_type_class_ref(e_import_get_type());
- e_import_class_add_importer(klass, evolution_ldif_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, evolution_vcard_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, evolution_csv_outlook_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, evolution_csv_mozilla_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, evolution_csv_evolution_importer_peek(), NULL, NULL);
- }
-}
-
-/* Public API. */
-
-AddressbookComponent *
-addressbook_component_peek (void)
-{
- static AddressbookComponent *component = NULL;
-
- if (component == NULL)
- component = g_object_new (addressbook_component_get_type (), NULL);
-
- return component;
-}
-
-GConfClient*
-addressbook_component_peek_gconf_client (AddressbookComponent *component)
-{
- g_return_val_if_fail (ADDRESSBOOK_IS_COMPONENT (component), NULL);
-
- return component->priv->gconf_client;
-}
-
-const gchar *
-addressbook_component_peek_base_directory (AddressbookComponent *component)
-{
- g_return_val_if_fail (ADDRESSBOOK_IS_COMPONENT (component), NULL);
-
- return component->priv->base_directory;
-}
-
-BONOBO_TYPE_FUNC_FULL (AddressbookComponent, GNOME_Evolution_Component, PARENT_TYPE, addressbook_component)
diff --git a/addressbook/gui/component/addressbook-component.h b/addressbook/gui/component/addressbook-component.h
deleted file mode 100644
index e5119295b3..0000000000
--- a/addressbook/gui/component/addressbook-component.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _ADDRESSBOOK_COMPONENT_H_
-#define _ADDRESSBOOK_COMPONENT_H_
-
-#include <bonobo/bonobo-object.h>
-
-#include "Evolution.h"
-#include "e-activity-handler.h"
-#include <libedataserver/e-source-list.h>
-
-#define ADDRESSBOOK_TYPE_COMPONENT (addressbook_component_get_type ())
-#define ADDRESSBOOK_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ADDRESSBOOK_TYPE_COMPONENT, AddressbookComponent))
-#define ADDRESSBOOK_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ADDRESSBOOK_TYPE_COMPONENT, AddressbookComponentClass))
-#define ADDRESSBOOK_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ADDRESSBOOK_TYPE_COMPONENT))
-#define ADDRESSBOOK_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), ADDRESSBOOK_TYPE_COMPONENT))
-
-typedef struct _AddressbookComponent AddressbookComponent;
-typedef struct _AddressbookComponentPrivate AddressbookComponentPrivate;
-typedef struct _AddressbookComponentClass AddressbookComponentClass;
-
-struct _AddressbookComponent {
- BonoboObject parent;
-
- AddressbookComponentPrivate *priv;
-};
-
-struct _AddressbookComponentClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Component__epv epv;
-};
-
-GType addressbook_component_get_type (void);
-
-AddressbookComponent *addressbook_component_peek (void);
-
-GConfClient *addressbook_component_peek_gconf_client (AddressbookComponent *component);
-const gchar *addressbook_component_peek_base_directory (AddressbookComponent *component);
-
-#endif /* _ADDRESSBOOK_COMPONENT_H_ */
diff --git a/addressbook/gui/component/addressbook-view.c b/addressbook/gui/component/addressbook-view.c
deleted file mode 100644
index 6a66a94913..0000000000
--- a/addressbook/gui/component/addressbook-view.c
+++ /dev/null
@@ -1,1533 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <gdk/gdkkeysyms.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-exception.h>
-#include <e-util/e-util.h>
-#include <libedataserverui/e-source-selector.h>
-#include <libedataserverui/e-passwords.h>
-
-#include "e-util/e-error.h"
-#include "e-util/e-request.h"
-#include "misc/e-task-bar.h"
-#include "misc/e-info-label.h"
-
-#include "e-util/e-icon-factory.h"
-#include "e-util/e-util-private.h"
-#include "shell/e-user-creatable-items-handler.h"
-
-#include "evolution-shell-component-utils.h"
-#include "e-activity-handler.h"
-#include "e-contact-editor.h"
-#include "addressbook-config.h"
-#include "addressbook.h"
-#include "addressbook-view.h"
-#include "addressbook-component.h"
-#include "addressbook/gui/widgets/e-addressbook-view.h"
-#include "addressbook/gui/widgets/eab-gui-util.h"
-#include "addressbook/gui/merging/eab-contact-merging.h"
-#include "addressbook/printing/e-contact-print.h"
-#include "addressbook/util/eab-book-util.h"
-#include "addressbook/gui/widgets/eab-popup.h"
-#include "addressbook/gui/widgets/eab-menu.h"
-
-#define PARENT_TYPE G_TYPE_OBJECT
-static GObjectClass *parent_class = NULL;
-
-#define d(x)
-
-struct _AddressbookViewPrivate {
- GtkWidget *notebook;
- BonoboControl *folder_view_control;
-
- GtkWidget *statusbar_widget;
- EActivityHandler *activity_handler;
-
- GtkWidget *info_widget;
- GtkWidget *sidebar_widget;
- GtkWidget *selector;
-
- GConfClient *gconf_client;
-
- GHashTable *uid_to_view;
- GHashTable *uid_to_editor;
-
- EBook *book;
- guint activity_id;
- ESourceList *source_list;
- gchar *passwd;
- EUserCreatableItemsHandler *creatable_items_handler;
-
- EABMenu *menu;
-};
-
-enum DndTargetType {
- DND_TARGET_TYPE_VCARD_LIST,
- DND_TARGET_TYPE_SOURCE_VCARD_LIST
-};
-#define VCARD_TYPE "text/x-vcard"
-#define SOURCE_VCARD_TYPE "text/x-source-vcard"
-static GtkTargetEntry drag_types[] = {
- { (gchar *) SOURCE_VCARD_TYPE, 0, DND_TARGET_TYPE_SOURCE_VCARD_LIST },
- { (gchar *) VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD_LIST }
-};
-static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
-
-static void set_status_message (EABView *eav, const gchar *message, AddressbookView *view);
-static void search_result (EABView *eav, EBookViewStatus status, AddressbookView *view);
-
-static void activate_source (AddressbookView *view, ESource *source);
-
-static void addressbook_view_init (AddressbookView *view);
-static void addressbook_view_class_init (AddressbookViewClass *klass);
-static void addressbook_view_dispose (GObject *object);
-
-static ESource *find_first_source (ESourceList *source_list);
-static ESource *get_primary_source (AddressbookView *view);
-
-typedef struct {
- GtkWidget *editor;
- gchar *uid;
- AddressbookView *view;
-} EditorUidClosure;
-
-static void
-editor_weak_notify (gpointer data, GObject *o)
-{
- EditorUidClosure *closure = data;
- AddressbookViewPrivate *priv = closure->view->priv;
-
- g_hash_table_remove (priv->uid_to_editor,
- closure->uid);
-}
-
-static EABView *
-get_current_view (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
-
- return EAB_VIEW (gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook),
- gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook))));
-}
-
-static void
-save_all_contacts_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
-
- if (v)
- eab_view_save_as (v, TRUE);
-}
-
-static void
-save_contact_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_save_as(v, FALSE);
-}
-
-static void
-view_contact_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_view(v);
-}
-
-static void
-delete_contact_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_delete_selection(v, TRUE);
-}
-
-static void
-print_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_print (v, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-}
-
-static void
-print_preview_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_print (v, GTK_PRINT_OPERATION_ACTION_PREVIEW);
-}
-
-static void
-stop_loading_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_stop(v);
-}
-
-static void
-cut_contacts_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_cut(v);
-}
-
-static void
-copy_contacts_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_copy(v);
-}
-
-static void
-paste_contacts_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_paste(v);
-}
-
-static void
-select_all_contacts_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_select_all (v);
-}
-
-static void
-send_contact_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_send (v);
-}
-
-static void
-send_contact_to_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_send_to (v);
-}
-
-static void
-copy_all_contacts_to_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
-
- if (v)
- eab_view_copy_to_folder (v, TRUE);
-}
-
-static void
-copy_contact_to_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_copy_to_folder (v, FALSE);
-}
-
-static void
-move_all_contacts_to_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_move_to_folder (v, TRUE);
-}
-
-static void
-move_contact_to_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_move_to_folder (v, FALSE);
-}
-
-static void
-forget_passwords_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- e_passwords_forget_passwords();
-}
-
-static void
-new_addressbook_folder (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- addressbook_config_create_new_source (gtk_widget_get_toplevel(priv->notebook));
-}
-
-static void
-new_folder_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- new_addressbook_folder (view);
-}
-
-static void
-delete_addressbook_folder (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- ESource *selected_source;
- EBook *book;
- GError *error = NULL;
- GtkWindow *toplevel;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector));
- if (!selected_source)
- return;
- toplevel = (GtkWindow *) gtk_widget_get_toplevel (priv->notebook);
-
- if (e_error_run (toplevel, "addressbook:ask-delete-addressbook",
- e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES)
- return;
-
- /* Remove local data */
- book = e_book_new (selected_source, &error);
- if (book) {
- if (e_book_remove (book, NULL)) {
- if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (priv->selector),
- selected_source))
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->selector),
- selected_source);
-
- e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
-
- e_source_list_sync (priv->source_list, NULL);
- }
- else {
- e_error_run (toplevel, "addressbook:remove-addressbook", NULL);
- }
- g_object_unref (book);
- }
- else {
- g_warning ("error removing addressbook : %s", error->message);
- g_error_free (error);
- }
-}
-
-static void
-delete_folder_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- if (view)
- delete_addressbook_folder (view);
-
-}
-
-static void
-edit_addressbook_folder (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- ESource *selected_source;
- const gchar *uid;
- EditorUidClosure *closure;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector));
- if (!selected_source)
- return;
-
- uid = e_source_peek_uid (selected_source);
-
- closure = g_hash_table_lookup (priv->uid_to_editor, uid);
- if (!closure) {
- gchar *uid_copy = g_strdup (uid);
-
- closure = g_new (EditorUidClosure, 1);
- closure->editor = addressbook_config_edit_source (gtk_widget_get_toplevel(priv->notebook), selected_source);
- closure->uid = uid_copy;
- closure->view = view;
-
- g_hash_table_insert (priv->uid_to_editor,
- uid_copy,
- closure);
-
- g_object_weak_ref (G_OBJECT (closure->editor),
- editor_weak_notify, closure);
- }
-
- gtk_window_present (GTK_WINDOW (closure->editor));
-
-}
-
-static void
-edit_folder_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- if (view)
- edit_addressbook_folder (view);
-
-}
-
-static void
-rename_addressbook_folder (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- ESource *source;
- const gchar *old_name;
- gchar *prompt, *new_name;
- gboolean done = FALSE;
-
- source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector));
- old_name = e_source_peek_name(source);
- prompt = g_strdup_printf (_("Rename the \"%s\" folder to:"), old_name);
-
- while (!done) {
- new_name = e_request_string (NULL, _("Rename Folder"), prompt, old_name);
- if (new_name == NULL || !strcmp (old_name, new_name)) {
- done = TRUE;
- } else if (strchr(new_name, '/') != NULL) {
- e_error_run (NULL,
- "addressbook:no-rename-folder", old_name, new_name, _("Folder names cannot contain '/'"), NULL);
- done = TRUE;
- } else if (e_source_group_peek_source_by_name(e_source_peek_group(source), new_name)) {
- e_error_run (NULL, "addressbook:no-rename-folder-exists", old_name, new_name, NULL);
- } else {
- e_source_set_name (source, new_name);
- done = TRUE;
- }
- }
- g_free (new_name);
-
-}
-
-static void
-rename_folder_cb (BonoboUIComponent *uih, gpointer user_data, const gchar *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- if (view)
- rename_addressbook_folder (view);
-}
-
-static gboolean
-folder_can_delete (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- ESource *source;
- const gchar *source_uri;
-
- source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector));
- if (source) {
- source_uri = e_source_peek_relative_uri (source);
- if (source_uri && !strcmp("system", source_uri))
- return 0;
- else
- return 1;
- }
- else
- return 0;
-}
-
-static void
-set_status_message (EABView *eav, const gchar *message, AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- EActivityHandler *activity_handler = priv->activity_handler;
-
- if (!message || !*message) {
- if (priv->activity_id != 0) {
- e_activity_handler_operation_finished (activity_handler, priv->activity_id);
- priv->activity_id = 0;
- }
- } else if (priv->activity_id == 0) {
- gchar *clientid = g_strdup_printf ("%p", (gpointer) view);
-
- priv->activity_id = e_activity_handler_operation_started (
- activity_handler, clientid, message, TRUE);
-
- g_free (clientid);
- } else {
- e_activity_handler_operation_progressing (activity_handler, priv->activity_id, message, -1.0);
- }
-
-}
-
-static void
-set_folder_bar_message (EABView *eav, const gchar *message, AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- EABView *current_view = get_current_view (view);
-
- if (eav == current_view) {
- ESource *source = eav->source;
-
- if (source) {
- const gchar *name = e_source_peek_name (source);
-
- e_info_label_set_info((EInfoLabel*)priv->info_widget, name, message);
- }
- }
-}
-
-static void
-search_result (EABView *eav, EBookViewStatus status, AddressbookView *view)
-{
- eab_search_result_dialog (NULL /* XXX */, status);
-}
-
-static void
-update_command_state (EABView *eav, AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- BonoboUIComponent *uic;
- EABMenuTargetSelect *target;
-
- if (eav != get_current_view (view))
- return;
-
- g_object_ref (view);
-
- target = eab_view_get_menu_target(eav, priv->menu);
- e_menu_update_target((EMenu *)priv->menu, target);
-
- uic = bonobo_control_get_ui_component (priv->folder_view_control);
-
- /* TODO: this stuff can mostly be made to use the target bits instead */
-
- if (bonobo_ui_component_get_container (uic) != CORBA_OBJECT_NIL) {
-#define SET_SENSITIVE(verb,f) \
- bonobo_ui_component_set_prop (uic, (verb), "sensitive", (f)(eav) ? "1" : "0", NULL)
-
- SET_SENSITIVE ("/commands/ContactsSaveAsVCard", eab_view_can_save_as);
- SET_SENSITIVE ("/commands/ContactsView", eab_view_can_view);
-
- /* Print Contact */
- SET_SENSITIVE ("/commands/ContactsPrint", eab_view_can_print);
- SET_SENSITIVE ("/commands/ContactsPrintPreview", eab_view_can_print);
-
- /* Delete Contact */
- SET_SENSITIVE ("/commands/ContactDelete", eab_view_can_delete);
- SET_SENSITIVE ("/commands/ContactsCut", eab_view_can_cut);
-
- SET_SENSITIVE ("/commands/ContactsCopy", eab_view_can_copy);
- SET_SENSITIVE ("/commands/ContactsPaste", eab_view_can_paste);
- SET_SENSITIVE ("/commands/ContactsSelectAll", eab_view_can_select_all);
- SET_SENSITIVE ("/commands/ContactsSendContactToOther", eab_view_can_send);
- SET_SENSITIVE ("/commands/ContactsSendMessageToContact", eab_view_can_send_to);
- SET_SENSITIVE ("/commands/ContactsMoveToFolder", eab_view_can_move_to_folder);
- SET_SENSITIVE ("/commands/ContactsCopyToFolder", eab_view_can_copy_to_folder);
-
- bonobo_ui_component_set_prop (uic, ("/commands/FolderDelete"), "sensitive", folder_can_delete(view) ? "1" : "0", NULL);
-
- /* Stop */
- SET_SENSITIVE ("/commands/ContactStop", eab_view_can_stop);
-#undef SET_SENSITIVE
- }
-
- g_object_unref (view);
-}
-
-static BonoboUIVerb verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("ContactsPrint", print_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsPrintPreview", print_preview_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsSaveAsVCard", save_contact_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsView", view_contact_cb),
-
- BONOBO_UI_UNSAFE_VERB ("ContactDelete", delete_contact_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactStop", stop_loading_cb),
-
- BONOBO_UI_UNSAFE_VERB ("ContactsCut", cut_contacts_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsCopy", copy_contacts_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsPaste", paste_contacts_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsSelectAll", select_all_contacts_cb),
-
- BONOBO_UI_UNSAFE_VERB ("ContactsSendContactToOther", send_contact_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsSendMessageToContact", send_contact_to_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsMoveToFolder", move_contact_to_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsCopyToFolder", copy_contact_to_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsForgetPasswords", forget_passwords_cb),
- /* ContactsViewPreview is a toggle */
-
- BONOBO_UI_UNSAFE_VERB ("FolderCreate", new_folder_cb),
- BONOBO_UI_UNSAFE_VERB ("FolderCopy", copy_all_contacts_to_cb),
- BONOBO_UI_UNSAFE_VERB ("FolderMove", move_all_contacts_to_cb),
- BONOBO_UI_UNSAFE_VERB ("FolderSave", save_all_contacts_cb),
- BONOBO_UI_UNSAFE_VERB ("FolderDelete", delete_folder_cb),
- BONOBO_UI_UNSAFE_VERB ("FolderRename", rename_folder_cb),
- BONOBO_UI_UNSAFE_VERB ("ChangeFolderProperties", edit_folder_cb),
-
- BONOBO_UI_VERB_END
-};
-
-static EPixmap pixmaps [] = {
- E_PIXMAP ("/commands/ChangeFolderProperties", "document-properties", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactDelete", "edit-delete", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactsCopy", "edit-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactsCut", "edit-cut", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactsPaste", "edit-paste", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactsPrint", "document-print", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactsPrintPreview", "document-print-preview", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactsSaveAsVCard", "document-save-as", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactsSendContactToOther", "mail-forward", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ContactsSendMessageToContact", "mail-message-new", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/FolderCopy", "edit-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/FolderDelete", "edit-delete", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/FolderMove", "folder-move", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/FolderSave", "document-save-as", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP ("/Toolbar/ContactsPrint", "document-print", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/ContactDelete", "edit-delete", GTK_ICON_SIZE_LARGE_TOOLBAR),
-
- E_PIXMAP_END
-};
-
-static void
-control_activate (BonoboControl *control,
- BonoboUIComponent *uic,
- AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- Bonobo_UIContainer remote_ui_container;
- EABView *v = get_current_view (view);
- gchar *xmlfile;
-
- remote_ui_container = bonobo_control_get_remote_ui_container (control, NULL);
- bonobo_ui_component_set_container (uic, remote_ui_container, NULL);
- bonobo_object_release_unref (remote_ui_container, NULL);
-
- bonobo_ui_component_add_verb_list_with_data (
- uic, verbs, view);
-
- bonobo_ui_component_freeze (uic, NULL);
-
- xmlfile = g_build_filename (EVOLUTION_UIDIR,
- "evolution-addressbook.xml",
- NULL);
- bonobo_ui_util_set_ui (uic, PREFIX,
- xmlfile,
- "evolution-addressbook", NULL);
- g_free (xmlfile);
-
- if (v)
- eab_view_setup_menus (v, uic);
-
- e_pixmaps_update (uic, pixmaps);
-
- e_user_creatable_items_handler_activate (priv->creatable_items_handler, uic);
-
- bonobo_ui_component_thaw (uic, NULL);
-
- if (v)
- update_command_state (v, view);
-}
-
-static void
-control_activate_cb (BonoboControl *control,
- gboolean activate,
- AddressbookView *view)
-{
- BonoboUIComponent *uic;
- EABView *v = get_current_view (view);
-
- uic = bonobo_control_get_ui_component (control);
- g_return_if_fail (uic != NULL);
-
- if (activate) {
- control_activate (control, uic, view);
- e_menu_activate((EMenu *)view->priv->menu, uic, activate);
- if (activate && v && v->model)
- eab_model_force_folder_bar_message (v->model);
- } else {
- e_menu_activate((EMenu *)view->priv->menu, uic, activate);
- bonobo_ui_component_unset_container (uic, NULL);
- eab_view_discard_menus (v);
- }
-}
-
-static void
-gather_uids_foreach (gchar *key,
- gpointer value,
- GList **list)
-{
- (*list) = g_list_prepend (*list, key);
-}
-
-static void
-source_list_changed_cb (ESourceList *source_list, AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- GList *uids, *l;
- EABView *v;
-
- uids = NULL;
- g_hash_table_foreach (priv->uid_to_view, (GHFunc)gather_uids_foreach, &uids);
- for (l = uids; l; l = l->next) {
- gchar *uid = l->data;
- if (e_source_list_peek_source_by_uid (source_list, uid)) {
- /* the source still exists, do nothing */
- }
- else {
- /* the source no longer exists, remove its
- view remove it from our hash table. */
- v = g_hash_table_lookup (priv->uid_to_view,
- uid);
- gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook),
- gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook),
- GTK_WIDGET (v)));
- g_hash_table_remove (priv->uid_to_view, uid);
- }
- }
- g_list_free (uids);
-
- uids = NULL;
- g_hash_table_foreach (priv->uid_to_editor, (GHFunc)gather_uids_foreach, &uids);
- for (l = uids; l; l = l->next) {
- gchar *uid = l->data;
- if (e_source_list_peek_source_by_uid (source_list, uid)) {
- /* the source still exists, do nothing */
- }
- else {
- /* the source no longer exists, remove its
- editor remove it from our hash table. */
- EditorUidClosure *closure = g_hash_table_lookup (priv->uid_to_editor,
- uid);
- g_object_weak_unref (G_OBJECT (closure->editor),
- editor_weak_notify, closure);
- gtk_widget_destroy (closure->editor);
- g_hash_table_remove (priv->uid_to_editor, uid);
- }
- }
- g_list_free (uids);
-
- /* make sure we've got the current view selected and updated
- properly */
- v = get_current_view (view);
- if (v) {
- eab_view_setup_menus (v, bonobo_control_get_ui_component (priv->folder_view_control));
- update_command_state (v, view);
- }
-}
-
-static void
-load_uri_for_selection (ESourceSelector *selector,
- AddressbookView *view,
- gboolean force)
-{
- ESource *selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (selector));
- ESource *primary = get_primary_source (view);
-
- if (selected_source != NULL &&
- ((primary && (!g_str_equal (e_source_peek_uid (primary),e_source_peek_uid (selected_source) )))||force))
- activate_source (view, selected_source);
-}
-
-static ESource *
-find_first_source (ESourceList *source_list)
-{
- GSList *groups, *sources, *l, *m;
-
- groups = e_source_list_peek_groups (source_list);
- for (l = groups; l; l = l->next) {
- ESourceGroup *group = l->data;
-
- sources = e_source_group_peek_sources (group);
- for (m = sources; m; m = m->next) {
- ESource *source = m->data;
-
- return source;
- }
- }
-
- return NULL;
-}
-
-static void
-save_primary_selection (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- ESource *source;
-
- source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector));
- if (!source)
- return;
-
- /* Save the selection for next time we start up */
- gconf_client_set_string (priv->gconf_client,
- "/apps/evolution/addressbook/display/primary_addressbook",
- e_source_peek_uid (source), NULL);
-}
-
-static ESource *
-get_primary_source (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- ESource *source;
- gchar *uid;
-
- uid = gconf_client_get_string (priv->gconf_client,
- "/apps/evolution/addressbook/display/primary_addressbook",
- NULL);
- if (uid) {
- source = e_source_list_peek_source_by_uid (priv->source_list, uid);
- g_free (uid);
- } else {
- /* Try to create a default if there isn't one */
- source = find_first_source (priv->source_list);
- }
-
- return source;
-}
-
-static void
-load_primary_selection (AddressbookView *view)
-{
- AddressbookViewPrivate *priv = view->priv;
- ESource *source;
-
- source = get_primary_source (view);
- if (source)
- e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (priv->selector), source);
-}
-
-/* Folder popup menu callbacks */
-typedef struct {
- AddressbookView *view;
- ESource *selected_source;
- GtkWidget *toplevel;
-} BookRemovedClosure;
-
-static void
-book_removed (EBook *book, EBookStatus status, gpointer data)
-{
- BookRemovedClosure *closure = data;
- AddressbookView *view = closure->view;
- AddressbookViewPrivate *priv = view->priv;
- ESource *source = closure->selected_source;
- GtkWidget *toplevel = closure->toplevel;
-
- g_free (closure);
-
- g_object_unref (book);
-
- if (E_BOOK_ERROR_OK == status) {
- /* Remove source */
- if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (priv->selector),
- source))
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->selector),
- source);
-
- e_source_group_remove_source (e_source_peek_group (source), source);
-
- e_source_list_sync (priv->source_list, NULL);
- }
- else {
- e_error_run (GTK_WINDOW (toplevel),
- "addressbook:remove-addressbook",
- NULL);
- }
-}
-
-static void
-delete_addressbook_cb(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- AddressbookView *view = data;
- AddressbookViewPrivate *priv = view->priv;
- ESource *selected_source;
- EBook *book;
- GError *error = NULL;
- GtkWindow *toplevel;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector));
- if (!selected_source)
- return;
-
- toplevel = (GtkWindow *)gtk_widget_get_toplevel(ep->target->widget);
-
- if (e_error_run (toplevel, "addressbook:ask-delete-addressbook", e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES)
- return;
-
- /* Remove local data */
- book = e_book_new (selected_source, &error);
- if (book) {
- BookRemovedClosure *closure = g_new (BookRemovedClosure, 1);
-
- closure->toplevel = (GtkWidget *)toplevel;
- closure->view = view;
- closure->selected_source = selected_source;
-
- if (e_book_async_remove (book, book_removed, closure)) {
- e_error_run (toplevel, "addressbook:remove-addressbook", NULL);
- g_free (closure);
- g_object_unref (book);
- }
- }
-}
-
-static void
-new_addressbook_cb(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- addressbook_config_create_new_source (gtk_widget_get_toplevel(ep->target->widget));
-}
-
-static void
-rename_addressbook_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- AddressbookView *view = data;
- ESourceSelector *selector;
-
- selector = E_SOURCE_SELECTOR (view->priv->selector);
- e_source_selector_edit_primary_selection (selector);
-}
-
-static void
-save_addressbook_cb(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- AddressbookView *view = data;
- EABView *v = get_current_view (view);
- if (v)
- eab_view_save_as (v, TRUE);
-}
-
-static void
-edit_addressbook_cb(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- AddressbookView *view = data;
- if (view)
- edit_addressbook_folder (view);
-}
-
-/* Callbacks. */
-
-static void
-primary_source_selection_changed_callback (ESourceSelector *selector,
- AddressbookView *view)
-{
- load_uri_for_selection (selector, view, FALSE);
- save_primary_selection (view);
-}
-
-static EPopupItem abv_source_popups[] = {
- { E_POPUP_ITEM, (gchar *) "10.new", (gchar *) N_("_New Address Book"), new_addressbook_cb, NULL, (gchar *) "address-book-new", 0, 0 },
- { E_POPUP_ITEM, (gchar *) "20.saveasvcard", (gchar *) N_("Save As vCard..."), save_addressbook_cb, NULL, (gchar *) "document-save-as", 0, EAB_POPUP_SOURCE_PRIMARY },
- { E_POPUP_ITEM, (gchar *) "25.rename", (gchar *) N_("_Rename..."), rename_addressbook_cb, NULL, NULL, 0, EAB_POPUP_SOURCE_PRIMARY },
-
- { E_POPUP_BAR, (gchar *) "30.bar" },
- { E_POPUP_ITEM, (gchar *) "30.delete", (gchar *) N_("_Delete"), delete_addressbook_cb, NULL, (gchar *) "edit-delete", 0, EAB_POPUP_SOURCE_USER|EAB_POPUP_SOURCE_PRIMARY },
-
- { E_POPUP_BAR, (gchar *) "99.bar" },
- { E_POPUP_ITEM, (gchar *) "99.properties", (gchar *) N_("_Properties"), edit_addressbook_cb, NULL, (gchar *) "document-properties", 0, EAB_POPUP_SOURCE_PRIMARY },
-};
-
-static void
-abv_source_popup_free(EPopup *ep, GSList *list, gpointer data)
-{
- g_slist_free(list);
-}
-
-static gboolean
-popup_event_callback(ESourceSelector *selector, ESource *source, GdkEventButton *event, AddressbookView *view)
-{
- EABPopup *ep;
- EABPopupTargetSource *t;
- GSList *menus = NULL;
- gint i;
- GtkMenu *menu;
-
- /** @HookPoint-EABPopup:Addressbook Source Selector Context Menu
- * @Id: org.gnome.evolution.addressbook.source.popup
- * @Class: org.gnome.evolution.addresbook.popup:1.0
- * @Target: EABPopupTargetSource
- *
- * The context menu on the source selector in the contacts window.
- */
-
- ep = eab_popup_new("org.gnome.evolution.addressbook.source.popup");
- t = eab_popup_target_new_source(ep, selector);
- t->target.widget = (GtkWidget *)view->priv->notebook;
-
- for (i=0;i<sizeof(abv_source_popups)/sizeof(abv_source_popups[0]);i++)
- menus = g_slist_prepend(menus, &abv_source_popups[i]);
-
- e_popup_add_items((EPopup *)ep, menus, NULL, abv_source_popup_free, view);
-
- menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time());
-
- return TRUE;
-}
-
-typedef struct
-{
- guint remove_from_source : 1;
- guint copy_done : 1;
- gint pending_removals;
-
- EContact *current_contact;
- GList *remaining_contacts;
-
- EBook *source_book;
- EBook *target_book;
-}
-MergeContext;
-
-static void
-destroy_merge_context (MergeContext *merge_context)
-{
- if (merge_context->source_book)
- g_object_unref (merge_context->source_book);
- if (merge_context->target_book)
- g_object_unref (merge_context->target_book);
-
- g_free (merge_context);
-}
-
-static void
-removed_contact_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- MergeContext *merge_context = closure;
-
- merge_context->pending_removals--;
-
- if (merge_context->copy_done && merge_context->pending_removals == 0) {
- /* Finished */
-
- destroy_merge_context (merge_context);
- }
-}
-
-static void
-merged_contact_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure)
-{
- MergeContext *merge_context = closure;
-
- if (merge_context->remove_from_source && status == E_BOOK_ERROR_OK) {
- /* Remove previous contact from source */
-
- e_book_async_remove_contact (merge_context->source_book, merge_context->current_contact,
- removed_contact_cb, merge_context);
- merge_context->pending_removals++;
- }
-
- g_object_unref (merge_context->current_contact);
-
- if (merge_context->remaining_contacts) {
- /* Copy next contact */
-
- merge_context->current_contact = merge_context->remaining_contacts->data;
- merge_context->remaining_contacts = g_list_delete_link (merge_context->remaining_contacts,
- merge_context->remaining_contacts);
- eab_merging_book_add_contact (merge_context->target_book, merge_context->current_contact,
- merged_contact_cb, merge_context);
- } else if (merge_context->pending_removals == 0) {
- /* Finished */
-
- destroy_merge_context (merge_context);
- } else {
- /* Finished, but have pending removals */
-
- merge_context->copy_done = TRUE;
- }
-}
-
-static gboolean
-selector_tree_data_dropped (ESourceSelector *selector,
- GtkSelectionData *data,
- ESource *destination,
- GdkDragAction action,
- guint info,
- AddressbookView *view)
-{
- EBook *source_book, *target_book;
- MergeContext *merge_context = NULL;
- GList *contactlist;
- EABView *v;
-
- target_book = e_book_new (destination, NULL);
- if (!target_book) {
- g_message (G_STRLOC ":Couldn't create EBook.");
- return FALSE;
- }
- e_book_open (target_book, FALSE, NULL);
-
- eab_book_and_contact_list_from_string ((gchar *)data->data, &source_book, &contactlist);
-
- v = get_current_view (view);
- g_object_get (v->model, "book",&source_book, NULL);
-
- /* Set up merge context */
-
- merge_context = g_new0 (MergeContext, 1);
-
- merge_context->source_book = source_book;
- merge_context->target_book = target_book;
-
- merge_context->current_contact = contactlist->data;
- merge_context->remaining_contacts = g_list_delete_link (contactlist, contactlist);
-
- merge_context->remove_from_source = action == GDK_ACTION_MOVE ? TRUE : FALSE;
-
- /* Start merge */
-
- eab_merging_book_add_contact (target_book, merge_context->current_contact,
- merged_contact_cb, merge_context);
-
- return TRUE;
-}
-
-static void
-destroy_callback(gpointer data, GObject *where_object_was)
-{
- AddressbookView *view = data;
- g_object_unref (view);
-}
-
-GType
-addressbook_view_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (AddressbookViewClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) addressbook_view_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EABView),
- 0, /* n_preallocs */
- (GInstanceInitFunc) addressbook_view_init,
- };
-
- type = g_type_register_static (PARENT_TYPE, "AddressbookView", &info, 0);
- }
-
- return type;
-}
-
-static void
-addressbook_view_class_init (AddressbookViewClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = addressbook_view_dispose;
-
- parent_class = g_type_class_peek_parent (klass);
-}
-
-static gboolean
-source_selector_key_press_event_callback (GtkWidget *widget, GdkEventKey *event, AddressbookView *view)
-{
- if (event->keyval == GDK_Delete) {
- /* suppress delete key press in a source selector */
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-addressbook_view_init (AddressbookView *view)
-{
- AddressbookViewPrivate *priv;
- GtkWidget *selector_scrolled_window;
- AtkObject *a11y;
-
- view->priv =
- priv = g_new0 (AddressbookViewPrivate, 1);
-
- priv->gconf_client = addressbook_component_peek_gconf_client (addressbook_component_peek ());
-
- priv->uid_to_view = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_object_unref);
- priv->uid_to_editor = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free);
-
- priv->notebook = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
-
- g_object_weak_ref (G_OBJECT (priv->notebook), destroy_callback, view);
-
- /* Create the control. */
- priv->folder_view_control = bonobo_control_new (priv->notebook);
-
- gtk_widget_show (priv->notebook);
-
- e_book_get_addressbooks (&priv->source_list, NULL);
- g_signal_connect (priv->source_list,
- "changed",
- G_CALLBACK (source_list_changed_cb), view);
-
- priv->creatable_items_handler = e_user_creatable_items_handler_new ("contacts", NULL, NULL);
- priv->menu = eab_menu_new("org.gnome.evolution.addressbook.view");
-
- g_signal_connect (priv->folder_view_control, "activate",
- G_CALLBACK (control_activate_cb), view);
-
- priv->activity_handler = e_activity_handler_new ();
-
- priv->statusbar_widget = e_task_bar_new ();
- gtk_widget_show (priv->statusbar_widget);
-
- e_activity_handler_attach_task_bar (priv->activity_handler,
- E_TASK_BAR (priv->statusbar_widget));
-
- priv->info_widget = e_info_label_new("x-office-address-book");
- e_info_label_set_info((EInfoLabel*)priv->info_widget, _("Contacts"), "");
- gtk_widget_show (priv->info_widget);
-
- priv->selector = e_source_selector_new (priv->source_list);
-
- g_signal_connect (
- priv->selector, "data-dropped",
- G_CALLBACK (selector_tree_data_dropped), view);
- gtk_drag_dest_set (priv->selector, GTK_DEST_DEFAULT_ALL, drag_types, num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE);
- a11y = gtk_widget_get_accessible (GTK_WIDGET (priv->selector));
- atk_object_set_name (a11y, _("Contact Source Selector"));
-
- e_source_selector_show_selection (E_SOURCE_SELECTOR (priv->selector), FALSE);
- gtk_widget_show (priv->selector);
-
- selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window), GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (selector_scrolled_window), priv->selector);
- gtk_widget_show (selector_scrolled_window);
-
- priv->sidebar_widget = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX (priv->sidebar_widget), priv->info_widget, FALSE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX (priv->sidebar_widget), selector_scrolled_window, TRUE, TRUE, 0);
- gtk_widget_show (priv->sidebar_widget);
-
- g_signal_connect_object (priv->selector, "primary_selection_changed",
- G_CALLBACK (primary_source_selection_changed_callback),
- G_OBJECT (view), 0);
- g_signal_connect_after (priv->selector, "key_press_event",
- G_CALLBACK (source_selector_key_press_event_callback),
- G_OBJECT (view));
- g_signal_connect_object (priv->selector, "popup_event",
- G_CALLBACK (popup_event_callback),
- G_OBJECT (view), 0);
-
- load_primary_selection (view);
- load_uri_for_selection (E_SOURCE_SELECTOR (priv->selector), view, TRUE);
-}
-
-static void
-destroy_editor (gchar *key,
- gpointer value,
- gpointer nada)
-{
- EditorUidClosure *closure = value;
-
- g_object_weak_unref (G_OBJECT (closure->editor),
- editor_weak_notify, closure);
-
- gtk_widget_destroy (GTK_WIDGET (closure->editor));
-}
-
-static void
-addressbook_view_dispose (GObject *object)
-{
- AddressbookView *view = ADDRESSBOOK_VIEW (object);
- AddressbookViewPrivate *priv = view->priv;
-
- if (view->priv) {
- if (priv->book)
- g_object_unref (priv->book);
-
- g_free(priv->passwd);
-
- if (priv->source_list)
- g_object_unref (priv->source_list);
-
- if (priv->uid_to_view)
- g_hash_table_destroy (priv->uid_to_view);
-
- if (priv->uid_to_editor) {
- g_hash_table_foreach (priv->uid_to_editor, (GHFunc)destroy_editor, NULL);
- g_hash_table_destroy (priv->uid_to_editor);
- }
-
- if (priv->creatable_items_handler)
- g_object_unref (priv->creatable_items_handler);
-
- if (priv->menu)
- g_object_unref (priv->menu);
-
- g_free (view->priv);
- view->priv = NULL;
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-typedef struct {
- EABView *view;
- ESource *source;
-} BookOpenData;
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- BookOpenData *data = closure;
- EABView *view = data->view;
- ESource *source = data->source;
-
- g_free (data);
-
- /* we always set the "source" property on the EABView, since
- we use it to reload a previously failed book. */
- g_object_set(view,
- "source", source,
- NULL);
-
- if (status == E_BOOK_ERROR_OK) {
- g_object_set(view,
- "book", book,
- NULL);
-
- if (view->model)
- eab_model_force_folder_bar_message (view->model);
- }
- else if (status != E_BOOK_ERROR_CANCELLED) {
- eab_load_error_dialog (NULL /* XXX */, source, status);
- }
-
- g_object_unref (source);
-}
-
-static void
-activate_source (AddressbookView *view,
- ESource *source)
-{
- AddressbookViewPrivate *priv = view->priv;
- const gchar *uid;
- GtkWidget *uid_view;
- EBook *book;
- BookOpenData *data;
-
- uid = e_source_peek_uid (source);
- uid_view = g_hash_table_lookup (priv->uid_to_view, uid);
-
- if (uid_view) {
- /* there is a view for this uid. make
- sure that the view actually
- contains an EBook (if it doesn't
- contain an EBook a previous load
- failed. try to load it again */
- g_object_get (uid_view,
- "book", &book,
- NULL);
-
- if (book) {
- g_object_unref (book);
- }
- else {
- g_object_get (uid_view,
- "source", &source,
- NULL);
-
- /* source can be NULL here, if
- a previous load hasn't
- actually made it to
- book_open_cb yet. */
- if (source) {
- book = e_book_new (source, NULL);
-
- if (!book) {
- g_object_unref (source);
- }
- else {
- data = g_new (BookOpenData, 1);
- data->view = g_object_ref (uid_view);
- data->source = source; /* transfer the ref we get back from g_object_get */
-
- addressbook_load (book, book_open_cb, data);
- }
- }
- }
- }
- else {
- /* we don't have a view for this uid already
- set up. */
- GtkWidget *label = gtk_label_new (uid);
- GError *error = NULL;
-
- uid_view = eab_view_new ();
-
- gtk_widget_show (uid_view);
- gtk_widget_show (label);
-
- g_object_set (uid_view, "type", EAB_VIEW_TABLE, NULL);
-
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
- uid_view,
- label);
-
- g_hash_table_insert (priv->uid_to_view, g_strdup (uid), uid_view);
-
- g_signal_connect (uid_view, "status_message",
- G_CALLBACK(set_status_message), view);
-
- g_signal_connect (uid_view, "search_result",
- G_CALLBACK(search_result), view);
-
- g_signal_connect (uid_view, "folder_bar_message",
- G_CALLBACK(set_folder_bar_message), view);
-
- g_signal_connect (uid_view, "command_state_change",
- G_CALLBACK(update_command_state), view);
-
- book = e_book_new (source, &error);
-
- if (book) {
- data = g_new (BookOpenData, 1);
- data->view = g_object_ref (uid_view);
- data->source = g_object_ref (source);
-
- addressbook_load (book, book_open_cb, data);
- }
- else {
- g_warning ("error loading addressbook : %s", error->message);
- g_error_free (error);
- }
- }
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook),
- gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook),
- uid_view));
-
- if (EAB_VIEW (uid_view)->model)
- eab_model_force_folder_bar_message (EAB_VIEW (uid_view)->model);
-
- /* change menus/toolbars to reflect the new view, assuming we are already displayed */
- if (bonobo_ui_component_get_container (bonobo_control_get_ui_component (priv->folder_view_control)) != CORBA_OBJECT_NIL) {
- eab_view_setup_menus (EAB_VIEW (uid_view), bonobo_control_get_ui_component (priv->folder_view_control));
- update_command_state (EAB_VIEW (uid_view), view);
- }
-}
-
-AddressbookView *
-addressbook_view_new (void)
-{
- return g_object_new (ADDRESSBOOK_TYPE_VIEW, NULL);
-}
-
-EActivityHandler*
-addressbook_view_peek_activity_handler (AddressbookView *view)
-{
- g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL);
-
- return view->priv->activity_handler;
-}
-
-GtkWidget*
-addressbook_view_peek_info_label (AddressbookView *view)
-{
- g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL);
-
- return view->priv->info_widget;
-}
-
-GtkWidget*
-addressbook_view_peek_sidebar (AddressbookView *view)
-{
- g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL);
-
- return view->priv->sidebar_widget;
-}
-
-GtkWidget*
-addressbook_view_peek_statusbar (AddressbookView *view)
-{
- g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL);
-
- return view->priv->statusbar_widget;
-}
-
-BonoboControl*
-addressbook_view_peek_folder_view (AddressbookView *view)
-{
- g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL);
-
- return view->priv->folder_view_control;
-}
-
-void
-addressbook_view_edit_contact (AddressbookView* view,
- const gchar * source_uid,
- const gchar * contact_uid)
-{
- AddressbookViewPrivate *priv = view->priv;
-
- ESource* source = NULL;
- EContact* contact = NULL;
- EBook* book = NULL;
-
- if (!source_uid || !contact_uid)
- return;
-
- source = e_source_list_peek_source_by_uid (priv->source_list, source_uid);
- if (!source)
- return;
-
- /* FIXME: Can I unref this book? */
- book = e_book_new (source, NULL);
- if (!book)
- return;
-
- if (!e_book_open (book, TRUE, NULL)) {
- g_object_unref (book);
- return;
- }
-
- e_book_get_contact (book, contact_uid, &contact, NULL);
-
- if (!contact) {
- g_object_unref (book);
- return;
- }
- eab_show_contact_editor (book, contact, FALSE, FALSE);
- g_object_unref (contact);
- g_object_unref (book);
-}
diff --git a/addressbook/gui/component/addressbook-view.h b/addressbook/gui/component/addressbook-view.h
deleted file mode 100644
index 38554b7acf..0000000000
--- a/addressbook/gui/component/addressbook-view.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _ADDRESSBOOK_VIEW_H_
-#define _ADDRESSBOOK_VIEW_H_
-
-#include <bonobo/bonobo-control.h>
-
-#define ADDRESSBOOK_TYPE_VIEW (addressbook_view_get_type ())
-#define ADDRESSBOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ADDRESSBOOK_TYPE_VIEW, AddressbookView))
-#define ADDRESSBOOK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ADDRESSBOOK_TYPE_VIEW, AddressbookViewClass))
-#define ADDRESSBOOK_IS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ADDRESSBOOK_TYPE_VIEW))
-#define ADDRESSBOOK_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), ADDRESSBOOK_TYPE_VIEW))
-
-typedef struct _AddressbookView AddressbookView;
-typedef struct _AddressbookViewPrivate AddressbookViewPrivate;
-typedef struct _AddressbookViewClass AddressbookViewClass;
-
-struct _AddressbookView {
- GObject parent;
-
- AddressbookViewPrivate *priv;
-};
-
-struct _AddressbookViewClass {
- GObjectClass parent_class;
-};
-
-GType addressbook_view_get_type (void);
-
-AddressbookView *addressbook_view_new (void);
-
-EActivityHandler *addressbook_view_peek_activity_handler (AddressbookView *view);
-GtkWidget *addressbook_view_peek_info_label (AddressbookView *view);
-GtkWidget *addressbook_view_peek_sidebar (AddressbookView *view);
-GtkWidget *addressbook_view_peek_statusbar (AddressbookView *view);
-BonoboControl *addressbook_view_peek_folder_view (AddressbookView *view);
-
-void addressbook_view_edit_contact (AddressbookView* view,
- const gchar * source_id,
- const gchar * contact_id);
-
-#endif /* _ADDRESSBOOK_VIEW_H_ */
diff --git a/addressbook/gui/component/autocompletion-config.c b/addressbook/gui/component/autocompletion-config.c
deleted file mode 100644
index ebb2381e1e..0000000000
--- a/addressbook/gui/component/autocompletion-config.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * e-shell-config-autocompletion.h - Configuration page for addressbook autocompletion.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-
-#include "autocompletion-config.h"
-
-#include "Evolution.h"
-
-#include <bonobo/bonobo-exception.h>
-
-#include <libedataserver/e-source-list.h>
-#include <libedataserverui/e-source-selector.h>
-#include <libedataserverui/e-name-selector-entry.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-#include "e-util/e-datetime-format.h"
-
-
-typedef struct {
- EvolutionConfigControl *config_control;
-
- GtkWidget *control_widget;
-
- ESourceList *source_list;
- GConfClient *gconf;
-} AutocompletionConfig;
-
-static void
-source_selection_changed (ESourceSelector *selector,
- AutocompletionConfig *ac)
-{
- GSList *selection;
- GSList *l;
- GSList *groups;
-
- /* first we clear all the completion flags from all sources */
- for (groups = e_source_list_peek_groups (ac->source_list); groups; groups = groups->next) {
- ESourceGroup *group = E_SOURCE_GROUP (groups->data);
- GSList *sources;
- for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) {
- ESource *source = E_SOURCE (sources->data);
-
- e_source_set_property (source, "completion", NULL);
- }
- }
-
- /* then we loop over the selector's selection, setting the
- property on those sources */
- selection = e_source_selector_get_selection (selector);
- for (l = selection; l; l = l->next) {
- e_source_set_property (E_SOURCE (l->data), "completion", "true");
- }
- e_source_selector_free_selection (selection);
-
- e_source_list_sync (ac->source_list, NULL); /* XXX we should pop up a dialog if this fails */
-}
-
-static void
-config_control_destroy_notify (gpointer data,
- GObject *where_the_config_control_was)
-{
- AutocompletionConfig *ac = (AutocompletionConfig *) data;
-
- g_object_unref (ac->source_list);
- g_object_unref (ac->gconf);
-
- g_free (ac);
-}
-
-static void
-initialize_selection (AutocompletionConfig *ac)
-{
- GSList *groups;
-
- for (groups = e_source_list_peek_groups (ac->source_list); groups; groups = groups->next) {
- ESourceGroup *group = E_SOURCE_GROUP (groups->data);
- GSList *sources;
- for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) {
- ESource *source = E_SOURCE (sources->data);
- const gchar *completion = e_source_get_property (source, "completion");
- if (completion && !g_ascii_strcasecmp (completion, "true"))
- e_source_selector_select_source (E_SOURCE_SELECTOR (ac->control_widget),
- source);
- }
- }
-}
-
-static GtkWidget *
-add_section (GtkWidget *vbox, const gchar *caption, gboolean expand)
-{
- GtkWidget *label, *hbox, *itembox;
- gchar *txt;
-
- g_return_val_if_fail (vbox != NULL, NULL);
- g_return_val_if_fail (caption != NULL, NULL);
-
- txt = g_strconcat ("<b>", caption, "</b>", NULL);
-
- label = gtk_label_new (NULL);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_label_set_markup (GTK_LABEL (label), txt);
-
- g_free (txt);
-
- /* bold caption of the section */
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-
- hbox = gtk_hbox_new (FALSE, 12);
-
- /* space on the left for the items in the section */
- gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (""), FALSE, FALSE, 0);
-
- /* itembox, here will all section items go */
- itembox = gtk_vbox_new (FALSE, 2);
- gtk_box_pack_start (GTK_BOX (hbox), itembox, TRUE, TRUE, 0);
-
- gtk_box_pack_start (GTK_BOX (vbox), hbox, expand, expand, 0);
-
- return itembox;
-}
-
-static void
-show_address_check_toggled_cb (GtkToggleButton *check, AutocompletionConfig *ac)
-{
- g_return_if_fail (check != NULL);
- g_return_if_fail (ac != NULL);
- g_return_if_fail (ac->gconf != NULL);
-
- gconf_client_set_bool (ac->gconf, FORCE_SHOW_ADDRESS, gtk_toggle_button_get_active (check), NULL);
-}
-
-EvolutionConfigControl*
-autocompletion_config_control_new (void)
-{
- AutocompletionConfig *ac;
- CORBA_Environment ev;
- GtkWidget *scrolledwin, *vbox, *itembox, *w, *table;
-
- ac = g_new0 (AutocompletionConfig, 1);
-
- CORBA_exception_init (&ev);
-
- ac->gconf = gconf_client_get_default ();
-
- vbox = gtk_vbox_new (FALSE, 6);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
-
- itembox = add_section (vbox, _("Autocompletion"), FALSE);
-
- w = gtk_check_button_new_with_mnemonic (_("Always _show address of the autocompleted contact"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), gconf_client_get_bool (ac->gconf, FORCE_SHOW_ADDRESS, NULL));
- g_signal_connect (w, "toggled", (GCallback)show_address_check_toggled_cb, ac);
- gtk_box_pack_start (GTK_BOX (itembox), w, FALSE, FALSE, 0);
-
- itembox = add_section (vbox, _("Date/Time Format"), FALSE);
- table = gtk_table_new (1, 3, FALSE);
- gtk_box_pack_start (GTK_BOX (itembox), table, TRUE, TRUE, 0);
- e_datetime_format_add_setup_widget (table, 0, "addressbook", "table", DTFormatKindDateTime, _("Table column:"));
-
- itembox = add_section (vbox, _("Look up in address books"), TRUE);
-
- ac->source_list = e_source_list_new_for_gconf_default ("/apps/evolution/addressbook/sources");
- /* XXX should we watch for the source list to change and
- update it in the control? what about our local changes? */
- /* g_signal_connect (ac->source_list, "changed", G_CALLBACK (source_list_changed), ac); */
-
- scrolledwin = gtk_scrolled_window_new (NULL, NULL);
-
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwin),
- GTK_SHADOW_IN);
-
- ac->control_widget = e_source_selector_new (ac->source_list);
-
- gtk_container_add (GTK_CONTAINER (scrolledwin), ac->control_widget);
-
- initialize_selection (ac);
-
- gtk_widget_show (ac->control_widget);
- gtk_widget_show (scrolledwin);
-
- gtk_widget_show_all (vbox);
- gtk_box_pack_start (GTK_BOX (itembox), scrolledwin, TRUE, TRUE, 0);
-
- ac->config_control = evolution_config_control_new (vbox);
-
- g_signal_connect (ac->control_widget, "selection_changed",
- G_CALLBACK (source_selection_changed), ac);
-
- g_object_weak_ref (G_OBJECT (ac->config_control), config_control_destroy_notify, ac);
-
- CORBA_exception_free (&ev);
-
- return ac->config_control;
-}
-
diff --git a/addressbook/gui/component/component-factory.c b/addressbook/gui/component/component-factory.c
deleted file mode 100644
index eddabd7b48..0000000000
--- a/addressbook/gui/component/component-factory.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * component-factory.c - Factory for Evolution's Addressbook component.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <config.h>
-
-#include <string.h>
-#include "addressbook.h"
-#include "addressbook-component.h"
-#include "addressbook-config.h"
-#include "addressbook-view.h"
-#include "autocompletion-config.h"
-#include "eab-popup-control.h"
-#ifdef ENABLE_SMIME
-#include "smime/gui/certificate-manager.h"
-#endif
-#include <bonobo/bonobo-shlib-factory.h>
-
-
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_Factory:" BASE_VERSION
-
-#define COMPONENT_ID "OAFIID:GNOME_Evolution_Addressbook_Component:" BASE_VERSION
-#define ADDRESS_POPUP_ID "OAFIID:GNOME_Evolution_Addressbook_AddressPopup:" BASE_VERSION
-#define COMPLETION_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_Autocompletion_ConfigControl:" BASE_VERSION
-#define CERTIFICATE_MANAGER_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_SMime_CertificateManager_ConfigControl:" BASE_VERSION
-
-#define d(x)
-
-
-static BonoboObject *
-factory (BonoboGenericFactory *factory,
- const gchar *component_id,
- gpointer closure)
-{
- d(printf ("asked to activate component_id `%s'\n", component_id));
-
- if (strcmp (component_id, COMPONENT_ID) == 0) {
- BonoboObject *object = BONOBO_OBJECT (addressbook_component_peek ());
- bonobo_object_ref (object);
- return object;
- }
- if (strcmp (component_id, ADDRESS_POPUP_ID) == 0)
- return BONOBO_OBJECT (eab_popup_control_new ());
- if (strcmp (component_id, COMPLETION_CONFIG_CONTROL_ID) == 0)
- return BONOBO_OBJECT (autocompletion_config_control_new ());
-#ifdef ENABLE_SMIME
- if (strcmp (component_id, CERTIFICATE_MANAGER_CONFIG_CONTROL_ID) == 0)
- return BONOBO_OBJECT (certificate_manager_config_control_new ());
-#endif
-
- g_warning (FACTORY_ID ": Don't know what to do with %s", component_id);
- return NULL;
-}
-
-BONOBO_ACTIVATION_SHLIB_FACTORY (FACTORY_ID, "Evolution Addressbook component factory", factory, NULL)
diff --git a/addressbook/gui/contact-editor/Makefile.am b/addressbook/gui/contact-editor/Makefile.am
index 36ba4c90a8..29ddb6ee9c 100644
--- a/addressbook/gui/contact-editor/Makefile.am
+++ b/addressbook/gui/contact-editor/Makefile.am
@@ -29,10 +29,13 @@ libecontacteditor_la_SOURCES = \
libecontacteditor_la_LDFLAGS = $(NO_UNDEFINED)
-libecontacteditor_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/e-util/libeutil.la \
+libecontacteditor_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \
+ $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \
+ $(top_builddir)/addressbook/printing/libecontactprint.la \
$(EVOLUTION_ADDRESSBOOK_LIBS)
glade_DATA = \
diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c
index fc4c8ff8df..007436e7da 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.c
+++ b/addressbook/gui/contact-editor/e-contact-editor.c
@@ -33,7 +33,6 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libedataserverui/e-categories-dialog.h>
-#include <misc/e-gui-utils.h>
#include <libebook/e-address-western.h>
#include <libedataserverui/e-category-completion.h>
@@ -41,7 +40,7 @@
#include <camel/camel.h>
-#include "addressbook/gui/component/addressbook.h"
+#include "addressbook/util/addressbook.h"
#include "addressbook/printing/e-contact-print.h"
#include "addressbook/gui/widgets/eab-gui-util.h"
#include "e-util/e-util.h"
@@ -49,9 +48,9 @@
#include "misc/e-dateedit.h"
#include "misc/e-image-chooser.h"
#include "misc/e-url-entry.h"
-#include "shell/evolution-shell-component-utils.h"
#include "e-util/e-icon-factory.h"
#include "e-util/e-util-private.h"
+#include "shell/e-shell.h"
#include "eab-contact-merging.h"
@@ -198,6 +197,54 @@ static const gint email_default [] = { 0, 1, 2, 2 };
#define STRING_IS_EMPTY(x) (!(x) || !(*(x)))
#define STRING_MAKE_NON_NULL(x) ((x) ? (x) : "")
+static void
+e_contact_editor_contact_added (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
+{
+ if (status == E_BOOK_ERROR_OK)
+ return;
+
+ if (status == E_BOOK_ERROR_CANCELLED)
+ return;
+
+ eab_error_dialog (_("Error adding contact"), status);
+}
+
+static void
+e_contact_editor_contact_modified (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
+{
+ if (status == E_BOOK_ERROR_OK)
+ return;
+
+ if (status == E_BOOK_ERROR_CANCELLED)
+ return;
+
+ eab_error_dialog (_("Error modifying contact"), status);
+}
+
+static void
+e_contact_editor_contact_deleted (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
+{
+ if (status == E_BOOK_ERROR_OK)
+ return;
+
+ if (status == E_BOOK_ERROR_CANCELLED)
+ return;
+
+ eab_error_dialog (_("Error removing contact"), status);
+}
+
+static void
+e_contact_editor_closed (EABEditor *editor)
+{
+ g_object_unref (editor);
+}
+
GType
e_contact_editor_get_type (void)
{
@@ -241,6 +288,10 @@ e_contact_editor_class_init (EContactEditorClass *klass)
editor_class->save_contact = e_contact_editor_save_contact;
editor_class->is_changed = e_contact_editor_is_changed;
editor_class->get_window = e_contact_editor_get_window;
+ editor_class->contact_added = e_contact_editor_contact_added;
+ editor_class->contact_modified = e_contact_editor_contact_modified;
+ editor_class->contact_deleted = e_contact_editor_contact_deleted;
+ editor_class->editor_closed = e_contact_editor_closed;
g_object_class_install_property (object_class, PROP_SOURCE_BOOK,
g_param_spec_object ("source_book",
@@ -3322,6 +3373,7 @@ static void
e_contact_editor_init (EContactEditor *e_contact_editor)
{
GladeXML *gui;
+ EShell *shell;
GtkWidget *widget, *label;
GtkEntryCompletion *completion;
gchar *gladefile;
@@ -3399,6 +3451,10 @@ e_contact_editor_init (EContactEditor *e_contact_editor)
/* show window */
gtk_widget_show (e_contact_editor->app);
+
+ /* FIXME Shell should be passed in. */
+ shell = e_shell_get_default ();
+ e_shell_watch_window (shell, GTK_WINDOW (e_contact_editor->app));
}
static void
@@ -3455,7 +3511,7 @@ static void
supported_fields_cb (EBook *book, EBookStatus status,
EList *fields, EContactEditor *ce)
{
- if (!g_slist_find ((GSList*)eab_editor_get_all_editors (), ce)) {
+ if (!g_slist_find (eab_editor_get_all_editors (), ce)) {
g_warning ("supported_fields_cb called for book that's still around, but contact editor that's been destroyed.");
return;
}
@@ -3474,7 +3530,7 @@ required_fields_cb (EBook *book, EBookStatus status,
EList *fields, EContactEditor *ce)
{
- if (!g_slist_find ((GSList*)eab_editor_get_all_editors (), ce)) {
+ if (!g_slist_find (eab_editor_get_all_editors (), ce)) {
g_warning ("supported_fields_cb called for book that's still around, but contact editor that's been destroyed.");
return;
}
@@ -3485,30 +3541,22 @@ required_fields_cb (EBook *book, EBookStatus status,
}
-static void
-contact_editor_destroy_notify (gpointer data,
- GObject *where_the_object_was)
+EABEditor *
+e_contact_editor_new (EShell *shell,
+ EBook *book,
+ EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable)
{
- eab_editor_remove (EAB_EDITOR (data));
-}
-
-EContactEditor *
-e_contact_editor_new (EBook *book,
- EContact *contact,
- gboolean is_new_contact,
- gboolean editable)
-{
- EContactEditor *ce;
+ EABEditor *editor;
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
g_return_val_if_fail (E_IS_BOOK (book), NULL);
g_return_val_if_fail (E_IS_CONTACT (contact), NULL);
- ce = g_object_new (E_TYPE_CONTACT_EDITOR, NULL);
+ editor = g_object_new (E_TYPE_CONTACT_EDITOR, "shell", shell, NULL);
- eab_editor_add (EAB_EDITOR (ce));
- g_object_weak_ref (G_OBJECT (ce), contact_editor_destroy_notify, ce);
-
- g_object_set (ce,
+ g_object_set (editor,
"source_book", book,
"contact", contact,
"is_new_contact", is_new_contact,
@@ -3516,9 +3564,10 @@ e_contact_editor_new (EBook *book,
NULL);
if (book)
- e_book_async_get_supported_fields (book, (EBookEListCallback)supported_fields_cb, ce);
+ e_book_async_get_supported_fields (
+ book, (EBookEListCallback)supported_fields_cb, editor);
- return ce;
+ return editor;
}
static void
diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h
index cdd9c2e8da..9a83831eff 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.h
+++ b/addressbook/gui/contact-editor/e-contact-editor.h
@@ -23,7 +23,6 @@
#ifndef __E_CONTACT_EDITOR_H__
#define __E_CONTACT_EDITOR_H__
-#include <bonobo/bonobo-ui-component.h>
#include <glade/glade.h>
#include "addressbook/gui/contact-editor/eab-editor.h"
@@ -62,9 +61,6 @@ struct _EContactEditor
EBook *target_book;
EContact *contact;
- /* UI handler */
- BonoboUIComponent *uic;
-
GladeXML *gui;
GtkWidget *app;
@@ -110,11 +106,12 @@ struct _EContactEditorClass
EABEditorClass parent_class;
};
-EContactEditor *e_contact_editor_new (EBook *book,
- EContact *contact,
- gboolean is_new_contact,
- gboolean editable);
-GType e_contact_editor_get_type (void);
+GType e_contact_editor_get_type (void);
+EABEditor *e_contact_editor_new (EShell *shell,
+ EBook *book,
+ EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable);
G_END_DECLS
diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c
index 0f6552ba18..bb40e9a79d 100644
--- a/addressbook/gui/contact-editor/e-contact-quick-add.c
+++ b/addressbook/gui/contact-editor/e-contact-quick-add.c
@@ -28,7 +28,7 @@
#include <libebook/e-book.h>
#include <libebook/e-contact.h>
#include <libedataserverui/e-source-combo-box.h>
-#include <addressbook/gui/component/addressbook.h>
+#include <addressbook/util/addressbook.h>
#include <addressbook/util/eab-book-util.h>
#include "e-contact-editor.h"
#include "e-contact-quick-add.h"
@@ -49,7 +49,7 @@ struct _QuickAdd {
GtkWidget *dialog;
GtkWidget *name_entry;
GtkWidget *email_entry;
- GtkWidget *option_menu;
+ GtkWidget *combo_box;
gint refs;
@@ -193,7 +193,12 @@ ce_have_book (EBook *book, EBookStatus status, gpointer closure)
g_warning ("Couldn't open local address book.");
quick_add_unref (qa);
} else {
- EContactEditor *contact_editor = e_contact_editor_new (book, qa->contact, TRUE, TRUE /* XXX */);
+ EShell *shell;
+ EABEditor *contact_editor;
+
+ shell = e_shell_get_default ();
+ contact_editor = e_contact_editor_new (
+ shell, book, qa->contact, TRUE, TRUE /* XXX */);
/* mark it as changed so the Save buttons are enabled when we bring up the dialog. */
g_object_set (contact_editor,
@@ -284,7 +289,7 @@ sanitize_widgets (QuickAdd *qa)
g_return_if_fail (qa->dialog != NULL);
/* do not call here e_book_is_writable (qa->book), because it requires opened book, which takes time for remote books */
- enabled = qa->book != NULL && e_source_combo_box_get_active_uid (E_SOURCE_COMBO_BOX (qa->option_menu));
+ enabled = qa->book != NULL && e_source_combo_box_get_active_uid (E_SOURCE_COMBO_BOX (qa->combo_box));
gtk_dialog_set_response_sensitive (GTK_DIALOG (qa->dialog), QUICK_ADD_RESPONSE_EDIT_FULL, enabled);
gtk_dialog_set_response_sensitive (GTK_DIALOG (qa->dialog), GTK_RESPONSE_OK, enabled);
@@ -355,13 +360,13 @@ build_quick_add_dialog (QuickAdd *qa)
gconf_client = gconf_client_get_default ();
source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/addressbook/sources");
g_object_unref (gconf_client);
- qa->option_menu = e_source_combo_box_new (source_list);
+ qa->combo_box = e_source_combo_box_new (source_list);
book = e_book_new_default_addressbook (NULL);
e_source_combo_box_set_active (
- E_SOURCE_COMBO_BOX (qa->option_menu),
+ E_SOURCE_COMBO_BOX (qa->combo_box),
e_book_get_source (book));
- if (!e_source_combo_box_get_active_uid (E_SOURCE_COMBO_BOX (qa->option_menu))) {
+ if (!e_source_combo_box_get_active_uid (E_SOURCE_COMBO_BOX (qa->combo_box))) {
/* this means the e_book_new_default_addressbook didn't find any "default" nor "system" source,
and created new one for us. That is wrong, choose one from combo instead. */
@@ -371,9 +376,9 @@ build_quick_add_dialog (QuickAdd *qa)
}
book = e_book_new (e_source_list_peek_source_any (source_list), NULL);
- e_source_combo_box_set_active (E_SOURCE_COMBO_BOX (qa->option_menu), e_book_get_source (book));
+ e_source_combo_box_set_active (E_SOURCE_COMBO_BOX (qa->combo_box), e_book_get_source (book));
- if (!e_source_combo_box_get_active_uid (E_SOURCE_COMBO_BOX (qa->option_menu))) {
+ if (!e_source_combo_box_get_active_uid (E_SOURCE_COMBO_BOX (qa->combo_box))) {
/* Does it failed again? What is going on? */
if (book)
g_object_unref (book);
@@ -386,9 +391,9 @@ build_quick_add_dialog (QuickAdd *qa)
qa->book = NULL;
}
qa->book = book;
- source_changed (E_SOURCE_COMBO_BOX (qa->option_menu), qa);
+ source_changed (E_SOURCE_COMBO_BOX (qa->combo_box), qa);
g_signal_connect (
- qa->option_menu, "changed",
+ qa->combo_box, "changed",
G_CALLBACK (source_changed), qa);
g_object_unref (source_list);
@@ -420,13 +425,13 @@ build_quick_add_dialog (QuickAdd *qa)
GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
label = gtk_label_new_with_mnemonic (_("_Select Address Book"));
- gtk_label_set_mnemonic_widget ((GtkLabel *)label, qa->option_menu);
+ gtk_label_set_mnemonic_widget ((GtkLabel *)label, qa->combo_box);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (table, label,
0, 1, 2, 3,
GTK_FILL, 0, xpad, ypad);
- gtk_table_attach (table, qa->option_menu,
+ gtk_table_attach (table, qa->combo_box,
1, 2, 2, 3,
GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
diff --git a/addressbook/gui/contact-editor/eab-editor.c b/addressbook/gui/contact-editor/eab-editor.c
index 19c3d9c7e3..554db9aa7b 100644
--- a/addressbook/gui/contact-editor/eab-editor.c
+++ b/addressbook/gui/contact-editor/eab-editor.c
@@ -28,16 +28,22 @@
#include <glib/gi18n.h>
#include "eab-editor.h"
-#include "addressbook/gui/widgets/eab-gui-util.h"
#include "e-util/e-util.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
+
+#define EAB_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_EDITOR, EABEditorPrivate))
+
+struct _EABEditorPrivate {
+ EShell *shell;
+};
-static void eab_editor_default_show (EABEditor *editor);
-static void eab_editor_default_raise (EABEditor *editor);
-static void eab_editor_default_close (EABEditor *editor);
-static void eab_editor_class_init (EABEditorClass *klass);
-static void eab_editor_init (EABEditor *editor);
+enum {
+ PROP_0,
+ PROP_SHELL
+};
-/* Signal IDs */
enum {
CONTACT_ADDED,
CONTACT_MODIFIED,
@@ -46,97 +52,125 @@ enum {
LAST_SIGNAL
};
-static GSList *all_editors = NULL;
-
-static GtkObjectClass *parent_class = NULL;
+static GSList *all_editors;
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
-static guint editor_signals[LAST_SIGNAL];
-
-GType
-eab_editor_get_type (void)
+static void
+eab_editor_quit_requested_cb (EABEditor *editor,
+ EShell *shell)
{
- static GType editor_type = 0;
-
- if (!editor_type) {
- static const GTypeInfo editor_info = {
- sizeof (EABEditorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) eab_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EABEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) eab_editor_init,
- };
+ GtkWindow *window;
- editor_type = g_type_register_static (G_TYPE_OBJECT, "EABEditor", &editor_info, 0);
- }
+ window = eab_editor_get_window (editor);
- return editor_type;
+ eab_editor_raise (editor);
+ if (!eab_editor_prompt_to_save_changes (editor, window))
+ e_shell_cancel_quit (shell);
}
static void
-eab_editor_default_show (EABEditor *editor)
+eab_editor_set_shell (EABEditor *editor,
+ EShell *shell)
{
- g_warning ("abstract eab_editor_show called");
+ g_return_if_fail (editor->priv->shell == NULL);
+ g_return_if_fail (E_IS_SHELL (shell));
+
+ editor->priv->shell = g_object_ref (shell);
+
+ g_signal_connect_swapped (
+ shell, "quit-requested",
+ G_CALLBACK (eab_editor_quit_requested_cb), editor);
}
static void
-eab_editor_default_close (EABEditor *editor)
+eab_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- g_warning ("abstract eab_editor_close called");
+ switch (property_id) {
+ case PROP_SHELL:
+ eab_editor_set_shell (
+ EAB_EDITOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-eab_editor_default_raise (EABEditor *editor)
+eab_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- g_warning ("abstract eab_editor_raise called");
+ switch (property_id) {
+ case PROP_SHELL:
+ g_value_set_object (
+ value, eab_editor_get_shell (
+ EAB_EDITOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-eab_editor_default_save_contact (EABEditor *editor, gboolean should_close)
+eab_editor_dispose (GObject *object)
{
- g_warning ("abstract eab_editor_save_contact called");
-}
+ EABEditorPrivate *priv;
-static gboolean
-eab_editor_default_is_valid (EABEditor *editor)
-{
- g_warning ("abstract eab_editor_is_valid called");
- return FALSE;
-}
+ priv = EAB_EDITOR_GET_PRIVATE (object);
-static gboolean
-eab_editor_default_is_changed (EABEditor *editor)
-{
- g_warning ("abstract eab_editor_is_changed called");
- return FALSE;
-}
+ if (priv->shell != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->shell, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->shell);
+ priv->shell = NULL;
+ }
-static GtkWindow*
-eab_editor_default_get_window (EABEditor *editor)
-{
- g_warning ("abstract eab_editor_get_window called");
- return NULL;
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-eab_editor_class_init (EABEditorClass *klass)
+eab_editor_finalize (GObject *object)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ all_editors = g_slist_remove (all_editors, object);
- parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
- klass->show = eab_editor_default_show;
- klass->close = eab_editor_default_close;
- klass->raise = eab_editor_default_raise;
- klass->save_contact = eab_editor_default_save_contact;
- klass->is_valid = eab_editor_default_is_valid;
- klass->is_changed = eab_editor_default_is_changed;
- klass->get_window = eab_editor_default_get_window;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
- editor_signals[CONTACT_ADDED] =
+static void
+eab_editor_class_init (EABEditorClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EABEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = eab_editor_set_property;
+ object_class->get_property = eab_editor_get_property;
+ object_class->dispose = eab_editor_dispose;
+ object_class->finalize = eab_editor_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ _("Shell"),
+ _("The EShell singleton"),
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[CONTACT_ADDED] =
g_signal_new ("contact_added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@@ -146,7 +180,7 @@ eab_editor_class_init (EABEditorClass *klass)
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
- editor_signals[CONTACT_MODIFIED] =
+ signals[CONTACT_MODIFIED] =
g_signal_new ("contact_modified",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@@ -156,7 +190,7 @@ eab_editor_class_init (EABEditorClass *klass)
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
- editor_signals[CONTACT_DELETED] =
+ signals[CONTACT_DELETED] =
g_signal_new ("contact_deleted",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@@ -166,7 +200,7 @@ eab_editor_class_init (EABEditorClass *klass)
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
- editor_signals[EDITOR_CLOSED] =
+ signals[EDITOR_CLOSED] =
g_signal_new ("editor_closed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@@ -179,78 +213,143 @@ eab_editor_class_init (EABEditorClass *klass)
static void
eab_editor_init (EABEditor *editor)
{
+ editor->priv = EAB_EDITOR_GET_PRIVATE (editor);
+
+ all_editors = g_slist_prepend (all_editors, editor);
}
-
+GType
+eab_editor_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EABEditorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) eab_editor_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EABEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) eab_editor_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EABEditor", &type_info,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+EShell *
+eab_editor_get_shell (EABEditor *editor)
+{
+ g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL);
+
+ return E_SHELL (editor->priv->shell);
+}
+
+GSList *
+eab_editor_get_all_editors (void)
+{
+ return all_editors;
+}
void
eab_editor_show (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_if_fail (EAB_IS_EDITOR (editor));
- if (EAB_EDITOR_GET_CLASS(editor)->show)
- EAB_EDITOR_GET_CLASS(editor)->show (editor);
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->show != NULL);
+
+ class->show (editor);
}
void
eab_editor_close (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_if_fail (EAB_IS_EDITOR (editor));
- if (EAB_EDITOR_GET_CLASS(editor)->close)
- EAB_EDITOR_GET_CLASS(editor)->close (editor);
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->close != NULL);
+
+ class->close (editor);
}
void
eab_editor_raise (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_if_fail (EAB_IS_EDITOR (editor));
- if (EAB_EDITOR_GET_CLASS(editor)->raise)
- EAB_EDITOR_GET_CLASS(editor)->raise (editor);
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->raise != NULL);
+
+ class->raise (editor);
}
void
eab_editor_save_contact (EABEditor *editor, gboolean should_close)
{
+ EABEditorClass *class;
+
g_return_if_fail (EAB_IS_EDITOR (editor));
- if (EAB_EDITOR_GET_CLASS(editor)->save_contact)
- EAB_EDITOR_GET_CLASS(editor)->save_contact (editor, should_close);
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->save_contact != NULL);
+
+ class->save_contact (editor, should_close);
}
gboolean
eab_editor_is_changed (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE);
- if (EAB_EDITOR_GET_CLASS(editor)->is_changed)
- return EAB_EDITOR_GET_CLASS(editor)->is_changed (editor);
- else
- return FALSE;
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->is_changed != NULL, FALSE);
+
+ return class->is_changed (editor);
}
gboolean
eab_editor_is_valid (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE);
- if (EAB_EDITOR_GET_CLASS(editor)->is_valid)
- return EAB_EDITOR_GET_CLASS(editor)->is_valid (editor);
- else
- return FALSE;
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->is_valid != NULL, FALSE);
+
+ return class->is_valid (editor);
}
GtkWindow*
eab_editor_get_window (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL);
- if (EAB_EDITOR_GET_CLASS(editor)->get_window)
- return EAB_EDITOR_GET_CLASS(editor)->get_window (editor);
- else
- return NULL;
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->get_window != NULL, NULL);
+
+ return class->get_window (editor);
}
+
/* This function prompts for saving if editor conents are in changed state and
save or discards or cancels(just returns with out doing anything) according to user input.
Editor gets destoryed in case of save and discard case.
@@ -280,108 +379,37 @@ eab_editor_prompt_to_save_changes (EABEditor *editor, GtkWindow *window)
}
}
-gboolean
-eab_editor_request_close_all (void)
-{
- GSList *p;
- GSList *pnext;
- gboolean retval;
-
- retval = TRUE;
- for (p = all_editors; p != NULL; p = pnext) {
- EABEditor *editor = EAB_EDITOR (p->data);
- GtkWindow *window = eab_editor_get_window (editor);
-
- pnext = p->next;
-
- eab_editor_raise (editor);
- if (! eab_editor_prompt_to_save_changes (editor, window)) {
- retval = FALSE;
- break;
- }
- }
-
- return retval;
-}
-
-const GSList*
-eab_editor_get_all_editors (void)
-{
- return all_editors;
-}
-
-gboolean
-eab_editor_confirm_delete (GtkWindow *parent, gboolean plural, gboolean is_list, gchar *name)
-{
- GtkWidget *dialog;
- gint result;
- gchar *msg;
-
- if (is_list) {
- /* contact list(s) */
- if (!plural)
- msg = g_strdup_printf (_("Are you sure you want\nto delete contact list (%s)?"),
- name?name:"");
- else
- msg = g_strdup (_("Are you sure you want\nto delete these contact lists?"));
- }
- else {
- /* contact(s) */
- if (!plural)
- msg = g_strdup_printf (_("Are you sure you want\nto delete contact (%s)?"),
- name?name:"");
- else
- msg = g_strdup (_("Are you sure you want\nto delete these contacts?"));
- }
-
- dialog = gtk_message_dialog_new (parent,
- 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- "%s",
- msg);
- g_free (msg);
-
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
- NULL);
-
- result = gtk_dialog_run(GTK_DIALOG (dialog));
-
- gtk_widget_destroy (dialog);
-
- return (result == GTK_RESPONSE_ACCEPT);
-}
-
void
-eab_editor_contact_added (EABEditor *editor, EBookStatus status, EContact *contact)
+eab_editor_contact_added (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
- g_signal_emit (editor, editor_signals[CONTACT_ADDED], 0,
- status, contact);
+ g_signal_emit (editor, signals[CONTACT_ADDED], 0, status, contact);
}
void
-eab_editor_contact_modified (EABEditor *editor, EBookStatus status, EContact *contact)
+eab_editor_contact_modified (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
- g_signal_emit (editor, editor_signals[CONTACT_MODIFIED], 0,
- status, contact);
+ g_signal_emit (editor, signals[CONTACT_MODIFIED], 0, status, contact);
}
void
-eab_editor_contact_deleted (EABEditor *editor, EBookStatus status, EContact *contact)
+eab_editor_contact_deleted (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
- g_signal_emit (editor, editor_signals[CONTACT_DELETED], 0,
- status, contact);
+ g_signal_emit (editor, signals[CONTACT_DELETED], 0, status, contact);
}
void
@@ -389,21 +417,5 @@ eab_editor_closed (EABEditor *editor)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
- g_signal_emit (editor, editor_signals[EDITOR_CLOSED], 0);
-}
-
-void
-eab_editor_add (EABEditor *editor)
-{
- g_return_if_fail (EAB_IS_EDITOR (editor));
-
- all_editors = g_slist_prepend (all_editors, editor);
-}
-
-void
-eab_editor_remove (EABEditor *editor)
-{
- g_return_if_fail (EAB_IS_EDITOR (editor));
-
- all_editors = g_slist_remove (all_editors, editor);
+ g_signal_emit (editor, signals[EDITOR_CLOSED], 0);
}
diff --git a/addressbook/gui/contact-editor/eab-editor.h b/addressbook/gui/contact-editor/eab-editor.h
index 6d70107643..f3803e7341 100644
--- a/addressbook/gui/contact-editor/eab-editor.h
+++ b/addressbook/gui/contact-editor/eab-editor.h
@@ -24,42 +24,42 @@
#ifndef __EAB_EDITOR_H__
#define __EAB_EDITOR_H__
-#include <bonobo/bonobo-ui-component.h>
-#include <glade/glade.h>
-
+#include <gtk/gtk.h>
#include <libebook/e-book.h>
#include <libebook/e-contact.h>
-
-#include <gtk/gtk.h>
+#include <shell/e-shell.h>
+
+/* Standard GObject macros */
+#define EAB_TYPE_EDITOR \
+ (eab_editor_get_type ())
+#define EAB_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EAB_TYPE_EDITOR, EABEditor))
+#define EAB_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EAB_TYPE_EDITOR, EABEditorClass))
+#define EAB_IS_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EAB_TYPE_EDITOR))
+#define EAB_IS_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EAB_TYPE_EDITOR))
+#define EAB_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EAB_EDITOR_TYPE, EABEditorClass))
G_BEGIN_DECLS
-/* EABEditor - A dialog displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * --------------------------------------------------------------------------------
- * card ECard * RW The card currently being edited
- */
-
-#define EAB_TYPE_EDITOR (eab_editor_get_type ())
-#define EAB_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EAB_TYPE_EDITOR, EABEditor))
-#define EAB_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EAB_TYPE_EDITOR, EABEditorClass))
-#define EAB_IS_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EAB_TYPE_EDITOR))
-#define EAB_IS_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EAB_TYPE_EDITOR))
-#define EAB_EDITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EAB_EDITOR_TYPE, EABEditorClass))
-
-typedef struct _EABEditor EABEditor;
-typedef struct _EABEditorClass EABEditorClass;
+typedef struct _EABEditor EABEditor;
+typedef struct _EABEditorClass EABEditorClass;
+typedef struct _EABEditorPrivate EABEditorPrivate;
-struct _EABEditor
-{
+struct _EABEditor {
GObject parent;
+ EABEditorPrivate *priv;
};
-struct _EABEditorClass
-{
+struct _EABEditorClass {
GObjectClass parent_class;
/* virtual functions */
@@ -78,32 +78,35 @@ struct _EABEditorClass
void (* editor_closed) (EABEditor *editor);
};
-GType eab_editor_get_type (void);
+GType eab_editor_get_type (void);
+EShell * eab_editor_get_shell (EABEditor *editor);
+GSList * eab_editor_get_all_editors (void);
/* virtual functions */
-void eab_editor_show (EABEditor *editor);
-void eab_editor_close (EABEditor *editor);
-void eab_editor_raise (EABEditor *editor);
-void eab_editor_save_contact (EABEditor *editor, gboolean should_close);
-gboolean eab_editor_is_valid (EABEditor *editor);
-gboolean eab_editor_is_changed (EABEditor *editor);
-GtkWindow* eab_editor_get_window (EABEditor *editor);
-
-gboolean eab_editor_prompt_to_save_changes (EABEditor *editor, GtkWindow *window);
-gboolean eab_editor_confirm_delete (GtkWindow *parent, gboolean plural, gboolean is_list, gchar *name);
+void eab_editor_show (EABEditor *editor);
+void eab_editor_close (EABEditor *editor);
+void eab_editor_raise (EABEditor *editor);
+void eab_editor_save_contact (EABEditor *editor,
+ gboolean should_close);
+gboolean eab_editor_is_valid (EABEditor *editor);
+gboolean eab_editor_is_changed (EABEditor *editor);
+GtkWindow * eab_editor_get_window (EABEditor *editor);
+
+gboolean eab_editor_prompt_to_save_changes
+ (EABEditor *editor,
+ GtkWindow *window);
/* these four generate EABEditor signals */
-void eab_editor_contact_added (EABEditor *editor, EBookStatus status, EContact *contact);
-void eab_editor_contact_modified (EABEditor *editor, EBookStatus status, EContact *contact);
-void eab_editor_contact_deleted (EABEditor *editor, EBookStatus status, EContact *contact);
-void eab_editor_closed (EABEditor *editor);
-
-/* these maintain the global list of editors so we can prompt the user
- if there are unsaved changes when they exit. */
-void eab_editor_add (EABEditor *editor);
-void eab_editor_remove (EABEditor *editor);
-gboolean eab_editor_request_close_all (void);
-const GSList* eab_editor_get_all_editors (void);
+void eab_editor_contact_added (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact);
+void eab_editor_contact_modified (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact);
+void eab_editor_contact_deleted (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact);
+void eab_editor_closed (EABEditor *editor);
G_END_DECLS
diff --git a/addressbook/gui/contact-list-editor/Makefile.am b/addressbook/gui/contact-list-editor/Makefile.am
index 81aa679c07..608707395d 100644
--- a/addressbook/gui/contact-list-editor/Makefile.am
+++ b/addressbook/gui/contact-list-editor/Makefile.am
@@ -25,7 +25,6 @@ libecontactlisteditor_la_SOURCES = \
libecontactlisteditor_la_LDFLAGS = $(NO_UNDEFINED)
libecontactlisteditor_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
$(top_builddir)/addressbook/util/libeabutil.la \
$(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
$(top_builddir)/widgets/table/libetable.la \
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.c b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
index e62958a72e..77d91357c5 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
@@ -34,10 +34,8 @@
#include <libedataserverui/e-source-combo-box.h>
-#include "shell/evolution-shell-component-utils.h"
-
-#include "addressbook/gui/component/addressbook.h"
#include "addressbook/gui/widgets/eab-gui-util.h"
+#include "addressbook/util/addressbook.h"
#include "addressbook/util/eab-book-util.h"
#include "eab-editor.h"
@@ -883,6 +881,36 @@ contact_list_editor_create_name_selector (gchar *name,
gint int1,
gint int2);
+static gpointer
+contact_editor_fudge_new (EBook *book,
+ EContact *contact,
+ gboolean is_new,
+ gboolean editable)
+{
+ EShell *shell = e_shell_get_default ();
+
+ /* XXX Putting this function signature in libedataserverui
+ * was a terrible idea. Now we're stuck with it. */
+
+ return e_contact_editor_new (
+ shell, book, contact, is_new, editable);
+}
+
+static gpointer
+contact_list_editor_fudge_new (EBook *book,
+ EContact *contact,
+ gboolean is_new,
+ gboolean editable)
+{
+ EShell *shell = e_shell_get_default ();
+
+ /* XXX Putting this function signature in libedataserverui
+ * was a terrible idea. Now we're stuck with it. */
+
+ return e_contact_list_editor_new (
+ shell, book, contact, is_new, editable);
+}
+
GtkWidget *
contact_list_editor_create_name_selector (gchar *name,
gchar *string1,
@@ -903,9 +931,9 @@ contact_list_editor_create_name_selector (gchar *name,
name_selector, "Members");
e_name_selector_entry_set_contact_editor_func (
- name_selector_entry, e_contact_editor_new);
+ name_selector_entry, contact_editor_fudge_new);
e_name_selector_entry_set_contact_list_editor_func (
- name_selector_entry, e_contact_list_editor_new);
+ name_selector_entry, contact_list_editor_fudge_new);
gtk_widget_show (GTK_WIDGET (name_selector_entry));
g_signal_connect (
@@ -924,87 +952,6 @@ contact_list_editor_create_name_selector (gchar *name,
return GTK_WIDGET (name_selector_entry);
}
-/**************************** EABEditor Callbacks ****************************/
-
-static void
-contact_list_editor_show (EABEditor *editor)
-{
- gtk_widget_show (WIDGET (DIALOG));
-}
-
-static void
-contact_list_editor_close (EABEditor *editor)
-{
- gtk_widget_destroy (WIDGET (DIALOG));
- eab_editor_closed (editor);
-}
-
-static void
-contact_list_editor_raise (EABEditor *editor)
-{
- gdk_window_raise (WIDGET (DIALOG)->window);
-}
-
-static void
-contact_list_editor_save_contact (EABEditor *eab_editor,
- gboolean should_close)
-{
- EContactListEditor *editor = E_CONTACT_LIST_EDITOR (eab_editor);
- EContactListEditorPrivate *priv = editor->priv;
- EditorCloseStruct *ecs;
- EContact *contact;
-
- contact = e_contact_list_editor_get_contact (editor);
-
- if (priv->book == NULL)
- return;
-
- ecs = g_new (EditorCloseStruct, 1);
- ecs->editor = g_object_ref (editor);
- ecs->should_close = should_close;
-
- gtk_widget_set_sensitive (WIDGET (DIALOG), FALSE);
- priv->in_async_call = TRUE;
-
- if (priv->is_new_list)
- eab_merging_book_add_contact (
- priv->book, contact, (EBookIdCallback)
- contact_list_editor_list_added_cb, ecs);
- else
- eab_merging_book_commit_contact (
- priv->book, contact, (EBookCallback)
- contact_list_editor_list_modified_cb, ecs);
-
- priv->changed = FALSE;
-}
-
-static gboolean
-contact_list_editor_is_valid (EABEditor *editor)
-{
- GtkEditable *editable;
- gboolean valid;
- gchar *chars;
-
- editable = GTK_EDITABLE (WIDGET (LIST_NAME_ENTRY));
- chars = gtk_editable_get_chars (editable, 0, -1);
- valid = (chars != NULL && *chars != '\0');
- g_free (chars);
-
- return valid;
-}
-
-static gboolean
-contact_list_editor_is_changed (EABEditor *editor)
-{
- return E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->changed;
-}
-
-static GtkWindow*
-contact_list_editor_get_window (EABEditor *editor)
-{
- return GTK_WINDOW (WIDGET (DIALOG));
-}
-
/***************************** GObject Callbacks *****************************/
static GObject *
@@ -1114,6 +1061,135 @@ contact_list_editor_dispose (GObject *object)
G_OBJECT_CLASS (parent_class)->dispose (object);
}
+/**************************** EABEditor Callbacks ****************************/
+
+static void
+contact_list_editor_show (EABEditor *editor)
+{
+ gtk_widget_show (WIDGET (DIALOG));
+}
+
+static void
+contact_list_editor_close (EABEditor *editor)
+{
+ gtk_widget_destroy (WIDGET (DIALOG));
+ eab_editor_closed (editor);
+}
+
+static void
+contact_list_editor_raise (EABEditor *editor)
+{
+ gdk_window_raise (WIDGET (DIALOG)->window);
+}
+
+static void
+contact_list_editor_save_contact (EABEditor *eab_editor,
+ gboolean should_close)
+{
+ EContactListEditor *editor = E_CONTACT_LIST_EDITOR (eab_editor);
+ EContactListEditorPrivate *priv = editor->priv;
+ EditorCloseStruct *ecs;
+ EContact *contact;
+
+ contact = e_contact_list_editor_get_contact (editor);
+
+ if (priv->book == NULL)
+ return;
+
+ ecs = g_new (EditorCloseStruct, 1);
+ ecs->editor = g_object_ref (editor);
+ ecs->should_close = should_close;
+
+ gtk_widget_set_sensitive (WIDGET (DIALOG), FALSE);
+ priv->in_async_call = TRUE;
+
+ if (priv->is_new_list)
+ eab_merging_book_add_contact (
+ priv->book, contact, (EBookIdCallback)
+ contact_list_editor_list_added_cb, ecs);
+ else
+ eab_merging_book_commit_contact (
+ priv->book, contact, (EBookCallback)
+ contact_list_editor_list_modified_cb, ecs);
+
+ priv->changed = FALSE;
+}
+
+static gboolean
+contact_list_editor_is_valid (EABEditor *editor)
+{
+ GtkEditable *editable;
+ gboolean valid;
+ gchar *chars;
+
+ editable = GTK_EDITABLE (WIDGET (LIST_NAME_ENTRY));
+ chars = gtk_editable_get_chars (editable, 0, -1);
+ valid = (chars != NULL && *chars != '\0');
+ g_free (chars);
+
+ return valid;
+}
+
+static gboolean
+contact_list_editor_is_changed (EABEditor *editor)
+{
+ return E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->changed;
+}
+
+static GtkWindow *
+contact_list_editor_get_window (EABEditor *editor)
+{
+ return GTK_WINDOW (WIDGET (DIALOG));
+}
+
+static void
+contact_list_editor_contact_added (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
+{
+ if (status == E_BOOK_ERROR_OK)
+ return;
+
+ if (status == E_BOOK_ERROR_CANCELLED)
+ return;
+
+ eab_error_dialog (_("Error adding list"), status);
+}
+
+static void
+contact_list_editor_contact_modified (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
+{
+ if (status == E_BOOK_ERROR_OK)
+ return;
+
+ if (status == E_BOOK_ERROR_CANCELLED)
+ return;
+
+ eab_error_dialog (_("Error modifying list"), status);
+}
+
+static void
+contact_list_editor_contact_deleted (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
+{
+ if (status == E_BOOK_ERROR_OK)
+ return;
+
+ if (status == E_BOOK_ERROR_CANCELLED)
+ return;
+
+ eab_error_dialog (_("Error removing list"), status);
+}
+
+static void
+contact_list_editor_closed (EABEditor *editor)
+{
+ g_object_unref (editor);
+}
+
/****************************** GType Callbacks ******************************/
static void
@@ -1139,6 +1215,10 @@ contact_list_editor_class_init (EContactListEditorClass *class)
editor_class->is_valid = contact_list_editor_is_valid;
editor_class->is_changed = contact_list_editor_is_changed;
editor_class->get_window = contact_list_editor_get_window;
+ editor_class->contact_added = contact_list_editor_contact_added;
+ editor_class->contact_modified = contact_list_editor_contact_modified;
+ editor_class->contact_deleted = contact_list_editor_contact_deleted;
+ editor_class->editor_closed = contact_list_editor_closed;
g_object_class_install_property (
object_class,
@@ -1269,26 +1349,20 @@ e_contact_list_editor_get_type (void)
return type;
}
-static void
-contact_list_editor_destroy_notify (gpointer data,
- GObject *where_the_object_was)
-{
- eab_editor_remove (EAB_EDITOR (data));
-}
-
-EContactListEditor *
-e_contact_list_editor_new (EBook *book,
- EContact *list_contact,
- gboolean is_new_list,
- gboolean editable)
+EABEditor *
+e_contact_list_editor_new (EShell *shell,
+ EBook *book,
+ EContact *list_contact,
+ gboolean is_new_list,
+ gboolean editable)
{
- EContactListEditor *editor;
+ EABEditor *editor;
- editor = g_object_new (E_TYPE_CONTACT_LIST_EDITOR, NULL);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- eab_editor_add (EAB_EDITOR (editor));
- g_object_weak_ref (
- G_OBJECT (editor), contact_list_editor_destroy_notify, editor);
+ editor = g_object_new (
+ E_TYPE_CONTACT_LIST_EDITOR,
+ "shell", shell, NULL);
g_object_set (editor,
"book", book,
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.h b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
index fcee0b02ef..8e258597aa 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
@@ -68,7 +68,8 @@ struct _EContactListEditorClass
};
GType e_contact_list_editor_get_type (void);
-EContactListEditor * e_contact_list_editor_new (EBook *book,
+EABEditor * e_contact_list_editor_new (EShell *shell,
+ EBook *book,
EContact *list_contact,
gboolean is_new_list,
gboolean editable);
diff --git a/addressbook/gui/merging/eab-contact-compare.c b/addressbook/gui/merging/eab-contact-compare.c
index 236c6acd0c..86ed4e9de6 100644
--- a/addressbook/gui/merging/eab-contact-compare.c
+++ b/addressbook/gui/merging/eab-contact-compare.c
@@ -24,8 +24,8 @@
#include <config.h>
#include <ctype.h>
#include <string.h>
-#include "util/eab-book-util.h"
-#include "../component/addressbook.h"
+#include "addressbook/util/addressbook.h"
+#include "addressbook/util/eab-book-util.h"
#include "eab-contact-compare.h"
/* This is an "optimistic" combiner: the best of the two outcomes is
diff --git a/addressbook/gui/merging/eab-contact-merging.c b/addressbook/gui/merging/eab-contact-merging.c
index aabea67bdb..b927918d22 100644
--- a/addressbook/gui/merging/eab-contact-merging.c
+++ b/addressbook/gui/merging/eab-contact-merging.c
@@ -471,12 +471,18 @@ match_query_callback (EContact *contact, EContact *match, EABContactMatchType ty
}
widget = glade_xml_get_widget (ui, "custom-old-contact");
- eab_contact_display_render (EAB_CONTACT_DISPLAY (widget),
- match, EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (widget),
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (widget), match);
widget = glade_xml_get_widget (ui, "custom-new-contact");
- eab_contact_display_render (EAB_CONTACT_DISPLAY (widget),
- contact, EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (widget),
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (widget), contact);
widget = glade_xml_get_widget (ui, "dialog-duplicate-contact");
diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am
index dd4bacf276..58d1e1b1d1 100644
--- a/addressbook/gui/widgets/Makefile.am
+++ b/addressbook/gui/widgets/Makefile.am
@@ -7,11 +7,11 @@ AM_CPPFLAGS = \
-DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
-DSEARCH_RULE_DIR=\"$(ruledir)\" \
-I$(top_srcdir) \
+ -I$(top_srcdir)/filter \
-I$(top_srcdir)/widgets \
-I$(top_srcdir)/addressbook \
- -I$(top_srcdir)/addressbook/gui/contact-editor \
-I$(top_srcdir)/addressbook/gui/merging \
- -I$(top_srcdir)/addressbook/gui/component \
+ -I$(top_srcdir)/addressbook/util \
-I$(top_srcdir)/widgets/misc \
-I$(top_builddir)/shell \
$(EVOLUTION_ADDRESSBOOK_CFLAGS)
@@ -22,9 +22,7 @@ noinst_LTLIBRARIES = \
eabincludedir = $(privincludedir)/addressbook/gui/widgets
eabinclude_HEADERS = \
- eab-config.h \
- eab-menu.h \
- eab-popup.h
+ eab-config.h
libeabwidgets_la_SOURCES = \
eab-config.c \
@@ -32,11 +30,6 @@ libeabwidgets_la_SOURCES = \
eab-contact-display.h \
eab-gui-util.c \
eab-gui-util.h \
- eab-menu.c \
- eab-popup.c \
- eab-popup.h \
- eab-popup-control.c \
- eab-popup-control.h \
e-minicard.c \
e-minicard.h \
e-minicard-label.c \
@@ -51,12 +44,29 @@ libeabwidgets_la_SOURCES = \
e-addressbook-table-adapter.h \
e-addressbook-model.c \
e-addressbook-model.h \
+ e-addressbook-selector.c \
+ e-addressbook-selector.h \
e-addressbook-view.c \
e-addressbook-view.h \
gal-view-minicard.c \
gal-view-minicard.h \
gal-view-factory-minicard.c \
- gal-view-factory-minicard.h
+ gal-view-factory-minicard.h \
+ ea-minicard.c \
+ ea-minicard.h \
+ ea-minicard-view.c \
+ ea-minicard-view.h \
+ ea-addressbook-view.c \
+ ea-addressbook-view.h \
+ ea-addressbook.c \
+ ea-addressbook.h
+
+libeabwidgets_la_LIBADD = \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/shell/libeshell.la \
+ $(top_builddir)/widgets/table/libetable.la \
+ $(top_builddir)/widgets/menus/libmenus.la \
+ $(top_builddir)/a11y/libevolution-a11y.la
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
@@ -65,6 +75,6 @@ etspec_DATA= e-addressbook-view.etspec
EXTRA_DIST = \
$(etspec_DATA) \
- addresstypes.xml
+ $(rule_DATA)
-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/widgets/e-addressbook-model.c b/addressbook/gui/widgets/e-addressbook-model.c
index 786c4d994d..71de495f13 100644
--- a/addressbook/gui/widgets/e-addressbook-model.c
+++ b/addressbook/gui/widgets/e-addressbook-model.c
@@ -22,31 +22,45 @@
#include <config.h>
#include <string.h>
-#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include "e-util/e-util.h"
#include "e-addressbook-model.h"
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
+#include <e-util/e-util.h>
#include <misc/e-gui-utils.h>
#include "eab-gui-util.h"
-#define PARENT_TYPE G_TYPE_OBJECT
-static GObjectClass *parent_class;
-
-/*
- * EABModel callbacks
- * These are the callbacks that define the behavior of our custom model.
- */
-static void eab_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void eab_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+#define E_ADDRESSBOOK_MODEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelPrivate))
+
+struct _EAddressbookModelPrivate {
+ EBook *book;
+ EBookQuery *query;
+ EBookView *book_view;
+ guint book_view_idle_id;
+
+ /* Query Results */
+ GPtrArray *contacts;
+
+ /* Signal Handler IDs */
+ gulong create_contact_id;
+ gulong remove_contact_id;
+ gulong modify_contact_id;
+ gulong status_message_id;
+ gulong writable_status_id;
+ gulong sequence_complete_id;
+ gulong backend_died_id;
+
+ guint search_in_progress : 1;
+ guint editable : 1;
+ guint editable_set : 1;
+ guint first_get_view : 1;
+};
enum {
PROP_0,
PROP_BOOK,
- PROP_QUERY,
- PROP_EDITABLE
+ PROP_EDITABLE,
+ PROP_QUERY
};
enum {
@@ -64,672 +78,799 @@ enum {
LAST_SIGNAL
};
-static guint eab_model_signals [LAST_SIGNAL] = {0, };
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
static void
-free_data (EABModel *model)
+free_data (EAddressbookModel *model)
{
- if (model->data) {
- gint i;
-
- for ( i = 0; i < model->data_count; i++ ) {
- g_object_unref (model->data[i]);
- }
-
- g_free(model->data);
- model->data = NULL;
- model->data_count = 0;
- model->allocated_count = 0;
- }
-}
+ GPtrArray *array;
-static void
-remove_book_view(EABModel *model)
-{
- if (model->book_view && model->create_contact_id)
- g_signal_handler_disconnect (model->book_view,
- model->create_contact_id);
- if (model->book_view && model->remove_contact_id)
- g_signal_handler_disconnect (model->book_view,
- model->remove_contact_id);
- if (model->book_view && model->modify_contact_id)
- g_signal_handler_disconnect (model->book_view,
- model->modify_contact_id);
- if (model->book_view && model->status_message_id)
- g_signal_handler_disconnect (model->book_view,
- model->status_message_id);
- if (model->book_view && model->sequence_complete_id)
- g_signal_handler_disconnect (model->book_view,
- model->sequence_complete_id);
-
- model->create_contact_id = 0;
- model->remove_contact_id = 0;
- model->modify_contact_id = 0;
- model->status_message_id = 0;
- model->sequence_complete_id = 0;
-
- model->search_in_progress = FALSE;
-
- if (model->book_view) {
- e_book_view_stop (model->book_view);
- g_object_unref (model->book_view);
- model->book_view = NULL;
- }
+ array = model->priv->contacts;
+ g_ptr_array_foreach (array, (GFunc) g_object_unref, NULL);
+ g_ptr_array_set_size (array, 0);
}
static void
-addressbook_dispose(GObject *object)
+remove_book_view(EAddressbookModel *model)
{
- EABModel *model = EAB_MODEL(object);
-
- remove_book_view(model);
- free_data (model);
-
- if (model->book) {
- if (model->writable_status_id)
- g_signal_handler_disconnect (model->book,
- model->writable_status_id);
- model->writable_status_id = 0;
-
- if (model->backend_died_id)
- g_signal_handler_disconnect (model->book,
- model->backend_died_id);
- model->backend_died_id = 0;
-
- g_object_unref (model->book);
- model->book = NULL;
- }
-
- if (model->query) {
- e_book_query_unref (model->query);
- model->query = NULL;
+ if (model->priv->book_view && model->priv->create_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->book_view,
+ model->priv->create_contact_id);
+ if (model->priv->book_view && model->priv->remove_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->book_view,
+ model->priv->remove_contact_id);
+ if (model->priv->book_view && model->priv->modify_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->book_view,
+ model->priv->modify_contact_id);
+ if (model->priv->book_view && model->priv->status_message_id)
+ g_signal_handler_disconnect (
+ model->priv->book_view,
+ model->priv->status_message_id);
+ if (model->priv->book_view && model->priv->sequence_complete_id)
+ g_signal_handler_disconnect (
+ model->priv->book_view,
+ model->priv->sequence_complete_id);
+
+ model->priv->create_contact_id = 0;
+ model->priv->remove_contact_id = 0;
+ model->priv->modify_contact_id = 0;
+ model->priv->status_message_id = 0;
+ model->priv->sequence_complete_id = 0;
+
+ model->priv->search_in_progress = FALSE;
+
+ if (model->priv->book_view) {
+ e_book_view_stop (model->priv->book_view);
+ g_object_unref (model->priv->book_view);
+ model->priv->book_view = NULL;
}
-
- if (G_OBJECT_CLASS(parent_class)->dispose)
- G_OBJECT_CLASS(parent_class)->dispose(object);
}
static void
-update_folder_bar_message (EABModel *model)
+update_folder_bar_message (EAddressbookModel *model)
{
- gint count;
+ guint count;
gchar *message;
- count = model->data_count;
+ count = model->priv->contacts->len;
switch (count) {
case 0:
message = g_strdup (_("No contacts"));
break;
default:
- message = g_strdup_printf (ngettext("%d contact", "%d contacts", count), count);
+ message = g_strdup_printf (
+ ngettext ("%d contact", "%d contacts", count), count);
break;
}
- g_signal_emit (model,
- eab_model_signals [FOLDER_BAR_MESSAGE], 0,
- message);
+ g_signal_emit (model, signals[FOLDER_BAR_MESSAGE], 0, message);
g_free (message);
}
static void
-create_contact(EBookView *book_view,
- const GList *contacts,
- EABModel *model)
+create_contact (EBookView *book_view,
+ const GList *contact_list,
+ EAddressbookModel *model)
{
- gint old_count = model->data_count;
- gint length = g_list_length ((GList *)contacts);
+ GPtrArray *array;
+ guint count;
+ guint index;
- if (model->data_count + length > model->allocated_count) {
- while (model->data_count + length > model->allocated_count)
- model->allocated_count = model->allocated_count * 2 + 1;
- model->data = g_renew(EContact *, model->data, model->allocated_count);
- }
+ array = model->priv->contacts;
+ index = array->len;
+ count = g_list_length ((GList *) contact_list);
- for (; contacts; contacts = contacts->next) {
- model->data[model->data_count++] = contacts->data;
- g_object_ref (contacts->data);
- }
+ while (contact_list != NULL) {
+ EContact *contact = contact_list->data;
- g_signal_emit (model,
- eab_model_signals [CONTACT_ADDED], 0,
- old_count, model->data_count - old_count);
+ g_ptr_array_add (array, g_object_ref (contact));
+ contact_list = contact_list->next;
+ }
+ g_signal_emit (model, signals[CONTACT_ADDED], 0, index, count);
update_folder_bar_message (model);
}
static void
remove_contact(EBookView *book_view,
GList *ids,
- EABModel *model)
+ EAddressbookModel *model)
{
/* XXX we should keep a hash around instead of this O(n*m) loop */
- gint i = 0;
- GList *l;
+ GList *iter;
GArray *indices;
+ GPtrArray *array;
+ gint ii;
+ array = model->priv->contacts;
indices = g_array_new (FALSE, FALSE, sizeof (gint));
- for (l = ids; l; l = l->next) {
- gchar *id = l->data;
- for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_contact_get_const (model->data[i], E_CONTACT_UID), id) ) {
- g_object_unref (model->data[i]);
- memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (EContact *));
- model->data_count--;
- g_array_append_val (indices, i);
- break;
+
+ for (iter = ids; iter != NULL; iter = iter->next) {
+ const gchar *target_uid = iter->data;
+
+ for (ii = 0; ii < array->len; ii++) {
+ EContact *contact;
+ const gchar *uid;
+
+ contact = array->pdata[ii];
+ uid = e_contact_get_const (contact, E_CONTACT_UID);
+ if (strcmp (uid, target_uid) == 0) {
+ g_object_unref (contact);
+ g_array_append_val (indices, ii);
}
}
}
- g_signal_emit (model,
- eab_model_signals [CONTACTS_REMOVED], 0,
- indices);
+
+ for (ii = 0; ii < indices->len; ii++) {
+ gint index;
+
+ index = g_array_index (indices, gint, ii);
+ g_ptr_array_remove_index (array, index);
+ }
+
+ g_signal_emit (model, signals[CONTACTS_REMOVED], 0, indices);
g_array_free (indices, FALSE);
+
update_folder_bar_message (model);
}
static void
modify_contact(EBookView *book_view,
- const GList *contacts,
- EABModel *model)
-{
- for (; contacts; contacts = contacts->next) {
- gint i;
- for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_contact_get_const(model->data[i], E_CONTACT_UID),
- e_contact_get_const(E_CONTACT(contacts->data), E_CONTACT_UID)) ) {
- g_object_unref (model->data[i]);
- model->data[i] = e_contact_duplicate(E_CONTACT(contacts->data));
- g_signal_emit (model,
- eab_model_signals [CONTACT_CHANGED], 0,
- i);
- break;
- }
+ const GList *contact_list,
+ EAddressbookModel *model)
+{
+ GPtrArray *array;
+
+ array = model->priv->contacts;
+
+ while (contact_list != NULL) {
+ EContact *contact = contact_list->data;
+ const gchar *target_uid;
+ gint ii;
+
+ target_uid = e_contact_get_const (contact, E_CONTACT_UID);
+
+ for (ii = 0; ii < array->len; ii++) {
+ const gchar *uid;
+
+ uid = e_contact_get_const (
+ array->pdata[ii], E_CONTACT_UID);
+
+ if (strcmp (uid, target_uid) != 0)
+ continue;
+
+ g_object_unref (array->pdata[ii]);
+ contact = e_contact_duplicate (contact);
+ array->pdata[ii] = contact;
+
+ g_signal_emit (
+ model, signals[CONTACT_CHANGED], 0, ii);
+ break;
}
+
+ contact_list = contact_list->next;
}
}
static void
status_message (EBookView *book_view,
gchar * status,
- EABModel *model)
+ EAddressbookModel *model)
{
- g_signal_emit (model,
- eab_model_signals [STATUS_MESSAGE], 0,
- status);
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, status);
}
static void
sequence_complete (EBookView *book_view,
- EBookViewStatus status,
- EABModel *model)
+ EBookViewStatus status,
+ EAddressbookModel *model)
{
- model->search_in_progress = FALSE;
+ model->priv->search_in_progress = FALSE;
status_message (book_view, NULL, model);
- g_signal_emit (model,
- eab_model_signals [SEARCH_RESULT], 0,
- status);
- g_signal_emit (model,
- eab_model_signals [STOP_STATE_CHANGED], 0);
+ g_signal_emit (model, signals[SEARCH_RESULT], 0, status);
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
}
static void
writable_status (EBook *book,
gboolean writable,
- EABModel *model)
+ EAddressbookModel *model)
{
- if (!model->editable_set) {
- model->editable = writable;
+ if (!model->priv->editable_set) {
+ model->priv->editable = writable;
- g_signal_emit (model,
- eab_model_signals [WRITABLE_STATUS], 0,
- writable);
+ g_signal_emit (model, signals[WRITABLE_STATUS], 0, writable);
}
}
static void
backend_died (EBook *book,
- EABModel *model)
+ EAddressbookModel *model)
+{
+ g_signal_emit (model, signals[BACKEND_DIED], 0);
+}
+
+static void
+book_view_loaded (EBook *book,
+ EBookStatus status,
+ EBookView *book_view,
+ gpointer closure)
+{
+ EAddressbookModel *model = closure;
+
+ if (status != E_BOOK_ERROR_OK) {
+ eab_error_dialog (_("Error getting book view"), status);
+ return;
+ }
+
+ remove_book_view (model);
+ free_data (model);
+
+ model->priv->book_view = book_view;
+ if (model->priv->book_view)
+ g_object_ref (model->priv->book_view);
+
+ model->priv->create_contact_id = g_signal_connect (
+ model->priv->book_view, "contacts-added",
+ G_CALLBACK (create_contact), model);
+ model->priv->remove_contact_id = g_signal_connect (
+ model->priv->book_view, "contacts-removed",
+ G_CALLBACK (remove_contact), model);
+ model->priv->modify_contact_id = g_signal_connect (
+ model->priv->book_view, "contacts-changed",
+ G_CALLBACK (modify_contact), model);
+ model->priv->status_message_id = g_signal_connect (
+ model->priv->book_view, "status-message",
+ G_CALLBACK (status_message), model);
+ model->priv->sequence_complete_id = g_signal_connect (
+ model->priv->book_view, "sequence-complete",
+ G_CALLBACK (sequence_complete), model);
+
+ model->priv->search_in_progress = TRUE;
+ g_signal_emit (model, signals[MODEL_CHANGED], 0);
+ g_signal_emit (model, signals[SEARCH_STARTED], 0);
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
+
+ e_book_view_start (model->priv->book_view);
+}
+
+static gboolean
+addressbook_model_idle_cb (EAddressbookModel *model)
+{
+ model->priv->book_view_idle_id = 0;
+
+ if (model->priv->book && model->priv->query) {
+ ESource *source;
+ const gchar *limit_str;
+ gint limit = -1;
+
+ source = e_book_get_source (model->priv->book);
+
+ limit_str = e_source_get_property (source, "limit");
+ if (limit_str && *limit_str)
+ limit = atoi (limit_str);
+
+ remove_book_view(model);
+
+ if (model->priv->first_get_view) {
+ model->priv->first_get_view = FALSE;
+
+ if (e_book_check_static_capability (model->priv->book, "do-initial-query")) {
+ e_book_async_get_book_view (
+ model->priv->book, model->priv->query,
+ NULL, limit, book_view_loaded, model);
+ } else {
+ free_data (model);
+
+ g_signal_emit (model,
+ signals[MODEL_CHANGED], 0);
+ g_signal_emit (model,
+ signals[STOP_STATE_CHANGED], 0);
+ }
+ } else
+ e_book_async_get_book_view (
+ model->priv->book, model->priv->query,
+ NULL, limit, book_view_loaded, model);
+
+ }
+
+ g_object_unref (model);
+
+ return FALSE;
+}
+
+static void
+addressbook_model_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_BOOK:
+ e_addressbook_model_set_book (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_EDITABLE:
+ e_addressbook_model_set_editable (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_QUERY:
+ e_addressbook_model_set_query (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+
+}
+
+static void
+addressbook_model_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_BOOK:
+ g_value_set_object (
+ value, e_addressbook_model_get_book (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+
+ case PROP_EDITABLE:
+ g_value_set_boolean (
+ value, e_addressbook_model_get_editable (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+
+ case PROP_QUERY:
+ g_value_take_string (
+ value, e_addressbook_model_get_query (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+addressbook_model_dispose (GObject *object)
+{
+ EAddressbookModel *model = E_ADDRESSBOOK_MODEL(object);
+
+ remove_book_view (model);
+ free_data (model);
+
+ if (model->priv->book) {
+ if (model->priv->writable_status_id)
+ g_signal_handler_disconnect (
+ model->priv->book,
+ model->priv->writable_status_id);
+ model->priv->writable_status_id = 0;
+
+ if (model->priv->backend_died_id)
+ g_signal_handler_disconnect (
+ model->priv->book,
+ model->priv->backend_died_id);
+ model->priv->backend_died_id = 0;
+
+ g_object_unref (model->priv->book);
+ model->priv->book = NULL;
+ }
+
+ if (model->priv->query) {
+ e_book_query_unref (model->priv->query);
+ model->priv->query = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+addressbook_model_finalize (GObject *object)
{
- g_signal_emit (model,
- eab_model_signals [BACKEND_DIED], 0);
+ EAddressbookModelPrivate *priv;
+
+ priv = E_ADDRESSBOOK_MODEL_GET_PRIVATE (object);
+
+ g_ptr_array_free (priv->contacts, TRUE);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-eab_model_class_init (GObjectClass *object_class)
-{
- parent_class = g_type_class_ref (PARENT_TYPE);
-
- object_class->dispose = addressbook_dispose;
- object_class->set_property = eab_model_set_property;
- object_class->get_property = eab_model_get_property;
-
- g_object_class_install_property (object_class, PROP_BOOK,
- g_param_spec_object ("book",
- _("Book"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_BOOK,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_QUERY,
- g_param_spec_string ("query",
- _("Query"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_EDITABLE,
- g_param_spec_boolean ("editable",
- _("Editable"),
- /*_( */"XXX blurb" /*)*/,
- FALSE,
- G_PARAM_READWRITE));
-
- eab_model_signals [WRITABLE_STATUS] =
+addressbook_model_class_init (EAddressbookModelClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EAddressbookModelPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_model_set_property;
+ object_class->get_property = addressbook_model_get_property;
+ object_class->dispose = addressbook_model_dispose;
+ object_class->finalize = addressbook_model_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_BOOK,
+ g_param_spec_object (
+ "book",
+ _("Book"),
+ NULL,
+ E_TYPE_BOOK,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ _("Editable"),
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ _("Query"),
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[WRITABLE_STATUS] =
g_signal_new ("writable_status",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, writable_status),
+ G_STRUCT_OFFSET (EAddressbookModelClass, writable_status),
NULL, NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE,
1, G_TYPE_BOOLEAN);
- eab_model_signals [STATUS_MESSAGE] =
+ signals[STATUS_MESSAGE] =
g_signal_new ("status_message",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, status_message),
+ G_STRUCT_OFFSET (EAddressbookModelClass, status_message),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1, G_TYPE_POINTER);
- eab_model_signals [SEARCH_STARTED] =
+ signals[SEARCH_STARTED] =
g_signal_new ("search_started",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, search_started),
+ G_STRUCT_OFFSET (EAddressbookModelClass, search_started),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- eab_model_signals [SEARCH_RESULT] =
+ signals[SEARCH_RESULT] =
g_signal_new ("search_result",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, search_result),
+ G_STRUCT_OFFSET (EAddressbookModelClass, search_result),
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
- eab_model_signals [FOLDER_BAR_MESSAGE] =
+ signals[FOLDER_BAR_MESSAGE] =
g_signal_new ("folder_bar_message",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, folder_bar_message),
+ G_STRUCT_OFFSET (EAddressbookModelClass, folder_bar_message),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
- eab_model_signals [CONTACT_ADDED] =
+ signals[CONTACT_ADDED] =
g_signal_new ("contact_added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, contact_added),
+ G_STRUCT_OFFSET (EAddressbookModelClass, contact_added),
NULL, NULL,
e_marshal_NONE__INT_INT,
G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
- eab_model_signals [CONTACTS_REMOVED] =
+ signals[CONTACTS_REMOVED] =
g_signal_new ("contacts_removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, contacts_removed),
+ G_STRUCT_OFFSET (EAddressbookModelClass, contacts_removed),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
- eab_model_signals [CONTACT_CHANGED] =
+ signals[CONTACT_CHANGED] =
g_signal_new ("contact_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, contact_changed),
+ G_STRUCT_OFFSET (EAddressbookModelClass, contact_changed),
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
- eab_model_signals [MODEL_CHANGED] =
+ signals[MODEL_CHANGED] =
g_signal_new ("model_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, model_changed),
+ G_STRUCT_OFFSET (EAddressbookModelClass, model_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- eab_model_signals [STOP_STATE_CHANGED] =
+ signals[STOP_STATE_CHANGED] =
g_signal_new ("stop_state_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, stop_state_changed),
+ G_STRUCT_OFFSET (EAddressbookModelClass, stop_state_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- eab_model_signals [BACKEND_DIED] =
+ signals[BACKEND_DIED] =
g_signal_new ("backend_died",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABModelClass, backend_died),
+ G_STRUCT_OFFSET (EAddressbookModelClass, backend_died),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
-eab_model_init (GObject *object)
-{
- EABModel *model = EAB_MODEL(object);
- model->book = NULL;
- model->query = e_book_query_any_field_contains ("");
- model->book_view = NULL;
- model->create_contact_id = 0;
- model->remove_contact_id = 0;
- model->modify_contact_id = 0;
- model->status_message_id = 0;
- model->writable_status_id = 0;
- model->backend_died_id = 0;
- model->sequence_complete_id = 0;
- model->data = NULL;
- model->data_count = 0;
- model->allocated_count = 0;
- model->search_in_progress = FALSE;
- model->editable = FALSE;
- model->editable_set = FALSE;
- model->first_get_view = TRUE;
+addressbook_model_init (EAddressbookModel *model)
+{
+ model->priv = E_ADDRESSBOOK_MODEL_GET_PRIVATE (model);
+
+ model->priv->contacts = g_ptr_array_new ();
+ model->priv->first_get_view = TRUE;
}
-static void
-book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure)
+GType
+e_addressbook_model_get_type (void)
{
- EABModel *model = closure;
+ static GType type = 0;
- if (status != E_BOOK_ERROR_OK) {
- eab_error_dialog (_("Error getting book view"), status);
- return;
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EAddressbookModelClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) addressbook_model_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EAddressbookModel),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) addressbook_model_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EAddressbookModel", &type_info, 0);
}
- remove_book_view (model);
- free_data (model);
+ return type;
+}
- model->book_view = book_view;
- if (model->book_view)
- g_object_ref (model->book_view);
- model->create_contact_id = g_signal_connect(model->book_view,
- "contacts_added",
- G_CALLBACK (create_contact),
- model);
- model->remove_contact_id = g_signal_connect(model->book_view,
- "contacts_removed",
- G_CALLBACK (remove_contact),
- model);
- model->modify_contact_id = g_signal_connect(model->book_view,
- "contacts_changed",
- G_CALLBACK(modify_contact),
- model);
- model->status_message_id = g_signal_connect(model->book_view,
- "status_message",
- G_CALLBACK(status_message),
- model);
- model->sequence_complete_id = g_signal_connect(model->book_view,
- "sequence_complete",
- G_CALLBACK(sequence_complete),
- model);
-
- model->search_in_progress = TRUE;
- g_signal_emit (model,
- eab_model_signals [MODEL_CHANGED], 0);
- g_signal_emit (model,
- eab_model_signals [SEARCH_STARTED], 0);
- g_signal_emit (model,
- eab_model_signals [STOP_STATE_CHANGED], 0);
-
- e_book_view_start (model->book_view);
+EAddressbookModel*
+e_addressbook_model_new (void)
+{
+ return g_object_new (E_TYPE_ADDRESSBOOK_MODEL, NULL);
}
-static void
-get_view (EABModel *model)
+EContact *
+e_addressbook_model_get_contact (EAddressbookModel *model,
+ gint row)
{
- /* Should this be checked somehow? */
- gboolean success;
+ GPtrArray *array;
- if (model->book && model->query) {
- ESource *source;
- const gchar *limit_str;
- gint limit = -1;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
- source = e_book_get_source (model->book);
+ array = model->priv->contacts;
- limit_str = e_source_get_property (source, "limit");
- if (limit_str && *limit_str)
- limit = atoi (limit_str);
+ if (0 <= row && row < array->len)
+ return e_contact_duplicate (array->pdata[row]);
- remove_book_view(model);
+ return NULL;
+}
- if (model->first_get_view) {
- model->first_get_view = FALSE;
+void
+e_addressbook_model_stop (EAddressbookModel *model)
+{
+ const gchar *message;
- if (e_book_check_static_capability (model->book, "do-initial-query")) {
- success = e_book_async_get_book_view (model->book, model->query, NULL, limit, book_view_loaded, model);
- } else {
- free_data (model);
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
- g_signal_emit (model,
- eab_model_signals [MODEL_CHANGED], 0);
- g_signal_emit (model,
- eab_model_signals [STOP_STATE_CHANGED], 0);
- return;
- }
- }
- else
- success = e_book_async_get_book_view (model->book, model->query, NULL, limit, book_view_loaded, model);
+ remove_book_view (model);
- }
+ message = _("Search Interrupted");
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, message);
}
-static gboolean
-get_view_idle (EABModel *model)
+gboolean
+e_addressbook_model_can_stop (EAddressbookModel *model)
{
- model->book_view_idle_id = 0;
- get_view (model);
- g_object_unref (model);
- return FALSE;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE);
+
+ return model->priv->search_in_progress;
}
-EContact *
-eab_model_get_contact(EABModel *model,
- gint row)
+void
+e_addressbook_model_force_folder_bar_message (EAddressbookModel *model)
{
- if (model->data && 0 <= row && row < model->data_count) {
- return e_contact_duplicate (model->data[row]);
- }
- return NULL;
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
+ update_folder_bar_message (model);
}
-static void
-eab_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+gint
+e_addressbook_model_contact_count (EAddressbookModel *model)
{
- EABModel *model;
- gboolean need_get_book_view = FALSE;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), 0);
- model = EAB_MODEL (object);
+ return model->priv->contacts->len;
+}
- switch (prop_id) {
- case PROP_BOOK:
- if (model->book) {
- if (model->writable_status_id)
- g_signal_handler_disconnect (model->book,
- model->writable_status_id);
- model->writable_status_id = 0;
+EContact *
+e_addressbook_model_contact_at (EAddressbookModel *model,
+ gint index)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
- if (model->backend_died_id)
- g_signal_handler_disconnect (model->book,
- model->backend_died_id);
- model->backend_died_id = 0;
+ return model->priv->contacts->pdata[index];
+}
- g_object_unref (model->book);
- }
- model->book = E_BOOK(g_value_get_object (value));
- if (model->book) {
- model->writable_status_id =
- g_signal_connect (model->book,
- "writable_status",
- G_CALLBACK (writable_status), model);
- model->backend_died_id =
- g_signal_connect (model->book,
- "backend_died",
- G_CALLBACK (backend_died), model);
-
- if (!model->editable_set) {
- model->editable = e_book_is_writable (model->book);
+gint
+e_addressbook_model_find (EAddressbookModel *model,
+ EContact *contact)
+{
+ GPtrArray *array;
+ gint ii;
- g_signal_emit (model,
- eab_model_signals [WRITABLE_STATUS], 0,
- model->editable);
- }
+ /* XXX This searches for a particular EContact instance,
+ * as opposed to an equivalent but possibly different
+ * EContact instance. Might have to revise this in
+ * the future. */
- model->first_get_view = TRUE;
- g_object_ref (model->book);
- need_get_book_view = TRUE;
- }
- break;
- case PROP_QUERY:
- if (model->query)
- e_book_query_unref (model->query);
- model->query = e_book_query_from_string (g_value_get_string (value));
- need_get_book_view = TRUE;
- break;
- case PROP_EDITABLE:
- model->editable = g_value_get_boolean (value);
- model->editable_set = TRUE;
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), -1);
+ g_return_val_if_fail (E_IS_CONTACT (contact), -1);
- if (need_get_book_view) {
- if (!model->book_view_idle_id) {
- g_object_ref (model);
- model->book_view_idle_id = g_idle_add ((GSourceFunc)get_view_idle, model);
- }
+ array = model->priv->contacts;
+ for (ii = 0; ii < array->len; ii++) {
+ EContact *candidate = array->pdata[ii];
+
+ if (contact == candidate)
+ return ii;
}
+ return -1;
}
-static void
-eab_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+EBook *
+e_addressbook_model_get_book (EAddressbookModel *model)
{
- EABModel *eab_model;
-
- eab_model = EAB_MODEL (object);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
- switch (prop_id) {
- case PROP_BOOK:
- g_value_set_object (value, eab_model->book);
- break;
- case PROP_QUERY: {
- gchar *query_string = e_book_query_to_string (eab_model->query);
- g_value_set_string (value, query_string);
- break;
- }
- case PROP_EDITABLE:
- g_value_set_boolean (value, eab_model->editable);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ return model->priv->book;
}
-GType
-eab_model_get_type (void)
+void
+e_addressbook_model_set_book (EAddressbookModel *model,
+ EBook *book)
{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EABModelClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) eab_model_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EABModel),
- 0, /* n_preallocs */
- (GInstanceInitFunc) eab_model_init,
- };
-
- type = g_type_register_static (PARENT_TYPE, "EABModel", &info, 0);
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+ g_return_if_fail (E_IS_BOOK (book));
+
+ if (model->priv->book != NULL) {
+ if (model->priv->writable_status_id != 0)
+ g_signal_handler_disconnect (
+ model->priv->book,
+ model->priv->writable_status_id);
+ model->priv->writable_status_id = 0;
+
+ if (model->priv->backend_died_id != 0)
+ g_signal_handler_disconnect (
+ model->priv->book,
+ model->priv->backend_died_id);
+ model->priv->backend_died_id = 0;
+
+ g_object_unref (model->priv->book);
}
- return type;
-}
+ model->priv->book = g_object_ref (book);
+ model->priv->first_get_view = TRUE;
-EABModel*
-eab_model_new (void)
-{
- EABModel *et;
+ model->priv->writable_status_id = g_signal_connect (
+ book, "writable-status",
+ G_CALLBACK (writable_status), model);
- et = g_object_new (EAB_TYPE_MODEL, NULL);
+ model->priv->backend_died_id = g_signal_connect (
+ book, "backend-died",
+ G_CALLBACK (backend_died), model);
- return et;
-}
+ if (!model->priv->editable_set) {
+ model->priv->editable = e_book_is_writable (book);
+ g_signal_emit (
+ model, signals[WRITABLE_STATUS], 0,
+ model->priv->editable);
+ }
-void eab_model_stop (EABModel *model)
-{
- remove_book_view(model);
- g_signal_emit (model,
- eab_model_signals [STOP_STATE_CHANGED], 0);
- g_signal_emit (model,
- eab_model_signals [STATUS_MESSAGE], 0,
- "Search Interrupted.");
+ if (model->priv->book_view_idle_id == 0)
+ model->priv->book_view_idle_id = g_idle_add (
+ (GSourceFunc) addressbook_model_idle_cb,
+ g_object_ref (model));
+
+ g_object_notify (G_OBJECT (model), "book");
}
gboolean
-eab_model_can_stop (EABModel *model)
+e_addressbook_model_get_editable (EAddressbookModel *model)
{
- return model->search_in_progress;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE);
+
+ return model->priv->editable;
}
void
-eab_model_force_folder_bar_message (EABModel *model)
+e_addressbook_model_set_editable (EAddressbookModel *model,
+ gboolean editable)
{
- update_folder_bar_message (model);
-}
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
-gint
-eab_model_contact_count (EABModel *model)
-{
- return model->data_count;
-}
+ model->priv->editable = editable;
+ model->priv->editable_set = TRUE;
-const EContact *
-eab_model_contact_at (EABModel *model, gint index)
-{
- return model->data[index];
+ g_object_notify (G_OBJECT (model), "editable");
}
-gboolean
-eab_model_editable (EABModel *model)
+gchar *
+e_addressbook_model_get_query (EAddressbookModel *model)
{
- return model->editable;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return e_book_query_to_string (model->priv->query);
}
-EBook *
-eab_model_get_ebook (EABModel *model)
+void
+e_addressbook_model_set_query (EAddressbookModel *model,
+ const gchar *query)
{
- return model->book;
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
+ if (model->priv->query != NULL)
+ e_book_query_unref (model->priv->query);
+
+ if (query == NULL)
+ model->priv->query = e_book_query_any_field_contains ("");
+ else
+ model->priv->query = e_book_query_from_string (query);
+
+ if (model->priv->book_view_idle_id == 0)
+ model->priv->book_view_idle_id = g_idle_add (
+ (GSourceFunc) addressbook_model_idle_cb,
+ g_object_ref (model));
+
+ g_object_notify (G_OBJECT (model), "query");
}
diff --git a/addressbook/gui/widgets/e-addressbook-model.h b/addressbook/gui/widgets/e-addressbook-model.h
index 1383da4b19..b42de48dbc 100644
--- a/addressbook/gui/widgets/e-addressbook-model.h
+++ b/addressbook/gui/widgets/e-addressbook-model.h
@@ -18,82 +18,98 @@
*
*/
-#ifndef _EAB_MODEL_H_
-#define _EAB_MODEL_H_
+#ifndef E_ADDRESSBOOK_MODEL_H
+#define E_ADDRESSBOOK_MODEL_H
-#include <glib.h>
-#include <glib-object.h>
#include <libebook/e-book.h>
+#include <libebook/e-book-query.h>
#include <libebook/e-book-view.h>
-#define EAB_TYPE_MODEL (eab_model_get_type ())
-#define EAB_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EAB_TYPE_MODEL, EABModel))
-#define EAB_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EAB_TYPE_MODEL, EABModelClass))
-#define E_IS_ADDRESSBOOK_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EAB_TYPE_MODEL))
-#define E_IS_ADDRESSBOOK_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EAB_TYPE_MODEL))
-
-typedef struct _EABModel EABModel;
-typedef struct _EABModelClass EABModelClass;
-
-struct _EABModel {
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_MODEL \
+ (e_addressbook_model_get_type ())
+#define E_ADDRESSBOOK_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModel))
+#define E_ADDRESSBOOK_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelClass))
+#define E_IS_ADDRESSBOOK_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL))
+#define E_IS_ADDRESSBOOK_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ADDRESSBOOK_MODEL))
+#define E_ADDRESSBOOK_MODEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL))
+
+G_BEGIN_DECLS
+
+typedef struct _EAddressbookModel EAddressbookModel;
+typedef struct _EAddressbookModelClass EAddressbookModelClass;
+typedef struct _EAddressbookModelPrivate EAddressbookModelPrivate;
+
+struct _EAddressbookModel {
GObject parent;
-
- /* item specific fields */
- EBook *book;
- EBookQuery *query;
- EBookView *book_view;
-
- gint book_view_idle_id;
-
- EContact **data;
- gint data_count;
- gint allocated_count;
-
- gint create_contact_id, remove_contact_id, modify_contact_id;
- gint status_message_id, writable_status_id, sequence_complete_id;
- gint backend_died_id;
-
- guint search_in_progress : 1;
- guint editable : 1;
- guint editable_set : 1;
- guint first_get_view : 1;
+ EAddressbookModelPrivate *priv;
};
-struct _EABModelClass {
+struct _EAddressbookModelClass {
GObjectClass parent_class;
- /*
- * Signals
- */
- void (*writable_status) (EABModel *model, gboolean writable);
- void (*search_started) (EABModel *model);
- void (*search_result) (EABModel *model, EBookViewStatus status);
- void (*status_message) (EABModel *model, const gchar *message);
- void (*folder_bar_message) (EABModel *model, const gchar *message);
- void (*contact_added) (EABModel *model, gint index, gint count);
- void (*contacts_removed) (EABModel *model, gpointer id_list);
- void (*contact_changed) (EABModel *model, gint index);
- void (*model_changed) (EABModel *model);
- void (*stop_state_changed) (EABModel *model);
- void (*backend_died) (EABModel *model);
+ /* Signals */
+ void (*writable_status) (EAddressbookModel *model,
+ gboolean writable);
+ void (*search_started) (EAddressbookModel *model);
+ void (*search_result) (EAddressbookModel *model,
+ EBookViewStatus status);
+ void (*status_message) (EAddressbookModel *model,
+ const gchar *message);
+ void (*folder_bar_message) (EAddressbookModel *model,
+ const gchar *message);
+ void (*contact_added) (EAddressbookModel *model,
+ gint index,
+ gint count);
+ void (*contacts_removed) (EAddressbookModel *model,
+ gpointer id_list);
+ void (*contact_changed) (EAddressbookModel *model,
+ gint index);
+ void (*model_changed) (EAddressbookModel *model);
+ void (*stop_state_changed) (EAddressbookModel *model);
+ void (*backend_died) (EAddressbookModel *model);
};
-GType eab_model_get_type (void);
-EABModel *eab_model_new (void);
+GType e_addressbook_model_get_type (void);
+EAddressbookModel *
+ e_addressbook_model_new (void);
/* Returns object with ref count of 1. */
-EContact *eab_model_get_contact (EABModel *model,
- gint row);
-EBook *eab_model_get_ebook (EABModel *model);
-
-void eab_model_stop (EABModel *model);
-gboolean eab_model_can_stop (EABModel *model);
-
-void eab_model_force_folder_bar_message (EABModel *model);
-
-gint eab_model_contact_count (EABModel *model);
-const EContact *eab_model_contact_at (EABModel *model,
- gint index);
-gboolean eab_model_editable (EABModel *model);
-
-#endif /* _EAB_MODEL_H_ */
+EContact * e_addressbook_model_get_contact (EAddressbookModel *model,
+ gint row);
+
+void e_addressbook_model_stop (EAddressbookModel *model);
+gboolean e_addressbook_model_can_stop (EAddressbookModel *model);
+
+void e_addressbook_model_force_folder_bar_message
+ (EAddressbookModel *model);
+
+gint e_addressbook_model_contact_count
+ (EAddressbookModel *model);
+EContact * e_addressbook_model_contact_at (EAddressbookModel *model,
+ gint index);
+gint e_addressbook_model_find (EAddressbookModel *model,
+ EContact *contact);
+EBook * e_addressbook_model_get_book (EAddressbookModel *model);
+void e_addressbook_model_set_book (EAddressbookModel *model,
+ EBook *book);
+gboolean e_addressbook_model_get_editable(EAddressbookModel *model);
+void e_addressbook_model_set_editable(EAddressbookModel *model,
+ gboolean editable);
+gchar * e_addressbook_model_get_query (EAddressbookModel *model);
+void e_addressbook_model_set_query (EAddressbookModel *model,
+ const gchar *query);
+
+G_END_DECLS
+
+#endif /* E_ADDRESSBOOK_MODEL_H */
diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
index 536d065c10..500b045077 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
@@ -20,18 +20,17 @@
#include <string.h>
#include <glib/gi18n.h>
-#include "e-util/e-util.h"
#include "e-addressbook-reflow-adapter.h"
#include "e-addressbook-model.h"
-#include "e-addressbook-view.h"
#include "eab-gui-util.h"
#include "e-minicard.h"
+#include <e-util/e-util.h>
#include <misc/e-gui-utils.h>
#include "addressbook/printing/e-contact-print.h"
struct _EAddressbookReflowAdapterPrivate {
- EABModel *model;
+ EAddressbookModel *model;
gboolean loading;
@@ -54,10 +53,11 @@ enum {
enum {
DRAG_BEGIN,
+ OPEN_CONTACT,
LAST_SIGNAL
};
-static guint e_addressbook_reflow_adapter_signals [LAST_SIGNAL] = {0, };
+static guint signals [LAST_SIGNAL] = {0, };
static void
unlink_model(EAddressbookReflowAdapter *adapter)
@@ -128,7 +128,7 @@ addressbook_count (EReflowModel *erm)
EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- return eab_model_contact_count (priv->model);
+ return e_addressbook_model_contact_count (priv->model);
}
/* This function returns the height of the minicontact in question */
@@ -140,7 +140,7 @@ addressbook_height (EReflowModel *erm, gint i, GnomeCanvasGroup *parent)
EContactField field;
gint count = 0;
gchar *string;
- EContact *contact = (EContact*)eab_model_contact_at (priv->model, i);
+ EContact *contact = (EContact*)e_addressbook_model_contact_at (priv->model, i);
PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (parent)->canvas), "");
gint height;
@@ -189,8 +189,8 @@ addressbook_compare (EReflowModel *erm, gint n1, gint n2)
return n1-n2;
}
else {
- contact1 = (EContact*)eab_model_contact_at (priv->model, n1);
- contact2 = (EContact*)eab_model_contact_at (priv->model, n2);
+ contact1 = (EContact*)e_addressbook_model_contact_at (priv->model, n1);
+ contact2 = (EContact*)e_addressbook_model_contact_at (priv->model, n2);
if (contact1 && contact2) {
const gchar *file_as1, *file_as2;
@@ -226,12 +226,20 @@ adapter_drag_begin (EMinicard *card, GdkEvent *event, EAddressbookReflowAdapter
gint ret_val = 0;
g_signal_emit (adapter,
- e_addressbook_reflow_adapter_signals[DRAG_BEGIN], 0,
+ signals[DRAG_BEGIN], 0,
event, &ret_val);
return ret_val;
}
+static void
+adapter_open_contact (EMinicard *card,
+ EContact *contact,
+ EAddressbookReflowAdapter *adapter)
+{
+ g_signal_emit (adapter, signals[OPEN_CONTACT], 0, contact);
+}
+
static GnomeCanvasItem *
addressbook_incarnate (EReflowModel *erm, gint i, GnomeCanvasGroup *parent)
{
@@ -241,8 +249,8 @@ addressbook_incarnate (EReflowModel *erm, gint i, GnomeCanvasGroup *parent)
item = gnome_canvas_item_new(parent,
e_minicard_get_type(),
- "contact", eab_model_contact_at (priv->model, i),
- "editable", eab_model_editable (priv->model),
+ "contact", e_addressbook_model_contact_at (priv->model, i),
+ "editable", e_addressbook_model_get_editable (priv->model),
NULL);
#if 0
@@ -251,7 +259,10 @@ addressbook_incarnate (EReflowModel *erm, gint i, GnomeCanvasGroup *parent)
#endif
g_signal_connect (item, "drag_begin",
- G_CALLBACK(adapter_drag_begin), adapter);
+ G_CALLBACK (adapter_drag_begin), adapter);
+
+ g_signal_connect (item, "open-contact",
+ G_CALLBACK (adapter_open_contact), adapter);
return item;
}
@@ -263,12 +274,12 @@ addressbook_reincarnate (EReflowModel *erm, gint i, GnomeCanvasItem *item)
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
gnome_canvas_item_set(item,
- "contact", eab_model_contact_at (priv->model, i),
+ "contact", e_addressbook_model_contact_at (priv->model, i),
NULL);
}
static void
-create_contact (EABModel *model,
+create_contact (EAddressbookModel *model,
gint index, gint count,
EAddressbookReflowAdapter *adapter)
{
@@ -278,7 +289,7 @@ create_contact (EABModel *model,
}
static void
-remove_contacts (EABModel *model,
+remove_contacts (EAddressbookModel *model,
gpointer data,
EAddressbookReflowAdapter *adapter)
{
@@ -293,7 +304,7 @@ remove_contacts (EABModel *model,
}
static void
-modify_contact (EABModel *model,
+modify_contact (EAddressbookModel *model,
gint index,
EAddressbookReflowAdapter *adapter)
{
@@ -301,14 +312,14 @@ modify_contact (EABModel *model,
}
static void
-model_changed (EABModel *model,
+model_changed (EAddressbookModel *model,
EAddressbookReflowAdapter *adapter)
{
e_reflow_model_changed (E_REFLOW_MODEL (adapter));
}
static void
-search_started (EABModel *model,
+search_started (EAddressbookModel *model,
EAddressbookReflowAdapter *adapter)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
@@ -317,7 +328,7 @@ search_started (EABModel *model,
}
static void
-search_result (EABModel *model,
+search_result (EAddressbookModel *model,
EBookViewStatus status,
EAddressbookReflowAdapter *adapter)
{
@@ -423,10 +434,10 @@ e_addressbook_reflow_adapter_class_init (GObjectClass *object_class)
g_param_spec_object ("model",
_("Model"),
/*_( */"XXX blurb" /*)*/,
- EAB_TYPE_MODEL,
+ E_TYPE_ADDRESSBOOK_MODEL,
G_PARAM_READABLE));
- e_addressbook_reflow_adapter_signals [DRAG_BEGIN] =
+ signals [DRAG_BEGIN] =
g_signal_new ("drag_begin",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
@@ -435,6 +446,16 @@ e_addressbook_reflow_adapter_class_init (GObjectClass *object_class)
e_marshal_INT__POINTER,
G_TYPE_INT, 1, G_TYPE_POINTER);
+ signals [OPEN_CONTACT] =
+ g_signal_new ("open-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookReflowAdapterClass, open_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CONTACT);
+
model_class->set_width = addressbook_set_width;
model_class->count = addressbook_count;
model_class->height = addressbook_height;
@@ -486,7 +507,7 @@ e_addressbook_reflow_adapter_get_type (void)
void
e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
- EABModel *model)
+ EAddressbookModel *model)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
@@ -520,7 +541,7 @@ e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
}
EReflowModel *
-e_addressbook_reflow_adapter_new (EABModel *model)
+e_addressbook_reflow_adapter_new (EAddressbookModel *model)
{
EAddressbookReflowAdapter *et;
@@ -538,5 +559,5 @@ e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter,
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- return eab_model_get_contact (priv->model, index);
+ return e_addressbook_model_get_contact (priv->model, index);
}
diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
index 0f8eb4102c..bc428ba30c 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
@@ -21,7 +21,7 @@
#ifndef _E_ADDRESSBOOK_REFLOW_ADAPTER_H_
#define _E_ADDRESSBOOK_REFLOW_ADAPTER_H_
-#include <misc/e-reflow-model.h>
+#include <text/e-reflow-model.h>
#include <libebook/e-contact.h>
#include "e-addressbook-model.h"
@@ -47,13 +47,16 @@ struct _EAddressbookReflowAdapterClass {
/*
* Signals
*/
- gint (* drag_begin) (EAddressbookReflowAdapter *adapter, GdkEvent *event);
+ gint (*drag_begin) (EAddressbookReflowAdapter *adapter,
+ GdkEvent *event);
+ void (*open_contact) (EAddressbookReflowAdapter *adapter,
+ EContact *contact);
};
GType e_addressbook_reflow_adapter_get_type (void);
void e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
- EABModel *model);
-EReflowModel *e_addressbook_reflow_adapter_new (EABModel *model);
+ EAddressbookModel *model);
+EReflowModel *e_addressbook_reflow_adapter_new (EAddressbookModel *model);
/* Returns object with ref count of 1. */
EContact *e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter,
diff --git a/addressbook/gui/widgets/e-addressbook-selector.c b/addressbook/gui/widgets/e-addressbook-selector.c
new file mode 100644
index 0000000000..21347e2529
--- /dev/null
+++ b/addressbook/gui/widgets/e-addressbook-selector.c
@@ -0,0 +1,443 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-addressbook-selector.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "e-addressbook-selector.h"
+
+#include <eab-book-util.h>
+#include <eab-contact-merging.h>
+
+#define E_ADDRESSBOOK_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorPrivate))
+
+#define PRIMARY_ADDRESSBOOK_KEY \
+ "/apps/evolution/addressbook/display/primary_addressbook"
+
+typedef struct _MergeContext MergeContext;
+
+struct _EAddressbookSelectorPrivate {
+ EAddressbookView *current_view;
+};
+
+struct _MergeContext {
+ EBook *source_book;
+ EBook *target_book;
+
+ EContact *current_contact;
+ GList *remaining_contacts;
+ guint pending_removals;
+
+ gint remove_from_source : 1;
+ gint copy_done : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_CURRENT_VIEW
+};
+
+enum {
+ DND_TARGET_TYPE_VCARD,
+ DND_TARGET_TYPE_SOURCE_VCARD
+};
+
+static GtkTargetEntry drag_types[] = {
+ { (gchar *) "text/x-vcard", 0, DND_TARGET_TYPE_VCARD },
+ { (gchar *) "text/x-source-vcard", 0, DND_TARGET_TYPE_SOURCE_VCARD }
+};
+
+static gpointer parent_class;
+
+static void
+merge_context_next (MergeContext *merge_context)
+{
+ GList *list;
+
+ list = merge_context->remaining_contacts;
+ merge_context->current_contact = list->data;
+ list = g_list_delete_link (list, list);
+ merge_context->remaining_contacts = list;
+}
+
+static MergeContext *
+merge_context_new (EBook *source_book,
+ EBook *target_book,
+ GList *contact_list)
+{
+ MergeContext *merge_context;
+
+ merge_context = g_slice_new0 (MergeContext);
+ merge_context->source_book = source_book;
+ merge_context->target_book = target_book;
+ merge_context->remaining_contacts = contact_list;
+ merge_context_next (merge_context);
+
+ return merge_context;
+}
+
+static void
+merge_context_free (MergeContext *merge_context)
+{
+ if (merge_context->source_book != NULL)
+ g_object_unref (merge_context->source_book);
+
+ if (merge_context->target_book != NULL)
+ g_object_unref (merge_context->target_book);
+
+ g_slice_free (MergeContext, merge_context);
+}
+
+static void
+addressbook_selector_removed_cb (EBook *book,
+ EBookStatus status,
+ MergeContext *merge_context)
+{
+ merge_context->pending_removals--;
+
+ if (merge_context->remaining_contacts != NULL)
+ return;
+
+ if (merge_context->pending_removals > 0)
+ return;
+
+ merge_context_free (merge_context);
+}
+
+static void
+addressbook_selector_merge_next_cb (EBook *book,
+ EBookStatus status,
+ const gchar *id,
+ MergeContext *merge_context)
+{
+ if (merge_context->remove_from_source && status == E_BOOK_ERROR_OK) {
+ /* Remove previous contact from source. */
+ e_book_async_remove_contact (
+ merge_context->source_book,
+ merge_context->current_contact,
+ (EBookCallback) addressbook_selector_removed_cb,
+ merge_context);
+ merge_context->pending_removals++;
+ }
+
+ g_object_unref (merge_context->current_contact);
+
+ if (merge_context->remaining_contacts != NULL) {
+ merge_context_next (merge_context);
+ eab_merging_book_add_contact (
+ merge_context->target_book,
+ merge_context->current_contact,
+ (EBookIdCallback) addressbook_selector_merge_next_cb,
+ merge_context);
+
+ } else if (merge_context->pending_removals == 0)
+ merge_context_free (merge_context);
+}
+
+static void
+addressbook_selector_load_primary_source (ESourceSelector *selector)
+{
+ GConfClient *client;
+ ESourceList *source_list;
+ ESource *source = NULL;
+ const gchar *key;
+ gchar *uid;
+
+ /* XXX If ESourceSelector had a "primary-uid" property,
+ * we could just bind the GConf key to it. */
+
+ source_list = e_source_selector_get_source_list (selector);
+
+ client = gconf_client_get_default ();
+ key = PRIMARY_ADDRESSBOOK_KEY;
+ uid = gconf_client_get_string (client, key, NULL);
+ g_object_unref (client);
+
+ if (uid != NULL) {
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ g_free (uid);
+ } else {
+ GSList *groups;
+
+ /* Dig up the first source in the source list.
+ * XXX libedataserver should provide API for this. */
+ groups = e_source_list_peek_groups (source_list);
+ while (groups != NULL) {
+ ESourceGroup *source_group = groups->data;
+ GSList *sources;
+
+ sources = e_source_group_peek_sources (source_group);
+ if (sources != NULL) {
+ source = sources->data;
+ break;
+ }
+
+ groups = g_slist_next (groups);
+ }
+ }
+
+ if (source != NULL)
+ e_source_selector_set_primary_selection (selector, source);
+}
+
+static void
+addressbook_selector_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ e_addressbook_selector_set_current_view (
+ E_ADDRESSBOOK_SELECTOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+addressbook_selector_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ g_value_set_object (
+ value,
+ e_addressbook_selector_get_current_view (
+ E_ADDRESSBOOK_SELECTOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+addressbook_selector_dispose (GObject *object)
+{
+ EAddressbookSelectorPrivate *priv;
+
+ priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (object);
+
+ if (priv->current_view != NULL) {
+ g_object_unref (priv->current_view);
+ priv->current_view = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+addressbook_selector_constructed (GObject *object)
+{
+ ESourceSelector *selector;
+
+ selector = E_SOURCE_SELECTOR (object);
+ addressbook_selector_load_primary_source (selector);
+}
+
+static void
+addressbook_selector_primary_selection_changed (ESourceSelector *selector)
+{
+ ESource *source;
+ GConfClient *client;
+ const gchar *key;
+ const gchar *string;
+
+ /* XXX If ESourceSelector had a "primary-uid" property,
+ * we could just bind the GConf key to it. */
+
+ source = e_source_selector_peek_primary_selection (selector);
+ if (source == NULL)
+ return;
+
+ client = gconf_client_get_default ();
+ key = PRIMARY_ADDRESSBOOK_KEY;
+ string = e_source_peek_uid (source);
+ gconf_client_set_string (client, key, string, NULL);
+ g_object_unref (client);
+}
+
+static gboolean
+addressbook_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
+{
+ EAddressbookSelectorPrivate *priv;
+ MergeContext *merge_context;
+ EAddressbookModel *model;
+ EBook *source_book;
+ EBook *target_book;
+ GList *list;
+ const gchar *string;
+ gboolean remove_from_source;
+
+ priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (selector);
+ g_return_val_if_fail (priv->current_view != NULL, FALSE);
+
+ string = (const gchar *) selection_data->data;
+ remove_from_source = (action == GDK_ACTION_MOVE);
+
+ target_book = e_book_new (destination, NULL);
+ if (target_book == NULL)
+ return FALSE;
+
+ e_book_open (target_book, FALSE, NULL);
+
+ /* XXX Function assumes both out arguments are provided. All we
+ * care about is the contact list; source_book will be NULL. */
+ eab_book_and_contact_list_from_string (string, &source_book, &list);
+ if (list == NULL)
+ return FALSE;
+
+ model = e_addressbook_view_get_model (priv->current_view);
+ source_book = e_addressbook_model_get_book (model);
+ g_return_val_if_fail (E_IS_BOOK (source_book), FALSE);
+
+ merge_context = merge_context_new (source_book, target_book, list);
+ merge_context->remove_from_source = remove_from_source;
+
+ eab_merging_book_add_contact (
+ target_book, merge_context->current_contact,
+ (EBookIdCallback) addressbook_selector_merge_next_cb,
+ merge_context);
+
+ return TRUE;
+}
+
+static void
+addressbook_selector_class_init (EAddressbookSelectorClass *class)
+{
+ GObjectClass *object_class;
+ ESourceSelectorClass *selector_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EAddressbookSelectorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_selector_set_property;
+ object_class->get_property = addressbook_selector_get_property;
+ object_class->dispose = addressbook_selector_dispose;
+ object_class->constructed = addressbook_selector_constructed;
+
+ selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ selector_class->primary_selection_changed =
+ addressbook_selector_primary_selection_changed;
+ selector_class->data_dropped = addressbook_selector_data_dropped;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CURRENT_VIEW,
+ g_param_spec_object (
+ "current-view",
+ NULL,
+ NULL,
+ E_TYPE_ADDRESSBOOK_VIEW,
+ G_PARAM_READWRITE));
+}
+
+static void
+addressbook_selector_init (EAddressbookSelector *selector)
+{
+ selector->priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (selector);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+}
+
+GType
+e_addressbook_selector_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EAddressbookSelectorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) addressbook_selector_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EAddressbookSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) addressbook_selector_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_SOURCE_SELECTOR, "EAddressbookSelector",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_addressbook_selector_new (ESourceList *source_list)
+{
+ g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
+
+ return g_object_new (
+ E_TYPE_ADDRESSBOOK_SELECTOR,
+ "source-list", source_list, NULL);
+}
+
+EAddressbookView *
+e_addressbook_selector_get_current_view (EAddressbookSelector *selector)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector), NULL);
+
+ return selector->priv->current_view;
+}
+
+void
+e_addressbook_selector_set_current_view (EAddressbookSelector *selector,
+ EAddressbookView *current_view)
+{
+ /* XXX This is only needed for moving contacts via drag-and-drop.
+ * The selection data doesn't include the source of the data
+ * (the model for the currently selected address book view),
+ * so we have to rely on it being provided to us. I would
+ * be happy to see this function go away. */
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector));
+
+ if (current_view != NULL)
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (current_view));
+
+ if (selector->priv->current_view != NULL) {
+ g_object_unref (selector->priv->current_view);
+ selector->priv->current_view = NULL;
+ }
+
+ if (current_view != NULL)
+ g_object_ref (current_view);
+
+ selector->priv->current_view = current_view;
+
+ g_object_notify (G_OBJECT (selector), "current-view");
+}
diff --git a/addressbook/gui/widgets/e-addressbook-selector.h b/addressbook/gui/widgets/e-addressbook-selector.h
new file mode 100644
index 0000000000..c0102cb3b8
--- /dev/null
+++ b/addressbook/gui/widgets/e-addressbook-selector.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-addressbook-selector.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef E_ADDRESSBOOK_SELECTOR_H
+#define E_ADDRESSBOOK_SELECTOR_H
+
+#include <libedataserver/e-source-list.h>
+#include <libedataserverui/e-source-selector.h>
+#include "e-addressbook-view.h"
+
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_SELECTOR \
+ (e_addressbook_selector_get_type ())
+#define E_ADDRESSBOOK_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelector))
+#define E_ADDRESSBOOK_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorClass))
+#define E_IS_ADDRESSBOOK_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR))
+#define E_IS_ADDRESSBOOK_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ADDRESSBOOK_SELECTOR))
+#define E_ADDRESSBOOK_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EAddressbookSelector EAddressbookSelector;
+typedef struct _EAddressbookSelectorClass EAddressbookSelectorClass;
+typedef struct _EAddressbookSelectorPrivate EAddressbookSelectorPrivate;
+
+struct _EAddressbookSelector {
+ ESourceSelector parent;
+ EAddressbookSelectorPrivate *priv;
+};
+
+struct _EAddressbookSelectorClass {
+ ESourceSelectorClass parent_class;
+};
+
+GType e_addressbook_selector_get_type (void);
+GtkWidget * e_addressbook_selector_new (ESourceList *source_list);
+EAddressbookView *
+ e_addressbook_selector_get_current_view
+ (EAddressbookSelector *selector);
+void e_addressbook_selector_set_current_view
+ (EAddressbookSelector *selector,
+ EAddressbookView *current_view);
+
+G_END_DECLS
+
+#endif /* E_ADDRESSBOOK_SELECTOR_H */
diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.c b/addressbook/gui/widgets/e-addressbook-table-adapter.c
index a081ebb34d..396c382d32 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.c
@@ -31,7 +31,7 @@
#include <libxml/xmlmemory.h>
struct _EAddressbookTableAdapterPrivate {
- EABModel *model;
+ EAddressbookModel *model;
gint create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
@@ -100,7 +100,7 @@ addressbook_row_count (ETableModel *etc)
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- return eab_model_contact_count (priv->model);
+ return e_addressbook_model_contact_count (priv->model);
}
/* This function returns the value at a particular point in our ETableModel. */
@@ -111,10 +111,10 @@ addressbook_value_at (ETableModel *etc, gint col, gint row)
EAddressbookTableAdapterPrivate *priv = adapter->priv;
const gchar *value;
- if ( col >= COLS || row >= eab_model_contact_count (priv->model) )
+ if ( col >= COLS || row >= e_addressbook_model_contact_count (priv->model) )
return NULL;
- value = e_contact_get_const((EContact*)eab_model_contact_at (priv->model, row), col);
+ value = e_contact_get_const((EContact*)e_addressbook_model_contact_at (priv->model, row), col);
if (value && *value && (col == E_CONTACT_EMAIL_1 || col == E_CONTACT_EMAIL_2 || col == E_CONTACT_EMAIL_3)) {
gchar *val = g_hash_table_lookup (priv->emails, value);
@@ -156,13 +156,13 @@ addressbook_set_value_at (ETableModel *etc, gint col, gint row, gconstpointer va
EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- if (eab_model_editable (priv->model)) {
+ if (e_addressbook_model_get_editable (priv->model)) {
EContact *contact;
- if (col >= COLS || row >= eab_model_contact_count (priv->model))
+ if (col >= COLS || row >= e_addressbook_model_contact_count (priv->model))
return;
- contact = eab_model_get_contact (priv->model, row);
+ contact = e_addressbook_model_get_contact (priv->model, row);
if (!contact)
return;
@@ -177,7 +177,7 @@ addressbook_set_value_at (ETableModel *etc, gint col, gint row, gconstpointer va
}
e_contact_set(contact, col, (gpointer) val);
- eab_merging_book_commit_contact (eab_model_get_ebook (priv->model),
+ eab_merging_book_commit_contact (e_addressbook_model_get_book (priv->model),
contact, contact_modified_cb, etc);
g_object_unref (contact);
@@ -196,12 +196,12 @@ addressbook_is_cell_editable (ETableModel *etc, gint col, gint row)
EAddressbookTableAdapterPrivate *priv = adapter->priv;
const EContact *contact;
- if (row >= 0 && row < eab_model_contact_count (priv->model))
- contact = eab_model_contact_at (priv->model, row);
+ if (row >= 0 && row < e_addressbook_model_contact_count (priv->model))
+ contact = e_addressbook_model_contact_at (priv->model, row);
else
contact = NULL;
- if (!eab_model_editable(priv->model))
+ if (!e_addressbook_model_editable(priv->model))
return FALSE;
else if (contact && e_contact_get ((EContact *) contact, E_CONTACT_IS_LIST))
/* we only allow editing of the name and file as for
@@ -229,7 +229,7 @@ addressbook_append_row (ETableModel *etm, ETableModel *source, gint row)
e_contact_set (contact, col, (gpointer) val);
}
- eab_merging_book_add_contact (eab_model_get_ebook (priv->model), contact, NULL, NULL);
+ eab_merging_book_add_contact (e_addressbook_model_get_book (priv->model), contact, NULL, NULL);
g_object_unref (contact);
}
@@ -303,7 +303,7 @@ eab_table_adapter_init (GObject *object)
}
static void
-create_contact (EABModel *model,
+create_contact (EAddressbookModel *model,
gint index, gint count,
EAddressbookTableAdapter *adapter)
{
@@ -312,7 +312,7 @@ create_contact (EABModel *model,
}
static void
-remove_contacts (EABModel *model,
+remove_contacts (EAddressbookModel *model,
gpointer data,
EAddressbookTableAdapter *adapter)
{
@@ -330,7 +330,7 @@ remove_contacts (EABModel *model,
}
static void
-modify_contact (EABModel *model,
+modify_contact (EAddressbookModel *model,
gint index,
EAddressbookTableAdapter *adapter)
{
@@ -342,7 +342,7 @@ modify_contact (EABModel *model,
}
static void
-model_changed (EABModel *model,
+model_changed (EAddressbookModel *model,
EAddressbookTableAdapter *adapter)
{
/* clear whole cache */
@@ -378,7 +378,7 @@ eab_table_adapter_get_type (void)
void
eab_table_adapter_construct (EAddressbookTableAdapter *adapter,
- EABModel *model)
+ EAddressbookModel *model)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
@@ -406,7 +406,7 @@ eab_table_adapter_construct (EAddressbookTableAdapter *adapter,
}
ETableModel *
-eab_table_adapter_new (EABModel *model)
+eab_table_adapter_new (EAddressbookModel *model)
{
EAddressbookTableAdapter *et;
diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.h b/addressbook/gui/widgets/e-addressbook-table-adapter.h
index 27bfe0e3f4..71999bd4d1 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.h
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.h
@@ -47,7 +47,7 @@ struct _EAddressbookTableAdapterClass {
GType eab_table_adapter_get_type (void);
void eab_table_adapter_construct (EAddressbookTableAdapter *adapter,
- EABModel *model);
-ETableModel *eab_table_adapter_new (EABModel *model);
+ EAddressbookModel *model);
+ETableModel *eab_table_adapter_new (EAddressbookModel *model);
#endif /* _EAB_TABLE_ADAPTER_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index 283b25f89f..c606530594 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -31,12 +31,10 @@
#include <widgets/menus/gal-view-factory-etable.h>
#include <filter/rule-editor.h>
#include <widgets/menus/gal-view-etable.h>
-#include <e-util/e-xml-utils.h>
+#include <shell/e-shell-sidebar.h>
#include "addressbook/printing/e-contact-print.h"
-#include "addressbook/gui/widgets/eab-popup.h"
-#include "addressbook/gui/widgets/eab-menu.h"
-#include "a11y/addressbook/ea-addressbook.h"
+#include "ea-addressbook.h"
#include "e-util/e-print.h"
#include "e-util/e-util.h"
@@ -56,1538 +54,954 @@
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
-#include "e-contact-editor.h"
#include <gdk/gdkkeysyms.h>
#include <ctype.h>
#include <string.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-
-#define SHOW_ALL_SEARCH "(contains \"x-evolution-any-field\" \"\")"
+#define E_ADDRESSBOOK_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewPrivate))
#define d(x)
-static void eab_view_init (EABView *card);
-static void eab_view_class_init (EABViewClass *class);
-
-static void eab_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void eab_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-
-static void eab_view_dispose (GObject *object);
-static void change_view_type (EABView *view, EABViewType view_type);
-
-static void status_message (GtkObject *object, const gchar *status, EABView *eav);
-static void search_result (GtkObject *object, EBookViewStatus status, EABView *eav);
-static void folder_bar_message (GtkObject *object, const gchar *status, EABView *eav);
-static void stop_state_changed (GtkObject *object, EABView *eav);
-static void writable_status (GtkObject *object, gboolean writable, EABView *eav);
-static void backend_died (GtkObject *object, EABView *eav);
-static void contact_changed (EABModel *model, gint index, EABView *eav);
-static void contacts_removed (EABModel *model, gpointer data, EABView *eav);
-static GList *get_selected_contacts (EABView *view);
-
-static void command_state_change (EABView *eav);
-
-static void selection_clear_event (GtkWidget *invisible, GdkEventSelection *event,
- EABView *view);
-static void selection_received (GtkWidget *invisible, GtkSelectionData *selection_data,
- guint time, EABView *view);
-static void selection_get (GtkWidget *invisible, GtkSelectionData *selection_data,
- guint info, guint time_stamp, EABView *view);
-static void invisible_destroyed (gpointer data, GObject *where_object_was);
-
-static void categories_changed_cb (gpointer object, gpointer user_data);
-static void make_suboptions (EABView *view);
-static void query_changed (ESearchBar *esb, EABView *view);
-static void search_activated (ESearchBar *esb, EABView *view);
-static void search_menu_activated (ESearchBar *esb, gint id, EABView *view);
-static GList *get_master_list (gboolean force_rebuild);
+static void status_message (EAddressbookView *view, const gchar *status);
+static void search_result (EAddressbookView *view, EBookViewStatus status);
+static void folder_bar_message (EAddressbookView *view, const gchar *status);
+static void stop_state_changed (GtkObject *object, EAddressbookView *view);
+static void backend_died (EAddressbookView *view);
-static gpointer parent_class;
+static void command_state_change (EAddressbookView *view);
+
+struct _EAddressbookViewPrivate {
+ gpointer shell_view; /* weak pointer */
+
+ EAddressbookModel *model;
+ EActivity *activity;
+
+ GList *clipboard_contacts;
+ ESource *source;
+
+ GObject *object;
+ GtkWidget *widget;
+
+ GalViewInstance *view_instance;
+
+ GtkWidget *invisible;
+};
-/* The arguments we take */
enum {
PROP_0,
- PROP_BOOK,
- PROP_SOURCE,
- PROP_QUERY,
- PROP_TYPE
+ PROP_MODEL,
+ PROP_SHELL_VIEW,
+ PROP_SOURCE
};
enum {
- STATUS_MESSAGE,
- SEARCH_RESULT,
- FOLDER_BAR_MESSAGE,
+ OPEN_CONTACT,
+ POPUP_EVENT,
COMMAND_STATE_CHANGE,
+ SELECTION_CHANGE,
LAST_SIGNAL
};
-enum DndTargetType {
+enum {
DND_TARGET_TYPE_SOURCE_VCARD,
DND_TARGET_TYPE_VCARD
};
-#define VCARD_TYPE "text/x-vcard"
-#define SOURCE_VCARD_TYPE "text/x-source-vcard"
-
-typedef struct EABSearchBarItem {
- ESearchBarItem search;
- gchar *image;
-}EABSearchBarItem;
static GtkTargetEntry drag_types[] = {
- { (gchar *) SOURCE_VCARD_TYPE, 0, DND_TARGET_TYPE_SOURCE_VCARD },
- { (gchar *) VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD }
+ { (gchar *) "text/x-source-vcard", 0, DND_TARGET_TYPE_SOURCE_VCARD },
+ { (gchar *) "text/x-vcard", 0, DND_TARGET_TYPE_VCARD }
};
-static const gint num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
-
-static guint eab_view_signals [LAST_SIGNAL] = {0, };
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
static GdkAtom clipboard_atom = GDK_NONE;
-static GalViewCollection *collection = NULL;
-
-enum {
- ESB_FULL_NAME,
- ESB_EMAIL,
- ESB_ANY
-};
-
-#if 0
-static ESearchBarItem addressbook_search_option_items[] = {
- { N_("Name begins with"), ESB_FULL_NAME, ESB_ITEMTYPE_RADIO },
- { N_("Email begins with"), ESB_EMAIL, ESB_ITEMTYPE_RADIO },
- { N_("Any field contains"), ESB_ANY, ESB_ITEMTYPE_RADIO },
- { NULL, -1, 0 }
-};
-#endif
-
-static ESearchBarItem addressbook_search_items[] = {
- E_FILTERBAR_ADVANCED,
- {NULL, 0, 0},
- E_FILTERBAR_SAVE,
- E_FILTERBAR_EDIT,
- {NULL, -1, 0}
-};
-
-GType
-eab_view_get_type (void)
+static void
+addressbook_view_emit_open_contact (EAddressbookView *view,
+ EContact *contact,
+ gboolean is_new_contact)
{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EABViewClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) eab_view_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EABView),
- 0, /* n_preallocs */
- (GInstanceInitFunc) eab_view_init,
- };
-
- type = g_type_register_static (GTK_TYPE_VBOX, "EABView", &info, 0);
- }
-
- return type;
+ g_signal_emit (view, signals[OPEN_CONTACT], 0, contact, is_new_contact);
}
static void
-eab_view_class_init (EABViewClass *class)
+addressbook_view_emit_popup_event (EAddressbookView *view,
+ GdkEvent *event)
{
- GObjectClass *object_class;
-
- parent_class = g_type_class_peek_parent (class);
-
- object_class = G_OBJECT_CLASS(class);
- object_class->set_property = eab_view_set_property;
- object_class->get_property = eab_view_get_property;
- object_class->dispose = eab_view_dispose;
-
- g_object_class_install_property (object_class, PROP_BOOK,
- g_param_spec_object ("book",
- _("Book"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_BOOK,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_SOURCE,
- g_param_spec_object ("source",
- _("Source"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_SOURCE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_QUERY,
- g_param_spec_string ("query",
- _("Query"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_TYPE,
- g_param_spec_int ("type",
- _("Type"),
- /*_( */"XXX blurb" /*)*/,
- EAB_VIEW_NONE,
- EAB_VIEW_TABLE,
- EAB_VIEW_NONE,
- G_PARAM_READWRITE));
-
- eab_view_signals [STATUS_MESSAGE] =
- g_signal_new ("status_message",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABViewClass, status_message),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-
- eab_view_signals [SEARCH_RESULT] =
- g_signal_new ("search_result",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABViewClass, search_result),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1, G_TYPE_INT);
-
- eab_view_signals [FOLDER_BAR_MESSAGE] =
- g_signal_new ("folder_bar_message",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABViewClass, folder_bar_message),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-
- eab_view_signals [COMMAND_STATE_CHANGE] =
- g_signal_new ("command_state_change",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EABViewClass, command_state_change),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- if (!clipboard_atom)
- clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
-
- /* init the accessibility support for e_addressbook_view */
- eab_view_a11y_init();
+ g_signal_emit (view, signals[POPUP_EVENT], 0, event);
}
static void
-eab_view_init (EABView *eav)
+addressbook_view_emit_selection_change (EAddressbookView *view)
{
- eav->view_type = EAB_VIEW_NONE;
-
- eav->model = NULL;
- eav->object = NULL;
- eav->widget = NULL;
- eav->contact_display_window = NULL;
- eav->contact_display = NULL;
- eav->displayed_contact = -1;
-
- eav->view_instance = NULL;
- eav->view_menus = NULL;
- eav->current_view = NULL;
- eav->uic = NULL;
-
- eav->book = NULL;
- eav->source = NULL;
- eav->query = NULL;
-
- eav->invisible = NULL;
- eav->clipboard_contacts = NULL;
+ g_signal_emit (view, signals[SELECTION_CHANGE], 0);
}
static void
-eab_view_dispose (GObject *object)
+addressbook_view_open_contact (EAddressbookView *view,
+ EContact *contact)
{
- EABView *eav = EAB_VIEW(object);
-
- e_categories_unregister_change_listener (G_CALLBACK (categories_changed_cb), eav);
-
- if (eav->model) {
- g_signal_handlers_disconnect_matched (eav->model,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL,
- object);
- g_object_unref (eav->model);
- eav->model = NULL;
- }
-
- if (eav->book) {
- g_object_unref (eav->book);
- eav->book = NULL;
- }
-
- if (eav->source) {
- g_object_unref (eav->source);
- eav->source = NULL;
- }
-
- if (eav->query) {
- g_free(eav->query);
- eav->query = NULL;
- }
-
- eav->uic = NULL;
-
- if (eav->view_instance) {
- g_object_unref (eav->view_instance);
- eav->view_instance = NULL;
- }
-
- if (eav->view_menus) {
- g_object_unref (eav->view_menus);
- eav->view_menus = NULL;
- }
-
- if (eav->clipboard_contacts) {
- g_list_foreach (eav->clipboard_contacts, (GFunc)g_object_unref, NULL);
- g_list_free (eav->clipboard_contacts);
- eav->clipboard_contacts = NULL;
- }
-
- if (eav->invisible) {
- gtk_widget_destroy (eav->invisible);
- eav->invisible = NULL;
- }
-
- /*
- if (eav->search_context) {
- g_object_unref (eav->search_context);
- eav->search_context = NULL;
- }
- */
-
- if (eav->search_rule) {
- g_object_unref (eav->search_rule);
- eav->search_rule = NULL;
- }
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
+ addressbook_view_emit_open_contact (view, contact, FALSE);
}
static void
-set_paned_position (EABView *eav)
+addressbook_view_create_contact (EAddressbookView *view)
{
- GConfClient *gconf_client;
- gint pos;
-
- /* XXX this should use the addressbook's global gconf client */
- gconf_client = gconf_client_get_default ();
- pos = gconf_client_get_int (gconf_client, "/apps/evolution/addressbook/display/vpane_position", NULL);
- if (pos < 1)
- pos = 144;
-
- gtk_paned_set_position (GTK_PANED (eav->paned), pos);
+ EContact *contact;
- g_object_unref (gconf_client);
+ contact = e_contact_new ();
+ addressbook_view_emit_open_contact (view, contact, TRUE);
+ g_object_unref (contact);
}
-static gboolean
-get_paned_position (EABView *eav)
+static void
+addressbook_view_create_contact_list (EAddressbookView *view)
{
- GConfClient *gconf_client;
- gint pos;
-
- /* XXX this should use the addressbook's global gconf client */
- gconf_client = gconf_client_get_default ();
-
- pos = gtk_paned_get_position (GTK_PANED (eav->paned));
- gconf_client_set_int (gconf_client, "/apps/evolution/addressbook/display/vpane_position", pos, NULL);
-
- g_object_unref (gconf_client);
+ EContact *contact;
- return FALSE;
+ contact = e_contact_new ();
+ e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE));
+ addressbook_view_emit_open_contact (view, contact, TRUE);
+ g_object_unref (contact);
}
-GtkWidget*
-eab_view_new (void)
+static void
+table_double_click (ETableScrolled *table,
+ gint row,
+ gint col,
+ GdkEvent *event,
+ EAddressbookView *view)
{
- GtkWidget *widget = GTK_WIDGET (g_object_new (E_TYPE_AB_VIEW, NULL));
- EABView *eav = EAB_VIEW (widget);
- FilterPart *part;
- gchar *xmlfile;
- gchar *userfile;
-
- /* create our model */
- eav->model = eab_model_new ();
-
- g_signal_connect (eav->model, "status_message",
- G_CALLBACK (status_message), eav);
- g_signal_connect (eav->model, "search_result",
- G_CALLBACK (search_result), eav);
- g_signal_connect (eav->model, "folder_bar_message",
- G_CALLBACK (folder_bar_message), eav);
- g_signal_connect (eav->model, "stop_state_changed",
- G_CALLBACK (stop_state_changed), eav);
- g_signal_connect (eav->model, "writable_status",
- G_CALLBACK (writable_status), eav);
- g_signal_connect (eav->model, "backend_died",
- G_CALLBACK (backend_died), eav);
- g_signal_connect (eav->model, "contact_changed",
- G_CALLBACK (contact_changed), eav);
- g_signal_connect (eav->model, "contacts_removed",
- G_CALLBACK (contacts_removed), eav);
-
- eav->editable = FALSE;
- eav->query = g_strdup (SHOW_ALL_SEARCH);
-
- /* create the search context */
- eav->search_context = rule_context_new ();
- rule_context_add_part_set (eav->search_context, "partset", filter_part_get_type (),
- rule_context_add_part, rule_context_next_part);
- rule_context_add_rule_set (eav->search_context, "ruleset", filter_rule_get_type (),
- rule_context_add_rule, rule_context_next_rule);
-
- userfile = g_build_filename ( g_get_home_dir (), ".evolution/addressbook/searches.xml", NULL);
- xmlfile = g_build_filename (SEARCH_RULE_DIR, "addresstypes.xml", NULL);
-
- g_object_set_data_full (G_OBJECT (eav->search_context), "user", userfile, g_free);
- g_object_set_data_full (G_OBJECT (eav->search_context), "system", xmlfile, g_free);
-
- rule_context_load (eav->search_context, xmlfile, userfile);
-
- eav->search_rule = filter_rule_new ();
- part = rule_context_next_part (eav->search_context, NULL);
-
- if (part == NULL)
- g_warning ("Could not load addressbook search; no parts.");
- else
- filter_rule_add_part (eav->search_rule, filter_part_clone (part));
-
- eav->search = e_filter_bar_new (eav->search_context, xmlfile, userfile, NULL, eav);
-
- g_free (xmlfile);
- g_free (userfile);
-
- e_search_bar_set_menu ( (ESearchBar *) eav->search, addressbook_search_items);
- gtk_widget_show (GTK_WIDGET (eav->search));
- make_suboptions (eav);
-
- e_categories_register_change_listener (G_CALLBACK (categories_changed_cb), eav);
-
- g_signal_connect (eav->search, "query_changed",
- G_CALLBACK (query_changed), eav);
- g_signal_connect (eav->search, "search_activated",
- G_CALLBACK (search_activated), eav);
- g_signal_connect (eav->search, "menu_activated",
- G_CALLBACK (search_menu_activated), eav);
-
- gtk_box_pack_start (GTK_BOX (eav), GTK_WIDGET (eav->search), FALSE, FALSE, 0);
-
- /* create the paned window and contact display */
- eav->paned = gtk_vpaned_new ();
- gtk_box_pack_start (GTK_BOX (eav), eav->paned, TRUE, TRUE, 0);
- g_signal_connect_swapped (eav->paned, "button_release_event",
- G_CALLBACK (get_paned_position), eav);
-
- eav->contact_display = eab_contact_display_new ();
- eav->contact_display_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (eav->contact_display_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (eav->contact_display_window), GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (eav->contact_display_window), eav->contact_display);
- gtk_paned_add2 (GTK_PANED (eav->paned), eav->contact_display_window);
- gtk_widget_show (eav->contact_display);
- gtk_widget_show (eav->contact_display_window);
- gtk_widget_show (eav->paned);
-
- /* gtk selection crap */
- eav->invisible = gtk_invisible_new ();
-
- gtk_selection_add_target (eav->invisible,
- clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- 0);
-
- g_signal_connect (eav->invisible, "selection_get",
- G_CALLBACK (selection_get),
- eav);
- g_signal_connect (eav->invisible, "selection_clear_event",
- G_CALLBACK (selection_clear_event),
- eav);
- g_signal_connect (eav->invisible, "selection_received",
- G_CALLBACK (selection_received),
- eav);
- g_object_weak_ref (G_OBJECT (eav->invisible), invisible_destroyed, eav);
+ EAddressbookModel *model;
+ EContact *contact;
- return widget;
-}
+ if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER (view->priv->object))
+ return;
-RuleContext *
-eab_view_peek_search_context (EABView *view)
-{
- return view->search_context;
+ model = e_addressbook_view_get_model (view);
+ contact = e_addressbook_model_get_contact (model, row);
+ addressbook_view_emit_open_contact (view, contact, FALSE);
+ g_object_unref (contact);
}
-FilterRule *
-eab_view_peek_search_rule (EABView *view)
+static gint
+table_right_click (ETableScrolled *table,
+ gint row,
+ gint col,
+ GdkEvent *event,
+ EAddressbookView *view)
{
- return view->search_rule;
-}
+ addressbook_view_emit_popup_event (view, event);
-static void
-writable_status (GtkObject *object, gboolean writable, EABView *eav)
-{
- eav->editable = writable;
- command_state_change (eav);
+ return TRUE;
}
-static void
-init_collection (void)
+static gint
+table_white_space_event (ETableScrolled *table,
+ GdkEvent *event,
+ EAddressbookView *view)
{
- GalViewFactory *factory;
- ETableSpecification *spec;
- gchar *galview;
- gchar *addressbookdir;
- gchar *etspecfile;
+ gint button = ((GdkEventButton *) event)->button;
- if (collection == NULL) {
- collection = gal_view_collection_new();
-
- gal_view_collection_set_title (collection, _("Address Book"));
-
- galview = g_build_filename (
- e_get_user_data_dir (), "addressbook", "views", NULL);
- addressbookdir = g_build_filename (EVOLUTION_GALVIEWSDIR,
- "addressbook",
- NULL);
- gal_view_collection_set_storage_directories
- (collection,
- addressbookdir,
- galview);
- g_free(addressbookdir);
- g_free(galview);
-
- spec = e_table_specification_new();
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "e-addressbook-view.etspec",
- NULL);
- if (!e_table_specification_load_from_file (spec, etspecfile))
- g_error ("Unable to load ETable specification file "
- "for address book");
- g_free (etspecfile);
-
- factory = gal_view_factory_etable_new (spec);
- g_object_unref (spec);
- gal_view_collection_add_factory (collection, factory);
- g_object_unref (factory);
-
- factory = gal_view_factory_minicard_new();
- gal_view_collection_add_factory (collection, factory);
- g_object_unref (factory);
-
- gal_view_collection_load(collection);
+ if (event->type == GDK_BUTTON_PRESS && button == 3) {
+ addressbook_view_emit_popup_event (view, event);
+ return TRUE;
}
+
+ return FALSE;
}
static void
-set_view_preview (EABView *view)
-{
- /* XXX this should use the addressbook's global gconf client */
- GConfClient *gconf_client;
- gboolean state;
+table_drag_data_get (ETable *table,
+ gint row,
+ gint col,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer user_data)
+{
+ EAddressbookView *view = user_data;
+ EAddressbookModel *model;
+ EBook *book;
+ GList *contact_list;
+ gchar *value;
- gconf_client = gconf_client_get_default();
- state = gconf_client_get_bool(gconf_client, "/apps/evolution/addressbook/display/show_preview", NULL);
- bonobo_ui_component_set_prop (view->uic,
- "/commands/ContactsViewPreview",
- "state",
- state ? "1" : "0", NULL);
+ if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER (view->priv->object))
+ return;
- eab_view_show_contact_preview (view, state);
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
- g_object_unref (gconf_client);
-}
+ contact_list = e_addressbook_view_get_selected (view);
-static void
-display_view(GalViewInstance *instance,
- GalView *view,
- gpointer data)
-{
- EABView *address_view = data;
- if (GAL_IS_VIEW_ETABLE(view)) {
- change_view_type (address_view, EAB_VIEW_TABLE);
- gal_view_etable_attach_table (GAL_VIEW_ETABLE(view), e_table_scrolled_get_table(E_TABLE_SCROLLED(address_view->widget)));
- }
- else if (GAL_IS_VIEW_MINICARD(view)) {
- change_view_type (address_view, EAB_VIEW_MINICARD);
- gal_view_minicard_attach (GAL_VIEW_MINICARD (view), address_view);
- }
- address_view->current_view = view;
+ switch (info) {
+ case DND_TARGET_TYPE_VCARD:
+ value = eab_contact_list_to_string (contact_list);
- set_paned_position (address_view);
- set_view_preview (address_view);
-}
+ gtk_selection_data_set (
+ selection_data, selection_data->target,
+ 8, (guchar *)value, strlen (value));
-static void
-view_preview(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- /* XXX this should use the addressbook's global gconf client */
- GConfClient *gconf_client;
- EABView *view = EAB_VIEW (data);
+ g_free (value);
+ break;
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
+ case DND_TARGET_TYPE_SOURCE_VCARD:
+ value = eab_book_and_contact_list_to_string (
+ book, contact_list);
- gconf_client = gconf_client_get_default();
- gconf_client_set_bool(gconf_client, "/apps/evolution/addressbook/display/show_preview", state[0] != '0', NULL);
+ gtk_selection_data_set (
+ selection_data, selection_data->target,
+ 8, (guchar *)value, strlen (value));
- eab_view_show_contact_preview(view, state[0] != '0');
+ g_free (value);
+ break;
+ }
- g_object_unref (gconf_client);
+ g_list_foreach (contact_list, (GFunc) g_object_unref, NULL);
+ g_list_free (contact_list);
}
static void
-setup_menus (EABView *view)
+addressbook_view_create_table_view (EAddressbookView *view)
{
- if (view->book && view->view_instance == NULL) {
- init_collection ();
- view->view_instance = gal_view_instance_new (collection, e_book_get_uri (view->book));
- }
-
- if (view->view_instance && view->uic) {
- view->view_menus = gal_view_menus_new(view->view_instance);
- gal_view_menus_apply(view->view_menus, view->uic, NULL);
+ ETableModel *adapter;
+ ETableExtras *extras;
+ ECell *cell;
+ ETable *table;
+ GtkWidget *widget;
+ gchar *etspecfile;
- display_view (view->view_instance, gal_view_instance_get_current_view (view->view_instance), view);
+ adapter = eab_table_adapter_new (view->priv->model);
- g_signal_connect(view->view_instance, "display_view",
- G_CALLBACK (display_view), view);
- }
+ extras = e_table_extras_new ();
- bonobo_ui_component_add_listener(view->uic, "ContactsViewPreview", view_preview, view);
+ /* Set proper format component for a default 'date' cell renderer. */
+ cell = e_table_extras_get_cell (extras, "date");
+ e_cell_date_set_format_component (E_CELL_DATE (cell), "addressbook");
- set_view_preview (view);
-}
+ /* Here we create the table. We give it the three pieces of
+ the table we've created, the header, the model, and the
+ initial layout. It does the rest. */
+ etspecfile = g_build_filename (
+ EVOLUTION_ETSPECDIR, "e-addressbook-view.etspec", NULL);
+ widget = e_table_scrolled_new_from_spec_file (
+ adapter, extras, etspecfile, NULL);
+ table = E_TABLE (E_TABLE_SCROLLED (widget)->table);
+ g_free (etspecfile);
-static void
-eab_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- EABView *eav = EAB_VIEW(object);
+ view->priv->object = G_OBJECT (adapter);
+ view->priv->widget = widget;
- switch (prop_id) {
- case PROP_BOOK:
- if (eav->book) {
- g_object_unref (eav->book);
- }
- if (g_value_get_object (value)) {
- eav->book = E_BOOK(g_value_get_object (value));
- g_object_ref (eav->book);
- gtk_widget_set_sensitive (GTK_WIDGET (eav->search), TRUE);
- }
- else {
- eav->book = NULL;
- gtk_widget_set_sensitive (GTK_WIDGET (eav->search), FALSE);
- }
+ g_signal_connect (
+ table, "double_click",
+ G_CALLBACK(table_double_click), view);
+ g_signal_connect (
+ table, "right_click",
+ G_CALLBACK(table_right_click), view);
+ g_signal_connect (
+ table, "white_space_event",
+ G_CALLBACK(table_white_space_event), view);
+ g_signal_connect_swapped (
+ table, "selection_change",
+ G_CALLBACK (addressbook_view_emit_selection_change), view);
- if (eav->view_instance) {
- g_object_unref (eav->view_instance);
- eav->view_instance = NULL;
- }
+ e_table_drag_source_set (
+ table, GDK_BUTTON1_MASK,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
- g_object_set(eav->model,
- "book", eav->book,
- NULL);
+ g_signal_connect (
+ table, "table_drag_data_get",
+ G_CALLBACK (table_drag_data_get), view);
- setup_menus (eav);
+ gtk_box_pack_start (GTK_BOX (view), widget, TRUE, TRUE, 0);
- break;
- case PROP_SOURCE:
- if (eav->source) {
- g_warning ("EABView at present does not support multiple writes on the \"source\" property.");
- break;
- }
- else {
- if (g_value_get_object (value)) {
- eav->source = E_SOURCE(g_value_get_object (value));
- g_object_ref (eav->source);
- }
- else {
- eav->source = NULL;
- }
- }
- break;
- case PROP_QUERY:
-#if 0 /* This code will mess up ldap a bit. We need to think about the ramifications of this more. */
- if ((g_value_get_string (value) == NULL && !strcmp (eav->query, SHOW_ALL_SEARCH)) ||
- (g_value_get_string (value) != NULL && !strcmp (eav->query, g_value_get_string (value))))
- break;
-#endif
- g_free(eav->query);
- eav->query = g_strdup(g_value_get_string (value));
- if (!eav->query)
- eav->query = g_strdup (SHOW_ALL_SEARCH);
- g_object_set(eav->model,
- "query", eav->query,
- NULL);
- break;
- case PROP_TYPE:
- change_view_type(eav, g_value_get_int (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ gtk_widget_show (widget);
}
static void
-eab_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+addressbook_view_create_minicard_view (EAddressbookView *view)
{
- EABView *eav = EAB_VIEW(object);
+ GtkWidget *scrolled_window;
+ GtkWidget *minicard_view;
+ EAddressbookReflowAdapter *adapter;
- switch (prop_id) {
- case PROP_BOOK:
- if (eav->book)
- g_value_set_object (value, eav->book);
- else
- g_value_set_object (value, NULL);
- break;
- case PROP_SOURCE:
- if (eav->source)
- g_value_set_object (value, eav->source);
- else
- g_value_set_object (value, NULL);
- break;
-
- case PROP_QUERY:
- g_value_set_string (value, eav->query);
- break;
- case PROP_TYPE:
- g_value_set_int (value, eav->view_type);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
+ adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (
+ e_addressbook_reflow_adapter_new (view->priv->model));
+ minicard_view = e_minicard_view_widget_new (adapter);
-static ESelectionModel*
-get_selection_model (EABView *view)
-{
- if (view->view_type == EAB_VIEW_TABLE)
- return e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(view->widget)));
- else if (view->view_type == EAB_VIEW_MINICARD)
- return e_minicard_view_widget_get_selection_model (E_MINICARD_VIEW_WIDGET(view->object));
- g_return_val_if_reached (NULL);
-}
+ g_signal_connect_swapped (
+ adapter, "open-contact",
+ G_CALLBACK (addressbook_view_open_contact), view);
-/* Popup menu stuff */
-typedef struct {
- EABView *view;
- gpointer closure;
-} ContactAndBook;
+ g_signal_connect_swapped (
+ minicard_view, "create-contact",
+ G_CALLBACK (addressbook_view_create_contact), view);
-static ESelectionModel*
-contact_and_book_get_selection_model (ContactAndBook *contact_and_book)
-{
- return get_selection_model (contact_and_book->view);
-}
+ g_signal_connect_swapped (
+ minicard_view, "create-contact-list",
+ G_CALLBACK (addressbook_view_create_contact_list), view);
-static GList *
-get_contact_list (EABPopupTargetSelect *t)
-{
- GList *list = NULL;
- gint i;
+ g_signal_connect_swapped (
+ minicard_view, "selection_change",
+ G_CALLBACK (addressbook_view_emit_selection_change), view);
- for (i=0;i<t->cards->len;i++)
- list = g_list_prepend(list, t->cards->pdata[i]);
+ g_signal_connect_swapped (
+ minicard_view, "right_click",
+ G_CALLBACK (addressbook_view_emit_popup_event), view);
- return list;
-}
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-static void
-save_as (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- /*ContactAndBook *contact_and_book = data;*/
- GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target);
+ view->priv->object = G_OBJECT (minicard_view);
+ view->priv->widget = scrolled_window;
- if (contacts) {
- eab_contact_list_save(_("Save as vCard..."), contacts, NULL);
- g_list_free(contacts);
- }
-}
+ gtk_container_add (GTK_CONTAINER (scrolled_window), minicard_view);
+ gtk_widget_show (minicard_view);
-static void
-send_as (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- /*ContactAndBook *contact_and_book = data;*/
- GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target);
+ gtk_widget_show_all (scrolled_window);
- if (contacts) {
- eab_send_contact_list(contacts, EAB_DISPOSITION_AS_ATTACHMENT);
- g_list_free(contacts);
- }
+ gtk_box_pack_start (GTK_BOX (view), scrolled_window, TRUE, TRUE, 0);
+
+ e_reflow_model_changed (E_REFLOW_MODEL (adapter));
}
static void
-send_to (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- /*ContactAndBook *contact_and_book = data;*/
- GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target);
-
- if (contacts) {
- eab_send_contact_list(contacts, EAB_DISPOSITION_AS_TO);
- g_list_free(contacts);
+addressbook_view_display_view_cb (EAddressbookView *view,
+ GalView *gal_view)
+{
+ if (view->priv->widget != NULL) {
+ gtk_container_remove (
+ GTK_CONTAINER (view),
+ view->priv->widget);
+ view->priv->widget = NULL;
}
+ view->priv->object = NULL;
+
+ if (GAL_IS_VIEW_ETABLE (gal_view)) {
+ addressbook_view_create_table_view (view);
+ gal_view_etable_attach_table (
+ GAL_VIEW_ETABLE (gal_view),
+ e_table_scrolled_get_table (
+ E_TABLE_SCROLLED (view->priv->widget)));
+ }
+ else if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ addressbook_view_create_minicard_view (view);
+ gal_view_minicard_attach (
+ GAL_VIEW_MINICARD (gal_view), view);
+ }
+
+ command_state_change (view);
}
static void
-print (EPopup *ep, EPopupItem *pitem, gpointer data)
+addressbook_view_selection_get_cb (EAddressbookView *view,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time_stamp)
{
- /*ContactAndBook *contact_and_book = data;*/
- EABPopupTargetSelect *t = (EABPopupTargetSelect *)ep->target;
- GList *contact_list;
+ gchar *string;
- contact_list = get_contact_list (t);
- e_contact_print (
- NULL, NULL, contact_list,
- GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
- g_list_free (contact_list);
-}
+ string = eab_contact_list_to_string (view->priv->clipboard_contacts);
-static void
-copy (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ContactAndBook *contact_and_book = data;
+ gtk_selection_data_set (
+ selection_data, GDK_SELECTION_TYPE_STRING,
+ 8, (guchar *) string, strlen (string));
- eab_view_copy (contact_and_book->view);
+ g_free (string);
}
static void
-paste (EPopup *ep, EPopupItem *pitem, gpointer data)
+addressbook_view_selection_clear_event_cb (EAddressbookView *view,
+ GdkEventSelection *event)
{
- ContactAndBook *contact_and_book = data;
+ GList *list;
- eab_view_paste (contact_and_book->view);
+ list = view->priv->clipboard_contacts;
+ view->priv->clipboard_contacts = NULL;
+
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
}
static void
-cut (EPopup *ep, EPopupItem *pitem, gpointer data)
+addressbook_view_selection_received_cb (EAddressbookView *view,
+ GtkSelectionData *selection_data,
+ guint time)
{
- ContactAndBook *contact_and_book = data;
+ EAddressbookModel *model;
+ GList *list, *iter;
+ EBook *book;
- eab_view_cut (contact_and_book->view);
-}
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
-static void
-delete (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ContactAndBook *contact_and_book = data;
+ if (selection_data->length <= 0)
+ return;
- eab_view_delete_selection(contact_and_book->view, TRUE);
-}
+ if (selection_data->type != GDK_SELECTION_TYPE_STRING)
+ return;
-static void
-copy_to_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ContactAndBook *contact_and_book = data;
+ if (selection_data->data[selection_data->length - 1] != 0) {
+ gchar *string;
- eab_view_copy_to_folder (contact_and_book->view, FALSE);
-}
+ string = g_malloc0 (selection_data->length + 1);
+ memcpy (string, selection_data->data, selection_data->length);
+ list = eab_contact_list_from_string (string);
+ g_free (string);
+ } else
+ list = eab_contact_list_from_string (
+ (gchar *) selection_data->data);
-static void
-move_to_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ContactAndBook *contact_and_book = data;
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EContact *contact = iter->data;
- eab_view_move_to_folder (contact_and_book->view, FALSE);
+ /* XXX NULL for a callback /sigh */
+ eab_merging_book_add_contact (
+ book, contact, NULL /* XXX */, NULL);
+ }
+
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
}
static void
-open_contact (EPopup *ep, EPopupItem *pitem, gpointer data)
+addressbook_view_set_shell_view (EAddressbookView *view,
+ EShellView *shell_view)
{
- ContactAndBook *contact_and_book = data;
+ g_return_if_fail (view->priv->shell_view == NULL);
- eab_view_view (contact_and_book->view);
+ view->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &view->priv->shell_view);
}
static void
-new_card (EPopup *ep, EPopupItem *pitem, gpointer data)
+addressbook_view_set_source (EAddressbookView *view,
+ ESource *source)
{
- /*ContactAndBook *contact_and_book = data;*/
- EContact *contact = e_contact_new();
+ g_return_if_fail (view->priv->source == NULL);
- eab_show_contact_editor (((EABPopupTargetSelect *)ep->target)->book, contact, TRUE, TRUE);
- g_object_unref (contact);
+ view->priv->source = g_object_ref (source);
}
static void
-new_list (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- /*ContactAndBook *contact_and_book = data;*/
- EContact *contact = e_contact_new ();
+addressbook_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_VIEW:
+ addressbook_view_set_shell_view (
+ E_ADDRESSBOOK_VIEW (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SOURCE:
+ addressbook_view_set_source (
+ E_ADDRESSBOOK_VIEW (object),
+ g_value_get_object (value));
+ return;
+ }
- eab_show_contact_list_editor (((EABPopupTargetSelect *)ep->target)->book, contact, TRUE, TRUE);
- g_object_unref(contact);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-static EPopupItem eabv_popup_items[] = {
- { E_POPUP_ITEM, (gchar *) "05.open", (gchar *) N_("_Open"), open_contact, NULL, NULL, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EDITABLE },
- { E_POPUP_BAR, (gchar *) "10.bar" },
- { E_POPUP_ITEM, (gchar *) "10.new", (gchar *) N_("_New Contact..."), new_card, NULL, (gchar *) "contact-new", 0, EAB_POPUP_SELECT_EDITABLE},
- { E_POPUP_ITEM, (gchar *) "15.newlist", (gchar *) N_("New Contact _List..."), new_list, NULL, (gchar *) "stock_contact-list", 0, EAB_POPUP_SELECT_EDITABLE },
-
- { E_POPUP_BAR, (gchar *) "20.bar" },
- { E_POPUP_ITEM, (gchar *) "30.saveas", (gchar *) N_("_Save as vCard..."), save_as, NULL, (gchar *) "document-save-as", 0, EAB_POPUP_SELECT_ANY },
- { E_POPUP_ITEM, (gchar *) "40.forward", (gchar *) N_("_Forward Contact"), send_as, NULL, (gchar *) "mail-forward", EAB_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "40.forward", (gchar *) N_("_Forward Contacts"), send_as, NULL, (gchar *) "mail-forward", EAB_POPUP_SELECT_MANY },
- { E_POPUP_ITEM, (gchar *) "50.mailto", (gchar *) N_("Send _Message to Contact"), send_to, NULL, (gchar *) "mail-message-new", EAB_POPUP_SELECT_ONE|EAB_POPUP_SELECT_EMAIL|EAB_POPUP_CONTACT },
- { E_POPUP_ITEM, (gchar *) "50.mailto", (gchar *) N_("Send _Message to List"), send_to, NULL, (gchar *) "mail-message-new", EAB_POPUP_SELECT_ONE|EAB_POPUP_SELECT_EMAIL|EAB_POPUP_LIST },
- { E_POPUP_ITEM, (gchar *) "50.mailto", (gchar *) N_("Send _Message to Contacts"), send_to, NULL, (gchar *) "mail-message-new", EAB_POPUP_SELECT_MANY|EAB_POPUP_SELECT_EMAIL },
- { E_POPUP_ITEM, (gchar *) "60.print", (gchar *) N_("_Print"), print, NULL, (gchar *) "document-print", 0, EAB_POPUP_SELECT_ANY },
-
- { E_POPUP_BAR, (gchar *) "70.bar" },
- { E_POPUP_ITEM, (gchar *) "80.copyto", (gchar *) N_("Cop_y to Address Book..."), copy_to_folder, NULL, NULL, 0, EAB_POPUP_SELECT_ANY },
- { E_POPUP_ITEM, (gchar *) "90.moveto", (gchar *) N_("Mo_ve to Address Book..."), move_to_folder, NULL, NULL, 0, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EDITABLE },
-
- { E_POPUP_BAR, (gchar *) "a0.bar" },
- { E_POPUP_ITEM, (gchar *) "b0.cut", (gchar *) N_("Cu_t"), cut, NULL, (gchar *) "edit-cut", 0, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "c0.copy", (gchar *) N_("_Copy"), copy, NULL, (gchar *) "edit-copy", 0, EAB_POPUP_SELECT_ANY },
- { E_POPUP_ITEM, (gchar *) "d0.paste", (gchar *) N_("P_aste"), paste, NULL, (gchar *) "edit-paste", 0, EAB_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "e0.delete", (gchar *) N_("_Delete"), delete, NULL, (gchar *) "edit-delete", 0, EAB_POPUP_SELECT_EDITABLE|EAB_POPUP_SELECT_ANY },
-};
-
static void
-get_card_1(gint model_row, gpointer data)
-{
- ContactAndBook *contact_and_book = data;
- EContact *contact;
+addressbook_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (
+ value, e_addressbook_view_get_model (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_addressbook_view_get_shell_view (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
+
+ case PROP_SOURCE:
+ g_value_set_object (
+ value, e_addressbook_view_get_source (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
+ }
- contact = eab_model_get_contact(contact_and_book->view->model, model_row);
- if (contact)
- g_ptr_array_add((GPtrArray *)contact_and_book->closure, contact);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-eabv_popup_free(EPopup *ep, GSList *list, gpointer data)
+addressbook_view_dispose (GObject *object)
{
- ContactAndBook *cab = data;
- ESelectionModel *selection;
+ EAddressbookViewPrivate *priv;
- /* NB: this looks strange to me */
- selection = contact_and_book_get_selection_model(cab);
- if (selection)
- e_selection_model_right_click_up(selection);
+ priv = E_ADDRESSBOOK_VIEW_GET_PRIVATE (object);
- g_slist_free(list);
- g_object_unref(cab->view);
- g_free(cab);
-}
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view),
+ &priv->shell_view);
+ priv->shell_view = NULL;
+ }
-static void
-do_popup_menu(EABView *view, GdkEvent *event)
-{
- EABPopup *ep;
- EABPopupTargetSelect *t;
- GSList *menus = NULL;
- gint i;
- GtkMenu *menu;
- GPtrArray *cards = g_ptr_array_new();
- ContactAndBook *contact_and_book;
- ESelectionModel *selection_model;
-
- contact_and_book = g_new(ContactAndBook, 1);
- contact_and_book->view = view;
- g_object_ref(contact_and_book->view);
-
- selection_model = contact_and_book_get_selection_model(contact_and_book);
- if (selection_model) {
- contact_and_book->closure = cards;
- e_selection_model_foreach(selection_model, get_card_1, contact_and_book);
+ if (priv->model != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->model, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->model);
+ priv->model = NULL;
+ }
+
+ if (priv->activity != NULL) {
+ /* XXX Activity is not cancellable. */
+ e_activity_complete (priv->activity);
+ g_object_unref (priv->activity);
+ priv->activity = NULL;
}
- /** @HookPoint-EABPopup:Addressbook view Context Menu
- * @Id: org.gnome.evolution.addressbook.view.popup
- * @Class: org.gnome.evolution.addresbook.popup:1.0
- * @Target: EABPopupTargetSelect
- *
- * The context menu on the contacts view.
- */
+ if (priv->invisible != NULL) {
+ gtk_widget_destroy (priv->invisible);
+ priv->invisible = NULL;
+ }
- ep = eab_popup_new("org.gnome.evolution.addressbook.view.popup");
- t = eab_popup_target_new_select(ep, view->book, !eab_model_editable(view->model), cards);
- t->target.widget = (GtkWidget *)view;
+ if (priv->source != NULL) {
+ g_object_unref (priv->source);
+ priv->source = NULL;
+ }
- for (i=0;i<sizeof(eabv_popup_items)/sizeof(eabv_popup_items[0]);i++)
- menus = g_slist_prepend(menus, &eabv_popup_items[i]);
+ if (priv->view_instance != NULL) {
+ g_object_unref (priv->view_instance);
+ priv->view_instance = NULL;
+ }
- e_popup_add_items((EPopup *)ep, menus, NULL, eabv_popup_free, contact_and_book);
+ g_list_foreach (
+ priv->clipboard_contacts,
+ (GFunc) g_object_unref, NULL);
+ g_list_free (priv->clipboard_contacts);
+ priv->clipboard_contacts = NULL;
- menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button.button:0, event?event->button.time:gtk_get_current_event_time());
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-render_contact (gint row, EABView *view)
+addressbook_view_constructed (GObject *object)
{
- EContact *contact = eab_model_get_contact (view->model, row);
+ EAddressbookView *view = E_ADDRESSBOOK_VIEW (object);
+ GalViewInstance *view_instance;
+ EShellView *shell_view;
+ ESource *source;
+ gchar *uri;
- view->displayed_contact = row;
+ shell_view = e_addressbook_view_get_shell_view (view);
+ source = e_addressbook_view_get_source (view);
+ uri = e_source_get_uri (source);
- eab_contact_display_render (EAB_CONTACT_DISPLAY (view->contact_display), contact,
- EAB_CONTACT_DISPLAY_RENDER_NORMAL);
+ view_instance = e_shell_view_new_view_instance (shell_view, uri);
+ g_signal_connect_swapped (
+ view_instance, "display-view",
+ G_CALLBACK (addressbook_view_display_view_cb), view);
+ gal_view_instance_load (view_instance);
+ view->priv->view_instance = view_instance;
+
+ g_free (uri);
}
static void
-selection_changed (GObject *o, EABView *view)
+addressbook_view_class_init (EAddressbookViewClass *class)
{
- ESelectionModel *selection_model;
-
- command_state_change (view);
+ GObjectClass *object_class;
- selection_model = get_selection_model (view);
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EAddressbookViewPrivate));
- if (e_selection_model_selected_count (selection_model) == 1)
- e_selection_model_foreach (selection_model,
- (EForeachFunc)render_contact, view);
- else {
- view->displayed_contact = -1;
- eab_contact_display_render (EAB_CONTACT_DISPLAY (view->contact_display), NULL,
- EAB_CONTACT_DISPLAY_RENDER_NORMAL);
- }
+ object_class = G_OBJECT_CLASS(class);
+ object_class->set_property = addressbook_view_set_property;
+ object_class->get_property = addressbook_view_get_property;
+ object_class->dispose = addressbook_view_dispose;
+ object_class->constructed = addressbook_view_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ _("Model"),
+ NULL,
+ E_TYPE_ADDRESSBOOK_MODEL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ _("Shell View"),
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE,
+ g_param_spec_object (
+ "source",
+ _("Source"),
+ NULL,
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[OPEN_CONTACT] = g_signal_new (
+ "open-contact",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, open_contact),
+ NULL, NULL,
+ e_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE, 2,
+ E_TYPE_CONTACT,
+ G_TYPE_BOOLEAN);
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ signals[COMMAND_STATE_CHANGE] = g_signal_new (
+ "command-state-change",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, command_state_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SELECTION_CHANGE] = g_signal_new (
+ "selection-change",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, selection_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ if (clipboard_atom == NULL)
+ clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+ /* init the accessibility support for e_addressbook_view */
+ eab_view_a11y_init ();
}
static void
-table_double_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EABView *view)
+addressbook_view_init (EAddressbookView *view)
{
- if (E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object)) {
- EABModel *model = view->model;
- EContact *contact = eab_model_get_contact (model, row);
- EBook *book;
+ view->priv = E_ADDRESSBOOK_VIEW_GET_PRIVATE (view);
- g_object_get(model,
- "book", &book,
- NULL);
+ view->priv->model = e_addressbook_model_new ();
- g_return_if_fail (E_IS_BOOK (book));
+ view->priv->invisible = gtk_invisible_new ();
- if (e_contact_get (contact, E_CONTACT_IS_LIST))
- eab_show_contact_list_editor (book, contact, FALSE, view->editable);
- else
- eab_show_contact_editor (book, contact, FALSE, view->editable);
+ gtk_selection_add_target (
+ view->priv->invisible, clipboard_atom,
+ GDK_SELECTION_TYPE_STRING, 0);
- g_object_unref (book);
- g_object_unref (contact);
- }
+ g_signal_connect_swapped (
+ view->priv->invisible, "selection-get",
+ G_CALLBACK (addressbook_view_selection_get_cb), view);
+ g_signal_connect_swapped (
+ view->priv->invisible, "selection-clear-event",
+ G_CALLBACK (addressbook_view_selection_clear_event_cb), view);
+ g_signal_connect_swapped (
+ view->priv->invisible, "selection-received",
+ G_CALLBACK (addressbook_view_selection_received_cb), view);
}
-static gint
-table_right_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EABView *view)
+GType
+e_addressbook_view_get_type (void)
{
- do_popup_menu(view, event);
- return TRUE;
-}
+ static GType type = 0;
-static gint
-table_white_space_event(ETableScrolled *table, GdkEvent *event, EABView *view)
-{
- if (event->type == GDK_BUTTON_PRESS && ((GdkEventButton *)event)->button == 3) {
- do_popup_menu(view, event);
- return TRUE;
- } else {
- return FALSE;
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EAddressbookViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) addressbook_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EAddressbookView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) addressbook_view_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_VBOX, "EAddressbookView", &type_info, 0);
}
+
+ return type;
}
-static void
-table_drag_data_get (ETable *table,
- gint row,
- gint col,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer user_data)
+GtkWidget *
+e_addressbook_view_new (EShellView *shell_view,
+ ESource *source)
{
- EABView *view = user_data;
- GList *contact_list;
-
- if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object))
- return;
-
- contact_list = get_selected_contacts (view);
-
- switch (info) {
- case DND_TARGET_TYPE_VCARD: {
- gchar *value;
+ GtkWidget *widget;
+ EAddressbookView *view;
- value = eab_contact_list_to_string (contact_list);
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8,
- (guchar *)value, strlen (value));
- g_free (value);
- break;
- }
- case DND_TARGET_TYPE_SOURCE_VCARD: {
- gchar *value;
+ widget = g_object_new (
+ E_TYPE_ADDRESSBOOK_VIEW, "shell-view",
+ shell_view, "source", source, NULL);
- value = eab_book_and_contact_list_to_string (view->book, contact_list);
+ view = E_ADDRESSBOOK_VIEW (widget);
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8,
- (guchar *)value, strlen (value));
- g_free (value);
- break;
- }
- }
+ g_signal_connect_swapped (
+ view->priv->model, "status_message",
+ G_CALLBACK (status_message), view);
+ g_signal_connect_swapped (
+ view->priv->model, "search_result",
+ G_CALLBACK (search_result), view);
+ g_signal_connect_swapped (
+ view->priv->model, "folder_bar_message",
+ G_CALLBACK (folder_bar_message), view);
+ g_signal_connect (view->priv->model, "stop_state_changed",
+ G_CALLBACK (stop_state_changed), view);
+ g_signal_connect_swapped (
+ view->priv->model, "writable-status",
+ G_CALLBACK (command_state_change), view);
+ g_signal_connect_swapped (
+ view->priv->model, "backend_died",
+ G_CALLBACK (backend_died), view);
- g_list_foreach (contact_list, (GFunc) g_object_unref, NULL);
- g_list_free (contact_list);
+ return widget;
}
-static void
-emit_status_message (EABView *eav, const gchar *status)
+EAddressbookModel *
+e_addressbook_view_get_model (EAddressbookView *view)
{
- g_signal_emit (eav,
- eab_view_signals [STATUS_MESSAGE], 0,
- status);
-}
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
-static void
-emit_search_result (EABView *eav, EBookViewStatus status)
-{
- g_signal_emit (eav,
- eab_view_signals [SEARCH_RESULT], 0,
- status);
+ return view->priv->model;
}
-static void
-emit_folder_bar_message (EABView *eav, const gchar *message)
+GalViewInstance *
+e_addressbook_view_get_view_instance (EAddressbookView *view)
{
- g_signal_emit (eav,
- eab_view_signals [FOLDER_BAR_MESSAGE], 0,
- message);
-}
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
-static void
-status_message (GtkObject *object, const gchar *status, EABView *eav)
-{
- emit_status_message (eav, status);
+ return view->priv->view_instance;
}
-static void
-search_result (GtkObject *object, EBookViewStatus status, EABView *eav)
+GObject *
+e_addressbook_view_get_view_object (EAddressbookView *view)
{
- emit_search_result (eav, status);
-}
+ /* XXX Find a more descriptive name for this. */
-static void
-folder_bar_message (GtkObject *object, const gchar *status, EABView *eav)
-{
- emit_folder_bar_message (eav, status);
-}
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
-static void
-stop_state_changed (GtkObject *object, EABView *eav)
-{
- command_state_change (eav);
+ return view->priv->object;
}
-static void
-command_state_change (EABView *eav)
+GtkWidget *
+e_addressbook_view_get_view_widget (EAddressbookView *view)
{
- /* Reffing during emission is unnecessary. Gtk automatically refs during an emission. */
- g_signal_emit (eav, eab_view_signals [COMMAND_STATE_CHANGE], 0);
-}
+ /* XXX Find a more descriptive name for this. */
-static void
-backend_died (GtkObject *object, EABView *eav)
-{
- e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (eav))),
- "addressbook:backend-died", e_book_get_uri (eav->book), NULL);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
+
+ return view->priv->widget;
}
+/* Helper for e_addressbook_view_get_selected() */
static void
-contact_changed (EABModel *model, gint index, EABView *eav)
+add_to_list (gint model_row, gpointer closure)
{
- if (eav->displayed_contact == index) {
- /* if the contact that's presently displayed is changed, re-render it */
- render_contact (index, eav);
- }
+ GList **list = closure;
+ *list = g_list_prepend (*list, GINT_TO_POINTER (model_row));
}
-static void
-contacts_removed (EABModel *model, gpointer data, EABView *eav)
+GList *
+e_addressbook_view_get_selected (EAddressbookView *view)
{
- GArray *indices = (GArray *) data;
- gint count = indices->len;
- gint i;
+ GList *list, *iter;
+ ESelectionModel *selection;
- for (i = 0; i < count; i ++) {
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- if (eav->displayed_contact == g_array_index (indices, gint, i)) {
+ list = NULL;
+ selection = e_addressbook_view_get_selection_model (view);
+ e_selection_model_foreach (selection, add_to_list, &list);
- /* if the contact that's presently displayed is changed, clear the display */
- eab_contact_display_render (EAB_CONTACT_DISPLAY (eav->contact_display), NULL,
- EAB_CONTACT_DISPLAY_RENDER_NORMAL);
- eav->displayed_contact = -1;
- break;
- }
- }
-}
+ for (iter = list; iter != NULL; iter = iter->next)
+ iter->data = e_addressbook_model_get_contact (
+ view->priv->model, GPOINTER_TO_INT (iter->data));
+ list = g_list_reverse (list);
-static void
-minicard_right_click (EMinicardView *minicard_view_item, GdkEvent *event, EABView *view)
-{
- do_popup_menu(view, event);
+ return list;
}
-static void
-create_minicard_view (EABView *view)
+ESelectionModel *
+e_addressbook_view_get_selection_model (EAddressbookView *view)
{
- GtkWidget *scrolled_window;
- GtkWidget *minicard_view;
- EAddressbookReflowAdapter *adapter;
+ GalView *gal_view;
+ GalViewInstance *view_instance;
+ ESelectionModel *model = NULL;
- adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(e_addressbook_reflow_adapter_new (view->model));
- minicard_view = e_minicard_view_widget_new(adapter);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- g_signal_connect(minicard_view, "selection_change",
- G_CALLBACK(selection_changed), view);
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
- g_signal_connect(minicard_view, "right_click",
- G_CALLBACK(minicard_right_click), view);
+ if (GAL_IS_VIEW_ETABLE (gal_view)) {
+ ETableScrolled *scrolled_table;
+ ETable *table;
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
+ scrolled_table = E_TABLE_SCROLLED (view->priv->widget);
+ table = e_table_scrolled_get_table (scrolled_table);
- view->object = G_OBJECT(minicard_view);
- view->widget = scrolled_window;
+ model = e_table_get_selection_model (table);
- gtk_container_add (GTK_CONTAINER (scrolled_window), minicard_view);
- gtk_widget_show (minicard_view);
+ } else if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ EMinicardViewWidget *widget;
- gtk_widget_show_all( GTK_WIDGET(scrolled_window) );
+ widget = E_MINICARD_VIEW_WIDGET (view->priv->object);
- gtk_paned_add1 (GTK_PANED (view->paned), scrolled_window);
+ model = e_minicard_view_widget_get_selection_model (widget);
+ }
- e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+ return model;
}
-static void
-create_table_view (EABView *view)
+EShellView *
+e_addressbook_view_get_shell_view (EAddressbookView *view)
{
- ETableModel *adapter;
- ETableExtras *extras;
- ECell *cell;
- GtkWidget *table;
- gchar *etspecfile;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- adapter = eab_table_adapter_new(view->model);
-
- extras = e_table_extras_new ();
-
- /* set proper format component for a default 'date' cell renderer */
- cell = e_table_extras_get_cell (extras, "date");
- e_cell_date_set_format_component (E_CELL_DATE (cell), "addressbook");
-
- /* Here we create the table. We give it the three pieces of
- the table we've created, the header, the model, and the
- initial layout. It does the rest. */
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "e-addressbook-view.etspec",
- NULL);
- table = e_table_scrolled_new_from_spec_file (adapter, extras, etspecfile, NULL);
- g_free (etspecfile);
-
- view->object = G_OBJECT(adapter);
- view->widget = table;
-
- g_signal_connect(e_table_scrolled_get_table(E_TABLE_SCROLLED(table)), "double_click",
- G_CALLBACK(table_double_click), view);
- g_signal_connect(e_table_scrolled_get_table(E_TABLE_SCROLLED(table)), "right_click",
- G_CALLBACK(table_right_click), view);
- g_signal_connect(e_table_scrolled_get_table(E_TABLE_SCROLLED(table)), "white_space_event",
- G_CALLBACK(table_white_space_event), view);
- g_signal_connect(e_table_scrolled_get_table(E_TABLE_SCROLLED(table)), "selection_change",
- G_CALLBACK(selection_changed), view);
-
- /* drag & drop signals */
- e_table_drag_source_set (E_TABLE(E_TABLE_SCROLLED(table)->table), GDK_BUTTON1_MASK,
- drag_types, num_drag_types, GDK_ACTION_MOVE | GDK_ACTION_COPY);
-
- g_signal_connect (E_TABLE_SCROLLED(table)->table,
- "table_drag_data_get",
- G_CALLBACK (table_drag_data_get),
- view);
-
- gtk_paned_add1 (GTK_PANED (view->paned), table);
-
- gtk_widget_show( GTK_WIDGET(table) );
+ return view->priv->shell_view;
}
-static void
-change_view_type (EABView *view, EABViewType view_type)
+ESource *
+e_addressbook_view_get_source (EAddressbookView *view)
{
- if (view_type == view->view_type)
- return;
-
- if (view->widget) {
- gtk_container_remove (GTK_CONTAINER (view->paned), view->widget);
- view->widget = NULL;
- }
- view->object = NULL;
-
- switch (view_type) {
- case EAB_VIEW_TABLE:
- create_table_view (view);
- break;
- case EAB_VIEW_MINICARD:
- create_minicard_view (view);
- break;
- default:
- g_warning ("view_type not recognized.");
- return;
- }
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- view->view_type = view_type;
-
- command_state_change (view);
+ return view->priv->source;
}
-
-
static void
-search_activated (ESearchBar *esb, EABView *v)
-{
- GList *master_list;
- gchar *search_word, *search_query, *view_sexp;
- const gchar *category_name;
- gint search_type, subid;
-
- g_object_get(esb,
- "text", &search_word,
- "item_id", &search_type,
- NULL);
-
- if (search_type == E_FILTERBAR_ADVANCED_ID) {
- /* rebuild view immediately */
- query_changed (esb, v);
- }
- else {
- if ((search_word && strlen (search_word))) {
- GString *s = g_string_new ("");
- e_sexp_encode_string (s, search_word);
- switch (search_type) {
- case ESB_ANY:
- search_query = g_strdup_printf ("(contains \"x-evolution-any-field\" %s)",
- s->str);
- break;
- case ESB_FULL_NAME:
- search_query = g_strdup_printf ("(contains \"full_name\" %s)",
- s->str);
- break;
- case ESB_EMAIL:
- search_query = g_strdup_printf ("(beginswith \"email\" %s)",
- s->str);
- break;
- default:
- search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
- break;
- }
- g_string_free (s, TRUE);
-
- } else
- search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
-
- /* Merge view and sexp */
- subid = e_search_bar_get_viewitem_id (esb);
-
- if (subid) {
- master_list = get_master_list (FALSE);
- if (subid < 3) {
- view_sexp = g_strdup ("(not (and (exists \"CATEGORIES\") (not (is \"CATEGORIES\" \"\"))))");
- } else {
- category_name = g_list_nth_data (master_list, subid-3);
- view_sexp = g_strdup_printf ("(is \"category_list\" \"%s\")", category_name);
- }
- search_query = g_strconcat ("(and ", view_sexp, search_query, ")", NULL);
- g_free (view_sexp);
+status_message (EAddressbookView *view,
+ const gchar *status)
+{
+ EActivity *activity;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+
+ activity = view->priv->activity;
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ if (status == NULL || *status == '\0') {
+ if (activity != NULL) {
+ e_activity_complete (activity);
+ g_object_unref (activity);
+ view->priv->activity = NULL;
}
- if (search_query)
- g_object_set (v,
- "query", search_query,
- NULL);
-
- g_free (search_query);
- }
+ } else if (activity == NULL) {
+ activity = e_activity_new (status);
+ view->priv->activity = activity;
+ e_shell_backend_add_activity (shell_backend, activity);
- g_free (search_word);
- v->displayed_contact = -1;
- eab_contact_display_render (EAB_CONTACT_DISPLAY (v->contact_display), NULL,
- EAB_CONTACT_DISPLAY_RENDER_NORMAL);
+ } else
+ e_activity_set_primary_text (activity, status);
}
static void
-search_menu_activated (ESearchBar *esb, gint id, EABView *view)
+search_result (EAddressbookView *view,
+ EBookViewStatus status)
{
- if (id == E_FILTERBAR_ADVANCED_ID)
- e_search_bar_set_item_id (esb, id);
-}
+ EShellView *shell_view;
+ EShellWindow *shell_window;
-static void
-query_changed (ESearchBar *esb, EABView *view)
-{
- gint search_type;
- gchar *query;
-
- search_type = e_search_bar_get_item_id(esb);
- if (search_type == E_FILTERBAR_ADVANCED_ID) {
- g_object_get (esb, "query", &query, NULL);
- g_object_set (view, "query", query, NULL);
- g_free (query);
- }
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ eab_search_result_dialog (GTK_WIDGET (shell_window), status);
}
-static gint
-compare_subitems (gconstpointer a, gconstpointer b)
-{
- const ESearchBarItem *subitem_a = a;
- const ESearchBarItem *subitem_b = b;
- gchar *collate_a, *collate_b;
- gint ret;
-
- collate_a = g_utf8_collate_key (subitem_a->text, -1);
- collate_b = g_utf8_collate_key (subitem_b->text, -1);
-
- ret = strcmp (collate_a, collate_b);
-
- g_free (collate_a);
- g_free (collate_b);
-
- return ret;
-}
-
-static GtkWidget *
-generate_viewoption_menu (EABSearchBarItem *subitems)
+static void
+folder_bar_message (EAddressbookView *view,
+ const gchar *message)
{
- GtkWidget *menu, *menu_item;
- gint i = 0;
-
- menu = gtk_menu_new ();
-
- for (i = 0; subitems[i].search.id != -1; ++i) {
- if (subitems[i].search.text) {
- gchar *str = NULL;
- str = e_str_without_underscores (subitems[i].search.text);
- menu_item = gtk_image_menu_item_new_with_label (str);
- if (subitems[i].image) {
- GtkWidget *image;
-
- image = gtk_image_new_from_file (
- subitems[i].image);
- gtk_image_menu_item_set_image (
- GTK_IMAGE_MENU_ITEM (menu_item),
- image);
- }
- g_free (str);
- } else {
- menu_item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ const gchar *name;
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (subitems[i].search.id));
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
+ if (view->priv->source == NULL)
+ return;
- return menu;
+ name = e_source_peek_name (view->priv->source);
+ e_shell_sidebar_set_primary_text (shell_sidebar, name);
+ e_shell_sidebar_set_secondary_text (shell_sidebar, message);
}
static void
-categories_changed_cb (gpointer object, gpointer user_data)
+stop_state_changed (GtkObject *object, EAddressbookView *view)
{
- get_master_list (TRUE);
- make_suboptions (user_data);
+ command_state_change (view);
}
static void
-make_suboptions (EABView *view)
+command_state_change (EAddressbookView *view)
{
- EABSearchBarItem *subitems, *s;
- GList *master_list;
- gint i, N;
- GtkWidget *menu;
-
- master_list = get_master_list (FALSE);
- N = g_list_length (master_list);
- subitems = g_new (EABSearchBarItem, N+4);
-
- subitems[0].search.id = 0;
- subitems[0].search.text = g_strdup (_("Any Category"));
- subitems[0].image = NULL;
-
- subitems[1].search.text = g_strdup (_("Unmatched"));
- subitems[1].search.id = 1;
- subitems[1].image = NULL;
-
- subitems[2].search.text = NULL;
- subitems[2].search.id = 0;
- subitems[2].image = NULL;
-
- for (i=0; i<N; ++i) {
- const gchar *category = g_list_nth_data (master_list, i);
- subitems[i+3].search.id = i+3;
- subitems[i+3].search.text = g_strdup (category);
- subitems[i+3].image = (gchar *)e_categories_get_icon_file_for (category);
- }
-
- subitems[N+3].search.id = -1;
- subitems[N+3].search.text = NULL;
- subitems[N+3].image = NULL;
-
- qsort (subitems + 3, N, sizeof (subitems[0]), compare_subitems);
- menu = generate_viewoption_menu (subitems);
- e_search_bar_set_viewoption_menu ((ESearchBar *)view->search, menu);
-
- for (s = subitems; ((ESearchBarItem *)s)->id != -1; s++) {
- if (((ESearchBarItem *)s)->text)
- g_free (((ESearchBarItem *)s)->text);
- }
- g_free (subitems);
+ g_signal_emit (view, signals[COMMAND_STATE_CHANGE], 0);
}
-static GList *
-get_master_list (gboolean force_rebuild)
+static void
+backend_died (EAddressbookView *view)
{
- static GList *category_list = NULL;
-
- if (force_rebuild) {
- g_list_free (category_list);
- category_list = NULL;
- }
-
- if (category_list == NULL) {
- GList *l, *p = e_categories_get_list ();
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EAddressbookModel *model;
+ EBook *book;
- for (l = p; l; l = l->next) {
- if (e_categories_is_searchable ((const gchar *) l->data))
- category_list = g_list_prepend (category_list, l->data);
- }
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
- category_list = g_list_reverse (category_list);
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
- g_list_free (p);
- }
-
- return category_list;
+ e_error_run (
+ GTK_WINDOW (shell_window),
+ "addressbook:backend-died",
+ e_book_get_uri (book), NULL);
}
static void
@@ -1633,78 +1047,27 @@ e_contact_print_button (EPrintable *printable, GtkPrintOperationAction action)
}
void
-eab_view_show_contact_preview (EABView *view, gboolean show)
+e_addressbook_view_print (EAddressbookView *view,
+ GtkPrintOperationAction action)
{
- g_return_if_fail (view && E_IS_ADDRESSBOOK_VIEW (view));
-
- if (show)
- gtk_widget_show (view->contact_display_window);
- else
- gtk_widget_hide (view->contact_display_window);
-}
-
-void
-eab_view_setup_menus (EABView *view,
- BonoboUIComponent *uic)
-{
-
- g_return_if_fail (view != NULL);
- g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- g_return_if_fail (uic != NULL);
- g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
-
- init_collection ();
-
- view->uic = uic;
-
- setup_menus (view);
-
- /* XXX toshok - yeah this really doesn't belong here, but it
- needs to happen at the same time and takes the uic */
- e_search_bar_set_ui_component ( (ESearchBar *)view->search, uic);
-}
+ GalView *gal_view;
+ GalViewInstance *view_instance;
-/**
- * eab_view_discard_menus:
- * @view: An addressbook view.
- *
- * Makes an addressbook view discard its GAL view menus and its views instance
- * objects. This should be called when the corresponding Bonobo component is
- * deactivated.
- **/
-void
-eab_view_discard_menus (EABView *view)
-{
- g_return_if_fail (view != NULL);
g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- if (view->view_menus) {
- gal_view_menus_unmerge (view->view_menus, NULL);
-
- g_object_unref (view->view_menus);
- view->view_menus = NULL;
- }
-
- if (view->view_instance) {
- g_object_unref (view->view_instance);
- view->view_instance = NULL;
- }
-
- view->uic = NULL;
-}
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
-void
-eab_view_print (EABView *view, GtkPrintOperationAction action)
-{
- if (view->view_type == EAB_VIEW_MINICARD) {
+ if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ EAddressbookModel *model;
EBook *book;
EBookQuery *query;
gchar *query_string;
GList *contact_list;
- g_object_get (
- view->model, "query", &query_string,
- "book", &book, NULL);
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
+ query_string = e_addressbook_model_get_query (model);
if (query_string != NULL)
query = e_book_query_from_string (query_string);
@@ -1712,7 +1075,7 @@ eab_view_print (EABView *view, GtkPrintOperationAction action)
query = NULL;
g_free (query_string);
- contact_list = get_selected_contacts (view);
+ contact_list = e_addressbook_view_get_selected (view);
e_contact_print (book, query, contact_list, action);
g_list_foreach (contact_list, (GFunc) g_object_unref, NULL);
g_list_free (contact_list);
@@ -1720,11 +1083,11 @@ eab_view_print (EABView *view, GtkPrintOperationAction action)
if (query != NULL)
e_book_query_unref (query);
- } else if (view->view_type == EAB_VIEW_TABLE) {
+ } else if (GAL_IS_VIEW_ETABLE (gal_view)) {
EPrintable *printable;
ETable *table;
- g_object_get (view->widget, "table", &table, NULL);
+ g_object_get (view->priv->widget, "table", &table, NULL);
printable = e_table_get_printable (table);
g_object_ref_sink (printable);
g_object_unref (table);
@@ -1738,7 +1101,8 @@ eab_view_print (EABView *view, GtkPrintOperationAction action)
/* callback function to handle removal of contacts for
* which a user doesnt have write permission
*/
-static void delete_contacts_cb (EBook *book, EBookStatus status, gpointer closure)
+static void
+delete_contacts_cb (EBook *book, EBookStatus status, gpointer closure)
{
switch (status) {
case E_BOOK_ERROR_OK :
@@ -1754,19 +1118,85 @@ static void delete_contacts_cb (EBook *book, EBookStatus status, gpointer clos
}
}
+static gboolean
+addressbook_view_confirm_delete (GtkWindow *parent,
+ gboolean plural,
+ gboolean is_list,
+ const gchar *name)
+{
+ GtkWidget *dialog;
+ gchar *message;
+ gint response;
+
+ if (is_list) {
+ if (plural) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete these contact lists?"));
+ } else if (name == NULL) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete this contact list?"));
+ } else {
+ message = g_strdup_printf (
+ _("Are you sure you want to delete "
+ "this contact list (%s)?"), name);
+ }
+ } else {
+ if (plural) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete these contacts?"));
+ } else if (name == NULL) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete this contact?"));
+ } else {
+ message = g_strdup_printf (
+ _("Are you sure you want to delete "
+ "this contact (%s)?"), name);
+ }
+ }
+
+ dialog = gtk_message_dialog_new (
+ parent, 0, GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE, "%s", message);
+ gtk_dialog_add_buttons (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ g_free (message);
+
+ return (response == GTK_RESPONSE_ACCEPT);
+}
+
void
-eab_view_delete_selection(EABView *view, gboolean is_delete)
+e_addressbook_view_delete_selection(EAddressbookView *view, gboolean is_delete)
{
GList *list, *l;
gboolean plural = FALSE, is_list = FALSE;
EContact *contact;
ETable *etable = NULL;
+ EAddressbookModel *model;
+ EBook *book;
EMinicardView *card_view;
ESelectionModel *selection_model = NULL;
+ GalViewInstance *view_instance;
+ GalView *gal_view;
gchar *name = NULL;
gint row = 0, select;
- list = get_selected_contacts (view);
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
+
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
+
+ list = e_addressbook_view_get_selected (view);
contact = list->data;
if (g_list_next(list))
@@ -1777,28 +1207,29 @@ eab_view_delete_selection(EABView *view, gboolean is_delete)
if (e_contact_get (contact, E_CONTACT_IS_LIST))
is_list = TRUE;
- if (view->view_type == EAB_VIEW_MINICARD) {
- card_view = e_minicard_view_widget_get_view (E_MINICARD_VIEW_WIDGET(view->object));
- selection_model = get_selection_model (view);
+ if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ card_view = e_minicard_view_widget_get_view (E_MINICARD_VIEW_WIDGET(view->priv->object));
+ selection_model = e_addressbook_view_get_selection_model (view);
row = e_selection_model_cursor_row (selection_model);
}
- else if (view->view_type == EAB_VIEW_TABLE) {
- etable = e_table_scrolled_get_table(E_TABLE_SCROLLED(view->widget));
+ else if (GAL_IS_VIEW_ETABLE (gal_view)) {
+ etable = e_table_scrolled_get_table (
+ E_TABLE_SCROLLED(view->priv->widget));
row = e_table_get_cursor_row (E_TABLE (etable));
}
/* confirm delete */
- if (is_delete &&
- !eab_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(view->widget)),
- plural, is_list, name)) {
+ if (is_delete && !addressbook_view_confirm_delete (
+ GTK_WINDOW (gtk_widget_get_toplevel (
+ view->priv->widget)), plural, is_list, name)) {
g_free (name);
g_list_foreach (list, (GFunc) g_object_unref, NULL);
g_list_free (list);
return;
}
- if (e_book_check_static_capability (view->book, "bulk-remove")) {
+ if (e_book_check_static_capability (book, "bulk-remove")) {
GList *ids = NULL;
for (l=list;l;l=g_list_next(l)) {
@@ -1808,7 +1239,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete)
}
/* Remove the cards all at once. */
- e_book_async_remove_contacts (view->book,
+ e_book_async_remove_contacts (book,
ids,
delete_contacts_cb,
NULL);
@@ -1819,7 +1250,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete)
for (l=list;l;l=g_list_next(l)) {
contact = l->data;
/* Remove the card. */
- e_book_async_remove_contact (view->book,
+ e_book_async_remove_contact (book,
contact,
delete_contacts_cb,
NULL);
@@ -1827,7 +1258,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete)
}
/* Sets the cursor, at the row after the deleted row */
- if (view->view_type == EAB_VIEW_MINICARD && row!=0) {
+ if (GAL_IS_VIEW_MINICARD (gal_view) && row != 0) {
select = e_sorter_model_to_sorted (selection_model->sorter, row);
/* Sets the cursor, before the deleted row if its the last row */
@@ -1841,7 +1272,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete)
}
/* Sets the cursor, at the row after the deleted row */
- else if (view->view_type == EAB_VIEW_TABLE && row!=0) {
+ else if (GAL_IS_VIEW_ETABLE (gal_view) && row != 0) {
select = e_table_model_to_view_row (E_TABLE (etable), row);
/* Sets the cursor, before the deleted row if its the last row */
@@ -1857,234 +1288,149 @@ eab_view_delete_selection(EABView *view, gboolean is_delete)
g_list_free (list);
}
-static void
-invisible_destroyed (gpointer data, GObject *where_object_was)
-{
- EABView *view = data;
- view->invisible = NULL;
-}
-
-static void
-selection_get (GtkWidget *invisible,
- GtkSelectionData *selection_data,
- guint info,
- guint time_stamp,
- EABView *view)
-{
- gchar *value;
-
- value = eab_contact_list_to_string (view->clipboard_contacts);
-
- gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
- 8, (guchar *)value, strlen (value));
- g_free (value);
-}
-
-static void
-selection_clear_event (GtkWidget *invisible,
- GdkEventSelection *event,
- EABView *view)
-{
- if (view->clipboard_contacts) {
- g_list_foreach (view->clipboard_contacts, (GFunc)g_object_unref, NULL);
- g_list_free (view->clipboard_contacts);
- view->clipboard_contacts = NULL;
- }
-}
-
-static void
-selection_received (GtkWidget *invisible,
- GtkSelectionData *selection_data,
- guint time,
- EABView *view)
+void
+e_addressbook_view_save_as (EAddressbookView *view,
+ gboolean all)
{
- if (selection_data->length <= 0 || selection_data->type != GDK_SELECTION_TYPE_STRING) {
- return;
- } else {
- GList *contact_list;
- GList *l;
- gchar *str = NULL;
-
- if (selection_data->data [selection_data->length - 1] != 0) {
- str = g_malloc0 (selection_data->length + 1);
- memcpy (str, selection_data->data, selection_data->length);
- contact_list = eab_contact_list_from_string (str);
- } else
- contact_list = eab_contact_list_from_string ((gchar *)selection_data->data);
-
- for (l = contact_list; l; l = l->next) {
- EContact *contact = l->data;
-
- /* XXX NULL for a callback /sigh */
- eab_merging_book_add_contact (view->book, contact, NULL /* XXX */, NULL);
- }
+ GList *list = NULL;
+ EBook *book;
- g_list_foreach (contact_list, (GFunc)g_object_unref, NULL);
- g_list_free (contact_list);
- g_free (str);
- }
-}
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-static void
-add_to_list (gint model_row, gpointer closure)
-{
- GList **list = closure;
- *list = g_list_prepend (*list, GINT_TO_POINTER (model_row));
-}
+ book = e_addressbook_model_get_book (view->priv->model);
-static GList *
-get_selected_contacts (EABView *view)
-{
- GList *list;
- GList *iterator;
- ESelectionModel *selection = get_selection_model (view);
+ if (all) {
+ EBookQuery *query;
- list = NULL;
- e_selection_model_foreach (selection, add_to_list, &list);
+ query = e_book_query_any_field_contains ("");
+ e_book_get_contacts (book, query, &list, NULL);
+ e_book_query_unref (query);
+ } else
+ list = e_addressbook_view_get_selected (view);
- for (iterator = list; iterator; iterator = iterator->next) {
- iterator->data = eab_model_get_contact (view->model, GPOINTER_TO_INT (iterator->data));
+ if (list != NULL) {
+ eab_contact_list_save (_("Save as vCard..."), list, NULL);
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
}
- list = g_list_reverse (list);
- return list;
}
void
-eab_view_save_as (EABView *view, gboolean all)
+e_addressbook_view_view (EAddressbookView *view)
{
- GList *list = NULL;
+ EAddressbookModel *model;
EBook *book;
+ GList *list, *iter;
+ gboolean editable;
+ gint response;
+ guint length;
- g_object_get(view->model,
- "book", &book,
- NULL);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- if (all) {
- EBookQuery *query = e_book_query_any_field_contains("");
- e_book_get_contacts(book, query, &list, NULL);
- e_book_query_unref(query);
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
+ editable = e_addressbook_model_get_editable (model);
+
+ list = e_addressbook_view_get_selected (view);
+ length = g_list_length (list);
+ response = GTK_RESPONSE_YES;
+
+ if (length > 5) {
+ GtkWidget *dialog;
+
+ /* XXX Use e_error_new(). */
+ /* XXX Provide a parent window. */
+ dialog = gtk_message_dialog_new (
+ NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+ _("Opening %d contacts will open %d new windows as "
+ "well.\nDo you really want to display all of these "
+ "contacts?"), length, length);
+ gtk_dialog_add_buttons (
+ GTK_DIALOG (dialog),
+ _("_Don't Display"), GTK_RESPONSE_NO,
+ _("Display _All Contacts"), GTK_RESPONSE_YES,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
}
- else {
- list = get_selected_contacts(view);
- }
- if (list)
- eab_contact_list_save (_("Save as vCard..."), list, NULL);
- g_list_foreach (list, (GFunc) g_object_unref, NULL);
- g_list_free (list);
-}
-void
-eab_view_view (EABView *view)
-{
- GList *list = get_selected_contacts (view);
- eab_show_multiple_contacts (view->book, list, view->editable);
- g_list_foreach (list, (GFunc) g_object_unref, NULL);
- g_list_free (list);
-}
+ if (response == GTK_RESPONSE_YES)
+ for (iter = list; iter != NULL; iter = iter->next)
+ addressbook_view_emit_open_contact (
+ view, iter->data, FALSE);
-void
-eab_view_send (EABView *view)
-{
- GList *list = get_selected_contacts (view);
- if (list)
- eab_send_contact_list (list, EAB_DISPOSITION_AS_ATTACHMENT);
g_list_foreach (list, (GFunc) g_object_unref, NULL);
g_list_free (list);
}
void
-eab_view_send_to (EABView *view)
+e_addressbook_view_cut (EAddressbookView *view)
{
- GList *list = get_selected_contacts (view);
- if (list)
- eab_send_contact_list (list, EAB_DISPOSITION_AS_TO);
- g_list_foreach (list, (GFunc) g_object_unref, NULL);
- g_list_free (list);
-}
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-void
-eab_view_cut (EABView *view)
-{
- eab_view_copy (view);
- eab_view_delete_selection (view, FALSE);
+ e_addressbook_view_copy (view);
+ e_addressbook_view_delete_selection (view, FALSE);
}
-static gboolean
-contact_display_has_selection (EABContactDisplay *display)
+void
+e_addressbook_view_copy (EAddressbookView *view)
{
- gchar *string;
- gint selection_length;
- gboolean has_selection;
-
- string = gtk_html_get_selection_html (GTK_HTML (display), &selection_length);
-
- has_selection = string ? TRUE : FALSE;
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- if (string)
- g_free (string);
+ view->priv->clipboard_contacts = e_addressbook_view_get_selected (view);
- return has_selection;
+ gtk_selection_owner_set (
+ view->priv->invisible,
+ clipboard_atom, GDK_CURRENT_TIME);
}
void
-eab_view_copy (EABView *view)
+e_addressbook_view_paste (EAddressbookView *view)
{
- if (GTK_WIDGET_HAS_FOCUS (view->contact_display) &&
- contact_display_has_selection (EAB_CONTACT_DISPLAY (view->contact_display)))
- {
- gtk_html_copy (GTK_HTML (view->contact_display));
- }
- else
- {
- view->clipboard_contacts = get_selected_contacts (view);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- gtk_selection_owner_set (view->invisible, clipboard_atom, GDK_CURRENT_TIME);
- }
+ gtk_selection_convert (
+ view->priv->invisible, clipboard_atom,
+ GDK_SELECTION_TYPE_STRING, GDK_CURRENT_TIME);
}
void
-eab_view_paste (EABView *view)
+e_addressbook_view_select_all (EAddressbookView *view)
{
- gtk_selection_convert (view->invisible, clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- GDK_CURRENT_TIME);
-}
+ ESelectionModel *model;
-void
-eab_view_select_all (EABView *view)
-{
- ESelectionModel *model = get_selection_model (view);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+ model = e_addressbook_view_get_selection_model (view);
g_return_if_fail (model);
e_selection_model_select_all (model);
}
void
-eab_view_show_all(EABView *view)
+e_addressbook_view_show_all (EAddressbookView *view)
{
- g_object_set(view,
- "query", NULL,
- NULL);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+
+ e_addressbook_model_set_query (view->priv->model, "");
}
void
-eab_view_stop(EABView *view)
+e_addressbook_view_stop (EAddressbookView *view)
{
- if (view)
- eab_model_stop (view->model);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+
+ e_addressbook_model_stop (view->priv->model);
}
static void
-view_transfer_contacts (EABView *view, gboolean delete_from_source, gboolean all)
+view_transfer_contacts (EAddressbookView *view, gboolean delete_from_source, gboolean all)
{
EBook *book;
GList *contacts = NULL;
GtkWindow *parent_window;
- g_object_get(view->model,
- "book", &book,
- NULL);
+ book = e_addressbook_model_get_book (view->priv->model);
if (all) {
EBookQuery *query = e_book_query_any_field_contains("");
@@ -2092,7 +1438,7 @@ view_transfer_contacts (EABView *view, gboolean delete_from_source, gboolean all
e_book_query_unref(query);
}
else {
- contacts = get_selected_contacts (view);
+ contacts = e_addressbook_view_get_selected (view);
}
parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
@@ -2101,131 +1447,13 @@ view_transfer_contacts (EABView *view, gboolean delete_from_source, gboolean all
}
void
-eab_view_copy_to_folder (EABView *view, gboolean all)
+e_addressbook_view_copy_to_folder (EAddressbookView *view, gboolean all)
{
view_transfer_contacts (view, FALSE, all);
}
void
-eab_view_move_to_folder (EABView *view, gboolean all)
+e_addressbook_view_move_to_folder (EAddressbookView *view, gboolean all)
{
view_transfer_contacts (view, TRUE, all);
}
-
-static gboolean
-eab_view_selection_nonempty (EABView *view)
-{
- ESelectionModel *selection_model;
-
- selection_model = get_selection_model (view);
- if (selection_model == NULL)
- return FALSE;
-
- return e_selection_model_selected_count (selection_model) != 0;
-}
-
-gboolean
-eab_view_can_create (EABView *view)
-{
- return view ? eab_model_editable (view->model) : FALSE;
-}
-
-gboolean
-eab_view_can_print (EABView *view)
-{
- return view && view->model ? eab_model_contact_count (view->model) : FALSE;
-}
-
-gboolean
-eab_view_can_save_as (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) : FALSE;
-}
-
-gboolean
-eab_view_can_view (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) : FALSE;
-}
-
-gboolean
-eab_view_can_send (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) : FALSE;
-}
-
-gboolean
-eab_view_can_send_to (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) : FALSE;
-}
-
-gboolean
-eab_view_can_delete (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE;
-}
-
-gboolean
-eab_view_can_cut (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE;
-}
-
-gboolean
-eab_view_can_copy (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) : FALSE;
-}
-
-gboolean
-eab_view_can_paste (EABView *view)
-{
- return view ? eab_model_editable (view->model) : FALSE;
-}
-
-gboolean
-eab_view_can_select_all (EABView *view)
-{
- return view ? eab_model_contact_count (view->model) != 0 : FALSE;
-}
-
-gboolean
-eab_view_can_stop (EABView *view)
-{
- return view ? eab_model_can_stop (view->model) : FALSE;
-}
-
-gboolean
-eab_view_can_copy_to_folder (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) : FALSE;
-}
-
-gboolean
-eab_view_can_move_to_folder (EABView *view)
-{
- return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE;
-}
-
-EABMenuTargetSelect *
-eab_view_get_menu_target (EABView *view, EABMenu *menu)
-{
- GPtrArray *cards = g_ptr_array_new();
- ESelectionModel *selection_model;
- EABMenuTargetSelect *t;
-
- selection_model = get_selection_model (view);
- if (selection_model) {
- ContactAndBook cab;
-
- cab.view = view;
- cab.closure = cards;
- e_selection_model_foreach(selection_model, get_card_1, &cab);
- }
-
- t = eab_menu_target_new_select(menu, view->book, !eab_model_editable(view->model), cards);
- t->target.widget = (GtkWidget *)view;
-
- return t;
-}
diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h
index 03bdcb5a1a..4e0f82eeb0 100644
--- a/addressbook/gui/widgets/e-addressbook-view.h
+++ b/addressbook/gui/widgets/e-addressbook-view.h
@@ -20,142 +20,106 @@
*
*/
-#ifndef __EAB_VIEW_H__
-#define __EAB_VIEW_H__
+#ifndef E_ADDRESSBOOK_VIEW_H
+#define E_ADDRESSBOOK_VIEW_H
-#include <gtk/gtk.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <widgets/menus/gal-view-instance.h>
#include <libebook/e-book.h>
-#include "e-addressbook-model.h"
-#include "eab-contact-display.h"
-#include "eab-menu.h"
-#include "widgets/menus/gal-view-menus.h"
-#include "misc/e-search-bar.h"
-#include "misc/e-filter-bar.h"
+#include <libebook/e-contact.h>
-G_BEGIN_DECLS
+#include <menus/gal-view-instance.h>
+#include <misc/e-selection-model.h>
+#include <shell/e-shell-view.h>
-/* EABView - A card displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * --------------------------------------------------------------------------------
- */
+#include "e-addressbook-model.h"
+#include "eab-contact-display.h"
-#define E_TYPE_AB_VIEW (eab_view_get_type ())
-#define EAB_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_AB_VIEW, EABView))
-#define EAB_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_AB_VIEW, EABViewClass))
-#define E_IS_ADDRESSBOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_AB_VIEW))
-#define E_IS_ADDRESSBOOK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_AB_VIEW))
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_VIEW \
+ (e_addressbook_view_get_type ())
+#define E_ADDRESSBOOK_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookView))
+#define E_ADDRESSBOOK_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewClass))
+#define E_IS_ADDRESSBOOK_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW))
+#define E_IS_ADDRESSBOOK_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW))
+#define E_ADDRESSBOOK_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewClass))
-typedef enum {
- EAB_VIEW_NONE, /* initialized to this */
- EAB_VIEW_MINICARD,
- EAB_VIEW_TABLE
-} EABViewType;
+G_BEGIN_DECLS
-typedef struct _EABView EABView;
-typedef struct _EABViewClass EABViewClass;
+typedef struct _EAddressbookView EAddressbookView;
+typedef struct _EAddressbookViewClass EAddressbookViewClass;
+typedef struct _EAddressbookViewPrivate EAddressbookViewPrivate;
-struct _EABView
-{
+struct _EAddressbookView {
GtkVBox parent;
-
- /* item specific fields */
- EABViewType view_type;
-
- EABModel *model;
-
- GtkWidget *invisible;
- GList *clipboard_contacts;
-
- EBook *book;
- ESource *source;
- gchar *query;
- guint editable : 1;
-
- gint displayed_contact;
-
- GObject *object;
- GtkWidget *widget;
-
- GtkWidget *contact_display_window;
- GtkWidget *contact_display;
- GtkWidget *paned;
-
- /* Menus handler and the view instance */
- GalViewInstance *view_instance;
- GalViewMenus *view_menus;
- GalView *current_view;
- BonoboUIComponent *uic;
-
- /* the search bar and related machinery */
- EFilterBar *search;
- gint ecml_changed_id;
- RuleContext *search_context;
- FilterRule *search_rule;
+ EAddressbookViewPrivate *priv;
};
-struct _EABViewClass
-{
+struct _EAddressbookViewClass {
GtkVBoxClass parent_class;
- /*
- * Signals
- */
- void (*status_message) (EABView *view, const gchar *message);
- void (*search_result) (EABView *view, EBookViewStatus status);
- void (*folder_bar_message) (EABView *view, const gchar *message);
- void (*command_state_change) (EABView *view);
+ /* Signals */
+ void (*open_contact) (EAddressbookView *view,
+ EContact *contact,
+ gboolean is_new_contact);
+ void (*popup_event) (EAddressbookView *view,
+ GdkEvent *event);
+ void (*status_message) (EAddressbookView *view,
+ const gchar *message);
+ void (*command_state_change) (EAddressbookView *view);
+ void (*selection_change) (EAddressbookView *view);
};
-GtkWidget *eab_view_new (void);
-GType eab_view_get_type (void);
-
-void eab_view_show_contact_preview (EABView *view, gboolean show);
-
-void eab_view_setup_menus (EABView *view,
- BonoboUIComponent *uic);
-void eab_view_discard_menus (EABView *view);
-
-RuleContext *eab_view_peek_search_context (EABView *view);
-FilterRule *eab_view_peek_search_rule (EABView *view);
-
-void eab_view_save_as (EABView *view, gboolean all);
-void eab_view_view (EABView *view);
-void eab_view_send (EABView *view);
-void eab_view_send_to (EABView *view);
-void eab_view_print (EABView *view,
- GtkPrintOperationAction action);
-void eab_view_delete_selection (EABView *view, gboolean is_delete);
-void eab_view_cut (EABView *view);
-void eab_view_copy (EABView *view);
-void eab_view_paste (EABView *view);
-void eab_view_select_all (EABView *view);
-void eab_view_show_all (EABView *view);
-void eab_view_stop (EABView *view);
-void eab_view_copy_to_folder (EABView *view, gboolean all);
-void eab_view_move_to_folder (EABView *view, gboolean all);
-
-gboolean eab_view_can_create (EABView *view);
-gboolean eab_view_can_print (EABView *view);
-gboolean eab_view_can_save_as (EABView *view);
-gboolean eab_view_can_view (EABView *view);
-gboolean eab_view_can_send (EABView *view);
-gboolean eab_view_can_send_to (EABView *view);
-gboolean eab_view_can_delete (EABView *view);
-gboolean eab_view_can_cut (EABView *view);
-gboolean eab_view_can_copy (EABView *view);
-gboolean eab_view_can_paste (EABView *view);
-gboolean eab_view_can_select_all (EABView *view);
-gboolean eab_view_can_stop (EABView *view);
-gboolean eab_view_can_copy_to_folder (EABView *view);
-gboolean eab_view_can_move_to_folder (EABView *view);
-
-EABMenuTargetSelect *eab_view_get_menu_target (EABView *view, EABMenu *menu);
+GType e_addressbook_view_get_type (void);
+GtkWidget * e_addressbook_view_new (EShellView *shell_view,
+ ESource *source);
+EAddressbookModel *
+ e_addressbook_view_get_model (EAddressbookView *view);
+GalViewInstance *
+ e_addressbook_view_get_view_instance
+ (EAddressbookView *view);
+GObject * e_addressbook_view_get_view_object
+ (EAddressbookView *view);
+GtkWidget * e_addressbook_view_get_view_widget
+ (EAddressbookView *view);
+GList * e_addressbook_view_get_selected (EAddressbookView *view);
+ESelectionModel *
+ e_addressbook_view_get_selection_model
+ (EAddressbookView *view);
+EShellView * e_addressbook_view_get_shell_view
+ (EAddressbookView *view);
+ESource * e_addressbook_view_get_source (EAddressbookView *view);
+void e_addressbook_view_save_as (EAddressbookView *view,
+ gboolean all);
+void e_addressbook_view_view (EAddressbookView *view);
+void e_addressbook_view_print (EAddressbookView *view,
+ GtkPrintOperationAction action);
+void e_addressbook_view_delete_selection
+ (EAddressbookView *view,
+ gboolean is_delete);
+void e_addressbook_view_cut (EAddressbookView *view);
+void e_addressbook_view_copy (EAddressbookView *view);
+void e_addressbook_view_paste (EAddressbookView *view);
+void e_addressbook_view_select_all (EAddressbookView *view);
+void e_addressbook_view_show_all (EAddressbookView *view);
+void e_addressbook_view_stop (EAddressbookView *view);
+void e_addressbook_view_copy_to_folder
+ (EAddressbookView *view,
+ gboolean all);
+void e_addressbook_view_move_to_folder
+ (EAddressbookView *view,
+ gboolean all);
+
+gboolean e_addressbook_view_can_create (EAddressbookView *view);
G_END_DECLS
-#endif /* __EAB_VIEW_H__ */
+#endif /* E_ADDRESSBOOK_VIEW_H */
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.c b/addressbook/gui/widgets/e-minicard-view-widget.c
index 62778b4bf3..cb3904728e 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.c
+++ b/addressbook/gui/widgets/e-minicard-view-widget.c
@@ -53,6 +53,8 @@ enum {
};
enum {
+ CREATE_CONTACT,
+ CREATE_CONTACT_LIST,
SELECTION_CHANGE,
COLUMN_WIDTH_CHANGED,
RIGHT_CLICK,
@@ -140,6 +142,24 @@ e_minicard_view_widget_class_init (EMinicardViewWidgetClass *class)
0.0, G_MAXDOUBLE, 150.0,
G_PARAM_READWRITE));
+ signals [CREATE_CONTACT] =
+ g_signal_new ("create-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, create_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals [CREATE_CONTACT_LIST] =
+ g_signal_new ("create-contact-list",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, create_contact_list),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
signals [SELECTION_CHANGE] =
g_signal_new ("selection_change",
G_OBJECT_CLASS_TYPE (object_class),
@@ -315,6 +335,18 @@ column_width_changed (ESelectionModel *esm, double width, EMinicardViewWidget *w
signals [COLUMN_WIDTH_CHANGED], 0, width);
}
+static void
+create_contact (EMinicardView *view, EMinicardViewWidget *widget)
+{
+ g_signal_emit (widget, signals[CREATE_CONTACT], 0);
+}
+
+static void
+create_contact_list (EMinicardView *view, EMinicardViewWidget *widget)
+{
+ g_signal_emit (widget, signals[CREATE_CONTACT_LIST], 0);
+}
+
static guint
right_click (EMinicardView *view, GdkEvent *event, EMinicardViewWidget *widget)
{
@@ -369,6 +401,12 @@ e_minicard_view_widget_realize (GtkWidget *widget)
"column_width_changed",
G_CALLBACK (column_width_changed), view);
g_signal_connect (view->emv,
+ "create-contact",
+ G_CALLBACK (create_contact), view);
+ g_signal_connect (view->emv,
+ "create-contact-list",
+ G_CALLBACK (create_contact_list), view);
+ g_signal_connect (view->emv,
"right_click",
G_CALLBACK (right_click), view);
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.h b/addressbook/gui/widgets/e-minicard-view-widget.h
index 2b01dce65e..bf9fe8dd4e 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.h
+++ b/addressbook/gui/widgets/e-minicard-view-widget.h
@@ -57,6 +57,8 @@ struct _EMinicardViewWidget
struct _EMinicardViewWidgetClass
{
ECanvasClass parent_class;
+ void (*create_contact) (EMinicardViewWidget *emvw);
+ void (*create_contact_list) (EMinicardViewWidget *emvw);
void (*selection_change) (EMinicardViewWidget *emvw);
void (*column_width_changed) (EMinicardViewWidget *emvw, double width);
guint (*right_click) (EMinicardViewWidget *emvw);
diff --git a/addressbook/gui/widgets/e-minicard-view.c b/addressbook/gui/widgets/e-minicard-view.c
index c33b1f3045..80d7291113 100644
--- a/addressbook/gui/widgets/e-minicard-view.c
+++ b/addressbook/gui/widgets/e-minicard-view.c
@@ -33,7 +33,8 @@
#include <misc/e-canvas.h>
#include <glib/gi18n.h>
#include <string.h>
-#include "a11y/addressbook/ea-addressbook.h"
+#include "e-util/e-util.h"
+#include "ea-addressbook.h"
static void e_minicard_view_drag_data_get(GtkWidget *widget,
GdkDragContext *context,
@@ -55,6 +56,8 @@ enum {
};
enum {
+ CREATE_CONTACT,
+ CREATE_CONTACT_LIST,
RIGHT_CLICK,
LAST_SIGNAL
};
@@ -159,7 +162,7 @@ set_empty_message (EMinicardView *view)
EBook *book;
if (view->adapter) {
- EABModel *model = NULL;
+ EAddressbookModel *model = NULL;
g_object_get (view->adapter,
"editable", &editable,
@@ -170,7 +173,7 @@ set_empty_message (EMinicardView *view)
if (!e_book_check_static_capability (book, "do-initial-query"))
perform_initial_query = TRUE;
- searching = model && eab_model_can_stop (model);
+ searching = model && e_addressbook_model_can_stop (model);
}
if (searching) {
@@ -195,13 +198,13 @@ set_empty_message (EMinicardView *view)
}
static void
-writable_status_change (EABModel *model, gboolean writable, EMinicardView *view)
+writable_status_change (EAddressbookModel *model, gboolean writable, EMinicardView *view)
{
set_empty_message (view);
}
static void
-stop_state_changed (EABModel *model, EMinicardView *view)
+stop_state_changed (EAddressbookModel *model, EMinicardView *view)
{
set_empty_message (view);
}
@@ -229,7 +232,7 @@ e_minicard_view_set_property (GObject *object,
case PROP_ADAPTER:
if (view->adapter) {
if (view->writable_status_id || view->stop_state_id) {
- EABModel *model;
+ EAddressbookModel *model;
g_object_get (view->adapter,
"model", &model,
NULL);
@@ -252,7 +255,7 @@ e_minicard_view_set_property (GObject *object,
"model", view->adapter,
NULL);
if (view->adapter) {
- EABModel *model;
+ EAddressbookModel *model;
g_object_get (view->adapter,
"model", &model,
NULL);
@@ -337,7 +340,7 @@ e_minicard_view_dispose (GObject *object)
if (view->adapter) {
if (view->writable_status_id || view->stop_state_id) {
- EABModel *model;
+ EAddressbookModel *model;
g_object_get (view->adapter,
"model", &model,
NULL);
@@ -382,13 +385,8 @@ e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event)
g_object_get(view->adapter, "editable", &editable, NULL);
- if (editable) {
- EBook *book;
- g_object_get(view, "book", &book, NULL);
-
- if (book && E_IS_BOOK (book))
- eab_show_contact_editor (book, e_contact_new(), TRUE, editable);
- }
+ if (editable)
+ e_minicard_view_create_contact (view);
return TRUE;
}
case GDK_BUTTON_PRESS:
@@ -546,6 +544,22 @@ e_minicard_view_class_init (EMinicardViewClass *klass)
FALSE,
G_PARAM_READWRITE));
+ signals [CREATE_CONTACT] =
+ g_signal_new ("create-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals [CREATE_CONTACT_LIST] =
+ g_signal_new ("create-contact-list",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
signals [RIGHT_CLICK] =
g_signal_new ("right_click",
G_OBJECT_CLASS_TYPE (object_class),
@@ -654,3 +668,19 @@ e_minicard_view_get_card_list (EMinicardView *view)
mal.list = g_list_reverse (mal.list);
return mal.list;
}
+
+void
+e_minicard_view_create_contact (EMinicardView *view)
+{
+ g_return_if_fail (E_IS_MINICARD_VIEW (view));
+
+ g_signal_emit (view, signals[CREATE_CONTACT], 0);
+}
+
+void
+e_minicard_view_create_contact_list (EMinicardView *view)
+{
+ g_return_if_fail (E_IS_MINICARD_VIEW (view));
+
+ g_signal_emit (view, signals[CREATE_CONTACT_LIST], 0);
+}
diff --git a/addressbook/gui/widgets/e-minicard-view.h b/addressbook/gui/widgets/e-minicard-view.h
index 82b8cbb63a..babfddd0c3 100644
--- a/addressbook/gui/widgets/e-minicard-view.h
+++ b/addressbook/gui/widgets/e-minicard-view.h
@@ -26,7 +26,7 @@
#include "e-minicard.h"
-#include <misc/e-reflow.h>
+#include <text/e-reflow.h>
#include <misc/e-selection-model-simple.h>
#include <libebook/e-book.h>
#include "e-addressbook-reflow-adapter.h"
@@ -90,6 +90,8 @@ void e_minicard_view_remove_selection (EMinicardView *view,
void e_minicard_view_jump_to_letter (EMinicardView *view,
gunichar letter);
GList *e_minicard_view_get_card_list (EMinicardView *view);
+void e_minicard_view_create_contact (EMinicardView *view);
+void e_minicard_view_create_contact_list (EMinicardView *view);
G_END_DECLS
diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c
index c4568aac3b..1f6bc14117 100644
--- a/addressbook/gui/widgets/e-minicard.c
+++ b/addressbook/gui/widgets/e-minicard.c
@@ -35,11 +35,10 @@
#include "e-minicard.h"
#include "e-minicard-label.h"
#include "e-minicard-view.h"
-#include "e-contact-editor.h"
#include <e-util/e-html-utils.h>
#include <e-util/e-icon-factory.h>
#include <libebook/e-destination.h>
-#include "a11y/addressbook/ea-addressbook.h"
+#include "ea-addressbook.h"
static void e_minicard_init (EMinicard *card);
static void e_minicard_class_init (EMinicardClass *class);
@@ -86,6 +85,7 @@ enum {
enum {
SELECTED,
DRAG_BEGIN,
+ OPEN_CONTACT,
STYLE_SET,
LAST_SIGNAL
};
@@ -101,7 +101,7 @@ common_location [] =
{ "OTHER", N_ ("Other Email") }
};
-static guint e_minicard_signals [LAST_SIGNAL] = {0, };
+static guint signals [LAST_SIGNAL] = {0, };
GType
e_minicard_get_type (void)
@@ -200,7 +200,7 @@ e_minicard_class_init (EMinicardClass *class)
E_TYPE_CONTACT,
G_PARAM_READWRITE));
- e_minicard_signals [SELECTED] =
+ signals [SELECTED] =
g_signal_new ("selected",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
@@ -209,7 +209,7 @@ e_minicard_class_init (EMinicardClass *class)
e_marshal_INT__POINTER,
G_TYPE_INT, 1, G_TYPE_POINTER);
- e_minicard_signals [DRAG_BEGIN] =
+ signals [DRAG_BEGIN] =
g_signal_new ("drag_begin",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
@@ -218,7 +218,17 @@ e_minicard_class_init (EMinicardClass *class)
e_marshal_INT__POINTER,
G_TYPE_INT, 1, G_TYPE_POINTER);
- e_minicard_signals [STYLE_SET] =
+ signals [OPEN_CONTACT] =
+ g_signal_new ("open-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardClass, open_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CONTACT);
+
+ signals [STYLE_SET] =
g_signal_new ("style_set",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
@@ -249,8 +259,6 @@ e_minicard_init (EMinicard *minicard)
minicard->list_icon_pixbuf = e_icon_factory_get_icon (LIST_ICON_NAME, GTK_ICON_SIZE_MENU);
minicard->list_icon_size = gdk_pixbuf_get_height (minicard->list_icon_pixbuf);
- minicard->editor = NULL;
-
minicard->changed = FALSE;
e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard), e_minicard_reflow);
@@ -525,50 +533,12 @@ e_minicard_unrealize (GnomeCanvasItem *item)
(* GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize) (item);
}
-/* Callback used when the contact editor is closed */
-static void
-editor_closed_cb (GtkObject *editor, gpointer data)
-{
- EMinicard *minicard = data;
- g_object_unref (editor);
- minicard->editor = NULL;
-}
-
-gboolean
-e_minicard_activate_editor(EMinicard *minicard)
+void
+e_minicard_activate_editor (EMinicard *minicard)
{
- GnomeCanvasItem *item = (GnomeCanvasItem *)minicard;
-
- if (minicard->editor) {
- eab_editor_raise (minicard->editor);
- }
- else {
- EBook *book = NULL;
- if (E_IS_MINICARD_VIEW(item->parent)) {
- g_object_get(item->parent, "book", &book, NULL);
- }
-
- if (book != NULL) {
- if (e_contact_get (minicard->contact, E_CONTACT_IS_LIST)) {
- EContactListEditor *editor = eab_show_contact_list_editor (book, minicard->contact,
- FALSE, e_book_is_writable (book));
- minicard->editor = EAB_EDITOR (editor);
- }
- else {
- EContactEditor *editor = eab_show_contact_editor (book, minicard->contact,
- FALSE, e_book_is_writable (book));
- minicard->editor = EAB_EDITOR (editor);
- }
-
- g_object_ref (minicard->editor);
- g_signal_connect (minicard->editor, "editor_closed",
- G_CALLBACK (editor_closed_cb), minicard);
-
- g_object_unref (book);
- }
- }
+ g_return_if_fail (E_IS_MINICARD (minicard));
- return TRUE;
+ g_signal_emit (minicard, signals[OPEN_CONTACT], 0, minicard->contact);
}
static gboolean
@@ -652,7 +622,8 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
break;
case GDK_2BUTTON_PRESS:
if (event->button.button == 1 && E_IS_MINICARD_VIEW (item->parent)) {
- return e_minicard_activate_editor (e_minicard);
+ e_minicard_activate_editor (e_minicard);
+ return TRUE;
}
break;
case GDK_KEY_PRESS:
@@ -722,7 +693,8 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
}
else if (event->key.keyval == GDK_Return ||
event->key.keyval == GDK_KP_Enter) {
- return e_minicard_activate_editor (e_minicard);
+ e_minicard_activate_editor (e_minicard);
+ return TRUE;
}
break;
default:
@@ -1149,7 +1121,7 @@ e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event)
gint ret_val = 0;
GnomeCanvasItem *parent;
g_signal_emit (minicard,
- e_minicard_signals[DRAG_BEGIN], 0,
+ signals[DRAG_BEGIN], 0,
event, &ret_val);
parent = GNOME_CANVAS_ITEM (minicard)->parent;
diff --git a/addressbook/gui/widgets/e-minicard.h b/addressbook/gui/widgets/e-minicard.h
index 033e981636..4135090763 100644
--- a/addressbook/gui/widgets/e-minicard.h
+++ b/addressbook/gui/widgets/e-minicard.h
@@ -24,7 +24,6 @@
#define __E_MINICARD_H__
#include <gtk/gtk.h>
-#include "addressbook/gui/contact-editor/eab-editor.h"
#include <libgnomecanvas/gnome-canvas.h>
#include <libebook/e-contact.h>
@@ -71,8 +70,6 @@ struct _EMinicard
GdkPixbuf *list_icon_pixbuf;
double list_icon_size;
- EABEditor *editor;
-
GList *fields; /* Of type EMinicardField */
guint needs_remodeling : 1;
@@ -101,6 +98,7 @@ struct _EMinicardClass
gint (* selected) (EMinicard *minicard, GdkEvent *event);
gint (* drag_begin) (EMinicard *minicard, GdkEvent *event);
+ void (* open_contact) (EMinicard *minicard, EContact *contact);
void (* style_set) (EMinicard *minicard, GtkStyle *previous_style);
};
@@ -121,7 +119,7 @@ gint e_minicard_compare (EMinicard *minicard1,
gint e_minicard_selected (EMinicard *minicard,
GdkEvent *event);
-gboolean e_minicard_activate_editor (EMinicard *minicard);
+void e_minicard_activate_editor (EMinicard *minicard);
G_END_DECLS
diff --git a/a11y/addressbook/ea-addressbook-view.c b/addressbook/gui/widgets/ea-addressbook-view.c
index 75309daa14..b2d7ebb171 100644
--- a/a11y/addressbook/ea-addressbook-view.c
+++ b/addressbook/gui/widgets/ea-addressbook-view.c
@@ -28,7 +28,7 @@
static G_CONST_RETURN gchar * ea_ab_view_get_name (AtkObject *accessible);
static G_CONST_RETURN gchar * ea_ab_view_get_description (AtkObject *accessible);
-static void ea_ab_view_class_init (EABViewClass *klass);
+static void ea_ab_view_class_init (EAddressbookViewClass *class);
static gpointer parent_class = NULL;
@@ -42,13 +42,13 @@ ea_ab_view_get_type (void)
if (!type) {
static GTypeInfo tinfo = {
- sizeof (EABViewClass),
+ sizeof (EAddressbookViewClass),
(GBaseInitFunc) NULL, /* base_init */
(GBaseFinalizeFunc) NULL, /* base_finalize */
(GClassInitFunc) ea_ab_view_class_init,
(GClassFinalizeFunc) NULL, /* class_finalize */
NULL, /* class_data */
- sizeof (EaABView),
+ sizeof (EAddressbookView),
0, /* n_preallocs */
(GInstanceInitFunc) NULL, /* instance init */
NULL /* value table */
@@ -74,14 +74,15 @@ ea_ab_view_get_type (void)
}
static void
-ea_ab_view_class_init (EABViewClass *klass)
+ea_ab_view_class_init (EAddressbookViewClass *class)
{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ AtkObjectClass *atk_object_class;
- parent_class = g_type_class_peek_parent (klass);
+ parent_class = g_type_class_peek_parent (class);
- class->get_name = ea_ab_view_get_name;
- class->get_description = ea_ab_view_get_description;
+ atk_object_class = ATK_OBJECT_CLASS (class);
+ atk_object_class->get_name = ea_ab_view_get_name;
+ atk_object_class->get_description = ea_ab_view_get_description;
}
static G_CONST_RETURN gchar *
diff --git a/a11y/addressbook/ea-addressbook-view.h b/addressbook/gui/widgets/ea-addressbook-view.h
index 6179b6758e..6179b6758e 100644
--- a/a11y/addressbook/ea-addressbook-view.h
+++ b/addressbook/gui/widgets/ea-addressbook-view.h
diff --git a/a11y/addressbook/ea-addressbook.c b/addressbook/gui/widgets/ea-addressbook.c
index 8ccff66a5b..14fc4c1ca3 100644
--- a/a11y/addressbook/ea-addressbook.c
+++ b/addressbook/gui/widgets/ea-addressbook.c
@@ -21,7 +21,7 @@
*/
#include <text/e-text.h>
-#include "ea-factory.h"
+#include "a11y/ea-factory.h"
#include "ea-addressbook.h"
#include "ea-minicard.h"
#include "ea-minicard-view.h"
@@ -55,7 +55,7 @@ void e_minicard_view_a11y_init (void)
void eab_view_a11y_init (void)
{
- EA_SET_FACTORY (eab_view_get_type (), ea_ab_view);
+ EA_SET_FACTORY (E_TYPE_ADDRESSBOOK_VIEW, ea_ab_view);
}
static gboolean
diff --git a/a11y/addressbook/ea-addressbook.h b/addressbook/gui/widgets/ea-addressbook.h
index 97b691dc18..97b691dc18 100644
--- a/a11y/addressbook/ea-addressbook.h
+++ b/addressbook/gui/widgets/ea-addressbook.h
diff --git a/a11y/addressbook/ea-minicard-view.c b/addressbook/gui/widgets/ea-minicard-view.c
index 35d1a3d716..ffccbfa1d1 100644
--- a/a11y/addressbook/ea-minicard-view.c
+++ b/addressbook/gui/widgets/ea-minicard-view.c
@@ -361,11 +361,9 @@ static gboolean atk_action_interface_do_action (AtkAction *action, gint i)
{
gboolean return_value = TRUE;
EMinicardView *card_view;
- EContact *contact = e_contact_new();
AtkGObjectAccessible *atk_gobj= NULL;
EReflow *reflow = NULL;
- EBook *book;
atk_gobj = ATK_GOBJECT_ACCESSIBLE (action);
reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
@@ -374,26 +372,21 @@ static gboolean atk_action_interface_do_action (AtkAction *action, gint i)
return FALSE;
card_view = E_MINICARD_VIEW (reflow);
- g_object_get(card_view,
- "book", &book,
- NULL);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
switch (i) {
case 0:
/* New Contact */
- eab_show_contact_editor (book, contact, TRUE, TRUE);
+ e_minicard_view_create_contact (card_view);
break;
case 1:
/* New Contact List */
- eab_show_contact_list_editor (book, contact, TRUE, TRUE);
+ e_minicard_view_create_contact_list (card_view);
break;
default:
return_value = FALSE;
break;
}
- g_object_unref (book);
- g_object_unref (contact);
+
return return_value;
}
diff --git a/a11y/addressbook/ea-minicard-view.h b/addressbook/gui/widgets/ea-minicard-view.h
index cc8eaecae7..cc8eaecae7 100644
--- a/a11y/addressbook/ea-minicard-view.h
+++ b/addressbook/gui/widgets/ea-minicard-view.h
diff --git a/a11y/addressbook/ea-minicard.c b/addressbook/gui/widgets/ea-minicard.c
index 8791a68e73..8791a68e73 100644
--- a/a11y/addressbook/ea-minicard.c
+++ b/addressbook/gui/widgets/ea-minicard.c
diff --git a/a11y/addressbook/ea-minicard.h b/addressbook/gui/widgets/ea-minicard.h
index 8b49ab6284..8b49ab6284 100644
--- a/a11y/addressbook/ea-minicard.h
+++ b/addressbook/gui/widgets/ea-minicard.h
diff --git a/addressbook/gui/widgets/eab-config.c b/addressbook/gui/widgets/eab-config.c
index 91056e0544..f47a696195 100644
--- a/addressbook/gui/widgets/eab-config.c
+++ b/addressbook/gui/widgets/eab-config.c
@@ -27,7 +27,6 @@
#include "eab-config.h"
static GObjectClass *ecp_parent_class;
-static GObjectClass *ecph_parent_class;
struct _EABConfigPrivate {
guint source_changed_id;
@@ -143,48 +142,3 @@ eab_config_target_new_source (EABConfig *ecp, struct _ESource *source)
return t;
}
-
-static const EConfigHookTargetMask ecph_no_masks[] = {
- { NULL }
-};
-
-static const EConfigHookTargetMap ecph_targets[] = {
- { "source", EAB_CONFIG_TARGET_SOURCE, ecph_no_masks },
- { NULL },
-};
-
-static void
-ecph_class_init (EPluginHookClass *klass)
-{
- gint i;
-
- klass->id = "org.gnome.evolution.addressbook.config:1.0";
-
- for (i = 0; ecph_targets[i].type; i++) {
- e_config_hook_class_add_target_map ((EConfigHookClass *)klass, &ecph_targets[i]);
- }
-
- ((EConfigHookClass *)klass)->config_class = g_type_class_ref (eab_config_get_type ());
-}
-
-GType
-eab_config_hook_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EABConfigHookClass),
- NULL, NULL,
- (GClassInitFunc) ecph_class_init,
- NULL, NULL,
- sizeof (EABConfigHook), 0,
- (GInstanceInitFunc) NULL
- };
-
- ecph_parent_class = g_type_class_ref (e_config_hook_get_type ());
- type = g_type_register_static (e_config_hook_get_type (), "EABConfigHook", &info, 0);
- }
-
- return type;
-}
diff --git a/addressbook/gui/widgets/eab-config.h b/addressbook/gui/widgets/eab-config.h
index 8ecc8525bc..fcf6b76f00 100644
--- a/addressbook/gui/widgets/eab-config.h
+++ b/addressbook/gui/widgets/eab-config.h
@@ -60,21 +60,6 @@ EABConfig *eab_config_new (gint type, const gchar *menuid);
EABConfigTargetSource *eab_config_target_new_source (EABConfig *ecp, struct _ESource *source);
-/* ********************************************************************** */
-
-typedef struct _EABConfigHook EABConfigHook;
-typedef struct _EABConfigHookClass EABConfigHookClass;
-
-struct _EABConfigHook {
- EConfigHook hook;
-};
-
-struct _EABConfigHookClass {
- EConfigHookClass hook_class;
-};
-
-GType eab_config_hook_get_type (void);
-
G_END_DECLS
#endif
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
index bea167cc45..d47b3e1866 100644
--- a/addressbook/gui/widgets/eab-contact-display.c
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -25,27 +25,46 @@
#endif
#include "eab-contact-display.h"
-#include "eab-popup.h"
#include "eab-gui-util.h"
#include "e-util/e-util.h"
#include "e-util/e-html-utils.h"
#include "e-util/e-icon-factory.h"
+#include "e-util/e-plugin-ui.h"
#include <string.h>
#include <glib/gi18n.h>
#include <gtkhtml/gtkhtml.h>
#include <gtkhtml/gtkhtml-stream.h>
-#define HANDLE_MAILTO_INTERNALLY 1
+#define EAB_CONTACT_DISPLAY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayPrivate))
-#define PARENT_TYPE (GTK_TYPE_HTML)
+#define HANDLE_MAILTO_INTERNALLY 1
struct _EABContactDisplayPrivate {
EContact *contact;
+ EABContactDisplayMode mode;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *email_actions;
+ GtkActionGroup *uri_actions;
GtkWidget *invisible;
- gchar *selection_uri;
+
+ gchar *selected_uri;
+ gchar *clipboard_uri;
+};
+
+enum {
+ PROP_0,
+ PROP_CONTACT,
+ PROP_MODE
+};
+
+enum {
+ SEND_MESSAGE,
+ LAST_SIGNAL
};
static struct {
@@ -77,150 +96,154 @@ common_location [] =
#define MAX_COMPACT_IMAGE_DIMENSION 48
-static void
-eab_uri_popup_link_open(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EABPopupTargetURI *t = (EABPopupTargetURI *)ep->target;
+static const gchar *ui =
+"<ui>"
+" <popup>"
+" <menuitem action='open-link'/>"
+" <menuitem action='copy-link'/>"
+" <menuitem action='send-message'/>"
+" <menuitem action='copy-address'/>"
+" </popup>"
+"</ui>";
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, t->uri);
-}
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
static void
-eab_uri_popup_email_address_copy(EPopup *ep, EPopupItem *item, gpointer data)
+action_copy_address_cb (GtkAction *action,
+ EABContactDisplay *display)
{
- EABContactDisplay *display = data;
- struct _EABContactDisplayPrivate *p = display->priv;
- EABPopupTargetURI *t = (EABPopupTargetURI *)ep->target;
- const gchar *url = t->uri;
- gchar *html=NULL;
- gint i=0;
- GList *email_list, *l;
- gint email_num = atoi (url + strlen ("internal-mailto:"));
-
- email_list = e_contact_get (p->contact, E_CONTACT_EMAIL);
- for (l = email_list; l; l=l->next) {
- if (i==email_num)
- html = e_text_to_html (l->data, 0);
- i++;
- }
-
- g_free(p->selection_uri);
- p->selection_uri = g_strdup(html);
- g_free (html);
-
- gtk_selection_owner_set(p->invisible, GDK_SELECTION_PRIMARY, gtk_get_current_event_time());
- gtk_selection_owner_set(p->invisible, GDK_SELECTION_CLIPBOARD, gtk_get_current_event_time());
+ EContact *contact;
+ GList *list;
+ const gchar *uri;
+ gchar *html;
+ gint index;
+
+ uri = display->priv->selected_uri;
+ index = atoi (uri + strlen ("internal-mailto:"));
+ contact = eab_contact_display_get_contact (display);
+
+ list = e_contact_get (contact, E_CONTACT_EMAIL);
+ html = e_text_to_html (g_list_nth_data (list, index), 0);
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+
+ display->priv->clipboard_uri = html;
+ display->priv->selected_uri = NULL;
+
+ gtk_selection_owner_set (
+ display->priv->invisible, GDK_SELECTION_PRIMARY,
+ gtk_get_current_event_time ());
+ gtk_selection_owner_set (
+ display->priv->invisible, GDK_SELECTION_CLIPBOARD,
+ gtk_get_current_event_time ());
}
static void
-eab_uri_popup_link_copy(EPopup *ep, EPopupItem *pitem, gpointer data)
+action_copy_link_cb (GtkAction *action,
+ EABContactDisplay *display)
{
- EABContactDisplay *display = data;
- struct _EABContactDisplayPrivate *p = display->priv;
-
- g_free(p->selection_uri);
- p->selection_uri = g_strdup(pitem->user_data);
-
- gtk_selection_owner_set(p->invisible, GDK_SELECTION_PRIMARY, gtk_get_current_event_time());
- gtk_selection_owner_set(p->invisible, GDK_SELECTION_CLIPBOARD, gtk_get_current_event_time());
+ display->priv->clipboard_uri = display->priv->selected_uri;
+ display->priv->selected_uri = NULL;
+
+ gtk_selection_owner_set (
+ display->priv->invisible, GDK_SELECTION_PRIMARY,
+ gtk_get_current_event_time ());
+ gtk_selection_owner_set (
+ display->priv->invisible, GDK_SELECTION_CLIPBOARD,
+ gtk_get_current_event_time ());
}
static void
-eab_uri_popup_address_send(EPopup *ep, EPopupItem *item, gpointer data)
+action_open_link_cb (GtkAction *action,
+ EABContactDisplay *display)
{
- EABPopupTargetURI *t = (EABPopupTargetURI *)ep->target;
- const gchar *url = t->uri;
- EABContactDisplay *display = data;
- struct _EABContactDisplayPrivate *p = display->priv;
-
- gint mail_num = atoi (url + strlen ("internal-mailto:"));
-
- if (mail_num == -1)
- return;
-
- eab_send_contact (p->contact, mail_num, EAB_DISPOSITION_AS_TO);
-
+ /* XXX Pass a parent window. */
+ e_show_uri (NULL, display->priv->selected_uri);
}
static void
-eab_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint time_stamp, EABContactDisplay *display)
+action_send_message_cb (GtkAction *action,
+ EABContactDisplay *display)
{
- struct _EABContactDisplayPrivate *p = display->priv;
-
- if (p->selection_uri == NULL)
- return;
-
- gtk_selection_data_set(data, data->target, 8, (guchar *)p->selection_uri, strlen(p->selection_uri));
+ EDestination *destination;
+ EContact *contact;
+ const gchar *uri;
+ gint row;
+
+ uri = display->priv->selected_uri;
+ row = atoi (uri + strlen ("internal-mailto:"));
+ g_return_if_fail (row >= 0);
+
+ destination = e_destination_new ();
+ contact = eab_contact_display_get_contact (display);
+ e_destination_set_contact (destination, contact, row);
+ g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
+ g_object_unref (destination);
}
-static void
-eab_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, EABContactDisplay *display)
-{
-#if 0
- struct _EABContactDisplayPrivate *p = display->priv;
-
- g_free(p->selection_uri);
- p->selection_uri = NULL;
-#endif
-}
+static GtkActionEntry email_entries[] = {
+
+ { "copy-address",
+ NULL,
+ N_("Copy _Email Address"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_copy_address_cb) },
+
+ { "send-message",
+ NULL,
+ N_("_Send New Message To..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_send_message_cb) }
+};
-static EPopupItem eab_uri_popups[] = {
- { E_POPUP_ITEM, (gchar *) "05.open", (gchar *) N_("_Open Link in Browser"), eab_uri_popup_link_open, NULL, NULL, EAB_POPUP_URI_NOT_MAILTO },
- { E_POPUP_ITEM, (gchar *) "10.copy", (gchar *) N_("_Copy Link Location"), eab_uri_popup_link_copy, NULL, (gchar *) "edit-copy", EAB_POPUP_URI_NOT_MAILTO },
- { E_POPUP_ITEM, (gchar *) "15.send", (gchar *) N_("_Send New Message To..."), eab_uri_popup_address_send, NULL, (gchar *) "mail-message-new", EAB_POPUP_URI_MAILTO},
- { E_POPUP_ITEM, (gchar *) "20.copy", (gchar *) N_("Copy _Email Address"), eab_uri_popup_email_address_copy, NULL, (gchar *) "edit-copy", EAB_POPUP_URI_MAILTO},
- };
+static GtkActionEntry uri_entries[] = {
+
+ { "copy-link",
+ NULL,
+ N_("_Copy Link Location"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_copy_link_cb) },
+
+ { "open-link",
+ NULL,
+ N_("_Open Link in Browser"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_open_link_cb) }
+};
static void
-eab_uri_popup_free(EPopup *ep, GSList *list, gpointer data)
+contact_display_selection_get (EABContactDisplay *display,
+ GtkSelectionData *data,
+ guint info,
+ guint time_stamp)
{
- while (list) {
- GSList *n = list->next;
- struct _EPopupItem *item = list->data;
-
- g_free(item->user_data);
- item->user_data = NULL;
- g_slist_free_1(list);
+ if (display->priv->clipboard_uri == NULL)
+ return;
- list = n;
- }
+ gtk_selection_data_set (
+ data, data->target, 8,
+ (guchar *) display->priv->clipboard_uri,
+ strlen (display->priv->clipboard_uri));
}
-static gint
-eab_uri_popup_event(EABContactDisplay *display, GdkEvent *event, const gchar *uri)
+static void
+contact_display_selection_clear_event (EABContactDisplay *display,
+ GdkEventSelection *event)
{
- EABPopup *emp;
- EABPopupTargetURI *t;
- GtkMenu *menu;
- GSList *menus = NULL;
- gint i;
-
- emp = eab_popup_new("org.gnome.evolution.addressbook.contactdisplay.popup");
-
- t = eab_popup_target_new_uri(emp, uri);
- t->target.widget = (GtkWidget *)display;
-
- for (i=0;i<sizeof(eab_uri_popups)/sizeof(eab_uri_popups[0]);i++) {
- eab_uri_popups[i].user_data = g_strdup(t->uri);
- menus = g_slist_prepend(menus, &eab_uri_popups[i]);
- }
- e_popup_add_items((EPopup *)emp, menus, NULL, eab_uri_popup_free, display);
-
- menu = e_popup_create_menu_once((EPopup *)emp,(EPopupTarget*)t, 0);
-
- if (event == NULL) {
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
- } else {
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
- }
-
- return TRUE;
+ g_free (display->priv->clipboard_uri);
+ display->priv->clipboard_uri = NULL;
}
static void
-on_url_requested (GtkHTML *html, const gchar *url, GtkHTMLStream *handle,
- EABContactDisplay *display)
+contact_display_on_url_requested (GtkHTML *html,
+ const gchar *url,
+ GtkHTMLStream *handle,
+ EABContactDisplay *display)
{
if (!strcmp (url, "internal-contact-photo:")) {
EContactPhoto *photo;
@@ -253,16 +276,25 @@ on_url_requested (GtkHTML *html, const gchar *url, GtkHTMLStream *handle,
}
static void
-on_link_clicked (GtkHTML *html, const gchar *uri, EABContactDisplay *display)
+contact_display_on_link_clicked (GtkHTML *html,
+ const gchar *uri,
+ EABContactDisplay *display)
{
#ifdef HANDLE_MAILTO_INTERNALLY
if (!strncmp (uri, "internal-mailto:", strlen ("internal-mailto:"))) {
- gint mail_num = atoi (uri + strlen ("internal-mailto:"));
+ EDestination *destination;
+ EContact *contact;
+ gint email_num;
- if (mail_num == -1)
+ email_num = atoi (uri + strlen ("internal-mailto:"));
+ if (email_num == -1)
return;
- eab_send_contact (display->priv->contact, mail_num, EAB_DISPOSITION_AS_TO);
+ destination = e_destination_new ();
+ contact = eab_contact_display_get_contact (display);
+ e_destination_set_contact (destination, contact, email_num);
+ g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
+ g_object_unref (destination);
return;
}
@@ -272,44 +304,6 @@ on_link_clicked (GtkHTML *html, const gchar *uri, EABContactDisplay *display)
e_show_uri (NULL, uri);
}
-#if 0
-static void
-render_address (GtkHTMLStream *html_stream, EContact *contact, const gchar *html_label, EContactField adr_field, EContactField label_field)
-{
- EContactAddress *adr;
- const gchar *label;
-
- label = e_contact_get_const (contact, label_field);
- if (label) {
- gchar *html = e_text_to_html (label, E_TEXT_TO_HTML_CONVERT_NL);
-
- gtk_html_stream_printf (html_stream, "<tr><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td><td valign=\"top\" width=\"100\"><font color=" HEADER_COLOR ">%s:</font><br><a href=\"http://www.mapquest.com/\">%s</a></td><td valign=\"top\">%s</td></tr>", html_label, _("(map)"), html);
-
-This shoul g_free (html);
- return;
- }
-
- adr = e_contact_get (contact, adr_field);
- if (adr &&
- (adr->po || adr->ext || adr->street || adr->locality || adr->region || adr->code || adr->country)) {
-
- gtk_html_stream_printf (html_stream, "<tr><td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td><td valign=\"top\" width=\"100\"><font color=" HEADER_COLOR ">%s:</font><br><a href=\"http://www.mapquest.com/\">%s</a></td><td valign=\"top\">", html_label, _("map"));
-
- if (adr->po && *adr->po) gtk_html_stream_printf (html_stream, "%s<br>", adr->po);
- if (adr->ext && *adr->ext) gtk_html_stream_printf (html_stream, "%s<br>", adr->ext);
- if (adr->street && *adr->street) gtk_html_stream_printf (html_stream, "%s<br>", adr->street);
- if (adr->locality && *adr->locality) gtk_html_stream_printf (html_stream, "%s<br>", adr->locality);
- if (adr->region && *adr->region) gtk_html_stream_printf (html_stream, "%s<br>", adr->region);
- if (adr->code && *adr->code) gtk_html_stream_printf (html_stream, "%s<br>", adr->code);
- if (adr->country && *adr->country) gtk_html_stream_printf (html_stream, "%s<br>", adr->country);
-
- gtk_html_stream_printf (html_stream, "</td></tr>");
- }
- if (adr)
- e_contact_address_free (adr);
-}
-#endif
-
static void
render_name_value (GtkHTMLStream *html_stream, const gchar *label, const gchar *str, const gchar *icon, guint html_flags)
{
@@ -667,12 +661,6 @@ eab_contact_display_render_normal (EABContactDisplay *display, EContact *contact
GtkHTMLStream *html_stream;
gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
- if (display->priv->contact)
- g_object_unref (display->priv->contact);
- display->priv->contact = contact;
- if (display->priv->contact)
- g_object_ref (display->priv->contact);
-
html_stream = gtk_html_begin (GTK_HTML (display));
gtk_html_stream_write (html_stream, HTML_HEADER, sizeof (HTML_HEADER) - 1);
gtk_html_stream_printf (html_stream, "<body><table width=\"100%%\"><tr><td %s>\n", is_rtl ? " align=\"right\" " : "");
@@ -722,16 +710,11 @@ eab_contact_display_render_normal (EABContactDisplay *display, EContact *contact
}
static void
-eab_contact_display_render_compact (EABContactDisplay *display, EContact *contact)
+eab_contact_display_render_compact (EABContactDisplay *display,
+ EContact *contact)
{
GtkHTMLStream *html_stream;
- if (display->priv->contact)
- g_object_unref (display->priv->contact);
- display->priv->contact = contact;
- if (display->priv->contact)
- g_object_ref (display->priv->contact);
-
html_stream = gtk_html_begin (GTK_HTML (display));
gtk_html_stream_write (html_stream, HTML_HEADER, sizeof (HTML_HEADER) - 1);
gtk_html_stream_write (html_stream, "<body>\n", 7);
@@ -905,97 +888,266 @@ eab_contact_display_render_compact (EABContactDisplay *display, EContact *contac
gtk_html_end (GTK_HTML (display), html_stream, GTK_HTML_STREAM_OK);
}
-void
-eab_contact_display_render (EABContactDisplay *display, EContact *contact,
- EABContactDisplayRenderMode mode)
+static gint
+contact_display_button_press_event (GtkWidget *widget,
+ GdkEvent *event,
+ EABContactDisplay *display)
{
- switch (mode) {
- case EAB_CONTACT_DISPLAY_RENDER_NORMAL:
- eab_contact_display_render_normal (display, contact);
- break;
- case EAB_CONTACT_DISPLAY_RENDER_COMPACT:
- eab_contact_display_render_compact (display, contact);
- break;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ GtkWidget *menu;
+ gboolean has_email;
+ gchar *uri;
+
+ if (event->button.button != 3)
+ return FALSE;
+
+ uri = gtk_html_get_url_at (
+ GTK_HTML (widget),
+ event->button.x, event->button.y);
+
+ if (uri == NULL)
+ return FALSE;
+
+ g_free (display->priv->selected_uri);
+ display->priv->selected_uri = uri;
+
+ ui_manager = display->priv->ui_manager;
+ menu = gtk_ui_manager_get_widget (ui_manager, "/popup");
+ g_return_val_if_fail (GTK_IS_MENU (menu), FALSE);
+
+ has_email = (g_ascii_strncasecmp (uri, "internal-mailto:", 16) == 0);
+
+ /* Show the appropriate actions. */
+ action_group = display->priv->email_actions;
+ gtk_action_group_set_visible (action_group, has_email);
+ action_group = display->priv->uri_actions;
+ gtk_action_group_set_visible (action_group, !has_email);
+
+ if (event != NULL)
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ event->button.button, event->button.time);
+ else
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ 0, gtk_get_current_event_time ());
+
+ return TRUE;
+}
+
+static void
+contact_display_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CONTACT:
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_MODE:
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (object),
+ g_value_get_int (value));
+ return;
}
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-static gint
-eab_html_press_event (GtkWidget *widget, GdkEvent *event,EABContactDisplay *display)
+static void
+contact_display_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- gchar *uri;
- gboolean res = FALSE;
+ switch (property_id) {
+ case PROP_CONTACT:
+ g_value_set_object (
+ value, eab_contact_display_get_contact (
+ EAB_CONTACT_DISPLAY (object)));
+ return;
- if (event->button.button!= 3 )
- return FALSE;
+ case PROP_MODE:
+ g_value_set_int (
+ value, eab_contact_display_get_mode (
+ EAB_CONTACT_DISPLAY (object)));
+ return;
+ }
- uri = gtk_html_get_url_at (GTK_HTML (widget), event->button.x, event->button.y);
- if (uri) {
- eab_uri_popup_event(display,event,uri);
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
- g_free(uri);
+static void
+contact_display_dispose (GObject *object)
+{
+ EABContactDisplayPrivate *priv;
- return res;
+ priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (object);
+
+ if (priv->contact != NULL) {
+ g_object_unref (priv->contact);
+ priv->contact = NULL;
+ }
+
+ if (priv->ui_manager != NULL) {
+ g_object_unref (priv->ui_manager);
+ priv->ui_manager = NULL;
+ }
+
+ if (priv->email_actions != NULL) {
+ g_object_unref (priv->email_actions);
+ priv->email_actions = NULL;
+ }
+
+ if (priv->uri_actions != NULL) {
+ g_object_unref (priv->uri_actions);
+ priv->uri_actions = NULL;
+ }
+
+ if (priv->invisible != NULL) {
+ g_object_unref (priv->invisible);
+ priv->invisible = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
-GtkWidget*
-eab_contact_display_new (void)
+static void
+contact_display_finalize (GObject *object)
{
- EABContactDisplay *display;
-
- struct _EABContactDisplayPrivate *p;
-
- display = g_object_new (EAB_TYPE_CONTACT_DISPLAY, NULL);
- p=display->priv = g_new0 (EABContactDisplayPrivate, 1);
-
- gtk_html_set_default_content_type (GTK_HTML (display), "text/html; charset=utf-8");
-
- gtk_html_set_editable (GTK_HTML (display), FALSE);
-
- g_signal_connect (display, "url_requested",
- G_CALLBACK (on_url_requested),
- display);
- g_signal_connect (display, "link_clicked",
- G_CALLBACK (on_link_clicked),
- display);
- g_signal_connect(display, "button_press_event",
- G_CALLBACK(eab_html_press_event),
- display);
- p->invisible = gtk_invisible_new();
- g_signal_connect(p->invisible, "selection_get", G_CALLBACK(eab_selection_get), display);
- g_signal_connect(p->invisible, "selection_clear_event", G_CALLBACK(eab_selection_clear_event), display);
- gtk_selection_add_target(p->invisible, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0);
- gtk_selection_add_target(p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1);
-
-#if 0
- g_signal_connect (display, "object_requested",
- G_CALLBACK (on_object_requested),
- mail_display);
- g_signal_connect (display, "button_press_event",
- G_CALLBACK (html_button_press_event), mail_display);
- g_signal_connect (display, "motion_notify_event",
- G_CALLBACK (html_motion_notify_event), mail_display);
- g_signal_connect (display, "enter_notify_event",
- G_CALLBACK (html_enter_notify_event), mail_display);
- g_signal_connect (display, "iframe_created",
- G_CALLBACK (html_iframe_created), mail_display);
- g_signal_connect (display, "on_url",
- G_CALLBACK (html_on_url), mail_display);
-#endif
+ EABContactDisplayPrivate *priv;
+
+ priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (object);
- return GTK_WIDGET (display);
+ g_free (priv->selected_uri);
+ g_free (priv->clipboard_uri);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-eab_contact_display_init (GObject *object)
+eab_contact_display_class_init (EABContactDisplayClass *class)
{
- gtk_html_construct ((GtkHTML *)object);
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EABContactDisplayPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = contact_display_set_property;
+ object_class->get_property = contact_display_get_property;
+ object_class->dispose = contact_display_dispose;
+ object_class->finalize = contact_display_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTACT,
+ g_param_spec_object (
+ "contact",
+ NULL,
+ NULL,
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ /* XXX Make this a real enum property. */
+ g_object_class_install_property (
+ object_class,
+ PROP_MODE,
+ g_param_spec_int (
+ "mode",
+ NULL,
+ NULL,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ G_PARAM_READWRITE));
+
+ signals[SEND_MESSAGE] = g_signal_new (
+ "send-message",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EABContactDisplayClass, send_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_DESTINATION);
}
static void
-eab_contact_display_class_init (GtkObjectClass *object_class)
+eab_contact_display_init (EABContactDisplay *display)
{
- /* object_class->destroy = mail_display_destroy;*/
+ GtkActionGroup *action_group;
+ GtkHTML *html;
+ const gchar *id;
+
+ display->priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (display);
+ display->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
+ display->priv->ui_manager = gtk_ui_manager_new ();
+ display->priv->invisible = gtk_invisible_new ();
+
+ g_object_ref_sink (display->priv->invisible);
+
+ action_group = gtk_action_group_new ("email");
+ gtk_action_group_set_translation_domain (
+ action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (
+ action_group, email_entries,
+ G_N_ELEMENTS (email_entries), display);
+ gtk_ui_manager_insert_action_group (
+ display->priv->ui_manager, action_group, 0);
+ display->priv->email_actions = action_group;
+
+ action_group = gtk_action_group_new ("uri");
+ gtk_action_group_set_translation_domain (
+ action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (
+ action_group, uri_entries,
+ G_N_ELEMENTS (uri_entries), display);
+ gtk_ui_manager_insert_action_group (
+ display->priv->ui_manager, action_group, 0);
+ display->priv->uri_actions = action_group;
+
+ gtk_ui_manager_add_ui_from_string (
+ display->priv->ui_manager, ui, -1, NULL);
+
+ html = GTK_HTML (display);
+ gtk_html_construct (html);
+ gtk_html_set_editable (html, FALSE);
+ gtk_html_set_default_content_type (html, "text/html; charset=utf-8");
+
+ g_signal_connect (
+ display, "url-requested",
+ G_CALLBACK (contact_display_on_url_requested), display);
+ g_signal_connect (
+ display, "link-clicked",
+ G_CALLBACK (contact_display_on_link_clicked), display);
+ g_signal_connect (
+ display, "button-press-event",
+ G_CALLBACK (contact_display_button_press_event), display);
+
+ g_signal_connect_swapped (
+ display->priv->invisible, "selection-get",
+ G_CALLBACK (contact_display_selection_get), display);
+ g_signal_connect_swapped (
+ display->priv->invisible, "selection-clear-event",
+ G_CALLBACK (contact_display_selection_clear_event), display);
+ gtk_selection_add_target (
+ display->priv->invisible,
+ GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0);
+ gtk_selection_add_target (
+ display->priv->invisible,
+ GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1);
+
+ id = "org.gnome.evolution.contact-display";
+ e_plugin_ui_register_manager (display->priv->ui_manager, id, display);
+ e_plugin_ui_enable_manager (display->priv->ui_manager, id);
}
GType
@@ -1003,21 +1155,98 @@ eab_contact_display_get_type (void)
{
static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
sizeof (EABContactDisplayClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
(GClassInitFunc) eab_contact_display_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
sizeof (EABContactDisplay),
- 0, /* n_preallocs */
+ 0, /* n_preallocs */
(GInstanceInitFunc) eab_contact_display_init,
+ NULL /* value_table */
};
- type = g_type_register_static (PARENT_TYPE, "EABContactDisplay", &info, 0);
+ type = g_type_register_static (
+ GTK_TYPE_HTML, "EABContactDisplay", &type_info, 0);
}
return type;
}
+
+GtkWidget *
+eab_contact_display_new (void)
+{
+ return g_object_new (EAB_TYPE_CONTACT_DISPLAY, NULL);
+}
+
+EContact *
+eab_contact_display_get_contact (EABContactDisplay *display)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), NULL);
+
+ return display->priv->contact;
+}
+
+void
+eab_contact_display_set_contact (EABContactDisplay *display,
+ EContact *contact)
+{
+ EABContactDisplayMode mode;
+
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
+
+ mode = eab_contact_display_get_mode (display);
+
+ if (contact != NULL)
+ g_object_ref (contact);
+ if (display->priv->contact != NULL)
+ g_object_unref (display->priv->contact);
+ display->priv->contact = contact;
+
+ switch (mode) {
+ case EAB_CONTACT_DISPLAY_RENDER_NORMAL:
+ eab_contact_display_render_normal (display, contact);
+ break;
+
+ case EAB_CONTACT_DISPLAY_RENDER_COMPACT:
+ eab_contact_display_render_compact (display, contact);
+ break;
+ }
+
+ g_object_notify (G_OBJECT (display), "contact");
+}
+
+EABContactDisplayMode
+eab_contact_display_get_mode (EABContactDisplay *display)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), 0);
+
+ return display->priv->mode;
+}
+
+void
+eab_contact_display_set_mode (EABContactDisplay *display,
+ EABContactDisplayMode mode)
+{
+ EContact *contact;
+
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
+
+ display->priv->mode = mode;
+ contact = eab_contact_display_get_contact (display);
+
+ switch (mode) {
+ case EAB_CONTACT_DISPLAY_RENDER_NORMAL:
+ eab_contact_display_render_normal (display, contact);
+ break;
+
+ case EAB_CONTACT_DISPLAY_RENDER_COMPACT:
+ eab_contact_display_render_compact (display, contact);
+ break;
+ }
+
+ g_object_notify (G_OBJECT (display), "mode");
+}
diff --git a/addressbook/gui/widgets/eab-contact-display.h b/addressbook/gui/widgets/eab-contact-display.h
index 80acc5eefe..5a6902fc20 100644
--- a/addressbook/gui/widgets/eab-contact-display.h
+++ b/addressbook/gui/widgets/eab-contact-display.h
@@ -20,41 +20,67 @@
*
*/
-#ifndef _EAB_CONTACT_DISPLAY_H_
-#define _EAB_CONTACT_DISPLAY_H_
+#ifndef EAB_CONTACT_DISPLAY_H
+#define EAB_CONTACT_DISPLAY_H
#include <gtkhtml/gtkhtml.h>
#include <libebook/e-contact.h>
+#include <libebook/e-destination.h>
-#define EAB_TYPE_CONTACT_DISPLAY (eab_contact_display_get_type ())
-#define EAB_CONTACT_DISPLAY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplay))
-#define EAB_CONTACT_DISPLAY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayClass))
-#define IS_EAB_CONTACT_DISPLAY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EAB_TYPE_CONTACT_DISPLAY))
-#define IS_EAB_CONTACT_DISPLAY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EAB_TYPE_CONTACT_DISPLAY))
+/* Standard GObject macros */
+#define EAB_TYPE_CONTACT_DISPLAY \
+ (eab_contact_display_get_type ())
+#define EAB_CONTACT_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplay))
+#define EAB_CONTACT_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayClass))
+#define EAB_IS_CONTACT_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY))
+#define EAB_IS_CONTACT_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EAB_TYPE_CONTACT_DISPLAY))
+#define EAB_CONTACT_DISPLAY_GET_CLASS(obj) \
+ (G_TYPE_ISNTANCE_GET_CLASS \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayClass))
+
+G_BEGIN_DECLS
typedef struct _EABContactDisplay EABContactDisplay;
-typedef struct _EABContactDisplayPrivate EABContactDisplayPrivate;
typedef struct _EABContactDisplayClass EABContactDisplayClass;
+typedef struct _EABContactDisplayPrivate EABContactDisplayPrivate;
typedef enum {
EAB_CONTACT_DISPLAY_RENDER_NORMAL, /* for use in the preview pane */
EAB_CONTACT_DISPLAY_RENDER_COMPACT /* for use with embedded vcards (e.g, the EABVCardControl) */
-} EABContactDisplayRenderMode;
+} EABContactDisplayMode;
struct _EABContactDisplay {
GtkHTML parent;
-
EABContactDisplayPrivate *priv;
};
struct _EABContactDisplayClass {
GtkHTMLClass parent_class;
+
+ /* Signals */
+ void (*send_message) (EABContactDisplay *display,
+ EDestination *destination);
};
-GType eab_contact_display_get_type (void);
-GtkWidget * eab_contact_display_new (void);
+GType eab_contact_display_get_type (void);
+GtkWidget * eab_contact_display_new (void);
+
+EContact * eab_contact_display_get_contact (EABContactDisplay *display);
+void eab_contact_display_set_contact (EABContactDisplay *display,
+ EContact *contact);
+EABContactDisplayMode
+ eab_contact_display_get_mode (EABContactDisplay *display);
+void eab_contact_display_set_mode (EABContactDisplay *display,
+ EABContactDisplayMode mode);
-void eab_contact_display_render (EABContactDisplay *display, EContact *contact,
- EABContactDisplayRenderMode render_mode);
+G_END_DECLS
-#endif /* _EAB_CONTACT_DISPLAY_H_ */
+#endif /* EAB_CONTACT_DISPLAY_H */
diff --git a/addressbook/gui/widgets/eab-gui-util.c b/addressbook/gui/widgets/eab-gui-util.c
index c11ff5351a..effea132c3 100644
--- a/addressbook/gui/widgets/eab-gui-util.c
+++ b/addressbook/gui/widgets/eab-gui-util.c
@@ -40,17 +40,11 @@
#include "misc/e-image-chooser.h"
#include <e-util/e-icon-factory.h>
#include "eab-contact-merging.h"
-#include <composer/e-msg-composer.h>
-#include <mail/em-composer-utils.h>
/* we link to camel for decoding quoted printable email addresses */
#include <camel/camel-mime-utils.h>
-#include "addressbook/gui/contact-editor/eab-editor.h"
-#include "addressbook/gui/contact-editor/e-contact-editor.h"
-#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
-#include "addressbook/gui/component/addressbook-component.h"
-#include "addressbook/gui/component/addressbook.h"
+#include "addressbook/util/addressbook.h"
/* the NULL's in this table correspond to the status codes
that should *never* be generated by a backend */
@@ -201,139 +195,6 @@ eab_prompt_save_dialog (GtkWindow *parent)
return e_error_run (parent, "addressbook:prompt-save", NULL);
}
-static void
-added_cb (EBook* book, EBookStatus status, EContact *contact,
- gpointer data)
-{
- gboolean is_list = GPOINTER_TO_INT (data);
-
- if (status != E_BOOK_ERROR_OK && status != E_BOOK_ERROR_CANCELLED) {
- eab_error_dialog (is_list ? _("Error adding list") : _("Error adding contact"), status);
- }
-}
-
-static void
-modified_cb (EBook* book, EBookStatus status, EContact *contact,
- gpointer data)
-{
- gboolean is_list = GPOINTER_TO_INT (data);
-
- if (status != E_BOOK_ERROR_OK && status != E_BOOK_ERROR_CANCELLED) {
- eab_error_dialog (is_list ? _("Error modifying list") : _("Error modifying contact"),
- status);
- }
-}
-
-static void
-deleted_cb (EBook* book, EBookStatus status, EContact *contact,
- gpointer data)
-{
- gboolean is_list = GPOINTER_TO_INT (data);
-
- if (status != E_BOOK_ERROR_OK) {
- eab_error_dialog (is_list ? _("Error removing list") : _("Error removing contact"),
- status);
- }
-}
-
-static void
-editor_closed_cb (GtkObject *editor, gpointer data)
-{
- g_object_unref (editor);
-}
-
-EContactEditor *
-eab_show_contact_editor (EBook *book, EContact *contact,
- gboolean is_new_contact,
- gboolean editable)
-{
- EContactEditor *ce;
-
- ce = e_contact_editor_new (book, contact, is_new_contact, editable);
-
- g_signal_connect (ce, "contact_added",
- G_CALLBACK (added_cb), GINT_TO_POINTER (FALSE));
- g_signal_connect (ce, "contact_modified",
- G_CALLBACK (modified_cb), GINT_TO_POINTER (FALSE));
- g_signal_connect (ce, "contact_deleted",
- G_CALLBACK (deleted_cb), GINT_TO_POINTER (FALSE));
- g_signal_connect (ce, "editor_closed",
- G_CALLBACK (editor_closed_cb), NULL);
-
- return ce;
-}
-
-EContactListEditor *
-eab_show_contact_list_editor (EBook *book, EContact *contact,
- gboolean is_new_contact,
- gboolean editable)
-{
- EContactListEditor *ce;
-
- ce = e_contact_list_editor_new (book, contact, is_new_contact, editable);
-
- g_signal_connect (ce, "contact_added",
- G_CALLBACK (added_cb), GINT_TO_POINTER (TRUE));
- g_signal_connect (ce, "contact_modified",
- G_CALLBACK (modified_cb), GINT_TO_POINTER (TRUE));
- g_signal_connect (ce, "contact_deleted",
- G_CALLBACK (deleted_cb), GINT_TO_POINTER (TRUE));
- g_signal_connect (ce, "editor_closed",
- G_CALLBACK (editor_closed_cb), GINT_TO_POINTER (TRUE));
-
- eab_editor_show (EAB_EDITOR (ce));
-
- return ce;
-}
-
-static void
-view_contacts (EBook *book, GList *list, gboolean editable)
-{
- for (; list; list = list->next) {
- EContact *contact = list->data;
- if (e_contact_get (contact, E_CONTACT_IS_LIST))
- eab_show_contact_list_editor (book, contact, FALSE, editable);
- else
- eab_show_contact_editor (book, contact, FALSE, editable);
- }
-}
-
-void
-eab_show_multiple_contacts (EBook *book,
- GList *list,
- gboolean editable)
-{
- if (list) {
- gint length = g_list_length (list);
- if (length > 5) {
- GtkWidget *dialog;
- gint response;
-
- dialog = gtk_message_dialog_new (NULL,
- 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- ngettext("Opening %d contact will open %d new window as well.\n"
- "Do you really want to display this contact?",
- "Opening %d contacts will open %d new windows as well.\n"
- "Do you really want to display all of these contacts?",
- length),
- length,
- length);
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- _("_Don't Display"), GTK_RESPONSE_NO,
- _("Display _All Contacts"), GTK_RESPONSE_YES,
- NULL);
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- if (response == GTK_RESPONSE_YES)
- view_contacts (book, list, editable);
- } else {
- view_contacts (book, list, editable);
- }
- }
-}
-
static gint
file_exists(GtkWindow *window, const gchar *filename)
{
@@ -627,16 +488,6 @@ struct ContactCopyProcess_ {
ContactCopyDone done_cb;
};
-#if 0
-static void
-contact_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
-{
- if (status != E_BOOK_ERROR_OK) {
- eab_error_dialog (_("Error removing contact"), status);
- }
-}
-#endif
-
static void
do_delete (gpointer data, gpointer user_data)
{
@@ -781,234 +632,6 @@ eab_transfer_contacts (EBook *source, GList *contacts /* adopted */, gboolean de
addressbook_load (dest, got_book_cb, process);
}
-typedef struct {
- EContact *contact;
- gint email_num; /* if the contact is a person (not a list), the email address to use */
-} ContactAndEmailNum;
-
-static void
-eab_send_to_contact_and_email_num_list (GList *contact_list)
-{
- EMsgComposer *composer;
- EComposerHeaderTable *table;
- GPtrArray *to_array;
- GPtrArray *bcc_array;
-
- union {
- gpointer *pdata;
- EDestination **destinations;
- } convert;
-
- if (contact_list == NULL)
- return;
-
- composer = e_msg_composer_new ();
- table = e_msg_composer_get_header_table (composer);
- em_composer_utils_setup_default_callbacks (composer);
-
- to_array = g_ptr_array_new ();
- bcc_array = g_ptr_array_new ();
-
- /* Sort contacts into "To" and "Bcc" destinations. */
- while (contact_list != NULL) {
- ContactAndEmailNum *ce = contact_list->data;
- EContact *contact = ce->contact;
- EDestination *destination;
-
- destination = e_destination_new ();
- e_destination_set_contact (destination, contact, 0);
-
- if (e_destination_is_evolution_list (destination)) {
- if (e_destination_list_show_addresses (destination))
- g_ptr_array_add (to_array, destination);
- else
- g_ptr_array_add (bcc_array, destination);
- } else
- g_ptr_array_add (to_array, destination);
-
- contact_list = g_list_next (contact_list);
- }
-
- /* Add sentinels to each array. */
- g_ptr_array_add (to_array, NULL);
- g_ptr_array_add (bcc_array, NULL);
-
- /* XXX Acrobatics like this make me question whether NULL-terminated
- * arrays are really the best argument type for passing a list of
- * destinations to the header table. */
-
- /* Set "To" destinations. */
- convert.pdata = to_array->pdata;
- e_composer_header_table_set_destinations_to (
- table, convert.destinations);
- g_ptr_array_free (to_array, FALSE);
- e_destination_freev (convert.destinations);
-
- /* Add "Bcc" destinations.
- * Add destinations instead of setting, so we don't remove
- * automatic BCC addresses that have already been added. */
- convert.pdata = bcc_array->pdata;
- e_composer_header_table_add_destinations_bcc (
- table, convert.destinations);
- g_ptr_array_free (bcc_array, FALSE);
- e_destination_freev (convert.destinations);
-
- gtk_widget_show (GTK_WIDGET (composer));
-}
-
-static const gchar *
-get_email (EContact *contact, EContactField field_id, gchar **to_free)
-{
- gchar *name = NULL, *mail = NULL;
- const gchar *value = e_contact_get_const (contact, field_id);
-
- *to_free = NULL;
-
- if (eab_parse_qp_email (value, &name, &mail)) {
- *to_free = g_strdup_printf ("%s <%s>", name, mail);
- value = *to_free;
- }
-
- g_free (name);
- g_free (mail);
-
- return value;
-}
-
-static void
-eab_send_contact_list_as_attachment (GList *contacts)
-{
- EMsgComposer *composer;
- EComposerHeaderTable *table;
- CamelMimePart *attachment;
- gchar *data;
-
- if (contacts == NULL)
- return;
-
- composer = e_msg_composer_new ();
- table = e_msg_composer_get_header_table (composer);
- em_composer_utils_setup_default_callbacks (composer);
-
- attachment = camel_mime_part_new ();
- data = eab_contact_list_to_string (contacts);
-
- camel_mime_part_set_content (
- attachment, data, strlen (data), "text/x-vcard");
-
- if (contacts->next != NULL)
- camel_mime_part_set_description (
- attachment, _("Multiple vCards"));
- else {
- EContact *contact = contacts->data;
- const gchar *file_as;
- gchar *description;
-
- file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
- description = g_strdup_printf (_("vCard for %s"), file_as);
- camel_mime_part_set_description (attachment, description);
- g_free (description);
- }
-
- camel_mime_part_set_disposition (attachment, "attachment");
-
- e_msg_composer_attach (composer, attachment);
- camel_object_unref (attachment);
-
- if (contacts->next != NULL)
- e_composer_header_table_set_subject (
- table, _("Contact information"));
- else {
- EContact *contact = contacts->data;
- gchar *tempstr;
- const gchar *tempstr2;
- gchar *tempfree = NULL;
-
- tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS);
- if (!tempstr2 || !*tempstr2)
- tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
- if (!tempstr2 || !*tempstr2)
- tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG);
- if (!tempstr2 || !*tempstr2) {
- g_free (tempfree);
- tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree);
- }
- if (!tempstr2 || !*tempstr2) {
- g_free (tempfree);
- tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree);
- }
- if (!tempstr2 || !*tempstr2) {
- g_free (tempfree);
- tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree);
- }
-
- if (!tempstr2 || !*tempstr2)
- tempstr = g_strdup_printf (_("Contact information"));
- else
- tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2);
-
- e_composer_header_table_set_subject (table, tempstr);
-
- g_free (tempstr);
- g_free (tempfree);
- }
-
- gtk_widget_show (GTK_WIDGET (composer));
-}
-
-void
-eab_send_contact_list (GList *contacts, EABDisposition disposition)
-{
- switch (disposition) {
- case EAB_DISPOSITION_AS_TO: {
- GList *list = NULL, *l;
-
- for (l = contacts; l; l = l->next) {
- ContactAndEmailNum *ce = g_new (ContactAndEmailNum, 1);
- ce->contact = l->data;
- ce->email_num = 0; /* hardcode this */
-
- list = g_list_append (list, ce);
- }
-
- eab_send_to_contact_and_email_num_list (list);
-
- g_list_foreach (list, (GFunc)g_free, NULL);
- g_list_free (list);
- break;
- }
- case EAB_DISPOSITION_AS_ATTACHMENT:
- eab_send_contact_list_as_attachment (contacts);
- break;
- }
-}
-
-void
-eab_send_contact (EContact *contact, gint email_num, EABDisposition disposition)
-{
- GList *list = NULL;
-
- switch (disposition) {
- case EAB_DISPOSITION_AS_TO: {
- ContactAndEmailNum ce;
-
- ce.contact = contact;
- ce.email_num = email_num;
-
- list = g_list_prepend (NULL, &ce);
- eab_send_to_contact_and_email_num_list (list);
- break;
- }
- case EAB_DISPOSITION_AS_ATTACHMENT: {
- list = g_list_prepend (NULL, contact);
- eab_send_contact_list_as_attachment (list);
- break;
- }
- }
-
- g_list_free (list);
-}
-
GtkWidget *
eab_create_image_chooser_widget(gchar *name,
gchar *string1, gchar *string2,
diff --git a/addressbook/gui/widgets/eab-gui-util.h b/addressbook/gui/widgets/eab-gui-util.h
index cc7b127aaf..7422eabb65 100644
--- a/addressbook/gui/widgets/eab-gui-util.h
+++ b/addressbook/gui/widgets/eab-gui-util.h
@@ -26,8 +26,6 @@
#include <gtk/gtk.h>
#include <libebook/e-book.h>
-#include "addressbook/gui/contact-editor/e-contact-editor.h"
-#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
G_BEGIN_DECLS
@@ -40,17 +38,6 @@ void eab_search_result_dialog (GtkWidget *parent,
EBookViewStatus status);
gint eab_prompt_save_dialog (GtkWindow *parent);
-EContactEditor *eab_show_contact_editor (EBook *book,
- EContact *contact,
- gboolean is_new_contact,
- gboolean editable);
-EContactListEditor *eab_show_contact_list_editor (EBook *book,
- EContact *contact,
- gboolean is_new_contact,
- gboolean editable);
-void eab_show_multiple_contacts (EBook *book,
- GList *list,
- gboolean editable);
void eab_transfer_contacts (EBook *source,
GList *contacts, /* adopted */
gboolean delete_from_source,
@@ -64,25 +51,16 @@ void eab_contact_list_save (gchar *title,
GList *list,
GtkWindow *parent_window);
-typedef enum {
- EAB_DISPOSITION_AS_ATTACHMENT,
- EAB_DISPOSITION_AS_TO
-} EABDisposition;
-
-void eab_send_contact (EContact *contact,
- gint email_num,
- EABDisposition disposition);
-void eab_send_contact_list (GList *contacts,
- EABDisposition disposition);
-
GtkWidget *eab_create_image_chooser_widget (gchar *name, gchar *string1, gchar *string2, gint int1, gint int2);
ESource *eab_select_source (const gchar *title, const gchar *message,
const gchar *select_uid, GtkWindow *parent);
/* To parse quoted printable address & return email & name fields */
-gboolean eab_parse_qp_email (const gchar *string, gchar **name, gchar **email);
-gchar *eab_parse_qp_email_to_html (const gchar *string);
+gboolean eab_parse_qp_email (const gchar *string,
+ gchar **name,
+ gchar **email);
+gchar * eab_parse_qp_email_to_html (const gchar *string);
G_END_DECLS
diff --git a/addressbook/gui/widgets/eab-menu.c b/addressbook/gui/widgets/eab-menu.c
deleted file mode 100644
index e26e621437..0000000000
--- a/addressbook/gui/widgets/eab-menu.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include <libebook/e-contact.h>
-
-#include "eab-menu.h"
-
-static void eabm_standard_menu_factory(EMenu *emp, gpointer data);
-
-static GObjectClass *eabm_parent;
-
-static void
-eabm_init(GObject *o)
-{
- /*EABMenu *emp = (EABMenu *)o; */
-}
-
-static void
-eabm_finalise(GObject *o)
-{
- ((GObjectClass *)eabm_parent)->finalize(o);
-}
-
-static void
-eabm_target_free(EMenu *ep, EMenuTarget *t)
-{
- switch (t->type) {
- case EAB_MENU_TARGET_SELECT: {
- EABMenuTargetSelect *s = (EABMenuTargetSelect *)t;
- gint i;
-
- for (i=0;i<s->cards->len;i++)
- g_object_unref(s->cards->pdata[i]);
- g_ptr_array_free(s->cards, TRUE);
- if (s->book)
- g_object_unref(s->book);
- break; }
- }
-
- ((EMenuClass *)eabm_parent)->target_free(ep, t);
-}
-
-static void
-eabm_class_init(GObjectClass *klass)
-{
- klass->finalize = eabm_finalise;
- ((EMenuClass *)klass)->target_free = eabm_target_free;
-
- e_menu_class_add_factory((EMenuClass *)klass, NULL, (EMenuFactoryFunc)eabm_standard_menu_factory, NULL);
-}
-
-GType
-eab_menu_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EABMenuClass),
- NULL, NULL,
- (GClassInitFunc)eabm_class_init,
- NULL, NULL,
- sizeof(EABMenu), 0,
- (GInstanceInitFunc)eabm_init
- };
- eabm_parent = g_type_class_ref(e_menu_get_type());
- type = g_type_register_static(e_menu_get_type(), "EABMenu", &info, 0);
- }
-
- return type;
-}
-
-EABMenu *eab_menu_new(const gchar *menuid)
-{
- EABMenu *emp = g_object_new(eab_menu_get_type(), NULL);
-
- e_menu_construct(&emp->menu, menuid);
-
- return emp;
-}
-
-/**
- * eab_menu_target_new_select - create a menu target of the current selection.
- * @eabp: Address book menu.
- * @book: Book the cards belong to. May be NULL in which case cards must be an empty GPtrArray.
- * @readonly: Book is read-only mode. FIXME: Why can't we just get this off the book?
- * @cards: Cards selected. This will be freed on completion and the array indices unreferenced.
- *
- * Create a new selection menu target.
- *
- * Return value:
- **/
-EABMenuTargetSelect *
-eab_menu_target_new_select(EABMenu *eabp, struct _EBook *book, gint readonly, GPtrArray *cards)
-{
- EABMenuTargetSelect *t = e_menu_target_new(&eabp->menu, EAB_MENU_TARGET_SELECT, sizeof(*t));
- guint32 mask = ~0;
- gint has_email = FALSE, i;
-
- /* FIXME: duplicated in eab-popup.c */
-
- t->book = book;
- if (book)
- g_object_ref(book);
- t->cards = cards;
-
- for (i=0;i<cards->len && !has_email;i++) {
- EContact *contact = cards->pdata[i];
- GList *email;
-
- email = e_contact_get(E_CONTACT(contact), E_CONTACT_EMAIL);
- if (email) {
- has_email = TRUE;
-
- g_list_foreach(email, (GFunc)g_free, NULL);
- g_list_free(email);
- }
- }
-
- if (has_email)
- mask &= ~EAB_MENU_SELECT_EMAIL;
-
- if (!readonly)
- mask &= ~EAB_MENU_SELECT_EDITABLE;
-
- if (cards->len == 1)
- mask &= ~EAB_MENU_SELECT_ONE;
-
- if (cards->len > 1)
- mask &= ~EAB_MENU_SELECT_MANY;
-
- if (cards->len >= 1)
- mask &= ~EAB_MENU_SELECT_ANY;
-
- t->target.mask = mask;
-
- return t;
-}
-
-static void
-eabm_standard_menu_factory(EMenu *emp, gpointer data)
-{
- /* noop */
-}
-
-/* ********************************************************************** */
-
-/* menu plugin handler */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.item:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="IMAP4 and IMAP4v1 mail store">
- <hook class="org.gnome.mail.popupMenu:1.0"
- handler="HandlePopup">
- <menu id="any" target="select">
- <item
- type="item|toggle|radio|image|submenu|bar"
- active
- path="foo/bar"
- label="label"
- icon="foo"
- mask="select_one"
- activate="eabm_view_emacs"/>
- </menu>
- </extension>
-
-*/
-
-static gpointer eabmph_parent_class;
-#define eabmph ((EABMenuHook *)eph)
-
-static const EMenuHookTargetMask eabmph_select_masks[] = {
- { "one", EAB_MENU_SELECT_ONE },
- { "many", EAB_MENU_SELECT_MANY },
- { "any", EAB_MENU_SELECT_ANY },
- { "editable", EAB_MENU_SELECT_EDITABLE },
- { "email", EAB_MENU_SELECT_EMAIL },
- { NULL }
-};
-
-static const EMenuHookTargetMap eabmph_targets[] = {
- { "select", EAB_MENU_TARGET_SELECT, eabmph_select_masks },
- { NULL }
-};
-
-static void
-eabmph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)eabmph_parent_class)->finalize(o);
-}
-
-static void
-eabmph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = eabmph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.addressbook.bonobomenu:1.0";
-
- for (i=0;eabmph_targets[i].type;i++)
- e_menu_hook_class_add_target_map((EMenuHookClass *)klass, &eabmph_targets[i]);
-
- /* FIXME: leaks parent set class? */
- ((EMenuHookClass *)klass)->menu_class = g_type_class_ref(eab_menu_get_type());
-}
-
-GType
-eab_menu_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EABMenuHookClass), NULL, NULL, (GClassInitFunc) eabmph_class_init, NULL, NULL,
- sizeof(EABMenuHook), 0, (GInstanceInitFunc) NULL,
- };
-
- eabmph_parent_class = g_type_class_ref(e_menu_hook_get_type());
- type = g_type_register_static(e_menu_hook_get_type(), "EABMenuHook", &info, 0);
- }
-
- return type;
-}
diff --git a/addressbook/gui/widgets/eab-menu.h b/addressbook/gui/widgets/eab-menu.h
deleted file mode 100644
index 6f2b74c755..0000000000
--- a/addressbook/gui/widgets/eab-menu.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michel Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EAB_MENU_H__
-#define __EAB_MENU_H__
-
-#include <glib-object.h>
-#include <libebook/e-book.h>
-
-#include "e-util/e-menu.h"
-
-G_BEGIN_DECLS
-
-typedef struct _EABMenu EABMenu;
-typedef struct _EABMenuClass EABMenuClass;
-
-/* Current target description */
-enum _eab_menu_target_t {
- EAB_MENU_TARGET_SELECT
-};
-
-/**
- * enum _eab_menu_target_select_t - EABMenuTargetSelect qualifiers.
- *
- * @EAB_MENU_SELECT_ONE: Only one item is selected.
- * @EAB_MENU_SELECT_MANY: More than one item selected.
- * @EAB_MENU_SELECT_ANY: One or more items selected.
- * @EAB_MENU_SELECT_EDITABLE: Editable addressbook.
- * @EAB_MENU_SELECT_EMAIL: Has an email address.
- **/
-enum _eab_menu_target_select_t {
- EAB_MENU_SELECT_ONE = 1<<0,
- EAB_MENU_SELECT_MANY = 1<<1,
- EAB_MENU_SELECT_ANY = 1<<2,
- EAB_MENU_SELECT_EDITABLE = 1<<3,
- EAB_MENU_SELECT_EMAIL = 1<<4
-};
-
-typedef struct _EABMenuTargetSelect EABMenuTargetSelect;
-
-struct _EABMenuTargetSelect {
- EMenuTarget target;
-
- struct _EBook *book;
- GPtrArray *cards;
-};
-
-typedef struct _EMenuItem EABMenuItem;
-
-/* The object */
-struct _EABMenu {
- EMenu menu;
-
- struct _EABMenuPrivate *priv;
-};
-
-struct _EABMenuClass {
- EMenuClass menu_class;
-};
-
-GType eab_menu_get_type(void);
-
-EABMenu *eab_menu_new(const gchar *menuid);
-
-EABMenuTargetSelect *eab_menu_target_new_select(EABMenu *eabp, struct _EBook *book, gint readonly, GPtrArray *cards);
-
-/* ********************************************************************** */
-
-typedef struct _EABMenuHook EABMenuHook;
-typedef struct _EABMenuHookClass EABMenuHookClass;
-
-struct _EABMenuHook {
- EMenuHook hook;
-};
-
-struct _EABMenuHookClass {
- EMenuHookClass hook_class;
-};
-
-GType eab_menu_hook_get_type(void);
-
-G_END_DECLS
-
-#endif /* __EAB_MENU_H__ */
diff --git a/addressbook/gui/widgets/eab-popup-control.c b/addressbook/gui/widgets/eab-popup-control.c
deleted file mode 100644
index 28aa819e73..0000000000
--- a/addressbook/gui/widgets/eab-popup-control.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * This file is too big and this widget is too complicated. Forgive me.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- * Authors:
- * Jon Trowbridge <trow@ximian.com>
- * Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- */
-
-#include <config.h>
-#include <string.h>
-#include "addressbook.h"
-#include "eab-popup-control.h"
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-property-bag.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <addressbook/util/eab-book-util.h>
-#include <addressbook/gui/contact-editor/e-contact-editor.h>
-#include <addressbook/gui/contact-editor/e-contact-quick-add.h>
-#include <addressbook/gui/widgets/eab-contact-display.h>
-#include <addressbook/gui/widgets/eab-gui-util.h>
-
-static void eab_popup_control_set_name (EABPopupControl *pop, const gchar *name);
-static void eab_popup_control_set_email (EABPopupControl *pop, const gchar *email);
-static void eab_popup_control_set_vcard (EABPopupControl *pop, const gchar *vcard);
-
-static GtkObjectClass *parent_class;
-
-static void eab_popup_control_dispose (GObject *);
-static void eab_popup_control_query (EABPopupControl *);
-
-static void
-eab_popup_control_class_init (EABPopupControlClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->dispose = eab_popup_control_dispose;
-}
-
-static void
-eab_popup_control_init (EABPopupControl *pop)
-{
- pop->transitory = TRUE;
-}
-
-static void
-eab_popup_control_cleanup (EABPopupControl *pop)
-{
- if (pop->contact) {
- g_object_unref (pop->contact);
- pop->contact = NULL;
- }
-
- if (pop->scheduled_refresh) {
- g_source_remove (pop->scheduled_refresh);
- pop->scheduled_refresh = 0;
- }
-
- if (pop->query_tag) {
-#ifdef notyet
- e_book_simple_query_cancel (pop->book, pop->query_tag);
-#endif
- pop->query_tag = 0;
- }
-
- if (pop->book) {
- g_object_unref (pop->book);
- pop->book = NULL;
- }
-
- g_free (pop->name);
- pop->name = NULL;
-
- g_free (pop->email);
- pop->email = NULL;
-
- g_free (pop->vcard);
- pop->vcard = NULL;
-}
-
-static void
-eab_popup_control_dispose (GObject *obj)
-{
- EABPopupControl *pop = EAB_POPUP_CONTROL (obj);
-
- eab_popup_control_cleanup (pop);
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (obj);
-}
-
-GType
-eab_popup_control_get_type (void)
-{
- static GType pop_type = 0;
-
- if (!pop_type) {
- static const GTypeInfo pop_info = {
- sizeof (EABPopupControlClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) eab_popup_control_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EABPopupControl),
- 0, /* n_preallocs */
- (GInstanceInitFunc) eab_popup_control_init,
- };
-
- pop_type = g_type_register_static (gtk_event_box_get_type (), "EABPopupControl", &pop_info, 0);
- }
-
- return pop_type;
-}
-
-static void
-eab_popup_control_refresh_names (EABPopupControl *pop)
-{
- if (pop->name_widget) {
- if (pop->name && *pop->name) {
- gtk_label_set_text (GTK_LABEL (pop->name_widget), pop->name);
- gtk_widget_show (pop->name_widget);
- } else {
- gtk_widget_hide (pop->name_widget);
- }
- }
-
- if (pop->email_widget) {
- if (pop->email && *pop->email) {
- gtk_label_set_text (GTK_LABEL (pop->email_widget), pop->email);
- gtk_widget_show (pop->email_widget);
- } else {
- gtk_widget_hide (pop->email_widget);
- }
- }
-
- eab_popup_control_query (pop);
-}
-
-static gint
-refresh_timeout_cb (gpointer ptr)
-{
- EABPopupControl *pop = EAB_POPUP_CONTROL (ptr);
- eab_popup_control_refresh_names (pop);
- pop->scheduled_refresh = 0;
- return 0;
-}
-
-static void
-eab_popup_control_schedule_refresh (EABPopupControl *pop)
-{
- if (pop->scheduled_refresh == 0)
- pop->scheduled_refresh = g_timeout_add (20, refresh_timeout_cb, pop);
-}
-
-/* If we are handed something of the form "Foo <bar@bar.com>",
- do the right thing. */
-static gboolean
-eab_popup_control_set_free_form (EABPopupControl *pop, const gchar *txt)
-{
- gchar *lt, *gt = NULL;
-
- g_return_val_if_fail (pop && EAB_IS_POPUP_CONTROL (pop), FALSE);
-
- if (txt == NULL)
- return FALSE;
-
- lt = strchr (txt, '<');
- if (lt)
- gt = strchr (txt, '>');
-
- if (lt && gt && lt+1 < gt) {
- gchar *name = g_strndup (txt, lt-txt);
- gchar *email = g_strndup (lt+1, gt-lt-1);
- eab_popup_control_set_name (pop, name);
- eab_popup_control_set_email (pop, email);
- g_free(name);
- g_free(email);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-eab_popup_control_set_name (EABPopupControl *pop, const gchar *name)
-{
- g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
-
- /* We only allow the name to be set once. */
- if (pop->name)
- return;
-
- if (!eab_popup_control_set_free_form (pop, name)) {
- pop->name = g_strdup (name);
- if (pop->name)
- g_strstrip (pop->name);
- }
-
- eab_popup_control_schedule_refresh (pop);
-}
-
-static void
-eab_popup_control_set_email (EABPopupControl *pop, const gchar *email)
-{
- g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
-
- /* We only allow the e-mail to be set once. */
- if (pop->email)
- return;
-
- if (!eab_popup_control_set_free_form (pop, email)) {
- pop->email = g_strdup (email);
- if (pop->email)
- g_strstrip (pop->email);
- }
-
- eab_popup_control_schedule_refresh (pop);
-}
-
-static void
-eab_popup_control_set_vcard (EABPopupControl *pop, const gchar *vcard)
-{
- g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
-
- /* We only allow the vcard to be set once. */
- if (pop->vcard)
- return;
-
- g_free (pop->name);
- g_free (pop->email);
-
- pop->name = NULL;
- pop->email = NULL;
-
- pop->vcard = g_strdup (vcard);
-
- eab_popup_control_schedule_refresh (pop);
-}
-
-void
-eab_popup_control_construct (EABPopupControl *pop)
-{
- GtkWidget *vbox, *name_holder;
- GdkColor color = { 0x0, 0xffff, 0xffff, 0xffff };
-
- g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
-
- pop->main_vbox = gtk_vbox_new (FALSE, 0);
-
- /* Build Generic View */
-
- name_holder = gtk_event_box_new ();
- vbox = gtk_vbox_new (FALSE, 2);
- pop->name_widget = gtk_label_new ("");
- pop->email_widget = gtk_label_new ("");
-
- gtk_box_pack_start (GTK_BOX (vbox), pop->name_widget, TRUE, TRUE, 2);
- gtk_box_pack_start (GTK_BOX (vbox), pop->email_widget, TRUE, TRUE, 2);
- gtk_container_add (GTK_CONTAINER (name_holder), GTK_WIDGET (vbox));
-
- if (gdk_colormap_alloc_color (gtk_widget_get_colormap (GTK_WIDGET (name_holder)), &color, FALSE, TRUE)) {
- GtkStyle *style = gtk_style_copy (gtk_widget_get_style (GTK_WIDGET (name_holder)));
- style->bg[0] = color;
- gtk_widget_set_style (GTK_WIDGET (name_holder), style);
- g_object_unref (style);
- }
-
- pop->generic_view = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (pop->generic_view), name_holder);
- gtk_box_pack_start (GTK_BOX (pop->main_vbox), pop->generic_view, TRUE, TRUE, 0);
- gtk_widget_show_all (pop->generic_view);
-
- pop->query_msg = gtk_label_new (_("Querying Address Book..."));
- gtk_box_pack_start (GTK_BOX (pop->main_vbox), pop->query_msg, TRUE, TRUE, 0);
- gtk_widget_show (pop->query_msg);
-
- /* Build ContactDisplay */
- pop->contact_display = eab_contact_display_new ();
- gtk_box_pack_start (GTK_BOX (pop->main_vbox), pop->contact_display, TRUE, TRUE, 0);
-
- /* Final assembly */
-
- gtk_container_add (GTK_CONTAINER (pop), pop->main_vbox);
- gtk_widget_show (pop->main_vbox);
-
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
- gtk_container_set_border_width (GTK_CONTAINER (pop), 2);
-}
-
-static GtkWidget *
-eab_popup_new (void)
-{
- EABPopupControl *pop = g_object_new (EAB_TYPE_POPUP_CONTROL, NULL);
- eab_popup_control_construct (pop);
- return GTK_WIDGET (pop);
-}
-
-static void
-emit_event (EABPopupControl *pop, const gchar *event)
-{
- if (pop->es) {
- BonoboArg *arg;
-
- arg = bonobo_arg_new (BONOBO_ARG_BOOLEAN);
- BONOBO_ARG_SET_BOOLEAN (arg, TRUE);
- bonobo_event_source_notify_listeners_full (pop->es,
- "GNOME/Evolution/Addressbook/AddressPopup",
- "Event",
- event,
- arg, NULL);
- bonobo_arg_release (arg);
- }
-}
-
-static void
-eab_popup_control_no_matches (EABPopupControl *pop)
-{
- if (pop->vcard && *pop->vcard)
- e_contact_quick_add_vcard (pop->vcard, NULL, NULL);
- else if (pop->email && *pop->email) {
- if (pop->name && *pop->name)
- e_contact_quick_add (pop->name, pop->email, NULL, NULL);
- else
- e_contact_quick_add_free_form (pop->email, NULL, NULL);
-
- }
- eab_popup_control_cleanup (pop);
- emit_event (pop, "Destroy");
-}
-
-static void
-eab_popup_control_query (EABPopupControl *pop)
-{
- g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
-
- g_object_ref (pop);
-
- eab_popup_control_no_matches (pop);
-
- g_object_unref (pop);
-
-}
-
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-
-enum {
- PROPERTY_NAME,
- PROPERTY_EMAIL,
- PROPERTY_TRANSITORY,
- PROPERTY_VCARD
-};
-
-static void
-set_prop (BonoboPropertyBag *bag, const BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
-{
- EABPopupControl *pop = EAB_POPUP_CONTROL (user_data);
-
- switch (arg_id) {
-
- case PROPERTY_NAME:
- eab_popup_control_set_name (pop, BONOBO_ARG_GET_STRING (arg));
- break;
-
- case PROPERTY_EMAIL:
- eab_popup_control_set_email (pop, BONOBO_ARG_GET_STRING (arg));
- break;
-
- case PROPERTY_VCARD:
- eab_popup_control_set_vcard (pop, BONOBO_ARG_GET_STRING (arg));
- break;
-
- default:
- g_return_if_reached ();
- }
-}
-
-static void
-get_prop (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
-{
- EABPopupControl *pop = EAB_POPUP_CONTROL (user_data);
-
- switch (arg_id) {
-
- case PROPERTY_NAME:
- BONOBO_ARG_SET_STRING (arg, pop->name);
- break;
-
- case PROPERTY_EMAIL:
- BONOBO_ARG_SET_STRING (arg, pop->email);
- break;
-
- case PROPERTY_TRANSITORY:
- BONOBO_ARG_SET_BOOLEAN (arg, pop->transitory);
- break;
-
- case PROPERTY_VCARD:
- BONOBO_ARG_SET_STRING (arg, pop->vcard);
- break;
-
- default:
- g_return_if_reached ();
- }
-}
-
-BonoboControl *
-eab_popup_control_new (void)
-{
- BonoboControl *control;
- BonoboPropertyBag *bag;
- EABPopupControl *addy;
- GtkWidget *w;
-
- w = eab_popup_new ();
- addy = EAB_POPUP_CONTROL (w);
-
- control = bonobo_control_new (w);
- gtk_widget_show (w);
-
- bag = bonobo_property_bag_new (get_prop, set_prop, w);
- bonobo_property_bag_add (bag, "name", PROPERTY_NAME,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_WRITEABLE | BONOBO_PROPERTY_READABLE);
-
- bonobo_property_bag_add (bag, "email", PROPERTY_EMAIL,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_WRITEABLE | BONOBO_PROPERTY_READABLE);
-
- bonobo_property_bag_add (bag, "transitory", PROPERTY_TRANSITORY,
- BONOBO_ARG_BOOLEAN, NULL, NULL,
- BONOBO_PROPERTY_READABLE);
-
- bonobo_property_bag_add (bag, "vcard", PROPERTY_VCARD,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_WRITEABLE | BONOBO_PROPERTY_READABLE);
-
- bonobo_control_set_properties (control, bonobo_object_corba_objref (BONOBO_OBJECT (bag)), NULL);
- bonobo_object_unref (BONOBO_OBJECT (bag));
-
- addy->es = bonobo_event_source_new ();
- bonobo_object_add_interface (BONOBO_OBJECT (control),
- BONOBO_OBJECT (addy->es));
-
- return control;
-}
diff --git a/addressbook/gui/widgets/eab-popup-control.h b/addressbook/gui/widgets/eab-popup-control.h
deleted file mode 100644
index 9eeedc8e00..0000000000
--- a/addressbook/gui/widgets/eab-popup-control.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jon Trowbridge <trow@ximian.com>
- * Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EAB_POPUP_CONTROL_H__
-#define __EAB_POPUP_CONTROL_H__
-
-#include <bonobo/bonobo-event-source.h>
-#include <libebook/e-book.h>
-#include <libebook/e-contact.h>
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define EAB_TYPE_POPUP_CONTROL (eab_popup_control_get_type ())
-#define EAB_POPUP_CONTROL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EAB_TYPE_POPUP_CONTROL, EABPopupControl))
-#define EAB_POPUP_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EAB_TYPE_POPUP_CONTROL, EABPopupControlClass))
-#define EAB_IS_POPUP_CONTROL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EAB_TYPE_POPUP_CONTROL))
-#define EAB_IS_POPUP_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EAB_TYPE_POPUP_CONTROL))
-
-typedef struct _EABPopupControl EABPopupControl;
-typedef struct _EABPopupControlClass EABPopupControlClass;
-
-struct _EABPopupControl {
- GtkEventBox parent;
-
- gchar *name;
- gchar *email;
- gchar *vcard;
-
- GtkWidget *name_widget;
- GtkWidget *email_widget;
- GtkWidget *query_msg;
-
- GtkWidget *main_vbox;
- GtkWidget *generic_view;
- GtkWidget *contact_display;
-
- gboolean transitory;
-
- guint scheduled_refresh;
- EBook *book;
- guint query_tag;
- gboolean multiple_matches;
- EContact *contact;
-
- BonoboEventSource *es;
-};
-
-struct _EABPopupControlClass {
- GtkEventBoxClass parent_class;
-};
-
-GType eab_popup_control_get_type (void);
-
-void eab_popup_control_construct (EABPopupControl *);
-
-BonoboControl *eab_popup_control_new (void);
-
-G_END_DECLS
-
-#endif /* __EAB_POPUP_CONTROL_H__ */
-
diff --git a/addressbook/gui/widgets/eab-popup.c b/addressbook/gui/widgets/eab-popup.c
deleted file mode 100644
index 30ab08f837..0000000000
--- a/addressbook/gui/widgets/eab-popup.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include "eab-popup.h"
-#include <libedataserverui/e-source-selector.h>
-#include <libebook/e-contact.h>
-
-static GObjectClass *eabp_parent;
-
-static void
-eabp_init(GObject *o)
-{
- /*EABPopup *eabp = (EABPopup *)o; */
-}
-
-static void
-eabp_finalise(GObject *o)
-{
- ((GObjectClass *)eabp_parent)->finalize(o);
-}
-
-static void
-eabp_target_free(EPopup *ep, EPopupTarget *t)
-{
- switch (t->type) {
- case EAB_POPUP_TARGET_SELECT: {
- EABPopupTargetSelect *s = (EABPopupTargetSelect *)t;
- gint i;
-
- for (i=0;i<s->cards->len;i++)
- g_object_unref(s->cards->pdata[i]);
- g_ptr_array_free(s->cards, TRUE);
- g_object_unref(s->book);
-
- break; }
- case EAB_POPUP_TARGET_URI: {
- EABPopupTargetURI *s = (EABPopupTargetURI *)t;
-
- g_free(s->uri);
- break; }
- case EAB_POPUP_TARGET_SOURCE: {
- EABPopupTargetSource *s = (EABPopupTargetSource *)t;
-
- g_object_unref(s->selector);
- break; }
-
-#ifdef ADAPTED_TO_E_NAME_SELECTOR
-
- case EAB_POPUP_TARGET_SELECT_NAMES: {
- EABPopupTargetSelectNames *s = (EABPopupTargetSelectNames *)t;
-
- g_object_unref(s->model);
- break; }
-
-#endif
-
- }
-
- ((EPopupClass *)eabp_parent)->target_free(ep, t);
-}
-
-static void
-eabp_class_init(GObjectClass *klass)
-{
- klass->finalize = eabp_finalise;
- ((EPopupClass *)klass)->target_free = eabp_target_free;
-}
-
-GType
-eab_popup_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EABPopupClass),
- NULL, NULL,
- (GClassInitFunc)eabp_class_init,
- NULL, NULL,
- sizeof(EABPopup), 0,
- (GInstanceInitFunc)eabp_init
- };
- eabp_parent = g_type_class_ref(e_popup_get_type());
- type = g_type_register_static(e_popup_get_type(), "EABPopup", &info, 0);
- }
-
- return type;
-}
-
-EABPopup *eab_popup_new(const gchar *menuid)
-{
- EABPopup *eabp = g_object_new(eab_popup_get_type(), NULL);
-
- e_popup_construct(&eabp->popup, menuid);
-
- return eabp;
-}
-
-/**
- * eab_popup_target_new_select:
- * @eabp: Address book popup.
- * @book: Book the cards belong to.
- * @readonly: Book is read-only mode. FIXME: Why can't we just get this off the book?
- * @cards: Cards selected. This will be freed on completion.
- *
- * Create a new selection popup target.
- *
- * Return value:
- **/
-
-EABPopupTargetURI *
-eab_popup_target_new_uri(EABPopup *emp, const gchar *uri)
-{
- EABPopupTargetURI *t = e_popup_target_new(&emp->popup, EAB_POPUP_TARGET_URI, sizeof(*t));
- guint32 mask = ~0;
-
- t->uri = g_strdup(uri);
-
- if (g_ascii_strncasecmp(uri, "http:", 5) == 0
- || g_ascii_strncasecmp(uri, "https:", 6) == 0)
- mask &= ~EAB_POPUP_URI_HTTP;
- if (g_ascii_strncasecmp(uri, "internal-mailto:", 16) == 0)
- mask &= ~EAB_POPUP_URI_MAILTO;
- else
- mask &= ~EAB_POPUP_URI_NOT_MAILTO;
-
- t->target.mask = mask;
-
- return t;
-}
-
-EABPopupTargetSelect *
-eab_popup_target_new_select(EABPopup *eabp, struct _EBook *book, gint readonly, GPtrArray *cards)
-{
- EABPopupTargetSelect *t = e_popup_target_new(&eabp->popup, EAB_POPUP_TARGET_SELECT, sizeof(*t));
- guint32 mask = ~0;
- gint has_email = FALSE, i;
-
- /* FIXME: duplicated in eab-menu.c */
-
- t->book = book;
- g_object_ref(book);
- t->cards = cards;
-
- for (i=0;i<cards->len && !has_email;i++) {
- EContact *contact = cards->pdata[i];
- GList *email;
-
- email = e_contact_get(E_CONTACT(contact), E_CONTACT_EMAIL);
- if (email) {
- has_email = TRUE;
-
- g_list_foreach(email, (GFunc)g_free, NULL);
- g_list_free(email);
- }
- }
-
- if (cards->len == 1) {
- if (e_contact_get (E_CONTACT(cards->pdata[0]), E_CONTACT_IS_LIST))
- mask &= ~EAB_POPUP_LIST;
- else
- mask &= ~EAB_POPUP_CONTACT;
- }
-
- if (has_email)
- mask &= ~EAB_POPUP_SELECT_EMAIL;
-
- if (!readonly)
- mask &= ~EAB_POPUP_SELECT_EDITABLE;
-
- if (cards->len == 1)
- mask &= ~EAB_POPUP_SELECT_ONE;
-
- if (cards->len > 1)
- mask &= ~EAB_POPUP_SELECT_MANY;
-
- if (cards->len >= 1)
- mask &= ~EAB_POPUP_SELECT_ANY;
-
- t->target.mask = mask;
-
- return t;
-}
-
-EABPopupTargetSource *
-eab_popup_target_new_source(EABPopup *eabp, ESourceSelector *selector)
-{
- EABPopupTargetSource *t = e_popup_target_new(&eabp->popup, EAB_POPUP_TARGET_SOURCE, sizeof(*t));
- guint32 mask = ~0;
- const gchar *source_uri;
- ESource *source;
-
- /* TODO: this is duplicated for calendar and tasks too */
-
- t->selector = selector;
- g_object_ref(selector);
-
- /* TODO: perhaps we need to copy this so it doesn't change during the lifecycle */
- source = e_source_selector_peek_primary_selection(selector);
- if (source)
- mask &= ~EAB_POPUP_SOURCE_PRIMARY;
-
- /* FIXME Gross hack, should have a property or something */
- source_uri = e_source_peek_relative_uri(source);
- if (source_uri && !strcmp("system", source_uri))
- mask &= ~EAB_POPUP_SOURCE_SYSTEM;
- else
- mask &= ~EAB_POPUP_SOURCE_USER;
-
- t->target.mask = mask;
-
- return t;
-}
-
-#ifdef ADAPTED_TO_E_NAME_SELECTOR
-
-EABPopupTargetSelectNames *
-eab_popup_target_new_select_names(EABPopup *eabp, struct _ESelectNamesModel *model, gint row)
-{
- EABPopupTargetSelectNames *t = e_popup_target_new(&eabp->popup, EAB_POPUP_TARGET_SELECT_NAMES, sizeof(*t));
-
- /* TODO: this is sort of not very useful, maybe the popup which uses it doesn't
- need to be pluggable */
-
- t->model = model;
- g_object_ref(model);
- t->row = row;
-
- return t;
-}
-
-#endif
-
-/* ********************************************************************** */
-/* Popup menu plugin handler */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.iteab:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="IMAP4 and IMAP4v1 mail store">
- <hook class="org.gnome.mail.popupMenu:1.0"
- handler="HandlePopup">
- <menu id="any" target="select">
- <iteab
- type="iteab|toggle|radio|image|submenu|bar"
- active
- path="foo/bar"
- label="label"
- icon="foo"
- mask="select_one"
- activate="eabp_view_eabacs"/>
- </menu>
- </extension>
-
-*/
-
-static gpointer eabph_parent_class;
-#define eabph ((EABPopupHook *)eph)
-
-static const EPopupHookTargetMask eabph_select_masks[] = {
- { "one", EAB_POPUP_SELECT_ONE },
- { "many", EAB_POPUP_SELECT_MANY },
- { "any", EAB_POPUP_SELECT_ANY },
- { "editable", EAB_POPUP_SELECT_EDITABLE },
- { "email", EAB_POPUP_SELECT_EMAIL },
- { NULL }
-};
-
-static const EPopupHookTargetMask eabph_source_masks[] = {
- { "primary", EAB_POPUP_SOURCE_PRIMARY },
- { "system", EAB_POPUP_SOURCE_SYSTEM },
- { NULL }
-};
-
-static const EPopupHookTargetMask eabph_uri_masks[] = {
- { "http", EAB_POPUP_URI_HTTP },
- { "internal-mailto", EAB_POPUP_URI_MAILTO },
- { "notmailto", EAB_POPUP_URI_NOT_MAILTO },
- { NULL }
-};
-
-static const EPopupHookTargetMask eabph_select_names_masks[] = {
- { NULL }
-};
-
-static const EPopupHookTargetMap eabph_targets[] = {
- { "select", EAB_POPUP_TARGET_SELECT, eabph_select_masks },
- { "uri", EAB_POPUP_TARGET_URI, eabph_uri_masks },
- { "source", EAB_POPUP_TARGET_SOURCE, eabph_source_masks },
- { "select-names", EAB_POPUP_TARGET_SELECT_NAMES, eabph_select_names_masks },
- { NULL }
-};
-
-static void
-eabph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)eabph_parent_class)->finalize(o);
-}
-
-static void
-eabph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = eabph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.addressbook.popup:1.0";
-
- for (i=0;eabph_targets[i].type;i++)
- e_popup_hook_class_add_target_map((EPopupHookClass *)klass, &eabph_targets[i]);
-
- ((EPopupHookClass *)klass)->popup_class = g_type_class_ref(eab_popup_get_type());
-}
-
-GType
-eab_popup_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EABPopupHookClass), NULL, NULL, (GClassInitFunc) eabph_class_init, NULL, NULL,
- sizeof(EABPopupHook), 0, (GInstanceInitFunc) NULL,
- };
-
- eabph_parent_class = g_type_class_ref(e_popup_hook_get_type());
- type = g_type_register_static(e_popup_hook_get_type(), "EABPopupHook", &info, 0);
- }
-
- return type;
-}
diff --git a/addressbook/gui/widgets/eab-popup.h b/addressbook/gui/widgets/eab-popup.h
deleted file mode 100644
index 31d0310829..0000000000
--- a/addressbook/gui/widgets/eab-popup.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EAB_POPUP_H__
-#define __EAB_POPUP_H__
-
-#include <glib-object.h>
-
-#include "e-util/e-popup.h"
-
-G_BEGIN_DECLS
-
-#define ADAPTED_TO_E_NAME_SELECTOR 1
-
-typedef struct _EABPopup EABPopup;
-typedef struct _EABPopupClass EABPopupClass;
-
-/**
- * enum _eab_popup_target_t - A list of mail popup target types.
- *
- * @EAB_POPUP_TARGET_SELECT: A selection of cards
- * @EAB_POPUP_TARGET_SOURCE: A source selection.
- *
- * Defines the value of the targetid for all EABPopup target types.
- **/
-enum _eab_popup_target_t {
- EAB_POPUP_TARGET_SELECT,
- EAB_POPUP_TARGET_URI,
- EAB_POPUP_TARGET_SOURCE,
- EAB_POPUP_TARGET_SELECT_NAMES
-};
-
-/**
- * enum _eab_popup_target_select_t - EABPopupTargetSelect qualifiers.
- *
- * @EAB_POPUP_SELECT_ONE: Only one item is selected.
- * @EAB_POPUP_SELECT_MANY: Two or more items are selected.
- * @EAB_POPUP_SELECT_ANY: One or more items are selected.
- * @EAB_POPUP_SELECT_EDITABLE: Read/writable source.
- * @EAB_POPUP_SELECT_EMAIL: Has an email address.
- **/
-enum _eab_popup_target_select_t {
- EAB_POPUP_SELECT_ONE = 1<<0,
- EAB_POPUP_SELECT_MANY = 1<<1,
- EAB_POPUP_SELECT_ANY = 1<<2,
- EAB_POPUP_SELECT_EDITABLE = 1<<3,
- EAB_POPUP_SELECT_EMAIL = 1<<4,
- EAB_POPUP_LIST = 1<<5,
- EAB_POPUP_CONTACT = 1<<6
-};
-
-enum _eab_popup_target_uri_t {
- EAB_POPUP_URI_HTTP = 1<<0,
- EAB_POPUP_URI_MAILTO = 1<<1,
- EAB_POPUP_URI_NOT_MAILTO = 1<<2
-};
-/**
- * enum _eab_popup_target_source_t - EABPopupTargetSource qualifiers.
- *
- * @EAB_POPUP_SOURCE_PRIMARY: Has a primary selection.
- * @EAB_POPUP_SOURCE_SYSTEM: Is a 'system' folder.
- *
- **/
-enum _eab_popup_target_source_t {
- EAB_POPUP_SOURCE_PRIMARY = 1<<0,
- EAB_POPUP_SOURCE_SYSTEM = 1<<1, /* system folder */
- EAB_POPUP_SOURCE_USER = 1<<2 /* user folder (!system) */
-};
-
-typedef struct _EABPopupTargetSelect EABPopupTargetSelect;
-typedef struct _EABPopupTargetSource EABPopupTargetSource;
-typedef struct _EABPopupTargetSelectNames EABPopupTargetSelectNames;
-typedef struct _EABPopupTargetURI EABPopupTargetURI;
-/**
- * struct _EABPopupTargetSelect - A list of address cards.
- *
- * @target: Superclass.
- * @book: Book the cards belong to.
- * @cards: All selected cards.
- *
- * Used to represent a selection of cards as context for a popup
- * menu.
- **/
-struct _EABPopupTargetSelect {
- EPopupTarget target;
-
- struct _EBook *book;
- GPtrArray *cards;
-};
-
-struct _EABPopupTargetURI {
- EPopupTarget target;
- gchar *uri;
-};
-
-/**
- * struct _EABPopupTargetSource - A source target.
- *
- * @target: Superclass.
- * @selector: Selector holding the source selection.
- *
- * This target is used to represent a source selection.
- **/
-struct _EABPopupTargetSource {
- EPopupTarget target;
-
- struct _ESourceSelector *selector;
-};
-
-#ifdef ADAPTED_TO_E_NAME_SELECTOR
-
-/**
- * struct _EABPopupTargetSelectNames - A select names target.
- *
- * @target: Superclass.
- * @model: Select names model.
- * @row: Row of item selected.
- *
- * This target is used to represent an item selected in an
- * ESelectNames model.
- **/
-struct _EABPopupTargetSelectNames {
- EPopupTarget target;
-
- struct _ESelectNamesModel *model;
- gint row;
-};
-
-#endif
-
-typedef struct _EPopupItem EABPopupItem;
-
-/* The object */
-struct _EABPopup {
- EPopup popup;
-
- struct _EABPopupPrivate *priv;
-};
-
-struct _EABPopupClass {
- EPopupClass popup_class;
-};
-
-GType eab_popup_get_type(void);
-
-EABPopup *eab_popup_new(const gchar *menuid);
-
-EABPopupTargetSelect *eab_popup_target_new_select(EABPopup *eabp, struct _EBook *book, gint readonly, GPtrArray *cards);
-EABPopupTargetURI *eab_popup_target_new_uri(EABPopup *emp, const gchar *uri);
-EABPopupTargetSource *eab_popup_target_new_source(EABPopup *eabp, struct _ESourceSelector *selector);
-
-#ifdef ADAPTED_TO_E_NAME_SELECTOR
-
-EABPopupTargetSelectNames *eab_popup_target_new_select_names(EABPopup *eabp, struct _ESelectNamesModel *model, gint row);
-
-#endif
-
-/* ********************************************************************** */
-
-typedef struct _EABPopupHook EABPopupHook;
-typedef struct _EABPopupHookClass EABPopupHookClass;
-
-struct _EABPopupHook {
- EPopupHook hook;
-};
-
-struct _EABPopupHookClass {
- EPopupHookClass hook_class;
-};
-
-GType eab_popup_hook_get_type(void);
-
-G_END_DECLS
-
-#endif /* __EAB_POPUP_H__ */
diff --git a/addressbook/gui/widgets/gal-view-minicard.c b/addressbook/gui/widgets/gal-view-minicard.c
index 8ff48bede6..c7b2a4a38f 100644
--- a/addressbook/gui/widgets/gal-view-minicard.c
+++ b/addressbook/gui/widgets/gal-view-minicard.c
@@ -26,115 +26,172 @@
#include <config.h>
#include <libxml/parser.h>
-
-#include <libedataserver/e-xml-utils.h>
-
#include <e-util/e-xml-utils.h>
+#include <libedataserver/e-xml-utils.h>
#include "gal-view-minicard.h"
-#define PARENT_TYPE gal_view_get_type ()
-#define d(x)
+static gpointer parent_class;
+
+static void
+view_minicard_column_width_changed (EAddressbookView *address_view,
+ gdouble width)
+{
+ GalView *view;
+ GalViewInstance *view_instance;
+ GalViewMinicard *view_minicard;
+ GtkScrolledWindow *scrolled_window;
+ GtkAdjustment *adjustment;
+ GtkWidget *widget;
+ gdouble value, lower, upper;
+ gdouble page_increment, page_size;
+
+ view_instance = e_addressbook_view_get_view_instance (address_view);
+ view = gal_view_instance_get_current_view (view_instance);
+ view_minicard = GAL_VIEW_MINICARD (view);
+
+ if (view_minicard->column_width != width) {
+ view_minicard->column_width = width;
+ gal_view_changed (view);
+ }
+
+ widget = e_addressbook_view_get_view_widget (address_view);
+ scrolled_window = GTK_SCROLLED_WINDOW (widget);
+ adjustment = gtk_scrolled_window_get_hadjustment (scrolled_window);
+
+ value = gtk_adjustment_get_value (adjustment);
+ lower = gtk_adjustment_get_lower (adjustment);
+ upper = gtk_adjustment_get_upper (adjustment);
+ page_increment = gtk_adjustment_get_page_increment (adjustment);
+ page_size = gtk_adjustment_get_page_size (adjustment);
+
+ adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (
+ value, lower, upper, page_size, page_increment, page_size));
+ gtk_scrolled_window_set_hadjustment (scrolled_window, adjustment);
+}
+
+static void
+view_minicard_finalize (GObject *object)
+{
+ GalViewMinicard *view = GAL_VIEW_MINICARD (object);
+
+ if (view->title != NULL) {
+ gal_view_minicard_detach (view);
+ g_free (view->title);
+ view->title = NULL;
+ }
-static GalViewClass *gal_view_minicard_parent_class;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
static void
-gal_view_minicard_load (GalView *view,
- const gchar *filename)
+view_minicard_load (GalView *view,
+ const gchar *filename)
{
+ GalViewMinicard *view_minicard;
xmlDoc *doc;
+ xmlNode *root;
+
+ view_minicard = GAL_VIEW_MINICARD (view);
doc = e_xml_parse_file (filename);
- if (doc) {
- xmlNode *root = xmlDocGetRootElement(doc);
- GAL_VIEW_MINICARD (view)->column_width = e_xml_get_double_prop_by_name_with_default (root, (const guchar *)"column_width", 150);
- xmlFreeDoc(doc);
- }
+ g_return_if_fail (doc != NULL);
+
+ root = xmlDocGetRootElement (doc);
+ view_minicard->column_width =
+ e_xml_get_double_prop_by_name_with_default (
+ root, (guchar *) "column_width", 150);
+ xmlFreeDoc (doc);
}
static void
-gal_view_minicard_save (GalView *view,
- const gchar *filename)
+view_minicard_save (GalView *view,
+ const gchar *filename)
{
+ GalViewMinicard *view_minicard;
xmlDoc *doc;
xmlNode *root;
- doc = xmlNewDoc((const guchar *)"1.0");
- root = xmlNewNode (NULL, (const guchar *)"EMinicardViewState");
- e_xml_set_double_prop_by_name (root, (const guchar *)"column_width", GAL_VIEW_MINICARD (view)->column_width);
- xmlDocSetRootElement(doc, root);
+ view_minicard = GAL_VIEW_MINICARD (view);
+
+ doc = xmlNewDoc ((guchar *) "1.0");
+ root = xmlNewNode (NULL, (guchar *) "EMinicardViewState");
+ e_xml_set_double_prop_by_name (
+ root, (guchar *) "column_width",
+ view_minicard->column_width);
+ xmlDocSetRootElement (doc, root);
e_xml_save_file (filename, doc);
- xmlFreeDoc(doc);
+ xmlFreeDoc (doc);
}
static const gchar *
-gal_view_minicard_get_title (GalView *view)
+view_minicard_get_title (GalView *view)
{
- return GAL_VIEW_MINICARD(view)->title;
+ GalViewMinicard *view_minicard;
+
+ view_minicard = GAL_VIEW_MINICARD (view);
+
+ return view_minicard->title;
}
static void
-gal_view_minicard_set_title (GalView *view,
- const gchar *title)
+view_minicard_set_title (GalView *view,
+ const gchar *title)
{
- g_free(GAL_VIEW_MINICARD(view)->title);
- GAL_VIEW_MINICARD(view)->title = g_strdup(title);
+ GalViewMinicard *view_minicard;
+
+ view_minicard = GAL_VIEW_MINICARD (view);
+
+ g_free (view_minicard->title);
+ view_minicard->title = g_strdup (title);
}
static const gchar *
-gal_view_minicard_get_type_code (GalView *view)
+view_minicard_get_type_code (GalView *view)
{
return "minicard";
}
static GalView *
-gal_view_minicard_clone (GalView *view)
+view_minicard_clone (GalView *view)
{
- GalViewMinicard *gvm, *new;
+ GalViewMinicard *view_minicard;
+ GalViewMinicard *clone;
- gvm = GAL_VIEW_MINICARD(view);
+ view_minicard = GAL_VIEW_MINICARD(view);
- new = g_object_new (GAL_TYPE_VIEW_MINICARD, NULL);
- new->title = g_strdup (gvm->title);
- new->column_width = gvm->column_width;
+ clone = g_object_new (GAL_TYPE_VIEW_MINICARD, NULL);
+ clone->column_width = view_minicard->column_width;
+ clone->title = g_strdup (view_minicard->title);
- return GAL_VIEW(new);
+ return GAL_VIEW (clone);
}
static void
-gal_view_minicard_dispose (GObject *object)
+gal_view_minicard_class_init (GalViewMinicardClass *class)
{
- GalViewMinicard *view = GAL_VIEW_MINICARD(object);
+ GObjectClass *object_class;
+ GalViewClass *gal_view_class;
- if (view->title != NULL) {
- gal_view_minicard_detach (view);
- g_free(view->title);
- view->title = NULL;
- }
+ parent_class = g_type_class_peek_parent (class);
- if (G_OBJECT_CLASS (gal_view_minicard_parent_class)->dispose)
- (* G_OBJECT_CLASS (gal_view_minicard_parent_class)->dispose) (object);
-}
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = view_minicard_finalize;
+
+ gal_view_class = GAL_VIEW_CLASS (class);
+ gal_view_class->edit = NULL;
+ gal_view_class->load = view_minicard_load;
+ gal_view_class->save = view_minicard_save;
+ gal_view_class->get_title = view_minicard_get_title;
+ gal_view_class->set_title = view_minicard_set_title;
+ gal_view_class->get_type_code = view_minicard_get_type_code;
+ gal_view_class->clone = view_minicard_clone;
-static void
-gal_view_minicard_class_init (GObjectClass *object_class)
-{
- GalViewClass *gal_view_class = GAL_VIEW_CLASS(object_class);
- gal_view_minicard_parent_class = g_type_class_ref (PARENT_TYPE);
-
- gal_view_class->edit = NULL;
- gal_view_class->load = gal_view_minicard_load;
- gal_view_class->save = gal_view_minicard_save;
- gal_view_class->get_title = gal_view_minicard_get_title;
- gal_view_class->set_title = gal_view_minicard_set_title;
- gal_view_class->get_type_code = gal_view_minicard_get_type_code;
- gal_view_class->clone = gal_view_minicard_clone;
-
- object_class->dispose = gal_view_minicard_dispose;
}
static void
-gal_view_minicard_init (GalViewMinicard *gvm)
+gal_view_minicard_init (GalViewMinicard *gvm)
{
gvm->title = NULL;
gvm->column_width = 150.0;
@@ -143,6 +200,32 @@ gal_view_minicard_init (GalViewMinicard *gvm)
gvm->emvw_column_width_changed_id = 0;
}
+GType
+gal_view_minicard_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (GalViewMinicardClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_view_minicard_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalViewMinicard),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gal_view_minicard_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GAL_VIEW_TYPE, "GalViewMinicard", &type_info, 0);
+ }
+
+ return type;
+}
+
/**
* gal_view_minicard_new
* @title: The name of the new view.
@@ -155,7 +238,8 @@ gal_view_minicard_init (GalViewMinicard *gvm)
GalView *
gal_view_minicard_new (const gchar *title)
{
- return gal_view_minicard_construct (g_object_new (GAL_TYPE_VIEW_MINICARD, NULL), title);
+ return gal_view_minicard_construct (
+ g_object_new (GAL_TYPE_VIEW_MINICARD, NULL), title);
}
/**
@@ -163,7 +247,7 @@ gal_view_minicard_new (const gchar *title)
* @view: The view to construct.
* @title: The name of the new view.
*
- * constructs the GalViewMinicard. To be used by subclasses and
+ * Constructs the GalViewMinicard. To be used by subclasses and
* language bindings.
*
* Returns: The GalViewMinicard.
@@ -172,85 +256,49 @@ GalView *
gal_view_minicard_construct (GalViewMinicard *view,
const gchar *title)
{
- view->title = g_strdup(title);
- return GAL_VIEW(view);
-}
-
-GType
-gal_view_minicard_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (GalViewMinicardClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gal_view_minicard_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GalViewMinicard),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gal_view_minicard_init,
- };
+ view->title = g_strdup (title);
- type = g_type_register_static (PARENT_TYPE, "GalViewMinicard", &info, 0);
- }
-
- return type;
+ return GAL_VIEW (view);
}
-static void
-column_width_changed (EMinicardViewWidget *w, double width, EABView *address_view)
+void
+gal_view_minicard_attach (GalViewMinicard *view,
+ EAddressbookView *address_view)
{
- GalViewMinicard *view = GAL_VIEW_MINICARD (gal_view_instance_get_current_view (address_view->view_instance));
- GtkScrolledWindow *scrolled_window;
- GtkAdjustment *adj;
- GtkAdjustment *adj_new;
+ GObject *object;
- d(g_print("%s: Old width = %f, New width = %f\n", G_STRFUNC, view->column_width, width));
- if (view->column_width != width) {
- view->column_width = width;
- gal_view_changed(GAL_VIEW(view));
- }
+ g_return_if_fail (GAL_IS_VIEW_MINICARD (view));
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (address_view));
- scrolled_window = GTK_SCROLLED_WINDOW (address_view->widget);
- adj = gtk_scrolled_window_get_hadjustment (scrolled_window);
- adj_new = GTK_ADJUSTMENT (gtk_adjustment_new (adj->value, adj->lower, adj->upper,
- adj->page_size, adj->page_increment,
- adj->page_size));
- gtk_scrolled_window_set_hadjustment (scrolled_window, adj_new);
-}
+ object = e_addressbook_view_get_view_object (address_view);
+ g_return_if_fail (E_IS_MINICARD_VIEW_WIDGET (object));
-void
-gal_view_minicard_attach (GalViewMinicard *view, EABView *address_view)
-{
- EMinicardViewWidget *emvw = E_MINICARD_VIEW_WIDGET (address_view->object);
gal_view_minicard_detach (view);
+ view->emvw = g_object_ref (object);
- view->emvw = emvw;
-
- g_object_ref (view->emvw);
-
- g_object_set (view->emvw,
- "column_width", view->column_width,
- NULL);
+ g_object_set (view->emvw, "column-width", view->column_width, NULL);
view->emvw_column_width_changed_id =
- g_signal_connect(view->emvw, "column_width_changed",
- G_CALLBACK (column_width_changed), address_view);
+ g_signal_connect_swapped (
+ view->emvw, "column-width-changed",
+ G_CALLBACK (view_minicard_column_width_changed),
+ address_view);
}
void
gal_view_minicard_detach (GalViewMinicard *view)
{
+ g_return_if_fail (GAL_IS_VIEW_MINICARD (view));
+
if (view->emvw == NULL)
return;
- if (view->emvw_column_width_changed_id) {
- g_signal_handler_disconnect (view->emvw,
- view->emvw_column_width_changed_id);
+
+ if (view->emvw_column_width_changed_id > 0) {
+ g_signal_handler_disconnect (
+ view->emvw, view->emvw_column_width_changed_id);
view->emvw_column_width_changed_id = 0;
}
+
g_object_unref (view->emvw);
view->emvw = NULL;
}
diff --git a/addressbook/gui/widgets/gal-view-minicard.h b/addressbook/gui/widgets/gal-view-minicard.h
index f5681fcca5..c506fb1a2b 100644
--- a/addressbook/gui/widgets/gal-view-minicard.h
+++ b/addressbook/gui/widgets/gal-view-minicard.h
@@ -22,40 +22,59 @@
*
*/
-#ifndef _GAL_VIEW_MINICARD_H_
-#define _GAL_VIEW_MINICARD_H_
+#ifndef GAL_VIEW_MINICARD_H
+#define GAL_VIEW_MINICARD_H
#include <widgets/menus/gal-view.h>
#include <e-minicard-view-widget.h>
#include "e-addressbook-view.h"
-#define GAL_TYPE_VIEW_MINICARD (gal_view_minicard_get_type ())
-#define GAL_VIEW_MINICARD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GAL_TYPE_VIEW_MINICARD, GalViewMinicard))
-#define GAL_VIEW_MINICARD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass))
-#define GAL_IS_VIEW_MINICARD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GAL_TYPE_VIEW_MINICARD))
-#define GAL_IS_VIEW_MINICARD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GAL_TYPE_VIEW_MINICARD))
+/* Standard GObject macros */
+#define GAL_TYPE_VIEW_MINICARD \
+ (gal_view_minicard_get_type ())
+#define GAL_VIEW_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), GAL_TYPE_VIEW_MINICARD, GalViewMinicard))
+#define GAL_VIEW_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass))
+#define GAL_IS_VIEW_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), GAL_TYPE_VIEW_MINICARD))
+#define GAL_IS_VIEW_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), GAL_TYPE_VIEW_MINICARD))
+#define GAL_VIEW_MINICARD_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass))
-typedef struct {
- GalView base;
+G_BEGIN_DECLS
+
+typedef struct _GalViewMinicard GalViewMinicard;
+typedef struct _GalViewMinicardClass GalViewMinicardClass;
+
+struct _GalViewMinicard {
+ GalView parent;
gchar *title;
double column_width;
EMinicardViewWidget *emvw;
guint emvw_column_width_changed_id;
-} GalViewMinicard;
+};
-typedef struct {
+struct _GalViewMinicardClass {
GalViewClass parent_class;
-} GalViewMinicardClass;
-
-/* Standard functions */
-GType gal_view_minicard_get_type (void);
-GalView *gal_view_minicard_new (const gchar *title);
-GalView *gal_view_minicard_construct (GalViewMinicard *view,
- const gchar *title);
-void gal_view_minicard_attach (GalViewMinicard *view,
- EABView *address_view);
-void gal_view_minicard_detach (GalViewMinicard *view);
-
-#endif /* _GAL_VIEW_MINICARD_H_ */
+};
+
+GType gal_view_minicard_get_type (void);
+GalView * gal_view_minicard_new (const gchar *title);
+GalView * gal_view_minicard_construct (GalViewMinicard *view,
+ const gchar *title);
+void gal_view_minicard_attach (GalViewMinicard *view,
+ EAddressbookView *address_view);
+void gal_view_minicard_detach (GalViewMinicard *view);
+
+G_END_DECLS
+
+#endif /* GAL_VIEW_MINICARD_H */
diff --git a/addressbook/util/Makefile.am b/addressbook/util/Makefile.am
index 42f160ea5f..50d5d430e2 100644
--- a/addressbook/util/Makefile.am
+++ b/addressbook/util/Makefile.am
@@ -12,6 +12,8 @@ AM_CPPFLAGS = \
privsolib_LTLIBRARIES = libeabutil.la
libeabutil_la_SOURCES = \
+ addressbook.c \
+ addressbook.h \
eab-book-util.c \
eab-book-util.h
diff --git a/addressbook/gui/component/addressbook.c b/addressbook/util/addressbook.c
index 7caa545059..7caa545059 100644
--- a/addressbook/gui/component/addressbook.c
+++ b/addressbook/util/addressbook.c
diff --git a/addressbook/gui/component/addressbook.h b/addressbook/util/addressbook.h
index 3997c9c176..7bc92ee344 100644
--- a/addressbook/gui/component/addressbook.h
+++ b/addressbook/util/addressbook.h
@@ -22,9 +22,6 @@
#ifndef __ADDRESSBOOK_H__
#define __ADDRESSBOOK_H__
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-moniker-util.h>
#include <libebook/e-book.h>
guint addressbook_load (EBook *book, EBookCallback cb, gpointer closure);
diff --git a/addressbook/util/eab-book-util.h b/addressbook/util/eab-book-util.h
index 8c43b64bcd..9f8a79eae1 100644
--- a/addressbook/util/eab-book-util.h
+++ b/addressbook/util/eab-book-util.h
@@ -24,8 +24,6 @@
#ifndef __EAB_UTIL_H__
#define __EAB_UTIL_H__
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-moniker-util.h>
#include <libebook/e-book.h>
G_BEGIN_DECLS
diff --git a/calendar/conduits/calendar/calendar-conduit.c b/calendar/conduits/calendar/calendar-conduit.c
index 0052c13f30..cd91981799 100644
--- a/calendar/conduits/calendar/calendar-conduit.c
+++ b/calendar/conduits/calendar/calendar-conduit.c
@@ -27,6 +27,13 @@
#define G_LOG_DOMAIN "ecalconduit"
+/* Work around deprecated API usage in GnomePilot. */
+#ifdef GTK_DISABLE_DEPRECATED
+#include <glib-object.h>
+#define GTK_CHECK_CAST G_TYPE_CHECK_INSTANCE_CAST
+typedef GType GtkType;
+#endif
+
#include <glib/gi18n.h>
#include <libecal/e-cal-types.h>
#include <libecal/e-cal.h>
diff --git a/calendar/conduits/memo/memo-conduit.c b/calendar/conduits/memo/memo-conduit.c
index ac28e0465c..a7bc8952a1 100644
--- a/calendar/conduits/memo/memo-conduit.c
+++ b/calendar/conduits/memo/memo-conduit.c
@@ -29,6 +29,13 @@
#define G_LOG_DOMAIN "ememoconduit"
+/* Work around deprecated API usage in GnomePilot. */
+#ifdef GTK_DISABLE_DEPRECATED
+#include <glib-object.h>
+#define GTK_CHECK_CAST G_TYPE_CHECK_INSTANCE_CAST
+typedef GType GtkType;
+#endif
+
#include <glib/gi18n.h>
#include <libecal/e-cal-types.h>
#include <libecal/e-cal.h>
diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c
index 89e012bfd7..6868b4681a 100644
--- a/calendar/conduits/todo/todo-conduit.c
+++ b/calendar/conduits/todo/todo-conduit.c
@@ -29,6 +29,13 @@
#define G_LOG_DOMAIN "etodoconduit"
+/* Work around deprecated API usage in GnomePilot. */
+#ifdef GTK_DISABLE_DEPRECATED
+#include <glib-object.h>
+#define GTK_CHECK_CAST G_TYPE_CHECK_INSTANCE_CAST
+typedef GType GtkType;
+#endif
+
#include <glib/gi18n.h>
#include <libecal/e-cal-types.h>
#include <libecal/e-cal.h>
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 853cfce649..ede213e1ff 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -1,53 +1,27 @@
if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libevolution-mail-shared.la
+WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libevolution-mail.la
endif
-## CORBA stuff
-
-IDLS = \
- $(top_srcdir)/calendar/idl/evolution-calendar.idl
-
-CALENDAR_IDL_GENERATED_H = \
- evolution-calendar.h
-CALENDAR_IDL_GENERATED_C = \
- evolution-calendar-common.c \
- evolution-calendar-skels.c \
- evolution-calendar-stubs.c
-CALENDAR_IDL_GENERATED = $(CALENDAR_IDL_GENERATED_C) $(CALENDAR_IDL_GENERATED_H)
-
-$(CALENDAR_IDL_GENERATED_H): $(IDLS)
- $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) \
- $(top_srcdir)/calendar/idl/evolution-calendar.idl
-$(CALENDAR_IDL_GENERATED_C): $(CALENDAR_IDL_GENERATED_H)
-
-IDL_GENERATED = $(CALENDAR_IDL_GENERATED)
-
SUBDIRS = alarm-notify dialogs
-privsolib_LTLIBRARIES = libevolution-cal-shared.la
-component_LTLIBRARIES = libevolution-calendar.la
+privsolib_LTLIBRARIES = libevolution-calendar.la
ecalendarincludedir = $(privincludedir)/calendar/gui
ecalendarinclude_HEADERS = \
cal-editor-utils.h \
- cal-search-bar.h \
calendar-config.h \
calendar-config-keys.h \
comp-util.h \
e-alarm-list.h \
- e-attachment-handler-calendar.h \
e-cal-config.h \
e-cal-event.h \
e-cal-model-calendar.h \
e-cal-model.h \
- e-cal-popup.h \
e-calendar-view.h \
e-cell-date-edit-text.h \
e-comp-editor-registry.h \
- e-date-edit-config.h \
e-date-time-list.h \
- e-day-view-config.h \
e-day-view-layout.h \
e-day-view-main-item.h \
e-day-view-time-item.h \
@@ -60,10 +34,8 @@ ecalendarinclude_HEADERS = \
e-meeting-time-sel-item.h \
e-meeting-types.h \
e-meeting-utils.h \
- e-mini-calendar-config.h \
e-select-names-editable.h \
e-select-names-renderer.h \
- e-week-view-config.h \
e-week-view-event-item.h \
e-week-view-layout.h \
e-week-view-main-item.h \
@@ -89,7 +61,6 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/calendar \
-I$(top_srcdir)/widgets \
-I$(top_srcdir)/widgets/misc \
- -I$(top_srcdir)/a11y/calendar \
-DSEARCH_RULE_DIR=\"$(ruledir)\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
@@ -110,20 +81,22 @@ etspec_DATA = \
e-cal-list-view.etspec \
e-memo-table.etspec
-libevolution_cal_shared_la_SOURCES = \
+libevolution_calendar_la_SOURCES = \
cal-editor-utils.c \
cal-editor-utils.h \
- cal-search-bar.c \
- cal-search-bar.h \
calendar-config.c \
calendar-config.h \
calendar-config-keys.h \
+ calendar-view.c \
+ calendar-view.h \
+ calendar-view-factory.c \
+ calendar-view-factory.h \
comp-util.c \
comp-util.h \
e-alarm-list.c \
e-alarm-list.h \
- e-attachment-handler-calendar.c \
- e-attachment-handler-calendar.h \
+ e-cal-component-preview.c \
+ e-cal-component-preview.h \
e-cal-config.c \
e-cal-config.h \
e-cal-event.c \
@@ -132,20 +105,24 @@ libevolution_cal_shared_la_SOURCES = \
e-cal-model-calendar.h \
e-cal-model.c \
e-cal-model.h \
- e-cal-popup.h \
- e-cal-popup.c \
+ e-cal-list-view.c \
+ e-cal-list-view.h \
+ e-cal-model-memos.c \
+ e-cal-model-memos.h \
+ e-cal-model-tasks.c \
+ e-cal-model-tasks.h \
+ e-calendar-selector.c \
+ e-calendar-selector.h \
+ e-calendar-table.c \
+ e-calendar-table.h \
e-calendar-view.c \
e-calendar-view.h \
e-cell-date-edit-text.h \
e-cell-date-edit-text.c \
e-comp-editor-registry.c \
e-comp-editor-registry.h \
- e-date-edit-config.c \
- e-date-edit-config.h \
- e-date-time-list.c \
- e-date-time-list.h \
- e-day-view-config.c \
- e-day-view-config.h \
+ e-date-time-list.c \
+ e-date-time-list.h \
e-day-view-layout.c \
e-day-view-layout.h \
e-day-view-main-item.c \
@@ -156,6 +133,8 @@ libevolution_cal_shared_la_SOURCES = \
e-day-view-top-item.h \
e-day-view.c \
e-day-view.h \
+ e-itip-control.c \
+ e-itip-control.h \
e-meeting-attendee.c \
e-meeting-attendee.h \
e-meeting-list-view.c \
@@ -169,14 +148,18 @@ libevolution_cal_shared_la_SOURCES = \
e-meeting-types.h \
e-meeting-utils.c \
e-meeting-utils.h \
- e-mini-calendar-config.c \
- e-mini-calendar-config.h \
+ e-memo-list-selector.c \
+ e-memo-list-selector.h \
+ e-memo-table.c \
+ e-memo-table.h \
+ e-month-view.c \
+ e-month-view.h \
e-select-names-editable.c \
e-select-names-editable.h \
e-select-names-renderer.c \
e-select-names-renderer.h \
- e-week-view-config.c \
- e-week-view-config.h \
+ e-task-list-selector.c \
+ e-task-list-selector.h \
e-week-view-event-item.c \
e-week-view-event-item.h \
e-week-view-layout.c \
@@ -191,140 +174,63 @@ libevolution_cal_shared_la_SOURCES = \
e-timezone-entry.h \
goto.c \
goto.h \
+ gnome-cal.c \
+ gnome-cal.h \
itip-utils.c \
itip-utils.h \
misc.c \
misc.h \
+ print.c \
+ print.h \
tag-calendar.c \
tag-calendar.h \
weekday-picker.c \
- weekday-picker.h
-
-libevolution_calendar_la_SOURCES = \
- $(IDL_GENERATED) \
- calendar-commands.c \
- calendar-commands.h \
- calendar-component.c \
- calendar-component.h \
- calendar-view.c \
- calendar-view.h \
- calendar-view-factory.c \
- calendar-view-factory.h \
- comp-editor-factory.c \
- comp-editor-factory.h \
- control-factory.c \
- control-factory.h \
- e-cal-component-preview.c \
- e-cal-component-preview.h \
- e-cal-component-memo-preview.c \
- e-cal-component-memo-preview.h \
- e-cal-menu.c \
- e-cal-menu.h \
- e-cal-model-tasks.c \
- e-cal-model-tasks.h \
- e-cal-list-view.c \
- e-cal-list-view.h \
- e-cal-list-view-config.c \
- e-cal-list-view-config.h \
- e-cal-model-memos.c \
- e-cal-model-memos.h \
- e-calendar-table.c \
- e-calendar-table.h \
- e-calendar-table-config.c \
- e-calendar-table-config.h \
- e-cell-date-edit-config.c \
- e-cell-date-edit-config.h \
- e-itip-control.h \
- e-itip-control.c \
- e-memo-table.c \
- e-memo-table.h \
- e-memo-table-config.c \
- e-memo-table-config.h \
- e-memos.c \
- e-memos.h \
- e-tasks.c \
- e-tasks.h \
- gnome-cal.c \
- gnome-cal.h \
- itip-bonobo-control.c \
- itip-bonobo-control.h \
- main.c \
- memos-component.c \
- memos-component.h \
- memos-control.c \
- memos-control.h \
- migration.c \
- migration.h \
- print.c \
- print.h \
- tasks-component.c \
- tasks-component.h \
- tasks-control.c \
- tasks-control.h
-
-libevolution_cal_shared_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(top_builddir)/widgets/menus/libmenus.la \
- $(top_builddir)/shell/libeshell.la \
- $(top_builddir)/calendar/common/libevolution-calendarprivate.la \
- $(top_builddir)/calendar/gui/dialogs/libcal-dialogs.la \
- $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \
- $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \
- $(top_builddir)/widgets/misc/libefilterbar.la \
- $(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/filter/libfilter.la \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \
- $(LIBSOUP_LIBS) \
- $(CAMEL_LIBS) \
- $(EVOLUTION_CALENDAR_LIBS)
-
-libevolution_cal_shared_la_LDFLAGS = $(NO_UNDEFINED)
-
+ weekday-picker.h \
+ ea-calendar.c \
+ ea-calendar.h \
+ ea-calendar-helpers.c \
+ ea-calendar-helpers.h \
+ ea-cal-view.c \
+ ea-cal-view.h \
+ ea-cal-view-event.c \
+ ea-cal-view-event.h \
+ ea-day-view.c \
+ ea-day-view.h \
+ ea-day-view-main-item.c \
+ ea-day-view-main-item.h \
+ ea-day-view-cell.c \
+ ea-day-view-cell.h \
+ ea-week-view.c \
+ ea-week-view.h \
+ ea-week-view-main-item.c \
+ ea-week-view-main-item.h \
+ ea-week-view-cell.c \
+ ea-week-view-cell.h \
+ ea-jump-button.c \
+ ea-jump-button.h \
+ ea-gnome-calendar.c \
+ ea-gnome-calendar.h
libevolution_calendar_la_LIBADD = \
- $(top_builddir)/calendar/gui/libevolution-cal-shared.la \
- $(WIN32_BOOTSTRAP_LIBS) \
+ $(top_builddir)/composer/libcomposer.la \
+ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
$(top_builddir)/widgets/menus/libmenus.la \
$(top_builddir)/shell/libeshell.la \
$(top_builddir)/calendar/common/libevolution-calendarprivate.la \
$(top_builddir)/calendar/gui/dialogs/libcal-dialogs.la \
$(top_builddir)/calendar/importers/libevolution-calendar-importers.la \
$(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \
- $(top_builddir)/widgets/misc/libefilterbar.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/widgets/table/libetable.la \
$(top_builddir)/filter/libfilter.la \
$(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \
$(LIBSOUP_LIBS) \
$(CAMEL_LIBS) \
$(EVOLUTION_CALENDAR_LIBS)
-libevolution_calendar_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED)
-
-libevolution_calendar_la_DEPENDENCIES = libevolution-cal-shared.la
-
-# --- BIG NASTY AUTOMAKE HACK ---
-#
-# Automake apparently sorts Makefile.am rules alphabetically. And
-# since component_LTLIBRARIES < privsolib_LTLIBRARIES, it tries to
-# install libevolution-calendar.la before libevolution-cal-shared.la,
-# which fails when libtool tries to relink libevolution-calendar.la
-# against the not-yet-installed libevolution-cal-shared.la.
-install-data-am: \
- install-privsolibLTLIBRARIES \
- install-componentLTLIBRARIES \
- install-data-local \
- install-etspecDATA \
- install-gladeDATA \
- install-schemaDATA \
- install-ruleDATA \
- install-ecalendarincludeHEADERS \
- install-serverDATA
+libevolution_calendar_la_LDFLAGS = $(NO_UNDEFINED)
-server_in_files = GNOME_Evolution_Calendar.server.in.in
-server_DATA = $(server_in_files:.server.in.in=.server)
-@EVO_SERVER_RULE@
@INTLTOOL_SERVER_RULE@
# GConf schemas
@@ -339,10 +245,8 @@ EXTRA_DIST = \
$(glade_DATA) \
$(schema_in_files) \
$(etspec_DATA) \
- $(server_in_files) \
$(search_files)
-BUILT_SOURCES = $(IDL_GENERATED) $(server_DATA)
CLEANFILES = $(BUILT_SOURCES)
DISTCLEANFILES = $(schema_DATA)
diff --git a/calendar/gui/alarm-notify/Makefile.am b/calendar/gui/alarm-notify/Makefile.am
index 680c5e95e5..ea1c36e0d9 100644
--- a/calendar/gui/alarm-notify/Makefile.am
+++ b/calendar/gui/alarm-notify/Makefile.am
@@ -25,7 +25,8 @@ AM_CPPFLAGS = \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
-DEVOLUTION_LIBEXECDIR=\""$(privlibexecdir)"\" \
- $(EVOLUTION_CALENDAR_CFLAGS)
+ $(EVOLUTION_CALENDAR_CFLAGS) \
+ $(CANBERRA_CFLAGS)
glade_DATA = \
alarm-notify.glade
@@ -51,7 +52,8 @@ evolution_alarm_notify_LDADD = \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
$(top_builddir)/calendar/common/libevolution-calendarprivate.la \
$(CAMEL_LIBS) \
- $(EVOLUTION_CALENDAR_LIBS)
+ $(EVOLUTION_CALENDAR_LIBS) \
+ $(CANBERRA_LIBS)
if OS_WIN32
evolution_alarm_notify_LDFLAGS = -mwindows
diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c
index 99e9a4f8e5..ef6e77d386 100644
--- a/calendar/gui/alarm-notify/alarm-queue.c
+++ b/calendar/gui/alarm-notify/alarm-queue.c
@@ -34,7 +34,7 @@
#include <bonobo/bonobo-main.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include <libgnome/gnome-sound.h>
+#include <canberra-gtk.h>
#include <libecal/e-cal-time-util.h>
#include <libecal/e-cal-component.h>
@@ -50,7 +50,6 @@
#include "alarm-notify.h"
#include "config-data.h"
#include "util.h"
-#include "e-util/e-popup.h"
#include "e-util/e-error.h"
#define d(x)
@@ -896,6 +895,7 @@ create_snooze (CompQueuedAlarms *cqa, gpointer alarm_id, gint snooze_mins)
static void
edit_component (ECal *client, ECalComponent *comp)
{
+#if 0 /* KILL-BONOBO */
const gchar *uid;
const gchar *uri;
ECalSourceType source_type;
@@ -939,6 +939,7 @@ edit_component (ECal *client, ECalComponent *comp)
/* Get rid of the factory */
bonobo_object_release_unref (factory, NULL);
+#endif
}
typedef struct {
@@ -1640,13 +1641,23 @@ audio_notification (time_t trigger, CompQueuedAlarms *cqa,
if (attach && icalattach_get_is_url (attach)) {
const gchar *url;
+ gchar *filename;
+ GError *error = NULL;
url = icalattach_get_url (attach);
+ filename = g_filename_from_uri (url, NULL, &error);
- if (url && *url && g_file_test (url, G_FILE_TEST_EXISTS)) {
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ } else if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
flag = 1;
- gnome_sound_play (url); /* this sucks */
+ ca_context_play (
+ ca_gtk_context_get(), 0,
+ CA_PROP_MEDIA_FILENAME, filename, NULL);
}
+
+ g_free (filename);
}
if (!flag)
diff --git a/calendar/gui/alarm-notify/notify-main.c b/calendar/gui/alarm-notify/notify-main.c
index 887adaa1d5..b3ff0db6a5 100644
--- a/calendar/gui/alarm-notify/notify-main.c
+++ b/calendar/gui/alarm-notify/notify-main.c
@@ -31,7 +31,6 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-init.h>
-#include <libgnome/gnome-sound.h>
#include <libgnomeui/gnome-client.h>
#include <libgnomeui/gnome-ui-init.h>
#include <glade/glade.h>
@@ -48,8 +47,6 @@
#include "config-data.h"
#include <camel/camel-object.h>
-
-
static BonoboGenericFactory *factory;
static AlarmNotify *alarm_notify_service = NULL;
@@ -142,8 +139,6 @@ main (gint argc, gchar **argv)
glade_init ();
- gnome_sound_init ("localhost");
-
e_icon_factory_init ();
init_alarm_service (NULL);
@@ -173,7 +168,6 @@ main (gint argc, gchar **argv)
alarm_done ();
e_passwords_shutdown ();
- gnome_sound_shutdown ();
return 0;
}
diff --git a/calendar/gui/apps_evolution_calendar.schemas.in b/calendar/gui/apps_evolution_calendar.schemas.in
index 210a6fc159..b232c60cce 100644
--- a/calendar/gui/apps_evolution_calendar.schemas.in
+++ b/calendar/gui/apps_evolution_calendar.schemas.in
@@ -279,16 +279,91 @@
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/calendar/display/tag_vpane_position</key>
- <applyto>/apps/evolution/calendar/display/tag_vpane_position</applyto>
+ <key>/schemas/apps/evolution/calendar/display/date_navigator_pane_position</key>
+ <applyto>/apps/evolution/calendar/display/date_navigator_pane_position</applyto>
<owner>evolution-calendar</owner>
- <type>float</type>
- <default>0.5</default>
+ <type>int</type>
+ <default>150</default>
<locale name="C">
<short>Month view vertical pane position </short>
<long>Position of the vertical pane, between the calendar lists and the date navigator calendar.</long>
</locale>
</schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/calendar/display/memo_layout</key>
+ <applyto>/apps/evolution/calendar/display/memo_layout</applyto>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short>Memo layout style</short>
+ <long>
+ The layout style determines where to place the preview pane
+ in relation to the memo list. "0" (Classic View) places the
+ preview pane below the memo list. "1" (Vertical View) places
+ the preview pane next to the memo list.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/calendar/display/show_memo_preview</key>
+ <applyto>/apps/evolution/calendar/display/show_memo_preview</applyto>
+ <owner>evolution-calendar</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short>Show the memo preview pane</short>
+ <long>
+ If "true", show the memo preview pane in the main window.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/calendar/display/memo_hpane_position</key>
+ <applyto>/apps/evolution/calendar/display/memo_hpane_position</applyto>
+ <owner>evolution-calendar</owner>
+ <type>int</type>
+ <default>200</default>
+ <locale name="C">
+ <short>Memo preview pane position (horizontal)</short>
+ <long>
+ Position of the task preview pane when oriented horizontally.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/calendar/display/memo_vpane_position</key>
+ <applyto>/apps/evolution/calendar/display/memo_vpane_position</applyto>
+ <owner>evolution-calendar</owner>
+ <type>int</type>
+ <default>400</default>
+ <locale name="C">
+ <short>Memo preview pane position (vertical)</short>
+ <long>
+ Position of the memo preview pane when oriented vertically.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/calendar/display/task_layout</key>
+ <applyto>/apps/evolution/calendar/display/task_layout</applyto>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short>Task layout style</short>
+ <long>
+ The layout style determines where to place the preview pane
+ in relation to the task list. "0" (Classic View) places the
+ preview pane below the task list. "1" (Vertical View) places
+ the preview pane next to the task list.
+ </long>
+ </locale>
+ </schema>
+
<schema>
<key>/schemas/apps/evolution/calendar/display/show_task_preview</key>
<applyto>/apps/evolution/calendar/display/show_task_preview</applyto>
@@ -296,22 +371,38 @@
<type>bool</type>
<default>true</default>
<locale name="C">
- <short>Show the "Preview" pane</short>
+ <short>Show the task preview pane</short>
<long>
- Show the "Preview" pane.
+ If "true", show the task preview pane in the main window.
</long>
</locale>
</schema>
<schema>
+ <key>/schemas/apps/evolution/calendar/display/task_hpane_position</key>
+ <applyto>/apps/evolution/calendar/display/task_hpane_position</applyto>
+ <owner>evolution-calendar</owner>
+ <type>int</type>
+ <default>200</default>
+ <locale name="C">
+ <short>Task preview pane position (horizontal)</short>
+ <long>
+ Position of the task preview pane when oriented horizontally.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/evolution/calendar/display/task_vpane_position</key>
<applyto>/apps/evolution/calendar/display/task_vpane_position</applyto>
<owner>evolution-calendar</owner>
<type>int</type>
<default>400</default>
<locale name="C">
- <short>Tasks vertical pane position </short>
- <long>Position of the vertical pane, between the task list and the task preview pane, in pixels.</long>
+ <short>Task preview pane position (vertical)</short>
+ <long>
+ Position of the task preview pane when oriented vertically.
+ </long>
</locale>
</schema>
diff --git a/calendar/gui/cal-editor-utils.c b/calendar/gui/cal-editor-utils.c
index ece9abe532..0da7ca2af9 100644
--- a/calendar/gui/cal-editor-utils.c
+++ b/calendar/gui/cal-editor-utils.c
@@ -47,14 +47,19 @@ extern ECompEditorRegistry *comp_editor_registry;
* It blocks until finished and should be called in the main thread.
**/
void
-open_component_editor (ECal *client, ECalComponent *comp, gboolean is_new, GError **error)
+open_component_editor (EShell *shell,
+ ECal *client,
+ ECalComponent *comp,
+ gboolean is_new,
+ GError **error)
{
ECalComponentId *id;
CompEditorFlags flags = 0;
CompEditor *editor = NULL;
- g_return_if_fail (client != NULL);
- g_return_if_fail (comp != NULL);
+ g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (E_IS_CAL (client));
+ g_return_if_fail (E_IS_CAL_COMPONENT (comp));
id = e_cal_component_get_id (comp);
g_return_if_fail (id != NULL);
@@ -63,7 +68,7 @@ open_component_editor (ECal *client, ECalComponent *comp, gboolean is_new, GErro
if (is_new) {
flags |= COMP_EDITOR_NEW_ITEM;
} else {
- editor = e_comp_editor_registry_find (comp_editor_registry, id->uid);
+ editor = comp_editor_find_instance (id->uid);
}
if (!editor) {
@@ -75,7 +80,7 @@ open_component_editor (ECal *client, ECalComponent *comp, gboolean is_new, GErro
if (e_cal_component_has_attendees (comp))
flags |= COMP_EDITOR_MEETING;
- editor = event_editor_new (client, flags);
+ editor = event_editor_new (client, shell, flags);
if (flags & COMP_EDITOR_MEETING)
event_editor_show_meeting (EVENT_EDITOR (editor));
@@ -84,7 +89,7 @@ open_component_editor (ECal *client, ECalComponent *comp, gboolean is_new, GErro
if (e_cal_component_has_attendees (comp))
flags |= COMP_EDITOR_IS_ASSIGNED;
- editor = task_editor_new (client, flags);
+ editor = task_editor_new (client, shell, flags);
if (flags & COMP_EDITOR_IS_ASSIGNED)
task_editor_show_assignment (TASK_EDITOR (editor));
@@ -93,7 +98,7 @@ open_component_editor (ECal *client, ECalComponent *comp, gboolean is_new, GErro
if (e_cal_component_has_organizer (comp))
flags |= COMP_EDITOR_IS_SHARED;
- editor = memo_editor_new (client, flags);
+ editor = memo_editor_new (client, shell, flags);
break;
default:
if (error)
@@ -106,8 +111,6 @@ open_component_editor (ECal *client, ECalComponent *comp, gboolean is_new, GErro
/* request save for new events */
comp_editor_set_changed (editor, is_new);
-
- e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
}
}
diff --git a/calendar/gui/cal-editor-utils.h b/calendar/gui/cal-editor-utils.h
index de37367756..211684eb20 100644
--- a/calendar/gui/cal-editor-utils.h
+++ b/calendar/gui/cal-editor-utils.h
@@ -17,17 +17,22 @@
*
*/
-#ifndef CAL_EDITOR_UTILS_HEADER
-#define CAL_EDITOR_UTILS_HEADER
+#ifndef CAL_EDITOR_UTILS_H
+#define CAL_EDITOR_UTILS_H
#include <glib.h>
#include <libecal/e-cal.h>
#include <libecal/e-cal-component.h>
+#include <shell/e-shell.h>
G_BEGIN_DECLS
-void open_component_editor (ECal *client, ECalComponent *comp, gboolean is_new, GError **error);
+void open_component_editor (EShell *shell,
+ ECal *client,
+ ECalComponent *comp,
+ gboolean is_new,
+ GError **error);
G_END_DECLS
-#endif
+#endif /* CAL_EDITOR_UTILS_H */
diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c
deleted file mode 100644
index 63fcb03497..0000000000
--- a/calendar/gui/cal-search-bar.c
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * Evolution calendar - Search bar widget for calendar views
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena-Quintero <federico@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <libedataserver/e-categories.h>
-#include <libecal/e-cal-time-util.h>
-#include <libedataserver/e-categories.h>
-#include <filter/rule-editor.h>
-
-#include "cal-search-bar.h"
-#include "calendar-component.h"
-#include "memos-component.h"
-#include "tasks-component.h"
-
-#include "e-util/e-util.h"
-#include "e-util/e-error.h"
-#include "e-util/e-util-private.h"
-
-typedef struct CALSearchBarItem {
- ESearchBarItem search;
- const gchar *image;
-} CALSearchBarItem;
-
-static ESearchBarItem calendar_search_items[] = {
- E_FILTERBAR_ADVANCED,
- {NULL, 0, 0},
- E_FILTERBAR_SAVE,
- E_FILTERBAR_EDIT,
- {NULL, -1, 0}
-};
-
-/* IDs and option items for the ESearchBar */
-enum {
- SEARCH_SUMMARY_CONTAINS,
- SEARCH_DESCRIPTION_CONTAINS,
- SEARCH_ANY_FIELD_CONTAINS,
- SEARCH_CATEGORY_IS,
- SEARCH_COMMENT_CONTAINS,
- SEARCH_LOCATION_CONTAINS,
- SEARCH_ATTENDEE_CONTAINS
-
-};
-
-/* Comments are disabled because they are kind of useless right now, see bug 33247 */
-static ESearchBarItem search_option_items[] = {
- { (gchar *) N_("Summary contains"), SEARCH_SUMMARY_CONTAINS, ESB_ITEMTYPE_RADIO },
- { (gchar *) N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS, ESB_ITEMTYPE_RADIO },
- { (gchar *) N_("Category is"), SEARCH_CATEGORY_IS, ESB_ITEMTYPE_RADIO },
- { (gchar *) N_("Comment contains"), SEARCH_COMMENT_CONTAINS, ESB_ITEMTYPE_RADIO },
- { (gchar *) N_("Location contains"), SEARCH_LOCATION_CONTAINS, ESB_ITEMTYPE_RADIO },
- { (gchar *) N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS, ESB_ITEMTYPE_RADIO },
-};
-
-/* IDs for the categories suboptions */
-
-typedef enum {
- CATEGORIES_ALL,
- CATEGORIES_UNMATCHED,
- LAST_FIELD
-} common_search_options;
-
-typedef enum {
- N_DAY_TASK = LAST_FIELD,
- ACTIVE_TASK,
- OVERDUE_TASK,
- COMPLETED_TASK,
- TASK_WITH_ATTACHMENT,
- TASK_LAST_FIELD
-} task_search_options;
-
-typedef enum {
- ACTIVE_APPONTMENT = LAST_FIELD,
- N_DAY_APPOINTMENT,
- CAL_LAST_FIELD
-} cal_search_options;
-
-/* We add 2 to the offset to include the separators used to differenciate the quick search queries. */
-#define CATEGORIES_TASKS_OFFSET (TASK_LAST_FIELD + 2)
-#define CATEGORIES_MEMOS_OFFSET (LAST_FIELD + 1)
-#define CATEGORIES_CALENDAR_OFFSET (CAL_LAST_FIELD + 2)
-
-/* Private part of the CalSearchBar structure */
-struct CalSearchBarPrivate {
- /* Array of categories */
- GPtrArray *categories;
-
- RuleContext *search_context;
- FilterRule *search_rule;
- guint32 view_flag;
-
- time_t start;
- time_t end;
-};
-
-static void cal_search_bar_destroy (GtkObject *object);
-
-static void cal_search_bar_search_activated (ESearchBar *search);
-
-/* Signal IDs */
-enum {
- SEXP_CHANGED,
- CATEGORY_CHANGED,
- LAST_SIGNAL
-};
-
-static guint cal_search_bar_signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (CalSearchBar, cal_search_bar, E_FILTER_BAR_TYPE)
-
-/* Class initialization function for the calendar search bar */
-static void
-cal_search_bar_class_init (CalSearchBarClass *klass)
-{
-
- GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
- ESearchBarClass *search_bar_class = E_SEARCH_BAR_CLASS (klass);
-
- cal_search_bar_signals[SEXP_CHANGED] =
- g_signal_new ("sexp_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalSearchBarClass, sexp_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- cal_search_bar_signals[CATEGORY_CHANGED] =
- g_signal_new ("category_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalSearchBarClass, category_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- klass->sexp_changed = NULL;
- klass->category_changed = NULL;
-
- search_bar_class->search_activated = cal_search_bar_search_activated;
- object_class->destroy = cal_search_bar_destroy;
-}
-
-/* Object initialization function for the calendar search bar */
-static void
-cal_search_bar_init (CalSearchBar *cal_search)
-{
- CalSearchBarPrivate *priv;
-
- priv = g_new (CalSearchBarPrivate, 1);
- cal_search->priv = priv;
-
- priv->categories = g_ptr_array_new ();
- g_ptr_array_set_size (priv->categories, 0);
-
- priv->start = -1;
- priv->end = -1;
-}
-
-/* Frees an array of categories */
-static void
-free_categories (GPtrArray *categories)
-{
- gint i;
-
- for (i = 0; i < categories->len; i++) {
- if (categories->pdata[i] == NULL)
- continue;
- g_free (categories->pdata[i]);
- }
-
- g_ptr_array_free (categories, TRUE);
-}
-
-/* Destroy handler for the calendar search bar */
-static void
-cal_search_bar_destroy (GtkObject *object)
-{
- CalSearchBar *cal_search;
- CalSearchBarPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_SEARCH_BAR (object));
-
- cal_search = CAL_SEARCH_BAR (object);
- priv = cal_search->priv;
-
- if (priv) {
- if (priv->categories) {
- free_categories (priv->categories);
- priv->categories = NULL;
- }
-
- if (priv->search_rule) {
- g_object_unref (priv->search_rule);
- priv->search_rule = NULL;
- }
-
- /* FIXME
- if (priv->search_context) {
- g_object_unref (priv->search_context);
- priv->search_context = NULL;
- }*/
-
- g_free (priv);
- cal_search->priv = NULL;
- }
-
- if (GTK_OBJECT_CLASS (cal_search_bar_parent_class)->destroy)
- (* GTK_OBJECT_CLASS (cal_search_bar_parent_class)->destroy) (object);
-}
-
-
-
-/* Emits the "sexp_changed" signal for the calendar search bar */
-static void
-notify_sexp_changed (CalSearchBar *cal_search, const gchar *sexp)
-{
- g_signal_emit (GTK_OBJECT (cal_search), cal_search_bar_signals[SEXP_CHANGED], 0, sexp);
-}
-
-/* Returns the string of the currently selected category, NULL for "Unmatched" and "All
-*/
-static const gchar *
-get_current_category (CalSearchBar *cal_search)
-{
- CalSearchBarPrivate *priv;
- gint viewid, i = -1;
-
- priv = cal_search->priv;
-
- g_return_val_if_fail (priv->categories != NULL, NULL);
-
- viewid = e_search_bar_get_viewitem_id (E_SEARCH_BAR (cal_search));
-
- if (viewid == CATEGORIES_ALL || viewid == CATEGORIES_UNMATCHED)
- return NULL;
-
- if (priv->view_flag == CAL_SEARCH_TASKS_DEFAULT)
- i = viewid - CATEGORIES_TASKS_OFFSET;
- else if (priv->view_flag == CAL_SEARCH_MEMOS_DEFAULT)
- i = viewid - CATEGORIES_MEMOS_OFFSET;
- else if (priv->view_flag == CAL_SEARCH_CALENDAR_DEFAULT)
- i = viewid - CATEGORIES_CALENDAR_OFFSET;
-
- if (i >= 0 && i < priv->categories->len)
- return priv->categories->pdata[i];
- else
- return NULL;
-}
-
-/* Returns a sexp for the selected category in the drop-down menu. The "All"
- * option is returned as (const gchar *) 1, and the "Unfiled" option is returned
- * as NULL.
- */
-static gchar *
-get_show_option_sexp (CalSearchBar *cal_search)
-{
- CalSearchBarPrivate *priv;
- gint viewid;
- gchar *start, *end, *due, *ret = NULL;
- const gchar *category = NULL;
- time_t start_range, end_range;
-
- priv = cal_search->priv;
- viewid = e_search_bar_get_viewitem_id (E_SEARCH_BAR (cal_search));
-
- if (viewid == CATEGORIES_UNMATCHED)
- return g_strdup ("(has-categories? #f)"); /* Unfiled items */
- else if (viewid == CATEGORIES_ALL)
- return NULL; /* All items */
-
- switch (priv->view_flag) {
- case CAL_SEARCH_TASKS_DEFAULT:
- if (viewid == N_DAY_TASK) {
- start_range = time(NULL);
- end_range = time_add_day(start_range, 7);
- start = isodate_from_time_t (start_range);
- due = isodate_from_time_t (end_range);
-
- ret = g_strdup_printf ("(due-in-time-range? (make-time \"%s\")"
- " (make-time \"%s\"))",
- start, due);
-
- g_free (start);
- g_free (due);
-
- return ret;
- } else if (viewid == ACTIVE_TASK) {
- /* Shows the tasks due for an year from now which are not completed yet*/
- start_range = time(NULL);
- end_range = time_add_day(start_range, 365);
- start = isodate_from_time_t (start_range);
- due = isodate_from_time_t (end_range);
-
- ret = g_strdup_printf ("(and (due-in-time-range? (make-time \"%s\")"
- " (make-time \"%s\")) (not (is-completed?)))",
- start, due);
-
- g_free (start);
- g_free (due);
-
- return ret;
- } else if (viewid == OVERDUE_TASK) {
- /* Shows the tasks which are overdue from lower limit 1970 to the current time */
- start_range = 0;
- end_range = time (NULL);
- start = isodate_from_time_t (start_range);
- due = isodate_from_time_t (end_range);
-
- ret = g_strdup_printf ("(and (due-in-time-range? (make-time \"%s\")"
- " (make-time \"%s\")) (not (is-completed?)))",
- start, due);
-
- g_free (start);
- g_free (due);
-
- return ret;
- } else if (viewid == COMPLETED_TASK)
- return g_strdup ("(is-completed?)");
- else if (viewid == TASK_WITH_ATTACHMENT)
- return g_strdup ("(has-attachments?)");
- break;
- case CAL_SEARCH_CALENDAR_DEFAULT:
- if (viewid == ACTIVE_APPONTMENT) {
- /* Shows next one year's Appointments */
- start_range = time (NULL);
- end_range = time_add_day (start_range, 365);
- start = isodate_from_time_t (start_range);
- end = isodate_from_time_t (end_range);
-
- ret = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\")"
- " (make-time \"%s\"))",
- start, end);
-
- cal_search->priv->start = start_range;
- cal_search->priv->end = end_range;
-
- g_free (start);
- g_free (end);
-
- return ret;
- } else if (viewid == N_DAY_APPOINTMENT) {
- start_range = time (NULL);
- end_range = time_add_day (start_range, 7);
- start = isodate_from_time_t (start_range);
- end = isodate_from_time_t (end_range);
-
- ret = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\")"
- " (make-time \"%s\"))",
- start, end);
-
- cal_search->priv->start = start_range;
- cal_search->priv->end = end_range;
-
- g_free (start);
- g_free (end);
-
- return ret;
- }
- break;
- default:
- break;
- }
-
- category = get_current_category (cal_search);
-
- if (category != NULL)
- return g_strdup_printf ("(has-categories? \"%s\")", category);
- else
- return NULL;
-}
-
-/* Sets the query string to be (contains? "field" "text") */
-static void
-notify_e_cal_view_contains (CalSearchBar *cal_search, const gchar *field, const gchar *view)
-{
- gchar *text = NULL;
- gchar *sexp;
-
- text = e_search_bar_get_text (E_SEARCH_BAR (cal_search));
-
- if (!text)
- return; /* This is an error in the UTF8 conversion, not an empty string! */
-
- if (text && *text)
- sexp = g_strdup_printf ("(contains? \"%s\" \"%s\")", field, text);
- else
- sexp = g_strdup ("(contains? \"summary\" \"\")"); /* Show all */
-
- g_free (text);
-
- /* Apply the selected view on search */
- if (view && *view) {
- sexp = g_strconcat ("(and ",sexp, view, ")", NULL);
- }
-
- notify_sexp_changed (cal_search, sexp);
-
- g_free (sexp);
-}
-
-#if 0
-/* Sets the query string to the appropriate match for categories */
-static void
-notify_category_is (CalSearchBar *cal_search)
-{
- gchar *sexp;
-
- sexp = get_show_option_sexp (cal_search);
-
- if (!sexp)
- notify_sexp_changed (cal_search, "#t"); /* Match all */
- else
- notify_sexp_changed (cal_search, sexp);
-
- if (sexp)
- g_free (sexp);
-}
-#endif
-
-/* Creates a new query from the values in the widgets and notifies upstream */
-static void
-regen_query (CalSearchBar *cal_search)
-{
- gint id;
- gchar *show_option_sexp = NULL;
- gchar *sexp = NULL;
- GString *out = NULL;
- EFilterBar *efb = (EFilterBar *) cal_search;
-
- /* Fetch the data from the ESearchBar's entry widgets */
- id = e_search_bar_get_item_id (E_SEARCH_BAR (cal_search));
-
- cal_search->priv->start = -1;
- cal_search->priv->end = -1;
-
- /* Get the selected view */
- show_option_sexp = get_show_option_sexp (cal_search);
-
- /* Generate the different types of queries */
- switch (id) {
- case SEARCH_ANY_FIELD_CONTAINS:
- notify_e_cal_view_contains (cal_search, "any", show_option_sexp);
- break;
-
- case SEARCH_SUMMARY_CONTAINS:
- notify_e_cal_view_contains (cal_search, "summary", show_option_sexp);
- break;
-
- case SEARCH_DESCRIPTION_CONTAINS:
- notify_e_cal_view_contains (cal_search, "description", show_option_sexp);
- break;
-
- case SEARCH_COMMENT_CONTAINS:
- notify_e_cal_view_contains (cal_search, "comment", show_option_sexp);
- break;
-
- case SEARCH_LOCATION_CONTAINS:
- notify_e_cal_view_contains (cal_search, "location", show_option_sexp);
- break;
- case SEARCH_ATTENDEE_CONTAINS:
- notify_e_cal_view_contains (cal_search, "attendee", show_option_sexp);
- break;
- case E_FILTERBAR_ADVANCED_ID:
- out = g_string_new ("");
- filter_rule_build_code (efb->current_query, out);
-
- if (show_option_sexp && *show_option_sexp)
- sexp = g_strconcat ("(and ", out->str, show_option_sexp, ")", NULL);
-
- notify_sexp_changed (cal_search, sexp ? sexp : out->str);
-
- g_string_free (out, TRUE);
- g_free(sexp);
- break;
-
- default:
- g_return_if_reached ();
- }
-
- g_free (show_option_sexp);
-}
-
-#if 0
-static void
-regen_view_query (CalSearchBar *cal_search)
-{
- const gchar *category;
- notify_category_is (cal_search);
-
- category = cal_search_bar_get_category (cal_search);
- g_signal_emit (GTK_OBJECT (cal_search), cal_search_bar_signals[CATEGORY_CHANGED], 0, category);
-}
-#endif
-
-/* search_activated handler for the calendar search bar */
-static void
-cal_search_bar_search_activated (ESearchBar *search)
-{
- CalSearchBar *cal_search;
-
- cal_search = CAL_SEARCH_BAR (search);
- regen_query (cal_search);
-}
-
-static GtkWidget *
-generate_viewoption_menu (CALSearchBarItem *subitems)
-{
- GtkWidget *menu, *menu_item;
- gint i = 0;
-
- menu = gtk_menu_new ();
-
- for (i = 0; subitems[i].search.id != -1; ++i) {
- if (subitems[i].search.text) {
- gchar *str = NULL;
- str = e_str_without_underscores (subitems[i].search.text);
- menu_item = gtk_image_menu_item_new_with_label (str);
- if (subitems[i].image) {
- GtkWidget *image;
-
- image = gtk_image_new_from_file (
- subitems[i].image);
- gtk_image_menu_item_set_image (
- GTK_IMAGE_MENU_ITEM (menu_item),
- image);
- }
- g_free (str);
- } else {
- menu_item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
-
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (subitems[i].search.id));
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
-
- return menu;
-}
-
-static void
-setup_category_options (CalSearchBar *cal_search, CALSearchBarItem *subitems, gint index, gint offset)
-{
- CalSearchBarPrivate *priv;
- gint i;
-
- priv = cal_search->priv;
-
- if (priv->categories->len > 0) {
- subitems[index].search.text = NULL; /* separator */
- subitems[index].search.id = 0;
- subitems[index].image = NULL;
-
- for (i = 0; i < priv->categories->len; i++) {
- const gchar *category;
-
- category = priv->categories->pdata[i] ? priv->categories->pdata [i] : "";
-
- /* The search.text field should not be free'd */
- subitems[i + offset].search.text = (gchar *) category;
- subitems[i + offset].search.id = i + offset;
- subitems[i + offset].image = e_categories_get_icon_file_for (category);
- }
- index = i + offset;
- }
-
- subitems[index].search.id = -1; /* terminator */
- subitems[index].search.text = NULL;
- subitems[index].image = NULL;
-}
-
-/* Creates the suboptions menu for the ESearchBar with the list of categories */
-static void
-make_suboptions (CalSearchBar *cal_search)
-{
- CalSearchBarPrivate *priv;
- CALSearchBarItem *subitems = NULL;
- GtkWidget *menu;
-
- priv = cal_search->priv;
-
- g_return_if_fail (priv->categories != NULL);
-
- /* Categories plus "all", "unmatched", separator, terminator */
-
- /* All, unmatched, separator */
-
- if (priv->view_flag == CAL_SEARCH_TASKS_DEFAULT) {
- subitems = g_new (CALSearchBarItem, priv->categories->len + CATEGORIES_TASKS_OFFSET + 1);
-
- subitems[0].search.text = _("Any Category");
- subitems[0].search.id = CATEGORIES_ALL;
- subitems[0].image = NULL;
-
- subitems[1].search.text = _("Unmatched");
- subitems[1].search.id = CATEGORIES_UNMATCHED;
- subitems[1].image = NULL;
-
- subitems[2].search.text = NULL;
- subitems[2].search.id = 0;
- subitems[2].image = NULL;
-
- subitems[3].search.text = _("Next 7 Days' Tasks");
- subitems[3].search.id = N_DAY_TASK;
- subitems[3].image = NULL;
-
- subitems[4].search.text = _("Active Tasks");
- subitems[4].search.id = ACTIVE_TASK;
- subitems[4].image = NULL;
-
- subitems[5].search.text = _("Overdue Tasks");
- subitems[5].search.id = OVERDUE_TASK;
- subitems[5].image = NULL;
-
- subitems[6].search.text = _("Completed Tasks");
- subitems[6].search.id = COMPLETED_TASK;
- subitems[6].image = NULL;
-
- subitems[7].search.text = _("Tasks with Attachments");
- subitems[7].search.id = TASK_WITH_ATTACHMENT;
- subitems[7].image = NULL;
-
- /* All the other items */
- setup_category_options (cal_search, subitems, 8, CATEGORIES_TASKS_OFFSET);
-
- menu = generate_viewoption_menu (subitems);
- e_search_bar_set_viewoption_menu ((ESearchBar *)cal_search, menu);
-
- } else if (priv->view_flag == CAL_SEARCH_MEMOS_DEFAULT) {
- subitems = g_new (CALSearchBarItem, priv->categories->len + CATEGORIES_MEMOS_OFFSET + 1);
-
- /* All, unmatched, separator */
-
- subitems[0].search.text = _("Any Category");
- subitems[0].search.id = CATEGORIES_ALL;
- subitems[0].image = NULL;
-
- subitems[1].search.text = _("Unmatched");
- subitems[1].search.id = CATEGORIES_UNMATCHED;
- subitems[1].image = NULL;
-
- /* All the other items */
- setup_category_options (cal_search, subitems, 2, CATEGORIES_MEMOS_OFFSET);
-
- menu = generate_viewoption_menu (subitems);
- e_search_bar_set_viewoption_menu ((ESearchBar *)cal_search, menu);
-
- } else if (priv->view_flag == CAL_SEARCH_CALENDAR_DEFAULT) {
- subitems = g_new (CALSearchBarItem, priv->categories->len + CATEGORIES_CALENDAR_OFFSET + 1);
-
- /* All, unmatched, separator */
-
- subitems[0].search.text = _("Any Category");
- subitems[0].search.id = CATEGORIES_ALL;
- subitems[0].image = NULL;
-
- subitems[1].search.text = _("Unmatched");
- subitems[1].search.id = CATEGORIES_UNMATCHED;
- subitems[1].image = NULL;
-
- subitems[2].search.text = NULL;
- subitems[2].search.id = 0;
- subitems[2].image = NULL;
-
- subitems[3].search.text = _("Active Appointments");
- subitems[3].search.id = ACTIVE_APPONTMENT;
- subitems[3].image = NULL;
-
- subitems[4].search.text = _("Next 7 Days' Appointments");
- subitems[4].search.id = N_DAY_APPOINTMENT;
- subitems[4].image = NULL;
-
- /* All the other items */
- setup_category_options (cal_search, subitems, 5, CATEGORIES_CALENDAR_OFFSET);
-
- menu = generate_viewoption_menu (subitems);
- e_search_bar_set_viewoption_menu ((ESearchBar *)cal_search, menu);
- }
-
- if (subitems != NULL)
- g_free (subitems);
-}
-
-static void
-search_menu_activated (ESearchBar *esb, gint id)
-{
- if (id == E_FILTERBAR_ADVANCED_ID)
- e_search_bar_set_item_id (esb, id);
-}
-
-/**
- * cal_search_bar_construct:
- * @cal_search: A calendar search bar.
- * @flags: bitfield of items to appear in the search menu
- *
- * Constructs a calendar search bar by binding its menu and option items.
- *
- * Return value: The same value as @cal_search.
- **/
-CalSearchBar *
-cal_search_bar_construct (CalSearchBar *cal_search, guint32 flags)
-{
- ESearchBarItem *items;
- guint32 bit = 0x1;
- gint i, j;
- gchar *xmlfile = NULL;
- gchar *userfile = NULL;
- FilterPart *part;
- RuleContext *search_context;
- FilterRule *search_rule;
- const gchar *base_dir;
-
- g_return_val_if_fail (IS_CAL_SEARCH_BAR (cal_search), NULL);
-
- items = g_alloca ((G_N_ELEMENTS (search_option_items) + 1) * sizeof (ESearchBarItem));
- for (i = 0, j = 0; i < G_N_ELEMENTS (search_option_items); i++, bit <<= 1) {
- if ((flags & bit) != 0) {
- items[j].text = search_option_items[i].text;
- items[j].id = search_option_items[i].id;
- items[j].type = search_option_items[i].type;
- j++;
- }
- }
-
- items[j].text = NULL;
- items[j].id = -1;
- search_context = rule_context_new ();
- cal_search->priv->view_flag = flags;
-
- rule_context_add_part_set (search_context, "partset", filter_part_get_type (),
- rule_context_add_part, rule_context_next_part);
- rule_context_add_rule_set (search_context, "ruleset", filter_rule_get_type (),
- rule_context_add_rule, rule_context_next_rule);
-
- if (flags == CAL_SEARCH_MEMOS_DEFAULT) {
- base_dir = memos_component_peek_base_directory (memos_component_peek ());
- xmlfile = g_build_filename (SEARCH_RULE_DIR, "memotypes.xml", NULL);
- } else if (flags == CAL_SEARCH_TASKS_DEFAULT) {
- base_dir = tasks_component_peek_base_directory (tasks_component_peek ());
- xmlfile = g_build_filename (SEARCH_RULE_DIR, "tasktypes.xml", NULL);
- } else {
- base_dir = calendar_component_peek_base_directory (calendar_component_peek ());
- xmlfile = g_build_filename (SEARCH_RULE_DIR, "caltypes.xml", NULL);
- }
-
- userfile = g_build_filename (base_dir, "searches.xml", NULL);
-
- g_object_set_data_full (G_OBJECT (search_context), "user", userfile, g_free);
- g_object_set_data_full (G_OBJECT (search_context), "system", xmlfile, g_free);
-
- rule_context_load (search_context, xmlfile, userfile);
- search_rule = filter_rule_new ();
- part = rule_context_next_part (search_context, NULL);
-
- if (part == NULL)
- g_warning ("Could not load calendar search; no parts.");
- else
- filter_rule_add_part (search_rule, filter_part_clone (part));
-
- e_filter_bar_new_construct (search_context, xmlfile, userfile, NULL, cal_search,
- (EFilterBar*) cal_search );
- e_search_bar_set_menu ((ESearchBar *) cal_search, calendar_search_items);
-
- g_signal_connect ((ESearchBar *) cal_search, "menu_activated", G_CALLBACK (search_menu_activated), cal_search);
-
- make_suboptions (cal_search);
-
- cal_search->priv->search_rule = search_rule;
- cal_search->priv->search_context = search_context;
-
- g_free (xmlfile);
- g_free (userfile);
-
- return cal_search;
-}
-
-/**
- * cal_search_bar_new:
- * flags: bitfield of items to appear in the search menu
- *
- * creates a new calendar search bar.
- *
- * return value: a newly-created calendar search bar. you should connect to the
- * "sexp_changed" signal to monitor changes in the generated sexps.
- **/
-GtkWidget *
-cal_search_bar_new (guint32 flags)
-{
- CalSearchBar *cal_search;
-
- cal_search = g_object_new (TYPE_CAL_SEARCH_BAR, NULL);
- return GTK_WIDGET (cal_search_bar_construct (cal_search, flags));
-}
-
-/* Used from qsort() */
-static gint
-compare_categories_cb (gconstpointer a, gconstpointer b)
-{
- const gchar **ca, **cb;
-
- ca = (const gchar **) a;
- cb = (const gchar **) b;
-
- /* FIXME: should use some utf8 strcoll() thingy */
- return strcmp (*ca, *cb);
-}
-
-/* Creates a sorted array of categories based on the original one; copies the
- * string values.
- */
-static GPtrArray *
-sort_categories (GPtrArray *categories)
-{
- GPtrArray *c;
- gint i;
-
- c = g_ptr_array_new ();
- g_ptr_array_set_size (c, categories->len);
-
- for (i = 0; i < categories->len; i++)
- c->pdata[i] = g_strdup (categories->pdata[i]);
-
- qsort (c->pdata, c->len, sizeof (gpointer), compare_categories_cb);
-
- return c;
-}
-
-/**
- * cal_search_bar_set_categories:
- * @cal_search: A calendar search bar.
- * @categories: Array of pointers to strings for the category names.
- *
- * Sets the list of categories that are to be shown in the drop-down list
- * of a calendar search bar. The search bar will automatically add an item
- * for "unfiled" components, that is, those that have no categories assigned
- * to them.
- **/
-void
-cal_search_bar_set_categories (CalSearchBar *cal_search, GPtrArray *categories)
-{
- CalSearchBarPrivate *priv;
-
- g_return_if_fail (IS_CAL_SEARCH_BAR (cal_search));
- g_return_if_fail (categories != NULL);
-
- priv = cal_search->priv;
-
- g_return_if_fail (priv->categories != NULL);
- free_categories (priv->categories);
-
- priv->categories = sort_categories (categories);
- make_suboptions (cal_search);
-}
-
-/**
- * cal_search_bar_get_category:
- * @cal_search: A calendar search bar.
- *
- * Queries the currently selected category name in a calendar search bar.
- * If "All" or "Unfiled" are selected, this function will return NULL.
- *
- * Return value: Name of the selected category, or NULL if there is no
- * selected category.
- **/
-const gchar *
-cal_search_bar_get_category (CalSearchBar *cal_search)
-{
- const gchar *category;
-
- category = get_current_category (cal_search);
-
- return category;
-}
-
-void
-cal_search_bar_get_time_range (CalSearchBar *cal_search, time_t *start, time_t *end)
-{
- CalSearchBarPrivate *priv;
-
- g_return_if_fail (IS_CAL_SEARCH_BAR (cal_search));
-
- priv = cal_search->priv;
-
- *start = priv->start;
- *end = priv->end;
-}
-
diff --git a/calendar/gui/cal-search-bar.h b/calendar/gui/cal-search-bar.h
deleted file mode 100644
index 3c7304f136..0000000000
--- a/calendar/gui/cal-search-bar.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *
- * Evolution calendar - Search bar widget for calendar views
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena-Quintero <federico@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef CAL_SEARCH_BAR_H
-#define CAL_SEARCH_BAR_H
-
-#include "misc/e-search-bar.h"
-#include "misc/e-filter-bar.h"
-
-G_BEGIN_DECLS
-
-
-
-#define TYPE_CAL_SEARCH_BAR (cal_search_bar_get_type ())
-#define CAL_SEARCH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CAL_SEARCH_BAR, CalSearchBar))
-#define CAL_SEARCH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CAL_SEARCH_BAR, \
- CalSearchBarClass))
-#define IS_CAL_SEARCH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CAL_SEARCH_BAR))
-#define IS_CAL_SEARCH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CAL_SEARCH_BAR))
-
-typedef struct CalSearchBarPrivate CalSearchBarPrivate;
-
-enum {
- CAL_SEARCH_SUMMARY_CONTAINS = (1 << 0),
- CAL_SEARCH_DESCRIPTION_CONTAINS = (1 << 1),
- CAL_SEARCH_CATEGORY_IS = (1 << 2),
- CAL_SEARCH_COMMENT_CONTAINS = (1 << 3),
- CAL_SEARCH_LOCATION_CONTAINS = (1 << 4),
- CAL_SEARCH_ANY_FIELD_CONTAINS = (1 << 5)
-};
-
-#define CAL_SEARCH_ALL (0xff)
-#define CAL_SEARCH_CALENDAR_DEFAULT (0x33)
-#define CAL_SEARCH_TASKS_DEFAULT (0xE3)
-#define CAL_SEARCH_MEMOS_DEFAULT (0x23)
-
-typedef struct {
- EFilterBar search_bar;
-
- /* Private data */
- CalSearchBarPrivate *priv;
-} CalSearchBar;
-
-typedef struct {
- EFilterBarClass parent_class;
-
- /* Notification signals */
-
- void (* sexp_changed) (CalSearchBar *cal_search, const gchar *sexp);
- void (* category_changed) (CalSearchBar *cal_search, const gchar *category);
-} CalSearchBarClass;
-
-GType cal_search_bar_get_type (void);
-
-CalSearchBar *cal_search_bar_construct (CalSearchBar *cal_search, guint32 flags);
-
-GtkWidget *cal_search_bar_new (guint32 flags);
-
-void cal_search_bar_set_categories (CalSearchBar *cal_search, GPtrArray *categories);
-
-const gchar *cal_search_bar_get_category (CalSearchBar *cal_search);
-
-void cal_search_bar_get_time_range (CalSearchBar *cal_search, time_t *start, time_t *end);
-
-
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c
index f91442a109..6368857ead 100644
--- a/calendar/gui/calendar-commands.c
+++ b/calendar/gui/calendar-commands.c
@@ -66,71 +66,6 @@ typedef struct {
guint taskpad_focused : 1;
} FocusData;
-static void
-file_open_event_cb (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- e_calendar_view_open_event (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
-}
-
-/* Prints the calendar at its current view and time range */
-void
-calendar_command_print (GnomeCalendar *gcal, GtkPrintOperationAction action)
-{
- if (gnome_calendar_get_view (gcal) == GNOME_CAL_LIST_VIEW) {
- ECalListView *list_view;
- ETable *table;
-
- list_view = E_CAL_LIST_VIEW (gnome_calendar_get_current_view_widget (gcal));
- table = e_table_scrolled_get_table (list_view->table_scrolled);
- print_table (table, _("Print"), _("Calendar"), action);
- } else {
- time_t start;
-
- gnome_calendar_get_current_time_range (gcal, &start, NULL);
-
- if (gnome_calendar_get_view (gcal) == GNOME_CAL_MONTH_VIEW) {
- EWeekView *week_view = E_WEEK_VIEW (gnome_calendar_get_current_view_widget (gcal));
-
- if (week_view && week_view->multi_week_view && week_view->weeks_shown >= 4 && g_date_valid (&week_view->first_day_shown)) {
- GDate date = week_view->first_day_shown;
- struct icaltimetype start_tt = icaltime_null_time ();
-
- g_date_add_days (&date, 7);
-
- start_tt.is_date = TRUE;
- start_tt.year = g_date_get_year (&date);
- start_tt.month = g_date_get_month (&date);
- start_tt.day = g_date_get_day (&date);
-
- start = icaltime_as_timet (start_tt);
- }
- }
-
- print_calendar (gcal, action, start);
- }
-}
-
-/* File/Print callback */
-static void
-file_print_cb (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal = GNOME_CALENDAR (data);
-
- calendar_command_print (gcal, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-}
-
-static void
-file_print_preview_cb (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal = GNOME_CALENDAR (data);
-
- calendar_command_print (gcal, GTK_PRINT_OPERATION_ACTION_PREVIEW);
-}
-
/* Sets a clock cursor for the specified calendar window */
static void
set_clock_cursor (GnomeCalendar *gcal)
@@ -152,58 +87,6 @@ set_normal_cursor (GnomeCalendar *gcal)
}
static void
-previous_clicked (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_previous (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-next_clicked (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_next (gcal);
- set_normal_cursor (gcal);
-}
-
-void
-calendar_goto_today (GnomeCalendar *gcal)
-{
- set_clock_cursor (gcal);
- gnome_calendar_goto_today (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-today_clicked (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- calendar_goto_today (gcal);
-}
-
-static void
-goto_clicked (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- goto_dialog (gcal);
-}
-
-static void
show_day_view_clicked (BonoboUIComponent *uic, gpointer data, const gchar *path)
{
GnomeCalendar *gcal;
@@ -253,113 +136,6 @@ show_list_view_clicked (BonoboUIComponent *uic, gpointer data, const gchar *path
gnome_calendar_set_view (gcal, GNOME_CAL_LIST_VIEW);
}
-static void
-cut_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
- set_clock_cursor (gcal);
- gnome_calendar_cut_clipboard (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-copy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_copy_clipboard (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-paste_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_paste_clipboard (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-delete_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_delete_selection (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-delete_occurrence_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_delete_selected_occurrence (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-purge_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
- GtkWidget *dialog, *parent, *box, *label, *spin;
- gint response;
-
- gcal = GNOME_CALENDAR (data);
-
- /* create the dialog */
- parent = gtk_widget_get_toplevel (GTK_WIDGET (gcal));
- dialog = gtk_message_dialog_new (
- (GtkWindow *)parent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_OK_CANCEL,
- _("This operation will permanently erase all events older than the selected amount of time. If you continue, you will not be able to recover these events."));
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
-
- box = gtk_hbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), box, TRUE, FALSE, 6);
-
- label = gtk_label_new (_("Purge events older than"));
- gtk_box_pack_start (GTK_BOX (box), label, TRUE, FALSE, 6);
- spin = gtk_spin_button_new_with_range (0.0, 1000.0, 1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 60.0);
- gtk_box_pack_start (GTK_BOX (box), spin, FALSE, FALSE, 6);
- label = gtk_label_new (_("days"));
- gtk_box_pack_start (GTK_BOX (box), label, TRUE, FALSE, 6);
-
- gtk_widget_show_all (box);
-
- /* run the dialog */
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- if (response == GTK_RESPONSE_OK) {
- gint days;
- time_t tt;
-
- days = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));
- tt = time (NULL);
- tt -= (days * (24 * 3600));
-
- gnome_calendar_purge (gcal, tt);
- }
-
- gtk_widget_destroy (dialog);
-}
-
struct _sensitize_item {
const gchar *command;
guint32 enable;
@@ -384,69 +160,6 @@ sensitize_items(BonoboUIComponent *uic, struct _sensitize_item *items, guint32 m
}
}
-static struct _sensitize_item calendar_sensitize_table[] = {
- { "EventOpen", E_CAL_MENU_SELECT_ONE },
- { "Cut", E_CAL_MENU_SELECT_EDITABLE | E_CAL_MENU_SELECT_ANY },
- { "Copy", E_CAL_MENU_SELECT_ANY },
- { "Paste", E_CAL_MENU_SELECT_EDITABLE },
- { "Delete", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_NONRECURRING },
- { "DeleteOccurrence", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_RECURRING },
- { "DeleteAllOccurrences", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_RECURRING },
- { NULL }
-};
-
-/* Sensitizes the UI Component menu/toolbar calendar commands based on the
- * number of selected events. (This will always be 0 or 1 currently.) If enable
- * is FALSE, all will be disabled. Otherwise, the currently-selected number of
- * events will be used.
- */
-void
-calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable)
-{
- BonoboUIComponent *uic;
- GtkWidget *view;
- ECalMenu *menu;
- ECalModel *model;
- GPtrArray *events;
- GList *selected, *l;
- ECalMenuTargetSelect *t;
-
- uic = bonobo_control_get_ui_component (control);
- g_return_if_fail (uic != NULL);
-
- if (bonobo_ui_component_get_container (uic) == CORBA_OBJECT_NIL)
- return;
-
- view = gnome_calendar_get_current_view_widget (gcal);
-
- menu = gnome_calendar_get_calendar_menu (gcal);
- model = e_calendar_view_get_model((ECalendarView *)view);
- events = g_ptr_array_new();
- selected = e_calendar_view_get_selected_events((ECalendarView *)view);
- for (l=selected;l;l=g_list_next(l)) {
- ECalendarViewEvent *event = l->data;
- if (event && event->comp_data)
- g_ptr_array_add (events, e_cal_model_copy_component_data(event->comp_data));
- }
- g_list_free(selected);
-
- t = e_cal_menu_target_new_select(menu, model, events);
- if (!enable)
- t->target.mask = ~((~t->target.mask) & E_CAL_MENU_SELECT_EDITABLE);
-
- sensitize_items(uic, calendar_sensitize_table, t->target.mask);
-#if 0
- /* retrieve read-onlyness of the default client */
- e_cal = e_cal_model_get_default_client (gnome_calendar_get_calendar_model (gcal));
- if (e_cal)
- e_cal_is_read_only (e_cal, &default_read_only, NULL);
- else
- default_read_only = TRUE;
-#endif
-
- e_menu_update_target((EMenu *)menu, (EMenuTarget *)t);
-}
-
static struct _sensitize_item taskpad_sensitize_table[] = {
{ "Cut", E_CAL_MENU_SELECT_EDITABLE | E_CAL_MENU_SELECT_ANY },
{ "Copy", E_CAL_MENU_SELECT_ANY },
@@ -574,21 +287,6 @@ help_debug (BonoboUIComponent *uid, gpointer data, const gchar *path)
}
static BonoboUIVerb verbs [] = {
- BONOBO_UI_VERB ("EventOpen", file_open_event_cb),
- BONOBO_UI_VERB ("CalendarPrint", file_print_cb),
- BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb),
-
- BONOBO_UI_VERB ("Cut", cut_cmd),
- BONOBO_UI_VERB ("Copy", copy_cmd),
- BONOBO_UI_VERB ("Paste", paste_cmd),
- BONOBO_UI_VERB ("Delete", delete_cmd),
- BONOBO_UI_VERB ("DeleteOccurrence", delete_occurrence_cmd),
- BONOBO_UI_VERB ("DeleteAllOccurrences", delete_cmd),
-
- BONOBO_UI_VERB ("CalendarPrev", previous_clicked),
- BONOBO_UI_VERB ("CalendarToday", today_clicked),
- BONOBO_UI_VERB ("CalendarNext", next_clicked),
- BONOBO_UI_VERB ("CalendarGoto", goto_clicked),
BONOBO_UI_VERB ("ShowDayView", show_day_view_clicked),
BONOBO_UI_VERB ("ShowWorkWeekView", show_work_week_view_clicked),
@@ -596,40 +294,10 @@ static BonoboUIVerb verbs [] = {
BONOBO_UI_VERB ("ShowMonthView", show_month_view_clicked),
BONOBO_UI_VERB ("ShowListView", show_list_view_clicked),
- BONOBO_UI_VERB ("CalendarPurge", purge_cmd),
BONOBO_UI_VERB ("HelpDebug", help_debug),
BONOBO_UI_VERB_END
};
-static EPixmap pixmaps [] = {
- E_PIXMAP ("/commands/CalendarPrev", "go-previous", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/CalendarPrint", "document-print", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/DeleteAllOccurrences", "edit-delete", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/DeleteOccurrence", "edit-delete", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/CalendarGoto", "go-jump", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/CalendarNext", "go-next", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/CalendarPrintPreview", "document-print-preview", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/Copy", "edit-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/Cut", "edit-cut", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/Delete", "edit-delete", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/Paste", "edit-paste", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/CalendarToday", "go-today", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP ("/Toolbar/Print", "document-print", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Delete", "edit-delete", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Prev", "go-previous", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Next", "go-next", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Goto", "go-jump", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/DayView", "view-calendar-day", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/WorkWeekView", "view-calendar-workweek", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/WeekView", "view-calendar-week", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MonthView", "view-calendar-month", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/ListView", "view-calendar-list", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Today", "go-today", GTK_ICON_SIZE_LARGE_TOOLBAR),
-
- E_PIXMAP_END
-};
-
void
calendar_control_activate (BonoboControl *control,
GnomeCalendar *gcal)
@@ -661,8 +329,6 @@ calendar_control_activate (BonoboControl *control,
NULL);
g_free (xmlfile);
- e_pixmaps_update (uic, pixmaps);
-
gnome_calendar_setup_view_menus (gcal, uic);
g_signal_connect (gcal, "calendar_focus_change",
diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c
index 625321a934..e9629c70ee 100644
--- a/calendar/gui/calendar-component.c
+++ b/calendar/gui/calendar-component.c
@@ -65,26 +65,9 @@
#define CREATE_MEETING_ID "meeting"
#define CREATE_ALLDAY_EVENT_ID "allday-event"
#define CREATE_CALENDAR_ID "calendar"
-#define WEB_BASE_URI "webcal://"
-#define CONTACTS_BASE_URI "contacts://"
-#define WEATHER_BASE_URI "weather://"
-#define PERSONAL_RELATIVE_URI "system"
#define CALENDAR_ERROR_LEVEL_KEY "/apps/evolution/calendar/display/error_level"
#define CALENDAR_ERROR_TIME_OUT_KEY "/apps/evolution/calendar/display/error_timeout"
-enum DndTargetType {
- DND_TARGET_TYPE_CALENDAR_LIST
-};
-#define CALENDAR_TYPE "text/calendar"
-#define XCALENDAR_TYPE "text/x-calendar"
-static GtkTargetEntry drag_types[] = {
- { (gchar *) CALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST },
- { (gchar *) XCALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST }
-};
-static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
-#define CALENDAR_COMPONENT_DEFAULT(cc) if (cc == NULL) cc = calendar_component_peek()
-#define PARENT_TYPE bonobo_object_get_type ()
-
static BonoboObjectClass *parent_class = NULL;
typedef struct
@@ -99,27 +82,17 @@ typedef struct
GnomeCalendar *calendar;
- EInfoLabel *info_label;
GtkWidget *source_selector;
BonoboControl *view_control;
- BonoboControl *sidebar_control;
- BonoboControl *statusbar_control;
GList *notifications;
- EUserCreatableItemsHandler *creatable_items_handler;
-
- EActivityHandler *activity_handler;
-
gfloat vpane_pos;
} CalendarComponentView;
struct _CalendarComponentPrivate {
- gchar *base_directory;
- gchar *config_directory;
- GConfClient *gconf_client;
gint gconf_notify_id;
ESourceList *source_list;
@@ -136,9 +109,6 @@ struct _CalendarComponentPrivate {
GList *notifications;
};
-/* FIXME This should be gnome cal likely */
-extern ECompEditorRegistry *comp_editor_registry;
-
static void
calcomp_vpane_realized (GtkWidget *vpane, CalendarComponentView *view)
{
@@ -156,157 +126,6 @@ calcomp_vpane_resized (GtkWidget *vpane, GdkEventButton *e, CalendarComponentVie
return FALSE;
}
-static void
-ensure_sources (CalendarComponent *component)
-{
- ESourceList *source_list;
- ESourceGroup *on_this_computer;
- ESourceGroup *contacts;
- ESource *personal_source;
- ESource *birthdays_source;
- gchar *base_uri, *base_uri_proto, base_uri_proto_seventh;
- const gchar *base_dir;
- gchar *create_source;
-
- personal_source = NULL;
- birthdays_source = NULL;
-
- if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_EVENT, NULL)) {
- g_warning ("Could not get calendar source list from GConf!");
- return;
- }
-
- base_dir = calendar_component_peek_base_directory (component);
- base_uri = g_build_filename (base_dir, "local", NULL);
-
- base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
- if (strlen (base_uri_proto) > 7) {
- /* compare only file:// part. If user home dir name changes we do not want to create
- one more group */
- base_uri_proto_seventh = base_uri_proto[7];
- base_uri_proto[7] = 0;
- } else {
- base_uri_proto_seventh = -1;
- }
-
- on_this_computer = e_source_list_ensure_group (source_list, _("On This Computer"), base_uri_proto, TRUE);
- contacts = e_source_list_ensure_group (source_list, _("Contacts"), CONTACTS_BASE_URI, TRUE);
- e_source_list_ensure_group (source_list, _("On The Web"), WEB_BASE_URI, FALSE);
- e_source_list_ensure_group (source_list, _("Weather"), WEATHER_BASE_URI, FALSE);
-
- if (base_uri_proto_seventh != -1) {
- base_uri_proto[7] = base_uri_proto_seventh;
- }
-
- if (on_this_computer) {
- /* make sure "Personal" shows up as a source under
- this group */
- GSList *sources = e_source_group_peek_sources (on_this_computer);
- GSList *s;
- for (s = sources; s; s = s->next) {
- ESource *source = E_SOURCE (s->data);
- const gchar *relative_uri;
-
- relative_uri = e_source_peek_relative_uri (source);
- if (relative_uri == NULL)
- continue;
- if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
- personal_source = source;
- break;
- }
- }
- /* Make sure we have the correct base uri. This can change when user's
- homedir name changes */
- if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) {
- e_source_group_set_base_uri (on_this_computer, base_uri_proto);
-
- /* *sigh* . We shouldn't need this sync call here as set_base_uri
- call results in synching to gconf, but that happens in idle loop
- and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/
- e_source_list_sync (source_list,NULL);
- }
- }
-
- if (personal_source) {
- /* ensure the source name is in current locale, not read from configuration */
- e_source_set_name (personal_source, _("Personal"));
- } else {
- gchar *primary_calendar = calendar_config_get_primary_calendar();
- GSList *calendars_selected;
-
- /* Create the default Person addressbook */
- personal_source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
- e_source_group_add_source (on_this_computer, personal_source, -1);
- g_object_unref (personal_source);
-
- calendars_selected = calendar_config_get_calendars_selected ();
- if (!primary_calendar && !calendars_selected) {
- GSList selected;
-
- calendar_config_set_primary_calendar (e_source_peek_uid (personal_source));
-
- selected.data = (gpointer)e_source_peek_uid (personal_source);
- selected.next = NULL;
- calendar_config_set_calendars_selected (&selected);
- }
-
- if (calendars_selected) {
- g_slist_foreach (calendars_selected, (GFunc) g_free, NULL);
- g_slist_free (calendars_selected);
- }
-
- g_free (primary_calendar);
- e_source_set_color_spec (personal_source, "#BECEDD");
- }
-
- if (contacts) {
- GSList *sources = e_source_group_peek_sources (contacts);
- if (sources) {
- birthdays_source = E_SOURCE (sources->data); /* There is only one source under Contacts Group*/
-
- if (sources->next) {
- /* Ensure we have only one contacts source - we was able to create more than one before */
- GSList *l = NULL, *p;
-
- for (p = sources->next; p; p = p->next)
- l = g_slist_prepend (l, p->data);
-
- for (p = l; p; p = p->next)
- e_source_group_remove_source (contacts, p->data);
-
- g_slist_free (l);
- }
- }
- }
-
- create_source = e_source_group_get_property (contacts, "create_source");
- if (!create_source)
- e_source_group_set_property (contacts, "create_source", "no");
- g_free (create_source);
-
- if (birthdays_source) {
- /* ensure the source name is in current locale, not read from configuration */
- e_source_set_name (birthdays_source, _("Birthdays & Anniversaries"));
- } else {
- birthdays_source = e_source_new (_("Birthdays & Anniversaries"), "/");
- e_source_group_add_source (contacts, birthdays_source, -1);
- g_object_unref (birthdays_source);
- }
-
- if (!e_source_get_property (birthdays_source, "delete"))
- e_source_set_property(birthdays_source, "delete", "no");
-
- if (e_source_peek_color_spec (birthdays_source) == NULL)
- e_source_set_color_spec (birthdays_source, "#DDBECE");
-
- component->priv->source_list = source_list;
-
- g_object_unref (on_this_computer);
- g_object_unref (contacts);
- g_free (base_uri_proto);
- g_free (base_uri);
-}
-
/* Utility functions. */
static gboolean
@@ -340,88 +159,6 @@ is_in_uids (GSList *uids, ESource *source)
}
static void
-update_uris_for_selection (CalendarComponentView *component_view)
-{
- GSList *selection, *l, *uids_selected = NULL;
-
- selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
-
- for (l = component_view->source_selection; l; l = l->next) {
- ESource *old_selected_source = l->data;
-
- if (!is_in_selection (selection, old_selected_source))
- gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, old_selected_source);
- }
-
- for (l = selection; l; l = l->next) {
- ESource *selected_source = l->data;
-
- if (gnome_calendar_add_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, selected_source))
- uids_selected = g_slist_append (uids_selected, (gchar *) e_source_peek_uid (selected_source));
- }
-
- e_source_selector_free_selection (component_view->source_selection);
- component_view->source_selection = selection;
-
- /* Save the selection for next time we start up */
- calendar_config_set_calendars_selected (uids_selected);
- g_slist_free (uids_selected);
-}
-
-static void
-update_uri_for_primary_selection (CalendarComponentView *component_view)
-{
- ESource *source;
-
- source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!source)
- return;
-
- /* Set the default */
- gnome_calendar_set_default_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, source);
-
- /* Make sure we are embedded first */
- calendar_control_sensitize_calendar_commands (component_view->view_control, component_view->calendar, TRUE);
-
- /* Save the selection for next time we start up */
- calendar_config_set_primary_calendar (e_source_peek_uid (source));
-}
-
-static void
-update_selection (CalendarComponentView *component_view)
-{
- GSList *selection, *uids_selected, *l;
-
- /* Get the selection in gconf */
- uids_selected = calendar_config_get_calendars_selected ();
-
- /* Remove any that aren't there any more */
- selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
-
- for (l = selection; l; l = l->next) {
- ESource *source = l->data;
-
- if (!is_in_uids (uids_selected, source))
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
- }
-
- e_source_selector_free_selection (selection);
-
- /* Make sure the whole selection is there */
- for (l = uids_selected; l; l = l->next) {
- gchar *uid = l->data;
- ESource *source;
-
- source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
- if (source)
- e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
-
- g_free (uid);
- }
- g_slist_free (uids_selected);
-}
-
-static void
update_task_memo_selection (CalendarComponentView *component_view, ECalSourceType type)
{
GSList *uids_selected, *l, *source_selection;
@@ -471,28 +208,6 @@ update_task_memo_selection (CalendarComponentView *component_view, ECalSourceTyp
}
static void
-update_primary_selection (CalendarComponentView *component_view)
-{
- ESource *source = NULL;
- gchar *uid;
-
- uid = calendar_config_get_primary_calendar ();
- if (uid) {
- source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
- g_free (uid);
- }
-
- if (source) {
- e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source);
- } else {
- /* Try to create a default if there isn't one */
- source = e_source_list_peek_source_any (component_view->source_list);
- if (source)
- e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source);
- }
-}
-
-static void
update_primary_task_memo_selection (CalendarComponentView *component_view, ECalSourceType type)
{
ESource *source = NULL;
@@ -517,314 +232,6 @@ update_primary_task_memo_selection (CalendarComponentView *component_view, ECalS
gnome_calendar_set_default_source (component_view->calendar, type, source);
}
-/* Callbacks. */
-static void
-copy_calendar_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- CalendarComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel (ep->target->widget)), selected_source, E_CAL_SOURCE_TYPE_EVENT);
-}
-
-static void
-delete_calendar_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- CalendarComponentView *component_view = data;
- ESource *selected_source;
- ECal *cal;
- gchar *uri;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- if (e_error_run((GtkWindow *)gtk_widget_get_toplevel(ep->target->widget),
- "calendar:prompt-delete-calendar", e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES)
- return;
-
- /* first, ask the backend to remove the calendar */
- uri = e_source_get_uri (selected_source);
- cal = e_cal_model_get_client_for_uri (gnome_calendar_get_calendar_model (component_view->calendar), uri);
- if (!cal)
- cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_EVENT);
- g_free (uri);
- if (cal) {
- if (e_cal_remove (cal, NULL)) {
- if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source)) {
- gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, selected_source);
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source);
- }
-
- e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
- e_source_list_sync (component_view->source_list, NULL);
- }
- }
-}
-
-static void
-new_calendar_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- calendar_setup_edit_calendar (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), NULL, pitem->user_data);
-}
-
-static void
-rename_calendar_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- CalendarComponentView *component_view = data;
- ESourceSelector *selector;
-
- selector = E_SOURCE_SELECTOR (component_view->source_selector);
- e_source_selector_edit_primary_selection (selector);
-}
-
-static void
-edit_calendar_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- CalendarComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- calendar_setup_edit_calendar (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source, NULL);
-}
-
-static void
-set_offline_availability (EPopup *ep, EPopupItem *pitem, gpointer data, const gchar *value)
-{
- CalendarComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- e_source_set_property (selected_source, "offline_sync", value);
-}
-
-static void
-mark_no_offline_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- set_offline_availability (ep, pitem, data, "0");
-}
-
-static void
-mark_offline_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- set_offline_availability (ep, pitem, data, "1");
-}
-
-static EPopupItem ecc_source_popups[] = {
- { E_POPUP_ITEM, (gchar *) "10.new", (gchar *) N_("_New Calendar"), new_calendar_cb, NULL, (gchar *) "x-office-calendar", 0, 0 },
- { E_POPUP_ITEM, (gchar *) "15.copy", (gchar *) N_("_Copy..."), copy_calendar_cb, NULL, (gchar *) "edit-copy", 0, E_CAL_POPUP_SOURCE_PRIMARY },
- { E_POPUP_ITEM, (gchar *) "18.rename", (gchar *) N_("_Rename..."), rename_calendar_cb, NULL, NULL, 0, E_CAL_POPUP_SOURCE_PRIMARY },
-
- { E_POPUP_BAR, (gchar *) "20.bar" },
- { E_POPUP_ITEM, (gchar *) "20.delete", (gchar *) N_("_Delete"), delete_calendar_cb, NULL, (gchar *) "edit-delete", 0,E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_DELETE },
- { E_POPUP_ITEM, (gchar *) "30.mark_calendar_offline", (gchar *) N_("_Make available for offline use"), mark_offline_cb, NULL, (gchar *) "stock_disconnect", E_CAL_POPUP_SOURCE_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_OFFLINE },
- { E_POPUP_ITEM, (gchar *) "40.mark_calendar_no_offline", (gchar *) N_("_Do not make available for offline use"), mark_no_offline_cb, NULL, (gchar *) "stock_connect", E_CAL_POPUP_SOURCE_NO_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_NO_OFFLINE },
-
- { E_POPUP_BAR, (gchar *) "99.bar" },
- { E_POPUP_ITEM, (gchar *) "99.properties", (gchar *) N_("_Properties"), edit_calendar_cb, NULL, (gchar *) "document-properties", 0, E_CAL_POPUP_SOURCE_PRIMARY },
-};
-
-static void
-ecc_source_popup_free(EPopup *ep, GSList *list, gpointer data)
-{
- g_slist_free(list);
-}
-
-static gboolean
-popup_event_cb(ESourceSelector *selector, ESource *insource, GdkEventButton *event, CalendarComponentView *component_view)
-{
- ECalPopup *ep;
- ECalPopupTargetSource *t;
- GSList *menus = NULL;
- gint i;
- GtkMenu *menu;
-
- /** @HookPoint-ECalPopup: Calendar Source Selector Context Menu
- * @Id: org.gnome.evolution.calendar.source.popup
- * @Class: org.gnome.evolution.calendar.popup:1.0
- * @Target: ECalPopupTargetSource
- *
- * The context menu on the source selector in the calendar window.
- */
- ep = e_cal_popup_new("org.gnome.evolution.calendar.source.popup");
- t = e_cal_popup_target_new_source(ep, selector);
- t->target.widget = (GtkWidget *)component_view->calendar;
-
- for (i=0;i<sizeof(ecc_source_popups)/sizeof(ecc_source_popups[0]);i++)
- menus = g_slist_prepend(menus, &ecc_source_popups[i]);
-
- e_popup_add_items((EPopup *)ep, menus, NULL, ecc_source_popup_free, component_view);
-
- menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time());
-
- return TRUE;
-}
-
-static void
-source_selection_changed_cb (ESourceSelector *selector, CalendarComponentView *component_view)
-{
- update_uris_for_selection (component_view);
-}
-
-static void
-primary_source_selection_changed_cb (ESourceSelector *selector, CalendarComponentView *component_view)
-{
- update_uri_for_primary_selection (component_view);
-}
-
-static void
-source_changed_cb (ESource *source, GnomeCalendar *calendar)
-{
- if (calendar) {
- GtkWidget *widget = gnome_calendar_get_current_view_widget (calendar);
-
- if (widget)
- gtk_widget_queue_draw (widget);
- }
-}
-
-static void
-source_added_cb (GnomeCalendar *calendar, ECalSourceType source_type, ESource *source, CalendarComponentView *component_view)
-{
- switch (source_type) {
- case E_CAL_SOURCE_TYPE_EVENT:
- e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
- g_signal_connect (source, "changed", G_CALLBACK (source_changed_cb), calendar);
- break;
- default:
- break;
- }
-}
-
-static void
-source_removed_cb (GnomeCalendar *calendar, ECalSourceType source_type, ESource *source, CalendarComponentView *component_view)
-{
- switch (source_type) {
- case E_CAL_SOURCE_TYPE_EVENT:
- g_signal_handlers_disconnect_by_func (source, G_CALLBACK (source_changed_cb), calendar);
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
- break;
- default:
- break;
- }
-}
-
-static void
-set_info (CalendarComponentView *component_view)
-{
- icaltimezone *zone;
- struct icaltimetype start_tt, end_tt;
- time_t start_time, end_time;
- struct tm start_tm, end_tm;
- gchar buffer[512], end_buffer[256];
- GnomeCalendarViewType view;
-
- gnome_calendar_get_visible_time_range (component_view->calendar, &start_time, &end_time);
- zone = gnome_calendar_get_timezone (component_view->calendar);
-
- start_tt = icaltime_from_timet_with_zone (start_time, FALSE, zone);
- start_tm.tm_year = start_tt.year - 1900;
- start_tm.tm_mon = start_tt.month - 1;
- start_tm.tm_mday = start_tt.day;
- start_tm.tm_hour = start_tt.hour;
- start_tm.tm_min = start_tt.minute;
- start_tm.tm_sec = start_tt.second;
- start_tm.tm_isdst = -1;
- start_tm.tm_wday = time_day_of_week (start_tt.day, start_tt.month - 1,
- start_tt.year);
-
- /* Take one off end_time so we don't get an extra day. */
- end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, zone);
- end_tm.tm_year = end_tt.year - 1900;
- end_tm.tm_mon = end_tt.month - 1;
- end_tm.tm_mday = end_tt.day;
- end_tm.tm_hour = end_tt.hour;
- end_tm.tm_min = end_tt.minute;
- end_tm.tm_sec = end_tt.second;
- end_tm.tm_isdst = -1;
- end_tm.tm_wday = time_day_of_week (end_tt.day, end_tt.month - 1,
- end_tt.year);
-
- view = gnome_calendar_get_view (component_view->calendar);
-
- switch (view) {
- case GNOME_CAL_DAY_VIEW:
- case GNOME_CAL_WORK_WEEK_VIEW:
- case GNOME_CAL_WEEK_VIEW:
- if (start_tm.tm_year == end_tm.tm_year
- && start_tm.tm_mon == end_tm.tm_mon
- && start_tm.tm_mday == end_tm.tm_mday) {
- e_utf8_strftime (buffer, sizeof (buffer),
- _("%A %d %b %Y"), &start_tm);
- } else if (start_tm.tm_year == end_tm.tm_year) {
- e_utf8_strftime (buffer, sizeof (buffer),
- _("%a %d %b"), &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer),
- _("%a %d %b %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- } else {
- e_utf8_strftime (buffer, sizeof (buffer),
- _("%a %d %b %Y"), &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer),
- _("%a %d %b %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- }
- break;
- case GNOME_CAL_MONTH_VIEW:
- case GNOME_CAL_LIST_VIEW:
- if (start_tm.tm_year == end_tm.tm_year) {
- if (start_tm.tm_mon == end_tm.tm_mon) {
- e_utf8_strftime (buffer, sizeof (buffer),
- "%d", &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer),
- _("%d %b %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- } else {
- e_utf8_strftime (buffer, sizeof (buffer),
- _("%d %b"), &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer),
- _("%d %b %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- }
- } else {
- e_utf8_strftime (buffer, sizeof (buffer),
- _("%d %b %Y"), &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer),
- _("%d %b %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- }
- break;
- default:
- g_return_if_reached ();
- }
-
- e_info_label_set_info (component_view->info_label, _("Calendars"), buffer);
-}
-
-static void
-calendar_dates_changed_cb (GnomeCalendar *calendar, CalendarComponentView *component_view)
-{
- set_info (component_view);
-}
-
static void
config_primary_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
{
@@ -930,8 +337,7 @@ impl_handleURI (PortableServer_Servant servant, const gchar *uri, CORBA_Environm
if (start != -1) {
if (end == -1)
- end = start;
- gnome_calendar_set_selected_time_range (view->calendar, start, end);
+ gnome_calendar_set_selected_time_range (view->calendar, start);
}
if (src_uid && uid)
gnome_calendar_edit_appointment (view->calendar, src_uid, uid, rid);
@@ -945,84 +351,6 @@ impl_handleURI (PortableServer_Servant servant, const gchar *uri, CORBA_Environm
}
static void
-impl_upgradeFromVersion (PortableServer_Servant servant,
- CORBA_short major,
- CORBA_short minor,
- CORBA_short revision,
- CORBA_Environment *ev)
-{
- GError *err = NULL;
- CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant));
-
- if (!migrate_calendars (calendar_component, major, minor, revision, &err)) {
- GNOME_Evolution_Component_UpgradeFailed *failedex;
-
- failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
- failedex->what = CORBA_string_dup(_("Failed upgrading calendars."));
- failedex->why = CORBA_string_dup(err->message);
- CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
- }
-
- if (err)
- g_error_free(err);
-}
-
-static gboolean
-selector_tree_data_dropped (ESourceSelector *selector,
- GtkSelectionData *data,
- ESource *destination,
- GdkDragAction action,
- guint info,
- CalendarComponent *component)
-{
- gboolean success = FALSE;
- ECal *client;
-
- client = auth_new_cal_from_source (destination, E_CAL_SOURCE_TYPE_EVENT);
-
- if (!client || !e_cal_open (client, TRUE, NULL)) {
- if (client)
- g_object_unref (client);
-
- return FALSE;
- }
-
- if (data->data) {
- icalcomponent *icalcomp = NULL;
- gchar *comp_str; /* do not free this! */
-
- /* data->data is "source_uid\ncomponent_string" */
- comp_str = strchr ((gchar *)data->data, '\n');
- if (comp_str) {
- comp_str [0] = 0;
- comp_str++;
-
- icalcomp = icalparser_parse_string (comp_str);
-
- if (icalcomp) {
- success = cal_comp_process_source_list_drop (client, icalcomp, action, (gchar *)data->data, component->priv->source_list);
- icalcomponent_free (icalcomp);
- }
- }
- }
-
- return success;
-}
-
-static void
-control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
-{
- CalendarComponentView *component_view = data;
-
- if (activate) {
- BonoboUIComponent *uic;
- uic = bonobo_control_get_ui_component (component_view->view_control);
-
- e_user_creatable_items_handler_activate (component_view->creatable_items_handler, uic);
- }
-}
-
-static void
config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
{
CalendarComponent *calendar_component = data;
@@ -1120,79 +448,13 @@ setup_create_ecal (CalendarComponent *calendar_component, CalendarComponentView
return priv->create_ecal;
}
-static gboolean
-create_new_event (CalendarComponent *calendar_component, CalendarComponentView *component_view, gboolean is_allday, gboolean is_meeting)
-{
- ECal *ecal;
- ECalendarView *view;
-
- ecal = setup_create_ecal (calendar_component, component_view);
- if (!ecal)
- return FALSE;
-
- if (component_view && (view = E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (component_view->calendar)))) {
- e_calendar_view_new_appointment_full (view, is_allday, is_meeting, TRUE);
- } else {
- ECalComponent *comp;
- CompEditor *editor;
- CompEditorFlags flags;
-
- flags = COMP_EDITOR_USER_ORG | COMP_EDITOR_NEW_ITEM;
- if (is_meeting)
- flags |= COMP_EDITOR_MEETING;
- comp = cal_comp_event_new_with_current_time (ecal, is_allday);
- editor = event_editor_new (ecal, flags);
- e_cal_component_commit_sequence (comp);
-
- comp_editor_edit_comp (editor, comp);
- if (is_meeting)
- event_editor_show_meeting (EVENT_EDITOR (editor));
- gtk_window_present (GTK_WINDOW (editor));
-
- e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
- }
-
- return TRUE;
-}
-
-static void
-create_local_item_cb (EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data)
-{
- CalendarComponent *calendar_component = data;
- CalendarComponentPrivate *priv;
- CalendarComponentView *component_view = NULL;
- GList *l;
-
- priv = calendar_component->priv;
-
- for (l = priv->views; l; l = l->next) {
- component_view = l->data;
-
- if (component_view->creatable_items_handler == handler)
- break;
-
- component_view = NULL;
- }
-
- if (strcmp (item_type_name, CREATE_EVENT_ID) == 0)
- create_new_event (calendar_component, component_view, FALSE, FALSE);
- else if (strcmp (item_type_name, CREATE_ALLDAY_EVENT_ID) == 0)
- create_new_event (calendar_component, component_view, TRUE, FALSE);
- else if (strcmp (item_type_name, CREATE_MEETING_ID) == 0)
- create_new_event (calendar_component, component_view, FALSE, TRUE);
- else if (strcmp (item_type_name, CREATE_CALENDAR_ID) == 0)
- calendar_setup_new_calendar (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->calendar))));
-}
-
static CalendarComponentView *
create_component_view (CalendarComponent *calendar_component)
{
CalendarComponentPrivate *priv;
CalendarComponentView *component_view;
- GtkWidget *selector_scrolled_window, *vbox, *vpane;
- GtkWidget *statusbar_widget;
+ GtkWidget **vpane;
guint not;
- AtkObject *a11y;
priv = calendar_component->priv;
@@ -1209,14 +471,8 @@ create_component_view (CalendarComponent *calendar_component)
component_view->source_list = g_object_ref (priv->source_list);
component_view->task_source_list = g_object_ref (priv->task_source_list);
component_view->memo_source_list = g_object_ref (priv->memo_source_list);
- component_view->vpane_pos = calendar_config_get_tag_vpane_pos ();
-
/* Create sidebar selector */
component_view->source_selector = e_source_selector_new (calendar_component->priv->source_list);
- e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE);
- a11y = gtk_widget_get_accessible (GTK_WIDGET (component_view->source_selector));
- atk_object_set_name (a11y, _("Calendar Source Selector"));
-
g_signal_connect (
component_view->source_selector, "data-dropped",
G_CALLBACK (selector_tree_data_dropped), calendar_component);
@@ -1286,18 +542,11 @@ create_component_view (CalendarComponent *calendar_component)
g_signal_connect (component_view->source_selector, "popup_event",
G_CALLBACK (popup_event_cb), component_view);
+>>>>>>> 23df769955ea54f756a579c19964df87ae6fd5c8:calendar/gui/calendar-component.c
/* Set up the "new" item handler */
- component_view->creatable_items_handler = e_user_creatable_items_handler_new ("calendar", create_local_item_cb, calendar_component);
g_signal_connect (component_view->view_control, "activate", G_CALLBACK (control_activate_cb), component_view);
- /* We use this to update the component information */
- set_info (component_view);
- g_signal_connect (component_view->calendar, "dates_shown_changed",
- G_CALLBACK (calendar_dates_changed_cb), component_view);
-
/* Load the selection from the last run */
- update_selection (component_view);
- update_primary_selection (component_view);
update_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_TODO);
update_primary_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_TODO);
update_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_JOURNAL);
@@ -1345,12 +594,6 @@ destroy_component_view (CalendarComponentView *component_view)
calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
g_list_free (component_view->notifications);
- if (component_view->creatable_items_handler)
- g_object_unref (component_view->creatable_items_handler);
-
- if (component_view->activity_handler)
- g_object_unref (component_view->activity_handler);
-
if (component_view->task_source_selection) {
g_slist_foreach (component_view->task_source_selection, (GFunc) g_free, NULL);
g_slist_free (component_view->task_source_selection);
@@ -1385,109 +628,6 @@ view_destroyed_cb (gpointer data, GObject *where_the_object_was)
}
}
-static GNOME_Evolution_ComponentView
-impl_createView (PortableServer_Servant servant,
- GNOME_Evolution_ShellView parent,
- CORBA_boolean select_item,
- CORBA_Environment *ev)
-{
- CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant));
- CalendarComponentPrivate *priv;
- CalendarComponentView *component_view;
- EComponentView *ecv;
-
- priv = calendar_component->priv;
-
- /* Create the calendar component view */
- component_view = create_component_view (calendar_component);
- if (!component_view) {
- /* FIXME Should we describe the problem in a control? */
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
-
- return CORBA_OBJECT_NIL;
- }
-
- g_object_weak_ref (G_OBJECT (component_view->view_control), view_destroyed_cb, calendar_component);
- priv->views = g_list_append (priv->views, component_view);
-
- /* TODO: Make CalendarComponentView just subclass EComponentView */
- ecv = e_component_view_new_controls (parent, "calendar", component_view->sidebar_control,
- component_view->view_control, component_view->statusbar_control);
-
- return BONOBO_OBJREF(ecv);
-}
-
-static GNOME_Evolution_CreatableItemTypeList *
-impl__get_userCreatableItems (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
-
- list->_length = 4;
- list->_maximum = list->_length;
- list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
-
- CORBA_sequence_set_release (list, FALSE);
-
- list->_buffer[0].id = (gchar *) CREATE_EVENT_ID;
- list->_buffer[0].description = (gchar *) _("New appointment");
- list->_buffer[0].menuDescription = (gchar *) C_("New", "_Appointment");
- list->_buffer[0].tooltip = (gchar *) _("Create a new appointment");
- list->_buffer[0].menuShortcut = 'a';
- list->_buffer[0].iconName = (gchar *) "appointment-new";
- list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[1].id = (gchar *) CREATE_MEETING_ID;
- list->_buffer[1].description = (gchar *) _("New meeting");
- list->_buffer[1].menuDescription = (gchar *) C_("New", "M_eeting");
- list->_buffer[1].tooltip = (gchar *) _("Create a new meeting request");
- list->_buffer[1].menuShortcut = 'e';
- list->_buffer[1].iconName = (gchar *) "stock_new-meeting";
- list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[2].id = (gchar *) CREATE_ALLDAY_EVENT_ID;
- list->_buffer[2].description = (gchar *) _("New all day appointment");
- list->_buffer[2].menuDescription = (gchar *) C_("New", "All Day A_ppointment");
- list->_buffer[2].tooltip = (gchar *) _("Create a new all-day appointment");
- list->_buffer[2].menuShortcut = '\0';
- list->_buffer[2].iconName = (gchar *) "stock_new-24h-appointment";
- list->_buffer[2].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[3].id = (gchar *) CREATE_CALENDAR_ID;
- list->_buffer[3].description = (gchar *) _("New calendar");
- list->_buffer[3].menuDescription = (gchar *) C_("New", "Cale_ndar");
- list->_buffer[3].tooltip = (gchar *) _("Create a new calendar");
- list->_buffer[3].menuShortcut = '\0';
- list->_buffer[3].iconName = (gchar *) "x-office-calendar";
- list->_buffer[3].type = GNOME_Evolution_CREATABLE_FOLDER;
-
- return list;
-}
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
- const CORBA_char *item_type_name,
- CORBA_Environment *ev)
-{
- CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant));
- gboolean result = FALSE;
-
- if (strcmp (item_type_name, CREATE_EVENT_ID) == 0)
- result = create_new_event (calendar_component, NULL, FALSE, FALSE);
- else if (strcmp (item_type_name, CREATE_ALLDAY_EVENT_ID) == 0)
- result = create_new_event (calendar_component, NULL, TRUE, FALSE);
- else if (strcmp (item_type_name, CREATE_MEETING_ID) == 0)
- result = create_new_event (calendar_component, NULL, FALSE, TRUE);
- else if (strcmp (item_type_name, CREATE_CALENDAR_ID) == 0)
- /* FIXME Should we use the last opened window? */
- calendar_setup_new_calendar (NULL);
- else
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType);
-
- if (!result)
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
-}
-
/* GObject methods. */
static void
@@ -1502,9 +642,9 @@ impl_dispose (GObject *object)
priv->source_list = NULL;
}
- if (priv->gconf_client != NULL) {
- g_object_unref (priv->gconf_client);
- priv->gconf_client = NULL;
+ if (priv->activity_handler != NULL) {
+ g_object_unref (priv->activity_handler);
+ priv->activity_handler = NULL;
}
if (priv->activity_handler != NULL) {
@@ -1534,27 +674,6 @@ impl_dispose (GObject *object)
}
static void
-impl_finalize (GObject *object)
-{
- CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv;
- GList *l;
-
- for (l = priv->views; l; l = l->next) {
- CalendarComponentView *component_view = l->data;
-
- destroy_component_view (component_view);
- }
- g_list_free (priv->views);
-
- g_free (priv->base_directory);
- g_free (priv->config_directory);
- g_object_unref (priv->logger);
- g_free (priv);
-
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-static void
calendar_component_class_init (CalendarComponentClass *class)
{
POA_GNOME_Evolution_Component__epv *epv = &class->epv;
@@ -1565,17 +684,9 @@ calendar_component_class_init (CalendarComponentClass *class)
parent_class = g_type_class_peek_parent (class);
- epv->upgradeFromVersion = impl_upgradeFromVersion;
- epv->createView = impl_createView;
- epv->_get_userCreatableItems = impl__get_userCreatableItems;
- epv->requestCreateItem = impl_requestCreateItem;
epv->handleURI = impl_handleURI;
object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- /* Register attachment handler types. */
- e_attachment_handler_calendar_get_type ();
}
static void
@@ -1584,15 +695,6 @@ calendar_component_init (CalendarComponent *component)
CalendarComponentPrivate *priv;
guint not;
- priv = g_new0 (CalendarComponentPrivate, 1);
-
- priv->base_directory = g_build_filename (e_get_user_data_dir (), "calendar", NULL);
- priv->config_directory = g_build_filename (priv->base_directory, "config", NULL);
-
- /* EPFIXME: Should use a custom one instead? Also we should add
- * calendar_component_peek_gconf_client(). */
- priv->gconf_client = gconf_client_get_default ();
-
not = calendar_config_add_notification_primary_calendar (config_primary_selection_changed_cb,
component);
priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
@@ -1603,67 +705,7 @@ calendar_component_init (CalendarComponent *component)
e_activity_handler_set_error_flush_time (priv->activity_handler,eni_config_get_error_timeout (CALENDAR_ERROR_TIME_OUT_KEY)*1000);
component->priv = priv;
- ensure_sources (component);
e_cal_get_sources (&priv->task_source_list, E_CAL_SOURCE_TYPE_TODO, NULL);
e_cal_get_sources (&priv->memo_source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL);
}
-
-/* Public API. */
-
-CalendarComponent *
-calendar_component_peek (void)
-{
- static CalendarComponent *component = NULL;
-
- if (component == NULL) {
- component = g_object_new (calendar_component_get_type (), NULL);
-
- if (g_mkdir_with_parents (calendar_component_peek_config_directory (component), 0777) != 0) {
- g_warning (G_STRLOC ": Cannot create directory %s: %s",
- calendar_component_peek_config_directory (component),
- g_strerror (errno));
- g_object_unref (component);
- component = NULL;
- }
- }
-
- return component;
-}
-
-const gchar *
-calendar_component_peek_base_directory (CalendarComponent *component)
-{
- return component->priv->base_directory;
-}
-
-const gchar *
-calendar_component_peek_config_directory (CalendarComponent *component)
-{
- return component->priv->config_directory;
-}
-
-ESourceList *
-calendar_component_peek_source_list (CalendarComponent *component)
-{
- return component->priv->source_list;
-}
-
-EActivityHandler *
-calendar_component_peek_activity_handler (CalendarComponent *component)
-{
- CALENDAR_COMPONENT_DEFAULT(component);
-
- return component->priv->activity_handler;
-}
-
-void
-calendar_component_show_logger (gpointer top)
-{
- CalendarComponent *cc = calendar_component_peek ();
- ELogger *logger = cc->priv->logger;
-
- eni_show_logger(logger, top, CALENDAR_ERROR_TIME_OUT_KEY, CALENDAR_ERROR_LEVEL_KEY);
-}
-
-BONOBO_TYPE_FUNC_FULL (CalendarComponent, GNOME_Evolution_Component, PARENT_TYPE, calendar_component)
diff --git a/calendar/gui/calendar-component.h b/calendar/gui/calendar-component.h
index 480b0c4c93..fbdd8efd23 100644
--- a/calendar/gui/calendar-component.h
+++ b/calendar/gui/calendar-component.h
@@ -52,12 +52,4 @@ struct _CalendarComponentClass {
GType calendar_component_get_type (void);
-CalendarComponent *calendar_component_peek (void);
-
-const gchar *calendar_component_peek_base_directory (CalendarComponent *component);
-const gchar *calendar_component_peek_config_directory (CalendarComponent *component);
-ESourceList *calendar_component_peek_source_list (CalendarComponent *component);
-EActivityHandler *calendar_component_peek_activity_handler (CalendarComponent *component);
-void calendar_component_show_logger (gpointer);
-
#endif /* _CALENDAR_COMPONENT_H_ */
diff --git a/calendar/gui/calendar-config-keys.h b/calendar/gui/calendar-config-keys.h
index 7210e83834..9afa8dc7e4 100644
--- a/calendar/gui/calendar-config-keys.h
+++ b/calendar/gui/calendar-config-keys.h
@@ -28,18 +28,10 @@ G_BEGIN_DECLS
#define CALENDAR_CONFIG_PREFIX "/apps/evolution/calendar"
/* Display settings */
-#define CALENDAR_CONFIG_USE_SYSTEM_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/use_system_timezone"
#define CALENDAR_CONFIG_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/timezone"
#define CALENDAR_CONFIG_SELECTED_CALENDARS CALENDAR_CONFIG_PREFIX "/display/selected_calendars"
-#define CALENDAR_CONFIG_PRIMARY_CALENDAR CALENDAR_CONFIG_PREFIX "/display/primary_calendar"
#define CALENDAR_CONFIG_24HOUR CALENDAR_CONFIG_PREFIX "/display/use_24hour_format"
#define CALENDAR_CONFIG_SHOW_ATTENDEE CALENDAR_CONFIG_PREFIX "/display/show_attendee"
-#define CALENDAR_CONFIG_SHOW_ROLE CALENDAR_CONFIG_PREFIX "/display/show_role"
-#define CALENDAR_CONFIG_SHOW_STATUS CALENDAR_CONFIG_PREFIX "/display/show_status"
-#define CALENDAR_CONFIG_SHOW_TYPE CALENDAR_CONFIG_PREFIX "/display/show_type"
-#define CALENDAR_CONFIG_SHOW_RSVP CALENDAR_CONFIG_PREFIX "/display/show_rsvp"
-#define CALENDAR_CONFIG_SHOW_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/show_timezone"
-#define CALENDAR_CONFIG_SHOW_CATEGORIES CALENDAR_CONFIG_PREFIX "/display/show_categories"
#define CALENDAR_CONFIG_WEEK_START CALENDAR_CONFIG_PREFIX "/display/week_start_day"
#define CALENDAR_CONFIG_DAY_START_HOUR CALENDAR_CONFIG_PREFIX "/display/day_start_hour"
#define CALENDAR_CONFIG_DAY_START_MINUTE CALENDAR_CONFIG_PREFIX "/display/day_start_minute"
diff --git a/calendar/gui/calendar-config.c b/calendar/gui/calendar-config.c
index 9262836d32..3208fb5f5b 100644
--- a/calendar/gui/calendar-config.c
+++ b/calendar/gui/calendar-config.c
@@ -29,12 +29,13 @@
#include <config.h>
#endif
-#include <string.h>
#include <time.h>
-#include <libedataserver/e-data-server-util.h>
+#include <string.h>
#include <e-util/e-util.h>
-#include <widgets/e-timezone-dialog/e-timezone-dialog.h>
#include <libecal/e-cal-time-util.h>
+#include <libedataserver/e-data-server-util.h>
+#include <widgets/e-timezone-dialog/e-timezone-dialog.h>
+#include <shell/e-shell.h>
#include "calendar-config-keys.h"
#include "calendar-config.h"
@@ -155,85 +156,33 @@ calendar_config_add_notification_calendars_selected (GConfClientNotifyFunc func,
return id;
}
-/* The primary calendar */
-gchar *
-calendar_config_get_primary_calendar (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_string (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, NULL);
-}
-
-void
-calendar_config_set_primary_calendar (const gchar *primary_uid)
-{
- calendar_config_init ();
-
- gconf_client_set_string (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, primary_uid, NULL);
-}
-
-guint
-calendar_config_add_notification_primary_calendar (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, func, data, NULL, NULL);
-
- return id;
-}
-
-gboolean
-calendar_config_get_use_system_timezone (void)
+static gchar *
+calendar_config_get_timezone_stored (void)
{
calendar_config_init ();
- return gconf_client_get_bool (config, CALENDAR_CONFIG_USE_SYSTEM_TIMEZONE, NULL);
+ return gconf_client_get_string (config, CALENDAR_CONFIG_TIMEZONE, NULL);
}
-void
-calendar_config_set_use_system_timezone (gboolean use)
+static gchar *
+calendar_config_get_timezone (void)
{
- calendar_config_init ();
-
- if (calendar_config_get_use_system_timezone () != use) {
- gconf_client_set_bool (config, CALENDAR_CONFIG_USE_SYSTEM_TIMEZONE, use, NULL);
- gconf_client_notify (config, CALENDAR_CONFIG_TIMEZONE);
+ EShell *shell;
+ EShellSettings *shell_settings;
+ gboolean use_system_timezone;
- /* FIXME: notify CALENDAR_CONFIG_TIMEZONE change on system timezone change
- itself too, when using system timezone. How to receive such change? */
- }
-}
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
-guint
-calendar_config_add_notification_use_system_timezone (GConfClientNotifyFunc func, gpointer data)
-{
- calendar_config_init ();
+ use_system_timezone = e_shell_settings_get_boolean (
+ shell_settings, "cal-use-system-timezone");
- return gconf_client_notify_add (config, CALENDAR_CONFIG_USE_SYSTEM_TIMEZONE, func, data, NULL, NULL);
-}
-
-/* The current timezone, e.g. "Europe/London". It may be NULL, in which case
- you should assume UTC (though Evolution will show the timezone-setting
- dialog the next time a calendar or task folder is selected). */
-gchar *
-calendar_config_get_timezone (void)
-{
- if (calendar_config_get_use_system_timezone ())
+ if (use_system_timezone)
return e_cal_util_get_system_timezone_location ();
return calendar_config_get_timezone_stored ();
}
-gchar *
-calendar_config_get_timezone_stored (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_string (config, CALENDAR_CONFIG_TIMEZONE, NULL);
-}
-
icaltimezone *
calendar_config_get_icaltimezone (void)
{
@@ -251,31 +200,6 @@ calendar_config_get_icaltimezone (void)
return zone;
}
-/* Sets the timezone. If set to NULL it defaults to UTC.
- FIXME: Should check it is being set to a valid timezone. */
-void
-calendar_config_set_timezone (const gchar *timezone)
-{
- calendar_config_init ();
-
- if (timezone && timezone[0])
- gconf_client_set_string (config, CALENDAR_CONFIG_TIMEZONE, timezone, NULL);
- else
- gconf_client_set_string (config, CALENDAR_CONFIG_TIMEZONE, "UTC", NULL);
-}
-
-guint
-calendar_config_add_notification_timezone (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_TIMEZONE, func, data, NULL, NULL);
-
- return id;
-}
-
/* Whether we use 24-hour format or 12-hour format (AM/PM). */
gboolean
calendar_config_get_24_hour_format (void)
@@ -292,126 +216,6 @@ calendar_config_get_24_hour_format (void)
return TRUE;
}
-void
-calendar_config_set_24_hour_format (gboolean use_24_hour)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_24HOUR, use_24_hour, NULL);
-}
-
-guint
-calendar_config_add_notification_24_hour_format (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_24HOUR, func, data, NULL, NULL);
-
- return id;
-}
-
-/* Show RSVP*/
-gboolean
-calendar_config_get_show_rsvp (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_RSVP, NULL);
-}
-
-void
-calendar_config_set_show_rsvp (gboolean state)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_RSVP, state, NULL);
-}
-
-/* Show Role*/
-gboolean
-calendar_config_get_show_role (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_ROLE, NULL);
-}
-
-void
-calendar_config_set_show_role (gboolean state)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_ROLE, state, NULL);
-}
-
-/* Show Type*/
-gboolean
-calendar_config_get_show_type (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_TYPE, NULL);
-}
-
-void
-calendar_config_set_show_type (gboolean state)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_TYPE, state, NULL);
-}
-
-/* Show status */
-gboolean
-calendar_config_get_show_status (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_STATUS, NULL);
-}
-
-void
-calendar_config_set_show_status (gboolean state)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_STATUS, state, NULL);
-}
-
-/* Show timezone */
-gboolean
-calendar_config_get_show_timezone (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_TIMEZONE, NULL);
-}
-
-void
-calendar_config_set_show_timezone (gboolean status)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_TIMEZONE, status, NULL);
-}
-
-gboolean
-calendar_config_get_show_categories (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_CATEGORIES, NULL);
-}
-void
-calendar_config_set_show_categories (gboolean status)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_CATEGORIES, status, NULL);
-}
-
/* The start day of the week (0 = Sun to 6 = Mon). */
gint
calendar_config_get_week_start_day (void)
@@ -421,26 +225,6 @@ calendar_config_get_week_start_day (void)
return gconf_client_get_int (config, CALENDAR_CONFIG_WEEK_START, NULL);
}
-void
-calendar_config_set_week_start_day (gint week_start_day)
-{
- calendar_config_init ();
-
- gconf_client_set_int (config, CALENDAR_CONFIG_WEEK_START, week_start_day, NULL);
-}
-
-guint
-calendar_config_add_notification_week_start_day (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_WEEK_START, func, data, NULL, NULL);
-
- return id;
-}
-
/* The start and end times of the work-day. */
gint
calendar_config_get_day_start_hour (void)
@@ -458,18 +242,6 @@ calendar_config_set_day_start_hour (gint day_start_hour)
gconf_client_set_int (config, CALENDAR_CONFIG_DAY_START_HOUR, day_start_hour, NULL);
}
-guint
-calendar_config_add_notification_day_start_hour (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_START_HOUR, func, data, NULL, NULL);
-
- return id;
-}
-
gint
calendar_config_get_day_start_minute (void)
{
@@ -486,18 +258,6 @@ calendar_config_set_day_start_minute (gint day_start_min)
gconf_client_set_int (config, CALENDAR_CONFIG_DAY_START_MINUTE, day_start_min, NULL);
}
-guint
-calendar_config_add_notification_day_start_minute (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_START_MINUTE, func, data, NULL, NULL);
-
- return id;
-}
-
gint
calendar_config_get_day_end_hour (void)
{
@@ -514,18 +274,6 @@ calendar_config_set_day_end_hour (gint day_end_hour)
gconf_client_set_int (config, CALENDAR_CONFIG_DAY_END_HOUR, day_end_hour, NULL);
}
-guint
-calendar_config_add_notification_day_end_hour (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_END_HOUR, func, data, NULL, NULL);
-
- return id;
-}
-
gint
calendar_config_get_day_end_minute (void)
{
@@ -542,18 +290,6 @@ calendar_config_set_day_end_minute (gint day_end_min)
gconf_client_set_int (config, CALENDAR_CONFIG_DAY_END_MINUTE, day_end_min, NULL);
}
-guint
-calendar_config_add_notification_day_end_minute (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_END_MINUTE, func, data, NULL, NULL);
-
- return id;
-}
-
/* The time divisions in the Day/Work-Week view in minutes (5/10/15/30/60). */
gint
calendar_config_get_time_divisions (void)
@@ -612,66 +348,6 @@ calendar_config_add_notification_month_scroll_by_week (GConfClientNotifyFunc fun
return id;
}
-/* Whether we show the Marcus Bains Line (current time), and in what colors. */
-void
-calendar_config_get_marcus_bains (gboolean *show_line, const gchar **dayview_color, const gchar **timebar_color)
-{
- static gchar *dcolor = NULL, *tcolor = NULL;
-
- calendar_config_init ();
-
- if (dcolor)
- g_free (dcolor);
- if (tcolor)
- g_free (tcolor);
-
- dcolor = gconf_client_get_string (config, CALENDAR_CONFIG_MARCUS_BAINS_COLOR_DAYVIEW, NULL);
- tcolor = gconf_client_get_string (config, CALENDAR_CONFIG_MARCUS_BAINS_COLOR_TIMEBAR, NULL);
-
- *show_line = gconf_client_get_bool (config, CALENDAR_CONFIG_MARCUS_BAINS_LINE, NULL);
- *dayview_color = dcolor;
- *timebar_color = tcolor;
-}
-
-void
-calendar_config_add_notification_marcus_bains (GConfClientNotifyFunc func, gpointer data, gint *not_show, gint *not_dcolor, gint *not_tcolor)
-{
- calendar_config_init ();
-
- *not_show = gconf_client_notify_add (config, CALENDAR_CONFIG_MARCUS_BAINS_LINE, func, data, NULL, NULL);
- *not_dcolor = gconf_client_notify_add (config, CALENDAR_CONFIG_MARCUS_BAINS_COLOR_DAYVIEW, func, data, NULL, NULL);
- *not_tcolor = gconf_client_notify_add (config, CALENDAR_CONFIG_MARCUS_BAINS_COLOR_TIMEBAR, func, data, NULL, NULL);
-}
-
-/* Whether we show week number in the Day View. */
-gboolean
-calendar_config_get_dview_show_week_no (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_DV_WEEK_NUMBER, NULL);
-}
-
-void
-calendar_config_set_dview_show_week_no (gboolean show_week_no)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_DV_WEEK_NUMBER, show_week_no, NULL);
-}
-
-guint
-calendar_config_add_notification_dview_show_week_no (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_DV_WEEK_NUMBER, func, data, NULL, NULL);
-
- return id;
-}
-
/* Whether we show week numbers in the Date Navigator. */
gboolean
calendar_config_get_dnav_show_week_no (void)
@@ -681,14 +357,6 @@ calendar_config_get_dnav_show_week_no (void)
return gconf_client_get_bool (config, CALENDAR_CONFIG_DN_SHOW_WEEK_NUMBERS, NULL);
}
-void
-calendar_config_set_dnav_show_week_no (gboolean show_week_no)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_DN_SHOW_WEEK_NUMBERS, show_week_no, NULL);
-}
-
guint
calendar_config_add_notification_dnav_show_week_no (GConfClientNotifyFunc func, gpointer data)
{
@@ -702,14 +370,6 @@ calendar_config_add_notification_dnav_show_week_no (GConfClientNotifyFunc func,
}
/* The positions of the panes in the normal and month views. */
-gint
-calendar_config_get_hpane_pos (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_int (config, CALENDAR_CONFIG_HPANE_POS, NULL);
-}
-
void
calendar_config_set_hpane_pos (gint hpane_pos)
{
@@ -718,58 +378,6 @@ calendar_config_set_hpane_pos (gint hpane_pos)
gconf_client_set_int (config, CALENDAR_CONFIG_HPANE_POS, hpane_pos, NULL);
}
-gint
-calendar_config_get_vpane_pos (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_int (config, CALENDAR_CONFIG_VPANE_POS, NULL);
-}
-
-void
-calendar_config_set_vpane_pos (gint vpane_pos)
-{
- calendar_config_init ();
-
- gconf_client_set_int (config, CALENDAR_CONFIG_VPANE_POS, vpane_pos, NULL);
-}
-
-gboolean
-calendar_config_get_preview_state (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_TASK_PREVIEW, NULL);
-}
-
-void
-calendar_config_set_preview_state (gboolean state)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_TASK_PREVIEW, state, NULL);
-}
-
-guint
-calendar_config_add_notification_preview_state (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_TASK_PREVIEW, func, data, NULL, NULL);
-
- return id;
-}
-
-gint
-calendar_config_get_month_hpane_pos (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_int (config, CALENDAR_CONFIG_MONTH_HPANE_POS, NULL);
-}
-
void
calendar_config_set_month_hpane_pos (gint hpane_pos)
{
@@ -778,38 +386,6 @@ calendar_config_set_month_hpane_pos (gint hpane_pos)
gconf_client_set_int (config, CALENDAR_CONFIG_MONTH_HPANE_POS, hpane_pos, NULL);
}
-gint
-calendar_config_get_month_vpane_pos (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_int (config, CALENDAR_CONFIG_MONTH_VPANE_POS, NULL);
-}
-
-void
-calendar_config_set_month_vpane_pos (gint vpane_pos)
-{
- calendar_config_init ();
-
- gconf_client_set_int (config, CALENDAR_CONFIG_MONTH_VPANE_POS, vpane_pos, NULL);
-}
-
-gfloat
-calendar_config_get_tag_vpane_pos (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_float (config, CALENDAR_CONFIG_TAG_VPANE_POS, NULL);
-}
-
-void
-calendar_config_set_tag_vpane_pos (gfloat vpane_pos)
-{
- calendar_config_init ();
-
- gconf_client_set_float (config, CALENDAR_CONFIG_TAG_VPANE_POS, vpane_pos, NULL);
-}
-
/* The current list of task lists selected */
GSList *
calendar_config_get_tasks_selected (void)
@@ -839,51 +415,6 @@ calendar_config_add_notification_tasks_selected (GConfClientNotifyFunc func, gpo
return id;
}
-/* The primary task list */
-gchar *
-calendar_config_get_primary_tasks (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_string (config, CALENDAR_CONFIG_PRIMARY_TASKS, NULL);
-}
-
-void
-calendar_config_set_primary_tasks (const gchar *primary_uid)
-{
- calendar_config_init ();
-
- gconf_client_set_string (config, CALENDAR_CONFIG_PRIMARY_TASKS, primary_uid, NULL);
-}
-
-guint
-calendar_config_add_notification_primary_tasks (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_PRIMARY_TASKS, func, data, NULL, NULL);
-
- return id;
-}
-
-gint
-calendar_config_get_task_vpane_pos (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_int (config, CALENDAR_CONFIG_TASK_VPANE_POS, NULL);
-}
-
-void
-calendar_config_set_task_vpane_pos (gint vpane_pos)
-{
- calendar_config_init ();
-
- gconf_client_set_int (config, CALENDAR_CONFIG_TASK_VPANE_POS, vpane_pos, NULL);
-}
-
/***************************************/
/* The current list of memo lists selected */
@@ -915,34 +446,6 @@ calendar_config_add_notification_memos_selected (GConfClientNotifyFunc func, gpo
return id;
}
-/* The primary memo list */
-gchar *
-calendar_config_get_primary_memos (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_string (config, CALENDAR_CONFIG_PRIMARY_MEMOS, NULL);
-}
-
-void
-calendar_config_set_primary_memos (const gchar *primary_uid)
-{
- calendar_config_init ();
-
- gconf_client_set_string (config, CALENDAR_CONFIG_PRIMARY_MEMOS, primary_uid, NULL);
-}
-
-guint
-calendar_config_add_notification_primary_memos (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_PRIMARY_MEMOS, func, data, NULL, NULL);
-
- return id;
-}
/***************************************/
/* Whether we compress the weekend in the week/month views. */
@@ -954,55 +457,6 @@ calendar_config_get_compress_weekend (void)
return gconf_client_get_bool (config, CALENDAR_CONFIG_COMPRESS_WEEKEND, NULL);
}
-void
-calendar_config_set_compress_weekend (gboolean compress)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_COMPRESS_WEEKEND, compress, NULL);
-}
-
-guint
-calendar_config_add_notification_compress_weekend (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_COMPRESS_WEEKEND, func, data, NULL, NULL);
-
- return id;
-}
-
-/* Whether we show event end times. */
-gboolean
-calendar_config_get_show_event_end (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_EVENT_END, NULL);
-}
-
-void
-calendar_config_set_show_event_end (gboolean show_end)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_EVENT_END, show_end, NULL);
-}
-
-guint
-calendar_config_add_notification_show_event_end (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_SHOW_EVENT_END, func, data, NULL, NULL);
-
- return id;
-}
-
/* The working days of the week, a bit-wise combination of flags. */
CalWeekdays
calendar_config_get_working_days (void)
@@ -1012,14 +466,6 @@ calendar_config_get_working_days (void)
return gconf_client_get_int (config, CALENDAR_CONFIG_WORKING_DAYS, NULL);
}
-void
-calendar_config_set_working_days (CalWeekdays days)
-{
- calendar_config_init ();
-
- gconf_client_set_int (config, CALENDAR_CONFIG_WORKING_DAYS, days, NULL);
-}
-
guint
calendar_config_add_notification_working_days (GConfClientNotifyFunc func, gpointer data)
{
@@ -1049,18 +495,6 @@ calendar_config_set_hide_completed_tasks (gboolean hide)
gconf_client_set_bool (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED, hide, NULL);
}
-guint
-calendar_config_add_notification_hide_completed_tasks (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED , func, data, NULL, NULL);
-
- return id;
-}
-
CalUnits
calendar_config_get_hide_completed_tasks_units (void)
{
@@ -1106,18 +540,6 @@ calendar_config_set_hide_completed_tasks_units (CalUnits cu)
g_free (units);
}
-guint
-calendar_config_add_notification_hide_completed_tasks_units (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_UNITS , func, data, NULL, NULL);
-
- return id;
-}
-
gint
calendar_config_get_hide_completed_tasks_value (void)
{
@@ -1134,18 +556,6 @@ calendar_config_set_hide_completed_tasks_value (gint value)
gconf_client_set_int (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_VALUE, value, NULL);
}
-guint
-calendar_config_add_notification_hide_completed_tasks_value (GConfClientNotifyFunc func, gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_VALUE , func, data, NULL, NULL);
-
- return id;
-}
-
/**
* calendar_config_get_confirm_delete:
*
@@ -1163,162 +573,6 @@ calendar_config_get_confirm_delete (void)
}
/**
- * calendar_config_set_confirm_delete:
- * @confirm: Whether confirmation is required when deleting items.
- *
- * Sets the configuration value for whether a confirmation dialog is presented
- * when deleting calendar/tasks items.
- **/
-void
-calendar_config_set_confirm_delete (gboolean confirm)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_PROMPT_DELETE, confirm, NULL);
-}
-
-/**
- * calendar_config_get_confirm_purge:
- *
- * Queries the configuration value for whether a confirmation dialog is
- * presented when purging calendar/tasks items.
- *
- * Return value: Whether confirmation is required when purging items.
- **/
-gboolean
-calendar_config_get_confirm_purge (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_bool (config, CALENDAR_CONFIG_PROMPT_PURGE, NULL);
-}
-
-/**
- * calendar_config_set_confirm_purge:
- * @confirm: Whether confirmation is required when purging items.
- *
- * Sets the configuration value for whether a confirmation dialog is presented
- * when purging calendar/tasks items.
- **/
-void
-calendar_config_set_confirm_purge (gboolean confirm)
-{
- calendar_config_init ();
-
- gconf_client_set_bool (config, CALENDAR_CONFIG_PROMPT_PURGE, confirm, NULL);
-}
-
-/**
- * calendar_config_get_tasks_due_today_color:
- * @color: the location to store the color
- *
- * Queries the color to be used to display tasks that are due today.
- **/
-void
-calendar_config_get_tasks_due_today_color (GdkColor *color)
-{
- const gchar *key = CALENDAR_CONFIG_TASKS_DUE_TODAY_COLOR;
- GError *error = NULL;
- gchar *color_spec;
-
- g_return_if_fail (color != NULL);
-
- calendar_config_init ();
-
- color_spec = gconf_client_get_string (config, key, &error);
-
- if (color_spec != NULL && !gdk_color_parse (color_spec, color))
- g_warning ("Unknown color \"%s\"", color_spec);
- else if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_free (color_spec);
-}
-
-/**
- * calendar_config_set_tasks_due_today_color:
- * @color: a #GdkColor
- *
- * Sets the color to be used to display tasks that are due today.
- **/
-void
-calendar_config_set_tasks_due_today_color (GdkColor *color)
-{
- const gchar *key = CALENDAR_CONFIG_TASKS_DUE_TODAY_COLOR;
- GError *error = NULL;
- gchar color_spec[16];
-
- g_return_if_fail (color != NULL);
-
- g_snprintf (color_spec, sizeof (color_spec), "#%04x%04x%04x",
- color->red, color->green, color->blue);
-
- calendar_config_init ();
-
- if (!gconf_client_set_string (config, key, color_spec, &error)) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-}
-
-/**
- * calendar_config_get_tasks_overdue_color:
- * @color: the location to store the color
- *
- * Queries the color to be used to display overdue tasks.
- **/
-void
-calendar_config_get_tasks_overdue_color (GdkColor *color)
-{
- const gchar *key = CALENDAR_CONFIG_TASKS_OVERDUE_COLOR;
- GError *error = NULL;
- gchar *color_spec;
-
- g_return_if_fail (color != NULL);
-
- calendar_config_init ();
-
- color_spec = gconf_client_get_string (config, key, &error);
-
- if (color_spec != NULL && !gdk_color_parse (color_spec, color))
- g_warning ("Unknown color \"%s\"", color_spec);
- else if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_free (color_spec);
-}
-
-/**
- * calendar_config_set_tasks_overdue_color:
- * @color: a #GdkColor
- *
- * Sets the color to be used to display overdue tasks.
- **/
-void
-calendar_config_set_tasks_overdue_color (GdkColor *color)
-{
- const gchar *key = CALENDAR_CONFIG_TASKS_OVERDUE_COLOR;
- GError *error = NULL;
- gchar color_spec[16];
-
- g_return_if_fail (color != NULL);
-
- g_snprintf (color_spec, sizeof (color_spec), "#%04x%04x%04x",
- color->red, color->green, color->blue);
-
- calendar_config_init ();
-
- if (!gconf_client_set_string (config, key, color_spec, &error)) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-}
-
-/**
* calendar_config_get_use_default_reminder:
*
* Queries whether new appointments should be created with a default reminder.
@@ -1540,36 +794,6 @@ calendar_config_get_hide_completed_tasks_sexp (gboolean get_completed)
return sexp;
}
-gchar *
-calendar_config_get_free_busy_template (void)
-{
- calendar_config_init ();
-
- return gconf_client_get_string (config, CALENDAR_CONFIG_TEMPLATE, NULL);
-}
-
-void
-calendar_config_set_free_busy_template (const gchar *template)
-{
- calendar_config_init ();
-
- gconf_client_set_string (config, CALENDAR_CONFIG_TEMPLATE, template, NULL);
-}
-
-guint
-calendar_config_add_notification_free_busy_template (GConfClientNotifyFunc func,
- gpointer data)
-{
- guint id;
-
- calendar_config_init ();
-
- id = gconf_client_notify_add (config, CALENDAR_CONFIG_TEMPLATE, func, data,
- NULL, NULL);
-
- return id;
-}
-
void
calendar_config_set_dir_path (const gchar *path)
{
diff --git a/calendar/gui/calendar-config.h b/calendar/gui/calendar-config.h
index 53d636faf5..ff018abeca 100644
--- a/calendar/gui/calendar-config.h
+++ b/calendar/gui/calendar-config.h
@@ -66,174 +66,73 @@ GSList *calendar_config_get_calendars_selected (void);
void calendar_config_set_calendars_selected (GSList *selected);
guint calendar_config_add_notification_calendars_selected (GConfClientNotifyFunc func, gpointer data);
-/* The primary calendar */
-gchar *calendar_config_get_primary_calendar (void);
-void calendar_config_set_primary_calendar (const gchar *primary_uid);
-guint calendar_config_add_notification_primary_calendar (GConfClientNotifyFunc func, gpointer data);
-
-/* Use system timezone; if TRUE, then influences also the current timezone functions. */
-gboolean calendar_config_get_use_system_timezone (void);
-void calendar_config_set_use_system_timezone (gboolean use);
-guint calendar_config_add_notification_use_system_timezone (GConfClientNotifyFunc func, gpointer data);
-
/* The current timezone, e.g. "Europe/London". */
-gchar * calendar_config_get_timezone (void);
-gchar * calendar_config_get_timezone_stored (void);
icaltimezone *calendar_config_get_icaltimezone (void);
-void calendar_config_set_timezone (const gchar *timezone);
-guint calendar_config_add_notification_timezone (GConfClientNotifyFunc func, gpointer data);
/* The working days of the week, a bit-wise combination of flags. */
CalWeekdays calendar_config_get_working_days (void);
-void calendar_config_set_working_days (CalWeekdays days);
guint calendar_config_add_notification_working_days (GConfClientNotifyFunc func, gpointer data);
/* The start day of the week (0 = Sun to 6 = Sat). */
gint calendar_config_get_week_start_day (void);
-void calendar_config_set_week_start_day (gint week_start_day);
-guint calendar_config_add_notification_week_start_day (GConfClientNotifyFunc func, gpointer data);
/* The start and end times of the work-day. */
gint calendar_config_get_day_start_hour (void);
void calendar_config_set_day_start_hour (gint day_start_hour);
-guint calendar_config_add_notification_day_start_hour (GConfClientNotifyFunc func, gpointer data);
gint calendar_config_get_day_start_minute (void);
void calendar_config_set_day_start_minute (gint day_start_min);
-guint calendar_config_add_notification_day_start_minute (GConfClientNotifyFunc func, gpointer data);
gint calendar_config_get_day_end_hour (void);
void calendar_config_set_day_end_hour (gint day_end_hour);
-guint calendar_config_add_notification_day_end_hour (GConfClientNotifyFunc func, gpointer data);
gint calendar_config_get_day_end_minute (void);
void calendar_config_set_day_end_minute (gint day_end_min);
-guint calendar_config_add_notification_day_end_minute (GConfClientNotifyFunc func, gpointer data);
/* Whether we use 24-hour format or 12-hour format (AM/PM). */
gboolean calendar_config_get_24_hour_format (void);
-void calendar_config_set_24_hour_format (gboolean use_24_hour);
-guint calendar_config_add_notification_24_hour_format (GConfClientNotifyFunc func, gpointer data);
-
-gboolean calendar_config_get_show_status (void);
-void calendar_config_set_show_status (gboolean status);
-
-gboolean calendar_config_get_show_type (void);
-void calendar_config_set_show_type (gboolean status);
-
-gboolean calendar_config_get_show_rsvp (void);
-void calendar_config_set_show_rsvp (gboolean status);
-
-gboolean calendar_config_get_show_timezone (void);
-void calendar_config_set_show_timezone (gboolean status);
-
-gboolean calendar_config_get_show_categories (void);
-void calendar_config_set_show_categories (gboolean status);
-
-gboolean calendar_config_get_show_role (void);
-void calendar_config_set_show_role (gboolean state);
/* The time divisions in the Day/Work-Week view in minutes (5/10/15/30/60). */
gint calendar_config_get_time_divisions (void);
void calendar_config_set_time_divisions (gint divisions);
guint calendar_config_add_notification_time_divisions (GConfClientNotifyFunc func, gpointer data);
-/* Whether we show the Marcus Bains Line, and in what colors. */
-void calendar_config_get_marcus_bains (gboolean *show_line, const gchar **dayview_color, const gchar **timebar_color);
-void calendar_config_add_notification_marcus_bains (GConfClientNotifyFunc func, gpointer data, gint *not_show, gint *not_dcolor, gint *not_tcolor);
-
-/* Whether we show event end times. */
-gboolean calendar_config_get_show_event_end (void);
-void calendar_config_set_show_event_end (gboolean show_end);
-guint calendar_config_add_notification_show_event_end (GConfClientNotifyFunc func, gpointer data);
-
/* Whether we compress the weekend in the week/month views. */
gboolean calendar_config_get_compress_weekend (void);
-void calendar_config_set_compress_weekend (gboolean compress);
-guint calendar_config_add_notification_compress_weekend (GConfClientNotifyFunc func, gpointer data);
/* Whether we show week numbers in the Date Navigator. */
gboolean calendar_config_get_dnav_show_week_no (void);
-void calendar_config_set_dnav_show_week_no (gboolean show_week_no);
guint calendar_config_add_notification_dnav_show_week_no (GConfClientNotifyFunc func, gpointer data);
-/* Whether we show week number in the day view. */
-gboolean calendar_config_get_dview_show_week_no (void);
-void calendar_config_set_dview_show_week_no (gboolean show_week_no);
-guint calendar_config_add_notification_dview_show_week_no (GConfClientNotifyFunc func, gpointer data);
-
/* The positions of the panes in the normal and month views. */
-gint calendar_config_get_hpane_pos (void);
void calendar_config_set_hpane_pos (gint hpane_pos);
-gint calendar_config_get_vpane_pos (void);
-void calendar_config_set_vpane_pos (gint vpane_pos);
-
-gboolean calendar_config_get_preview_state (void);
-void calendar_config_set_preview_state (gboolean state);
-guint calendar_config_add_notification_preview_state (GConfClientNotifyFunc func, gpointer data);
-
-gint calendar_config_get_month_hpane_pos (void);
void calendar_config_set_month_hpane_pos (gint hpane_pos);
-gint calendar_config_get_month_vpane_pos (void);
-void calendar_config_set_month_vpane_pos (gint vpane_pos);
-
-gfloat calendar_config_get_tag_vpane_pos (void);
-void calendar_config_set_tag_vpane_pos (gfloat vpane_pos);
-
/* The current list of task lists selected */
GSList *calendar_config_get_tasks_selected (void);
void calendar_config_set_tasks_selected (GSList *selected);
guint calendar_config_add_notification_tasks_selected (GConfClientNotifyFunc func, gpointer data);
-/* The primary calendar */
-gchar *calendar_config_get_primary_tasks (void);
-void calendar_config_set_primary_tasks (const gchar *primary_uid);
-guint calendar_config_add_notification_primary_tasks (GConfClientNotifyFunc func, gpointer data);
-
-/* The pane position */
-gint calendar_config_get_task_vpane_pos (void);
-void calendar_config_set_task_vpane_pos (gint vpane_pos);
-
/* The current list of memo lists selected */
GSList *calendar_config_get_memos_selected (void);
void calendar_config_set_memos_selected (GSList *selected);
guint calendar_config_add_notification_memos_selected (GConfClientNotifyFunc func, gpointer data);
-/* The primary calendar */
-gchar *calendar_config_get_primary_memos (void);
-void calendar_config_set_primary_memos (const gchar *primary_uid);
-guint calendar_config_add_notification_primary_memos (GConfClientNotifyFunc func, gpointer data);
-
-/* Colors for the task list */
-void calendar_config_get_tasks_due_today_color (GdkColor *color);
-void calendar_config_set_tasks_due_today_color (GdkColor *color);
-
-void calendar_config_get_tasks_overdue_color (GdkColor *color);
-void calendar_config_set_tasks_overdue_color (GdkColor *color);
-
/* Settings to hide completed tasks. */
gboolean calendar_config_get_hide_completed_tasks (void);
void calendar_config_set_hide_completed_tasks (gboolean hide);
-guint calendar_config_add_notification_hide_completed_tasks (GConfClientNotifyFunc func, gpointer data);
CalUnits calendar_config_get_hide_completed_tasks_units(void);
void calendar_config_set_hide_completed_tasks_units(CalUnits units);
-guint calendar_config_add_notification_hide_completed_tasks_units (GConfClientNotifyFunc func, gpointer data);
gint calendar_config_get_hide_completed_tasks_value(void);
void calendar_config_set_hide_completed_tasks_value(gint value);
-guint calendar_config_add_notification_hide_completed_tasks_value (GConfClientNotifyFunc func, gpointer data);
gchar * calendar_config_get_hide_completed_tasks_sexp (gboolean get_completed);
/* Confirmation options */
gboolean calendar_config_get_confirm_delete (void);
-void calendar_config_set_confirm_delete (gboolean confirm);
-
-gboolean calendar_config_get_confirm_purge (void);
-void calendar_config_set_confirm_purge (gboolean confirm);
/* Default reminder options */
gboolean calendar_config_get_use_default_reminder (void);
@@ -249,11 +148,6 @@ void calendar_config_set_default_reminder_units (CalUnits units);
GSList * calendar_config_get_free_busy (void);
void calendar_config_set_free_busy (GSList * url_list);
-gchar *calendar_config_get_free_busy_template (void);
-void calendar_config_set_free_busy_template (const gchar *template);
-guint calendar_config_add_notification_free_busy_template (GConfClientNotifyFunc func,
- gpointer data);
-
/* Returns TRUE if the locale has 'am' and 'pm' strings defined, i.e. it
supports 12-hour time format. */
gboolean calendar_config_locale_supports_12_hour_format(void);
diff --git a/calendar/gui/calendar-view-factory.c b/calendar/gui/calendar-view-factory.c
index 95497b1782..34e8344a88 100644
--- a/calendar/gui/calendar-view-factory.c
+++ b/calendar/gui/calendar-view-factory.c
@@ -181,7 +181,7 @@ calendar_view_factory_new_view (GalViewFactory *factory, const gchar *name)
*
* Return value: The same value as @cal_view_factory.
**/
-CalendarViewFactory *
+GalViewFactory *
calendar_view_factory_construct (CalendarViewFactory *cal_view_factory,
GnomeCalendarViewType view_type)
{
@@ -194,7 +194,7 @@ calendar_view_factory_construct (CalendarViewFactory *cal_view_factory,
priv->view_type = view_type;
- return cal_view_factory;
+ return GAL_VIEW_FACTORY (cal_view_factory);
}
/**
@@ -205,7 +205,7 @@ calendar_view_factory_construct (CalendarViewFactory *cal_view_factory,
*
* Return value: A newly-created calendar view factory.
**/
-CalendarViewFactory *
+GalViewFactory *
calendar_view_factory_new (GnomeCalendarViewType view_type)
{
CalendarViewFactory *cal_view_factory;
diff --git a/calendar/gui/calendar-view-factory.h b/calendar/gui/calendar-view-factory.h
index 0f182a11e1..c0b90f2bd9 100644
--- a/calendar/gui/calendar-view-factory.h
+++ b/calendar/gui/calendar-view-factory.h
@@ -57,10 +57,10 @@ typedef struct {
GType calendar_view_factory_get_type (void);
-CalendarViewFactory *calendar_view_factory_construct (CalendarViewFactory *cal_view_factory,
+GalViewFactory *calendar_view_factory_construct (CalendarViewFactory *cal_view_factory,
GnomeCalendarViewType view_type);
-CalendarViewFactory *calendar_view_factory_new (GnomeCalendarViewType view_type);
+GalViewFactory *calendar_view_factory_new (GnomeCalendarViewType view_type);
diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c
deleted file mode 100644
index ee80a00ae5..0000000000
--- a/calendar/gui/comp-editor-factory.c
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * Evolution calendar - Component editor factory object
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena-Quintero <federico@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-exception.h>
-#include <evolution-calendar.h>
-#include <libedataserver/e-url.h>
-#include <libecal/e-cal.h>
-#include "calendar-config.h"
-#include "e-comp-editor-registry.h"
-#include "comp-editor-factory.h"
-#include "comp-util.h"
-#include "common/authentication.h"
-#include "dialogs/event-editor.h"
-#include "dialogs/task-editor.h"
-
-extern ECompEditorRegistry *comp_editor_registry;
-
-
-
-/* A pending request */
-
-typedef enum {
- REQUEST_EXISTING,
- REQUEST_NEW
-} RequestType;
-
-typedef struct {
- RequestType type;
-
- union {
- struct {
- gchar *uid;
- } existing;
-
- struct {
- GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type;
- } new;
- } u;
-} Request;
-
-/* A client we have open */
-typedef struct {
- /* Our parent CompEditorFactory */
- CompEditorFactory *factory;
-
- /* Uri of the calendar, used as key in the clients hash table */
- gchar *uri;
-
- /* Client of the calendar */
- ECal *client;
-
- /* Count editors using this client */
- gint editor_count;
-
- /* Pending requests; they are pending if the client is still being opened */
- GSList *pending;
-
- /* Whether this is open or still waiting */
- guint open : 1;
-} OpenClient;
-
-/* Private part of the CompEditorFactory structure */
-struct CompEditorFactoryPrivate {
- /* Hash table of URI->OpenClient */
- GHashTable *uri_client_hash;
-};
-
-
-
-static void comp_editor_factory_class_init (CompEditorFactoryClass *class);
-static void comp_editor_factory_init (CompEditorFactory *factory);
-static void comp_editor_factory_finalize (GObject *object);
-
-static void impl_editExisting (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- const CORBA_char *uid,
- const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode corba_type,
- CORBA_Environment *ev);
-static void impl_editNew (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- const GNOME_Evolution_Calendar_CalObjType type,
- CORBA_Environment *ev);
-
-static BonoboObjectClass *parent_class = NULL;
-
-
-
-BONOBO_TYPE_FUNC_FULL (CompEditorFactory,
- GNOME_Evolution_Calendar_CompEditorFactory,
- BONOBO_OBJECT_TYPE,
- comp_editor_factory)
-
-/* Class initialization function for the component editor factory */
-static void
-comp_editor_factory_class_init (CompEditorFactoryClass *class)
-{
- GObjectClass *object_class;
-
- object_class = (GObjectClass *) class;
-
- parent_class = g_type_class_peek_parent (class);
-
- class->epv.editExisting = impl_editExisting;
- class->epv.editNew = impl_editNew;
-
- object_class->finalize = comp_editor_factory_finalize;
-}
-
-/* Frees a Request structure */
-static void
-free_request (Request *r)
-{
- if (r->type == REQUEST_EXISTING)
- g_free (r->u.existing.uid);
-
- g_free (r);
-}
-
-/* Frees an OpenClient structure */
-static void
-free_client (OpenClient *oc)
-{
- GSList *l;
-
- g_free (oc->uri);
- oc->uri = NULL;
-
- g_object_unref (oc->client);
- oc->client = NULL;
-
- for (l = oc->pending; l; l = l->next) {
- Request *r;
-
- r = l->data;
- free_request (r);
- }
- g_slist_free (oc->pending);
- oc->pending = NULL;
-
- g_free (oc);
-}
-
-/* Object initialization function for the component editor factory */
-static void
-comp_editor_factory_init (CompEditorFactory *factory)
-{
- CompEditorFactoryPrivate *priv;
-
- priv = g_new (CompEditorFactoryPrivate, 1);
- factory->priv = priv;
-
- priv->uri_client_hash = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) free_client);
-}
-
-/* Destroy handler for the component editor factory */
-static void
-comp_editor_factory_finalize (GObject *object)
-{
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_COMP_EDITOR_FACTORY (object));
-
- factory = COMP_EDITOR_FACTORY (object);
- priv = factory->priv;
-
- g_hash_table_destroy (priv->uri_client_hash);
- priv->uri_client_hash = NULL;
-
- g_free (priv);
- factory->priv = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-
-
-/* Callback used when a component editor gets destroyed */
-static void
-editor_destroy_cb (GtkObject *object, gpointer data)
-{
- OpenClient *oc;
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
-
- oc = data;
- factory = oc->factory;
- priv = factory->priv;
-
- oc->editor_count--;
-
- /* See if we need to free the client */
- g_return_if_fail (oc->pending == NULL);
-
- if (oc->editor_count != 0)
- return;
-
- g_hash_table_remove (priv->uri_client_hash, oc->uri);
-}
-
-/* Starts editing an existing component on a client that is already open */
-static void
-edit_existing (OpenClient *oc, const gchar *uid)
-{
- ECalComponent *comp;
- icalcomponent *icalcomp;
- CompEditor *editor;
- ECalComponentVType vtype;
- CompEditorFlags flags = { 0, };
-
- g_return_if_fail (oc->open);
-
- /* Get the object */
- if (!e_cal_get_object (oc->client, uid, NULL, &icalcomp, NULL)) {
- /* FIXME Better error handling */
- g_warning (G_STRLOC ": Syntax error while getting component `%s'", uid);
-
- return;
- }
-
- comp = e_cal_component_new ();
- if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- return;
- }
-
- /* Create the appropriate type of editor */
-
- vtype = e_cal_component_get_vtype (comp);
- if (itip_organizer_is_user (comp, oc->client))
- flags |= COMP_EDITOR_USER_ORG;
-
- switch (vtype) {
- case E_CAL_COMPONENT_EVENT:
- if (e_cal_component_has_attendees (comp))
- flags |= COMP_EDITOR_MEETING;
-
- editor = event_editor_new (oc->client, flags);
- break;
-
- case E_CAL_COMPONENT_TODO:
- editor = COMP_EDITOR (task_editor_new (oc->client, flags));
- break;
-
- default:
- g_message ("edit_exiting(): Unsupported object type %d", (gint) vtype);
- g_object_unref (comp);
- return;
- }
-
- /* Set the object on the editor */
- comp_editor_edit_comp (editor, comp);
- gtk_window_present (GTK_WINDOW (editor));
- g_object_unref (comp);
-
- oc->editor_count++;
- g_signal_connect (editor, "destroy", G_CALLBACK (editor_destroy_cb), oc);
-
- e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
-}
-
-static ECalComponent *
-get_default_task (ECal *client)
-{
- ECalComponent *comp;
-
- comp = cal_comp_task_new_with_defaults (client);
-
- return comp;
-}
-
-/* Edits a new object in the context of a client */
-static void
-edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type)
-{
- ECalComponent *comp;
- CompEditor *editor;
-
- switch (type) {
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT:
- editor = event_editor_new (oc->client, FALSE);
- comp = cal_comp_event_new_with_current_time (oc->client, FALSE);
- break;
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING:
- editor = event_editor_new (oc->client, TRUE);
- comp = cal_comp_event_new_with_current_time (oc->client, FALSE);
- break;
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT:
- editor = event_editor_new (oc->client, FALSE);
- comp = cal_comp_event_new_with_current_time (oc->client, TRUE);
- break;
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO:
- editor = COMP_EDITOR (task_editor_new (oc->client, FALSE));
- comp = get_default_task (oc->client);
- break;
- default:
- g_return_if_reached ();
- return;
- }
-
- comp_editor_edit_comp (editor, comp);
- if (type == GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING)
- event_editor_show_meeting (EVENT_EDITOR (editor));
- gtk_window_present (GTK_WINDOW (editor));
-
- oc->editor_count++;
- g_signal_connect (editor, "destroy", G_CALLBACK (editor_destroy_cb), oc);
-
- e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
-}
-
-/* Resolves all the pending requests for a client */
-static void
-resolve_pending_requests (OpenClient *oc)
-{
- GSList *l;
- icaltimezone *zone;
-
- if (!oc->pending)
- return;
-
- /* Set the default timezone in the backend. */
- zone = calendar_config_get_icaltimezone ();
-
- /* FIXME Error handling? */
- e_cal_set_default_timezone (oc->client, zone, NULL);
-
- for (l = oc->pending; l; l = l->next) {
- Request *request;
-
- request = l->data;
-
- switch (request->type) {
- case REQUEST_EXISTING:
- edit_existing (oc, request->u.existing.uid);
- break;
-
- case REQUEST_NEW:
- edit_new (oc, request->u.new.type);
- break;
- }
-
- free_request (request);
- }
-
- g_slist_free (oc->pending);
- oc->pending = NULL;
-}
-
-/* Callback used when a client is finished opening. We resolve all the pending
- * requests.
- */
-static void
-cal_opened_cb (ECal *client, ECalendarStatus status, gpointer data)
-{
- OpenClient *oc;
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
- GtkWidget *dialog = NULL;
-
- oc = data;
- factory = oc->factory;
- priv = factory->priv;
-
- switch (status) {
- case E_CALENDAR_STATUS_OK:
- oc->open = TRUE;
- resolve_pending_requests (oc);
- return;
-
- case E_CALENDAR_STATUS_OTHER_ERROR:
- case E_CALENDAR_STATUS_NO_SUCH_CALENDAR:
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- "%s", _("Error while opening the calendar"));
- break;
-
- case E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED:
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- "%s", _("Method not supported when opening the calendar"));
- break;
-
- case E_CALENDAR_STATUS_PERMISSION_DENIED :
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- "%s", _("Permission denied to open the calendar"));
- break;
-
- case E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED:
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- "%s", _("Authentication Required"));
- break;
-
- case E_CALENDAR_STATUS_AUTHENTICATION_FAILED :
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- "%s", _("Authentication Failed"));
- break;
-
- default:
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- "%s", _("Unknown error"));
- return;
- }
-
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- g_hash_table_remove (priv->uri_client_hash, oc->uri);
-}
-
-/* Creates a new OpenClient structure and queues the component editing/creation
- * process until the client is open. Returns NULL if it could not issue the
- * open request.
- */
-static OpenClient *
-open_client (CompEditorFactory *factory, ECalSourceType source_type, const gchar *uristr)
-{
- CompEditorFactoryPrivate *priv;
- ECal *client;
- OpenClient *oc;
- GError *error = NULL;
-
- priv = factory->priv;
-
- client = auth_new_cal_from_uri (uristr, source_type);
- if (!client)
- return NULL;
-
- oc = g_new (OpenClient, 1);
- oc->factory = factory;
-
- oc->uri = g_strdup (uristr);
-
- oc->client = client;
- oc->editor_count = 0;
- oc->pending = NULL;
- oc->open = FALSE;
-
- g_signal_connect (oc->client, "cal_opened", G_CALLBACK (cal_opened_cb), oc);
-
- g_hash_table_insert (priv->uri_client_hash, oc->uri, oc);
-
- if (!e_cal_open (oc->client, FALSE, &error)) {
- g_warning (G_STRLOC ": %s", error->message);
- g_free (oc->uri);
- g_object_unref (oc->client);
- g_free (oc);
- g_error_free (error);
-
- return NULL;
- }
-
- return oc;
-}
-
-/* Looks up an open client or queues it for being opened. Returns the client or
- * NULL on failure; in the latter case it sets the ev exception.
- */
-static OpenClient *
-lookup_open_client (CompEditorFactory *factory, ECalSourceType source_type, const gchar *str_uri, CORBA_Environment *ev)
-{
- CompEditorFactoryPrivate *priv;
- OpenClient *oc;
- EUri *uri;
-
- priv = factory->priv;
-
- /* Look up the client */
-
- uri = e_uri_new (str_uri);
- if (!uri) {
- bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CompEditorFactory_InvalidURI);
- return NULL;
- }
- e_uri_free (uri);
-
- oc = g_hash_table_lookup (priv->uri_client_hash, str_uri);
- if (!oc) {
- oc = open_client (factory, source_type, str_uri);
- if (!oc) {
- bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CompEditorFactory_BackendContactError);
- return NULL;
- }
- }
-
- return oc;
-}
-
-/* Queues a request for editing an existing object */
-static void
-queue_edit_existing (OpenClient *oc, const gchar *uid)
-{
- Request *request;
-
- g_return_if_fail (!oc->open);
-
- request = g_new (Request, 1);
- request->type = REQUEST_EXISTING;
- request->u.existing.uid = g_strdup (uid);
-
- oc->pending = g_slist_append (oc->pending, request);
-}
-
-/* ::editExisting() method implementation */
-static void
-impl_editExisting (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- const CORBA_char *uid,
- const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode corba_type,
- CORBA_Environment *ev)
-{
- CompEditorFactory *factory;
- OpenClient *oc;
- CompEditor *editor;
- ECalSourceType source_type;
-
- factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant));
-
- switch (corba_type) {
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO:
- source_type = E_CAL_SOURCE_TYPE_TODO;
- break;
- default:
- source_type = E_CAL_SOURCE_TYPE_EVENT;
- }
-
- oc = lookup_open_client (factory, source_type, str_uri, ev);
- if (!oc)
- return;
-
- if (!oc->open) {
- queue_edit_existing (oc, uid);
- return;
- }
-
- /* Look up the component */
- editor = e_comp_editor_registry_find (comp_editor_registry, uid);
- if (editor == NULL) {
- edit_existing (oc, uid);
- } else {
- gtk_window_present (GTK_WINDOW (editor));
- }
-}
-
-/* Queues a request for creating a new object */
-static void
-queue_edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type)
-{
- Request *request;
-
- g_return_if_fail (!oc->open);
-
- request = g_new (Request, 1);
- request->type = REQUEST_NEW;
- request->u.new.type = type;
-
- oc->pending = g_slist_append (oc->pending, request);
-}
-
-/* ::editNew() method implementation */
-static void
-impl_editNew (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode corba_type,
- CORBA_Environment *ev)
-{
- CompEditorFactory *factory;
- OpenClient *oc;
- ECalSourceType source_type;
-
- factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant));
-
- switch (corba_type) {
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO:
- source_type = E_CAL_SOURCE_TYPE_TODO;
- break;
- default:
- source_type = E_CAL_SOURCE_TYPE_EVENT;
- }
-
- oc = lookup_open_client (factory, source_type, str_uri, ev);
- if (!oc)
- return;
-
- if (!oc->open)
- queue_edit_new (oc, corba_type);
- else
- edit_new (oc, corba_type);
-}
-
-
-
-/**
- * comp_editor_factory_new:
- *
- * Creates a new calendar component editor factory.
- *
- * Return value: A newly-created component editor factory.
- **/
-CompEditorFactory *
-comp_editor_factory_new (void)
-{
- return g_object_new (TYPE_COMP_EDITOR_FACTORY, NULL);
-}
-
diff --git a/calendar/gui/comp-editor-factory.h b/calendar/gui/comp-editor-factory.h
deleted file mode 100644
index 3e79992d67..0000000000
--- a/calendar/gui/comp-editor-factory.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Evolution calendar - Component editor factory object
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena-Quintero <federico@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef COMP_EDITOR_FACTORY_H
-#define COMP_EDITOR_FACTORY_H
-
-#include <bonobo/bonobo-object.h>
-#include "evolution-calendar.h"
-
-
-
-#define TYPE_COMP_EDITOR_FACTORY (comp_editor_factory_get_type ())
-#define COMP_EDITOR_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMP_EDITOR_FACTORY, \
- CompEditorFactory))
-#define COMP_EDITOR_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
- TYPE_COMP_EDITOR_FACTORY, CompEditorFactoryClass))
-#define IS_COMP_EDITOR_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMP_EDITOR_FACTORY))
-#define IS_COMP_EDITOR_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMP_EDITOR_FACTORY))
-
-typedef struct CompEditorFactoryPrivate CompEditorFactoryPrivate;
-
-typedef struct {
- BonoboObject object;
-
- /* Private data */
- CompEditorFactoryPrivate *priv;
-} CompEditorFactory;
-
-typedef struct {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Calendar_CompEditorFactory__epv epv;
-} CompEditorFactoryClass;
-
-GType comp_editor_factory_get_type (void);
-
-CompEditorFactory *comp_editor_factory_new (void);
-
-
-
-#endif
diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c
deleted file mode 100644
index 3e7b7499cc..0000000000
--- a/calendar/gui/control-factory.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <config.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-persist-file.h>
-#include <bonobo/bonobo-context.h>
-#include <glade/glade.h>
-
-#include <libecal/e-cal-time-util.h>
-#include <gui/gnome-cal.h>
-#include <gui/calendar-commands.h>
-#include <gui/calendar-config.h>
-
-#include "control-factory.h"
-
-/* Are these supposed to be global or static? */
-CORBA_Environment ev;
-CORBA_ORB orb;
-
-static void
-control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- if (activate)
- calendar_control_activate (control, gcal);
- else
- calendar_control_deactivate (control, gcal);
-}
-
-BonoboControl *
-control_factory_new_control (void)
-{
- BonoboControl *control;
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (gnome_calendar_new ());
- if (!gcal)
- return NULL;
-
- gtk_widget_show (GTK_WIDGET (gcal));
-
- control = bonobo_control_new (GTK_WIDGET (gcal));
- if (!control) {
- g_message ("control_factory_fn(): could not create the control!");
- return NULL;
- }
- g_object_set_data (G_OBJECT (gcal), "control", control);
-
- g_signal_connect (control, "activate", G_CALLBACK (control_activate_cb), gcal);
-
- return control;
-}
diff --git a/calendar/gui/dialogs/cal-prefs-dialog.c b/calendar/gui/dialogs/cal-prefs-dialog.c
index 2fc17202cc..6fccf0cea1 100644
--- a/calendar/gui/dialogs/cal-prefs-dialog.c
+++ b/calendar/gui/dialogs/cal-prefs-dialog.c
@@ -31,16 +31,13 @@
#include "../calendar-config.h"
#include "cal-prefs-dialog.h"
#include <widgets/misc/e-dateedit.h>
-#include "e-util/e-datetime-format.h"
+#include <e-util/e-binding.h>
+#include <e-util/e-datetime-format.h>
#include <e-util/e-dialog-widgets.h>
#include <e-util/e-util-private.h>
#include <glib/gi18n.h>
#include <string.h>
-static const gint week_start_day_map[] = {
- 1, 2, 3, 4, 5, 6, 0, -1
-};
-
static const gint time_division_map[] = {
60, 30, 15, 10, 5, -1
};
@@ -99,32 +96,6 @@ eccp_widget_glade (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
}
static void
-working_days_changed (GtkWidget *widget, CalendarPrefsDialog *prefs)
-{
- CalWeekdays working_days = 0;
- guint32 mask = 1;
- gint day;
-
- for (day = 0; day < 7; day++) {
- if (e_dialog_toggle_get (prefs->working_days[day]))
- working_days |= mask;
- mask <<= 1;
- }
-
- calendar_config_set_working_days (working_days);
-}
-
-static void
-timezone_changed (GtkWidget *widget, CalendarPrefsDialog *prefs)
-{
- icaltimezone *zone;
-
- zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (prefs->timezone));
-
- calendar_config_set_timezone (icaltimezone_get_location (zone));
-}
-
-static void
update_day_second_zone_caption (CalendarPrefsDialog *prefs)
{
gchar *location;
@@ -268,27 +239,6 @@ end_of_day_changed (GtkWidget *widget, CalendarPrefsDialog *prefs)
calendar_config_set_day_end_hour (end_hour);
calendar_config_set_day_end_minute (end_minute);
}
-static void
-week_start_day_changed (GtkWidget *widget, CalendarPrefsDialog *prefs)
-{
- gint week_start_day;
-
- week_start_day = e_dialog_combo_box_get (prefs->week_start_day, week_start_day_map);
- calendar_config_set_week_start_day (week_start_day);
-}
-
-static void
-use_24_hour_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs)
-{
- gboolean use_24_hour;
-
- use_24_hour = gtk_toggle_button_get_active (toggle);
-
- e_date_edit_set_use_24_hour_format (E_DATE_EDIT (prefs->start_of_day), use_24_hour);
- e_date_edit_set_use_24_hour_format (E_DATE_EDIT (prefs->end_of_day), use_24_hour);
-
- calendar_config_set_24_hour_format (use_24_hour);
-}
static void
time_divisions_changed (GtkWidget *widget, CalendarPrefsDialog *prefs)
@@ -300,30 +250,6 @@ time_divisions_changed (GtkWidget *widget, CalendarPrefsDialog *prefs)
}
static void
-show_end_times_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs)
-{
- calendar_config_set_show_event_end (gtk_toggle_button_get_active (toggle));
-}
-
-static void
-compress_weekend_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs)
-{
- calendar_config_set_compress_weekend (gtk_toggle_button_get_active (toggle));
-}
-
-static void
-dnav_show_week_no_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs)
-{
- calendar_config_set_dnav_show_week_no (gtk_toggle_button_get_active (toggle));
-}
-
-static void
-dview_show_week_no_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs)
-{
- calendar_config_set_dview_show_week_no (gtk_toggle_button_get_active (toggle));
-}
-
-static void
month_scroll_by_week_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs)
{
calendar_config_set_month_scroll_by_week (gtk_toggle_button_get_active (toggle));
@@ -356,30 +282,6 @@ hide_completed_tasks_units_changed (GtkWidget *widget, CalendarPrefsDialog *pref
}
static void
-tasks_due_today_set_color (GtkColorButton *color_button, CalendarPrefsDialog *prefs)
-{
- GdkColor color;
-
- gtk_color_button_get_color (color_button, &color);
- calendar_config_set_tasks_due_today_color (&color);
-}
-
-static void
-tasks_overdue_set_color (GtkColorButton *color_button, CalendarPrefsDialog *prefs)
-{
- GdkColor color;
-
- gtk_color_button_get_color (color_button, &color);
- calendar_config_set_tasks_overdue_color (&color);
-}
-
-static void
-confirm_delete_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs)
-{
- calendar_config_set_confirm_delete (gtk_toggle_button_get_active (toggle));
-}
-
-static void
default_reminder_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs)
{
calendar_config_set_use_default_reminder (gtk_toggle_button_get_active (toggle));
@@ -491,13 +393,9 @@ alarms_selection_changed (ESourceSelector *selector, CalendarPrefsDialog *prefs)
}
static void
-template_url_changed (GtkEntry *entry, CalendarPrefsDialog *prefs)
-{
- calendar_config_set_free_busy_template (gtk_entry_get_text (entry));
-}
-
-static void
-update_system_tz_widgets (CalendarPrefsDialog *prefs)
+update_system_tz_widgets (EShellSettings *shell_settings,
+ GParamSpec *pspec,
+ CalendarPrefsDialog *prefs)
{
icaltimezone *zone;
@@ -509,42 +407,18 @@ update_system_tz_widgets (CalendarPrefsDialog *prefs)
} else {
gtk_label_set_text (GTK_LABEL (prefs->system_tz_label), "(UTC)");
}
-
- gtk_widget_set_sensitive (prefs->timezone, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prefs->use_system_tz_check)));
-}
-
-static void
-use_system_tz_changed (GtkWidget *check, CalendarPrefsDialog *prefs)
-{
- calendar_config_set_use_system_timezone (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)));
- update_system_tz_widgets (prefs);
}
static void
setup_changes (CalendarPrefsDialog *prefs)
{
- gint i;
-
- for (i = 0; i < 7; i ++)
- g_signal_connect (G_OBJECT (prefs->working_days[i]), "toggled", G_CALLBACK (working_days_changed), prefs);
-
- g_signal_connect (G_OBJECT (prefs->use_system_tz_check), "toggled", G_CALLBACK (use_system_tz_changed), prefs);
- g_signal_connect (G_OBJECT (prefs->timezone), "changed", G_CALLBACK (timezone_changed), prefs);
g_signal_connect (G_OBJECT (prefs->day_second_zone), "clicked", G_CALLBACK (day_second_zone_clicked), prefs);
g_signal_connect (G_OBJECT (prefs->start_of_day), "changed", G_CALLBACK (start_of_day_changed), prefs);
g_signal_connect (G_OBJECT (prefs->end_of_day), "changed", G_CALLBACK (end_of_day_changed), prefs);
- g_signal_connect (G_OBJECT (prefs->week_start_day), "changed", G_CALLBACK (week_start_day_changed), prefs);
-
- g_signal_connect (G_OBJECT (prefs->use_24_hour), "toggled", G_CALLBACK (use_24_hour_toggled), prefs);
-
g_signal_connect (G_OBJECT (prefs->time_divisions), "changed", G_CALLBACK (time_divisions_changed), prefs);
- g_signal_connect (G_OBJECT (prefs->show_end_times), "toggled", G_CALLBACK (show_end_times_toggled), prefs);
- g_signal_connect (G_OBJECT (prefs->compress_weekend), "toggled", G_CALLBACK (compress_weekend_toggled), prefs);
- g_signal_connect (G_OBJECT (prefs->dnav_show_week_no), "toggled", G_CALLBACK (dnav_show_week_no_toggled), prefs);
- g_signal_connect (G_OBJECT (prefs->dview_show_week_no), "toggled", G_CALLBACK (dview_show_week_no_toggled), prefs);
g_signal_connect (G_OBJECT (prefs->month_scroll_by_week), "toggled", G_CALLBACK (month_scroll_by_week_toggled), prefs);
g_signal_connect (G_OBJECT (prefs->tasks_hide_completed), "toggled",
@@ -552,12 +426,7 @@ setup_changes (CalendarPrefsDialog *prefs)
g_signal_connect (G_OBJECT (prefs->tasks_hide_completed_interval), "value-changed",
G_CALLBACK (hide_completed_tasks_changed), prefs);
g_signal_connect (G_OBJECT (prefs->tasks_hide_completed_units), "changed", G_CALLBACK (hide_completed_tasks_units_changed), prefs);
- g_signal_connect (G_OBJECT (prefs->tasks_due_today_color), "color-set",
- G_CALLBACK (tasks_due_today_set_color), prefs);
- g_signal_connect (G_OBJECT (prefs->tasks_overdue_color), "color-set",
- G_CALLBACK (tasks_overdue_set_color), prefs);
- g_signal_connect (G_OBJECT (prefs->confirm_delete), "toggled", G_CALLBACK (confirm_delete_toggled), prefs);
g_signal_connect (G_OBJECT (prefs->default_reminder), "toggled", G_CALLBACK (default_reminder_toggled), prefs);
g_signal_connect (G_OBJECT (prefs->default_reminder_interval), "changed",
G_CALLBACK (default_reminder_interval_changed), prefs);
@@ -570,39 +439,15 @@ setup_changes (CalendarPrefsDialog *prefs)
g_signal_connect (G_OBJECT (prefs->notify_with_tray), "toggled", G_CALLBACK (notify_with_tray_toggled), prefs);
g_signal_connect (G_OBJECT (prefs->alarm_list_widget), "selection_changed", G_CALLBACK (alarms_selection_changed), prefs);
-
- g_signal_connect (G_OBJECT (prefs->template_url), "changed", G_CALLBACK (template_url_changed), prefs);
-}
-
-/* Shows the current Free/Busy settings in the dialog */
-static void
-show_fb_config (CalendarPrefsDialog *prefs)
-{
- gchar *template_url;
-
- template_url = calendar_config_get_free_busy_template ();
- gtk_entry_set_text (GTK_ENTRY (prefs->template_url), (template_url ? template_url : ""));
-
- g_free (template_url);
}
/* Shows the current task list settings in the dialog */
static void
show_task_list_config (CalendarPrefsDialog *prefs)
{
- GtkColorButton *color_button;
- GdkColor color;
CalUnits units;
gboolean hide_completed_tasks;
- color_button = GTK_COLOR_BUTTON (prefs->tasks_due_today_color);
- calendar_config_get_tasks_due_today_color (&color);
- gtk_color_button_set_color (color_button, &color);
-
- color_button = GTK_COLOR_BUTTON (prefs->tasks_overdue_color);
- calendar_config_get_tasks_overdue_color (&color);
- gtk_color_button_set_color (color_button, &color);
-
/* Hide Completed Tasks. */
hide_completed_tasks = calendar_config_get_hide_completed_tasks ();
e_dialog_toggle_set (prefs->tasks_hide_completed, hide_completed_tasks);
@@ -660,39 +505,16 @@ show_alarms_config (CalendarPrefsDialog *prefs)
static void
show_config (CalendarPrefsDialog *prefs)
{
- CalWeekdays working_days;
- gint mask, day, week_start_day, time_divisions;
- icaltimezone *zone;
- gboolean sensitive, set = FALSE;
- gchar *location;
+ gint time_divisions;
+ gboolean set = FALSE;
CalUnits units;
gint interval;
- /* Use system timezone */
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->use_system_tz_check), calendar_config_get_use_system_timezone ());
- gtk_widget_set_sensitive (prefs->system_tz_label, FALSE);
- update_system_tz_widgets (prefs);
-
- /* Timezone. */
- location = calendar_config_get_timezone_stored ();
- zone = icaltimezone_get_builtin_timezone (location);
- e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (prefs->timezone), zone);
- g_free (location);
-
/* Day's second zone */
update_day_second_zone_caption (prefs);
- /* Working Days. */
- working_days = calendar_config_get_working_days ();
- mask = 1 << 0;
- for (day = 0; day < 7; day++) {
- e_dialog_toggle_set (prefs->working_days[day], (working_days & mask) ? TRUE : FALSE);
- mask <<= 1;
- }
-
- /* Week Start Day. */
- week_start_day = calendar_config_get_week_start_day ();
- e_dialog_combo_box_set (prefs->week_start_day, week_start_day, week_start_day_map);
+ /* Day's second zone */
+ update_day_second_zone_caption (prefs);
/* Start of Day. */
e_date_edit_set_time_of_day (E_DATE_EDIT (prefs->start_of_day), calendar_config_get_day_start_hour (), calendar_config_get_day_start_minute ());
@@ -700,32 +522,10 @@ show_config (CalendarPrefsDialog *prefs)
/* End of Day. */
e_date_edit_set_time_of_day (E_DATE_EDIT (prefs->end_of_day), calendar_config_get_day_end_hour (), calendar_config_get_day_end_minute ());
- /* 12/24 Hour Format. */
- if (calendar_config_get_24_hour_format ())
- e_dialog_toggle_set (prefs->use_24_hour, TRUE);
- else
- e_dialog_toggle_set (prefs->use_12_hour, TRUE);
-
- sensitive = calendar_config_locale_supports_12_hour_format ();
- gtk_widget_set_sensitive (prefs->use_12_hour, sensitive);
- gtk_widget_set_sensitive (prefs->use_24_hour, sensitive);
-
/* Time Divisions. */
time_divisions = calendar_config_get_time_divisions ();
e_dialog_combo_box_set (prefs->time_divisions, time_divisions, time_division_map);
- /* Show Appointment End Times. */
- e_dialog_toggle_set (prefs->show_end_times, calendar_config_get_show_event_end ());
-
- /* Compress Weekend. */
- e_dialog_toggle_set (prefs->compress_weekend, calendar_config_get_compress_weekend ());
-
- /* Date Navigator - Show Week Numbers. */
- e_dialog_toggle_set (prefs->dnav_show_week_no, calendar_config_get_dnav_show_week_no ());
-
- /* Day/Work Week view - Show Week Number. */
- e_dialog_toggle_set (prefs->dview_show_week_no, calendar_config_get_dview_show_week_no ());
-
/* Month View - Scroll by a week */
e_dialog_toggle_set (prefs->month_scroll_by_week, calendar_config_get_month_scroll_by_week ());
@@ -735,11 +535,7 @@ show_config (CalendarPrefsDialog *prefs)
/* Alarms list*/
show_alarms_config (prefs);
- /* Free/Busy */
- show_fb_config (prefs);
-
/* Other page */
- e_dialog_toggle_set (prefs->confirm_delete, calendar_config_get_confirm_delete ());
e_dialog_toggle_set (prefs->default_reminder, calendar_config_get_use_default_reminder ());
e_dialog_spin_set (prefs->default_reminder_interval, calendar_config_get_default_reminder_interval ());
e_dialog_combo_box_set (prefs->default_reminder_units, calendar_config_get_default_reminder_units (), default_reminder_units_map);
@@ -774,25 +570,26 @@ eccp_free (EConfig *ec, GSList *items, gpointer data)
}
static void
-calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs)
+calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs,
+ EShell *shell)
{
GladeXML *gui;
ECalConfig *ec;
ECalConfigTargetPrefs *target;
+ EShellSettings *shell_settings;
+ gboolean locale_supports_12_hour_format;
gint i;
- GtkWidget *toplevel, *table;
+ GtkWidget *toplevel;
+ GtkWidget *widget;
+ GtkWidget *table;
GSList *l;
- const gchar *working_day_names[] = {
- "sun_button",
- "mon_button",
- "tue_button",
- "wed_button",
- "thu_button",
- "fri_button",
- "sat_button",
- };
gchar *gladefile;
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ locale_supports_12_hour_format =
+ calendar_config_locale_supports_12_hour_format ();
+
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
"cal-prefs-dialog.glade",
NULL);
@@ -816,19 +613,97 @@ calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs)
l = g_slist_prepend (l, &eccp_items[i]);
e_config_add_items ((EConfig *) ec, l, NULL, NULL, eccp_free, prefs);
+ widget = glade_xml_get_widget (gui, "use-system-tz-check");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-use-system-timezone",
+ G_OBJECT (widget), "active");
+ g_signal_connect (
+ G_OBJECT (shell_settings), "notify::cal-use-system-timezone",
+ G_CALLBACK (update_system_tz_widgets), prefs);
+
+ widget = glade_xml_get_widget (gui, "timezone");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-timezone",
+ G_OBJECT (widget), "timezone");
+ e_mutual_binding_new_with_negation (
+ G_OBJECT (shell_settings), "cal-use-system-timezone",
+ G_OBJECT (widget), "sensitive");
+
/* General tab */
- prefs->use_system_tz_check = glade_xml_get_widget (gui, "use-system-tz-check");
prefs->system_tz_label = glade_xml_get_widget (gui, "system-tz-label");
- prefs->timezone = glade_xml_get_widget (gui, "timezone");
prefs->day_second_zone = glade_xml_get_widget (gui, "day_second_zone");
- for (i = 0; i < 7; i++)
- prefs->working_days[i] = glade_xml_get_widget (gui, working_day_names[i]);
- prefs->week_start_day = glade_xml_get_widget (gui, "week_start_day");
- prefs->start_of_day = glade_xml_get_widget (gui, "start_of_day");
- prefs->end_of_day = glade_xml_get_widget (gui, "end_of_day");
- prefs->use_12_hour = glade_xml_get_widget (gui, "use_12_hour");
- prefs->use_24_hour = glade_xml_get_widget (gui, "use_24_hour");
- prefs->confirm_delete = glade_xml_get_widget (gui, "confirm_delete");
+
+ widget = glade_xml_get_widget (gui, "sun_button");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-working-days-sunday",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "mon_button");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-working-days-monday",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "tue_button");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-working-days-tuesday",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "wed_button");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-working-days-wednesday",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "thu_button");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-working-days-thursday",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "fri_button");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-working-days-friday",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "sat_button");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-working-days-saturday",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "week_start_day");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-week-start-day",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "start_of_day");
+ prefs->start_of_day = widget; /* XXX delete this */
+ if (locale_supports_12_hour_format)
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-use-24-hour-format",
+ G_OBJECT (widget), "use-24-hour-format");
+
+ widget = glade_xml_get_widget (gui, "end_of_day");
+ prefs->end_of_day = widget; /* XXX delete this */
+ if (locale_supports_12_hour_format)
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-use-24-hour-format",
+ G_OBJECT (widget), "use-24-hour-format");
+
+ widget = glade_xml_get_widget (gui, "use_12_hour");
+ gtk_widget_set_sensitive (widget, locale_supports_12_hour_format);
+ e_mutual_binding_new_with_negation (
+ G_OBJECT (shell_settings), "cal-use-24-hour-format",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "use_24_hour");
+ gtk_widget_set_sensitive (widget, locale_supports_12_hour_format);
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-use-24-hour-format",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "confirm_delete");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-confirm-delete",
+ G_OBJECT (widget), "active");
+
prefs->default_reminder = glade_xml_get_widget (gui, "default_reminder");
prefs->default_reminder_interval = glade_xml_get_widget (gui, "default_reminder_interval");
prefs->default_reminder_units = glade_xml_get_widget (gui, "default_reminder_units");
@@ -838,13 +713,45 @@ calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs)
/* Display tab */
prefs->time_divisions = glade_xml_get_widget (gui, "time_divisions");
- prefs->show_end_times = glade_xml_get_widget (gui, "show_end_times");
- prefs->compress_weekend = glade_xml_get_widget (gui, "compress_weekend");
- prefs->dnav_show_week_no = glade_xml_get_widget (gui, "dnav_show_week_no");
- prefs->dview_show_week_no = glade_xml_get_widget (gui, "dview_show_week_no");
+
+ widget = glade_xml_get_widget (gui, "show_end_times");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-show-event-end-times",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "compress_weekend");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-compress-weekend",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "dnav_show_week_no");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-show-week-numbers",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "dview_show_week_no");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-day-view-show-week-numbers",
+ G_OBJECT (widget), "active");
+
prefs->month_scroll_by_week = glade_xml_get_widget (gui, "month_scroll_by_week");
- prefs->tasks_due_today_color = glade_xml_get_widget (gui, "tasks_due_today_color");
- prefs->tasks_overdue_color = glade_xml_get_widget (gui, "tasks_overdue_color");
+
+ widget = glade_xml_get_widget (gui, "tasks_due_today_color");
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-tasks-color-due-today",
+ G_OBJECT (widget), "color",
+ e_binding_transform_string_to_color,
+ e_binding_transform_color_to_string,
+ (GDestroyNotify) NULL, NULL);
+
+ widget = glade_xml_get_widget (gui, "tasks_overdue_color");
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-tasks-color-overdue",
+ G_OBJECT (widget), "color",
+ e_binding_transform_string_to_color,
+ e_binding_transform_color_to_string,
+ (GDestroyNotify) NULL, NULL);
+
prefs->tasks_hide_completed = glade_xml_get_widget (gui, "tasks_hide_completed");
prefs->tasks_hide_completed_interval = glade_xml_get_widget (gui, "tasks_hide_completed_interval");
prefs->tasks_hide_completed_units = glade_xml_get_widget (gui, "tasks_hide_completed_units");
@@ -854,7 +761,10 @@ calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs)
prefs->scrolled_window = glade_xml_get_widget (gui, "calendar-source-scrolled-window");
/* Free/Busy tab */
- prefs->template_url = glade_xml_get_widget (gui, "template_url");
+ widget = glade_xml_get_widget (gui, "template_url");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-free-busy-template",
+ G_OBJECT (widget), "text");
target = e_cal_config_target_new_prefs (ec, prefs->gconf);
e_config_set_target ((EConfig *)ec, (EConfigTarget *) target);
toplevel = e_config_create_widget ((EConfig *)ec);
@@ -893,14 +803,18 @@ calendar_prefs_dialog_get_type (void)
}
GtkWidget *
-calendar_prefs_dialog_new (void)
+calendar_prefs_dialog_new (EShell *shell)
{
CalendarPrefsDialog *dialog;
- dialog = (CalendarPrefsDialog *) g_object_new (calendar_prefs_dialog_get_type (), NULL);
- calendar_prefs_dialog_construct (dialog);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ dialog = g_object_new (CALENDAR_TYPE_PREFS_DIALOG, NULL);
+
+ /* FIXME Kill this function. */
+ calendar_prefs_dialog_construct (dialog, shell);
- return (GtkWidget *) dialog;
+ return GTK_WIDGET (dialog);
}
/* called by libglade to create our custom EDateEdit widgets. */
@@ -912,7 +826,6 @@ cal_prefs_dialog_create_time_edit (void)
dedit = e_date_edit_new ();
gtk_widget_show (GTK_WIDGET (dedit));
- e_date_edit_set_use_24_hour_format (E_DATE_EDIT (dedit), calendar_config_get_24_hour_format ());
e_date_edit_set_time_popup_range (E_DATE_EDIT (dedit), 0, 24);
e_date_edit_set_show_date (E_DATE_EDIT (dedit), FALSE);
diff --git a/calendar/gui/dialogs/cal-prefs-dialog.h b/calendar/gui/dialogs/cal-prefs-dialog.h
index 611d4aabcc..ceaa379474 100644
--- a/calendar/gui/dialogs/cal-prefs-dialog.h
+++ b/calendar/gui/dialogs/cal-prefs-dialog.h
@@ -21,14 +21,33 @@
*
*/
-#ifndef _CAL_PREFS_DIALOG_H_
-#define _CAL_PREFS_DIALOG_H_
+#ifndef CAL_PREFS_DIALOG_H
+#define CAL_PREFS_DIALOG_H
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gconf/gconf-client.h>
#include <libedataserverui/e-source-selector.h>
-#include "evolution-config-control.h"
+#include <shell/e-shell.h>
+
+/* Standard GObject macros */
+#define CALENDAR_TYPE_PREFS_DIALOG \
+ (calendar_prefs_dialog_get_type ())
+#define CALENDAR_PREFS_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CALENDAR_TYPE_PREFS_DIALOG, CalendarPrefsDialog))
+#define CALENDAR_PREFS_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CALENDAR_TYPE_PREFS_DIALOG, CalendarPrefsDialogClass))
+#define CALENDAR_IS_PREFS_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CALENDAR_TYPE_PREFS_DIALOG))
+#define CALENDAR_IS_PREFS_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CALENDAR_TYPE_PREFS_DIALOG))
+#define CALENDAR_PREFS_DIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CALENDAR_TYPE_PREFS_DIALOG, CalendarPrefsDialogClass))
G_BEGIN_DECLS
@@ -43,16 +62,12 @@ struct _CalendarPrefsDialog {
GConfClient *gconf;
/* General tab */
- GtkWidget *use_system_tz_check;
GtkWidget *system_tz_label;
- GtkWidget *timezone;
GtkWidget *day_second_zone;
GtkWidget *working_days[7];
GtkWidget *week_start_day;
GtkWidget *start_of_day;
GtkWidget *end_of_day;
- GtkWidget *use_12_hour;
- GtkWidget *use_24_hour;
GtkWidget *confirm_delete;
GtkWidget *default_reminder;
GtkWidget *default_reminder_interval;
@@ -68,8 +83,6 @@ struct _CalendarPrefsDialog {
GtkWidget *dnav_show_week_no;
GtkWidget *dview_show_week_no;
GtkWidget *month_scroll_by_week;
- GtkWidget *tasks_due_today_color;
- GtkWidget *tasks_overdue_color;
GtkWidget *tasks_hide_completed;
GtkWidget *tasks_hide_completed_interval;
GtkWidget *tasks_hide_completed_units;
@@ -96,9 +109,9 @@ struct _CalendarPrefsDialogClass {
GtkVBoxClass parent;
};
-GType calendar_prefs_dialog_get_type (void);
-GtkWidget *calendar_prefs_dialog_new (void);
+GType calendar_prefs_dialog_get_type (void);
+GtkWidget * calendar_prefs_dialog_new (EShell *shell);
G_END_DECLS
-#endif /* _CAL_PREFS_DIALOG_H_ */
+#endif /* CAL_PREFS_DIALOG_H */
diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c
index fa5d9a6583..6fc05d4a92 100644
--- a/calendar/gui/dialogs/comp-editor-util.c
+++ b/calendar/gui/dialogs/comp-editor-util.c
@@ -32,8 +32,9 @@
#include <glib/gi18n.h>
#include <libedataserver/e-time-utils.h>
#include <libecal/e-cal-time-util.h>
+#include "e-util/e-binding.h"
+#include "widgets/misc/e-dateedit.h"
#include "../calendar-config.h"
-#include "../e-date-edit-config.h"
#include "../itip-utils.h"
#include "comp-editor-util.h"
@@ -205,16 +206,9 @@ comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label)
gtk_label_set_text (GTK_LABEL (label), buffer);
}
-static void
-date_edit_destroy_cb (EDateEdit *date_edit, gpointer data)
-{
- EDateEditConfig *config = data;
-
- g_object_unref (config);
-}
-
/**
* comp_editor_new_date_edit:
+ * @shell_settings: an #EShellSettings
* @show_date: Whether to show a date picker in the widget.
* @show_time: Whether to show a time picker in the widget.
* @make_time_insensitive: Whether the time field is made insensitive rather
@@ -226,11 +220,14 @@ date_edit_destroy_cb (EDateEdit *date_edit, gpointer data)
* Return value: A newly-created #EDateEdit widget.
**/
GtkWidget *
-comp_editor_new_date_edit (gboolean show_date, gboolean show_time,
- gboolean make_time_insensitive)
+comp_editor_new_date_edit (EShellSettings *shell_settings,
+ gboolean show_date,
+ gboolean show_time,
+ gboolean make_time_insensitive)
{
EDateEdit *dedit;
- EDateEditConfig *config;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
dedit = E_DATE_EDIT (e_date_edit_new ());
@@ -242,8 +239,13 @@ comp_editor_new_date_edit (gboolean show_date, gboolean show_time,
e_date_edit_set_make_time_insensitive (dedit, FALSE);
#endif
- config = e_date_edit_config_new (dedit);
- g_signal_connect (G_OBJECT (dedit), "destroy", G_CALLBACK (date_edit_destroy_cb), config);
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-show-week-numbers",
+ G_OBJECT (dedit), "show-week-numbers");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-week-start-day",
+ G_OBJECT (dedit), "week-start-day");
return GTK_WIDGET (dedit);
}
diff --git a/calendar/gui/dialogs/comp-editor-util.h b/calendar/gui/dialogs/comp-editor-util.h
index cebb8f74c1..ec481fa457 100644
--- a/calendar/gui/dialogs/comp-editor-util.h
+++ b/calendar/gui/dialogs/comp-editor-util.h
@@ -26,6 +26,7 @@
#define _COMP_EDITOR_UTIL_H_
#include <gtk/gtk.h>
+#include <shell/e-shell-settings.h>
#include "comp-editor-page.h"
#include "../e-meeting-attendee.h"
@@ -34,8 +35,10 @@ void comp_editor_free_dates (CompEditorPageDates *dates);
void comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label);
-GtkWidget *comp_editor_new_date_edit (gboolean show_date, gboolean show_time,
- gboolean make_time_insensitive);
+GtkWidget * comp_editor_new_date_edit (EShellSettings *shell_settings,
+ gboolean show_date,
+ gboolean show_time,
+ gboolean make_time_insensitive);
struct tm comp_editor_get_current_time (GtkObject *object, gpointer data);
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 5097c9f336..8995b0eddc 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -39,7 +39,7 @@
#include <e-util/e-dialog-utils.h>
#include <e-util/e-util-private.h>
#include <e-util/gconf-bridge.h>
-#include <evolution-shell-component-utils.h>
+#include <shell/e-shell.h>
#include <camel/camel-url.h>
#include <camel/camel-exception.h>
@@ -61,7 +61,6 @@
#include "recur-comp.h"
#include "comp-editor.h"
#include "comp-editor-util.h"
-#include "../e-cal-popup.h"
#include "../calendar-config-keys.h"
#include "cal-attachment-select-file.h"
#include "widgets/misc/e-attachment-view.h"
@@ -79,6 +78,9 @@ static gboolean comp_lite = FALSE;
/* Private part of the CompEditor structure */
struct _CompEditorPrivate {
+
+ gpointer shell; /* weak pointer */
+
/* Client to use */
ECal *client;
@@ -128,6 +130,7 @@ enum {
PROP_CHANGED,
PROP_CLIENT,
PROP_FLAGS,
+ PROP_SHELL,
PROP_SUMMARY
};
@@ -136,7 +139,10 @@ static const gchar *ui =
" <menubar action='main-menu'>"
" <menu action='file-menu'>"
" <menuitem action='save'/>"
+" <separator/>"
+" <menuitem action='print-preview'/>"
" <menuitem action='print'/>"
+" <separator/>"
" <menuitem action='close'/>"
" </menu>"
" <menu action='edit-menu'>"
@@ -173,8 +179,8 @@ static void close_dialog (CompEditor *editor);
static void page_dates_changed_cb (CompEditor *editor, CompEditorPageDates *dates, CompEditorPage *page);
-static void obj_modified_cb (ECal *client, GList *objs, gpointer data);
-static void obj_removed_cb (ECal *client, GList *uids, gpointer data);
+static void obj_modified_cb (ECal *client, GList *objs, CompEditor *editor);
+static void obj_removed_cb (ECal *client, GList *uids, CompEditor *editor);
G_DEFINE_TYPE (CompEditor, comp_editor, GTK_TYPE_WINDOW)
@@ -183,7 +189,15 @@ enum {
LAST_SIGNAL
};
-static guint comp_editor_signals[LAST_SIGNAL] = { 0 };
+static guint signals[LAST_SIGNAL];
+static GList *active_editors;
+
+static void
+comp_editor_weak_notify_cb (gpointer unused,
+ GObject *where_the_object_was)
+{
+ active_editors = g_list_remove (active_editors, where_the_object_was);
+}
static void
attachment_store_changed_cb (CompEditor *editor)
@@ -716,17 +730,22 @@ action_print_cb (GtkAction *action,
CompEditor *editor)
{
CompEditorPrivate *priv = editor->priv;
+ GtkPrintOperationAction print_action;
ECalComponent *comp;
GList *l;
- icalcomponent *icalcomp = e_cal_component_get_icalcomponent (priv->comp);
+ icalcomponent *component;
+ icalcomponent *clone;
comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ component = e_cal_component_get_icalcomponent (priv->comp);
+ clone = icalcomponent_new_clone (component);
+ e_cal_component_set_icalcomponent (comp, clone);
for (l = priv->pages; l != NULL; l = l->next)
comp_editor_page_fill_component (l->data, comp);
- print_comp (comp, priv->client, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ print_comp (comp, priv->client, print_action);
g_object_unref (comp);
}
@@ -736,15 +755,22 @@ action_print_preview_cb (GtkAction *action,
CompEditor *editor)
{
CompEditorPrivate *priv = editor->priv;
+ GtkPrintOperationAction print_action;
ECalComponent *comp;
GList *l;
- icalcomponent *icalcomp = e_cal_component_get_icalcomponent (priv->comp);
+ icalcomponent *component;
+ icalcomponent *clone;
comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ component = e_cal_component_get_icalcomponent (priv->comp);
+ clone = icalcomponent_new_clone (component);
+ e_cal_component_set_icalcomponent (comp, clone);
+
for (l = priv->pages; l != NULL; l = l->next)
comp_editor_page_fill_component (l->data, comp);
- print_comp (comp, priv->client, TRUE);
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
+ print_comp (comp, priv->client, print_action);
g_object_unref (comp);
}
@@ -812,12 +838,10 @@ action_save_cb (GtkAction *action,
if (e_cal_component_has_recurrences (priv->comp)) {
if (!recur_component_dialog (priv->client, priv->comp, &priv->mod, GTK_WINDOW (editor), delegated))
return;
-
} else if (e_cal_component_is_instance (priv->comp))
priv->mod = CALOBJ_MOD_THIS;
comp = comp_editor_get_current_comp (editor, &correct);
-
e_cal_component_get_summary (comp, &text);
g_object_unref (comp);
@@ -1199,6 +1223,17 @@ comp_editor_setup_recent_menu (CompEditor *editor)
}
static void
+comp_editor_set_shell (CompEditor *editor,
+ EShell *shell)
+{
+ g_return_if_fail (editor->priv->shell == NULL);
+
+ editor->priv->shell = shell;
+
+ g_object_add_weak_pointer (G_OBJECT (shell), &editor->priv->shell);
+}
+
+static void
comp_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -1223,6 +1258,12 @@ comp_editor_set_property (GObject *object,
g_value_get_int (value));
return;
+ case PROP_SHELL:
+ comp_editor_set_shell (
+ COMP_EDITOR (object),
+ g_value_get_object (value));
+ return;
+
case PROP_SUMMARY:
comp_editor_set_summary (
COMP_EDITOR (object),
@@ -1258,6 +1299,12 @@ comp_editor_get_property (GObject *object,
COMP_EDITOR (object)));
return;
+ case PROP_SHELL:
+ g_value_set_object (
+ value, comp_editor_get_shell (
+ COMP_EDITOR (object)));
+ return;
+
case PROP_SUMMARY:
g_value_set_string (
value, comp_editor_get_summary (
@@ -1275,6 +1322,12 @@ comp_editor_dispose (GObject *object)
priv = COMP_EDITOR_GET_PRIVATE (object);
+ if (priv->shell != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell), &priv->shell);
+ priv->shell = NULL;
+ }
+
if (priv->client) {
g_object_unref (priv->client);
priv->client = NULL;
@@ -1333,42 +1386,39 @@ static void
comp_editor_map (GtkWidget *widget)
{
CompEditor *editor = COMP_EDITOR (widget);
- GConfBridge *bridge = gconf_bridge_get ();
+ GConfBridge *bridge;
GtkAction *action;
+ const gchar *key;
+
+ bridge = gconf_bridge_get ();
/* Give subclasses a chance to construct their pages before
* we fiddle with their widgets. That's why we don't do this
* until after object construction. */
+ key = "/apps/evolution/calendar/display/show_categories";
action = comp_editor_get_action (editor, "view-categories");
- gconf_bridge_bind_property (
- bridge, CALENDAR_CONFIG_SHOW_CATEGORIES,
- G_OBJECT (action), "active");
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+ key = "/apps/evolution/calendar/display/show_role";
action = comp_editor_get_action (editor, "view-role");
- gconf_bridge_bind_property (
- bridge, CALENDAR_CONFIG_SHOW_ROLE,
- G_OBJECT (action), "active");
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+ key = "/apps/evolution/calendar/display/show_rsvp";
action = comp_editor_get_action (editor, "view-rsvp");
- gconf_bridge_bind_property (
- bridge, CALENDAR_CONFIG_SHOW_RSVP,
- G_OBJECT (action), "active");
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+ key = "/apps/evolution/calendar/display/show_status";
action = comp_editor_get_action (editor, "view-status");
- gconf_bridge_bind_property (
- bridge, CALENDAR_CONFIG_SHOW_STATUS,
- G_OBJECT (action), "active");
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+ key = "/apps/evolution/calendar/display/show_timezone";
action = comp_editor_get_action (editor, "view-time-zone");
- gconf_bridge_bind_property (
- bridge, CALENDAR_CONFIG_SHOW_TIMEZONE,
- G_OBJECT (action), "active");
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+ key = "/apps/evolution/calendar/display/show_type";
action = comp_editor_get_action (editor, "view-type");
- gconf_bridge_bind_property (
- bridge, CALENDAR_CONFIG_SHOW_TYPE,
- G_OBJECT (action), "active");
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
/* Chain up to parent's map() method. */
GTK_WIDGET_CLASS (comp_editor_parent_class)->map (widget);
@@ -1515,6 +1565,17 @@ comp_editor_class_init (CompEditorClass *class)
g_object_class_install_property (
object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ NULL,
+ NULL,
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
PROP_SUMMARY,
g_param_spec_string (
"summary",
@@ -1523,7 +1584,7 @@ comp_editor_class_init (CompEditorClass *class)
NULL,
G_PARAM_READWRITE));
- comp_editor_signals[OBJECT_CREATED] =
+ signals[OBJECT_CREATED] =
g_signal_new ("object_created",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
@@ -1547,11 +1608,18 @@ comp_editor_init (CompEditor *editor)
GtkWidget *container;
GtkWidget *widget;
GtkWidget *scroll;
+ EShell *shell;
gint n_targets;
GError *error = NULL;
editor->priv = priv = COMP_EDITOR_GET_PRIVATE (editor);
+ g_object_weak_ref (
+ G_OBJECT (editor), (GWeakNotify)
+ comp_editor_weak_notify_cb, NULL);
+
+ active_editors = g_list_prepend (active_editors, editor);
+
priv->pages = NULL;
priv->changed = FALSE;
priv->needs_send = FALSE;
@@ -1734,6 +1802,10 @@ comp_editor_init (CompEditor *editor)
g_signal_connect_swapped (
store, "row-inserted",
G_CALLBACK (attachment_store_changed_cb), editor);
+
+ /* FIXME Shell should be passed in. */
+ shell = e_shell_get_default ();
+ e_shell_watch_window (shell, GTK_WINDOW (editor));
}
static gboolean
@@ -1815,7 +1887,18 @@ close_dialog (CompEditor *editor)
gtk_widget_destroy (GTK_WIDGET (editor));
}
-
+gint
+comp_editor_compare (CompEditor *editor_a,
+ CompEditor *editor_b)
+{
+ const gchar *uid_a = NULL;
+ const gchar *uid_b = NULL;
+
+ e_cal_component_get_uid (editor_a->priv->comp, &uid_a);
+ e_cal_component_get_uid (editor_b->priv->comp, &uid_b);
+
+ return g_strcmp0 (uid_a, uid_b);
+}
void
comp_editor_set_existing_org (CompEditor *editor, gboolean existing_org)
@@ -1901,6 +1984,14 @@ comp_editor_get_classification (CompEditor *editor)
return gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
}
+EShell *
+comp_editor_get_shell (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+
+ return editor->priv->shell;
+}
+
void
comp_editor_set_summary (CompEditor *editor,
const gchar *summary)
@@ -2010,7 +2101,7 @@ comp_editor_set_flags (CompEditor *editor,
CompEditorFlags
comp_editor_get_flags (CompEditor *editor)
{
- g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), 0);
return editor->priv->flags;
}
@@ -2068,6 +2159,20 @@ comp_editor_get_managed_widget (CompEditor *editor,
return widget;
}
+CompEditor *
+comp_editor_find_instance (const gchar *uid)
+{
+ GList *link;
+
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ link = g_list_find_custom (
+ active_editors, uid,
+ (GCompareFunc) comp_editor_compare);
+
+ return (link != NULL) ? link->data : NULL;
+}
+
/**
* comp_editor_set_needs_send:
* @editor: A component editor
@@ -2391,8 +2496,14 @@ fill_widgets (CompEditor *editor)
EAttachmentStore *store;
EAttachmentView *view;
CompEditorPrivate *priv;
- GList *l;
GtkAction *action;
+ GList *iter;
+
+ view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
+ store = e_attachment_view_get_store (view);
+
+ view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
+ store = e_attachment_view_get_store (view);
view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
store = e_attachment_view_get_store (view);
@@ -2415,12 +2526,14 @@ fill_widgets (CompEditor *editor)
}
action = comp_editor_get_action (editor, "classify-public");
- g_signal_handlers_block_by_func (action, G_CALLBACK (action_classification_cb), editor);
+ g_signal_handlers_block_by_func (
+ action, G_CALLBACK (action_classification_cb), editor);
- for (l = priv->pages; l != NULL; l = l->next)
- comp_editor_page_fill_widgets (l->data, priv->comp);
+ for (iter = priv->pages; iter != NULL; iter = iter->next)
+ comp_editor_page_fill_widgets (iter->data, priv->comp);
- g_signal_handlers_unblock_by_func (action, G_CALLBACK (action_classification_cb), editor);
+ g_signal_handlers_unblock_by_func (
+ action, G_CALLBACK (action_classification_cb), editor);
}
static void
@@ -2836,9 +2949,10 @@ page_dates_changed_cb (CompEditor *editor,
}
static void
-obj_modified_cb (ECal *client, GList *objects, gpointer data)
+obj_modified_cb (ECal *client,
+ GList *objects,
+ CompEditor *editor)
{
- CompEditor *editor = COMP_EDITOR (data);
CompEditorPrivate *priv;
ECalComponent *comp = NULL;
@@ -2871,12 +2985,11 @@ obj_modified_cb (ECal *client, GList *objects, gpointer data)
}
static void
-obj_removed_cb (ECal *client, GList *uids, gpointer data)
+obj_removed_cb (ECal *client,
+ GList *uids,
+ CompEditor *editor)
{
- CompEditor *editor = COMP_EDITOR (data);
- CompEditorPrivate *priv;
-
- priv = editor->priv;
+ CompEditorPrivate *priv = editor->priv;
if (changed_component_dialog ((GtkWindow *) editor, priv->comp, TRUE, priv->changed))
close_dialog (editor);
diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h
index d95d496ffd..454f02b2e6 100644
--- a/calendar/gui/dialogs/comp-editor.h
+++ b/calendar/gui/dialogs/comp-editor.h
@@ -29,6 +29,7 @@
#include <libecal/e-cal.h>
#include "../itip-utils.h"
#include "comp-editor-page.h"
+#include <shell/e-shell.h>
/* Standard GObject macros */
#define TYPE_COMP_EDITOR \
@@ -88,6 +89,8 @@ typedef enum {
} CompEditorFlags;
GType comp_editor_get_type (void);
+gint comp_editor_compare (CompEditor *editor_a,
+ CompEditor *editor_b);
void comp_editor_set_changed (CompEditor *editor,
gboolean changed);
gboolean comp_editor_get_changed (CompEditor *editor);
@@ -107,6 +110,7 @@ void comp_editor_set_classification (CompEditor *editor,
ECalComponentClassification classification);
ECalComponentClassification
comp_editor_get_classification (CompEditor *editor);
+EShell * comp_editor_get_shell (CompEditor *editor);
void comp_editor_set_summary (CompEditor *editor,
const gchar *summary);
const gchar * comp_editor_get_summary (CompEditor *editor);
@@ -150,9 +154,11 @@ GtkActionGroup *
const gchar *group_name);
GtkWidget * comp_editor_get_managed_widget (CompEditor *editor,
const gchar *widget_path);
+CompEditor * comp_editor_find_instance (const gchar *uid);
void comp_editor_set_lite (gboolean status);
gboolean comp_editor_get_lite (void);
+
G_END_DECLS
#endif
diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c
index 7251123100..91c879928c 100644
--- a/calendar/gui/dialogs/event-editor.c
+++ b/calendar/gui/dialogs/event-editor.c
@@ -34,9 +34,9 @@
#include <glib/gi18n.h>
#include <misc/e-dateedit.h>
+#include <e-util/e-binding.h>
#include <e-util/e-plugin-ui.h>
#include <e-util/e-util-private.h>
-#include <evolution-shell-component-utils.h>
#include "event-page.h"
#include "recurrence-page.h"
@@ -249,15 +249,6 @@ static GtkActionEntry meeting_entries[] = {
};
static void
-event_editor_client_changed_cb (EventEditor *ee)
-{
- ECal *client;
-
- client = comp_editor_get_client (COMP_EDITOR (ee));
- e_meeting_store_set_e_cal (ee->priv->model, client);
-}
-
-static void
event_editor_model_changed_cb (EventEditor *ee)
{
if (!ee->priv->updating) {
@@ -370,6 +361,31 @@ event_editor_dispose (GObject *object)
}
static void
+event_editor_constructed (GObject *object)
+{
+ EventEditorPrivate *priv;
+ EShellSettings *shell_settings;
+ EShell *shell;
+
+ priv = EVENT_EDITOR_GET_PRIVATE (object);
+
+ shell = comp_editor_get_shell (COMP_EDITOR (object));
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_binding_new (
+ G_OBJECT (object), "client",
+ G_OBJECT (priv->model), "client");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-free-busy-template",
+ G_OBJECT (priv->model), "free-busy-template");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-timezone",
+ G_OBJECT (priv->model), "timezone");
+}
+
+static void
event_editor_show_categories (CompEditor *editor,
gboolean visible)
{
@@ -446,6 +462,7 @@ event_editor_class_init (EventEditorClass *class)
object_class = G_OBJECT_CLASS (class);
object_class->constructor = event_editor_constructor;
object_class->dispose = event_editor_dispose;
+ object_class->constructed = event_editor_constructed;
editor_class = COMP_EDITOR_CLASS (class);
editor_class->help_section = "usage-calendar-apts";
@@ -466,6 +483,7 @@ event_editor_init (EventEditor *ee)
GtkUIManager *ui_manager;
GtkActionGroup *action_group;
GtkAction *action;
+ const gchar *id;
GError *error = NULL;
ee->priv = EVENT_EDITOR_GET_PRIVATE (ee);
@@ -488,7 +506,10 @@ event_editor_init (EventEditor *ee)
ui_manager = comp_editor_get_ui_manager (editor);
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
- e_plugin_ui_register_manager ("event-editor", ui_manager, ee);
+
+ id = "org.gnome.evolution.event-editor";
+ e_plugin_ui_register_manager (ui_manager, id, ee);
+ e_plugin_ui_enable_manager (ui_manager, id);
if (error != NULL) {
g_critical ("%s: %s", G_STRFUNC, error->message);
@@ -499,10 +520,6 @@ event_editor_init (EventEditor *ee)
action = comp_editor_get_action (editor, "send-options");
gtk_action_set_visible (action, FALSE);
- g_signal_connect (
- ee, "notify::client",
- G_CALLBACK (event_editor_client_changed_cb), NULL);
-
g_signal_connect_swapped (
ee->priv->model, "row_changed",
G_CALLBACK (event_editor_model_changed_cb), ee);
@@ -637,7 +654,7 @@ event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboo
ECal *client;
gboolean result;
- client = e_meeting_store_get_e_cal (priv->model);
+ client = e_meeting_store_get_client (priv->model);
result = itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp,
client, NULL, NULL, NULL, strip_alarms, FALSE);
g_object_unref (comp);
@@ -663,13 +680,16 @@ event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboo
* editor could not be created.
**/
CompEditor *
-event_editor_new (ECal *client, CompEditorFlags flags)
+event_editor_new (ECal *client,
+ EShell *shell,
+ CompEditorFlags flags)
{
g_return_val_if_fail (E_IS_CAL (client), NULL);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
return g_object_new (
TYPE_EVENT_EDITOR,
- "flags", flags, "client", client, NULL);
+ "client", client, "flags", flags, "shell", shell, NULL);
}
void
diff --git a/calendar/gui/dialogs/event-editor.h b/calendar/gui/dialogs/event-editor.h
index 03afd6448a..abb8f0e659 100644
--- a/calendar/gui/dialogs/event-editor.h
+++ b/calendar/gui/dialogs/event-editor.h
@@ -66,6 +66,7 @@ struct _EventEditorClass {
GType event_editor_get_type (void);
CompEditor * event_editor_new (ECal *client,
+ EShell *shell,
CompEditorFlags flags);
void event_editor_show_meeting (EventEditor *ee);
diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c
index eb95245128..5a9b8ec47a 100644
--- a/calendar/gui/dialogs/event-page.c
+++ b/calendar/gui/dialogs/event-page.c
@@ -39,7 +39,6 @@
#include "common/authentication.h"
#include "e-util/e-categories-config.h"
#include "e-util/e-dialog-widgets.h"
-#include "e-util/e-popup.h"
#include "misc/e-dateedit.h"
#include "misc/e-send-options.h"
#include <libecal/e-cal-time-util.h>
@@ -52,7 +51,6 @@
#include "../e-meeting-attendee.h"
#include "../e-meeting-store.h"
#include "../e-meeting-list-view.h"
-#include "../e-cal-popup.h"
#include "comp-editor.h"
#include "comp-editor-util.h"
#include "../e-alarm-list.h"
@@ -384,9 +382,11 @@ update_time (EventPage *epage, ECalComponentDateTime *start_date, ECalComponentD
EventPagePrivate *priv = epage->priv;
CompEditor *editor;
ECal *client;
+ GtkAction *action;
struct icaltimetype *start_tt, *end_tt, implied_tt;
icaltimezone *start_zone = NULL, *def_zone = NULL;
gboolean all_day_event, homezone=TRUE;
+ gboolean show_timezone;
editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
client = comp_editor_get_client (editor);
@@ -458,7 +458,9 @@ update_time (EventPage *epage, ECalComponentDateTime *start_date, ECalComponentD
if (!def_zone || !start_zone || strcmp (icaltimezone_get_tzid(def_zone), icaltimezone_get_tzid (start_zone)))
homezone = FALSE;
- event_page_set_show_timezone (epage, (calendar_config_get_show_timezone()|| !homezone) & !all_day_event);
+ action = comp_editor_get_action (editor, "view-time-zone");
+ show_timezone = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ event_page_set_show_timezone (epage, (show_timezone || !homezone) & !all_day_event);
/*unblock the endtimezone widget*/
g_signal_handlers_unblock_matched (priv->end_timezone, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage);
@@ -1833,15 +1835,10 @@ remove_clicked_cb (GtkButton *btn, EventPage *epage)
}
static void
-invite_cb (GtkWidget *widget, gpointer data)
+invite_cb (GtkWidget *widget,
+ EventPage *page)
{
- EventPage *page;
- EventPagePrivate *priv;
-
- page = EVENT_PAGE (data);
- priv = page->priv;
-
- e_meeting_list_view_invite_others_dialog (priv->list_view);
+ e_meeting_list_view_invite_others_dialog (page->priv->list_view);
}
static void
@@ -1884,102 +1881,6 @@ attendee_added_cb (EMeetingListView *emlv,
}
}
-/* Callbacks for list view*/
-static void
-popup_add_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EventPage *epage = data;
-
- add_clicked_cb (NULL, epage);
-}
-
-static void
-popup_delete_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EventPage *epage = data;
-
- remove_clicked_cb (NULL, epage);
-}
-
-enum {
- ATTENDEE_CAN_DELEGATE = 1<<1,
- ATTENDEE_CAN_DELETE = 1<<2,
- ATTENDEE_CAN_ADD = 1<<3,
- ATTENDEE_LAST = 1<<4
-};
-
-static EPopupItem context_menu_items[] = {
- { E_POPUP_ITEM, (gchar *) "10.delete", (gchar *) N_("_Remove"), popup_delete_cb, NULL, (gchar *) GTK_STOCK_REMOVE, ATTENDEE_CAN_DELETE },
- { E_POPUP_ITEM, (gchar *) "15.add", (gchar *) N_("_Add "), popup_add_cb, NULL, (gchar *) GTK_STOCK_ADD, ATTENDEE_CAN_ADD },
-};
-
-static void
-context_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static gint
-button_press_event (GtkWidget *widget, GdkEventButton *event, EventPage *epage)
-{
- EventPagePrivate *priv = epage->priv;
- CompEditor *editor;
- CompEditorFlags flags;
- GtkMenu *menu;
- EMeetingAttendee *ia;
- GtkTreePath *path;
- GtkTreeIter iter;
- gchar *address;
- guint32 disable_mask = ~0;
- GSList *menus = NULL;
- ECalPopup *ep;
- gint i;
-
- /* only process right-clicks */
- if (event->button != 3 || event->type != GDK_BUTTON_PRESS)
- return FALSE;
-
- editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
- flags = comp_editor_get_flags (editor);
-
- /* only if we right-click on an attendee */
- if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (priv->list_view), event->x, event->y, &path, NULL, NULL, NULL)) {
- GtkTreeSelection *selection;
-
- if (gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->model), &iter, path)) {
-
- gtk_tree_model_get (GTK_TREE_MODEL (priv->model), &iter, E_MEETING_STORE_ADDRESS_COL, &address, -1);
- ia = e_meeting_store_find_attendee (priv->model, address, &priv->row);
- g_free (address);
-
- if (ia) {
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->list_view));
- gtk_tree_selection_unselect_all (selection);
- gtk_tree_selection_select_path (selection, path);
-
- if (e_meeting_attendee_get_edit_level (ia) == E_MEETING_ATTENDEE_EDIT_FULL)
- disable_mask &= ~ATTENDEE_CAN_DELETE;
- }
- }
- }
-
- if (GTK_WIDGET_IS_SENSITIVE(priv->add))
- disable_mask &= ~ATTENDEE_CAN_ADD;
- else if (flags & COMP_EDITOR_USER_ORG)
- disable_mask &= ~ATTENDEE_CAN_ADD;
-
- ep = e_cal_popup_new("org.gnome.evolution.calendar.meeting.popup");
-
- for (i=0;i<sizeof(context_menu_items)/sizeof(context_menu_items[0]);i++)
- menus = g_slist_prepend(menus, &context_menu_items[i]);
-
- e_popup_add_items((EPopup *)ep, menus, NULL, context_popup_free, epage);
- menu = e_popup_create_menu_once((EPopup *)ep, NULL, disable_mask);
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button, event->time);
-
- return TRUE;
-}
-
static gboolean
list_view_event (EMeetingListView *list_view, GdkEvent *event, EventPage *epage) {
@@ -2032,6 +1933,7 @@ event_page_set_all_day_event (EventPage *epage, gboolean all_day)
CompEditor *editor;
GtkAction *action;
gboolean date_set;
+ gboolean active;
editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
@@ -2110,7 +2012,10 @@ event_page_set_all_day_event (EventPage *epage, gboolean all_day)
TRUE);
}
- event_page_set_show_timezone (epage, calendar_config_get_show_timezone() & !all_day);
+ action = comp_editor_get_action (editor, "view-time-zone");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ event_page_set_show_timezone (epage, active & !all_day);
+
g_signal_handlers_block_matched (priv->start_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage);
g_signal_handlers_block_matched (priv->end_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage);
@@ -2192,10 +2097,12 @@ event_page_set_info_string (EventPage *epage, const gchar *icon, const gchar *ms
static gboolean
get_widgets (EventPage *epage)
{
+ CompEditor *editor;
CompEditorPage *page = COMP_EDITOR_PAGE (epage);
GtkEntryCompletion *completion;
EventPagePrivate *priv;
GSList *accel_groups;
+ GtkAction *action;
GtkWidget *toplevel;
GtkWidget *sw;
@@ -2203,6 +2110,8 @@ get_widgets (EventPage *epage)
#define GW(name) glade_xml_get_widget (priv->xml, name)
+ editor = comp_editor_page_get_editor (page);
+
priv->main = GW ("event-page");
if (!priv->main)
return FALSE;
@@ -2224,7 +2133,8 @@ get_widgets (EventPage *epage)
gtk_widget_show (priv->status_icons);
- if (!calendar_config_get_show_timezone()) {
+ action = comp_editor_get_action (editor, "view-time-zone");
+ if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
gtk_widget_hide (priv->timezone_label);
gtk_widget_hide (priv->start_timezone);
} else {
@@ -2503,14 +2413,10 @@ times_updated (EventPage *epage, gboolean adjust_end_time)
* start date < end date and we set the "all day event" button as appropriate.
*/
static void
-start_date_changed_cb (GtkWidget *dedit, gpointer data)
+start_date_changed_cb (GtkWidget *dedit,
+ EventPage *epage)
{
- EventPage *epage;
-
- epage = EVENT_PAGE (data);
-
hour_minute_changed (epage);
-
times_updated (epage, TRUE);
}
@@ -2518,12 +2424,9 @@ start_date_changed_cb (GtkWidget *dedit, gpointer data)
* start date < end date and we set the "all day event" button as appropriate.
*/
static void
-end_date_changed_cb (GtkWidget *dedit, gpointer data)
+end_date_changed_cb (GtkWidget *dedit,
+ EventPage *epage)
{
- EventPage *epage;
-
- epage = EVENT_PAGE (data);
-
times_updated (epage, FALSE);
}
@@ -2532,15 +2435,12 @@ end_date_changed_cb (GtkWidget *dedit, gpointer data)
* labels on the other notebook pages.
*/
static void
-start_timezone_changed_cb (GtkWidget *widget, gpointer data)
+start_timezone_changed_cb (GtkWidget *widget,
+ EventPage *epage)
{
- EventPage *epage;
- EventPagePrivate *priv;
+ EventPagePrivate *priv = epage->priv;
icaltimezone *zone;
- epage = EVENT_PAGE (data);
- priv = epage->priv;
-
if (priv->sync_timezones) {
zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone));
comp_editor_page_set_updating (COMP_EDITOR_PAGE (epage), TRUE);
@@ -2557,17 +2457,13 @@ start_timezone_changed_cb (GtkWidget *widget, gpointer data)
* category list dialog.
*/
static void
-categories_clicked_cb (GtkWidget *button, gpointer data)
+categories_clicked_cb (GtkWidget *button,
+ EventPage *epage)
{
- EventPage *epage;
- EventPagePrivate *priv;
- GtkWidget *entry;
-
- epage = EVENT_PAGE (data);
- priv = epage->priv;
+ GtkEntry *entry;
- entry = priv->categories;
- e_categories_config_open_dialog_for_entry (GTK_ENTRY (entry));
+ entry = GTK_ENTRY (epage->priv->categories);
+ e_categories_config_open_dialog_for_entry (entry);
}
void
@@ -2692,13 +2588,10 @@ set_subscriber_info_string (EventPage *epage, const gchar *backend_address)
}
static void
-alarm_changed_cb (GtkWidget *widget, gpointer data)
+alarm_changed_cb (GtkWidget *widget,
+ EventPage *epage)
{
- EventPage *epage;
- EventPagePrivate *priv;
-
- epage = EVENT_PAGE (data);
- priv = epage->priv;
+ EventPagePrivate *priv = epage->priv;
if (e_dialog_combo_box_get (priv->alarm_time_combo, priv->alarm_map) != ALARM_NONE) {
ECalComponentAlarm *ca;
@@ -2840,7 +2733,9 @@ init_widgets (EventPage *epage)
GtkTextBuffer *text_buffer;
icaltimezone *zone;
gchar *combo_label = NULL;
+ GtkAction *action;
GtkTreeSelection *selection;
+ gboolean active;
ECal *client;
editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
@@ -2896,16 +2791,32 @@ init_widgets (EventPage *epage)
g_signal_connect((priv->start_timezone), "changed",
G_CALLBACK (start_timezone_changed_cb), epage);
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_ATTENDEE_COL, TRUE);
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_ROLE_COL, calendar_config_get_show_role ());
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_RSVP_COL, calendar_config_get_show_rsvp ());
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_STATUS_COL, calendar_config_get_show_status ());
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_TYPE_COL, calendar_config_get_show_type ());
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_ATTENDEE_COL, TRUE);
+
+ action = comp_editor_get_action (editor, "view-role");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_ROLE_COL, active);
+
+ action = comp_editor_get_action (editor, "view-rsvp");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_RSVP_COL, active);
+
+ action = comp_editor_get_action (editor, "view-status");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_STATUS_COL, active);
+
+ action = comp_editor_get_action (editor, "view-type");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_TYPE_COL, active);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->list_view));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
- g_signal_connect (G_OBJECT (priv->list_view), "button_press_event", G_CALLBACK (button_press_event), epage);
g_signal_connect (G_OBJECT (priv->list_view), "event", G_CALLBACK (list_view_event), epage);
g_signal_connect (priv->list_view, "key_press_event", G_CALLBACK (list_key_press), epage);
@@ -2936,7 +2847,8 @@ init_widgets (EventPage *epage)
gtk_widget_show (GTK_WIDGET (priv->list_view));
/* categories */
- if (!calendar_config_get_show_categories()) {
+ action = comp_editor_get_action (editor, "view-categories");
+ if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
gtk_widget_hide (priv->categories_btn);
gtk_widget_hide (priv->categories);
} else {
@@ -3030,7 +2942,9 @@ init_widgets (EventPage *epage)
e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->start_timezone), zone);
e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->end_timezone), zone);
- event_page_set_show_timezone (epage, calendar_config_get_show_timezone());
+ action = comp_editor_get_action (editor, "view-time-zone");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ event_page_set_show_timezone (epage, active);
return TRUE;
}
@@ -3194,7 +3108,13 @@ GtkWidget *make_date_edit (void);
GtkWidget *
make_date_edit (void)
{
- return comp_editor_new_date_edit (TRUE, TRUE, TRUE);
+ EShell *shell;
+ EShellSettings *shell_settings;
+
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ return comp_editor_new_date_edit (shell_settings, TRUE, TRUE, TRUE);
}
GtkWidget *make_timezone_entry (void);
diff --git a/calendar/gui/dialogs/memo-editor.c b/calendar/gui/dialogs/memo-editor.c
index cf3781a3c2..bda54e55eb 100644
--- a/calendar/gui/dialogs/memo-editor.c
+++ b/calendar/gui/dialogs/memo-editor.c
@@ -34,7 +34,6 @@
#include <e-util/e-plugin-ui.h>
#include <e-util/e-util-private.h>
-#include <evolution-shell-component-utils.h>
#include "memo-page.h"
#include "cancel-comp.h"
@@ -135,6 +134,7 @@ memo_editor_init (MemoEditor *me)
{
CompEditor *editor = COMP_EDITOR (me);
GtkUIManager *ui_manager;
+ const gchar *id;
GError *error = NULL;
me->priv = MEMO_EDITOR_GET_PRIVATE (me);
@@ -142,7 +142,10 @@ memo_editor_init (MemoEditor *me)
ui_manager = comp_editor_get_ui_manager (editor);
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
- e_plugin_ui_register_manager ("memo-editor", ui_manager, me);
+
+ id = "org.gnome.evolution.memo-editor";
+ e_plugin_ui_register_manager (ui_manager, id, me);
+ e_plugin_ui_enable_manager (ui_manager, id);
if (error != NULL) {
g_critical ("%s: %s", G_STRFUNC, error->message);
@@ -160,11 +163,14 @@ memo_editor_init (MemoEditor *me)
* editor could not be created.
**/
CompEditor *
-memo_editor_new (ECal *client, CompEditorFlags flags)
+memo_editor_new (ECal *client,
+ EShell *shell,
+ CompEditorFlags flags)
{
g_return_val_if_fail (E_IS_CAL (client), NULL);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
return g_object_new (
TYPE_MEMO_EDITOR,
- "flags", flags, "client", client, NULL);
+ "client", client, "flags", flags, "shell", shell, NULL);
}
diff --git a/calendar/gui/dialogs/memo-editor.h b/calendar/gui/dialogs/memo-editor.h
index 2e431b507f..cd4bc194ac 100644
--- a/calendar/gui/dialogs/memo-editor.h
+++ b/calendar/gui/dialogs/memo-editor.h
@@ -68,6 +68,7 @@ struct _MemoEditorClass {
GType memo_editor_get_type (void);
CompEditor * memo_editor_new (ECal *client,
+ EShell *shell,
CompEditorFlags flags);
G_END_DECLS
diff --git a/calendar/gui/dialogs/memo-page.c b/calendar/gui/dialogs/memo-page.c
index 8026a467ee..595a0e409e 100644
--- a/calendar/gui/dialogs/memo-page.c
+++ b/calendar/gui/dialogs/memo-page.c
@@ -948,9 +948,14 @@ to_button_clicked_cb (GtkButton *button,
static gboolean
init_widgets (MemoPage *mpage)
{
+ CompEditor *editor;
MemoPagePrivate *priv = mpage->priv;
GtkTextBuffer *buffer;
GtkTextView *view;
+ GtkAction *action;
+ gboolean active;
+
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (mpage));
/* Generic informative messages */
gtk_widget_hide (priv->info_hbox);
@@ -1015,8 +1020,9 @@ init_widgets (MemoPage *mpage)
G_CALLBACK (comp_editor_page_changed), mpage);
}
- memo_page_set_show_categories (
- mpage, calendar_config_get_show_categories());
+ action = comp_editor_get_action (editor, "view-categories");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ memo_page_set_show_categories (mpage, active);
return TRUE;
}
@@ -1215,9 +1221,14 @@ GtkWidget *memo_page_create_date_edit (void);
GtkWidget *
memo_page_create_date_edit (void)
{
+ EShell *shell;
+ EShellSettings *shell_settings;
GtkWidget *widget;
- widget = comp_editor_new_date_edit (TRUE, FALSE, TRUE);
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ widget = comp_editor_new_date_edit (shell_settings, TRUE, FALSE, TRUE);
e_date_edit_set_allow_no_date_set (E_DATE_EDIT (widget), TRUE);
gtk_widget_show (widget);
diff --git a/calendar/gui/dialogs/memo-page.glade b/calendar/gui/dialogs/memo-page.glade
index b1ff10f3f4..8728c9366e 100644
--- a/calendar/gui/dialogs/memo-page.glade
+++ b/calendar/gui/dialogs/memo-page.glade
@@ -159,6 +159,7 @@
<widget class="GtkLabel" id="label18">
<property name="visible">True</property>
<property name="label" translatable="yes">_Description:</property>
+ <property name="mnemonic_widget">memo_content</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c
index 385b4eeea0..ca53a41737 100644
--- a/calendar/gui/dialogs/recurrence-page.c
+++ b/calendar/gui/dialogs/recurrence-page.c
@@ -34,6 +34,7 @@
#include <glib/gi18n.h>
#include <glade/glade.h>
#include <libedataserver/e-time-utils.h>
+#include <e-util/e-binding.h>
#include <e-util/e-dialog-widgets.h>
#include <e-util/e-util-private.h>
#include <misc/e-dateedit.h>
@@ -44,7 +45,6 @@
#include "../weekday-picker.h"
#include "comp-editor-util.h"
#include "../e-date-time-list.h"
-#include "../e-mini-calendar-config.h"
#include "recurrence-page.h"
#define RECURRENCE_PAGE_GET_PRIVATE(obj) \
@@ -188,7 +188,6 @@ struct _RecurrencePagePrivate {
/* For the recurrence preview, the actual widget */
GtkWidget *preview_calendar;
- EMiniCalendarConfig *preview_calendar_config;
};
@@ -323,11 +322,6 @@ recurrence_page_dispose (GObject *object)
priv->exception_list_store = NULL;
}
- if (priv->preview_calendar_config != NULL) {
- g_object_unref (priv->preview_calendar_config);
- priv->preview_calendar_config = NULL;
- }
-
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (recurrence_page_parent_class)->dispose (object);
}
@@ -1338,6 +1332,8 @@ static void
make_ending_until_special (RecurrencePage *rpage)
{
RecurrencePagePrivate *priv = rpage->priv;
+ EShell *shell;
+ EShellSettings *shell_settings;
CompEditor *editor;
CompEditorFlags flags;
EDateEdit *de;
@@ -1349,10 +1345,13 @@ make_ending_until_special (RecurrencePage *rpage)
editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (rpage));
flags = comp_editor_get_flags (editor);
+ shell = comp_editor_get_shell (editor);
+ shell_settings = e_shell_get_shell_settings (shell);
+
/* Create the widget */
- priv->ending_date_edit = comp_editor_new_date_edit (TRUE, FALSE,
- FALSE);
+ priv->ending_date_edit = comp_editor_new_date_edit (
+ shell_settings, TRUE, FALSE, FALSE);
de = E_DATE_EDIT (priv->ending_date_edit);
gtk_container_add (GTK_CONTAINER (priv->ending_special),
@@ -2077,9 +2076,16 @@ create_exception_dialog (RecurrencePage *rpage, const gchar *title, GtkWidget **
{
RecurrencePagePrivate *priv;
GtkWidget *dialog, *toplevel;
+ CompEditor *editor;
+ EShell *shell;
+ EShellSettings *shell_settings;
priv = rpage->priv;
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (rpage));
+ shell = comp_editor_get_shell (editor);
+ shell_settings = e_shell_get_shell_settings (shell);
+
toplevel = gtk_widget_get_toplevel (priv->main);
dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (toplevel),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -2087,7 +2093,7 @@ create_exception_dialog (RecurrencePage *rpage, const gchar *title, GtkWidget **
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
- *date_edit = comp_editor_new_date_edit (TRUE, FALSE, TRUE);
+ *date_edit = comp_editor_new_date_edit (shell_settings, TRUE, FALSE, TRUE);
gtk_widget_show (*date_edit);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), *date_edit, FALSE, TRUE, 6);
@@ -2243,6 +2249,9 @@ static void
init_widgets (RecurrencePage *rpage)
{
RecurrencePagePrivate *priv;
+ EShell *shell;
+ EShellSettings *shell_settings;
+ CompEditor *editor;
ECalendar *ecal;
GtkAdjustment *adj;
GtkTreeViewColumn *column;
@@ -2250,11 +2259,23 @@ init_widgets (RecurrencePage *rpage)
priv = rpage->priv;
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (rpage));
+ shell = comp_editor_get_shell (editor);
+ shell_settings = e_shell_get_shell_settings (shell);
+
/* Recurrence preview */
priv->preview_calendar = e_calendar_new ();
ecal = E_CALENDAR (priv->preview_calendar);
- priv->preview_calendar_config = e_mini_calendar_config_new (ecal);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-show-week-numbers",
+ G_OBJECT (ecal->calitem), "show-week-numbers");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-week-start-day",
+ G_OBJECT (ecal->calitem), "week-start-day");
+
g_signal_connect((ecal->calitem), "date_range_changed",
G_CALLBACK (preview_date_range_changed_cb),
rpage);
@@ -2401,6 +2422,12 @@ GtkWidget *make_exdate_date_edit (void);
GtkWidget *
make_exdate_date_edit (void)
{
- return comp_editor_new_date_edit (TRUE, TRUE, FALSE);
+ EShell *shell;
+ EShellSettings *shell_settings;
+
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ return comp_editor_new_date_edit (shell_settings, TRUE, TRUE, FALSE);
}
diff --git a/calendar/gui/dialogs/schedule-page.c b/calendar/gui/dialogs/schedule-page.c
index 712d2708b9..5a7277084b 100644
--- a/calendar/gui/dialogs/schedule-page.c
+++ b/calendar/gui/dialogs/schedule-page.c
@@ -32,6 +32,7 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glade/glade.h>
+#include <e-util/e-binding.h>
#include <e-util/e-dialog-widgets.h>
#include <e-util/e-util-private.h>
#include <misc/e-dateedit.h>
@@ -218,7 +219,7 @@ update_time (SchedulePage *spage, ECalComponentDateTime *start_date, ECalCompone
if (start_zone != end_zone) {
icaltimezone_convert_time (&end_tt, end_zone, start_zone);
}
- e_meeting_store_set_zone (priv->model, priv->zone);
+ e_meeting_store_set_timezone (priv->model, priv->zone);
all_day = (start_tt.is_date && end_tt.is_date) ? TRUE : FALSE;
@@ -385,10 +386,14 @@ SchedulePage *
schedule_page_construct (SchedulePage *spage, EMeetingStore *ems)
{
SchedulePagePrivate *priv = spage->priv;
+ EShellSettings *shell_settings;
+ EShell *shell;
CompEditor *editor;
gchar *gladefile;
editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (spage));
+ shell = comp_editor_get_shell (editor);
+ shell_settings = e_shell_get_shell_settings (shell);
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
"schedule-page.glade",
@@ -423,6 +428,18 @@ schedule_page_construct (SchedulePage *spage, EMeetingStore *ems)
gtk_widget_show (GTK_WIDGET (priv->sel));
gtk_box_pack_start (GTK_BOX (priv->main), GTK_WIDGET (priv->sel), TRUE, TRUE, 6);
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-show-week-numbers",
+ G_OBJECT (priv->sel), "show-week-numbers");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-use-24-hour-format",
+ G_OBJECT (priv->sel), "use-24-hour-format");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-week-start-day",
+ G_OBJECT (priv->sel), "week-start-day");
+
if (!init_widgets (spage)) {
g_message ("schedule_page_construct(): "
"Could not initialize the widgets!");
diff --git a/calendar/gui/dialogs/task-details-page.c b/calendar/gui/dialogs/task-details-page.c
index 8c63c4dd02..38faa99c0b 100644
--- a/calendar/gui/dialogs/task-details-page.c
+++ b/calendar/gui/dialogs/task-details-page.c
@@ -515,16 +515,15 @@ complete_date_changed (TaskDetailsPage *tdpage, time_t ctime, gboolean complete)
}
static void
-date_changed_cb (EDateEdit *dedit, gpointer data)
+date_changed_cb (EDateEdit *dedit,
+ TaskDetailsPage *tdpage)
{
- TaskDetailsPage *tdpage;
- TaskDetailsPagePrivate *priv;
+ TaskDetailsPagePrivate *priv = tdpage->priv;
CompEditorPageDates dates = {NULL, NULL, NULL, NULL};
struct icaltimetype completed_tt = icaltime_null_time ();
icalproperty_status status;
gboolean date_set;
- tdpage = TASK_DETAILS_PAGE (data);
priv = tdpage->priv;
if (comp_editor_page_get_updating (COMP_EDITOR_PAGE (tdpage)))
@@ -769,9 +768,14 @@ GtkWidget *task_details_page_create_date_edit (void);
GtkWidget *
task_details_page_create_date_edit (void)
{
+ EShell *shell;
+ EShellSettings *shell_settings;
GtkWidget *dedit;
- dedit = comp_editor_new_date_edit (TRUE, TRUE, FALSE);
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ dedit = comp_editor_new_date_edit (shell_settings, TRUE, TRUE, FALSE);
e_date_edit_set_allow_no_date_set (E_DATE_EDIT (dedit), TRUE);
return dedit;
diff --git a/calendar/gui/dialogs/task-details-page.glade b/calendar/gui/dialogs/task-details-page.glade
index 44fc3b2fbb..aac90876ed 100644
--- a/calendar/gui/dialogs/task-details-page.glade
+++ b/calendar/gui/dialogs/task-details-page.glade
@@ -4,7 +4,7 @@
<glade-interface>
<widget class="GtkWindow" id="task-details-toplevel">
- <property name="title">window1</property>
+ <property name="title" translatable="no">window1</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
@@ -15,8 +15,6 @@
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
<child>
<widget class="GtkVBox" id="task-details-page">
@@ -38,10 +36,6 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -69,10 +63,6 @@
<property name="yalign">0.5</property>
<property name="xpad">12</property>
<property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -103,10 +93,7 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
+ <property name="mnemonic_widget">status</property>
</widget>
<packing>
<property name="left_attach">0</property>
@@ -132,10 +119,6 @@
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">percent-complete</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
@@ -160,10 +143,7 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
+ <property name="mnemonic_widget">priority</property>
</widget>
<packing>
<property name="left_attach">0</property>
@@ -188,10 +168,6 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
@@ -204,85 +180,153 @@
</child>
<child>
- <widget class="GtkSpinButton" id="percent-complete">
+ <widget class="GtkOptionMenu" id="priority">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="climb_rate">1</property>
- <property name="digits">0</property>
- <property name="numeric">True</property>
- <property name="update_policy">GTK_UPDATE_ALWAYS</property>
- <property name="snap_to_ticks">False</property>
- <property name="wrap">False</property>
- <property name="adjustment">0 0 100 1 10 0</property>
+ <property name="history">0</property>
+
+ <child internal-child="menu">
+ <widget class="GtkMenu" id="convertwidget7">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkMenuItem" id="convertwidget8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">High</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="convertwidget9">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Normal</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="convertwidget10">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Low</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="convertwidget11">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Undefined</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="Custom" id="completed-date">
+ <widget class="GtkOptionMenu" id="status">
<property name="visible">True</property>
- <property name="creation_function">task_details_page_create_date_edit</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Fri, 01 Jun 2001 18:58:51 GMT</property>
- <accessibility>
- <atkrelation target="date_completed_label" type="labelled-by"/>
- </accessibility>
+ <property name="can_focus">True</property>
+ <property name="history">0</property>
+
+ <child internal-child="menu">
+ <widget class="GtkMenu" id="convertwidget1">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkMenuItem" id="convertwidget2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Not Started</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="convertwidget3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">In Progress</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="convertwidget5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Completed</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="convertwidget6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Canceled</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkComboBox" id="priority-combobox">
+ <widget class="GtkSpinButton" id="percent-complete">
<property name="visible">True</property>
- <property name="items" translatable="yes">High
-Normal
-Low
-Undefined</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">0 0 100 1 10 0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="x_options">fill</property>
- <property name="y_options">fill</property>
+ <property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkComboBox" id="status-combobox">
+ <widget class="Custom" id="completed-date">
<property name="visible">True</property>
- <property name="items" translatable="yes">Not Started
-In Progress
-Completed
-Canceled</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
+ <property name="creation_function">task_details_page_create_date_edit</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Fri, 01 Jun 2001 18:58:51 GMT</property>
+ <accessibility>
+ <atkrelation target="date_completed_label" type="labelled-by"/>
+ </accessibility>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
<property name="x_options">fill</property>
- <property name="y_options">fill</property>
+ <property name="y_options"></property>
</packing>
</child>
</widget>
@@ -313,10 +357,6 @@ Canceled</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -344,10 +384,6 @@ Canceled</property>
<property name="yalign">0.5</property>
<property name="xpad">12</property>
<property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -379,10 +415,6 @@ Canceled</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c
index 0ca6ff5a3d..edd54859d6 100644
--- a/calendar/gui/dialogs/task-editor.c
+++ b/calendar/gui/dialogs/task-editor.c
@@ -33,9 +33,9 @@
#include <glade/glade.h>
#include <glib/gi18n.h>
-#include <e-util/e-plugin-ui.h>
-#include <e-util/e-util-private.h>
-#include <evolution-shell-component-utils.h>
+#include "e-util/e-binding.h"
+#include "e-util/e-plugin-ui.h"
+#include "e-util/e-util-private.h"
#include "task-page.h"
#include "task-details-page.h"
@@ -127,15 +127,6 @@ static GtkActionEntry assigned_task_entries[] = {
};
static void
-task_editor_client_changed_cb (TaskEditor *te)
-{
- ECal *client;
-
- client = comp_editor_get_client (COMP_EDITOR (te));
- e_meeting_store_set_e_cal (te->priv->model, client);
-}
-
-static void
task_editor_model_changed_cb (TaskEditor *te)
{
if (!te->priv->updating) {
@@ -209,6 +200,31 @@ task_editor_dispose (GObject *object)
}
static void
+task_editor_constructed (GObject *object)
+{
+ TaskEditorPrivate *priv;
+ EShellSettings *shell_settings;
+ EShell *shell;
+
+ priv = TASK_EDITOR_GET_PRIVATE (object);
+
+ shell = comp_editor_get_shell (COMP_EDITOR (object));
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_binding_new (
+ G_OBJECT (object), "client",
+ G_OBJECT (priv->model), "client");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-free-busy-template",
+ G_OBJECT (priv->model), "free-busy-template");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-timezone",
+ G_OBJECT (priv->model), "timezone");
+}
+
+static void
task_editor_show_categories (CompEditor *editor,
gboolean visible)
{
@@ -285,6 +301,7 @@ task_editor_class_init (TaskEditorClass *class)
object_class = G_OBJECT_CLASS (class);
object_class->constructor = task_editor_constructor;
object_class->dispose = task_editor_dispose;
+ object_class->constructed = task_editor_constructed;
editor_class = COMP_EDITOR_CLASS (class);
editor_class->help_section = "usage-calendar-todo";
@@ -304,6 +321,7 @@ task_editor_init (TaskEditor *te)
CompEditor *editor = COMP_EDITOR (te);
GtkUIManager *ui_manager;
GtkActionGroup *action_group;
+ const gchar *id;
GError *error = NULL;
te->priv = TASK_EDITOR_GET_PRIVATE (te);
@@ -346,17 +364,16 @@ task_editor_init (TaskEditor *te)
ui_manager = comp_editor_get_ui_manager (editor);
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
- e_plugin_ui_register_manager ("task-editor", ui_manager, te);
+
+ id = "org.gnome.evolution.task-editor";
+ e_plugin_ui_register_manager (ui_manager, id, te);
+ e_plugin_ui_enable_manager (ui_manager, id);
if (error != NULL) {
g_critical ("%s: %s", G_STRFUNC, error->message);
g_error_free (error);
}
- g_signal_connect (
- te, "notify::client",
- G_CALLBACK (task_editor_client_changed_cb), NULL);
-
g_signal_connect_swapped (
te->priv->model, "row_changed",
G_CALLBACK (task_editor_model_changed_cb), te);
@@ -462,7 +479,7 @@ task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gbool
ECal *client;
gboolean result;
- client = e_meeting_store_get_e_cal (priv->model);
+ client = e_meeting_store_get_client (priv->model);
result = itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp,
client, NULL, NULL, NULL, strip_alarms, FALSE);
g_object_unref (comp);
@@ -488,13 +505,16 @@ task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gbool
* editor could not be created.
**/
CompEditor *
-task_editor_new (ECal *client, CompEditorFlags flags)
+task_editor_new (ECal *client,
+ EShell *shell,
+ CompEditorFlags flags)
{
g_return_val_if_fail (E_IS_CAL (client), NULL);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
return g_object_new (
TYPE_TASK_EDITOR,
- "flags", flags, "client", client, NULL);
+ "client", client, "flags", flags, "shell", shell, NULL);
}
void
diff --git a/calendar/gui/dialogs/task-editor.h b/calendar/gui/dialogs/task-editor.h
index 57ab33b54f..f026acae0c 100644
--- a/calendar/gui/dialogs/task-editor.h
+++ b/calendar/gui/dialogs/task-editor.h
@@ -66,6 +66,7 @@ struct _TaskEditorClass {
GType task_editor_get_type (void);
CompEditor * task_editor_new (ECal *client,
+ EShell *shell,
CompEditorFlags flags);
void task_editor_show_assignment (TaskEditor *te);
diff --git a/calendar/gui/dialogs/task-page.c b/calendar/gui/dialogs/task-page.c
index 8b5c02843e..2f0c258f3a 100644
--- a/calendar/gui/dialogs/task-page.c
+++ b/calendar/gui/dialogs/task-page.c
@@ -39,7 +39,6 @@
#include <misc/e-dateedit.h>
#include <e-util/e-dialog-utils.h>
#include "common/authentication.h"
-#include "e-util/e-popup.h"
#include "e-util/e-dialog-widgets.h"
#include "e-util/e-categories-config.h"
#include "e-util/e-util-private.h"
@@ -53,7 +52,6 @@
#include "../e-meeting-attendee.h"
#include "../e-meeting-store.h"
#include "../e-meeting-list-view.h"
-#include "../e-cal-popup.h"
#define TASK_PAGE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -466,12 +464,14 @@ task_page_fill_widgets (CompEditorPage *page, ECalComponent *comp)
ECalComponentClassification cl;
CompEditor *editor;
CompEditorFlags flags;
+ GtkAction *action;
ECal *client;
GSList *l;
icalcomponent *icalcomp;
const gchar *categories, *uid;
icaltimezone *zone, *default_zone;
gchar *backend_addr = NULL;
+ gboolean active;
tpage = TASK_PAGE (page);
priv = tpage->priv;
@@ -554,7 +554,10 @@ task_page_fill_widgets (CompEditorPage *page, ECalComponent *comp)
e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->timezone),
zone ? zone : default_zone);
- task_page_set_show_timezone (tpage, calendar_config_get_show_timezone());
+
+ action = comp_editor_get_action (editor, "view-time-zone");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ task_page_set_show_timezone (tpage, active);
if (!(flags & COMP_EDITOR_NEW_ITEM) && !zone) {
GtkAction *action;
@@ -1140,15 +1143,10 @@ remove_clicked_cb (GtkButton *btn, TaskPage *page)
}
static void
-invite_cb (GtkWidget *widget, gpointer data)
+invite_cb (GtkWidget *widget,
+ TaskPage *page)
{
- TaskPage *page;
- TaskPagePrivate *priv;
-
- page = TASK_PAGE (data);
- priv = page->priv;
-
- e_meeting_list_view_invite_others_dialog (priv->list_view);
+ e_meeting_list_view_invite_others_dialog (page->priv->list_view);
}
static void
@@ -1191,102 +1189,6 @@ attendee_added_cb (EMeetingListView *emlv,
}
}
-/* Callbacks for list view*/
-static void
-popup_add_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- TaskPage *page = data;
-
- add_clicked_cb (NULL, page);
-}
-
-static void
-popup_delete_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- TaskPage *page = data;
-
- remove_clicked_cb (NULL, page);
-}
-
-enum {
- ATTENDEE_CAN_DELEGATE = 1<<1,
- ATTENDEE_CAN_DELETE = 1<<2,
- ATTENDEE_CAN_ADD = 1<<3,
- ATTENDEE_LAST = 1<<4
-};
-
-static EPopupItem context_menu_items[] = {
- { E_POPUP_ITEM, (gchar *) "10.delete", (gchar *) N_("_Remove"), popup_delete_cb, NULL, (gchar *) GTK_STOCK_REMOVE, ATTENDEE_CAN_DELETE },
- { E_POPUP_ITEM, (gchar *) "15.add", (gchar *) N_("_Add "), popup_add_cb, NULL, (gchar *) GTK_STOCK_ADD, ATTENDEE_CAN_ADD },
-};
-
-static void
-context_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static gint
-button_press_event (GtkWidget *widget, GdkEventButton *event, TaskPage *page)
-{
- TaskPagePrivate *priv = page->priv;
- CompEditor *editor;
- CompEditorFlags flags;
- GtkMenu *menu;
- EMeetingAttendee *ia;
- GtkTreePath *path;
- GtkTreeIter iter;
- gchar *address;
- guint32 disable_mask = ~0;
- GSList *menus = NULL;
- ECalPopup *ep;
- gint i;
-
- /* only process right-clicks */
- if (event->button != 3 || event->type != GDK_BUTTON_PRESS)
- return FALSE;
-
- editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (page));
- flags = comp_editor_get_flags (editor);
-
- /* only if we right-click on an attendee */
- if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (priv->list_view), event->x, event->y, &path, NULL, NULL, NULL)) {
- GtkTreeSelection *selection;
-
- if (gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->model), &iter, path)) {
-
- gtk_tree_model_get (GTK_TREE_MODEL (priv->model), &iter, E_MEETING_STORE_ADDRESS_COL, &address, -1);
- ia = e_meeting_store_find_attendee (priv->model, address, &priv->row);
- g_free (address);
-
- if (ia) {
- selection = gtk_tree_view_get_selection ((GtkTreeView *) priv->list_view);
- gtk_tree_selection_unselect_all (selection);
- gtk_tree_selection_select_path (selection, path);
-
- if (e_meeting_attendee_get_edit_level (ia) == E_MEETING_ATTENDEE_EDIT_FULL)
- disable_mask &= ~ATTENDEE_CAN_DELETE;
- }
- }
- }
-
- if (GTK_WIDGET_IS_SENSITIVE(priv->add))
- disable_mask &= ~ATTENDEE_CAN_ADD;
- else if (flags & COMP_EDITOR_USER_ORG)
- disable_mask &= ~ATTENDEE_CAN_ADD;
-
- ep = e_cal_popup_new("org.gnome.evolution.calendar.task.popup");
-
- for (i=0;i<sizeof(context_menu_items)/sizeof(context_menu_items[0]);i++)
- menus = g_slist_prepend(menus, &context_menu_items[i]);
-
- e_popup_add_items((EPopup *)ep, menus, NULL, context_popup_free, page);
- menu = e_popup_create_menu_once((EPopup *)ep, NULL, disable_mask);
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button, event->time);
-
- return TRUE;
-}
-
static gboolean
list_view_event (EMeetingListView *list_view, GdkEvent *event, TaskPage *page) {
@@ -1510,17 +1412,16 @@ summary_changed_cb (GtkEditable *editable,
* other pages in the task editor, so they can update any labels.
*/
static void
-date_changed_cb (EDateEdit *dedit, gpointer data)
+date_changed_cb (EDateEdit *dedit,
+ TaskPage *tpage)
{
- TaskPage *tpage;
- TaskPagePrivate *priv;
+ TaskPagePrivate *priv = tpage->priv;
CompEditorPageDates dates;
gboolean date_set, time_set;
ECalComponentDateTime start_dt, due_dt;
struct icaltimetype start_tt = icaltime_null_time();
struct icaltimetype due_tt = icaltime_null_time();
- tpage = TASK_PAGE (data);
priv = tpage->priv;
if (comp_editor_page_get_updating (COMP_EDITOR_PAGE (tpage)))
@@ -1579,33 +1480,24 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
}
static void
-timezone_changed_cb (EDateEdit *dedit, gpointer data)
+timezone_changed_cb (EDateEdit *dedit,
+ TaskPage *tpage)
{
- TaskPage *tpage;
- TaskPagePrivate *priv;
-
- tpage = TASK_PAGE (data);
- priv = tpage->priv;
-
- date_changed_cb ((EDateEdit *) priv->start_date, tpage);
- date_changed_cb ((EDateEdit *) priv->due_date, tpage);
+ date_changed_cb ((EDateEdit *) tpage->priv->start_date, tpage);
+ date_changed_cb ((EDateEdit *) tpage->priv->due_date, tpage);
}
/* Callback used when the categories button is clicked; we must bring up the
* category list dialog.
*/
static void
-categories_clicked_cb (GtkWidget *button, gpointer data)
+categories_clicked_cb (GtkWidget *button,
+ TaskPage *tpage)
{
- TaskPage *tpage;
- TaskPagePrivate *priv;
- GtkWidget *entry;
+ GtkEntry *entry;
- tpage = TASK_PAGE (data);
- priv = tpage->priv;
-
- entry = priv->categories;
- e_categories_config_open_dialog_for_entry (GTK_ENTRY (entry));
+ entry = GTK_ENTRY (tpage->priv->categories);
+ e_categories_config_open_dialog_for_entry (entry);
}
static gboolean
@@ -1865,12 +1757,17 @@ task_page_sendoptions_clicked_cb (TaskPage *tpage)
static gboolean
init_widgets (TaskPage *tpage)
{
+ CompEditor *editor;
TaskPagePrivate *priv;
+ GtkAction *action;
GtkTextBuffer *text_buffer;
icaltimezone *zone;
+ gboolean active;
priv = tpage->priv;
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (tpage));
+
/* Make sure the EDateEdit widgets use our timezones to get the
current time. */
e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->start_date),
@@ -1938,9 +1835,6 @@ init_widgets (TaskPage *tpage)
G_CALLBACK (comp_editor_page_changed), tpage);
g_signal_connect (
- priv->list_view, "button_press_event",
- G_CALLBACK (button_press_event), tpage);
- g_signal_connect (
priv->list_view, "event",
G_CALLBACK (list_view_event), tpage);
g_signal_connect (
@@ -1966,15 +1860,36 @@ init_widgets (TaskPage *tpage)
zone = calendar_config_get_icaltimezone ();
e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->timezone), zone);
- task_page_set_show_timezone (tpage, calendar_config_get_show_timezone());
+ action = comp_editor_get_action (editor, "view-time-zone");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ task_page_set_show_timezone (tpage, active);
+
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_ATTENDEE_COL, TRUE);
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_ATTENDEE_COL, TRUE);
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_ROLE_COL, calendar_config_get_show_role ());
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_RSVP_COL, calendar_config_get_show_rsvp ());
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_STATUS_COL, calendar_config_get_show_status ());
- e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_TYPE_COL, calendar_config_get_show_type ());
+ action = comp_editor_get_action (editor, "view-role");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_ROLE_COL, active);
- task_page_set_show_categories (tpage, calendar_config_get_show_categories());
+ action = comp_editor_get_action (editor, "view-rsvp");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_RSVP_COL, active);
+
+ action = comp_editor_get_action (editor, "view-status");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_STATUS_COL, active);
+
+ action = comp_editor_get_action (editor, "view-type");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ e_meeting_list_view_column_set_visible (
+ priv->list_view, E_MEETING_STORE_TYPE_COL, active);
+
+ action = comp_editor_get_action (editor, "view-categories");
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ task_page_set_show_categories (tpage, active);
return TRUE;
}
@@ -2159,9 +2074,14 @@ GtkWidget *task_page_create_date_edit (void);
GtkWidget *
task_page_create_date_edit (void)
{
+ EShell *shell;
+ EShellSettings *shell_settings;
GtkWidget *dedit;
- dedit = comp_editor_new_date_edit (TRUE, TRUE, TRUE);
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ dedit = comp_editor_new_date_edit (shell_settings, TRUE, TRUE, TRUE);
e_date_edit_set_allow_no_date_set (E_DATE_EDIT (dedit), TRUE);
return dedit;
diff --git a/calendar/gui/e-attachment-handler-calendar.h b/calendar/gui/e-attachment-handler-calendar.h
deleted file mode 100644
index f34cac14c3..0000000000
--- a/calendar/gui/e-attachment-handler-calendar.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * e-attachment-handler-calendar.h
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_ATTACHMENT_HANDLER_CALENDAR_H
-#define E_ATTACHMENT_HANDLER_CALENDAR_H
-
-#include <misc/e-attachment-handler.h>
-
-/* Standard GObject macros */
-#define E_TYPE_ATTACHMENT_HANDLER_CALENDAR \
- (e_attachment_handler_calendar_get_type ())
-#define E_ATTACHMENT_HANDLER_CALENDAR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_CALENDAR, EAttachmentHandlerCalendar))
-#define E_ATTACHMENT_HANDLER_CALENDAR_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_ATTACHMENT_HANDLER_CALENDAR, EAttachmentHandlerCalendarClass))
-#define E_IS_ATTACHMENT_HANDLER_CALENDAR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_CALENDAR))
-#define E_IS_ATTACHMENT_HANDLER_CALENDAR_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_ATTACHMENT_HANDLER_CALENDAR))
-#define E_ATTACHMENT_HANDLER_CALENDAR_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_CALENDAR, EAttachmentHandlerCalendarClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EAttachmentHandlerCalendar EAttachmentHandlerCalendar;
-typedef struct _EAttachmentHandlerCalendarClass EAttachmentHandlerCalendarClass;
-typedef struct _EAttachmentHandlerCalendarPrivate EAttachmentHandlerCalendarPrivate;
-
-struct _EAttachmentHandlerCalendar {
- EAttachmentHandler parent;
- EAttachmentHandlerCalendarPrivate *priv;
-};
-
-struct _EAttachmentHandlerCalendarClass {
- EAttachmentHandlerClass parent_class;
-};
-
-GType e_attachment_handler_calendar_get_type (void);
-
-G_END_DECLS
-
-#endif /* E_ATTACHMENT_HANDLER_CALENDAR_H */
diff --git a/calendar/gui/e-cal-component-memo-preview.c b/calendar/gui/e-cal-component-memo-preview.c
deleted file mode 100644
index f3969157a9..0000000000
--- a/calendar/gui/e-cal-component-memo-preview.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena Quintero <federico@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- * Rodrigo Moya <rodrigo@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <libecal/e-cal-time-util.h>
-#include <libedataserver/e-categories.h>
-#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-stream.h>
-#include <libedataserver/e-time-utils.h>
-#include <e-util/e-util.h>
-#include <e-util/e-categories-config.h>
-#include "calendar-config.h"
-#include "e-cal-component-memo-preview.h"
-#include "e-cal-component-preview.h"
-#include <camel/camel-mime-filter-tohtml.h>
-
-struct _ECalComponentMemoPreviewPrivate {
- GtkWidget *html;
-
- icaltimezone *zone;
-};
-
-G_DEFINE_TYPE (ECalComponentMemoPreview, e_cal_component_memo_preview, GTK_TYPE_TABLE)
-
-static void
-on_link_clicked (GtkHTML *html, const gchar *url, gpointer data)
-{
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, url);
-}
-
-static void
-on_url_cb (GtkHTML *html, const gchar *url, gpointer data)
-{
-#if 0
- gchar *msg;
- ECalComponentMemoPreview *preview = data;
-
- if (url && *url) {
- msg = g_strdup_printf (_("Click to open %s"), url);
- e_calendar_table_set_status_message (e_tasks_get_calendar_table (tasks), msg);
- g_free (msg);
- } else
- e_calendar_table_set_status_message (e_tasks_get_calendar_table (tasks), NULL);
-#endif
-}
-
-/* Converts a time_t to a string, relative to the specified timezone */
-static gchar *
-timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *default_zone)
-{
- struct icaltimetype itt;
- icaltimezone *zone;
- struct tm tm;
- gchar buf[256];
-
- if (dt->tzid) {
- /* If we can't find the zone, we'll guess its "local" */
- if (!e_cal_get_timezone (ecal, dt->tzid, &zone, NULL))
- zone = NULL;
- } else if (dt->value->is_utc) {
- zone = icaltimezone_get_utc_timezone ();
- } else {
- zone = NULL;
- }
-
- itt = *dt->value;
- if (zone)
- icaltimezone_convert_time (&itt, zone, default_zone);
- tm = icaltimetype_to_tm (&itt);
-
- e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (),
- FALSE, FALSE, buf, sizeof (buf));
-
- return g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
-}
-
-static void
-write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone *default_zone)
-{
- ECalComponentText text;
- ECalComponentDateTime dt;
- gchar *str;
- GSList *l;
- gboolean one_added = FALSE;
-
- g_return_if_fail (E_IS_CAL_COMPONENT (comp));
-
- /* write document header */
- e_cal_component_get_summary (comp, &text);
-
- if (text.value)
- gtk_html_stream_printf (stream,
- "<HTML><BODY><H1>%s</H1>",
- text.value);
- else
- gtk_html_stream_printf (stream,
- "<HTML><BODY><H1><I>%s</I></H1>",
- _("Untitled"));
-
- /* write icons for the categories */
- e_cal_component_get_categories_list (comp, &l);
- if (l) {
- GSList *node;
- GString *string = g_string_new (NULL);
-
- gtk_html_stream_printf(stream, "<H3>%s: ", _("Categories"));
-
- for (node = l; node != NULL; node = node->next) {
- const gchar *icon_file;
-
- icon_file = e_categories_get_icon_file_for ((const gchar *) node->data);
- if (icon_file && g_file_test(icon_file, G_FILE_TEST_EXISTS)) {
- gchar *icon_file_uri = g_filename_to_uri (icon_file, NULL, NULL);
- gtk_html_stream_printf (stream, "<IMG ALT=\"%s\" SRC=\"%s\">",
- (const gchar *) node->data, icon_file_uri);
- g_free (icon_file_uri);
- one_added = TRUE;
- }
- else{
- if (one_added == FALSE) {
- g_string_append_printf (string, "%s", (const gchar *) node->data);
- one_added = TRUE;
- }
- else{
- g_string_append_printf (string, ", %s", (const gchar *) node->data);
- }
- }
- }
-
- if (string->len > 0)
- gtk_html_stream_printf(stream, "%s", string->str);
-
- g_string_free (string, TRUE);
-
- gtk_html_stream_printf(stream, "</H3>");
-
- e_cal_component_free_categories_list (l);
- }
-
- /* Start table */
- gtk_html_stream_printf (stream, "<TABLE BORDER=\"0\" WIDTH=\"80%%\">"
- "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"15%%\"></TD></TR>");
-
- /* write start date */
- e_cal_component_get_dtstart (comp, &dt);
- if (dt.value != NULL) {
- str = timet_to_str_with_zone (&dt, ecal, default_zone);
- gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD><TD>%s</TD></TR>",
- _("Start Date:"), str);
-
- g_free (str);
- }
- e_cal_component_free_datetime (&dt);
-
- /* write description and URL */
- gtk_html_stream_printf (stream, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>");
-
- e_cal_component_get_description_list (comp, &l);
- if (l) {
- GSList *node;
-
- gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Description:"));
-
- gtk_html_stream_printf (stream, "<TD><TT>");
-
- for (node = l; node != NULL; node = node->next) {
- gchar *html;
-
- text = * (ECalComponentText *) node->data;
- html = camel_text_to_html (text.value ? text.value : "", CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES | CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES, 0);
-
- if (html)
- gtk_html_stream_printf (stream, "%s", html);
-
- g_free (html);
- }
-
- gtk_html_stream_printf (stream, "</TT></TD></TR>");
-
- e_cal_component_free_text_list (l);
- }
-
- /* URL */
- e_cal_component_get_url (comp, (const gchar **) &str);
- if (str) {
- gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Web Page:"));
- gtk_html_stream_printf (stream, "<TD><A HREF=\"%s\">%s</A></TD></TR>", str, str);
- }
-
- gtk_html_stream_printf (stream, "</TABLE>");
-
- /* close document */
- gtk_html_stream_printf (stream, "</BODY></HTML>");
-}
-
-static void
-e_cal_component_memo_preview_init (ECalComponentMemoPreview *preview)
-{
- ECalComponentMemoPreviewPrivate *priv;
- GtkWidget *scroll;
-
- priv = g_new0 (ECalComponentMemoPreviewPrivate, 1);
- preview->priv = priv;
-
- priv->html = gtk_html_new ();
- gtk_html_set_default_content_type (GTK_HTML (priv->html), "charset=utf-8");
- gtk_html_load_empty (GTK_HTML (priv->html));
-
- g_signal_connect (G_OBJECT (priv->html), "url_requested",
- G_CALLBACK (e_cal_comp_preview_url_requested_cb), NULL);
- g_signal_connect (G_OBJECT (priv->html), "link_clicked",
- G_CALLBACK (on_link_clicked), preview);
- g_signal_connect (G_OBJECT (priv->html), "on_url",
- G_CALLBACK (on_url_cb), preview);
-
- scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
-
- gtk_container_add (GTK_CONTAINER (scroll), priv->html);
- gtk_container_add (GTK_CONTAINER (preview), scroll);
- gtk_widget_show_all (scroll);
-
- priv->zone = icaltimezone_get_utc_timezone ();
-}
-
-static void
-e_cal_component_memo_preview_destroy (GtkObject *object)
-{
- ECalComponentMemoPreview *preview;
- ECalComponentMemoPreviewPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (object));
-
- preview = E_CAL_COMPONENT_MEMO_PREVIEW (object);
- priv = preview->priv;
-
- if (priv) {
-
- g_free (priv);
- preview->priv = NULL;
- }
-
- if (GTK_OBJECT_CLASS (e_cal_component_memo_preview_parent_class)->destroy)
- (* GTK_OBJECT_CLASS (e_cal_component_memo_preview_parent_class)->destroy) (object);
-}
-
-static void
-e_cal_component_memo_preview_class_init (ECalComponentMemoPreviewClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) klass;
-
- object_class->destroy = e_cal_component_memo_preview_destroy;
-}
-
-GtkWidget *
-e_cal_component_memo_preview_new (void)
-{
- ECalComponentMemoPreview *preview;
-
- preview = g_object_new (e_cal_component_memo_preview_get_type (), NULL);
-
- return GTK_WIDGET (preview);
-}
-
-icaltimezone *
-e_cal_component_memo_preview_get_default_timezone (ECalComponentMemoPreview *preview)
-{
- ECalComponentMemoPreviewPrivate *priv;
-
- g_return_val_if_fail (preview != NULL, NULL);
- g_return_val_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview), NULL);
-
- priv = preview->priv;
-
- return priv->zone;
-}
-
-void
-e_cal_component_memo_preview_set_default_timezone (ECalComponentMemoPreview *preview, icaltimezone *zone)
-{
- ECalComponentMemoPreviewPrivate *priv;
-
- g_return_if_fail (preview != NULL);
- g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview));
- g_return_if_fail (zone != NULL);
-
- priv = preview->priv;
-
- priv->zone = zone;
-}
-
-void
-e_cal_component_memo_preview_display (ECalComponentMemoPreview *preview, ECal *ecal, ECalComponent *comp)
-{
- ECalComponentMemoPreviewPrivate *priv;
- GtkHTMLStream *stream;
-
- g_return_if_fail (preview != NULL);
- g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview));
- g_return_if_fail (comp != NULL);
- g_return_if_fail (E_IS_CAL_COMPONENT (comp));
-
- priv = preview->priv;
-
- stream = gtk_html_begin (GTK_HTML (priv->html));
- write_html (stream, ecal, comp, priv->zone);
- gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
-}
-
-void
-e_cal_component_memo_preview_clear (ECalComponentMemoPreview *preview)
-{
- ECalComponentMemoPreviewPrivate *priv;
-
- g_return_if_fail (preview != NULL);
- g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview));
-
- priv = preview->priv;
-
- gtk_html_load_empty (GTK_HTML (priv->html));
-}
-
-GtkWidget *
-e_cal_component_memo_preview_get_html (ECalComponentMemoPreview *preview)
-{
- g_return_val_if_fail (preview != NULL, NULL);
- g_return_val_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview), NULL);
-
- return preview->priv->html;
-}
diff --git a/calendar/gui/e-cal-component-memo-preview.h b/calendar/gui/e-cal-component-memo-preview.h
deleted file mode 100644
index 0f8c21c565..0000000000
--- a/calendar/gui/e-cal-component-memo-preview.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena Quintero <federico@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_CAL_COMPONENT_MEMO_PREVIEW_H_
-#define _E_CAL_COMPONENT_MEMO_PREVIEW_H_
-
-#include <gtk/gtk.h>
-#include <libecal/e-cal.h>
-
-#define E_TYPE_CAL_COMPONENT_MEMO_PREVIEW (e_cal_component_memo_preview_get_type ())
-#define E_CAL_COMPONENT_MEMO_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW, ECalComponentMemoPreview))
-#define E_CAL_COMPONENT_MEMO_PREVIEW_CLASS(klass) (G_TYPE_CHECK_INSTANCE_CAST_CLASS ((klass), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW, \
- ECalComponentMemoPreviewClass))
-#define E_IS_CAL_COMPONENT_MEMO_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW))
-#define E_IS_CAL_COMPONENT_MEMO_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW))
-
-typedef struct _ECalComponentMemoPreview ECalComponentMemoPreview;
-typedef struct _ECalComponentMemoPreviewClass ECalComponentMemoPreviewClass;
-typedef struct _ECalComponentMemoPreviewPrivate ECalComponentMemoPreviewPrivate;
-
-struct _ECalComponentMemoPreview {
- GtkTable table;
-
- /* Private data */
- ECalComponentMemoPreviewPrivate *priv;
-};
-
-struct _ECalComponentMemoPreviewClass {
- GtkTableClass parent_class;
-
- /* Notification signals */
- void (* selection_changed) (ECalComponentMemoPreview *preview, gint n_selected);
-};
-
-GType e_cal_component_memo_preview_get_type (void);
-GtkWidget *e_cal_component_memo_preview_new (void);
-
-icaltimezone *e_cal_component_memo_preview_get_default_timezone (ECalComponentMemoPreview *preview);
-void e_cal_component_memo_preview_set_default_timezone (ECalComponentMemoPreview *preview, icaltimezone *zone);
-
-void e_cal_component_memo_preview_display (ECalComponentMemoPreview *preview, ECal *ecal, ECalComponent *comp);
-void e_cal_component_memo_preview_clear (ECalComponentMemoPreview *preview);
-GtkWidget *e_cal_component_memo_preview_get_html (ECalComponentMemoPreview *preview);
-
-#endif /* _E_CAL_COMPONENT_MEMO_PREVIEW_H_ */
diff --git a/calendar/gui/e-cal-component-preview.c b/calendar/gui/e-cal-component-preview.c
index 8a33d48c0b..de6f6fcd3d 100644
--- a/calendar/gui/e-cal-component-preview.c
+++ b/calendar/gui/e-cal-component-preview.c
@@ -22,42 +22,41 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "e-cal-component-preview.h"
#include <string.h>
-#include <gio/gio.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include <libedataserver/e-categories.h>
#include <libecal/e-cal-time-util.h>
-#include <gtkhtml/gtkhtml.h>
+#include <libedataserver/e-categories.h>
#include <gtkhtml/gtkhtml-stream.h>
#include <libedataserver/e-time-utils.h>
#include <e-util/e-util.h>
#include <e-util/e-categories-config.h>
#include "calendar-config.h"
-#include "e-cal-component-preview.h"
#include <camel/camel-mime-filter-tohtml.h>
-struct _ECalComponentPreviewPrivate {
- GtkWidget *html;
+#define E_CAL_COMPONENT_PREVIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreviewPrivate))
+struct _ECalComponentPreviewPrivate {
icaltimezone *zone;
};
-G_DEFINE_TYPE (ECalComponentPreview, e_cal_component_preview, GTK_TYPE_TABLE)
+static gpointer parent_class;
static void
-on_link_clicked (GtkHTML *html, const gchar *url, gpointer data)
+cal_component_preview_link_clicked (GtkHTML *html,
+ const gchar *uri)
{
/* FIXME Pass a parent window. */
- e_show_uri (NULL, url);
+ e_show_uri (NULL, uri);
}
static void
-on_url_cb (GtkHTML *html, const gchar *url, gpointer data)
+cal_component_preview_on_url (GtkHTML *html,
+ const gchar *url)
{
#if 0
gchar *msg;
@@ -72,51 +71,11 @@ on_url_cb (GtkHTML *html, const gchar *url, gpointer data)
#endif
}
-/* Callback used when the user selects a URL in the HTML widget */
-void
-e_cal_comp_preview_url_requested_cb (GtkHTML *html, const gchar *url, GtkHTMLStream *html_stream, gpointer data)
-{
- gint len = strlen ("file:///");
-
- if (!strncmp ("file:///", url, len)) {
- GFile *file;
- const gchar *path = url + len - 1;
-
- g_return_if_fail (html_stream != NULL);
- g_return_if_fail (path != NULL);
-
- file = g_file_new_for_path (path);
- if (file) {
- gchar buffer[4096];
- GInputStream *stream;
-
- /* ignore errors here */
- stream = G_INPUT_STREAM (g_file_read (file, NULL, NULL));
-
- if (stream) {
- gssize bread;
-
- do {
- /* ignore errors here as well */
- bread = g_input_stream_read (stream, buffer, sizeof (buffer), NULL, NULL);
- if (bread > 0)
- gtk_html_stream_write (html_stream, buffer, bread);
- } while (bread > 0);
-
- g_input_stream_close (stream, NULL, NULL);
- g_object_unref (stream);
-
- gtk_html_stream_close (html_stream, GTK_HTML_STREAM_OK);
- }
-
- g_object_unref (file);
- }
- }
-}
-
/* Converts a time_t to a string, relative to the specified timezone */
static gchar *
-timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *default_zone)
+timet_to_str_with_zone (ECalComponentDateTime *dt,
+ ECal *ecal,
+ icaltimezone *default_zone)
{
struct icaltimetype itt;
icaltimezone *zone;
@@ -145,12 +104,18 @@ timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *def
}
static void
-write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone *default_zone)
+cal_component_preview_write_html (GtkHTMLStream *stream,
+ ECal *ecal,
+ ECalComponent *comp,
+ icaltimezone *default_zone)
{
ECalComponentText text;
ECalComponentDateTime dt;
gchar *str;
- GSList *l;
+ GString *string;
+ GSList *list, *iter;
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
icalproperty_status status;
const gchar *location;
gint *priority_value;
@@ -170,26 +135,33 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone
_("Untitled"));
/* write icons for the categories */
- e_cal_component_get_categories_list (comp, &l);
- if (l) {
- GSList *node;
-
- for (node = l; node != NULL; node = node->next) {
- const gchar *icon_file;
-
- icon_file = e_categories_get_icon_file_for ((const gchar *) node->data);
- if (icon_file) {
- gchar *icon_file_uri = g_filename_to_uri (icon_file, NULL, NULL);
- gtk_html_stream_printf (stream, "<IMG ALT=\"%s\" SRC=\"%s\">",
- (const gchar *) node->data, icon_file_uri);
- g_free (icon_file_uri);
- }
+ string = g_string_new (NULL);
+ e_cal_component_get_categories_list (comp, &list);
+ if (list != NULL)
+ gtk_html_stream_printf (stream, "<H3>%s ", _("Categories:"));
+ for (iter = list; iter != NULL; iter = iter->next) {
+ const gchar *category = iter->data;
+ const gchar *icon_file;
+
+ icon_file = e_categories_get_icon_file_for (category);
+ if (icon_file && g_file_test (icon_file, G_FILE_TEST_EXISTS)) {
+ gchar *uri;
+
+ uri = g_filename_to_uri (icon_file, NULL, NULL);
+ gtk_html_stream_printf (
+ stream, "<IMG ALT=\"%s\" SRC=\"%s\">",
+ category, uri);
+ g_free (uri);
+ } else {
+ if (iter != list)
+ g_string_append_len (string, ", ", 2);
+ g_string_append (string, category);
}
-
- e_cal_component_free_categories_list (l);
-
- gtk_html_stream_printf (stream, "<BR><BR><BR>");
}
+ if (string->len > 0)
+ gtk_html_stream_printf (stream, "%s</H3>", string->str);
+ e_cal_component_free_categories_list (list);
+ g_string_free (string, TRUE);
/* Start table */
gtk_html_stream_printf (stream, "<TABLE BORDER=\"0\" WIDTH=\"80%%\">"
@@ -235,26 +207,31 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone
e_cal_component_free_datetime (&dt);
/* write status */
- gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Status:"));
- e_cal_component_get_status (comp, &status);
- switch (status) {
- case ICAL_STATUS_INPROCESS :
- str = g_strdup (_("In Progress"));
- break;
- case ICAL_STATUS_COMPLETED :
- str = g_strdup (_("Completed"));
- break;
- case ICAL_STATUS_CANCELLED :
- str = g_strdup (_("Canceled"));
- break;
- case ICAL_STATUS_NONE :
- default :
- str = g_strdup (_("Not Started"));
- break;
- }
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+ icalprop = icalcomponent_get_first_property (
+ icalcomp, ICAL_STATUS_PROPERTY);
+ if (icalprop != NULL) {
+ gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Status:"));
+ e_cal_component_get_status (comp, &status);
+ switch (status) {
+ case ICAL_STATUS_INPROCESS :
+ str = g_strdup (_("In Progress"));
+ break;
+ case ICAL_STATUS_COMPLETED :
+ str = g_strdup (_("Completed"));
+ break;
+ case ICAL_STATUS_CANCELLED :
+ str = g_strdup (_("Canceled"));
+ break;
+ case ICAL_STATUS_NONE :
+ default :
+ str = g_strdup (_("Not Started"));
+ break;
+ }
- gtk_html_stream_printf (stream, "<TD>%s</TD></TR>", str);
- g_free (str);
+ gtk_html_stream_printf (stream, "<TD>%s</TD></TR>", str);
+ g_free (str);
+ }
/* write priority */
e_cal_component_get_priority (comp, &priority_value);
@@ -278,15 +255,15 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone
/* write description and URL */
gtk_html_stream_printf (stream, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>");
- e_cal_component_get_description_list (comp, &l);
- if (l) {
+ e_cal_component_get_description_list (comp, &list);
+ if (list) {
GSList *node;
gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Description:"));
gtk_html_stream_printf (stream, "<TD><TT>");
- for (node = l; node != NULL; node = node->next) {
+ for (node = list; node != NULL; node = node->next) {
gchar *html;
text = * (ECalComponentText *) node->data;
@@ -300,7 +277,7 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone
gtk_html_stream_printf (stream, "</TT></TD></TR>");
- e_cal_component_free_text_list (l);
+ e_cal_component_free_text_list (list);
}
/* URL */
@@ -317,143 +294,119 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone
}
static void
-e_cal_component_preview_init (ECalComponentPreview *preview)
+cal_component_preview_finalize (GObject *object)
{
ECalComponentPreviewPrivate *priv;
- GtkWidget *scroll;
- priv = g_new0 (ECalComponentPreviewPrivate, 1);
- preview->priv = priv;
+ priv = E_CAL_COMPONENT_PREVIEW_GET_PRIVATE (object);
+
+ /* XXX Nothing to do? */
- priv->html = gtk_html_new ();
- gtk_html_set_default_content_type (GTK_HTML (priv->html), "charset=utf-8");
- gtk_html_load_empty (GTK_HTML (priv->html));
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
- g_signal_connect (G_OBJECT (priv->html), "url_requested",
- G_CALLBACK (e_cal_comp_preview_url_requested_cb), NULL);
- g_signal_connect (G_OBJECT (priv->html), "link_clicked",
- G_CALLBACK (on_link_clicked), preview);
- g_signal_connect (G_OBJECT (priv->html), "on_url",
- G_CALLBACK (on_url_cb), preview);
+static void
+cal_component_preview_class_init (ECalComponentPreviewClass *class)
+{
+ GObjectClass *object_class;
+ GtkHTMLClass *gtkhtml_class;
- scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECalComponentPreviewPrivate));
- gtk_container_add (GTK_CONTAINER (scroll), priv->html);
- gtk_container_add (GTK_CONTAINER (preview), scroll);
- gtk_widget_show_all (scroll);
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = cal_component_preview_finalize;
- priv->zone = icaltimezone_get_utc_timezone ();
+ gtkhtml_class = GTK_HTML_CLASS (class);
+ gtkhtml_class->link_clicked = cal_component_preview_link_clicked;
+ gtkhtml_class->on_url = cal_component_preview_on_url;
}
static void
-e_cal_component_preview_destroy (GtkObject *object)
+cal_component_preview_init (ECalComponentPreview *preview)
{
- ECalComponentPreview *preview;
- ECalComponentPreviewPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (object));
-
- preview = E_CAL_COMPONENT_PREVIEW (object);
- priv = preview->priv;
+ GtkHTML *html;
- if (priv) {
+ preview->priv = E_CAL_COMPONENT_PREVIEW_GET_PRIVATE (preview);
- g_free (priv);
- preview->priv = NULL;
- }
+ html = GTK_HTML (preview);
+ gtk_html_set_default_content_type (html, "charset=utf-8");
+ gtk_html_load_empty (html);
- if (GTK_OBJECT_CLASS (e_cal_component_preview_parent_class)->destroy)
- (* GTK_OBJECT_CLASS (e_cal_component_preview_parent_class)->destroy) (object);
+ preview->priv->zone = icaltimezone_get_utc_timezone ();
}
-static void
-e_cal_component_preview_class_init (ECalComponentPreviewClass *klass)
+GType
+e_cal_component_preview_get_type (void)
{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) klass;
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ECalComponentPreviewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_component_preview_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalComponentPreview),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) cal_component_preview_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HTML, "ECalComponentPreview", &type_info, 0);
+ }
- object_class->destroy = e_cal_component_preview_destroy;
+ return type;
}
GtkWidget *
e_cal_component_preview_new (void)
{
- ECalComponentPreview *preview;
-
- preview = g_object_new (e_cal_component_preview_get_type (), NULL);
-
- return GTK_WIDGET (preview);
+ return g_object_new (E_TYPE_CAL_COMPONENT_PREVIEW, NULL);
}
icaltimezone *
e_cal_component_preview_get_default_timezone (ECalComponentPreview *preview)
{
- ECalComponentPreviewPrivate *priv;
-
- g_return_val_if_fail (preview != NULL, NULL);
g_return_val_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview), NULL);
- priv = preview->priv;
-
- return priv->zone;
+ return preview->priv->zone;
}
void
-e_cal_component_preview_set_default_timezone (ECalComponentPreview *preview, icaltimezone *zone)
+e_cal_component_preview_set_default_timezone (ECalComponentPreview *preview,
+ icaltimezone *zone)
{
- ECalComponentPreviewPrivate *priv;
-
- g_return_if_fail (preview != NULL);
g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview));
g_return_if_fail (zone != NULL);
- priv = preview->priv;
-
- priv->zone = zone;
+ preview->priv->zone = zone;
}
void
-e_cal_component_preview_display (ECalComponentPreview *preview, ECal *ecal, ECalComponent *comp)
+e_cal_component_preview_display (ECalComponentPreview *preview,
+ ECal *ecal,
+ ECalComponent *comp)
{
- ECalComponentPreviewPrivate *priv;
GtkHTMLStream *stream;
- g_return_if_fail (preview != NULL);
g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview));
- g_return_if_fail (comp != NULL);
g_return_if_fail (E_IS_CAL_COMPONENT (comp));
- priv = preview->priv;
-
- stream = gtk_html_begin (GTK_HTML (priv->html));
- write_html (stream, ecal, comp, priv->zone);
+ stream = gtk_html_begin (GTK_HTML (preview));
+ cal_component_preview_write_html (
+ stream, ecal, comp, preview->priv->zone);
gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
}
void
e_cal_component_preview_clear (ECalComponentPreview *preview)
{
- ECalComponentPreviewPrivate *priv;
-
- g_return_if_fail (preview != NULL);
g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview));
- priv = preview->priv;
-
- gtk_html_load_empty (GTK_HTML (priv->html));
-}
-
-GtkWidget *
-e_cal_component_preview_get_html (ECalComponentPreview *preview)
-{
- g_return_val_if_fail (preview != NULL, NULL);
- g_return_val_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview), NULL);
-
- return preview->priv->html;
+ gtk_html_load_empty (GTK_HTML (preview));
}
diff --git a/calendar/gui/e-cal-component-preview.h b/calendar/gui/e-cal-component-preview.h
index f1d26a79f7..8b2b0acd18 100644
--- a/calendar/gui/e-cal-component-preview.h
+++ b/calendar/gui/e-cal-component-preview.h
@@ -1,5 +1,4 @@
/*
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -22,51 +21,62 @@
*
*/
-#ifndef _E_CAL_COMPONENT_PREVIEW_H_
-#define _E_CAL_COMPONENT_PREVIEW_H_
+#ifndef E_CAL_COMPONENT_PREVIEW_H
+#define E_CAL_COMPONENT_PREVIEW_H
#include <gtk/gtk.h>
#include <libecal/e-cal.h>
#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-stream.h>
-#define E_TYPE_CAL_COMPONENT_PREVIEW (e_cal_component_preview_get_type ())
-#define E_CAL_COMPONENT_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreview))
-#define E_CAL_COMPONENT_PREVIEW_CLASS(klass) (G_TYPE_CHECK_INSTANCE_CAST_CLASS ((klass), E_TYPE_CAL_COMPONENT_PREVIEW, \
- ECalComponentPreviewClass))
-#define E_IS_CAL_COMPONENT_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_COMPONENT_PREVIEW))
-#define E_IS_CAL_COMPONENT_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_COMPONENT_PREVIEW))
+/* Standard GObject macros */
+#define E_TYPE_CAL_COMPONENT_PREVIEW \
+ (e_cal_component_preview_get_type ())
+#define E_CAL_COMPONENT_PREVIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreview))
+#define E_CAL_COMPONENT_PREVIEW_CLASS(cls) \
+ (G_TYPE_CHECK_INSTANCE_CAST_CLASS \
+ ((cls), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreviewClass))
+#define E_IS_CAL_COMPONENT_PREVIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_COMPONENT_PREVIEW))
+#define E_IS_CAL_COMPONENT_PREVIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_COMPONENT_PREVIEW))
+#define E_CAL_COMPONENT_PREVIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreviewClass))
+
+G_BEGIN_DECLS
typedef struct _ECalComponentPreview ECalComponentPreview;
typedef struct _ECalComponentPreviewClass ECalComponentPreviewClass;
typedef struct _ECalComponentPreviewPrivate ECalComponentPreviewPrivate;
struct _ECalComponentPreview {
- GtkTable table;
-
- /* Private data */
+ GtkHTML parent;
ECalComponentPreviewPrivate *priv;
};
struct _ECalComponentPreviewClass {
- GtkTableClass parent_class;
+ GtkHTMLClass parent_class;
/* Notification signals */
void (* selection_changed) (ECalComponentPreview *preview, gint n_selected);
};
-GType e_cal_component_preview_get_type (void);
-GtkWidget *e_cal_component_preview_new (void);
-
-icaltimezone *e_cal_component_preview_get_default_timezone (ECalComponentPreview *preview);
-void e_cal_component_preview_set_default_timezone (ECalComponentPreview *preview, icaltimezone *zone);
-
-void e_cal_component_preview_display (ECalComponentPreview *preview, ECal *ecal, ECalComponent *comp);
-void e_cal_component_preview_clear (ECalComponentPreview *preview);
-
-/* Callback used when GtkHTML widget requests URL */
-void e_cal_comp_preview_url_requested_cb (GtkHTML *html, const gchar *url, GtkHTMLStream *html_stream, gpointer data);
+GType e_cal_component_preview_get_type(void);
+GtkWidget * e_cal_component_preview_new (void);
+icaltimezone * e_cal_component_preview_get_default_timezone
+ (ECalComponentPreview *preview);
+void e_cal_component_preview_set_default_timezone
+ (ECalComponentPreview *preview,
+ icaltimezone *zone);
+void e_cal_component_preview_display (ECalComponentPreview *preview,
+ ECal *ecal,
+ ECalComponent *comp);
+void e_cal_component_preview_clear (ECalComponentPreview *preview);
-GtkWidget *e_cal_component_preview_get_html (ECalComponentPreview *preview);
+G_END_DECLS
-#endif /* _E_CAL_COMPONENT_PREVIEW_H_ */
+#endif /* E_CAL_COMPONENT_PREVIEW_H */
diff --git a/calendar/gui/e-cal-config.c b/calendar/gui/e-cal-config.c
index 33b6bc9c46..a8d2ad169f 100644
--- a/calendar/gui/e-cal-config.c
+++ b/calendar/gui/e-cal-config.c
@@ -28,7 +28,6 @@
#include "e-cal-config.h"
static GObjectClass *ecp_parent_class;
-static GObjectClass *ecph_parent_class;
struct _ECalConfigPrivate {
guint source_changed_id;
@@ -166,49 +165,3 @@ e_cal_config_target_new_prefs (ECalConfig *ecp, struct _GConfClient *gconf)
return t;
}
-
-static const EConfigHookTargetMask ecph_no_masks[] = {
- { NULL }
-};
-
-static const EConfigHookTargetMap ecph_targets[] = {
- { "source", EC_CONFIG_TARGET_SOURCE, ecph_no_masks },
- { "prefs", EC_CONFIG_TARGET_PREFS, ecph_no_masks },
- { NULL },
-};
-
-static void
-ecph_class_init (EPluginHookClass *klass)
-{
- gint i;
-
- klass->id = "org.gnome.evolution.calendar.config:1.0";
-
- for (i = 0; ecph_targets[i].type; i++) {
- e_config_hook_class_add_target_map ((EConfigHookClass *)klass, &ecph_targets[i]);
- }
-
- ((EConfigHookClass *)klass)->config_class = g_type_class_ref (e_cal_config_get_type ());
-}
-
-GType
-e_cal_config_hook_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (ECalConfigHookClass),
- NULL, NULL,
- (GClassInitFunc) ecph_class_init,
- NULL, NULL,
- sizeof (ECalConfigHook), 0,
- (GInstanceInitFunc) NULL
- };
-
- ecph_parent_class = g_type_class_ref (e_config_hook_get_type ());
- type = g_type_register_static (e_config_hook_get_type (), "ECalConfigHook", &info, 0);
- }
-
- return type;
-}
diff --git a/calendar/gui/e-cal-config.h b/calendar/gui/e-cal-config.h
index 52989aa0e2..30e12bbf0c 100644
--- a/calendar/gui/e-cal-config.h
+++ b/calendar/gui/e-cal-config.h
@@ -71,21 +71,6 @@ ECalConfig *e_cal_config_new (gint type, const gchar *menuid);
ECalConfigTargetSource *e_cal_config_target_new_source (ECalConfig *ecp, struct _ESource *source);
ECalConfigTargetPrefs *e_cal_config_target_new_prefs (ECalConfig *ecp, struct _GConfClient *gconf);
-/* ********************************************************************** */
-
-typedef struct _ECalConfigHook ECalConfigHook;
-typedef struct _ECalConfigHookClass ECalConfigHookClass;
-
-struct _ECalConfigHook {
- EConfigHook hook;
-};
-
-struct _ECalConfigHookClass {
- EConfigHookClass hook_class;
-};
-
-GType e_cal_config_hook_get_type (void);
-
G_END_DECLS
#endif
diff --git a/calendar/gui/e-cal-event.c b/calendar/gui/e-cal-event.c
index 86bd20e4e7..7d0a9d196d 100644
--- a/calendar/gui/e-cal-event.c
+++ b/calendar/gui/e-cal-event.c
@@ -43,10 +43,12 @@ static void
ece_target_free (EEvent *ev, EEventTarget *t)
{
switch (t->type) {
- case E_CAL_EVENT_TARGET_COMPONENT: {
- ECalEventTargetComponent *s = (ECalEventTargetComponent *) t;
- if (s->component)
- g_object_unref (s->component);
+ case E_CAL_EVENT_TARGET_BACKEND: {
+ ECalEventTargetBackend *s = (ECalEventTargetBackend *) t;
+ if (s->shell_backend)
+ g_object_unref (s->shell_backend);
+ if (s->source_list)
+ g_object_unref (s->source_list);
break; }
}
@@ -92,69 +94,14 @@ e_cal_event_peek (void)
return e_cal_event;
}
-ECalEventTargetComponent *
-e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *component, guint32 flags)
+ECalEventTargetBackend *
+e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, ESourceList *source_list, guint32 flags)
{
- ECalEventTargetComponent *t = e_event_target_new (&ece->event, E_CAL_EVENT_TARGET_COMPONENT, sizeof (*t));
+ ECalEventTargetBackend *t = e_event_target_new (&ece->event, E_CAL_EVENT_TARGET_BACKEND, sizeof (*t));
- t->component = g_object_ref (component);
+ t->shell_backend = g_object_ref (shell_backend);
+ t->source_list = g_object_ref (source_list);
t->target.mask = ~flags;
return t;
}
-
-/* ********************************************************************** */
-
-static gpointer eceh_parent_class;
-
-static const EEventHookTargetMask eceh_component_masks[] = {
- { "migration", E_CAL_EVENT_COMPONENT_MIGRATION },
- { NULL },
-};
-
-static const EEventHookTargetMap eceh_targets[] = {
- { "component", E_CAL_EVENT_TARGET_COMPONENT, eceh_component_masks },
- { NULL },
-};
-
-static void
-eceh_finalize (GObject *o)
-{
- ((GObjectClass *) eceh_parent_class)->finalize (o);
-}
-
-static void
-eceh_class_init (EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = eceh_finalize;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.calendar.events:1.0";
-
- for (i = 0; eceh_targets[i].type; i++)
- e_event_hook_class_add_target_map ((EEventHookClass *)klass, &eceh_targets[i]);
-
- ((EEventHookClass *)klass)->event = (EEvent *) e_cal_event_peek ();
-}
-
-GType
-e_cal_event_hook_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (ECalEventHookClass),
- NULL, NULL,
- (GClassInitFunc) eceh_class_init,
- NULL, NULL,
- sizeof (ECalEventHook), 0,
- (GInstanceInitFunc) NULL,
- };
-
- eceh_parent_class = g_type_class_ref (e_event_hook_get_type ());
- type = g_type_register_static (e_event_hook_get_type (), "ECalEventHook", &info, 0);
- }
-
- return type;
-}
diff --git a/calendar/gui/e-cal-event.h b/calendar/gui/e-cal-event.h
index 8fb28dfd17..8d72a93fa5 100644
--- a/calendar/gui/e-cal-event.h
+++ b/calendar/gui/e-cal-event.h
@@ -25,8 +25,10 @@
#define __E_CAL_EVENT_H__
#include <glib-object.h>
+#include <libedataserver/e-source-list.h>
#include "e-util/e-event.h"
+#include "shell/e-shell-backend.h"
G_BEGIN_DECLS
@@ -34,20 +36,20 @@ typedef struct _ECalEvent ECalEvent;
typedef struct _ECalEventClass ECalEventClass;
enum _e_cal_event_target_t {
- E_CAL_EVENT_TARGET_COMPONENT
+ E_CAL_EVENT_TARGET_BACKEND,
};
-/* Flags that describe TARGET_COMPONENT */
+/* Flags that describe TARGET_BACKEND */
enum {
- E_CAL_EVENT_COMPONENT_MIGRATION = 1 << 0
+ E_CAL_EVENT_MODULE_MIGRATION = 1 << 0,
};
-typedef struct _ECalEventTargetComponent ECalEventTargetComponent;
+typedef struct _ECalEventTargetBackend ECalEventTargetBackend;
-struct _ECalEventTargetComponent {
+struct _ECalEventTargetBackend {
EEventTarget target;
-
- struct _CalendarComponent *component;
+ EShellBackend *shell_backend;
+ ESourceList *source_list;
};
struct _ECalEvent {
@@ -62,22 +64,7 @@ struct _ECalEventClass {
GType e_cal_event_get_type (void);
ECalEvent* e_cal_event_peek (void);
-ECalEventTargetComponent* e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *component, guint32 flags);
-
-/* ********************************************************************** */
-
-typedef struct _ECalEventHook ECalEventHook;
-typedef struct _ECalEventHookClass ECalEventHookClass;
-
-struct _ECalEventHook {
- EEventHook hook;
-};
-
-struct _ECalEventHookClass {
- EEventHookClass hook_class;
-};
-
-GType e_cal_event_hook_get_type (void);
+ECalEventTargetBackend* e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, ESourceList *source_list, guint32 flags);
G_END_DECLS
diff --git a/calendar/gui/e-cal-list-view-config.c b/calendar/gui/e-cal-list-view-config.c
deleted file mode 100644
index 543b5e8eb7..0000000000
--- a/calendar/gui/e-cal-list-view-config.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "calendar-config.h"
-#include "e-cal-list-view-config.h"
-
-struct _ECalListViewConfigPrivate {
- ECalListView *view;
-
- GList *notifications;
-};
-
-/* Property IDs */
-enum props {
- PROP_0,
- PROP_VIEW
-};
-
-G_DEFINE_TYPE (ECalListViewConfig, e_cal_list_view_config, G_TYPE_OBJECT)
-
-static void
-e_cal_list_view_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- ECalListViewConfig *view_config;
-
- view_config = E_CAL_LIST_VIEW_CONFIG (object);
-
- switch (property_id) {
- case PROP_VIEW:
- e_cal_list_view_config_set_view (view_config, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_cal_list_view_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- ECalListViewConfig *view_config;
-
- view_config = E_CAL_LIST_VIEW_CONFIG (object);
-
- switch (property_id) {
- case PROP_VIEW:
- g_value_set_object (value, e_cal_list_view_config_get_view (view_config));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_cal_list_view_config_dispose (GObject *object)
-{
- ECalListViewConfig *view_config = E_CAL_LIST_VIEW_CONFIG (object);
-
- e_cal_list_view_config_set_view (view_config, NULL);
-
- if (G_OBJECT_CLASS (e_cal_list_view_config_parent_class)->dispose)
- G_OBJECT_CLASS (e_cal_list_view_config_parent_class)->dispose (object);
-}
-
-static void
-e_cal_list_view_config_finalize (GObject *object)
-{
- ECalListViewConfig *view_config = E_CAL_LIST_VIEW_CONFIG (object);
- ECalListViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_cal_list_view_config_parent_class)->finalize)
- G_OBJECT_CLASS (e_cal_list_view_config_parent_class)->finalize (object);
-}
-
-static void
-e_cal_list_view_config_class_init (ECalListViewConfigClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *spec;
-
- /* Method override */
- gobject_class->set_property = e_cal_list_view_config_set_property;
- gobject_class->get_property = e_cal_list_view_config_get_property;
- gobject_class->dispose = e_cal_list_view_config_dispose;
- gobject_class->finalize = e_cal_list_view_config_finalize;
-
- spec = g_param_spec_object ("view", NULL, NULL, e_cal_list_view_get_type (),
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (gobject_class, PROP_VIEW, spec);
-}
-
-static void
-e_cal_list_view_config_init (ECalListViewConfig *view_config)
-{
- view_config->priv = g_new0 (ECalListViewConfigPrivate, 1);
-
-}
-
-ECalListViewConfig *
-e_cal_list_view_config_new (ECalListView *list_view)
-{
- ECalListViewConfig *view_config;
-
- view_config = g_object_new (e_cal_list_view_config_get_type (), "view", list_view, NULL);
-
- return view_config;
-}
-
-ECalListView *
-e_cal_list_view_config_get_view (ECalListViewConfig *view_config)
-{
- ECalListViewConfigPrivate *priv;
-
- g_return_val_if_fail (view_config != NULL, NULL);
- g_return_val_if_fail (E_IS_CAL_LIST_VIEW_CONFIG (view_config), NULL);
-
- priv = view_config->priv;
-
- return priv->view;
-}
-
-static void
-set_twentyfour_hour (ECalListView *list_view)
-{
- gboolean use_24_hour;
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- e_calendar_view_set_use_24_hour_format (E_CALENDAR_VIEW (list_view), use_24_hour);
-}
-
-static void
-twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ECalListViewConfig *view_config = data;
- ECalListViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_twentyfour_hour (priv->view);
-}
-
-void
-e_cal_list_view_config_set_view (ECalListViewConfig *view_config, ECalListView *list_view)
-{
- ECalListViewConfigPrivate *priv;
- guint not;
- GList *l;
-
- g_return_if_fail (view_config != NULL);
- g_return_if_fail (E_IS_CAL_LIST_VIEW_CONFIG (view_config));
-
- priv = view_config->priv;
-
- if (priv->view) {
- g_object_unref (priv->view);
- priv->view = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
-
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- /* If the new view is NULL, return right now */
- if (!list_view)
- return;
-
- priv->view = g_object_ref (list_view);
-
- /* 24 Hour format */
- set_twentyfour_hour (list_view);
-
- not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-}
diff --git a/calendar/gui/e-cal-list-view-config.h b/calendar/gui/e-cal-list-view-config.h
deleted file mode 100644
index 270228bed6..0000000000
--- a/calendar/gui/e-cal-list-view-config.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_CAL_LIST_VIEW_CONFIG_H_
-#define _E_CAL_LIST_VIEW_CONFIG_H_
-
-#include "e-cal-list-view.h"
-
-G_BEGIN_DECLS
-
-#define E_CAL_LIST_VIEW_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_cal_list_view_config_get_type (), ECalListViewConfig)
-#define E_CAL_LIST_VIEW_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_cal_list_view_config_get_type (), ECalListViewConfigClass)
-#define E_IS_CAL_LIST_VIEW_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_cal_list_view_config_get_type ())
-
-typedef struct _ECalListViewConfig ECalListViewConfig;
-typedef struct _ECalListViewConfigClass ECalListViewConfigClass;
-typedef struct _ECalListViewConfigPrivate ECalListViewConfigPrivate;
-
-struct _ECalListViewConfig {
- GObject parent;
-
- ECalListViewConfigPrivate *priv;
-};
-
-struct _ECalListViewConfigClass {
- GObjectClass parent_class;
-};
-
-GType e_cal_list_view_config_get_type (void);
-ECalListViewConfig *e_cal_list_view_config_new (ECalListView *list_view);
-ECalListView *e_cal_list_view_config_get_view (ECalListViewConfig *view_config);
-void e_cal_list_view_config_set_view (ECalListViewConfig *view_config, ECalListView *list_view);
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/e-cal-list-view.c b/calendar/gui/e-cal-list-view.c
index d0771398c1..42e7f941eb 100644
--- a/calendar/gui/e-cal-list-view.c
+++ b/calendar/gui/e-cal-list-view.c
@@ -35,6 +35,7 @@
#include <glib/gstdio.h>
#include <gdk/gdkkeysyms.h>
#include <misc/e-gui-utils.h>
+#include <e-util/e-binding.h>
#include <table/e-table-memory-store.h>
#include <table/e-cell-checkbox.h>
#include <table/e-cell-toggle.h>
@@ -42,7 +43,7 @@
#include <table/e-cell-combo.h>
#include <table/e-cell-date.h>
#include <misc/e-popup-menu.h>
-#include <misc/e-cell-date-edit.h>
+#include <table/e-cell-date-edit.h>
#include <e-util/e-categories-config.h>
#include <e-util/e-dialog-utils.h>
#include <e-util/e-util-private.h>
@@ -57,7 +58,6 @@
#include "dialogs/recur-comp.h"
#include "comp-util.h"
#include "itip-utils.h"
-#include "calendar-commands.h"
#include "calendar-config.h"
#include "goto.h"
#include "misc.h"
@@ -72,7 +72,7 @@ static gboolean e_cal_list_view_get_visible_time_range (ECalendarView *cal_view
static gboolean e_cal_list_view_popup_menu (GtkWidget *widget);
static void e_cal_list_view_show_popup_menu (ECalListView *cal_list_view, gint row,
- GdkEvent *gdk_event);
+ GdkEventButton *event);
static gboolean e_cal_list_view_on_table_double_click (GtkWidget *table, gint row, gint col,
GdkEvent *event, gpointer data);
static gboolean e_cal_list_view_on_table_right_click (GtkWidget *table, gint row, gint col,
@@ -189,15 +189,15 @@ e_cal_list_view_save_state (ECalListView *cal_list_view, gchar *filename)
static void
setup_e_table (ECalListView *cal_list_view)
{
- ECalModelCalendar *model;
- ETableExtras *extras;
- GList *strings;
- ECell *cell, *popup_cell;
- GnomeCanvas *canvas;
- GtkStyle *style;
- gchar *etspecfile;
+ ECalModel *model;
+ ETableExtras *extras;
+ GList *strings;
+ ECell *cell, *popup_cell;
+ GnomeCanvas *canvas;
+ GtkStyle *style;
+ gchar *etspecfile;
- model = E_CAL_MODEL_CALENDAR (e_calendar_view_get_model (E_CALENDAR_VIEW (cal_list_view)));
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (cal_list_view));
/* Create the header columns */
@@ -219,9 +219,22 @@ setup_e_table (ECalListView *cal_list_view)
"bg_color_column", E_CAL_MODEL_FIELD_COLOR,
NULL);
+ e_mutual_binding_new (
+ G_OBJECT (model), "timezone",
+ G_OBJECT (cell), "timezone");
+
+ e_mutual_binding_new (
+ G_OBJECT (model), "use-24-hour-format",
+ G_OBJECT (cell), "use-24-hour-format");
+
popup_cell = e_cell_date_edit_new ();
e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
g_object_unref (cell);
+
+ e_mutual_binding_new (
+ G_OBJECT (model), "use-24-hour-format",
+ G_OBJECT (popup_cell), "use-24-hour-format");
+
e_table_extras_add_cell (extras, "dateedit", popup_cell);
cal_list_view->dates_cell = E_CELL_DATE_EDIT (popup_cell);
@@ -297,35 +310,24 @@ setup_e_table (ECalListView *cal_list_view)
gtk_widget_show (GTK_WIDGET (cal_list_view->table_scrolled));
}
-GtkWidget *
-e_cal_list_view_construct (ECalListView *cal_list_view)
-{
- setup_e_table (cal_list_view);
-
- return GTK_WIDGET (cal_list_view);
-}
-
/**
* e_cal_list_view_new:
* @Returns: a new #ECalListView.
*
* Creates a new #ECalListView.
**/
-GtkWidget *
+ECalendarView *
e_cal_list_view_new (ECalModel *model)
{
- ECalListView *cal_list_view;
+ ECalendarView *cal_list_view;
- cal_list_view = g_object_new (e_cal_list_view_get_type (), "model", model, NULL);
- if (!e_cal_list_view_construct (cal_list_view)) {
- g_message (G_STRLOC ": Could not construct the calendar list GUI");
- g_object_unref (cal_list_view);
- return NULL;
- }
+ cal_list_view = g_object_new (
+ E_TYPE_CAL_LIST_VIEW, "model", model, NULL);
+ setup_e_table (E_CAL_LIST_VIEW (cal_list_view));
g_object_unref (model);
- return GTK_WIDGET (cal_list_view);
+ return cal_list_view;
}
static void
@@ -361,12 +363,11 @@ e_cal_list_view_destroy (GtkObject *object)
}
static void
-e_cal_list_view_show_popup_menu (ECalListView *cal_list_view, gint row, GdkEvent *gdk_event)
+e_cal_list_view_show_popup_menu (ECalListView *cal_list_view,
+ gint row,
+ GdkEventButton *event)
{
- GtkMenu *menu;
-
- menu = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (cal_list_view));
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0, gdk_event?gdk_event->button.time:gtk_get_current_event_time());
+ e_calendar_view_popup_event (E_CALENDAR_VIEW (cal_list_view), event);
}
static gboolean
@@ -408,7 +409,7 @@ e_cal_list_view_on_table_right_click (GtkWidget *table, gint row, gint col, GdkE
{
ECalListView *cal_list_view = E_CAL_LIST_VIEW (data);
- e_cal_list_view_show_popup_menu (cal_list_view, row, event);
+ e_cal_list_view_show_popup_menu (cal_list_view, row, (GdkEventButton *) event);
return TRUE;
}
diff --git a/calendar/gui/e-cal-list-view.h b/calendar/gui/e-cal-list-view.h
index df5b3dbeab..f4f71a6269 100644
--- a/calendar/gui/e-cal-list-view.h
+++ b/calendar/gui/e-cal-list-view.h
@@ -30,22 +30,36 @@
#include "e-calendar-view.h"
#include "gnome-cal.h"
-G_BEGIN_DECLS
-
/*
* ECalListView - displays calendar events in an ETable.
*/
-#define E_CAL_LIST_VIEW(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_cal_list_view_get_type (), ECalListView)
-#define E_CAL_LIST_VIEW_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_cal_list_view_get_type (), ECalListViewClass)
-#define E_IS_CAL_LIST_VIEW(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_cal_list_view_get_type ())
+/* Standard GObject macros */
+#define E_TYPE_CAL_LIST_VIEW \
+ (e_cal_list_view_get_type ())
+#define E_CAL_LIST_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_LIST_VIEW, ECalListView))
+#define E_CAL_LIST_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_LIST_VIEW, ECalListViewClass))
+#define E_IS_CAL_LIST_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_LIST_VIEW))
+#define E_IS_CAL_LIST_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_LIST_VIEW))
+#define E_CAL_LIST_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_LIST_VIEW, ECalListViewClass))
+
+G_BEGIN_DECLS
typedef struct _ECalListView ECalListView;
typedef struct _ECalListViewClass ECalListViewClass;
-struct _ECalListView
-{
- ECalendarView cal_view;
+struct _ECalListView {
+ ECalendarView parent;
/* The main display table */
ETableScrolled *table_scrolled;
@@ -66,15 +80,12 @@ struct _ECalListView
gint set_table_id;
};
-struct _ECalListViewClass
-{
+struct _ECalListViewClass {
ECalendarViewClass parent_class;
};
GType e_cal_list_view_get_type (void);
-GtkWidget *e_cal_list_view_construct (ECalListView *cal_list_view);
-
-GtkWidget *e_cal_list_view_new (ECalModel *cal_model);
+ECalendarView *e_cal_list_view_new (ECalModel *cal_model);
void e_cal_list_view_load_state (ECalListView *cal_list_view, gchar *filename);
void e_cal_list_view_save_state (ECalListView *cal_list_view, gchar *filename);
diff --git a/calendar/gui/e-cal-menu.c b/calendar/gui/e-cal-menu.c
deleted file mode 100644
index 30d287ff6b..0000000000
--- a/calendar/gui/e-cal-menu.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include "e-cal-menu.h"
-#include "gui/e-cal-model.h"
-#include "itip-utils.h"
-
-static void ecalm_standard_menu_factory(EMenu *emp, gpointer data);
-
-static GObjectClass *ecalm_parent;
-
-static void
-ecalm_init(GObject *o)
-{
- /*ECalMenu *emp = (ECalMenu *)o; */
-}
-
-static void
-ecalm_finalise(GObject *o)
-{
- ((GObjectClass *)ecalm_parent)->finalize(o);
-}
-
-static void
-ecalm_target_free(EMenu *ep, EMenuTarget *t)
-{
- switch (t->type) {
- case E_CAL_MENU_TARGET_SELECT: {
- ECalMenuTargetSelect *s = (ECalMenuTargetSelect *)t;
- gint i;
-
- for (i=0;i<s->events->len;i++)
- e_cal_model_free_component_data(s->events->pdata[i]);
- g_ptr_array_free(s->events, TRUE);
- g_object_unref(s->model);
- break; }
- }
-
- ((EMenuClass *)ecalm_parent)->target_free(ep, t);
-}
-
-static void
-ecalm_class_init(GObjectClass *klass)
-{
- klass->finalize = ecalm_finalise;
- ((EMenuClass *)klass)->target_free = ecalm_target_free;
-
- e_menu_class_add_factory((EMenuClass *)klass, NULL, (EMenuFactoryFunc)ecalm_standard_menu_factory, NULL);
-}
-
-GType
-e_cal_menu_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(ECalMenuClass),
- NULL, NULL,
- (GClassInitFunc)ecalm_class_init,
- NULL, NULL,
- sizeof(ECalMenu), 0,
- (GInstanceInitFunc)ecalm_init
- };
- ecalm_parent = g_type_class_ref(e_menu_get_type());
- type = g_type_register_static(e_menu_get_type(), "ECalMenu", &info, 0);
- }
-
- return type;
-}
-
-ECalMenu *e_cal_menu_new(const gchar *menuid)
-{
- ECalMenu *emp = g_object_new(e_cal_menu_get_type(), NULL);
-
- e_menu_construct(&emp->menu, menuid);
-
- return emp;
-}
-
-/**
- * e_cal_menu_target_new_select:
- * @folder: The selection will ref this for the life of it.
- * @folder_uri:
- * @uids: The selection will free this when done with it.
- *
- * Create a new selection popup target.
- *
- * Return value:
- **/
-ECalMenuTargetSelect *
-e_cal_menu_target_new_select(ECalMenu *eabp, struct _ECalModel *model, GPtrArray *events)
-{
- ECalMenuTargetSelect *t = e_menu_target_new(&eabp->menu, E_CAL_MENU_TARGET_SELECT, sizeof(*t));
- guint32 mask = ~0;
- ECal *client;
- gboolean read_only;
-
- /* FIXME: This is duplicated in e-cal-popup */
-
- t->model = model;
- g_object_ref(t->model);
- t->events = events;
-
- if (t->events->len == 0) {
- client = e_cal_model_get_default_client(t->model);
- } else {
- ECalModelComponent *comp_data = (ECalModelComponent *)t->events->pdata[0];
-
- mask &= ~E_CAL_MENU_SELECT_ANY;
- if (t->events->len == 1)
- mask &= ~E_CAL_MENU_SELECT_ONE;
- else
- mask &= ~E_CAL_MENU_SELECT_MANY;
-
- if (icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY))
- mask &= ~E_CAL_MENU_SELECT_HASURL;
-
- if (!e_cal_get_static_capability (comp_data->client, CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT)
- && !e_cal_get_static_capability (comp_data->client, CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK)
- && !icalcomponent_get_first_property (comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY))
- mask &= ~E_CAL_MENU_SELECT_ASSIGNABLE;
-
- if (!icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY))
- mask &= ~ E_CAL_MENU_SELECT_NOTCOMPLETE;
-
- if (e_cal_util_component_has_recurrences (comp_data->icalcomp))
- mask &= ~E_CAL_MENU_SELECT_RECURRING;
- else if (e_cal_util_component_is_instance (comp_data->icalcomp))
- mask &= ~E_CAL_MENU_SELECT_RECURRING;
- else
- mask &= ~E_CAL_MENU_SELECT_NONRECURRING;
-
- if (e_cal_util_component_is_instance (comp_data->icalcomp))
- mask &= ~E_CAL_MENU_SELECT_INSTANCE;
-
- if (e_cal_util_component_has_organizer (comp_data->icalcomp)) {
- ECalComponent *comp;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- if (!itip_organizer_is_user (comp, comp_data->client))
- mask &= ~E_CAL_MENU_SELECT_ORGANIZER;
-
- g_object_unref (comp);
- } else {
- /* organiser is synonym for owner in this case */
- mask &= ~(E_CAL_MENU_SELECT_ORGANIZER|E_CAL_MENU_SELECT_NOTMEETING);
- }
-
- client = comp_data->client;
- }
-
- if (client) {
- e_cal_is_read_only(client, &read_only, NULL);
- if (!read_only)
- mask &= ~E_CAL_MENU_SELECT_EDITABLE;
- }
-
- /* This bit isn't implemented ... */
- mask &= ~E_CAL_MENU_SELECT_NOTEDITING;
-
- t->target.mask = mask;
-
- return t;
-}
-
-static void
-ecalm_standard_menu_factory(EMenu *emp, gpointer data)
-{
- /* noop */
-}
-
-/* ********************************************************************** */
-
-/* menu plugin handler */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.item:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="IMAP4 and IMAP4v1 mail store">
- <hook class="org.gnome.mail.popupMenu:1.0"
- handler="HandlePopup">
- <menu id="any" target="select">
- <item
- type="item|toggle|radio|image|submenu|bar"
- active
- path="foo/bar"
- label="label"
- icon="foo"
- mask="select_one"
- activate="ecalm_view_emacs"/>
- </menu>
- </extension>
-
-*/
-
-static gpointer ecalph_parent_class;
-#define ecalph ((ECalMenuHook *)eph)
-
-static const EMenuHookTargetMask ecalph_select_masks[] = {
- { "one", E_CAL_MENU_SELECT_ONE },
- { "many", E_CAL_MENU_SELECT_MANY },
- { "editable", E_CAL_MENU_SELECT_EDITABLE },
- { "recurring", E_CAL_MENU_SELECT_RECURRING },
- { "non-recurring", E_CAL_MENU_SELECT_NONRECURRING },
- { "instance", E_CAL_MENU_SELECT_INSTANCE },
- { "organizer", E_CAL_MENU_SELECT_ORGANIZER },
- { "not-editing", E_CAL_MENU_SELECT_NOTEDITING },
- { "not-meeting", E_CAL_MENU_SELECT_NOTMEETING },
- { "assignable", E_CAL_MENU_SELECT_ASSIGNABLE },
- { "hasurl", E_CAL_MENU_SELECT_HASURL },
- { "not-complete", E_CAL_MENU_SELECT_NOTCOMPLETE },
- { NULL }
-};
-
-static const EMenuHookTargetMap ecalph_targets[] = {
- { "select", E_CAL_MENU_TARGET_SELECT, ecalph_select_masks },
- { NULL }
-};
-
-static void
-ecalph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)ecalph_parent_class)->finalize(o);
-}
-
-static void
-ecalph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = ecalph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.calendar.bonobomenu:1.0";
-
- for (i = 0; ecalph_targets[i].type; i++)
- e_menu_hook_class_add_target_map((EMenuHookClass *)klass, &ecalph_targets[i]);
-
- /* FIXME: leaks parent set class? */
- ((EMenuHookClass *)klass)->menu_class = g_type_class_ref(e_cal_menu_get_type());
-}
-
-GType
-e_cal_menu_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(ECalMenuHookClass), NULL, NULL, (GClassInitFunc) ecalph_class_init, NULL, NULL,
- sizeof(ECalMenuHook), 0, (GInstanceInitFunc) NULL,
- };
-
- ecalph_parent_class = g_type_class_ref(e_menu_hook_get_type());
- type = g_type_register_static(e_menu_hook_get_type(), "ECalMenuHook", &info, 0);
- }
-
- return type;
-}
diff --git a/calendar/gui/e-cal-menu.h b/calendar/gui/e-cal-menu.h
deleted file mode 100644
index 0667f92051..0000000000
--- a/calendar/gui/e-cal-menu.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michel Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __E_CAL_MENU_H__
-#define __E_CAL_MENU_H__
-
-#include <glib-object.h>
-
-#include "e-util/e-menu.h"
-
-G_BEGIN_DECLS
-
-typedef struct _ECalMenu ECalMenu;
-typedef struct _ECalMenuClass ECalMenuClass;
-
-/* Current target description */
-/* Types of popup tagets */
-enum _e_cal_menu_target_t {
- E_CAL_MENU_TARGET_SELECT
-};
-
-/**
- * enum _e_cal_menu_target_select_t - ECalPopupTargetSelect qualifiers.
- *
- * @E_CAL_MENU_SELECT_ONE: Only one item is selected.
- * @E_CAL_MENU_SELECT_MANY: More than one item selected.
- * @E_CAL_MENU_SELECT_ANY: One or more items selected.
- * @E_CAL_MENU_SELECT_EDITABLE: The selection is editable.
- * @E_CAL_MENU_SELECT_RECURRING: Is a recurring event.
- * @E_CAL_MENU_SELECT_NONRECURRING: Is not a recurring event.
- * @E_CAL_MENU_SELECT_INSTANCE: This is an instance event.
- * @E_CAL_MENU_SELECT_ORGANIZER: The user is the organiser of the event.
- * @E_CAL_MENU_SELECT_NOTEDITING: The event is not being edited already. Not implemented.
- * @E_CAL_MENU_SELECT_NOTMEETING: The event is not a meeting.
- * @E_CAL_MENU_SELECT_ASSIGNABLE: An assignable task.
- * @E_CAL_MENU_SELECT_HASURL: A task that contains a URL.
- **/
-enum _e_cal_menu_target_select_t {
- E_CAL_MENU_SELECT_ONE = 1<<0,
- E_CAL_MENU_SELECT_MANY = 1<<1,
- E_CAL_MENU_SELECT_ANY = 1<<2,
- E_CAL_MENU_SELECT_EDITABLE = 1<<3,
- E_CAL_MENU_SELECT_RECURRING = 1<<4,
- E_CAL_MENU_SELECT_NONRECURRING = 1<<5,
- E_CAL_MENU_SELECT_INSTANCE = 1<<6,
-
- E_CAL_MENU_SELECT_ORGANIZER = 1<<7,
- E_CAL_MENU_SELECT_NOTEDITING = 1<<8,
- E_CAL_MENU_SELECT_NOTMEETING = 1<<9,
-
- E_CAL_MENU_SELECT_ASSIGNABLE = 1<<10,
- E_CAL_MENU_SELECT_HASURL = 1<<11,
- E_CAL_MENU_SELECT_NOTCOMPLETE = 1<<12
-};
-
-typedef struct _ECalMenuTargetSelect ECalMenuTargetSelect;
-
-struct _ECalMenuTargetSelect {
- EMenuTarget target;
-
- struct _ECalModel *model;
- GPtrArray *events;
-};
-
-typedef struct _EMenuItem ECalMenuItem;
-
-/* The object */
-struct _ECalMenu {
- EMenu menu;
-
- struct _ECalMenuPrivate *priv;
-};
-
-struct _ECalMenuClass {
- EMenuClass menu_class;
-};
-
-GType e_cal_menu_get_type(void);
-
-ECalMenu *e_cal_menu_new(const gchar *menuid);
-
-ECalMenuTargetSelect *e_cal_menu_target_new_select(ECalMenu *emp, struct _ECalModel *model, GPtrArray *events);
-
-/* ********************************************************************** */
-
-typedef struct _ECalMenuHook ECalMenuHook;
-typedef struct _ECalMenuHookClass ECalMenuHookClass;
-
-struct _ECalMenuHook {
- EMenuHook hook;
-};
-
-struct _ECalMenuHookClass {
- EMenuHookClass hook_class;
-};
-
-GType e_cal_menu_hook_get_type(void);
-
-G_END_DECLS
-
-#endif /* __E_CAL_MENU_H__ */
diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c
index fbf3235abf..9f94a601c1 100644
--- a/calendar/gui/e-cal-model-calendar.c
+++ b/calendar/gui/e-cal-model-calendar.c
@@ -570,8 +570,12 @@ ecmc_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data,
/**
* e_cal_model_calendar_new
*/
-ECalModelCalendar *
-e_cal_model_calendar_new (void)
+ECalModel *
+e_cal_model_calendar_new (EShellSettings *shell_settings)
{
- return g_object_new (E_TYPE_CAL_MODEL_CALENDAR, NULL);
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+
+ return g_object_new (
+ E_TYPE_CAL_MODEL_CALENDAR,
+ "shell-settings", shell_settings, NULL);
}
diff --git a/calendar/gui/e-cal-model-calendar.h b/calendar/gui/e-cal-model-calendar.h
index abe536399f..f1027032cb 100644
--- a/calendar/gui/e-cal-model-calendar.h
+++ b/calendar/gui/e-cal-model-calendar.h
@@ -28,14 +28,29 @@
#include "e-cal-model.h"
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_CAL_MODEL_CALENDAR \
+ (e_cal_model_calendar_get_type ())
+#define E_CAL_MODEL_CALENDAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_MODEL_CALENDAR, ECalModelCalendar))
+#define E_CAL_MODEL_CALENDAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_MODEL_CALENDAR, ECalModelCalendarClass))
+#define E_IS_CAL_MODEL_CALENDAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_MODEL_CALENDAR))
+#define E_IS_CAL_MODEL_CALENDAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_MODEL_CALENDAR))
+#define E_CAL_MODEL_CALENDAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_MODEL_CALENDAR, ECalModelCalendarClass))
-#define E_TYPE_CAL_MODEL_CALENDAR (e_cal_model_calendar_get_type ())
-#define E_CAL_MODEL_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL_CALENDAR, ECalModelCalendar))
-#define E_CAL_MODEL_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL_CALENDAR, ECalModelCalendarClass))
-#define E_IS_CAL_MODEL_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL_CALENDAR))
-#define E_IS_CAL_MODEL_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL_CALENDAR))
+G_BEGIN_DECLS
+typedef struct _ECalModelCalendar ECalModelCalendar;
+typedef struct _ECalModelCalendarClass ECalModelCalendarClass;
typedef struct _ECalModelCalendarPrivate ECalModelCalendarPrivate;
typedef enum {
@@ -47,18 +62,18 @@ typedef enum {
E_CAL_MODEL_CALENDAR_FIELD_LAST
} ECalModelCalendarField;
-typedef struct {
- ECalModel model;
+struct _ECalModelCalendar {
+ ECalModel parent;
ECalModelCalendarPrivate *priv;
-} ECalModelCalendar;
+};
-typedef struct {
+struct _ECalModelCalendarClass {
ECalModelClass parent_class;
-} ECalModelCalendarClass;
+};
-GType e_cal_model_calendar_get_type (void);
-ECalModelCalendar *e_cal_model_calendar_new (void);
+GType e_cal_model_calendar_get_type (void);
+ECalModel * e_cal_model_calendar_new (EShellSettings *shell_settings);
G_END_DECLS
-#endif
+#endif /* E_CAL_MODEL_CALENDAR_H */
diff --git a/calendar/gui/e-cal-model-memos.c b/calendar/gui/e-cal-model-memos.c
index dc21b9bdda..41f63700c8 100644
--- a/calendar/gui/e-cal-model-memos.c
+++ b/calendar/gui/e-cal-model-memos.c
@@ -260,8 +260,12 @@ ecmm_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data,
/**
* e_cal_model_memos_new
*/
-ECalModelMemos *
-e_cal_model_memos_new (void)
+ECalModel *
+e_cal_model_memos_new (EShellSettings *shell_settings)
{
- return g_object_new (E_TYPE_CAL_MODEL_MEMOS, NULL);
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+
+ return g_object_new (
+ E_TYPE_CAL_MODEL_MEMOS,
+ "shell-settings", shell_settings, NULL);
}
diff --git a/calendar/gui/e-cal-model-memos.h b/calendar/gui/e-cal-model-memos.h
index 34b8e5a14d..b58faa539b 100644
--- a/calendar/gui/e-cal-model-memos.h
+++ b/calendar/gui/e-cal-model-memos.h
@@ -29,14 +29,29 @@
#include "e-cal-model.h"
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_CAL_MODEL_MEMOS \
+ (e_cal_model_memos_get_type ())
+#define E_CAL_MODEL_MEMOS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_MODEL_MEMOS, ECalModelMemo))
+#define E_CAL_MODEL_MEMOS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_MODEL_MEMOS, ECalModelMemoClass))
+#define E_IS_CAL_MODEL_MEMOS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_MODEL_MEMOS))
+#define E_IS_CAL_MODEL_MEMOS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_MODEL_MEMOS))
+#define E_CAL_MODEL_MEMOS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_MODEL_MEMOS, ECalModelMemoClass))
-#define E_TYPE_CAL_MODEL_MEMOS (e_cal_model_memos_get_type ())
-#define E_CAL_MODEL_MEMOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL_MEMOS, ECalModelMemo))
-#define E_CAL_MODEL_MEMOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL_MEMOS, ECalModelMemoClass))
-#define E_IS_CAL_MODEL_MEMOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL_MEMOS))
-#define E_IS_CAL_MODEL_MEMOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL_MEMOS))
+G_BEGIN_DECLS
+typedef struct _ECalModelMemos ECalModelMemos;
+typedef struct _ECalModelMemosClass ECalModelMemosClass;
typedef struct _ECalModelMemosPrivate ECalModelMemosPrivate;
typedef enum {
@@ -46,18 +61,18 @@ typedef enum {
} ECalModelMemoField;
-typedef struct {
- ECalModel model;
+struct _ECalModelMemos {
+ ECalModel parent;
ECalModelMemosPrivate *priv;
-} ECalModelMemos;
+};
-typedef struct {
+struct _ECalModelMemosClass {
ECalModelClass parent_class;
-} ECalModelMemosClass;
+};
-GType e_cal_model_memos_get_type (void);
-ECalModelMemos *e_cal_model_memos_new (void);
+GType e_cal_model_memos_get_type (void);
+ECalModel * e_cal_model_memos_new (EShellSettings *shell_settings);
G_END_DECLS
-#endif
+#endif /* E_CAL_MODEL_MEMOS_H */
diff --git a/calendar/gui/e-cal-model-tasks.c b/calendar/gui/e-cal-model-tasks.c
index d951d13878..74647e46dc 100644
--- a/calendar/gui/e-cal-model-tasks.c
+++ b/calendar/gui/e-cal-model-tasks.c
@@ -31,17 +31,22 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <libedataserver/e-data-server-util.h>
+
+#include "e-util/e-binding.h"
#include "calendar-config.h"
#include "e-cal-model-tasks.h"
#include "e-cell-date-edit-text.h"
#include "misc.h"
+#define E_CAL_MODEL_TASKS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CAL_MODEL_TASKS, ECalModelTasksPrivate))
+
struct _ECalModelTasksPrivate {
- guint reserved;
+ gchar *color_due_today;
+ gchar *color_overdue;
};
-static void e_cal_model_tasks_finalize (GObject *object);
-
static gint ecmt_column_count (ETableModel *etm);
static gpointer ecmt_value_at (ETableModel *etm, gint col, gint row);
static void ecmt_set_value_at (ETableModel *etm, gint col, gint row, gconstpointer value);
@@ -59,56 +64,153 @@ static void commit_component_changes (ECalModelComponent *comp_data);
G_DEFINE_TYPE (ECalModelTasks, e_cal_model_tasks, E_TYPE_CAL_MODEL)
+enum {
+ PROP_0,
+ PROP_COLOR_DUE_TODAY,
+ PROP_COLOR_OVERDUE
+};
+
static void
-e_cal_model_tasks_class_init (ECalModelTasksClass *klass)
+cal_model_tasks_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (klass);
- ECalModelClass *model_class = E_CAL_MODEL_CLASS (klass);
-
- object_class->finalize = e_cal_model_tasks_finalize;
-
- etm_class->column_count = ecmt_column_count;
- etm_class->value_at = ecmt_value_at;
- etm_class->set_value_at = ecmt_set_value_at;
- etm_class->is_cell_editable = ecmt_is_cell_editable;
- etm_class->duplicate_value = ecmt_duplicate_value;
- etm_class->free_value = ecmt_free_value;
- etm_class->initialize_value = ecmt_initialize_value;
- etm_class->value_is_empty = ecmt_value_is_empty;
- etm_class->value_to_string = ecmt_value_to_string;
-
- model_class->get_color_for_component = ecmt_get_color_for_component;
- model_class->fill_component_from_model = ecmt_fill_component_from_model;
+ switch (property_id) {
+ case PROP_COLOR_DUE_TODAY:
+ e_cal_model_tasks_set_color_due_today (
+ E_CAL_MODEL_TASKS (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_COLOR_OVERDUE:
+ e_cal_model_tasks_set_color_overdue (
+ E_CAL_MODEL_TASKS (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_cal_model_tasks_init (ECalModelTasks *model)
+cal_model_tasks_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COLOR_DUE_TODAY:
+ g_value_set_string (
+ value,
+ e_cal_model_tasks_get_color_due_today (
+ E_CAL_MODEL_TASKS (object)));
+ return;
+
+ case PROP_COLOR_OVERDUE:
+ g_value_set_string (
+ value,
+ e_cal_model_tasks_get_color_overdue (
+ E_CAL_MODEL_TASKS (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cal_model_tasks_finalize (GObject *object)
{
ECalModelTasksPrivate *priv;
- priv = g_new0 (ECalModelTasksPrivate, 1);
- model->priv = priv;
+ priv = E_CAL_MODEL_TASKS_GET_PRIVATE (object);
+
+ g_free (priv->color_due_today);
+ g_free (priv->color_overdue);
- e_cal_model_set_component_kind (E_CAL_MODEL (model), ICAL_VTODO_COMPONENT);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_cal_model_tasks_parent_class)->finalize (object);
}
static void
-e_cal_model_tasks_finalize (GObject *object)
+cal_model_tasks_constructed (GObject *object)
{
- ECalModelTasksPrivate *priv;
- ECalModelTasks *model = (ECalModelTasks *) object;
+ ECalModel *model;
+ EShellSettings *shell_settings;
- g_return_if_fail (E_IS_CAL_MODEL_TASKS (model));
+ model = E_CAL_MODEL (object);
+ shell_settings = e_cal_model_get_shell_settings (model);
- priv = model->priv;
- if (priv) {
- g_free (priv);
- model->priv = NULL;
- }
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-tasks-color-due-today",
+ G_OBJECT (model), "color-due-today");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-tasks-color-overdue",
+ G_OBJECT (model), "color-overdue");
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_cal_model_tasks_parent_class)->constructed (object);
+}
+
+static void
+e_cal_model_tasks_class_init (ECalModelTasksClass *class)
+{
+ GObjectClass *object_class;
+ ETableModelClass *table_model_class;
+ ECalModelClass *cal_model_class;
+
+ g_type_class_add_private (class, sizeof (ECalModelTasksPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = cal_model_tasks_set_property;
+ object_class->get_property = cal_model_tasks_get_property;
+ object_class->finalize = cal_model_tasks_finalize;
+ object_class->constructed = cal_model_tasks_constructed;
+
+ table_model_class = E_TABLE_MODEL_CLASS (class);
+ table_model_class->column_count = ecmt_column_count;
+ table_model_class->value_at = ecmt_value_at;
+ table_model_class->set_value_at = ecmt_set_value_at;
+ table_model_class->is_cell_editable = ecmt_is_cell_editable;
+ table_model_class->duplicate_value = ecmt_duplicate_value;
+ table_model_class->free_value = ecmt_free_value;
+ table_model_class->initialize_value = ecmt_initialize_value;
+ table_model_class->value_is_empty = ecmt_value_is_empty;
+ table_model_class->value_to_string = ecmt_value_to_string;
+
+ cal_model_class = E_CAL_MODEL_CLASS (class);
+ cal_model_class->get_color_for_component = ecmt_get_color_for_component;
+ cal_model_class->fill_component_from_model = ecmt_fill_component_from_model;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_COLOR_DUE_TODAY,
+ g_param_spec_string (
+ "color-due-today",
+ "Color Due Today",
+ NULL,
+ "#1e90ff",
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_COLOR_OVERDUE,
+ g_param_spec_string (
+ "color-overdue",
+ "Color Overdue",
+ NULL,
+ "#ff0000",
+ G_PARAM_READWRITE));
+}
+
+static void
+e_cal_model_tasks_init (ECalModelTasks *model)
+{
+ model->priv = E_CAL_MODEL_TASKS_GET_PRIVATE (model);
- if (G_OBJECT_CLASS (e_cal_model_tasks_parent_class)->finalize)
- G_OBJECT_CLASS (e_cal_model_tasks_parent_class)->finalize (object);
+ e_cal_model_set_component_kind (
+ E_CAL_MODEL (model), ICAL_VTODO_COMPONENT);
}
/* ETableModel methods */
@@ -1038,11 +1140,9 @@ ecmt_value_to_string (ETableModel *etm, gint col, gconstpointer value)
/* ECalModel class methods */
static const gchar *
-ecmt_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data)
+ecmt_get_color_for_component (ECalModel *model,
+ ECalModelComponent *comp_data)
{
- static gchar color_spec[16];
- GdkColor color;
-
g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), NULL);
g_return_val_if_fail (comp_data != NULL, NULL);
@@ -1051,24 +1151,19 @@ ecmt_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data)
switch (get_due_status ((ECalModelTasks *) model, comp_data)) {
case E_CAL_MODEL_TASKS_DUE_TODAY:
- /* XXX ugly hack */
- calendar_config_get_tasks_due_today_color (&color);
- g_snprintf (color_spec, sizeof (color_spec), "#%04x%04x%04x",
- color.red, color.green, color.blue);
- return color_spec;
+ return e_cal_model_tasks_get_color_due_today (
+ E_CAL_MODEL_TASKS (model));
case E_CAL_MODEL_TASKS_DUE_OVERDUE:
- /* XXX ugly hack */
- calendar_config_get_tasks_overdue_color (&color);
- g_snprintf (color_spec, sizeof (color_spec), "#%04x%04x%04x",
- color.red, color.green, color.blue);
- return color_spec;
+ return e_cal_model_tasks_get_color_overdue (
+ E_CAL_MODEL_TASKS (model));
case E_CAL_MODEL_TASKS_DUE_NEVER:
case E_CAL_MODEL_TASKS_DUE_FUTURE:
case E_CAL_MODEL_TASKS_DUE_COMPLETE:
break;
}
- return E_CAL_MODEL_CLASS (e_cal_model_tasks_parent_class)->get_color_for_component (model, comp_data);
+ return E_CAL_MODEL_CLASS (e_cal_model_tasks_parent_class)->
+ get_color_for_component (model, comp_data);
}
static void
@@ -1103,13 +1198,56 @@ ecmt_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data,
e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_URL, row));
}
-/**
- * e_cal_model_tasks_new
- */
-ECalModelTasks *
-e_cal_model_tasks_new (void)
+ECalModel *
+e_cal_model_tasks_new (EShellSettings *shell_settings)
+{
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+
+ return g_object_new (
+ E_TYPE_CAL_MODEL_TASKS,
+ "shell-settings", shell_settings, NULL);
+}
+
+const gchar *
+e_cal_model_tasks_get_color_due_today (ECalModelTasks *model)
+{
+ g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), NULL);
+
+ return model->priv->color_due_today;
+}
+
+void
+e_cal_model_tasks_set_color_due_today (ECalModelTasks *model,
+ const gchar *color_due_today)
+{
+ g_return_if_fail (E_IS_CAL_MODEL_TASKS (model));
+ g_return_if_fail (color_due_today != NULL);
+
+ g_free (model->priv->color_due_today);
+ model->priv->color_due_today = g_strdup (color_due_today);
+
+ g_object_notify (G_OBJECT (model), "color-due-today");
+}
+
+const gchar *
+e_cal_model_tasks_get_color_overdue (ECalModelTasks *model)
+{
+ g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), NULL);
+
+ return model->priv->color_overdue;
+}
+
+void
+e_cal_model_tasks_set_color_overdue (ECalModelTasks *model,
+ const gchar *color_overdue)
{
- return g_object_new (E_TYPE_CAL_MODEL_TASKS, NULL);
+ g_return_if_fail (E_IS_CAL_MODEL_TASKS (model));
+ g_return_if_fail (color_overdue != NULL);
+
+ g_free (model->priv->color_overdue);
+ model->priv->color_overdue = g_strdup (color_overdue);
+
+ g_object_notify (G_OBJECT (model), "color-overdue");
}
/**
diff --git a/calendar/gui/e-cal-model-tasks.h b/calendar/gui/e-cal-model-tasks.h
index 0900d1e155..056325547d 100644
--- a/calendar/gui/e-cal-model-tasks.h
+++ b/calendar/gui/e-cal-model-tasks.h
@@ -28,14 +28,29 @@
#include "e-cal-model.h"
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_CAL_MODEL_TASKS \
+ (e_cal_model_tasks_get_type ())
+#define E_CAL_MODEL_TASKS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_MODEL_TASKS, ECalModelTasks))
+#define E_CAL_MODEL_TASKS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_MODEL_TASKS, ECalModelTasksClass))
+#define E_IS_CAL_MODEL_TASKS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_MODEL_TASKS))
+#define E_IS_CAL_MODEL_TASKS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_MODEL_TASKS))
+#define E_CAL_MODEL_TASKS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_MODEL_TASKS, ECalModelTasksClass))
-#define E_TYPE_CAL_MODEL_TASKS (e_cal_model_tasks_get_type ())
-#define E_CAL_MODEL_TASKS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL_TASKS, ECalModelTasks))
-#define E_CAL_MODEL_TASKS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL_TASKS, ECalModelTasksClass))
-#define E_IS_CAL_MODEL_TASKS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL_TASKS))
-#define E_IS_CAL_MODEL_TASKS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL_TASKS))
+G_BEGIN_DECLS
+typedef struct _ECalModelTasks ECalModelTasks;
+typedef struct _ECalModelTasksClass ECalModelTasksClass;
typedef struct _ECalModelTasksPrivate ECalModelTasksPrivate;
typedef enum {
@@ -54,22 +69,36 @@ typedef enum {
E_CAL_MODEL_TASKS_FIELD_LAST
} ECalModelTasksField;
-typedef struct {
- ECalModel model;
+struct _ECalModelTasks {
+ ECalModel parent;
ECalModelTasksPrivate *priv;
-} ECalModelTasks;
+};
-typedef struct {
+struct _ECalModelTasksClass {
ECalModelClass parent_class;
-} ECalModelTasksClass;
-
-GType e_cal_model_tasks_get_type (void);
-ECalModelTasks *e_cal_model_tasks_new (void);
+};
-void e_cal_model_tasks_mark_comp_complete (ECalModelTasks *model, ECalModelComponent *comp_data);
-void e_cal_model_tasks_mark_comp_incomplete (ECalModelTasks *model, ECalModelComponent *comp_data);
-void e_cal_model_tasks_update_due_tasks (ECalModelTasks *model);
+GType e_cal_model_tasks_get_type (void);
+ECalModel * e_cal_model_tasks_new (EShellSettings *shell_settings);
+const gchar * e_cal_model_tasks_get_color_due_today
+ (ECalModelTasks *model);
+void e_cal_model_tasks_set_color_due_today
+ (ECalModelTasks *model,
+ const gchar *color_due_today);
+const gchar * e_cal_model_tasks_get_color_overdue
+ (ECalModelTasks *model);
+void e_cal_model_tasks_set_color_overdue
+ (ECalModelTasks *model,
+ const gchar *color_overdue);
+void e_cal_model_tasks_mark_comp_complete
+ (ECalModelTasks *model,
+ ECalModelComponent *comp_data);
+void e_cal_model_tasks_mark_comp_incomplete
+ (ECalModelTasks *model,
+ ECalModelComponent *comp_data);
+void e_cal_model_tasks_update_due_tasks
+ (ECalModelTasks *model);
G_END_DECLS
-#endif
+#endif /* E_CAL_MODEL_TASKS_H */
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index ff6ae4172a..c582b0fb78 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -35,8 +35,16 @@
#include "e-cal-model.h"
#include "itip-utils.h"
#include "misc.h"
+#include "e-util/e-binding.h"
#include "e-util/e-util.h"
-#include "calendar-config.h"
+
+#define E_CAL_MODEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CAL_MODEL, ECalModelPrivate))
+
+#define E_CAL_MODEL_COMPONENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponentPrivate))
typedef struct {
ECal *client;
@@ -46,6 +54,8 @@ typedef struct {
} ECalModelClient;
struct _ECalModelPrivate {
+ EShellSettings *shell_settings;
+
/* The list of clients we are managing. Each element is of type ECalModelClient */
GList *clients;
@@ -78,6 +88,9 @@ struct _ECalModelPrivate {
/* Whether we display dates in 24-hour format. */
gboolean use_24_hour_format;
+ /* First day of the week: 0 (Monday) to 6 (Sunday) */
+ gint week_start_day;
+
/* callback, to retrieve start time for newly added rows by click-to-add */
ECalModelDefaultTimeFunc get_default_time;
gpointer get_default_time_user_data;
@@ -93,13 +106,6 @@ struct _ECalModelPrivate {
GMutex *notify_lock;
};
-#define E_CAL_MODEL_COMPONENT_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponentPrivate))
-
-static void e_cal_model_dispose (GObject *object);
-static void e_cal_model_finalize (GObject *object);
-
static gint ecm_column_count (ETableModel *etm);
static gint ecm_row_count (ETableModel *etm);
static gpointer ecm_value_at (ETableModel *etm, gint col, gint row);
@@ -119,7 +125,14 @@ static ECalModelClient *find_client_data (ECalModel *model, ECal *client);
static void remove_client_objects (ECalModel *model, ECalModelClient *client_data);
static void remove_client (ECalModel *model, ECalModelClient *client_data);
-/* Signal IDs */
+enum {
+ PROP_0,
+ PROP_SHELL_SETTINGS,
+ PROP_TIMEZONE,
+ PROP_USE_24_HOUR_FORMAT,
+ PROP_WEEK_START_DAY
+};
+
enum {
TIME_RANGE_CHANGED,
ROW_APPENDED,
@@ -129,19 +142,203 @@ enum {
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0 };
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE (ECalModel, e_cal_model, E_TABLE_MODEL_TYPE)
static void
-e_cal_model_class_init (ECalModelClass *klass)
+cal_model_set_shell_settings (ECalModel *cal_model,
+ EShellSettings *shell_settings)
+{
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (cal_model->priv->shell_settings == NULL);
+
+ cal_model->priv->shell_settings = g_object_ref (shell_settings);
+}
+
+static void
+cal_model_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_SETTINGS:
+ cal_model_set_shell_settings (
+ E_CAL_MODEL (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_TIMEZONE:
+ e_cal_model_set_timezone (
+ E_CAL_MODEL (object),
+ g_value_get_pointer (value));
+ return;
+
+ case PROP_USE_24_HOUR_FORMAT:
+ e_cal_model_set_use_24_hour_format (
+ E_CAL_MODEL (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_WEEK_START_DAY:
+ e_cal_model_set_week_start_day (
+ E_CAL_MODEL (object),
+ g_value_get_int (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cal_model_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_SETTINGS:
+ g_value_set_object (
+ value,
+ e_cal_model_get_shell_settings (
+ E_CAL_MODEL (object)));
+ return;
+
+ case PROP_TIMEZONE:
+ g_value_set_pointer (
+ value,
+ e_cal_model_get_timezone (
+ E_CAL_MODEL (object)));
+ return;
+
+ case PROP_USE_24_HOUR_FORMAT:
+ g_value_set_boolean (
+ value,
+ e_cal_model_get_use_24_hour_format (
+ E_CAL_MODEL (object)));
+ return;
+
+ case PROP_WEEK_START_DAY:
+ g_value_set_int (
+ value,
+ e_cal_model_get_week_start_day (
+ E_CAL_MODEL (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cal_model_dispose (GObject *object)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (klass);
+ ECalModelPrivate *priv;
+
+ priv = E_CAL_MODEL_GET_PRIVATE (object);
+
+ if (priv->shell_settings != NULL) {
+ g_object_unref (priv->shell_settings);
+ priv->shell_settings = NULL;
+ }
- object_class->dispose = e_cal_model_dispose;
- object_class->finalize = e_cal_model_finalize;
+ if (priv->clients) {
+ while (priv->clients != NULL) {
+ ECalModelClient *client_data = (ECalModelClient *) priv->clients->data;
+
+ g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ if (client_data->query)
+ g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+
+ priv->clients = g_list_remove (priv->clients, client_data);
+
+ g_object_unref (client_data->client);
+ if (client_data->query)
+ g_object_unref (client_data->query);
+ g_free (client_data);
+ }
+
+ priv->clients = NULL;
+ priv->default_client = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+static void
+cal_model_finalize (GObject *object)
+{
+ ECalModelPrivate *priv;
+ gint ii;
+
+ priv = E_CAL_MODEL_GET_PRIVATE (object);
+
+ g_free (priv->search_sexp);
+ g_free (priv->full_sexp);
+
+ g_free (priv->default_category);
+
+ for (ii = 0; ii < priv->objects->len; ii++) {
+ ECalModelComponent *comp_data;
+
+ comp_data = g_ptr_array_index (priv->objects, ii);
+ if (comp_data == NULL) {
+ g_warning ("comp_data is null\n");
+ continue;
+ }
+ e_cal_model_free_component_data (comp_data);
+ }
+ g_ptr_array_free (priv->objects, FALSE);
+
+ g_mutex_free (priv->notify_lock);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+cal_model_constructed (GObject *object)
+{
+ ECalModel *model;
+ EShellSettings *shell_settings;
+
+ model = E_CAL_MODEL (object);
+ shell_settings = e_cal_model_get_shell_settings (model);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-timezone",
+ G_OBJECT (model), "timezone");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-use-24-hour-format",
+ G_OBJECT (model), "use-24-hour-format");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-week-start-day",
+ G_OBJECT (model), "week-start-day");
+}
+
+static void
+e_cal_model_class_init (ECalModelClass *class)
+{
+ GObjectClass *object_class;
+ ETableModelClass *etm_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECalModelPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = cal_model_set_property;
+ object_class->get_property = cal_model_get_property;
+ object_class->dispose = cal_model_dispose;
+ object_class->finalize = cal_model_finalize;
+ object_class->constructed = cal_model_constructed;
+
+ etm_class = E_TABLE_MODEL_CLASS (class);
etm_class->column_count = ecm_column_count;
etm_class->row_count = ecm_row_count;
etm_class->value_at = ecm_value_at;
@@ -154,12 +351,54 @@ e_cal_model_class_init (ECalModelClass *klass)
etm_class->value_is_empty = ecm_value_is_empty;
etm_class->value_to_string = ecm_value_to_string;
- klass->get_color_for_component = ecm_get_color_for_component;
- klass->fill_component_from_model = NULL;
+ class->get_color_for_component = ecm_get_color_for_component;
+ class->fill_component_from_model = NULL;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_SETTINGS,
+ g_param_spec_object (
+ "shell-settings",
+ _("Shell Settings"),
+ _("Application-wide settings"),
+ E_TYPE_SHELL_SETTINGS,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TIMEZONE,
+ g_param_spec_pointer (
+ "timezone",
+ "Time Zone",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USE_24_HOUR_FORMAT,
+ g_param_spec_boolean (
+ "use-24-hour-format",
+ "Use 24-Hour Format",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WEEK_START_DAY,
+ g_param_spec_int (
+ "week-start-day",
+ "Week Start Day",
+ NULL,
+ 0, /* Monday */
+ 6, /* Sunday */
+ 0,
+ G_PARAM_READWRITE));
signals[TIME_RANGE_CHANGED] =
g_signal_new ("time_range_changed",
- G_TYPE_FROM_CLASS (klass),
+ G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ECalModelClass, time_range_changed),
NULL, NULL,
@@ -168,7 +407,7 @@ e_cal_model_class_init (ECalModelClass *klass)
signals[ROW_APPENDED] =
g_signal_new ("row_appended",
- G_TYPE_FROM_CLASS (klass),
+ G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ECalModelClass, row_appended),
NULL, NULL,
@@ -177,7 +416,7 @@ e_cal_model_class_init (ECalModelClass *klass)
signals[COMPS_DELETED] =
g_signal_new ("comps_deleted",
- G_TYPE_FROM_CLASS (klass),
+ G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ECalModelClass, comps_deleted),
NULL, NULL,
@@ -186,7 +425,7 @@ e_cal_model_class_init (ECalModelClass *klass)
signals[CAL_VIEW_PROGRESS] =
g_signal_new ("cal_view_progress",
- G_TYPE_FROM_CLASS (klass),
+ G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ECalModelClass, cal_view_progress),
NULL, NULL,
@@ -194,7 +433,7 @@ e_cal_model_class_init (ECalModelClass *klass)
G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
signals[CAL_VIEW_DONE] =
g_signal_new ("cal_view_done",
- G_TYPE_FROM_CLASS (klass),
+ G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ECalModelClass, cal_view_done),
NULL, NULL,
@@ -206,112 +445,29 @@ e_cal_model_class_init (ECalModelClass *klass)
static void
e_cal_model_init (ECalModel *model)
{
- ECalModelPrivate *priv;
-
- priv = g_new0 (ECalModelPrivate, 1);
- model->priv = priv;
+ model->priv = E_CAL_MODEL_GET_PRIVATE (model);
/* match none by default */
- priv->start = -1;
- priv->end = -1;
- priv->search_sexp = NULL;
- priv->full_sexp = g_strdup ("#f");
-
- priv->objects = g_ptr_array_new ();
- priv->kind = ICAL_NO_COMPONENT;
- priv->flags = 0;
-
- priv->accounts = itip_addresses_get ();
-
- priv->use_24_hour_format = TRUE;
-
- priv->in_added = FALSE;
- priv->in_modified = FALSE;
- priv->in_removed = FALSE;
- priv->notify_added = NULL;
- priv->notify_modified = NULL;
- priv->notify_removed = NULL;
- priv->notify_lock = g_mutex_new ();
-}
-
-static void
-clear_objects_array (ECalModelPrivate *priv)
-{
- gint i;
-
- for (i = 0; i < priv->objects->len; i++) {
- ECalModelComponent *comp_data;
-
- comp_data = g_ptr_array_index (priv->objects, i);
- if (comp_data == NULL) {
- g_warning ("comp_data is null\n");
- continue;
- }
- e_cal_model_free_component_data (comp_data);
- }
-
- g_ptr_array_set_size (priv->objects, 0);
-}
-
-static void
-e_cal_model_dispose (GObject *object)
-{
- ECalModelPrivate *priv;
- ECalModel *model = (ECalModel *) object;
-
- g_return_if_fail (E_IS_CAL_MODEL (model));
-
- priv = model->priv;
-
- if (priv->clients) {
- while (priv->clients != NULL) {
- ECalModelClient *client_data = (ECalModelClient *) priv->clients->data;
-
- g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, model);
- if (client_data->query)
- g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, model);
-
- priv->clients = g_list_remove (priv->clients, client_data);
-
- g_object_unref (client_data->client);
- if (client_data->query)
- g_object_unref (client_data->query);
- g_free (client_data);
- }
+ model->priv->start = -1;
+ model->priv->end = -1;
+ model->priv->search_sexp = NULL;
+ model->priv->full_sexp = g_strdup ("#f");
- priv->clients = NULL;
- priv->default_client = NULL;
- }
+ model->priv->objects = g_ptr_array_new ();
+ model->priv->kind = ICAL_NO_COMPONENT;
+ model->priv->flags = 0;
- if (G_OBJECT_CLASS (e_cal_model_parent_class)->dispose)
- G_OBJECT_CLASS (e_cal_model_parent_class)->dispose (object);
-}
+ model->priv->accounts = itip_addresses_get ();
-static void
-e_cal_model_finalize (GObject *object)
-{
- ECalModelPrivate *priv;
- ECalModel *model = (ECalModel *) object;
-
- g_return_if_fail (E_IS_CAL_MODEL (model));
+ model->priv->use_24_hour_format = TRUE;
- priv = model->priv;
-
- g_free (priv->search_sexp);
- g_free (priv->full_sexp);
-
- g_free (priv->default_category);
-
- clear_objects_array (priv);
- g_ptr_array_free (priv->objects, FALSE);
- g_mutex_free (priv->notify_lock);
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_cal_model_parent_class)->finalize)
- G_OBJECT_CLASS (e_cal_model_parent_class)->finalize (object);
+ model->priv->in_added = FALSE;
+ model->priv->in_modified = FALSE;
+ model->priv->in_removed = FALSE;
+ model->priv->notify_added = NULL;
+ model->priv->notify_modified = NULL;
+ model->priv->notify_removed = NULL;
+ model->priv->notify_lock = g_mutex_new ();
}
/* ETableModel methods */
@@ -1148,9 +1304,14 @@ ecm_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data)
return assigned_colors[first_empty].color;
}
-/**
- * e_cal_model_get_component_kind
- */
+EShellSettings *
+e_cal_model_get_shell_settings (ECalModel *model)
+{
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
+
+ return model->priv->shell_settings;
+}
+
icalcomponent_kind
e_cal_model_get_component_kind (ECalModel *model)
{
@@ -1162,9 +1323,6 @@ e_cal_model_get_component_kind (ECalModel *model)
return priv->kind;
}
-/**
- * e_cal_model_set_component_kind
- */
void
e_cal_model_set_component_kind (ECalModel *model, icalcomponent_kind kind)
{
@@ -1176,82 +1334,59 @@ e_cal_model_set_component_kind (ECalModel *model, icalcomponent_kind kind)
priv->kind = kind;
}
-/**
- * e_cal_model_get_flags
- */
ECalModelFlags
e_cal_model_get_flags (ECalModel *model)
{
- ECalModelPrivate *priv;
-
- g_return_val_if_fail (E_IS_CAL_MODEL (model), E_CAL_MODEL_FLAGS_INVALID);
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), 0);
- priv = model->priv;
- return priv->flags;
+ return model->priv->flags;
}
-/**
- * e_cal_model_set_flags
- */
void
e_cal_model_set_flags (ECalModel *model, ECalModelFlags flags)
{
- ECalModelPrivate *priv;
-
g_return_if_fail (E_IS_CAL_MODEL (model));
- priv = model->priv;
- priv->flags = flags;
+ model->priv->flags = flags;
}
-/**
- * e_cal_model_get_timezone
- */
icaltimezone *
e_cal_model_get_timezone (ECalModel *model)
{
g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
+
return model->priv->zone;
}
-/**
- * e_cal_model_set_timezone
- */
void
-e_cal_model_set_timezone (ECalModel *model, icaltimezone *zone)
+e_cal_model_set_timezone (ECalModel *model,
+ icaltimezone *zone)
{
- ECalModelPrivate *priv;
-
g_return_if_fail (E_IS_CAL_MODEL (model));
- priv = model->priv;
- if (priv->zone != zone) {
- e_table_model_pre_change (E_TABLE_MODEL (model));
- priv->zone = zone;
+ if (model->priv->zone == zone)
+ return;
- /* the timezone affects the times shown for date fields,
- so we need to redisplay everything */
- e_table_model_changed (E_TABLE_MODEL (model));
- }
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+ model->priv->zone = zone;
+
+ /* the timezone affects the times shown for date fields,
+ so we need to redisplay everything */
+ e_table_model_changed (E_TABLE_MODEL (model));
+
+ g_object_notify (G_OBJECT (model), "timezone");
}
-/**
- * e_cal_model_set_default_category
- */
void
-e_cal_model_set_default_category (ECalModel *model, const gchar *default_cat)
+e_cal_model_set_default_category (ECalModel *model,
+ const gchar *default_category)
{
g_return_if_fail (E_IS_CAL_MODEL (model));
- if (model->priv->default_category)
- g_free (model->priv->default_category);
-
- model->priv->default_category = g_strdup (default_cat);
+ g_free (model->priv->default_category);
+ model->priv->default_category = g_strdup (default_category);
}
-/**
- * e_cal_model_get_use_24_hour_format
- */
gboolean
e_cal_model_get_use_24_hour_format (ECalModel *model)
{
@@ -1260,25 +1395,48 @@ e_cal_model_get_use_24_hour_format (ECalModel *model)
return model->priv->use_24_hour_format;
}
-/**
- * e_cal_model_set_use_24_hour_format
- */
void
-e_cal_model_set_use_24_hour_format (ECalModel *model, gboolean use24)
+e_cal_model_set_use_24_hour_format (ECalModel *model,
+ gboolean use_24_hour_format)
{
g_return_if_fail (E_IS_CAL_MODEL (model));
- if (model->priv->use_24_hour_format != use24) {
- e_table_model_pre_change (E_TABLE_MODEL (model));
- model->priv->use_24_hour_format = use24;
- /* Get the views to redraw themselves. */
- e_table_model_changed (E_TABLE_MODEL (model));
- }
+ if (model->priv->use_24_hour_format == use_24_hour_format)
+ return;
+
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+ model->priv->use_24_hour_format = use_24_hour_format;
+
+ /* Get the views to redraw themselves. */
+ e_table_model_changed (E_TABLE_MODEL (model));
+
+ g_object_notify (G_OBJECT (model), "use-24-hour-format");
+}
+
+gint
+e_cal_model_get_week_start_day (ECalModel *model)
+{
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), 0);
+
+ return model->priv->week_start_day;
+}
+
+void
+e_cal_model_set_week_start_day (ECalModel *model,
+ gint week_start_day)
+{
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+ g_return_if_fail (week_start_day >= 0);
+ g_return_if_fail (week_start_day < 7);
+
+ if (model->priv->week_start_day == week_start_day)
+ return;
+
+ model->priv->week_start_day = week_start_day;
+
+ g_object_notify (G_OBJECT (model), "week-start-day");
}
-/**
- * e_cal_model_get_default_client
- */
ECal *
e_cal_model_get_default_client (ECalModel *model)
{
@@ -1334,9 +1492,6 @@ e_cal_model_set_default_client (ECalModel *model, ECal *client)
priv->default_client = client_data->client;
}
-/**
- * e_cal_model_get_client_list
- */
GList *
e_cal_model_get_client_list (ECalModel *model)
{
@@ -1354,7 +1509,7 @@ e_cal_model_get_client_list (ECalModel *model)
}
/**
- * e_cal_model_get_client_for_uri
+ * e_cal_model_get_client_for_uri:
* @model: A calendar model.
* @uri: Uri for the client to get.
*/
@@ -1486,14 +1641,16 @@ add_instance_cb (ECalComponent *comp, time_t instance_start, time_t instance_end
return TRUE;
}
-/* We do this check since the calendar items are downloaded from the server in the open_method,
- since the default timezone might not be set there */
+/* We do this check since the calendar items are downloaded from the server
+ * in the open_method, since the default timezone might not be set there. */
static void
-ensure_dates_are_in_default_zone (icalcomponent *icalcomp)
+ensure_dates_are_in_default_zone (ECalModel *model,
+ icalcomponent *icalcomp)
{
icaltimetype dt;
- icaltimezone *zone = calendar_config_get_icaltimezone ();
+ icaltimezone *zone;
+ zone = e_cal_model_get_timezone (model);
if (!zone)
return;
@@ -1557,7 +1714,7 @@ process_added (ECalView *query, GList *objects, ECalModel *model)
e_cal_component_free_id (id);
g_object_unref (comp);
- ensure_dates_are_in_default_zone (l->data);
+ ensure_dates_are_in_default_zone (model, l->data);
if (e_cal_util_component_has_recurrences (l->data) && (priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES)) {
RecurrenceExpansionData rdata;
@@ -2440,17 +2597,17 @@ struct _ECalModelComponentPrivate {
static void e_cal_model_component_finalize (GObject *object);
-static GObjectClass *parent_class;
+static GObjectClass *component_parent_class;
/* Class initialization function for the calendar component object */
static void
-e_cal_model_component_class_init (ECalModelComponentClass *klass)
+e_cal_model_component_class_init (ECalModelComponentClass *class)
{
GObjectClass *object_class;
- object_class = (GObjectClass *) klass;
+ object_class = (GObjectClass *) class;
- parent_class = g_type_class_peek_parent (klass);
+ component_parent_class = g_type_class_peek_parent (class);
object_class->finalize = e_cal_model_component_finalize;
}
@@ -2497,8 +2654,8 @@ e_cal_model_component_finalize (GObject *object)
comp_data->color = NULL;
}
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ if (G_OBJECT_CLASS (component_parent_class)->finalize)
+ (* G_OBJECT_CLASS (component_parent_class)->finalize) (object);
}
/* Object initialization function for the calendar component object */
diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h
index adaf736494..c5fffd3cd6 100644
--- a/calendar/gui/e-cal-model.h
+++ b/calendar/gui/e-cal-model.h
@@ -29,16 +29,47 @@
#include <table/e-table-model.h>
#include <libecal/e-cal.h>
#include "e-cell-date-edit-text.h"
+#include <shell/e-shell-settings.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_CAL_MODEL \
+ (e_cal_model_get_type ())
+#define E_CAL_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_MODEL, ECalModel))
+#define E_CAL_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_MODEL, ECalModelClass))
+#define E_IS_CAL_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_MODEL))
+#define E_IS_CAL_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_MODEL))
+#define E_CAL_MODEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_MODEL, ECalModelClass))
-#define E_TYPE_CAL_MODEL (e_cal_model_get_type ())
-#define E_CAL_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL, ECalModel))
-#define E_CAL_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL, ECalModelClass))
-#define E_IS_CAL_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL))
-#define E_IS_CAL_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL))
+/* Standard GObject macros */
+#define E_TYPE_CAL_MODEL_COMPONENT \
+ (e_cal_model_component_get_type ())
+#define E_CAL_MODEL_COMPONENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponent))
+#define E_CAL_MODEL_COMPONENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponentClass))
+#define E_IS_CAL_MODEL_COMPONENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_MODEL_COMPONENT))
+#define E_IS_CAL_MODEL_COMPONENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_MODEL_COMPONENT))
+#define E_CAL_MODEL_COMPONENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponentClass))
-typedef struct _ECalModelPrivate ECalModelPrivate;
+G_BEGIN_DECLS
typedef enum {
/* If you add new items here or reorder them, you have to update the
@@ -63,12 +94,9 @@ typedef enum {
E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES = 0x01
} ECalModelFlags;
-#define E_TYPE_CAL_MODEL_COMPONENT (e_cal_model_component_get_type ())
-#define E_CAL_MODEL_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponent))
-#define E_CAL_MODEL_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL_COMPONENT, \
- ECalComponentClass))
-#define E_IS_CAL_MODEL_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL_COMPONENT))
-#define E_IS_CAL_MODEL_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL_COMPONENT))
+typedef struct _ECalModel ECalModel;
+typedef struct _ECalModelClass ECalModelClass;
+typedef struct _ECalModelPrivate ECalModelPrivate;
typedef struct _ECalModelComponent ECalModelComponent;
typedef struct _ECalModelComponentClass ECalModelComponentClass;
@@ -104,94 +132,129 @@ typedef struct {
gpointer cb_data;
} ECalModelGenerateInstancesData;
-typedef struct _ECalModel {
+struct _ECalModel {
ETableModel model;
ECalModelPrivate *priv;
-} ECalModel;
+};
-typedef struct {
+struct _ECalModelClass {
ETableModelClass parent_class;
/* virtual methods */
- const gchar * (* get_color_for_component) (ECalModel *model, ECalModelComponent *comp_data);
- void (* fill_component_from_model) (ECalModel *model, ECalModelComponent *comp_data,
- ETableModel *source_model, gint row);
+ const gchar * (*get_color_for_component)
+ (ECalModel *model,
+ ECalModelComponent *comp_data);
+ void (*fill_component_from_model)
+ (ECalModel *model,
+ ECalModelComponent *comp_data,
+ ETableModel *source_model,
+ gint row);
/* Signals */
- void (* time_range_changed) (ECalModel *model, time_t start, time_t end);
- void (* row_appended) (ECalModel *model);
- void (* comps_deleted) (ECalModel *model, gpointer list);
- void (* cal_view_progress) (ECalModel *model, const gchar *message, gint progress, ECalSourceType type);
- void (* cal_view_done) (ECalModel *model, ECalendarStatus status, ECalSourceType type);
-} ECalModelClass;
-
-typedef time_t (*ECalModelDefaultTimeFunc)(ECalModel *model, gpointer user_data);
-
-GType e_cal_model_get_type (void);
-GType e_cal_model_component_get_type (void);
-icalcomponent_kind e_cal_model_get_component_kind (ECalModel *model);
-void e_cal_model_set_component_kind (ECalModel *model,
- icalcomponent_kind kind);
-ECalModelFlags e_cal_model_get_flags (ECalModel *model);
-void e_cal_model_set_flags (ECalModel *model,
- ECalModelFlags flags);
-icaltimezone *e_cal_model_get_timezone (ECalModel *model);
-void e_cal_model_set_timezone (ECalModel *model,
- icaltimezone *zone);
-void e_cal_model_set_default_category (ECalModel *model,
- const gchar *default_cat);
-gboolean e_cal_model_get_use_24_hour_format (ECalModel *model);
-void e_cal_model_set_use_24_hour_format (ECalModel *model,
- gboolean use24);
-ECal *e_cal_model_get_default_client (ECalModel *model);
-void e_cal_model_set_default_client (ECalModel *model,
- ECal *client);
-GList *e_cal_model_get_client_list (ECalModel *model);
-ECal *e_cal_model_get_client_for_uri (ECalModel *model,
- const gchar *uri);
-void e_cal_model_add_client (ECalModel *model,
- ECal *client);
-void e_cal_model_remove_client (ECalModel *model,
- ECal *client);
-void e_cal_model_remove_all_clients (ECalModel *model);
-void e_cal_model_get_time_range (ECalModel *model,
- time_t *start,
- time_t *end);
-void e_cal_model_set_time_range (ECalModel *model,
- time_t start,
- time_t end);
-const gchar *e_cal_model_get_search_query (ECalModel *model);
-void e_cal_model_set_search_query (ECalModel *model,
- const gchar *sexp);
-icalcomponent *e_cal_model_create_component_with_defaults (ECalModel *model, gboolean all_day);
-const gchar *e_cal_model_get_color_for_component (ECalModel *model,
- ECalModelComponent *comp_data);
-gboolean e_cal_model_get_rgb_color_for_component (ECalModel *model,
- ECalModelComponent *comp_data,
- double *red,
- double *green,
- double *blue);
-ECalModelComponent *e_cal_model_get_component_at (ECalModel *model,
- gint row);
-ECalModelComponent *e_cal_model_get_component_for_uid (ECalModel *model,
- const ECalComponentId *id);
-gchar *e_cal_model_date_value_to_string (ECalModel *model,
- const void *value);
-ECalModelComponent *e_cal_model_copy_component_data (ECalModelComponent *comp_data);
-void e_cal_model_free_component_data (ECalModelComponent *comp_data);
-void e_cal_model_generate_instances (ECalModel *model,
- time_t start,
- time_t end,
- ECalRecurInstanceFn cb,
- gpointer cb_data);
-GPtrArray * e_cal_model_get_object_array (ECalModel *model);
-void e_cal_model_set_instance_times (ECalModelComponent *comp_data, const icaltimezone *zone);
-void e_cal_model_set_search_query_with_time_range (ECalModel *model, const gchar *sexp, time_t start, time_t end);
-
-gboolean e_cal_model_test_row_editable (ECalModel *model, gint row);
-
-void e_cal_model_set_default_time_func (ECalModel *model, ECalModelDefaultTimeFunc func, gpointer user_data);
+ void (*time_range_changed) (ECalModel *model,
+ time_t start,
+ time_t end);
+ void (*row_appended) (ECalModel *model);
+ void (*comps_deleted) (ECalModel *model,
+ gpointer list);
+ void (*cal_view_progress) (ECalModel *model,
+ const gchar *message,
+ gint progress,
+ ECalSourceType type);
+ void (*cal_view_done) (ECalModel *model,
+ ECalendarStatus status,
+ ECalSourceType type);
+};
+
+typedef time_t (*ECalModelDefaultTimeFunc) (ECalModel *model, gpointer user_data);
+
+GType e_cal_model_get_type (void);
+GType e_cal_model_component_get_type (void);
+EShellSettings *e_cal_model_get_shell_settings (ECalModel *model);
+icalcomponent_kind
+ e_cal_model_get_component_kind (ECalModel *model);
+void e_cal_model_set_component_kind (ECalModel *model,
+ icalcomponent_kind kind);
+ECalModelFlags e_cal_model_get_flags (ECalModel *model);
+void e_cal_model_set_flags (ECalModel *model,
+ ECalModelFlags flags);
+icaltimezone * e_cal_model_get_timezone (ECalModel *model);
+void e_cal_model_set_timezone (ECalModel *model,
+ icaltimezone *zone);
+void e_cal_model_set_default_category(ECalModel *model,
+ const gchar *default_cat);
+gboolean e_cal_model_get_use_24_hour_format
+ (ECalModel *model);
+void e_cal_model_set_use_24_hour_format
+ (ECalModel *model,
+ gboolean use24);
+gint e_cal_model_get_week_start_day (ECalModel *model);
+void e_cal_model_set_week_start_day (ECalModel *model,
+ gint week_start_day);
+ECal * e_cal_model_get_default_client (ECalModel *model);
+void e_cal_model_set_default_client (ECalModel *model,
+ ECal *client);
+GList * e_cal_model_get_client_list (ECalModel *model);
+ECal * e_cal_model_get_client_for_uri (ECalModel *model,
+ const gchar *uri);
+void e_cal_model_add_client (ECalModel *model,
+ ECal *client);
+void e_cal_model_remove_client (ECalModel *model,
+ ECal *client);
+void e_cal_model_remove_all_clients (ECalModel *model);
+void e_cal_model_get_time_range (ECalModel *model,
+ time_t *start,
+ time_t *end);
+void e_cal_model_set_time_range (ECalModel *model,
+ time_t start,
+ time_t end);
+const gchar * e_cal_model_get_search_query (ECalModel *model);
+void e_cal_model_set_search_query (ECalModel *model,
+ const gchar *sexp);
+icalcomponent * e_cal_model_create_component_with_defaults
+ (ECalModel *model,
+ gboolean all_day);
+const gchar * e_cal_model_get_color_for_component
+ (ECalModel *model,
+ ECalModelComponent *comp_data);
+gboolean e_cal_model_get_rgb_color_for_component
+ (ECalModel *model,
+ ECalModelComponent *comp_data,
+ gdouble *red,
+ gdouble *green,
+ gdouble *blue);
+ECalModelComponent *
+ e_cal_model_get_component_at (ECalModel *model,
+ gint row);
+ECalModelComponent *
+ e_cal_model_get_component_for_uid
+ (ECalModel *model,
+ const ECalComponentId *id);
+gchar * e_cal_model_date_value_to_string(ECalModel *model,
+ gconstpointer value);
+ECalModelComponent *
+ e_cal_model_copy_component_data (ECalModelComponent *comp_data);
+void e_cal_model_free_component_data (ECalModelComponent *comp_data);
+void e_cal_model_generate_instances (ECalModel *model,
+ time_t start,
+ time_t end,
+ ECalRecurInstanceFn cb,
+ gpointer cb_data);
+GPtrArray * e_cal_model_get_object_array (ECalModel *model);
+void e_cal_model_set_instance_times (ECalModelComponent *comp_data,
+ const icaltimezone *zone);
+void e_cal_model_set_search_query_with_time_range
+ (ECalModel *model,
+ const gchar *sexp,
+ time_t start,
+ time_t end);
+gboolean e_cal_model_test_row_editable (ECalModel *model,
+ gint row);
+void e_cal_model_set_default_time_func
+ (ECalModel *model,
+ ECalModelDefaultTimeFunc func,
+ gpointer user_data);
G_END_DECLS
-#endif
+#endif /* E_CAL_MODEL_H */
diff --git a/calendar/gui/e-cal-popup.c b/calendar/gui/e-cal-popup.c
deleted file mode 100644
index cdbce07ac7..0000000000
--- a/calendar/gui/e-cal-popup.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#include "e-cal-popup.h"
-#include <libedataserver/e-data-server-util.h>
-#include <libedataserverui/e-source-selector.h>
-
-#include <camel/camel-mime-part.h>
-#include <camel/camel-stream-vfs.h>
-#include "e-util/e-util.h"
-#include <glib/gi18n.h>
-#include "e-util/e-mktemp.h"
-#include "e-util/e-dialog-utils.h"
-
-#include "gui/e-calendar-view.h"
-#include "gui/e-cal-model.h"
-#include "itip-utils.h"
-#include "e-attachment.h"
-
-static GObjectClass *ecalp_parent;
-
-static void
-ecalp_init(GObject *o)
-{
- /*ECalPopup *eabp = (ECalPopup *)o; */
-}
-
-static void
-ecalp_finalise(GObject *o)
-{
- ((GObjectClass *)ecalp_parent)->finalize(o);
-}
-
-static void
-ecalp_target_free(EPopup *ep, EPopupTarget *t)
-{
- switch (t->type) {
- case E_CAL_POPUP_TARGET_SELECT: {
- ECalPopupTargetSelect *s = (ECalPopupTargetSelect *)t;
- gint i;
-
- for (i=0;i<s->events->len;i++)
- e_cal_model_free_component_data(s->events->pdata[i]);
- g_ptr_array_free(s->events, TRUE);
- g_object_unref(s->model);
- break; }
- case E_CAL_POPUP_TARGET_SOURCE: {
- ECalPopupTargetSource *s = (ECalPopupTargetSource *)t;
-
- g_object_unref(s->selector);
- break; }
- }
-
- ((EPopupClass *)ecalp_parent)->target_free(ep, t);
-}
-
-/* Standard menu code */
-
-static void
-ecalp_class_init(GObjectClass *klass)
-{
- klass->finalize = ecalp_finalise;
- ((EPopupClass *)klass)->target_free = ecalp_target_free;
-}
-
-GType
-e_cal_popup_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(ECalPopupClass),
- NULL, NULL,
- (GClassInitFunc)ecalp_class_init,
- NULL, NULL,
- sizeof(ECalPopup), 0,
- (GInstanceInitFunc)ecalp_init
- };
- ecalp_parent = g_type_class_ref(e_popup_get_type());
- type = g_type_register_static(e_popup_get_type(), "ECalPopup", &info, 0);
- }
-
- return type;
-}
-
-ECalPopup *e_cal_popup_new(const gchar *menuid)
-{
- ECalPopup *eabp = g_object_new(e_cal_popup_get_type(), NULL);
-
- e_popup_construct(&eabp->popup, menuid);
-
- return eabp;
-}
-
-static icalproperty *
-get_attendee_prop (icalcomponent *icalcomp, const gchar *address)
-{
-
- icalproperty *prop;
-
- if (!(address && *address))
- return NULL;
-
- for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
- prop;
- prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) {
- const gchar *attendee = icalproperty_get_attendee (prop);
-
- if (g_str_equal (itip_strip_mailto (attendee), address)) {
- return prop;
- }
- }
- return NULL;
-}
-
-static gboolean
-is_delegated (icalcomponent *icalcomp, gchar *user_email)
-{
- icalproperty *prop;
- icalparameter *param;
- const gchar *delto = NULL;
-
- prop = get_attendee_prop (icalcomp, user_email);
-
- if (prop) {
- param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDTO_PARAMETER);
- if (param)
- delto = icalparameter_get_delegatedto (param);
- } else
- return FALSE;
-
- prop = get_attendee_prop (icalcomp, itip_strip_mailto (delto));
-
- if (prop) {
- const gchar *delfrom = NULL;
- icalparameter_partstat status = ICAL_PARTSTAT_NONE;
-
- param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDFROM_PARAMETER);
- if (param)
- delfrom = icalparameter_get_delegatedfrom (param);
- param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
- if (param)
- status = icalparameter_get_partstat (param);
- if ((delfrom && *delfrom) && g_str_equal (itip_strip_mailto (delfrom), user_email)
- && status != ICAL_PARTSTAT_DECLINED)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-needs_to_accept (icalcomponent *icalcomp, gchar *user_email)
-{
- icalproperty *prop;
- icalparameter *param;
- icalparameter_partstat status = ICAL_PARTSTAT_NONE;
-
- prop = get_attendee_prop (icalcomp, user_email);
-
- /* It might be a mailing list */
- if (!prop)
- return TRUE;
- param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
- if (param)
- status = icalparameter_get_partstat (param);
-
- if (status == ICAL_PARTSTAT_ACCEPTED || status == ICAL_PARTSTAT_TENTATIVE)
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * e_cal_popup_target_new_select:
- * @eabp:
- * @model: The calendar model.
- * @events: An array of pointers to ECalModelComponent items. These
- * items must be copied. They, and the @events array will be freed by
- * the popup menu automatically.
- *
- * Create a new selection popup target.
- *
- * Return value:
- **/
-ECalPopupTargetSelect *
-e_cal_popup_target_new_select(ECalPopup *eabp, struct _ECalModel *model, GPtrArray *events)
-{
- ECalPopupTargetSelect *t = e_popup_target_new(&eabp->popup, E_CAL_POPUP_TARGET_SELECT, sizeof(*t));
- guint32 mask = ~0;
- ECal *client;
- gboolean read_only, user_org = FALSE;
-
- /* FIXME: This is duplicated in e-cal-menu */
-
- t->model = model;
- g_object_ref(t->model);
- t->events = events;
-
- if (t->events->len == 0) {
- client = e_cal_model_get_default_client(t->model);
- } else {
- ECalModelComponent *comp_data = (ECalModelComponent *)t->events->pdata[0];
- ECalComponent *comp;
- gchar *user_email = NULL;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- user_email = itip_get_comp_attendee (comp, comp_data->client);
-
- mask &= ~E_CAL_POPUP_SELECT_ANY;
- if (t->events->len == 1)
- mask &= ~E_CAL_POPUP_SELECT_ONE;
- else {
- gint i=0;
-
- mask &= ~E_CAL_POPUP_SELECT_MANY;
- /* Now check for any incomplete tasks and set the flags*/
- for (; i < t->events->len; i++) {
- ECalModelComponent *comp_data = (ECalModelComponent *)t->events->pdata[i];
- if (!icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY))
- mask &= ~E_CAL_POPUP_SELECT_NOTCOMPLETE;
- else
- mask &= ~E_CAL_POPUP_SELECT_COMPLETE;
- }
- }
-
- if (icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY))
- mask &= ~E_CAL_POPUP_SELECT_HASURL;
-
- if (e_cal_util_component_has_recurrences (comp_data->icalcomp))
- mask &= ~E_CAL_POPUP_SELECT_RECURRING;
- else if (e_cal_util_component_is_instance (comp_data->icalcomp))
- mask &= ~E_CAL_POPUP_SELECT_RECURRING;
- else
- mask &= ~E_CAL_POPUP_SELECT_NONRECURRING;
-
- if (e_cal_util_component_is_instance (comp_data->icalcomp))
- mask &= ~E_CAL_POPUP_SELECT_INSTANCE;
-
- if (e_cal_util_component_has_attendee (comp_data->icalcomp))
- mask &= ~E_CAL_POPUP_SELECT_MEETING;
-
- if (!e_cal_get_save_schedules (comp_data->client))
- mask &= ~E_CAL_POPUP_SELECT_NOSAVESCHEDULES;
-
- if (e_cal_util_component_has_organizer (comp_data->icalcomp)) {
-
- if (itip_organizer_is_user (comp, comp_data->client)) {
- mask &= ~E_CAL_POPUP_SELECT_ORGANIZER;
- user_org = TRUE;
- }
-
- } else {
- /* organiser is synonym for owner in this case */
- mask &= ~(E_CAL_POPUP_SELECT_ORGANIZER|E_CAL_POPUP_SELECT_NOTMEETING);
- }
-
- client = comp_data->client;
-
- if (e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_DELEGATE_SUPPORTED)) {
-
- if (e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_DELEGATE_TO_MANY))
- mask &= ~E_CAL_POPUP_SELECT_DELEGATABLE;
- else if (!user_org && !is_delegated (comp_data->icalcomp, user_email))
- mask &= ~E_CAL_POPUP_SELECT_DELEGATABLE;
- }
-
- if (e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_HAS_UNACCEPTED_MEETING) &&
- needs_to_accept (comp_data->icalcomp, user_email))
- mask &= ~E_CAL_POPUP_SELECT_ACCEPTABLE;
-
- if (!icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY))
- mask &= ~E_CAL_POPUP_SELECT_NOTCOMPLETE;
-
- if (icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY))
- mask &= ~E_CAL_POPUP_SELECT_COMPLETE;
-
- g_object_unref (comp);
- g_free (user_email);
- }
-
- e_cal_is_read_only(client, &read_only, NULL);
- if (!read_only)
- mask &= ~E_CAL_POPUP_SELECT_EDITABLE;
-
- if (!e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT)
- && !e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK))
- mask &= ~E_CAL_POPUP_SELECT_ASSIGNABLE;
-
- /* This bit isn't implemented ... */
- mask &= ~E_CAL_POPUP_SELECT_NOTEDITING;
-
- t->target.mask = mask;
-
- return t;
-}
-
-ECalPopupTargetSource *
-e_cal_popup_target_new_source(ECalPopup *eabp, ESourceSelector *selector)
-{
- ECalPopupTargetSource *t = e_popup_target_new(&eabp->popup, E_CAL_POPUP_TARGET_SOURCE, sizeof(*t));
- guint32 mask = ~0;
- const gchar *relative_uri;
- gchar *uri;
- ESource *source;
- const gchar *offline = NULL;
- const gchar *delete = NULL;
-
- /* TODO: this is duplicated for addressbook too */
-
- t->selector = selector;
- g_object_ref(selector);
-
- /* TODO: perhaps we need to copy this so it doesn't change during the lifecycle */
- source = e_source_selector_peek_primary_selection(selector);
- if (source)
- mask &= ~E_CAL_POPUP_SOURCE_PRIMARY;
-
- /* FIXME Gross hack, should have a property or something */
- relative_uri = e_source_peek_relative_uri(source);
- if (relative_uri && !strcmp("system", relative_uri))
- mask &= ~E_CAL_POPUP_SOURCE_SYSTEM;
- else
- mask &= ~E_CAL_POPUP_SOURCE_USER;
-
- uri = e_source_get_uri (source);
- if (!uri || (g_ascii_strncasecmp (uri, "file://", 7) && g_ascii_strncasecmp (uri, "contacts://", 11))) {
- /* check for e_target_selector's offline_status property here */
- offline = e_source_get_property (source, "offline_sync");
- if (offline && strcmp (offline, "1") == 0)
- mask &= ~E_CAL_POPUP_SOURCE_NO_OFFLINE; /* set the menu item to Mark Offline */
- else
- mask &= ~E_CAL_POPUP_SOURCE_OFFLINE;
- } else {
- mask |= E_CAL_POPUP_SOURCE_NO_OFFLINE;
- mask |= E_CAL_POPUP_SOURCE_OFFLINE;
- }
- g_free (uri);
-
- /* check for delete_status property here */
- delete = e_source_get_property (source, "delete");
- if (delete && strcmp (delete, "no") == 0)
- mask &= ~E_CAL_POPUP_SOURCE_NO_DELETE; /* set the menu item to non deletable */
- else
- mask &= ~E_CAL_POPUP_SOURCE_DELETE;
-
- t->target.mask = mask;
-
- return t;
-}
-
-/* ********************************************************************** */
-/* Popup menu plugin handler */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.iteab:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="IMAP4 and IMAP4v1 mail store">
- <hook class="org.gnome.mail.popupMenu:1.0"
- handler="HandlePopup">
- <menu id="any" target="select">
- <iteab
- type="iteab|toggle|radio|image|submenu|bar"
- active
- path="foo/bar"
- label="label"
- icon="foo"
- mask="select_one"
- activate="ecalp_view_eabacs"/>
- </menu>
- </extension>
-
-*/
-
-static gpointer ecalph_parent_class;
-#define ecalph ((ECalPopupHook *)eph)
-
-static const EPopupHookTargetMask ecalph_select_masks[] = {
- { "one", E_CAL_POPUP_SELECT_ONE },
- { "many", E_CAL_POPUP_SELECT_MANY },
- { "editable", E_CAL_POPUP_SELECT_EDITABLE },
- { "recurring", E_CAL_POPUP_SELECT_RECURRING },
- { "non-recurring", E_CAL_POPUP_SELECT_NONRECURRING },
- { "instance", E_CAL_POPUP_SELECT_INSTANCE },
- { "organizer", E_CAL_POPUP_SELECT_ORGANIZER },
- { "not-editing", E_CAL_POPUP_SELECT_NOTEDITING },
- { "not-meeting", E_CAL_POPUP_SELECT_NOTMEETING },
- { "meeting", E_CAL_POPUP_SELECT_MEETING },
- { "assignable", E_CAL_POPUP_SELECT_ASSIGNABLE },
- { "hasurl", E_CAL_POPUP_SELECT_HASURL },
- { "delegate", E_CAL_POPUP_SELECT_DELEGATABLE },
- { "accept", E_CAL_POPUP_SELECT_ACCEPTABLE },
- { "not-complete", E_CAL_POPUP_SELECT_NOTCOMPLETE },
- { "no-save-schedules", E_CAL_POPUP_SELECT_NOSAVESCHEDULES },
- { "complete" , E_CAL_POPUP_SELECT_COMPLETE},
- { NULL }
-};
-
-static const EPopupHookTargetMask ecalph_source_masks[] = {
- { "primary", E_CAL_POPUP_SOURCE_PRIMARY },
- { "system", E_CAL_POPUP_SOURCE_SYSTEM },
- { "user", E_CAL_POPUP_SOURCE_USER },
- { "offline", E_CAL_POPUP_SOURCE_OFFLINE},
- { "no-offline", E_CAL_POPUP_SOURCE_NO_OFFLINE},
- { "delete", E_CAL_POPUP_SOURCE_DELETE},
- { "no-delete", E_CAL_POPUP_SOURCE_NO_DELETE},
-
- { NULL }
-};
-
-static const EPopupHookTargetMask ecalph_attachments_masks[] = {
- { "one", E_CAL_POPUP_ATTACHMENTS_ONE },
- { "many", E_CAL_POPUP_ATTACHMENTS_MANY },
- { "modify", E_CAL_POPUP_ATTACHMENTS_MODIFY },
- { "multiple", E_CAL_POPUP_ATTACHMENTS_MULTIPLE },
- { "image", E_CAL_POPUP_ATTACHMENTS_IMAGE },
- { NULL }
-};
-
-static const EPopupHookTargetMap ecalph_targets[] = {
- { "select", E_CAL_POPUP_TARGET_SELECT, ecalph_select_masks },
- { "source", E_CAL_POPUP_TARGET_SOURCE, ecalph_source_masks },
- { "attachments", E_CAL_POPUP_TARGET_ATTACHMENTS, ecalph_attachments_masks },
- { NULL }
-};
-
-static void
-ecalph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)ecalph_parent_class)->finalize(o);
-}
-
-static void
-ecalph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = ecalph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.calendar.popup:1.0";
-
- for (i=0;ecalph_targets[i].type;i++)
- e_popup_hook_class_add_target_map((EPopupHookClass *)klass, &ecalph_targets[i]);
-
- ((EPopupHookClass *)klass)->popup_class = g_type_class_ref(e_cal_popup_get_type());
-}
-
-GType
-e_cal_popup_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(ECalPopupHookClass), NULL, NULL, (GClassInitFunc) ecalph_class_init, NULL, NULL,
- sizeof(ECalPopupHook), 0, (GInstanceInitFunc) NULL,
- };
-
- ecalph_parent_class = g_type_class_ref(e_popup_hook_get_type());
- type = g_type_register_static(e_popup_hook_get_type(), "ECalPopupHook", &info, 0);
- }
-
- return type;
-}
diff --git a/calendar/gui/e-cal-popup.h b/calendar/gui/e-cal-popup.h
deleted file mode 100644
index 2cd20ebd9d..0000000000
--- a/calendar/gui/e-cal-popup.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __E_CAL_POPUP_H__
-#define __E_CAL_POPUP_H__
-
-#include <glib-object.h>
-#include <libedataserverui/e-source-selector.h>
-
-#include <e-util/e-popup.h>
-#include "dialogs/comp-editor.h"
-#include "e-cal-model.h"
-
-G_BEGIN_DECLS
-
-/**
- * enum _e_cal_popup_target_t - A list of mail popup target types.
- *
- * @E_CAL_POPUP_TARGET_SELECT: A selection of cards
- * @E_CAL_POPUP_TARGET_SOURCE: A source selection.
- *
- * Defines the value of the targetid for all ECalPopup target types.
- **/
-enum _e_cal_popup_target_t {
- E_CAL_POPUP_TARGET_SELECT,
- E_CAL_POPUP_TARGET_SOURCE,
- E_CAL_POPUP_TARGET_ATTACHMENTS
-};
-
-/**
- * enum _e_cal_popup_target_select_t - ECalPopupTargetSelect qualifiers.
- *
- * @E_CAL_POPUP_SELECT_ONE: Only one item is selected.
- * @E_CAL_POPUP_SELECT_MANY: More than one item selected.
- * @E_CAL_POPUP_SELECT_ANY: One ore more items are selected.
- * @E_CAL_POPUP_SELECT_EDITABLE: The selection is editable.
- * @E_CAL_POPUP_SELECT_RECURRING: Is a recurring event.
- * @E_CAL_POPUP_SELECT_NONRECURRING: Is not a recurring event.
- * @E_CAL_POPUP_SELECT_INSTANCE: This is an instance event.
- * @E_CAL_POPUP_SELECT_ORGANIZER: The user is the organiser of the event.
- * @E_CAL_POPUP_SELECT_NOTEDITING: The event is not being edited already. Not implemented.
- * @E_CAL_POPUP_SELECT_NOTMEETING: The event is not a meeting.
- * @E_CAL_POPUP_SELECT_ASSIGNABLE: An assignable task.
- * @E_CAL_POPUP_SELECT_HASURL: A task that contains a URL.
- **/
-enum _e_cal_popup_target_select_t {
- E_CAL_POPUP_SELECT_ONE = 1<<0,
- E_CAL_POPUP_SELECT_MANY = 1<<1,
- E_CAL_POPUP_SELECT_ANY = 1<<2,
- E_CAL_POPUP_SELECT_EDITABLE = 1<<3,
- E_CAL_POPUP_SELECT_RECURRING = 1<<4,
- E_CAL_POPUP_SELECT_NONRECURRING = 1<<5,
- E_CAL_POPUP_SELECT_INSTANCE = 1<<6,
-
- E_CAL_POPUP_SELECT_ORGANIZER = 1<<7,
- E_CAL_POPUP_SELECT_NOTEDITING = 1<<8,
- E_CAL_POPUP_SELECT_NOTMEETING = 1<<9,
-
- E_CAL_POPUP_SELECT_ASSIGNABLE = 1<<10,
- E_CAL_POPUP_SELECT_HASURL = 1<<11,
- E_CAL_POPUP_SELECT_MEETING = 1 <<12,
- E_CAL_POPUP_SELECT_DELEGATABLE = 1<<13,
- E_CAL_POPUP_SELECT_ACCEPTABLE = 1<<14,
- E_CAL_POPUP_SELECT_NOTCOMPLETE = 1<<15,
- E_CAL_POPUP_SELECT_NOSAVESCHEDULES = 1<<16,
- E_CAL_POPUP_SELECT_COMPLETE = 1<<17
-};
-
-/**
- * enum _e_cal_popup_target_source_t - ECalPopupTargetSource qualifiers.
- *
- * @E_CAL_POPUP_SOURCE_PRIMARY: Has a primary selection.
- * @E_CAL_POPUP_SOURCE_SYSTEM: Is a 'system' folder.
- *
- **/
-enum _e_cal_popup_target_source_t {
- E_CAL_POPUP_SOURCE_PRIMARY = 1<<0,
- E_CAL_POPUP_SOURCE_SYSTEM = 1<<1, /* system folder */
- E_CAL_POPUP_SOURCE_USER = 1<<2, /* user folder (!system) */
- E_CAL_POPUP_SOURCE_OFFLINE = 1 <<3,
- E_CAL_POPUP_SOURCE_NO_OFFLINE = 1 <<4,
- E_CAL_POPUP_SOURCE_DELETE = 1<<5,
- E_CAL_POPUP_SOURCE_NO_DELETE = 1<<6
-};
-
-/**
- * enum _e_cal_popup_target_attachments_t - ECalPopupTargetAttachments qualifiers.
- *
- * @E_CAL_POPUP_ATTACHMENTS_ONE: There is one and only one attachment selected.
- * @E_CAL_POPUP_ATTACHMENTS_MANY: There is one or more attachments selected.
- *
- **/
-enum _e_cal_popup_target_attachments_t {
- E_CAL_POPUP_ATTACHMENTS_ONE = 1<<0, /* only 1 selected */
- E_CAL_POPUP_ATTACHMENTS_MANY = 1<<1, /* one or more selected */
- E_CAL_POPUP_ATTACHMENTS_MODIFY = 1<<2, /* check for modify operation */
- E_CAL_POPUP_ATTACHMENTS_MULTIPLE = 1<<3,
- E_CAL_POPUP_ATTACHMENTS_IMAGE = 1<<4
-};
-
-typedef struct _ECalPopupTargetSelect ECalPopupTargetSelect;
-typedef struct _ECalPopupTargetSource ECalPopupTargetSource;
-typedef struct _ECalPopupTargetAttachments ECalPopupTargetAttachments;
-
-/**
- * struct _ECalPopupTargetSelect - A list of address cards.
- *
- * @target: Superclass. target.widget is an ECalendarView.
- * @model: The ECalModel.
- * @events: The selected events. These are ECalModelComponent's.
- *
- * Used to represent a selection of appointments as context for a popup
- * menu.
- *
- * TODO: For maximum re-usability references to the view could be removed
- * from this structure.
- **/
-struct _ECalPopupTargetSelect {
- EPopupTarget target;
-
- ECalModel *model;
- GPtrArray *events;
-};
-
-/**
- * struct _ECalPopupTargetSource - A source target.
- *
- * @target: Superclass.
- * @selector: Selector holding the source selection.
- *
- * This target is used to represent a source selection.
- **/
-struct _ECalPopupTargetSource {
- EPopupTarget target;
-
- ESourceSelector *selector;
-};
-
-/**
- * struct _ECalPopupTargetAttachments - A list of calendar attachments.
- *
- * @target: Superclass.
- * @attachments: A GSList list of CalAttachments.
- *
- * This target is used to represent a selected list of attachments in
- * the calendar attachment area.
- **/
-struct _ECalPopupTargetAttachments {
- EPopupTarget target;
- GSList *attachments;
-};
-
-typedef struct _EPopupItem ECalPopupItem;
-
-typedef struct _ECalPopup ECalPopup;
-typedef struct _ECalPopupClass ECalPopupClass;
-typedef struct _ECalPopupPrivate ECalPopupPrivate;
-
-/* The object */
-struct _ECalPopup {
- EPopup popup;
-
- ECalPopupPrivate *priv;
-};
-
-struct _ECalPopupClass {
- EPopupClass popup_class;
-};
-
-GType e_cal_popup_get_type(void);
-
-ECalPopup *e_cal_popup_new(const gchar *menuid);
-
-ECalPopupTargetSelect *e_cal_popup_target_new_select(ECalPopup *eabp, ECalModel *model, GPtrArray *events);
-ECalPopupTargetSource *e_cal_popup_target_new_source(ECalPopup *eabp, ESourceSelector *selector);
-
-/* ********************************************************************** */
-
-typedef struct _ECalPopupHook ECalPopupHook;
-typedef struct _ECalPopupHookClass ECalPopupHookClass;
-
-struct _ECalPopupHook {
- EPopupHook hook;
-};
-
-struct _ECalPopupHookClass {
- EPopupHookClass hook_class;
-};
-
-GType e_cal_popup_hook_get_type(void);
-
-G_END_DECLS
-
-#endif /* __E_CAL_POPUP_H__ */
diff --git a/calendar/gui/e-calendar-selector.c b/calendar/gui/e-calendar-selector.c
new file mode 100644
index 0000000000..94bd5ae339
--- /dev/null
+++ b/calendar/gui/e-calendar-selector.c
@@ -0,0 +1,226 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-calendar-selector.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "e-calendar-selector.h"
+
+#include <libecal/e-cal.h>
+#include "common/authentication.h"
+
+#define E_CALENDAR_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorPrivate))
+
+struct _ECalendarSelectorPrivate {
+ gint dummy_value;
+};
+
+enum {
+ DND_TARGET_TYPE_CALENDAR_LIST
+};
+
+static GtkTargetEntry drag_types[] = {
+ { (gchar *) "text/calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST },
+ { (gchar *) "text/x-calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST }
+};
+
+static gpointer parent_class;
+
+static gboolean
+calendar_selector_update_single_object (ECal *client,
+ icalcomponent *icalcomp)
+{
+ gchar *uid;
+ icalcomponent *tmp_icalcomp;
+
+ uid = (gchar *) icalcomponent_get_uid (icalcomp);
+
+ if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL))
+ return e_cal_modify_object (
+ client, icalcomp, CALOBJ_MOD_ALL, NULL);
+
+ return e_cal_create_object (client, icalcomp, &uid, NULL);
+}
+
+static gboolean
+calendar_selector_update_objects (ECal *client,
+ icalcomponent *icalcomp)
+{
+ icalcomponent *subcomp;
+ icalcomponent_kind kind;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VTODO_COMPONENT || kind == ICAL_VEVENT_COMPONENT)
+ return calendar_selector_update_single_object (
+ client, icalcomp);
+ else if (kind != ICAL_VCALENDAR_COMPONENT)
+ return FALSE;
+
+ subcomp = icalcomponent_get_first_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ while (subcomp != NULL) {
+ gboolean success;
+
+ kind = icalcomponent_isa (subcomp);
+ if (kind == ICAL_VTIMEZONE_COMPONENT) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+
+ success = e_cal_add_timezone (client, zone, NULL);
+ icaltimezone_free (zone, 1);
+ if (!success)
+ return FALSE;
+ } else if (kind == ICAL_VTODO_COMPONENT ||
+ kind == ICAL_VEVENT_COMPONENT) {
+ success = calendar_selector_update_single_object (
+ client, subcomp);
+ if (!success)
+ return FALSE;
+ }
+
+ subcomp = icalcomponent_get_next_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+calendar_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
+{
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreePath *path = NULL;
+ ECal *client;
+ icalcomponent *icalcomp;
+ const gchar *string;
+ gboolean remove_from_source;
+ gboolean success = FALSE;
+ gpointer object = NULL;
+
+ tree_view = GTK_TREE_VIEW (selector);
+ model = gtk_tree_view_get_model (tree_view);
+
+ string = (const gchar *) selection_data->data;
+ remove_from_source = (action == GDK_ACTION_MOVE);
+
+ icalcomp = icalparser_parse_string (string);
+
+ if (icalcomp == NULL)
+ goto exit;
+
+ /* FIXME Deal with GDK_ACTION_ASK. */
+ if (action == GDK_ACTION_COPY) {
+ gchar *uid;
+
+ uid = e_cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp, uid);
+ }
+
+ client = auth_new_cal_from_source (
+ destination, E_CAL_SOURCE_TYPE_EVENT);
+
+ if (client != NULL) {
+ if (e_cal_open (client, TRUE, NULL)) {
+ success = TRUE;
+ calendar_selector_update_objects (client, icalcomp);
+ }
+
+ g_object_unref (client);
+ }
+
+ icalcomponent_free (icalcomp);
+
+ success = TRUE;
+
+exit:
+ if (path != NULL)
+ gtk_tree_path_free (path);
+
+ if (object != NULL)
+ g_object_unref (object);
+
+ return TRUE;
+}
+
+static void
+calendar_selector_class_init (ECalendarSelectorClass *class)
+{
+ ESourceSelectorClass *source_selector_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECalendarSelectorPrivate));
+
+ source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ source_selector_class->data_dropped = calendar_selector_data_dropped;
+}
+
+static void
+calendar_selector_init (ECalendarSelector *selector)
+{
+ selector->priv = E_CALENDAR_SELECTOR_GET_PRIVATE (selector);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+}
+
+GType
+e_calendar_selector_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (ECalendarSelectorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) calendar_selector_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalendarSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) calendar_selector_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_SOURCE_SELECTOR, "ECalendarSelector",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_calendar_selector_new (ESourceList *source_list)
+{
+ g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
+
+ return g_object_new (
+ E_TYPE_CALENDAR_SELECTOR,
+ "source-list", source_list, NULL);
+}
diff --git a/calendar/gui/e-calendar-selector.h b/calendar/gui/e-calendar-selector.h
new file mode 100644
index 0000000000..65d9a2fc81
--- /dev/null
+++ b/calendar/gui/e-calendar-selector.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-calendar-selector.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef E_CALENDAR_SELECTOR_H
+#define E_CALENDAR_SELECTOR_H
+
+#include <libedataserver/e-source-list.h>
+#include <libedataserverui/e-source-selector.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CALENDAR_SELECTOR \
+ (e_calendar_selector_get_type ())
+#define E_CALENDAR_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelector))
+#define E_CALENDAR_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorClass))
+#define E_IS_CALENDAR_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CALENDAR_SELECTOR))
+#define E_IS_CALENDAR_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CALENDAR_SELECTOR))
+#define E_CALENDAR_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalendarSelector ECalendarSelector;
+typedef struct _ECalendarSelectorClass ECalendarSelectorClass;
+typedef struct _ECalendarSelectorPrivate ECalendarSelectorPrivate;
+
+struct _ECalendarSelector {
+ ESourceSelector parent;
+ ECalendarSelectorPrivate *priv;
+};
+
+struct _ECalendarSelectorClass {
+ ESourceSelectorClass parent_class;
+};
+
+GType e_calendar_selector_get_type (void);
+GtkWidget * e_calendar_selector_new (ESourceList *source_list);
+
+G_END_DECLS
+
+#endif /* E_CALENDAR_SELECTOR_H */
diff --git a/calendar/gui/e-calendar-table-config.c b/calendar/gui/e-calendar-table-config.c
deleted file mode 100644
index fb8d18c189..0000000000
--- a/calendar/gui/e-calendar-table-config.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "calendar-config.h"
-#include "e-cell-date-edit-config.h"
-#include "e-calendar-table-config.h"
-
-struct _ECalendarTableConfigPrivate {
- ECalendarTable *table;
-
- ECellDateEditConfig *cell_config;
-
- GList *notifications;
-};
-
-/* Property IDs */
-enum props {
- PROP_0,
- PROP_TABLE
-};
-
-G_DEFINE_TYPE (ECalendarTableConfig, e_calendar_table_config, G_TYPE_OBJECT)
-
-static void
-e_calendar_table_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- ECalendarTableConfig *table_config;
-
- table_config = E_CALENDAR_TABLE_CONFIG (object);
-
- switch (property_id) {
- case PROP_TABLE:
- e_calendar_table_config_set_table (table_config, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_calendar_table_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- ECalendarTableConfig *table_config;
-
- table_config = E_CALENDAR_TABLE_CONFIG (object);
-
- switch (property_id) {
- case PROP_TABLE:
- g_value_set_object (value, e_calendar_table_config_get_table (table_config));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_calendar_table_config_dispose (GObject *object)
-{
- ECalendarTableConfig *table_config = E_CALENDAR_TABLE_CONFIG (object);
-
- e_calendar_table_config_set_table (table_config, NULL);
-
- if (G_OBJECT_CLASS (e_calendar_table_config_parent_class)->dispose)
- G_OBJECT_CLASS (e_calendar_table_config_parent_class)->dispose (object);
-}
-
-static void
-e_calendar_table_config_finalize (GObject *object)
-{
- ECalendarTableConfig *table_config = E_CALENDAR_TABLE_CONFIG (object);
- ECalendarTableConfigPrivate *priv;
-
- priv = table_config->priv;
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_calendar_table_config_parent_class)->finalize)
- G_OBJECT_CLASS (e_calendar_table_config_parent_class)->finalize (object);
-}
-
-static void
-e_calendar_table_config_class_init (ECalendarTableConfigClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *spec;
-
- /* Method override */
- gobject_class->set_property = e_calendar_table_config_set_property;
- gobject_class->get_property = e_calendar_table_config_get_property;
- gobject_class->dispose = e_calendar_table_config_dispose;
- gobject_class->finalize = e_calendar_table_config_finalize;
-
- spec = g_param_spec_object ("table", NULL, NULL, e_calendar_table_get_type (),
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (gobject_class, PROP_TABLE, spec);
-}
-
-static void
-e_calendar_table_config_init (ECalendarTableConfig *table_config)
-{
- table_config->priv = g_new0 (ECalendarTableConfigPrivate, 1);
-
-}
-
-ECalendarTableConfig *
-e_calendar_table_config_new (ECalendarTable *table)
-{
- ECalendarTableConfig *table_config;
-
- table_config = g_object_new (e_calendar_table_config_get_type (), "table", table, NULL);
-
- return table_config;
-}
-
-ECalendarTable *
-e_calendar_table_config_get_table (ECalendarTableConfig *table_config)
-{
- ECalendarTableConfigPrivate *priv;
-
- g_return_val_if_fail (table_config != NULL, NULL);
- g_return_val_if_fail (E_IS_CALENDAR_TABLE_CONFIG (table_config), NULL);
-
- priv = table_config->priv;
-
- return priv->table;
-}
-
-static void
-set_timezone (ECalendarTable *table)
-{
- ECalModel *model;
- icaltimezone *zone;
-
- zone = calendar_config_get_icaltimezone ();
- model = e_calendar_table_get_model (table);
- if (model)
- e_cal_model_set_timezone (model, zone);
-}
-
-static void
-timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ECalendarTableConfig *table_config = data;
- ECalendarTableConfigPrivate *priv;
-
- priv = table_config->priv;
-
- set_timezone (priv->table);
-}
-
-static void
-set_twentyfour_hour (ECalendarTable *table)
-{
- ECalModel *model;
- gboolean use_24_hour;
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- model = e_calendar_table_get_model (table);
- if (model)
- e_cal_model_set_use_24_hour_format (model, use_24_hour);
-}
-
-static void
-twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ECalendarTableConfig *table_config = data;
- ECalendarTableConfigPrivate *priv;
-
- priv = table_config->priv;
-
- set_twentyfour_hour (priv->table);
-}
-
-void
-e_calendar_table_config_set_table (ECalendarTableConfig *table_config, ECalendarTable *table)
-{
- ECalendarTableConfigPrivate *priv;
- guint not;
- GList *l;
-
- g_return_if_fail (table_config != NULL);
- g_return_if_fail (E_IS_CALENDAR_TABLE_CONFIG (table_config));
-
- priv = table_config->priv;
-
- if (priv->table) {
- g_object_unref (priv->table);
- priv->table = NULL;
- }
-
- if (priv->cell_config) {
- g_object_unref (priv->cell_config);
- priv->cell_config = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
-
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- /* If the new view is NULL, return right now */
- if (!table)
- return;
-
- priv->table = g_object_ref (table);
-
- /* Time zone */
- set_timezone (table);
-
- not = calendar_config_add_notification_timezone (timezone_changed_cb, table_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* 24 Hour format */
- set_twentyfour_hour (table);
-
- not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, table_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Date cell */
- priv->cell_config = e_cell_date_edit_config_new (table->dates_cell);
-}
diff --git a/calendar/gui/e-calendar-table-config.h b/calendar/gui/e-calendar-table-config.h
deleted file mode 100644
index 93588a6e57..0000000000
--- a/calendar/gui/e-calendar-table-config.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_CALENDAR_TABLE_CONFIG_H_
-#define _E_CALENDAR_TABLE_CONFIG_H_
-
-#include "e-calendar-table.h"
-
-G_BEGIN_DECLS
-
-#define E_CALENDAR_TABLE_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_calendar_table_config_get_type (), ECalendarTableConfig)
-#define E_CALENDAR_TABLE_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_calendar_table_config_get_type (), ECalendarTableConfigClass)
-#define E_IS_CALENDAR_TABLE_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_calendar_table_config_get_type ())
-
-typedef struct _ECalendarTableConfig ECalendarTableConfig;
-typedef struct _ECalendarTableConfigClass ECalendarTableConfigClass;
-typedef struct _ECalendarTableConfigPrivate ECalendarTableConfigPrivate;
-
-struct _ECalendarTableConfig {
- GObject parent;
-
- ECalendarTableConfigPrivate *priv;
-};
-
-struct _ECalendarTableConfigClass {
- GObjectClass parent_class;
-};
-
-GType e_calendar_table_config_get_type (void);
-ECalendarTableConfig *e_calendar_table_config_new (ECalendarTable *table);
-ECalendarTable *e_calendar_table_config_get_table (ECalendarTableConfig *view_config);
-void e_calendar_table_config_set_table (ECalendarTableConfig *view_config, ECalendarTable *table);
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 284922c029..1122310a49 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -32,7 +32,6 @@
#include <sys/stat.h>
#include <unistd.h>
-#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gtk/gtk.h>
@@ -43,14 +42,14 @@
#include <table/e-cell-text.h>
#include <table/e-cell-combo.h>
#include <table/e-cell-date.h>
+#include <e-util/e-binding.h>
#include <e-util/e-dialog-utils.h>
#include <e-util/e-util-private.h>
-#include <misc/e-cell-date-edit.h>
-#include <misc/e-cell-percent.h>
+#include <table/e-cell-date-edit.h>
+#include <table/e-cell-percent.h>
#include <libecal/e-cal-time-util.h>
#include <libedataserver/e-time-utils.h>
-#include "calendar-component.h"
#include "calendar-config.h"
#include "dialogs/delete-comp.h"
#include "dialogs/delete-error.h"
@@ -59,103 +58,97 @@
#include "e-calendar-table.h"
#include "e-calendar-view.h"
#include "e-cell-date-edit-text.h"
-#include "e-comp-editor-registry.h"
#include "print.h"
#include <e-util/e-icon-factory.h>
-#include "e-cal-popup.h"
-#include "e-tasks.h"
#include "misc.h"
-enum TargetType{
- TARGET_TYPE_VCALENDAR
-};
+#define E_CALENDAR_TABLE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CALENDAR_TABLE, ECalendarTablePrivate))
-static GtkTargetEntry target_types[] = {
- { (gchar *) "text/x-calendar", 0, TARGET_TYPE_VCALENDAR },
- { (gchar *) "text/calendar", 0, TARGET_TYPE_VCALENDAR }
+struct _ECalendarTablePrivate {
+ gpointer shell_view; /* weak pointer */
+ ECalModel *model;
};
-static guint n_target_types = G_N_ELEMENTS (target_types);
-
-extern ECompEditorRegistry *comp_editor_registry;
-
-static void e_calendar_table_destroy (GtkObject *object);
-
-static void e_calendar_table_on_double_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- ECalendarTable *cal_table);
-static gint e_calendar_table_show_popup_menu (ETable *table,
- GdkEvent *gdk_event,
- ECalendarTable *cal_table);
-
-static gint e_calendar_table_on_right_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- ECalendarTable *cal_table);
-static gboolean e_calendar_table_on_popup_menu (GtkWidget *widget,
- gpointer data);
-
-static gint e_calendar_table_on_key_press (ETable *table,
- gint row,
- gint col,
- GdkEventKey *event,
- ECalendarTable *cal_table);
-
-static struct tm e_calendar_table_get_current_time (ECellDateEdit *ecde,
- gpointer data);
-static void mark_as_complete_cb (EPopup *ep, EPopupItem *pitem, gpointer data);
-
-static void hide_completed_rows (ECalModel *model, GList *clients_list, gchar *hide_sexp, GPtrArray *comp_objects);
-static void show_completed_rows (ECalModel *model, GList *clients_list, gchar *show_sexp, GPtrArray *comp_objects);
+enum {
+ PROP_0,
+ PROP_MODEL,
+ PROP_SHELL_VIEW
+};
-/* Signal IDs */
enum {
+ OPEN_COMPONENT,
+ POPUP_EVENT,
+ STATUS_MESSAGE,
USER_CREATED,
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0 };
+enum {
+ TARGET_TYPE_VCALENDAR
+};
+
+static GtkTargetEntry target_types[] = {
+ { (gchar *) "text/calendar", 0, TARGET_TYPE_VCALENDAR },
+ { (gchar *) "text/x-calendar", 0, TARGET_TYPE_VCALENDAR }
+};
+
+static struct tm e_calendar_table_get_current_time (ECellDateEdit *ecde, gpointer data);
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+static GdkAtom clipboard_atom;
/* The icons to represent the task. */
-#define E_CALENDAR_MODEL_NUM_ICONS 4
-static const gchar * icon_names[E_CALENDAR_MODEL_NUM_ICONS] = {
- "stock_task", "stock_task-recurring", "stock_task-assigned", "stock_task-assigned-to"
+#define NUM_ICONS 4
+static const gchar *icon_names[NUM_ICONS] = {
+ "stock_task",
+ "stock_task-recurring",
+ "stock_task-assigned",
+ "stock_task-assigned-to"
};
-static GdkPixbuf* icon_pixbufs[E_CALENDAR_MODEL_NUM_ICONS] = { NULL };
+static GdkPixbuf *icon_pixbufs[NUM_ICONS] = { NULL };
-static GdkAtom clipboard_atom = GDK_NONE;
+static void
+calendar_table_emit_open_component (ECalendarTable *cal_table,
+ ECalModelComponent *comp_data)
+{
+ guint signal_id = signals[OPEN_COMPONENT];
-G_DEFINE_TYPE (ECalendarTable, e_calendar_table, GTK_TYPE_TABLE)
+ g_signal_emit (cal_table, signal_id, 0, comp_data);
+}
static void
-e_calendar_table_class_init (ECalendarTableClass *class)
+calendar_table_emit_popup_event (ECalendarTable *cal_table,
+ GdkEvent *event)
{
- GtkObjectClass *object_class;
+ guint signal_id = signals[POPUP_EVENT];
- object_class = (GtkObjectClass *) class;
+ g_signal_emit (cal_table, signal_id, 0, event);
+}
+
+static void
+calendar_table_emit_status_message (ECalendarTable *cal_table,
+ const gchar *message,
+ gdouble percent)
+{
+ guint signal_id = signals[STATUS_MESSAGE];
- /* Method override */
- object_class->destroy = e_calendar_table_destroy;
+ g_signal_emit (cal_table, signal_id, 0, message, percent);
+}
- signals[USER_CREATED] =
- g_signal_new ("user_created",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ECalendarTableClass, user_created),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+static void
+calendar_table_emit_user_created (ECalendarTable *cal_table)
+{
+ guint signal_id = signals[USER_CREATED];
- /* clipboard atom */
- if (!clipboard_atom)
- clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+ g_signal_emit (cal_table, signal_id, 0);
}
static gint
-date_compare_cb (gconstpointer a, gconstpointer b)
+calendar_table_date_compare_cb (gconstpointer a,
+ gconstpointer b)
{
ECellDateEditValue *dv1 = (ECellDateEditValue *) a;
ECellDateEditValue *dv2 = (ECellDateEditValue *) b;
@@ -183,24 +176,18 @@ date_compare_cb (gconstpointer a, gconstpointer b)
}
static gint
-percent_compare_cb (gconstpointer a, gconstpointer b)
+calendar_table_percent_compare_cb (gconstpointer a,
+ gconstpointer b)
{
gint percent1 = GPOINTER_TO_INT (a);
gint percent2 = GPOINTER_TO_INT (b);
- gint retval;
- if (percent1 > percent2)
- retval = 1;
- else if (percent1 < percent2)
- retval = -1;
- else
- retval = 0;
-
- return retval;
+ return (percent1 < percent2) ? -1 : (percent1 > percent2);
}
static gint
-priority_compare_cb (gconstpointer a, gconstpointer b)
+calendar_table_priority_compare_cb (gconstpointer a,
+ gconstpointer b)
{
gint priority1, priority2;
@@ -214,71 +201,85 @@ priority_compare_cb (gconstpointer a, gconstpointer b)
priority2 = 10;
/* We'll just use the ordering of the priority values. */
- if (priority1 < priority2)
- return -1;
- else if (priority1 > priority2)
- return 1;
- else
- return 0;
+ return (priority1 < priority2) ? -1 : (priority1 > priority2);
}
static gint
-status_from_string (const gchar *str)
-{
- gint status = -2;
-
- if (!str || !str[0])
- status = -1;
- else if (!g_utf8_collate (str, _("Not Started")))
- status = 0;
- else if (!g_utf8_collate (str, _("In Progress")))
- status = 1;
- else if (!g_utf8_collate (str, _("Completed")))
- status = 2;
- else if (!g_utf8_collate (str, _("Canceled")))
- status = 3;
-
- return status;
+calendar_table_status_compare_cb (gconstpointer a,
+ gconstpointer b)
+{
+ const gchar *string_a = a;
+ const gchar *string_b = b;
+ gint status_a = -2;
+ gint status_b = -2;
+
+ if (string_a == NULL || *string_a == '\0')
+ status_a = -1;
+ else if (!g_utf8_collate (string_a, _("Not Started")))
+ status_a = 0;
+ else if (!g_utf8_collate (string_a, _("In Progress")))
+ status_a = 1;
+ else if (!g_utf8_collate (string_a, _("Completed")))
+ status_a = 2;
+ else if (!g_utf8_collate (string_a, _("Canceled")))
+ status_a = 3;
+
+ if (string_b == NULL || *string_b == '\0')
+ status_b = -1;
+ else if (!g_utf8_collate (string_b, _("Not Started")))
+ status_b = 0;
+ else if (!g_utf8_collate (string_b, _("In Progress")))
+ status_b = 1;
+ else if (!g_utf8_collate (string_b, _("Completed")))
+ status_b = 2;
+ else if (!g_utf8_collate (string_b, _("Canceled")))
+ status_b = 3;
+
+ return (status_a < status_b) ? -1 : (status_a > status_b);
}
-static gint
-status_compare_cb (gconstpointer a, gconstpointer b)
+static void
+calendar_table_double_click_cb (ECalendarTable *cal_table,
+ gint row,
+ gint col,
+ GdkEvent *event)
{
- gint sa = status_from_string ((const gchar *)a);
- gint sb = status_from_string ((const gchar *)b);
-
- if (sa < sb)
- return -1;
- else if (sa > sb)
- return 1;
+ ECalModel *model;
+ ECalModelComponent *comp_data;
- return 0;
+ model = e_calendar_table_get_model (cal_table);
+ comp_data = e_cal_model_get_component_at (model, row);
+ calendar_table_emit_open_component (cal_table, comp_data);
}
static void
-row_appended_cb (ECalModel *model, ECalendarTable *cal_table)
+calendar_table_model_cal_view_progress_cb (ECalendarTable *cal_table,
+ const gchar *message,
+ gint progress,
+ ECalSourceType type)
{
- g_signal_emit (cal_table, signals[USER_CREATED], 0);
+ gdouble percent = (gdouble) progress;
+
+ calendar_table_emit_status_message (cal_table, message, percent);
}
static void
-get_time_as_text (struct icaltimetype *tt, icaltimezone *f_zone, icaltimezone *t_zone, gchar *buff, gint buff_len)
+calendar_table_model_cal_view_done_cb (ECalendarTable *cal_table,
+ ECalendarStatus status,
+ ECalSourceType type)
{
- struct tm tmp_tm;
-
- buff [0] = 0;
-
- tmp_tm = icaltimetype_to_tm_with_zone (tt, f_zone, t_zone);
- e_time_format_date_and_time (&tmp_tm,
- calendar_config_get_24_hour_format (),
- FALSE, FALSE,
- buff, buff_len);
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
}
-gboolean
-ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, GtkWidget *etable_wgt, ECalModel *model)
+static gboolean
+calendar_table_query_tooltip_cb (ECalendarTable *cal_table,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip)
{
- ECalModelComponent *comp;
+ ECalModel *model;
+ ECalModelComponent *comp_data;
gint row = -1, col = -1;
GtkWidget *box, *l, *w;
GtkStyle *style = gtk_widget_get_default_style ();
@@ -287,47 +288,48 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk
GString *tmp2;
gchar buff[1001];
gboolean free_text = FALSE;
+ gboolean use_24_hour_format;
ECalComponent *new_comp;
ECalComponentOrganizer organizer;
ECalComponentDateTime dtstart, dtdue;
+ icalcomponent *clone;
icaltimezone *zone, *default_zone;
GSList *desc, *p;
gint len;
ETable *etable;
ESelectionModel *esm;
+ struct tm tmp_tm;
if (keyboard_mode)
return FALSE;
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (tooltip != NULL, FALSE);
- g_return_val_if_fail (E_IS_TABLE (etable_wgt), FALSE);
- g_return_val_if_fail (E_IS_CAL_MODEL (model), FALSE);
-
- etable = E_TABLE (etable_wgt);
-
+ etable = e_calendar_table_get_table (cal_table);
e_table_get_mouse_over_cell (etable, &row, &col);
if (row == -1 || !etable)
return FALSE;
- /* respect sorting option, the 'e_table_get_mouse_over_cell' returns sorted row, not the model one */
+ /* Respect sorting option; the 'e_table_get_mouse_over_cell'
+ * returns sorted row, not the model one. */
esm = e_table_get_selection_model (etable);
if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter))
row = e_sorter_sorted_to_model (esm->sorter, row);
- comp = e_cal_model_get_component_at (model, row);
- if (!comp || !comp->icalcomp)
+ model = e_calendar_table_get_model (cal_table);
+ comp_data = e_cal_model_get_component_at (model, row);
+ if (!comp_data || !comp_data->icalcomp)
return FALSE;
new_comp = e_cal_component_new ();
- if (!e_cal_component_set_icalcomponent (new_comp, icalcomponent_new_clone (comp->icalcomp))) {
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ if (!e_cal_component_set_icalcomponent (new_comp, clone)) {
g_object_unref (new_comp);
return FALSE;
}
box = gtk_vbox_new (FALSE, 0);
- str = e_calendar_view_get_icalcomponent_summary (comp->client, comp->icalcomp, &free_text);
+ str = e_calendar_view_get_icalcomponent_summary (
+ comp_data->client, comp_data->icalcomp, &free_text);
if (!(str && *str)) {
if (free_text)
g_free ((gchar *)str);
@@ -367,7 +369,7 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk
if (ptr) {
ptr++;
- /* To Translators: It will display "Organiser: NameOfTheUser <email@ofuser.com>" */
+ /* To Translators: It will display "Organizer: NameOfTheUser <email@ofuser.com>" */
tmp = g_strdup_printf (_("Organizer: %s <%s>"), organizer.cn, ptr);
} else {
/* With SunOne accounts, there may be no ':' in organiser.value */
@@ -384,12 +386,14 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk
e_cal_component_get_dtstart (new_comp, &dtstart);
e_cal_component_get_due (new_comp, &dtdue);
- default_zone = e_cal_model_get_timezone (model);
+ default_zone = e_cal_model_get_timezone (model);
+ use_24_hour_format = e_cal_model_get_use_24_hour_format (model);
if (dtstart.tzid) {
zone = icalcomponent_get_timezone (e_cal_component_get_icalcomponent (new_comp), dtstart.tzid);
if (!zone)
- e_cal_get_timezone (comp->client, dtstart.tzid, &zone, NULL);
+ e_cal_get_timezone (
+ comp_data->client, dtstart.tzid, &zone, NULL);
if (!zone)
zone = default_zone;
} else {
@@ -399,7 +403,13 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk
tmp2 = g_string_new ("");
if (dtstart.value) {
- get_time_as_text (dtstart.value, zone, default_zone, buff, 1000);
+ buff[0] = 0;
+
+ tmp_tm = icaltimetype_to_tm_with_zone (
+ dtstart.value, zone, default_zone);
+ e_time_format_date_and_time (
+ &tmp_tm, use_24_hour_format,
+ FALSE, FALSE, buff, 1000);
if (buff [0]) {
g_string_append (tmp2, _("Start: "));
@@ -408,7 +418,13 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk
}
if (dtdue.value) {
- get_time_as_text (dtdue.value, zone, default_zone, buff, 1000);
+ buff[0] = 0;
+
+ tmp_tm = icaltimetype_to_tm_with_zone (
+ dtdue.value, zone, default_zone);
+ e_time_format_date_and_time (
+ &tmp_tm, use_24_hour_format,
+ FALSE, FALSE, buff, 1000);
if (buff [0]) {
if (tmp2->len)
@@ -430,7 +446,8 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk
e_cal_component_free_datetime (&dtstart);
e_cal_component_free_datetime (&dtdue);
- tmp = e_calendar_view_get_attendees_status_info (new_comp, comp->client);
+ tmp = e_calendar_view_get_attendees_status_info (
+ new_comp, comp_data->client);
if (tmp) {
l = gtk_label_new (tmp);
gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
@@ -475,22 +492,135 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk
}
static gboolean
-query_tooltip_cb (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data)
+calendar_table_popup_menu_cb (ECalendarTable *cal_table)
{
- ECalendarTable *cal_table;
+ calendar_table_emit_popup_event (cal_table, NULL);
+
+ return TRUE;
+}
- g_return_val_if_fail (E_IS_CALENDAR_TABLE (user_data), FALSE);
+static gint
+calendar_table_right_click_cb (ECalendarTable *cal_table,
+ gint row,
+ gint col,
+ GdkEvent *event)
+{
+ calendar_table_emit_popup_event (cal_table, event);
+
+ return TRUE;
+}
+
+static void
+calendar_table_set_model (ECalendarTable *cal_table,
+ ECalModel *model)
+{
+ g_return_if_fail (cal_table->priv->model == NULL);
+
+ cal_table->priv->model = g_object_ref (model);
+
+ g_signal_connect_swapped (
+ model, "row_appended",
+ G_CALLBACK (calendar_table_emit_user_created), cal_table);
+
+ g_signal_connect_swapped (
+ model, "cal-view-progress",
+ G_CALLBACK (calendar_table_model_cal_view_progress_cb),
+ cal_table);
+
+ g_signal_connect_swapped (
+ model, "cal-view-done",
+ G_CALLBACK (calendar_table_model_cal_view_done_cb),
+ cal_table);
+}
+
+static void
+calendar_table_set_shell_view (ECalendarTable *cal_table,
+ EShellView *shell_view)
+{
+ g_return_if_fail (cal_table->priv->shell_view == NULL);
+
+ cal_table->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &cal_table->priv->shell_view);
+}
+
+static void
+calendar_table_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODEL:
+ calendar_table_set_model (
+ E_CALENDAR_TABLE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SHELL_VIEW:
+ calendar_table_set_shell_view (
+ E_CALENDAR_TABLE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+calendar_table_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (
+ value, e_calendar_table_get_model (
+ E_CALENDAR_TABLE (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_calendar_table_get_shell_view (
+ E_CALENDAR_TABLE (object)));
+ return;
+ }
- cal_table = E_CALENDAR_TABLE (user_data);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+calendar_table_dispose (GObject *object)
+{
+ ECalendarTablePrivate *priv;
+
+ priv = E_CALENDAR_TABLE_GET_PRIVATE (object);
+
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view), &priv->shell_view);
+ priv->shell_view = NULL;
+ }
- return ec_query_tooltip (widget, x, y, keyboard_mode, tooltip, GTK_WIDGET (e_calendar_table_get_table (cal_table)), cal_table->model);
+ if (priv->model != NULL) {
+ g_object_unref (priv->model);
+ priv->model = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-e_calendar_table_init (ECalendarTable *cal_table)
+calendar_table_constructed (GObject *object)
{
- GtkWidget *table;
- ETable *e_table;
+ ECalendarTable *cal_table;
+ GtkWidget *widget;
+ ECalModel *model;
+ ETable *table;
ECell *cell, *popup_cell;
ETableExtras *extras;
gint i;
@@ -499,22 +629,18 @@ e_calendar_table_init (ECalendarTable *cal_table)
AtkObject *a11y;
gchar *etspecfile;
- /* Create the model */
-
- cal_table->model = (ECalModel *) e_cal_model_tasks_new ();
- g_signal_connect (cal_table->model, "row_appended", G_CALLBACK (row_appended_cb), cal_table);
-
- cal_table->user_created_cal = NULL;
+ cal_table = E_CALENDAR_TABLE (object);
+ model = e_calendar_table_get_model (cal_table);
/* Create the header columns */
- extras = e_table_extras_new();
+ extras = e_table_extras_new ();
/*
* Normal string fields.
*/
cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
- g_object_set (G_OBJECT (cell),
+ g_object_set (cell,
"strikeout_column", E_CAL_MODEL_TASKS_FIELD_STRIKEOUT,
"bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE,
"bg_color_column", E_CAL_MODEL_FIELD_COLOR,
@@ -526,21 +652,34 @@ e_calendar_table_init (ECalendarTable *cal_table)
* Date fields.
*/
cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT);
- g_object_set (G_OBJECT (cell),
+ g_object_set (cell,
"strikeout_column", E_CAL_MODEL_TASKS_FIELD_STRIKEOUT,
"bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE,
"bg_color_column", E_CAL_MODEL_FIELD_COLOR,
NULL);
+ e_mutual_binding_new (
+ G_OBJECT (model), "timezone",
+ G_OBJECT (cell), "timezone");
+
+ e_mutual_binding_new (
+ G_OBJECT (model), "use-24-hour-format",
+ G_OBJECT (cell), "use-24-hour-format");
+
popup_cell = e_cell_date_edit_new ();
e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
g_object_unref (cell);
+
+ e_mutual_binding_new (
+ G_OBJECT (model), "use-24-hour-format",
+ G_OBJECT (popup_cell), "use-24-hour-format");
+
e_table_extras_add_cell (extras, "dateedit", popup_cell);
cal_table->dates_cell = E_CELL_DATE_EDIT (popup_cell);
- e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell),
- e_calendar_table_get_current_time,
- cal_table, NULL);
+ e_cell_date_edit_set_get_time_callback (
+ E_CELL_DATE_EDIT (popup_cell),
+ e_calendar_table_get_current_time, cal_table, NULL);
/*
* Combo fields.
@@ -548,7 +687,7 @@ e_calendar_table_init (ECalendarTable *cal_table)
/* Classification field. */
cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
- g_object_set (G_OBJECT (cell),
+ g_object_set (cell,
"strikeout_column", E_CAL_MODEL_TASKS_FIELD_STRIKEOUT,
"bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE,
"bg_color_column", E_CAL_MODEL_FIELD_COLOR,
@@ -665,22 +804,22 @@ e_calendar_table_init (ECalendarTable *cal_table)
e_table_extras_add_cell (extras, "calstatus", popup_cell);
e_table_extras_add_compare (extras, "date-compare",
- date_compare_cb);
+ calendar_table_date_compare_cb);
e_table_extras_add_compare (extras, "percent-compare",
- percent_compare_cb);
+ calendar_table_percent_compare_cb);
e_table_extras_add_compare (extras, "priority-compare",
- priority_compare_cb);
+ calendar_table_priority_compare_cb);
e_table_extras_add_compare (extras, "status-compare",
- status_compare_cb);
+ calendar_table_status_compare_cb);
/* Create pixmaps */
if (!icon_pixbufs[0])
- for (i = 0; i < E_CALENDAR_MODEL_NUM_ICONS; i++) {
+ for (i = 0; i < NUM_ICONS; i++) {
icon_pixbufs[i] = e_icon_factory_get_icon (icon_names[i], GTK_ICON_SIZE_MENU);
}
- cell = e_cell_toggle_new (0, E_CALENDAR_MODEL_NUM_ICONS, icon_pixbufs);
+ cell = e_cell_toggle_new (0, NUM_ICONS, icon_pixbufs);
e_table_extras_add_cell(extras, "icon", cell);
e_table_extras_add_pixbuf(extras, "icon", icon_pixbufs[0]);
@@ -694,51 +833,166 @@ e_calendar_table_init (ECalendarTable *cal_table)
/* Create the table */
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "e-calendar-table.etspec",
- NULL);
- table = e_table_scrolled_new_from_spec_file (E_TABLE_MODEL (cal_table->model),
- extras,
- etspecfile,
- NULL);
+ etspecfile = g_build_filename (
+ EVOLUTION_ETSPECDIR, "e-calendar-table.etspec", NULL);
+ widget = e_table_scrolled_new_from_spec_file (
+ E_TABLE_MODEL (model), extras, etspecfile, NULL);
+ gtk_table_attach (
+ GTK_TABLE (cal_table), widget, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ cal_table->etable = widget;
+ gtk_widget_show (widget);
g_free (etspecfile);
- /* FIXME: this causes a message from GLib about 'extras' having only a floating
- reference */
- /* g_object_unref (extras); */
+ table = e_table_scrolled_get_table (E_TABLE_SCROLLED (widget));
+ g_signal_connect_swapped (
+ table, "double-click",
+ G_CALLBACK (calendar_table_double_click_cb), cal_table);
+ g_signal_connect_swapped (
+ table, "query-tooltip",
+ G_CALLBACK (calendar_table_query_tooltip_cb), cal_table);
+ g_signal_connect_swapped (
+ table, "popup-menu",
+ G_CALLBACK (calendar_table_popup_menu_cb), cal_table);
+ g_signal_connect_swapped (
+ table, "right-click",
+ G_CALLBACK (calendar_table_right_click_cb), cal_table);
+ gtk_widget_set_has_tooltip (GTK_WIDGET (table), TRUE);
+
+ a11y = gtk_widget_get_accessible (GTK_WIDGET (table));
+ if (a11y)
+ atk_object_set_name (a11y, _("Tasks"));
+}
- cal_table->etable = table;
- gtk_table_attach (GTK_TABLE (cal_table), table, 0, 1, 0, 1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- gtk_widget_show (table);
+static void
+calendar_table_class_init (ECalendarTableClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECalendarTablePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = calendar_table_set_property;
+ object_class->get_property = calendar_table_get_property;
+ object_class->dispose = calendar_table_dispose;
+ object_class->constructed = calendar_table_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ _("Model"),
+ NULL,
+ E_TYPE_CAL_MODEL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ _("Shell View"),
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[OPEN_COMPONENT] = g_signal_new (
+ "open-component",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ECalendarTableClass, open_component),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CAL_MODEL_COMPONENT);
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ECalendarTableClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status-message",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ECalendarTableClass, status_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[USER_CREATED] = g_signal_new (
+ "user-created",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ECalendarTableClass, user_created),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+}
- e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (table));
- g_signal_connect (e_table, "double_click", G_CALLBACK (e_calendar_table_on_double_click), cal_table);
- g_signal_connect (e_table, "right_click", G_CALLBACK (e_calendar_table_on_right_click), cal_table);
- g_signal_connect (e_table, "key_press", G_CALLBACK (e_calendar_table_on_key_press), cal_table);
- g_signal_connect (e_table, "popup_menu", G_CALLBACK (e_calendar_table_on_popup_menu), cal_table);
- g_signal_connect (e_table, "query-tooltip", G_CALLBACK (query_tooltip_cb), cal_table);
- gtk_widget_set_has_tooltip (GTK_WIDGET (e_table), TRUE);
+static void
+calendar_table_init (ECalendarTable *cal_table)
+{
+ cal_table->priv = E_CALENDAR_TABLE_GET_PRIVATE (cal_table);
+}
- a11y = gtk_widget_get_accessible ((GtkWidget *)e_table);
- if (a11y)
- atk_object_set_name (a11y, _("Tasks"));
+GType
+e_calendar_table_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ECalendarTableClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) calendar_table_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalendarTable),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) calendar_table_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "ECalendarTable", &type_info, 0);
+ }
+
+ return type;
}
/**
* e_calendar_table_new:
- * @Returns: a new #ECalendarTable.
+ * @shell_view: an #EShellView
+ * @model: an #ECalModel for the table
*
- * Creates a new #ECalendarTable.
+ * Returns a new #ECalendarTable.
+ *
+ * Returns: a new #ECalendarTable
**/
GtkWidget *
-e_calendar_table_new (void)
+e_calendar_table_new (EShellView *shell_view,
+ ECalModel *model)
{
- GtkWidget *cal_table;
-
- cal_table = GTK_WIDGET (g_object_new (e_calendar_table_get_type (), NULL));
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
- return cal_table;
+ return g_object_new (
+ E_TYPE_CALENDAR_TABLE,
+ "model", model, "shell-view", shell_view, NULL);
}
/**
@@ -752,25 +1006,9 @@ e_calendar_table_new (void)
ECalModel *
e_calendar_table_get_model (ECalendarTable *cal_table)
{
- g_return_val_if_fail (cal_table != NULL, NULL);
g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL);
- return cal_table->model;
-}
-
-static void
-e_calendar_table_destroy (GtkObject *object)
-{
- ECalendarTable *cal_table;
-
- cal_table = E_CALENDAR_TABLE (object);
-
- if (cal_table->model) {
- g_object_unref (cal_table->model);
- cal_table->model = NULL;
- }
-
- GTK_OBJECT_CLASS (e_calendar_table_parent_class)->destroy (object);
+ return cal_table->priv->model;
}
/**
@@ -785,37 +1023,21 @@ e_calendar_table_destroy (GtkObject *object)
ETable *
e_calendar_table_get_table (ECalendarTable *cal_table)
{
- g_return_val_if_fail (cal_table != NULL, NULL);
- g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL);
+ ETableScrolled *table_scrolled;
- return e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
-}
+ g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL);
-void
-e_calendar_table_open_selected (ECalendarTable *cal_table)
-{
- ECalModelComponent *comp_data;
- icalproperty *prop;
+ table_scrolled = E_TABLE_SCROLLED (cal_table->etable);
- comp_data = e_calendar_table_get_selected_comp (cal_table);
- prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY);
- if (comp_data != NULL)
- e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, prop ? TRUE : FALSE);
+ return e_table_scrolled_get_table (table_scrolled);
}
-/**
- * e_calendar_table_complete_selected:
- * @cal_table: A calendar table
- *
- * Marks the selected items as completed
- **/
-void
-e_calendar_table_complete_selected (ECalendarTable *cal_table)
+EShellView *
+e_calendar_table_get_shell_view (ECalendarTable *cal_table)
{
- g_return_if_fail (cal_table != NULL);
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
+ g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL);
- mark_as_complete_cb (NULL, NULL, cal_table);
+ return cal_table->priv->shell_view;
}
/* Used from e_table_selected_row_foreach(); puts the selected row number in an
@@ -830,16 +1052,19 @@ get_selected_row_cb (gint model_row, gpointer data)
*row = model_row;
}
-/* Returns the component that is selected in the table; only works if there is
+/*
+ * Returns the component that is selected in the table; only works if there is
* one and only one selected row.
*/
-ECalModelComponent *
-e_calendar_table_get_selected_comp (ECalendarTable *cal_table)
+static ECalModelComponent *
+get_selected_comp (ECalendarTable *cal_table)
{
+ ECalModel *model;
ETable *etable;
gint row;
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
+ model = e_calendar_table_get_model (cal_table);
+ etable = e_calendar_table_get_table (cal_table);
if (e_table_selected_count (etable) != 1)
return NULL;
@@ -849,7 +1074,7 @@ e_calendar_table_get_selected_comp (ECalendarTable *cal_table)
&row);
g_return_val_if_fail (row != -1, NULL);
- return e_cal_model_get_component_at (cal_table->model, row);
+ return e_cal_model_get_component_at (model, row);
}
struct get_selected_uids_closure {
@@ -861,40 +1086,27 @@ struct get_selected_uids_closure {
static void
add_uid_cb (gint model_row, gpointer data)
{
- struct get_selected_uids_closure *closure;
+ struct get_selected_uids_closure *closure = data;
ECalModelComponent *comp_data;
+ ECalModel *model;
- closure = data;
-
- comp_data = e_cal_model_get_component_at (closure->cal_table->model, model_row);
+ model = e_calendar_table_get_model (closure->cal_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
closure->objects = g_slist_prepend (closure->objects, comp_data);
}
-static GSList *
-get_selected_objects (ECalendarTable *cal_table)
-{
- struct get_selected_uids_closure closure;
- ETable *etable;
-
- closure.cal_table = cal_table;
- closure.objects = NULL;
-
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
- e_table_selected_row_foreach (etable, add_uid_cb, &closure);
-
- return closure.objects;
-}
-
/* Deletes all of the selected components in the table */
static void
delete_selected_components (ECalendarTable *cal_table)
{
GSList *objs, *l;
+ const gchar *status_message;
- objs = get_selected_objects (cal_table);
+ objs = e_calendar_table_get_selected (cal_table);
- e_calendar_table_set_status_message (cal_table, _("Deleting selected objects"), -1);
+ status_message = _("Deleting selected objects");
+ calendar_table_emit_status_message (cal_table, status_message, -1.0);
for (l = objs; l; l = l->next) {
ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
@@ -906,7 +1118,7 @@ delete_selected_components (ECalendarTable *cal_table)
g_clear_error (&error);
}
- e_calendar_table_set_status_message (cal_table, NULL, -1);
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
g_slist_free (objs);
}
@@ -967,14 +1179,14 @@ e_calendar_table_delete_selected (ECalendarTable *cal_table)
g_return_if_fail (cal_table != NULL);
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
+ etable = e_calendar_table_get_table (cal_table);
n_selected = e_table_selected_count (etable);
if (n_selected <= 0)
return;
if (n_selected == 1)
- comp_data = e_calendar_table_get_selected_comp (cal_table);
+ comp_data = get_selected_comp (cal_table);
else
comp_data = NULL;
@@ -1038,7 +1250,16 @@ e_calendar_table_delete_selected (ECalendarTable *cal_table)
GSList *
e_calendar_table_get_selected (ECalendarTable *cal_table)
{
- return get_selected_objects(cal_table);
+ struct get_selected_uids_closure closure;
+ ETable *etable;
+
+ closure.cal_table = cal_table;
+ closure.objects = NULL;
+
+ etable = e_calendar_table_get_table (cal_table);
+ e_table_selected_row_foreach (etable, add_uid_cb, &closure);
+
+ return closure.objects;
}
/**
@@ -1082,6 +1303,7 @@ copy_row_cb (gint model_row, gpointer data)
{
ECalendarTable *cal_table;
ECalModelComponent *comp_data;
+ ECalModel *model;
gchar *comp_str;
icalcomponent *child;
@@ -1089,7 +1311,8 @@ copy_row_cb (gint model_row, gpointer data)
g_return_if_fail (cal_table->tmp_vcal != NULL);
- comp_data = e_cal_model_get_component_at (cal_table->model, model_row);
+ model = e_calendar_table_get_model (cal_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
if (!comp_data)
return;
@@ -1125,17 +1348,18 @@ e_calendar_table_copy_clipboard (ECalendarTable *cal_table)
/* create temporary VCALENDAR object */
cal_table->tmp_vcal = e_cal_util_new_top_level ();
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
+ etable = e_calendar_table_get_table (cal_table);
e_table_selected_row_foreach (etable, copy_row_cb, cal_table);
comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal);
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom);
- if (!gtk_clipboard_set_with_data(clipboard, target_types, n_target_types,
- clipboard_get_calendar_cb,
- NULL, comp_str)) {
-
+ if (!gtk_clipboard_set_with_data (
+ clipboard, target_types, G_N_ELEMENTS (target_types),
+ clipboard_get_calendar_cb, NULL, comp_str)) {
/* no-op */
} else {
- gtk_clipboard_set_can_store (clipboard, target_types + 1, n_target_types - 1);
+ gtk_clipboard_set_can_store (
+ clipboard, target_types + 1,
+ G_N_ELEMENTS (target_types) - 1);
}
/* free memory */
@@ -1150,8 +1374,10 @@ clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text)
icalcomponent *icalcomp;
gchar *uid;
ECalComponent *comp;
+ ECalModel *model;
ECal *client;
icalcomponent_kind kind;
+ const gchar *status_message;
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
@@ -1171,9 +1397,11 @@ clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text)
return;
}
- client = e_cal_model_get_default_client (cal_table->model);
+ model = e_calendar_table_get_model (cal_table);
+ client = e_cal_model_get_default_client (model);
- e_calendar_table_set_status_message (cal_table, _("Updating objects"), -1);
+ status_message = _("Updating objects");
+ calendar_table_emit_status_message (cal_table, status_message, -1.0);
if (kind == ICAL_VCALENDAR_COMPONENT) {
icalcomponent_kind child_kind;
@@ -1218,7 +1446,7 @@ clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text)
g_object_unref (comp);
}
- e_calendar_table_set_status_message (cal_table, NULL, -1);
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
}
static void
@@ -1227,7 +1455,7 @@ clipboard_paste_received_cb (GtkClipboard *clipboard,
gpointer data)
{
ECalendarTable *cal_table = E_CALENDAR_TABLE (data);
- ETable *e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
+ ETable *e_table = e_calendar_table_get_table (cal_table);
GnomeCanvas *canvas = e_table->table_canvas;
GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item;
@@ -1262,446 +1490,15 @@ void
e_calendar_table_paste_clipboard (ECalendarTable *cal_table)
{
GtkClipboard *clipboard;
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom);
- g_object_ref (cal_table);
- gtk_clipboard_request_contents (clipboard,
- gdk_atom_intern (target_types[0].target, FALSE),
- clipboard_paste_received_cb, cal_table);
-}
-
-/* Opens a task in the task editor */
-void
-e_calendar_table_open_task (ECalendarTable *cal_table, ECal *client, icalcomponent *icalcomp, gboolean assign)
-{
- CompEditor *tedit;
- const gchar *uid;
- guint32 flags = 0;
-
- uid = icalcomponent_get_uid (icalcomp);
-
- tedit = e_comp_editor_registry_find (comp_editor_registry, uid);
- if (tedit == NULL) {
- ECalComponent *comp;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
-
- if (assign) {
- flags |= COMP_EDITOR_IS_ASSIGNED;
-
- if (itip_organizer_is_user (comp, client) ||
- !e_cal_component_has_attendees (comp))
- flags |= COMP_EDITOR_USER_ORG;
- }
-
- tedit = task_editor_new (client, flags);
- comp_editor_edit_comp (tedit, comp);
- g_object_unref (comp);
-
- if (flags & COMP_EDITOR_IS_ASSIGNED)
- task_editor_show_assignment (TASK_EDITOR (tedit));
-
- e_comp_editor_registry_add (comp_editor_registry, tedit, FALSE);
- }
- gtk_window_present (GTK_WINDOW (tedit));
-}
-
-/* Opens the task in the specified row */
-static void
-open_task_by_row (ECalendarTable *cal_table, gint row)
-{
- ECalModelComponent *comp_data;
- icalproperty *prop;
-
- comp_data = e_cal_model_get_component_at (cal_table->model, row);
- prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY);
- e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, prop ? TRUE : FALSE);
-}
-
-static void
-e_calendar_table_on_double_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- ECalendarTable *cal_table)
-{
- open_task_by_row (cal_table, row);
-}
-
-/* popup menu callbacks */
-
-static void
-e_calendar_table_on_open_task (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
- ECalModelComponent *comp_data;
- icalproperty *prop;
-
- comp_data = e_calendar_table_get_selected_comp (cal_table);
-
- if (!comp_data)
- return;
-
- prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY);
- e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, prop ? TRUE : FALSE);
-}
-
-static void
-e_calendar_table_on_save_as (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
- ECalModelComponent *comp_data;
- gchar *filename;
- gchar *ical_string;
-
- comp_data = e_calendar_table_get_selected_comp (cal_table);
- if (comp_data == NULL)
- return;
-
- filename = e_file_dialog_save (_("Save as..."), NULL);
- if (filename == NULL)
- return;
-
- ical_string = e_cal_get_component_as_string (comp_data->client, comp_data->icalcomp);
- if (ical_string == NULL) {
- g_warning ("Couldn't convert item to a string");
- return;
- }
-
- e_write_file_uri (filename, ical_string);
-
- g_free (ical_string);
-}
-
-static void
-e_calendar_table_on_print_task (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
- ECalModelComponent *comp_data;
- ECalComponent *comp;
-
- comp_data = e_calendar_table_get_selected_comp (cal_table);
- if (comp_data == NULL)
- return;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- print_comp (comp, comp_data->client, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-
- g_object_unref (comp);
-}
-
-static void
-e_calendar_table_on_cut (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
-
- e_calendar_table_cut_clipboard (cal_table);
-}
-
-static void
-e_calendar_table_on_copy (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
-
- e_calendar_table_copy_clipboard (cal_table);
-}
-
-static void
-e_calendar_table_on_paste (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
-
- e_calendar_table_paste_clipboard (cal_table);
-}
-
-static void
-e_calendar_table_on_assign (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
- ECalModelComponent *comp_data;
-
- comp_data = e_calendar_table_get_selected_comp (cal_table);
- if (comp_data)
- e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, TRUE);
-}
-
-static void
-e_calendar_table_on_forward (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
- ECalModelComponent *comp_data;
-
- comp_data = e_calendar_table_get_selected_comp (cal_table);
- if (comp_data) {
- ECalComponent *comp;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
-
- g_object_unref (comp);
- }
-}
-
-struct AffectedComponents {
- ECalendarTable *cal_table;
- GSList *components; /* contains pointers to ECalModelComponent */
-};
-
-/**
- * get_selected_components_cb
- * Helper function to fill list of selected components in ECalendarTable.
- * This function is called from e_table_selected_row_foreach.
- **/
-static void
-get_selected_components_cb (gint model_row, gpointer data)
-{
- struct AffectedComponents *ac = (struct AffectedComponents *) data;
-
- if (!ac || !ac->cal_table)
- return;
-
- ac->components = g_slist_prepend (ac->components, e_cal_model_get_component_at (E_CAL_MODEL (ac->cal_table->model), model_row));
-}
-
-/**
- * do_for_selected_components
- * Calls function func for all selected components in cal_table.
- *
- * @param cal_table Table with selected components of our interest
- * @param func Function to be called on each selected component from cal_table.
- * The first parameter of this function is a pointer to ECalModelComponent and
- * the second parameter of this function is pointer to cal_table
- **/
-static void
-do_for_selected_components (ECalendarTable *cal_table, GFunc func)
-{
- ETable *etable;
- struct AffectedComponents ac;
-
- g_return_if_fail (cal_table != NULL);
-
- ac.cal_table = cal_table;
- ac.components = NULL;
-
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
- e_table_selected_row_foreach (etable, get_selected_components_cb, &ac);
-
- g_slist_foreach (ac.components, func, cal_table);
- g_slist_free (ac.components);
-}
-
-/**
- * mark_comp_complete_cb
- * Function used in call to @ref do_for_selected_components to mark each component as complete
- **/
-static void
-mark_comp_complete_cb (gpointer data, gpointer user_data)
-{
- ECalendarTable *cal_table;
- ECalModelComponent *comp_data;
-
- comp_data = (ECalModelComponent *) data;
- cal_table = E_CALENDAR_TABLE (user_data);
-
- e_cal_model_tasks_mark_comp_complete (E_CAL_MODEL_TASKS (cal_table->model), comp_data);
-}
-
-/**
- * mark_comp_incomplete_cb
- * Function used in call to @ref do_for_selected_components to mark each component as incomplete
- **/
-static void
-mark_comp_incomplete_cb (gpointer data, gpointer user_data)
-{
- ECalendarTable *cal_table;
- ECalModelComponent *comp_data;
-
- comp_data = (ECalModelComponent *) data;
- cal_table = E_CALENDAR_TABLE (user_data);
-
- e_cal_model_tasks_mark_comp_incomplete (E_CAL_MODEL_TASKS (cal_table->model), comp_data);
-}
-
-/* Callback used for the "mark tasks as incomplete" menu item */
-static void
-mark_as_incomplete_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- do_for_selected_components (data, mark_comp_incomplete_cb);
-}
-
-/* Callback used for the "mark tasks as complete" menu item */
-static void
-mark_as_complete_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- do_for_selected_components (data, mark_comp_complete_cb);
-}
-
-/* Opens the URL of the task */
-static void
-open_url_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
- ECalModelComponent *comp_data;
- icalproperty *prop;
-
- comp_data = e_calendar_table_get_selected_comp (cal_table);
- if (!comp_data)
- return;
-
- prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY);
- if (!prop)
- return;
-
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, icalproperty_get_url (prop));
-}
-
-/* Opens a new task editor */
-static void
-on_new_task (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
- ETasks *tasks = g_object_get_data (G_OBJECT (cal_table), "tasks");
-
- if (!tasks)
- return;
-
- e_tasks_new_task (tasks);
-
-}
-
-/* Callback for the "delete tasks" menu item */
-static void
-delete_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarTable *cal_table = data;
-
- e_calendar_table_delete_selected (cal_table);
-}
-
-static EPopupItem tasks_popup_items [] = {
- { E_POPUP_ITEM, (gchar *) "00.newtask", (gchar *) N_("New _Task"), on_new_task, NULL, (gchar *) "stock_task", 0, 0},
- { E_POPUP_BAR, (gchar *) "01.bar" },
-
- { E_POPUP_ITEM, (gchar *) "03.open", (gchar *) N_("_Open"), e_calendar_table_on_open_task, NULL, (gchar *) GTK_STOCK_OPEN, E_CAL_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "05.openweb", (gchar *) N_("Open _Web Page"), open_url_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_HASURL },
- { E_POPUP_ITEM, (gchar *) "10.saveas", (gchar *) N_("_Save As..."), e_calendar_table_on_save_as, NULL, (gchar *) GTK_STOCK_SAVE_AS, E_CAL_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "20.print", (gchar *) N_("P_rint..."), e_calendar_table_on_print_task, NULL, (gchar *) GTK_STOCK_PRINT, E_CAL_POPUP_SELECT_ONE },
-
- { E_POPUP_BAR, (gchar *) "30.bar" },
-
- { E_POPUP_ITEM, (gchar *) "40.cut", (gchar *) N_("C_ut"), e_calendar_table_on_cut, NULL, (gchar *) GTK_STOCK_CUT, 0, E_CAL_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "50.copy", (gchar *) N_("_Copy"), e_calendar_table_on_copy, NULL, (gchar *) GTK_STOCK_COPY, 0, 0 },
- { E_POPUP_ITEM, (gchar *) "60.paste", (gchar *) N_("_Paste"), e_calendar_table_on_paste, NULL, (gchar *) GTK_STOCK_PASTE, 0, E_CAL_POPUP_SELECT_EDITABLE },
-
- { E_POPUP_BAR, (gchar *) "70.bar" },
-
- { E_POPUP_ITEM, (gchar *) "80.assign", (gchar *) N_("_Assign Task"), e_calendar_table_on_assign, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE|E_CAL_POPUP_SELECT_ASSIGNABLE },
- { E_POPUP_ITEM, (gchar *) "90.forward", (gchar *) N_("_Forward as iCalendar"), e_calendar_table_on_forward, NULL, (gchar *) "mail-forward", E_CAL_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "a0.markonecomplete", (gchar *) N_("_Mark as Complete"), mark_as_complete_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_NOTCOMPLETE},
- { E_POPUP_ITEM, (gchar *) "b0.markmanycomplete", (gchar *) N_("_Mark Selected Tasks as Complete"), mark_as_complete_cb, NULL, NULL, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_NOTCOMPLETE },
- { E_POPUP_ITEM, (gchar *) "c0.markoneincomplete", (gchar *) N_("_Mark as Incomplete"), mark_as_incomplete_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE|E_CAL_POPUP_SELECT_COMPLETE},
- { E_POPUP_ITEM, (gchar *) "d0.markmanyincomplete", (gchar *) N_("_Mark Selected Tasks as Incomplete"), mark_as_incomplete_cb, NULL, NULL, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_COMPLETE },
-
- { E_POPUP_BAR, (gchar *) "e0.bar" },
-
- { E_POPUP_ITEM, (gchar *) "f0.delete", (gchar *) N_("_Delete"), delete_cb, NULL, (gchar *) GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "g0.deletemany", (gchar *) N_("_Delete Selected Tasks"), delete_cb, NULL, (gchar *) GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE },
-};
-
-static void
-ect_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static gint
-e_calendar_table_show_popup_menu (ETable *table,
- GdkEvent *gdk_event,
- ECalendarTable *cal_table)
-{
- GtkMenu *menu;
- GSList *selection, *l, *menus = NULL;
- GPtrArray *events;
- ECalPopup *ep;
- ECalPopupTargetSelect *t;
- gint i;
-
- selection = get_selected_objects (cal_table);
- if (!selection)
- return TRUE;
-
- /** @HookPoint-ECalPopup: Tasks Table Context Menu
- * @Id: org.gnome.evolution.tasks.table.popup
- * @Class: org.gnome.evolution.calendar.popup:1.0
- * @Target: ECalPopupTargetSelect
- *
- * The context menu on the tasks table.
- */
- ep = e_cal_popup_new("org.gnome.evolution.tasks.table.popup");
-
- events = g_ptr_array_new();
- for (l=selection;l;l=g_slist_next(l))
- g_ptr_array_add(events, e_cal_model_copy_component_data((ECalModelComponent *)l->data));
- g_slist_free(selection);
-
- t = e_cal_popup_target_new_select(ep, cal_table->model, events);
- t->target.widget = (GtkWidget *)cal_table;
-
- for (i=0;i<sizeof(tasks_popup_items)/sizeof(tasks_popup_items[0]);i++)
- menus = g_slist_prepend(menus, &tasks_popup_items[i]);
- e_popup_add_items((EPopup *)ep, menus, NULL, ect_popup_free, cal_table);
-
- menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
-
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0,
- gdk_event?gdk_event->button.time:gtk_get_current_event_time());
-
- return TRUE;
-}
-
-static gint
-e_calendar_table_on_right_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- ECalendarTable *cal_table)
-{
- return e_calendar_table_show_popup_menu (table, event, cal_table);
-}
+ g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-static gboolean
-e_calendar_table_on_popup_menu (GtkWidget *widget, gpointer data)
-{
- ETable *table = E_TABLE(widget);
- g_return_val_if_fail(table, FALSE);
+ clipboard = gtk_widget_get_clipboard (
+ GTK_WIDGET (cal_table), clipboard_atom);
- return e_calendar_table_show_popup_menu (table, NULL,
- E_CALENDAR_TABLE(data));
-}
-
-static gint
-e_calendar_table_on_key_press (ETable *table,
- gint row,
- gint col,
- GdkEventKey *event,
- ECalendarTable *cal_table)
-{
- if (event->keyval == GDK_Delete) {
- delete_cb (NULL, NULL, cal_table);
- return TRUE;
- } else if ((event->keyval == GDK_o)
- &&(event->state & GDK_CONTROL_MASK)) {
- open_task_by_row (cal_table, row);
- return TRUE;
- }
-
- return FALSE;
+ gtk_clipboard_request_contents (
+ clipboard, gdk_atom_intern (target_types[0].target, FALSE),
+ clipboard_paste_received_cb, g_object_ref (cal_table));
}
static void
@@ -1792,28 +1589,30 @@ show_completed_rows (ECalModel *model, GList *clients_list, gchar *show_sexp, GP
/* Loads the state of the table (headers shown etc.) from the given file. */
void
-e_calendar_table_load_state (ECalendarTable *cal_table,
- gchar *filename)
+e_calendar_table_load_state (ECalendarTable *cal_table,
+ const gchar *filename)
{
- struct stat st;
+ ETable *table;
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
+ g_return_if_fail (filename != NULL);
- if (g_stat (filename, &st) == 0 && st.st_size > 0
- && S_ISREG (st.st_mode)) {
- e_table_load_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)), filename);
- }
+ table = e_calendar_table_get_table (cal_table);
+ e_table_load_state (table, filename);
}
/* Saves the state of the table (headers shown etc.) to the given file. */
void
-e_calendar_table_save_state (ECalendarTable *cal_table,
- gchar *filename)
+e_calendar_table_save_state (ECalendarTable *cal_table,
+ const gchar *filename)
{
+ ETable *table;
+
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
+ g_return_if_fail (filename != NULL);
- e_table_save_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)),
- filename);
+ table = e_calendar_table_get_table (cal_table);
+ e_table_save_state (table, filename);
}
/* Returns the current time, for the ECellDateEdit items.
@@ -1822,12 +1621,15 @@ e_calendar_table_save_state (ECalendarTable *cal_table,
static struct tm
e_calendar_table_get_current_time (ECellDateEdit *ecde, gpointer data)
{
+ ECalendarTable *cal_table = data;
+ ECalModel *model;
icaltimezone *zone;
struct tm tmp_tm = { 0 };
struct icaltimetype tt;
/* Get the current timezone. */
- zone = calendar_config_get_icaltimezone ();
+ model = e_calendar_table_get_model (cal_table);
+ zone = e_cal_model_get_timezone (model);
tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
@@ -1843,56 +1645,6 @@ e_calendar_table_get_current_time (ECellDateEdit *ecde, gpointer data)
return tmp_tm;
}
-#ifdef TRANSLATORS_ONLY
-
-static gchar *test[] = {
- N_("Click to add a task")
-};
-
-#endif
-
-void
-e_calendar_table_set_activity_handler (ECalendarTable *cal_table, EActivityHandler *activity_handler)
-{
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- cal_table->activity_handler = activity_handler;
-}
-
-void
-e_calendar_table_set_status_message (ECalendarTable *cal_table, const gchar *message, gint percent)
-{
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- if (!cal_table->activity_handler)
- return;
-
- if (!message || !*message) {
- if (cal_table->activity_id != 0) {
- e_activity_handler_operation_finished (cal_table->activity_handler, cal_table->activity_id);
- cal_table->activity_id = 0;
- }
- } else if (cal_table->activity_id == 0) {
- gchar *client_id = g_strdup_printf ("%p", (gpointer) cal_table);
-
- cal_table->activity_id = e_activity_handler_operation_started (
- cal_table->activity_handler, client_id, message, TRUE);
-
- g_free (client_id);
- } else {
-
- double progress;
-
- if (percent < 0)
- progress = -1.0;
- else {
- progress = ((double) percent / 100);
- }
-
- e_activity_handler_operation_progressing (cal_table->activity_handler, cal_table->activity_id, message, progress);
- }
-}
-
/**
* e_calendar_table_hide_completed_tasks:
* @table: A calendar table model.
@@ -1901,7 +1653,9 @@ e_calendar_table_set_status_message (ECalendarTable *cal_table, const gchar *mes
* Hide completed tasks.
*/
void
-e_calendar_table_process_completed_tasks (ECalendarTable *table, GList *clients_list, gboolean config_changed)
+e_calendar_table_process_completed_tasks (ECalendarTable *table,
+ GList *clients_list,
+ gboolean config_changed)
{
ECalModel *model;
static GMutex *mutex = NULL;
diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h
index 0abcd4be0e..d2b376ba9d 100644
--- a/calendar/gui/e-calendar-table.h
+++ b/calendar/gui/e-calendar-table.h
@@ -23,31 +23,43 @@
#ifndef _E_CALENDAR_TABLE_H_
#define _E_CALENDAR_TABLE_H_
-#include <gtk/gtk.h>
+#include <shell/e-shell-view.h>
#include <table/e-table-scrolled.h>
-#include <misc/e-cell-date-edit.h>
-#include "e-activity-handler.h"
+#include <table/e-cell-date-edit.h>
#include "e-cal-model.h"
-G_BEGIN_DECLS
-
/*
* ECalendarTable - displays the iCalendar objects in a table (an ETable).
* Used for calendar events and tasks.
*/
-#define E_CALENDAR_TABLE(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_calendar_table_get_type (), ECalendarTable)
-#define E_CALENDAR_TABLE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_calendar_table_get_type (), ECalendarTableClass)
-#define E_IS_CALENDAR_TABLE(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_calendar_table_get_type ())
+/* Standard GObject macros */
+#define E_TYPE_CALENDAR_TABLE \
+ (e_calendar_table_get_type ())
+#define E_CALENDAR_TABLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CALENDAR_TABLE, ECalendarTable))
+#define E_CALENDAR_TABLE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CALENDAR_TABLE, ECalendarTableClass))
+#define E_IS_CALENDAR_TABLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CALENDAR_TABLE))
+#define E_IS_CALENDAR_TABLE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CALENDAR_TABLE))
+#define E_CALENDAR_TABLE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CALENDAR_TABLE, ECalendarTableClass))
-typedef struct _ECalendarTable ECalendarTable;
-typedef struct _ECalendarTableClass ECalendarTableClass;
+G_BEGIN_DECLS
-struct _ECalendarTable {
- GtkTable table;
+typedef struct _ECalendarTable ECalendarTable;
+typedef struct _ECalendarTableClass ECalendarTableClass;
+typedef struct _ECalendarTablePrivate ECalendarTablePrivate;
- /* The model that we use */
- ECalModel *model;
+struct _ECalendarTable {
+ GtkTable parent;
GtkWidget *etable;
@@ -57,62 +69,55 @@ struct _ECalendarTable {
/* Fields used for cut/copy/paste */
icalcomponent *tmp_vcal;
- /* Activity ID for the EActivityHandler (i.e. the status bar). */
- EActivityHandler *activity_handler;
- guint activity_id;
-
- /* We should know which calendar has been used to create object, so store it here
- before emitting "user_created" signal and make it NULL just after the emit. */
- ECal *user_created_cal;
+ ECalendarTablePrivate *priv;
};
struct _ECalendarTableClass {
GtkTableClass parent_class;
- /* Notification signals */
- void (* user_created) (ECalendarTable *cal_table);
+ /* Signals */
+ void (*open_component) (ECalendarTable *cal_table,
+ ECalModelComponent *comp_data);
+ void (*popup_event) (ECalendarTable *cal_table,
+ GdkEvent *event);
+ void (*status_message) (ECalendarTable *cal_table,
+ const gchar *message,
+ gdouble percent);
+ void (*user_created) (ECalendarTable *cal_table);
};
-GType e_calendar_table_get_type (void);
-GtkWidget* e_calendar_table_new (void);
-
-ECalModel *e_calendar_table_get_model (ECalendarTable *cal_table);
-
-ETable *e_calendar_table_get_table (ECalendarTable *cal_table);
-
-void e_calendar_table_open_selected (ECalendarTable *cal_table);
-void e_calendar_table_complete_selected (ECalendarTable *cal_table);
-void e_calendar_table_delete_selected (ECalendarTable *cal_table);
-
-GSList *e_calendar_table_get_selected (ECalendarTable *cal_table);
+GType e_calendar_table_get_type (void);
+GtkWidget * e_calendar_table_new (EShellView *shell_view,
+ ECalModel *model);
+ECalModel * e_calendar_table_get_model (ECalendarTable *cal_table);
+ETable * e_calendar_table_get_table (ECalendarTable *cal_table);
+EShellView * e_calendar_table_get_shell_view (ECalendarTable *cal_table);
+void e_calendar_table_delete_selected(ECalendarTable *cal_table);
+GSList * e_calendar_table_get_selected (ECalendarTable *cal_table);
/* Clipboard related functions */
-void e_calendar_table_cut_clipboard (ECalendarTable *cal_table);
-void e_calendar_table_copy_clipboard (ECalendarTable *cal_table);
-void e_calendar_table_paste_clipboard (ECalendarTable *cal_table);
+void e_calendar_table_cut_clipboard (ECalendarTable *cal_table);
+void e_calendar_table_copy_clipboard (ECalendarTable *cal_table);
+void e_calendar_table_paste_clipboard(ECalendarTable *cal_table);
/* These load and save the state of the table (headers shown etc.) to/from
the given file. */
-void e_calendar_table_load_state (ECalendarTable *cal_table,
- gchar *filename);
-void e_calendar_table_save_state (ECalendarTable *cal_table,
- gchar *filename);
-
-void e_calendar_table_set_activity_handler (ECalendarTable *cal_table,
- EActivityHandler *activity_handler);
-void e_calendar_table_set_status_message (ECalendarTable *cal_table,
- const gchar *message,
- gint percent);
-void e_calendar_table_open_task (ECalendarTable *cal_table,
- ECal *client,
- icalcomponent *icalcomp,
- gboolean assign);
-ECalModelComponent * e_calendar_table_get_selected_comp (ECalendarTable *cal_table);
-void e_calendar_table_hide_completed_tasks (ECalendarTable *table, GList *clients_list, gboolean config_changed);
-
-void e_calendar_table_process_completed_tasks (ECalendarTable *table, GList *clients_list, gboolean config_changed);
-
-gboolean ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, GtkWidget *etable_wgt, ECalModel *model);
+void e_calendar_table_load_state (ECalendarTable *cal_table,
+ const gchar *filename);
+void e_calendar_table_save_state (ECalendarTable *cal_table,
+ const gchar *filename);
+
+ECalModelComponent *
+ e_calendar_table_get_selected_comp
+ (ECalendarTable *cal_table);
+void e_calendar_table_hide_completed_tasks
+ (ECalendarTable *table,
+ GList *clients_list,
+ gboolean config_changed);
+void e_calendar_table_process_completed_tasks
+ (ECalendarTable *table,
+ GList *clients_list,
+ gboolean config_changed);
G_END_DECLS
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index 286db6b5f1..7450cd1221 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -38,15 +38,14 @@
#include <e-util/e-icon-factory.h>
#include <libecal/e-cal-time-util.h>
#include <libecal/e-cal-component.h>
+#include <shell/e-shell.h>
#include "common/authentication.h"
-#include "calendar-commands.h"
-#include "calendar-component.h"
#include "calendar-config.h"
#include "comp-util.h"
+#include "ea-calendar.h"
#include "e-cal-model-calendar.h"
#include "e-calendar-view.h"
-#include "e-comp-editor-registry.h"
#include "itip-utils.h"
#include "dialogs/comp-editor-util.h"
#include "dialogs/delete-comp.h"
@@ -58,10 +57,12 @@
#include "dialogs/select-source-dialog.h"
#include "print.h"
#include "goto.h"
-#include "ea-calendar.h"
-#include "e-cal-popup.h"
#include "misc.h"
+#define E_CALENDAR_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CALENDAR_VIEW, ECalendarViewPrivate))
+
struct _ECalendarViewPrivate {
/* The GnomeCalendar we are associated to */
GnomeCalendar *calendar;
@@ -69,22 +70,11 @@ struct _ECalendarViewPrivate {
/* The calendar model we are monitoring */
ECalModel *model;
- /* Current activity (for the EActivityHandler, i.e. the status bar). */
- EActivityHandler *activity_handler;
- guint activity_id;
-
/* The default category */
gchar *default_category;
};
-static void e_calendar_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
-static void e_calendar_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
-static void e_calendar_view_destroy (GtkObject *object);
-
-extern ECompEditorRegistry *comp_editor_registry;
-
-/* Property IDs */
-enum props {
+enum {
PROP_0,
PROP_MODEL
};
@@ -92,6 +82,7 @@ enum props {
/* FIXME Why are we emitting these event signals here? Can't the model just be listened to? */
/* Signal IDs */
enum {
+ POPUP_EVENT,
SELECTION_CHANGED,
SELECTED_TIME_CHANGED,
TIMEZONE_CHANGED,
@@ -102,7 +93,7 @@ enum {
LAST_SIGNAL
};
-static guint e_calendar_view_signals[LAST_SIGNAL] = { 0 };
+static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE (ECalendarView, e_calendar_view, GTK_TYPE_TABLE)
@@ -115,151 +106,227 @@ static GtkTargetEntry target_types[] = {
{ (gchar *) "text/calendar", 0, TARGET_TYPE_VCALENDAR }
};
-static guint n_target_types = G_N_ELEMENTS (target_types);
+static void
+calendar_view_set_model (ECalendarView *calendar_view,
+ ECalModel *model)
+{
+ g_return_if_fail (calendar_view->priv->model == NULL);
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+
+ calendar_view->priv->model = g_object_ref (model);
+}
static void
-e_calendar_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+calendar_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- ECalendarView *cal_view;
+ switch (property_id) {
+ case PROP_MODEL:
+ calendar_view_set_model (
+ E_CALENDAR_VIEW (object),
+ g_value_get_object (value));
+ return;
+ }
- cal_view = E_CALENDAR_VIEW (object);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+static void
+calendar_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
switch (property_id) {
- case PROP_MODEL:
- e_calendar_view_set_model (cal_view, E_CAL_MODEL (g_value_get_object (value)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
+ case PROP_MODEL:
+ g_value_set_object (
+ value, e_calendar_view_get_model (
+ E_CALENDAR_VIEW (object)));
+ return;
}
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_calendar_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+calendar_view_dispose (GObject *object)
{
- ECalendarView *cal_view;
+ ECalendarViewPrivate *priv;
- cal_view = E_CALENDAR_VIEW (object);
+ priv = E_CALENDAR_VIEW_GET_PRIVATE (object);
- switch (property_id) {
- case PROP_MODEL:
- g_value_set_object (value, e_calendar_view_get_model (cal_view));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
+ if (priv->model != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->model, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->model);
+ priv->model = NULL;
}
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_calendar_view_parent_class)->dispose (object);
}
static void
-e_calendar_view_class_init (ECalendarViewClass *klass)
+calendar_view_finalize (GObject *object)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
+ ECalendarViewPrivate *priv;
+
+ priv = E_CALENDAR_VIEW_GET_PRIVATE (object);
+ g_free (priv->default_category);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_calendar_view_parent_class)->finalize (object);
+}
+
+static void
+e_calendar_view_class_init (ECalendarViewClass *class)
+{
+ GObjectClass *object_class;
GtkBindingSet *binding_set;
- /* Method override */
- gobject_class->set_property = e_calendar_view_set_property;
- gobject_class->get_property = e_calendar_view_get_property;
- object_class->destroy = e_calendar_view_destroy;
-
- klass->selection_changed = NULL;
- klass->selected_time_changed = NULL;
- klass->event_changed = NULL;
- klass->event_added = NULL;
- klass->user_created = NULL;
-
- klass->get_selected_events = NULL;
- klass->get_selected_time_range = NULL;
- klass->set_selected_time_range = NULL;
- klass->get_visible_time_range = NULL;
- klass->update_query = NULL;
- klass->open_event = e_calendar_view_open_event;
- klass->paste_text = NULL;
-
- g_object_class_install_property (gobject_class, PROP_MODEL,
- g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL,
- G_PARAM_READABLE | G_PARAM_WRITABLE));
-
- /* Create class' signals */
- e_calendar_view_signals[SELECTION_CHANGED] =
- g_signal_new ("selection_changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ECalendarViewClass, selection_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- e_calendar_view_signals[SELECTED_TIME_CHANGED] =
- g_signal_new ("selected_time_changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ECalendarViewClass, selected_time_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- e_calendar_view_signals[TIMEZONE_CHANGED] =
- g_signal_new ("timezone_changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ECalendarViewClass, timezone_changed),
- NULL, NULL,
- e_marshal_VOID__POINTER_POINTER,
- G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
-
- e_calendar_view_signals[EVENT_CHANGED] =
- g_signal_new ("event_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (ECalendarViewClass, event_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
-
- e_calendar_view_signals[EVENT_ADDED] =
- g_signal_new ("event_added",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (ECalendarViewClass, event_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
-
- e_calendar_view_signals[USER_CREATED] =
- g_signal_new ("user_created",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ECalendarViewClass, user_created),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- e_calendar_view_signals[OPEN_EVENT] =
- g_signal_new ("open_event",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (ECalendarViewClass, open_event),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ g_type_class_add_private (class, sizeof (ECalendarViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = calendar_view_set_property;
+ object_class->get_property = calendar_view_get_property;
+ object_class->dispose = calendar_view_dispose;
+ object_class->finalize = calendar_view_finalize;
+
+ class->selection_changed = NULL;
+ class->selected_time_changed = NULL;
+ class->event_changed = NULL;
+ class->event_added = NULL;
+ class->user_created = NULL;
+
+ class->get_selected_events = NULL;
+ class->get_selected_time_range = NULL;
+ class->set_selected_time_range = NULL;
+ class->get_visible_time_range = NULL;
+ class->update_query = NULL;
+ class->open_event = e_calendar_view_open_event;
+ class->paste_text = NULL;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ "Model",
+ NULL,
+ E_TYPE_CAL_MODEL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (ECalendarViewClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ signals[SELECTION_CHANGED] = g_signal_new (
+ "selection-changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ECalendarViewClass, selection_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SELECTED_TIME_CHANGED] = g_signal_new (
+ "selected-time-changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ECalendarViewClass, selected_time_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[TIMEZONE_CHANGED] = g_signal_new (
+ "timezone-changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ECalendarViewClass, timezone_changed),
+ NULL, NULL,
+ e_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ signals[EVENT_CHANGED] = g_signal_new (
+ "event-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ECalendarViewClass, event_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[EVENT_ADDED] = g_signal_new (
+ "event-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ECalendarViewClass, event_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[USER_CREATED] = g_signal_new (
+ "user-created",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ECalendarViewClass, user_created),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[OPEN_EVENT] = g_signal_new (
+ "open-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ECalendarViewClass, open_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
/*
* Key bindings
*/
- binding_set = gtk_binding_set_by_class (klass);
+ binding_set = gtk_binding_set_by_class (class);
- gtk_binding_entry_add_signal (binding_set, GDK_o,
- GDK_CONTROL_MASK,
- "open_event", 0);
+ gtk_binding_entry_add_signal (
+ binding_set, GDK_o, GDK_CONTROL_MASK, "open-event", 0);
/* init the accessibility support for e_day_view */
e_cal_view_a11y_init ();
}
+static void
+e_calendar_view_init (ECalendarView *calendar_view)
+{
+ calendar_view->priv = E_CALENDAR_VIEW_GET_PRIVATE (calendar_view);
+}
+
+void
+e_calendar_view_popup_event (ECalendarView *calendar_view,
+ GdkEventButton *event)
+{
+ g_return_if_fail (E_IS_CALENDAR_VIEW (calendar_view));
+ g_return_if_fail (event != NULL);
+
+ g_signal_emit (calendar_view, signals[POPUP_EVENT], 0, event);
+}
+
void
e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart,
icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas)
@@ -383,41 +450,6 @@ e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart
g_object_unref (comp);
}
-static void
-e_calendar_view_init (ECalendarView *cal_view)
-{
- cal_view->priv = g_new0 (ECalendarViewPrivate, 1);
-}
-
-static void
-e_calendar_view_destroy (GtkObject *object)
-{
- ECalendarView *cal_view = (ECalendarView *) object;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- if (cal_view->priv) {
- if (cal_view->priv->model) {
- g_signal_handlers_disconnect_matched (cal_view->priv->model,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, cal_view);
- g_object_unref (cal_view->priv->model);
- cal_view->priv->model = NULL;
- }
-
- if (cal_view->priv->default_category) {
- g_free (cal_view->priv->default_category);
- cal_view->priv->default_category = NULL;
- }
-
- g_free (cal_view->priv);
- cal_view->priv = NULL;
- }
-
- if (GTK_OBJECT_CLASS (e_calendar_view_parent_class)->destroy)
- GTK_OBJECT_CLASS (e_calendar_view_parent_class)->destroy (object);
-}
-
GnomeCalendar *
e_calendar_view_get_calendar (ECalendarView *cal_view)
{
@@ -442,21 +474,6 @@ e_calendar_view_get_model (ECalendarView *cal_view)
return cal_view->priv->model;
}
-void
-e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model)
-{
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
- g_return_if_fail (E_IS_CAL_MODEL (model));
-
- if (cal_view->priv->model) {
- g_signal_handlers_disconnect_matched (cal_view->priv->model, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, cal_view);
- g_object_unref (cal_view->priv->model);
- }
-
- cal_view->priv->model = g_object_ref (model);
-}
-
icaltimezone *
e_calendar_view_get_timezone (ECalendarView *cal_view)
{
@@ -476,7 +493,7 @@ e_calendar_view_set_timezone (ECalendarView *cal_view, icaltimezone *zone)
return;
e_cal_model_set_timezone (cal_view->priv->model, zone);
- g_signal_emit (G_OBJECT (cal_view), e_calendar_view_signals[TIMEZONE_CHANGED], 0,
+ g_signal_emit (G_OBJECT (cal_view), signals[TIMEZONE_CHANGED], 0,
old_zone, zone);
}
@@ -506,142 +523,75 @@ e_calendar_view_set_default_category (ECalendarView *cal_view, const gchar *cate
cal_view->priv->default_category = g_strdup (category);
}
-/**
- * e_calendar_view_get_use_24_hour_format:
- * @cal_view: A calendar view.
- *
- * Gets whether the view is using 24 hour times or not.
- *
- * Returns: the 24 hour setting.
- */
-gboolean
-e_calendar_view_get_use_24_hour_format (ECalendarView *cal_view)
-{
- g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE);
-
- return e_cal_model_get_use_24_hour_format (cal_view->priv->model);
-}
-
-/**
- * e_calendar_view_set_use_24_hour_format
- * @cal_view: A calendar view.
- * @use_24_hour: Whether to use 24 hour times or not.
- *
- * Sets the 12/24 hour times setting for the given view.
- */
-void
-e_calendar_view_set_use_24_hour_format (ECalendarView *cal_view, gboolean use_24_hour)
-{
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- e_cal_model_set_use_24_hour_format (cal_view->priv->model, use_24_hour);
-}
-
-void
-e_calendar_view_set_activity_handler (ECalendarView *cal_view, EActivityHandler *activity_handler)
-{
- ECalendarViewPrivate *priv;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- priv = cal_view->priv;
-
- priv->activity_handler = activity_handler;
-}
-
-void
-e_calendar_view_set_status_message (ECalendarView *cal_view, const gchar *message, gint percent)
-{
- ECalendarViewPrivate *priv;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- priv = cal_view->priv;
-
- if (!priv->activity_handler)
- return;
-
- if (!message || !*message) {
- if (priv->activity_id != 0) {
- e_activity_handler_operation_finished (priv->activity_handler, priv->activity_id);
- priv->activity_id = 0;
- }
- } else if (priv->activity_id == 0) {
- gchar *client_id = g_strdup_printf ("%p", (gpointer) cal_view);
-
- priv->activity_id = e_activity_handler_operation_started (
- priv->activity_handler, client_id, message, TRUE);
-
- g_free (client_id);
- } else {
- double progress;
-
- if (percent < 0)
- progress = -1.0;
- else {
- progress = ((double) percent / 100);
- }
-
- e_activity_handler_operation_progressing (priv->activity_handler, priv->activity_id, message, progress);
- }
-}
-
GList *
e_calendar_view_get_selected_events (ECalendarView *cal_view)
{
+ ECalendarViewClass *class;
+
g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL);
- if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_events)
- return E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_events (cal_view);
+ class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_val_if_fail (class->get_selected_events != NULL, NULL);
- return NULL;
+ return class->get_selected_events (cal_view);
}
gboolean
-e_calendar_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time)
+e_calendar_view_get_selected_time_range (ECalendarView *cal_view,
+ time_t *start_time,
+ time_t *end_time)
{
+ ECalendarViewClass *class;
+
g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE);
- if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_time_range) {
- return E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_time_range (
- cal_view, start_time, end_time);
- }
+ class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_val_if_fail (class->get_selected_time_range != NULL, FALSE);
- return FALSE;
+ return class->get_selected_time_range (cal_view, start_time, end_time);
}
void
-e_calendar_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time)
+e_calendar_view_set_selected_time_range (ECalendarView *cal_view,
+ time_t start_time,
+ time_t end_time)
{
+ ECalendarViewClass *class;
+
g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
- if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->set_selected_time_range) {
- E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->set_selected_time_range (
- cal_view, start_time, end_time);
- }
+ class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_if_fail (class->set_selected_time_range != NULL);
+
+ class->set_selected_time_range (cal_view, start_time, end_time);
}
gboolean
-e_calendar_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time)
+e_calendar_view_get_visible_time_range (ECalendarView *cal_view,
+ time_t *start_time,
+ time_t *end_time)
{
+ ECalendarViewClass *class;
+
g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE);
- if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_visible_time_range) {
- return E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_visible_time_range (
- cal_view, start_time, end_time);
- }
+ class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_val_if_fail (class->get_visible_time_range != NULL, FALSE);
- return FALSE;
+ return class->get_visible_time_range (cal_view, start_time, end_time);
}
void
e_calendar_view_update_query (ECalendarView *cal_view)
{
+ ECalendarViewClass *class;
+
g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
- if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->update_query) {
- E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->update_query (cal_view);
- }
+ class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_if_fail (class->update_query != NULL);
+
+ class->update_query (cal_view);
}
void
@@ -656,7 +606,9 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view)
if (!selected)
return;
+#if 0 /* KILL-BONOBO */
e_calendar_view_set_status_message (cal_view, _("Deleting selected objects"), -1);
+#endif
e_calendar_view_copy_clipboard (cal_view);
for (l = selected; l != NULL; l = l->next) {
@@ -701,7 +653,9 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view)
g_object_unref (comp);
}
+#if 0 /* KILL-BONOBO */
e_calendar_view_set_status_message (cal_view, NULL, -1);
+#endif
g_list_free (selected);
}
@@ -828,13 +782,13 @@ e_calendar_view_copy_clipboard (ECalendarView *cal_view)
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_view), GDK_SELECTION_CLIPBOARD);
comp_str = icalcomponent_as_ical_string_r (vcal_comp);
- if (!gtk_clipboard_set_with_data (clipboard, target_types, n_target_types,
+ if (!gtk_clipboard_set_with_data (clipboard, target_types, G_N_ELEMENTS (target_types),
clipboard_get_calendar_cb,
clipboard_clear_calendar_cb,
comp_str)) {
g_free (comp_str);
} else {
- gtk_clipboard_set_can_store (clipboard, target_types + 1, n_target_types - 1);
+ gtk_clipboard_set_can_store (clipboard, target_types + 1, G_N_ELEMENTS (target_types) - 1);
}
/* free memory */
@@ -870,7 +824,9 @@ clipboard_get_calendar_data (ECalendarView *cal_view, const gchar *text)
if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
return;
+#if 0 /* KILL-BONOBO */
e_calendar_view_set_status_message (cal_view, _("Updating objects"), -1);
+#endif
e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
if ((selected_time_end - selected_time_start) == 60 * 60 * 24)
@@ -918,16 +874,22 @@ clipboard_get_calendar_data (ECalendarView *cal_view, const gchar *text)
e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, in_top_canvas);
}
+#if 0 /* KILL-BONOBO */
e_calendar_view_set_status_message (cal_view, NULL, -1);
+#endif
}
static void
e_calendar_view_paste_text (ECalendarView *cal_view)
{
+ ECalendarViewClass *class;
+
g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
- if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->paste_text)
- E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->paste_text (cal_view);
+ class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_if_fail (class->paste_text != NULL);
+
+ class->paste_text (cal_view);
}
static void
@@ -1240,660 +1202,6 @@ e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view)
g_object_unref (comp);
}
-static void
-on_new_appointment (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- e_calendar_view_new_appointment (cal_view);
-}
-
-static void
-on_new_event (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- e_calendar_view_new_appointment_full (cal_view, TRUE, FALSE, FALSE);
-}
-
-static void
-on_new_meeting (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- e_calendar_view_new_appointment_full (cal_view, FALSE, TRUE, FALSE);
-}
-
-static void
-on_new_task (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- time_t dtstart, dtend;
-
- e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_task (cal_view->priv->calendar, &dtstart, &dtend);
-}
-
-static void
-on_goto_date (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- goto_dialog (cal_view->priv->calendar);
-}
-
-static void
-on_goto_today (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- calendar_goto_today (cal_view->priv->calendar);
-}
-
-static void
-on_edit_appointment (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- GList *selected;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (selected) {
- ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data;
-
- if (event)
- e_calendar_view_edit_appointment (cal_view, event->comp_data->client,
- event->comp_data->icalcomp,
- icalcomponent_get_first_property(event->comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY) != NULL);
-
- g_list_free (selected);
- }
-}
-
-static void
-on_print (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- calendar_command_print (cal_view->priv->calendar, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-}
-
-static void
-on_save_as (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- GList *selected;
- gchar *filename;
- gchar *ical_string;
- ECalendarViewEvent *event;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (!selected)
- return;
-
- filename = e_file_dialog_save (_("Save as..."), NULL);
- if (filename == NULL)
- return;
-
- event = (ECalendarViewEvent *) selected->data;
- ical_string = e_cal_get_component_as_string (event->comp_data->client, event->comp_data->icalcomp);
- if (ical_string == NULL) {
- g_warning ("Couldn't convert item to a string");
- return;
- }
-
- e_write_file_uri (filename, ical_string);
- g_free (ical_string);
-
- g_list_free (selected);
-}
-
-static void
-on_print_event (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- GList *selected;
- ECalendarViewEvent *event;
- ECalComponent *comp;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (!selected)
- return;
-
- event = (ECalendarViewEvent *) selected->data;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- print_comp (comp, event->comp_data->client, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-
- g_object_unref (comp);
- g_list_free (selected);
-}
-
-static void
-transfer_item_to (ECalendarViewEvent *event, ECal *dest_client, gboolean remove_item)
-{
- const gchar *uid;
- gchar *new_uid;
- icalcomponent *orig_icalcomp;
- icalproperty *icalprop;
-
- uid = icalcomponent_get_uid (event->comp_data->icalcomp);
-
- /* put the new object into the destination calendar */
- if (e_cal_get_object (dest_client, uid, NULL, &orig_icalcomp, NULL)) {
- icalcomponent_free (orig_icalcomp);
-
- if (!e_cal_modify_object (dest_client, event->comp_data->icalcomp, CALOBJ_MOD_ALL, NULL))
- return;
- } else {
- if (e_cal_util_component_is_instance (event->comp_data->icalcomp)) {
- icalcomponent *icalcomp = NULL;
-
- if (e_cal_get_object (event->comp_data->client, uid, NULL, &icalcomp, NULL)) {
- /* use master object when working with recurring event */
- orig_icalcomp = icalcomponent_new_clone (icalcomp);
- icalcomponent_free (icalcomp);
- } else {
- /* ... or remove the recurrence id property... */
- orig_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp);
-
- if (e_cal_util_component_has_recurrences (orig_icalcomp)) {
- /* ... for non-detached instances, to make it a master object */
- icalproperty *prop;
-
- prop = icalcomponent_get_first_property (orig_icalcomp, ICAL_RECURRENCEID_PROPERTY);
- if (prop)
- icalcomponent_remove_property (orig_icalcomp, prop);
- }
- }
- } else
- orig_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp);
-
- icalprop = icalproperty_new_x ("1");
- icalproperty_set_x_name (icalprop, "X-EVOLUTION-MOVE-CALENDAR");
- icalcomponent_add_property (orig_icalcomp, icalprop);
-
- if (!remove_item) {
- /* change the UID to avoid problems with duplicated UIDs */
- new_uid = e_cal_component_gen_uid ();
- icalcomponent_set_uid (orig_icalcomp, new_uid);
-
- g_free (new_uid);
- }
-
- new_uid = NULL;
- if (!e_cal_create_object (dest_client, orig_icalcomp, &new_uid, NULL)) {
- icalcomponent_free (orig_icalcomp);
- return;
- }
-
- if (new_uid)
- g_free (new_uid);
- icalcomponent_free (orig_icalcomp);
- }
-
- /* remove the item from the source calendar */
- if (remove_item) {
- if (e_cal_util_component_is_instance (event->comp_data->icalcomp) || e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) {
- gchar *rid = NULL;
- struct icaltimetype recur_id = icalcomponent_get_recurrenceid (event->comp_data->icalcomp);
-
- if (!icaltime_is_null_time (recur_id))
- rid = icaltime_as_ical_string_r (recur_id);
-
- e_cal_remove_object_with_mod (event->comp_data->client, uid, rid, CALOBJ_MOD_ALL, NULL);
- g_free (rid);
- } else
- e_cal_remove_object (event->comp_data->client, uid, NULL);
- }
-}
-
-static void
-transfer_selected_items (ECalendarView *cal_view, gboolean remove_item)
-{
- GList *selected, *l;
- ESource *destination_source;
- ECal *dest_client;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (!selected)
- return;
-
- /* prompt the user for destination source */
- destination_source = select_source_dialog ((GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *)cal_view), E_CAL_SOURCE_TYPE_EVENT);
- if (!destination_source)
- return;
-
- /* open the destination calendar */
- dest_client = auth_new_cal_from_source (destination_source, E_CAL_SOURCE_TYPE_EVENT);
- if (!dest_client || !e_cal_open (dest_client, FALSE, NULL)) {
- if (dest_client)
- g_object_unref (dest_client);
- g_object_unref (destination_source);
- return;
- }
-
- /* process all selected events */
- if (remove_item)
- e_calendar_view_set_status_message (cal_view, _("Moving items"), -1);
- else
- e_calendar_view_set_status_message (cal_view, _("Copying items"), -1);
-
- for (l = selected; l != NULL; l = l->next)
- transfer_item_to ((ECalendarViewEvent *) l->data, dest_client, remove_item);
-
- e_calendar_view_set_status_message (cal_view, NULL, -1);
-
- /* free memory */
- g_object_unref (destination_source);
- g_object_unref (dest_client);
- g_list_free (selected);
-}
-
-static void
-on_copy_to (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- transfer_selected_items (cal_view, FALSE);
-}
-
-static void
-on_move_to (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- transfer_selected_items (cal_view, TRUE);
-}
-
-static void
-on_meeting (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- GList *selected;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (selected) {
- ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data;
- e_calendar_view_edit_appointment (cal_view, event->comp_data->client, event->comp_data->icalcomp, TRUE);
-
- g_list_free (selected);
- }
-}
-
-static void
-set_attendee_status_for_delegate (icalcomponent *icalcomp, ECal *client)
-{
- icalproperty *prop;
- icalparameter *param;
- gchar *address = NULL;
- ECalComponent *comp;
- gboolean found = FALSE;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
-
- address = itip_get_comp_attendee (comp, client);
-
- for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
- prop;
- prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) {
- const gchar *attendee = icalproperty_get_attendee (prop);
-
- if (!g_ascii_strcasecmp (itip_strip_mailto (attendee), address)) {
- param = icalparameter_new_role (ICAL_ROLE_NONPARTICIPANT);
- icalproperty_set_parameter (prop, param);
-
- param = icalparameter_new_partstat (ICAL_PARTSTAT_DELEGATED);
- icalproperty_set_parameter (prop, param);
-
- found = TRUE;
- break;
- }
-
- }
-
- /* We couldn find the attendee in the component, so add a new attendee */
- if (!found) {
- gchar *temp = g_strdup_printf ("MAILTO:%s", address);
-
- prop = icalproperty_new_attendee ((const gchar *) temp);
- icalcomponent_add_property (icalcomp, prop);
-
- param = icalparameter_new_partstat (ICAL_PARTSTAT_DELEGATED);
- icalproperty_add_parameter (prop, param);
-
- param = icalparameter_new_role (ICAL_ROLE_NONPARTICIPANT);
- icalproperty_add_parameter (prop, param);
-
- param = icalparameter_new_cutype (ICAL_CUTYPE_INDIVIDUAL);
- icalproperty_add_parameter (prop, param);
-
- param = icalparameter_new_rsvp (ICAL_RSVP_TRUE);
- icalproperty_add_parameter (prop, param);
-
- g_free (temp);
- }
-
- g_free (address);
- g_object_unref (comp);
-}
-
-static void
-on_delegate (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- GList *selected;
- guint32 flags = 0;
- icalcomponent *clone;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (selected) {
- ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data;
-
- clone = icalcomponent_new_clone (event->comp_data->icalcomp);
- set_attendee_status_for_delegate (clone, event->comp_data->client);
-
- flags |= COMP_EDITOR_MEETING | COMP_EDITOR_DELEGATE;
-
- e_calendar_view_open_event_with_flags (cal_view, event->comp_data->client, clone, flags);
-
- icalcomponent_free (clone);
- g_list_free (selected);
- }
-}
-
-static void
-on_forward (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- GList *selected;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (selected) {
- ECalComponent *comp;
- ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
-
- g_list_free (selected);
- g_object_unref (comp);
- }
-}
-
-static void
-on_reply (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- GList *selected;
- gboolean reply_all = FALSE;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (selected) {
- ECalComponent *comp;
- ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- reply_to_calendar_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, event->comp_data->client, reply_all, NULL, NULL);
-
- g_list_free (selected);
- g_object_unref (comp);
- }
-}
-
-static void
-on_reply_all (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- GList *selected;
- gboolean reply_all = TRUE;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (selected) {
- ECalComponent *comp;
- ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- reply_to_calendar_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, event->comp_data->client, reply_all, NULL, NULL);
-
- g_list_free (selected);
- g_object_unref (comp);
- }
-}
-
-static void
-on_delete_appointment (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- e_calendar_view_delete_selected_event (cal_view);
-}
-
-static void
-on_unrecur_appointment (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
- ECalendarViewEvent *event;
- ECalComponent *comp, *new_comp;
- ECalComponentDateTime date;
- struct icaltimetype itt;
- GList *selected;
- ECal *client;
- gchar *new_uid;
- ECalComponentId *id = NULL;
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (!selected)
- return;
-
- event = (ECalendarViewEvent *) selected->data;
- client = g_object_ref (event->comp_data->client);
-
- date.value = &itt;
- date.tzid = NULL;
-
- /* For the recurring object, we add an exception to get rid of the
- instance. */
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- id = e_cal_component_get_id (comp);
-
- /* For the unrecurred instance we duplicate the original object,
- create a new uid for it, get rid of the recurrence rules, and set
- the start & end times to the instances times. */
- new_comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (new_comp, icalcomponent_new_clone (event->comp_data->icalcomp));
-
- new_uid = e_cal_component_gen_uid ();
- e_cal_component_set_uid (new_comp, new_uid);
- g_free (new_uid);
- e_cal_component_set_recurid (new_comp, NULL);
- e_cal_component_set_rdate_list (new_comp, NULL);
- e_cal_component_set_rrule_list (new_comp, NULL);
- e_cal_component_set_exdate_list (new_comp, NULL);
- e_cal_component_set_exrule_list (new_comp, NULL);
-
- date.value = &itt;
- date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (cal_view));
-
- *date.value = icaltime_from_timet_with_zone (event->comp_data->instance_start, FALSE,
- e_calendar_view_get_timezone (cal_view));
- cal_comp_set_dtstart_with_oldzone (client, new_comp, &date);
- *date.value = icaltime_from_timet_with_zone (event->comp_data->instance_end, FALSE,
- e_calendar_view_get_timezone (cal_view));
- cal_comp_set_dtend_with_oldzone (client, new_comp, &date);
- e_cal_component_commit_sequence (new_comp);
-
- /* Now update both ECalComponents. Note that we do this last since at
- * present the updates happen synchronously so our event may disappear.
- */
-
- if (!e_cal_remove_object_with_mod (client, id->uid, id->rid, CALOBJ_MOD_THIS,
- NULL))
- g_message ("on_unrecur_appointment(): Could not remove the old object!");
-
- e_cal_component_free_id (id);
- g_object_unref (comp);
-
- if (!e_cal_create_object (client, e_cal_component_get_icalcomponent (new_comp), &new_uid, NULL))
- g_message ("on_unrecur_appointment(): Could not update the object!");
- else
- g_free (new_uid);
-
- g_object_unref (new_comp);
- g_object_unref (client);
- g_list_free (selected);
-}
-
-static void
-on_delete_occurrence (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- e_calendar_view_delete_selected_occurrence (cal_view);
-}
-
-static void
-on_cut (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- e_calendar_view_cut_clipboard (cal_view);
-}
-
-static void
-on_copy (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- e_calendar_view_copy_clipboard (cal_view);
-}
-
-static void
-on_paste (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- ECalendarView *cal_view = data;
-
- e_calendar_view_paste_clipboard (cal_view);
-}
-
-static EPopupItem ecv_main_items [] = {
- { E_POPUP_ITEM, (gchar *) "00.new", (gchar *) N_("New _Appointment..."), on_new_appointment, NULL, (gchar *) "appointment-new", 0, 0 },
- { E_POPUP_ITEM, (gchar *) "10.newallday", (gchar *) N_("New All Day _Event"), on_new_event, NULL, (gchar *) "stock_new-24h-appointment", 0, 0},
- { E_POPUP_ITEM, (gchar *) "20.meeting", (gchar *) N_("New _Meeting"), on_new_meeting, NULL, (gchar *) "stock_new-meeting", 0, 0},
- { E_POPUP_ITEM, (gchar *) "30.task", (gchar *) N_("New _Task"), on_new_task, NULL, (gchar *) "stock_task", 0, 0},
-
- { E_POPUP_BAR, (gchar *) "40."},
- { E_POPUP_ITEM, (gchar *) "40.print", (gchar *) N_("P_rint..."), on_print, NULL, (gchar *) GTK_STOCK_PRINT, 0, 0 },
-
- { E_POPUP_BAR, (gchar *) "50." },
- { E_POPUP_ITEM, (gchar *) "50.paste", (gchar *) N_("_Paste"), on_paste, NULL, (gchar *) GTK_STOCK_PASTE, 0, E_CAL_POPUP_SELECT_EDITABLE },
-
- { E_POPUP_BAR, (gchar *) "60." },
- /* FIXME: hook in this somehow */
- { E_POPUP_SUBMENU, (gchar *) "60.view", (gchar *) N_("_Current View") },
-
- { E_POPUP_ITEM, (gchar *) "61.today", (gchar *) N_("Select T_oday"), on_goto_today, NULL, (gchar *) "go-today" },
- { E_POPUP_ITEM, (gchar *) "62.todate", (gchar *) N_("_Select Date..."), on_goto_date, NULL, (gchar *) GTK_STOCK_JUMP_TO },
-};
-
-static EPopupItem ecv_child_items [] = {
- { E_POPUP_ITEM, (gchar *) "00.open", (gchar *) N_("_Open"), on_edit_appointment, NULL, (gchar *) GTK_STOCK_OPEN, 0, E_CAL_POPUP_SELECT_NOTEDITING },
- { E_POPUP_ITEM, (gchar *) "10.saveas", (gchar *) N_("_Save As..."), on_save_as, NULL, (gchar *) GTK_STOCK_SAVE_AS, 0, E_CAL_POPUP_SELECT_NOTEDITING },
- { E_POPUP_ITEM, (gchar *) "20.print", (gchar *) N_("Pri_nt..."), on_print_event, NULL, (gchar *) GTK_STOCK_PRINT, 0, E_CAL_POPUP_SELECT_NOTEDITING },
-
- { E_POPUP_BAR, (gchar *) "30." },
-
- { E_POPUP_ITEM, (gchar *) "31.cut", (gchar *) N_("C_ut"), on_cut, NULL, (gchar *) GTK_STOCK_CUT, 0, E_CAL_POPUP_SELECT_NOTEDITING|E_CAL_POPUP_SELECT_EDITABLE|E_CAL_POPUP_SELECT_ORGANIZER },
- { E_POPUP_ITEM, (gchar *) "32.copy", (gchar *) N_("_Copy"), on_copy, NULL, (gchar *) GTK_STOCK_COPY, 0, E_CAL_POPUP_SELECT_NOTEDITING|E_CAL_POPUP_SELECT_ORGANIZER },
- { E_POPUP_ITEM, (gchar *) "33.paste", (gchar *) N_("_Paste"), on_paste, NULL, (gchar *) GTK_STOCK_PASTE, 0, E_CAL_POPUP_SELECT_EDITABLE },
-
- { E_POPUP_BAR, (gchar *) "40." },
-
- { E_POPUP_ITEM, (gchar *) "43.copyto", (gchar *) N_("Cop_y to Calendar..."), on_copy_to, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING },
- { E_POPUP_ITEM, (gchar *) "44.moveto", (gchar *) N_("Mo_ve to Calendar..."), on_move_to, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "45.delegate", (gchar *) N_("_Delegate Meeting..."), on_delegate, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_DELEGATABLE | E_CAL_POPUP_SELECT_MEETING},
- { E_POPUP_ITEM, (gchar *) "46.schedule", (gchar *) N_("_Schedule Meeting..."), on_meeting, NULL, NULL, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_NOTMEETING },
- { E_POPUP_ITEM, (gchar *) "47.forward", (gchar *) N_("_Forward as iCalendar..."), on_forward, NULL, (gchar *) "mail-forward", 0, E_CAL_POPUP_SELECT_NOTEDITING },
- { E_POPUP_ITEM, (gchar *) "48.reply", (gchar *) N_("_Reply"), on_reply, NULL, (gchar *) "mail-reply-sender", E_CAL_POPUP_SELECT_MEETING | E_CAL_POPUP_SELECT_NOTEDITING },
- { E_POPUP_ITEM, (gchar *) "49.reply-all", (gchar *) N_("Reply to _All"), on_reply_all, NULL, (gchar *) "mail-reply-all", E_CAL_POPUP_SELECT_MEETING, E_CAL_POPUP_SELECT_NOTEDITING },
-
- { E_POPUP_BAR, (gchar *) "50." },
-
- { E_POPUP_ITEM, (gchar *) "51.delete", (gchar *) N_("_Delete"), on_delete_appointment, NULL, (gchar *) GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_NONRECURRING, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "52.move", (gchar *) N_("Make this Occurrence _Movable"), on_unrecur_appointment, NULL, NULL, E_CAL_POPUP_SELECT_RECURRING | E_CAL_POPUP_SELECT_INSTANCE, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "53.delete", (gchar *) N_("Delete this _Occurrence"), on_delete_occurrence, NULL, (gchar *) GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_RECURRING, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "54.delete", (gchar *) N_("Delete _All Occurrences"), on_delete_appointment, NULL, (gchar *) GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_RECURRING, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE },
-};
-
-static void
-ecv_popup_free (EPopup *ep, GSList *list, gpointer data)
-{
- g_slist_free(list);
-}
-
-GtkMenu *
-e_calendar_view_create_popup_menu (ECalendarView *cal_view)
-{
- ECalPopup *ep;
- GSList *menus = NULL;
- GList *selected, *l;
- gint i;
- ECalPopupTargetSelect *t;
- ECalModel *model;
- GPtrArray *events;
-
- g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL);
-
- /* We could do this using a factory on the ECalPopup class,
- * that way we would get called implicitly whenever a popup
- * menu was created rather than everyone having to call us.
- * We could also have a different menu id for each view */
-
- /** @HookPoint-ECalPopup: Calendar Main View Context Menu
- * @Id: org.gnome.evolution.calendar.view.popup
- * @Class: org.gnome.evolution.calendar.popup:1.0
- * @Target: ECalPopupTargetSelect
- *
- * The context menu on the main calendar view. This menu
- * applies to all view types.
- */
- ep = e_cal_popup_new("org.gnome.evolution.calendar.view.popup");
-
- model = e_calendar_view_get_model(cal_view);
- events = g_ptr_array_new();
- selected = e_calendar_view_get_selected_events(cal_view);
- for (l=selected;l;l=g_list_next(l)) {
- ECalendarViewEvent *event = l->data;
-
- if (event)
- g_ptr_array_add(events, e_cal_model_copy_component_data(event->comp_data));
- }
- g_list_free(selected);
-
- t = e_cal_popup_target_new_select(ep, model, events);
- t->target.widget = (GtkWidget *)cal_view;
-
- if (t->events->len == 0) {
- for (i=0;i<sizeof(ecv_main_items)/sizeof(ecv_main_items[0]);i++)
- menus = g_slist_prepend(menus, &ecv_main_items[i]);
-
- gnome_calendar_view_popup_factory(cal_view->priv->calendar, (EPopup *)ep, "60.view");
- } else {
- for (i=0;i<sizeof(ecv_child_items)/sizeof(ecv_child_items[0]);i++)
- menus = g_slist_prepend(menus, &ecv_child_items[i]);
- }
-
- e_popup_add_items((EPopup *)ep, menus, NULL, ecv_popup_free, cal_view);
-
- return e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
-}
-
void
e_calendar_view_open_event (ECalendarView *cal_view)
{
@@ -2092,7 +1400,7 @@ e_calendar_view_new_appointment (ECalendarView *cal_view)
static void
object_created_cb (CompEditor *ce, ECalendarView *cal_view)
{
- gnome_calendar_emit_user_created_signal (cal_view, e_calendar_view_get_calendar (cal_view), comp_editor_get_client (ce));
+ e_calendar_view_emit_user_created (cal_view);
}
CompEditor *
@@ -2101,12 +1409,16 @@ e_calendar_view_open_event_with_flags (ECalendarView *cal_view, ECal *client, ic
CompEditor *ce;
const gchar *uid;
ECalComponent *comp;
+ EShell *shell;
+
+ /* FIXME ECalendarView should own an EShell pointer. */
+ shell = e_shell_get_default ();
uid = icalcomponent_get_uid (icalcomp);
- ce = e_comp_editor_registry_find (comp_editor_registry, uid);
+ ce = comp_editor_find_instance (uid);
if (!ce) {
- ce = event_editor_new (client, flags);
+ ce = event_editor_new (client, shell, flags);
g_signal_connect (ce, "object_created", G_CALLBACK (object_created_cb), cal_view);
@@ -2116,8 +1428,6 @@ e_calendar_view_open_event_with_flags (ECalendarView *cal_view, ECal *client, ic
if (flags & COMP_EDITOR_MEETING)
event_editor_show_meeting (EVENT_EDITOR (ce));
- e_comp_editor_registry_add (comp_editor_registry, ce, FALSE);
-
g_object_unref (comp);
}
@@ -2601,6 +1911,14 @@ e_calendar_view_get_icalcomponent_summary (ECal *ecal, icalcomponent *icalcomp,
}
void
+e_calendar_view_emit_user_created (ECalendarView *cal_view)
+{
+ g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
+
+ g_signal_emit (cal_view, signals[USER_CREATED], 0);
+}
+
+void
draw_curved_rectangle (cairo_t *cr, double x0, double y0,
double rect_width, double rect_height,
double radius)
@@ -2650,36 +1968,6 @@ draw_curved_rectangle (cairo_t *cr, double x0, double y0,
cairo_close_path (cr);
}
-static void
-error_response(GtkWidget *widget, gint response, gpointer data)
-{
- gtk_widget_destroy (widget);
-}
-
-void
-e_calendar_utils_show_error_silent (GtkWidget *widget)
-{
- EActivityHandler *handler = calendar_component_peek_activity_handler (calendar_component_peek ());
-
- if (!g_object_get_data ((GObject *) widget, "response-handled")) {
- g_signal_connect(widget, "response", G_CALLBACK(error_response), NULL);
- }
-
- e_activity_handler_make_error (handler, "calendar", E_LOG_ERROR, widget);
-}
-
-void
-e_calendar_utils_show_info_silent (GtkWidget *widget)
-{
- EActivityHandler *handler = calendar_component_peek_activity_handler (calendar_component_peek ());
-
- if (!g_object_get_data ((GObject *) widget, "response-handled")) {
- g_signal_connect(widget, "response", G_CALLBACK(error_response), NULL);
- }
-
- e_activity_handler_make_error (handler, "calendar", E_LOG_WARNINGS, widget);
-}
-
/* returns either light or dark yellow, based on the base_background,
which is the default background color */
GdkColor
diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h
index ae0703addd..5af1d77801 100644
--- a/calendar/gui/e-calendar-view.h
+++ b/calendar/gui/e-calendar-view.h
@@ -20,26 +20,35 @@
*
*/
-#ifndef _E_CALENDAR_VIEW_H_
-#define _E_CALENDAR_VIEW_H_
+#ifndef E_CALENDAR_VIEW_H
+#define E_CALENDAR_VIEW_H
-#include <libecal/e-cal.h>
#include <gtk/gtk.h>
+#include <libecal/e-cal.h>
#include "e-cal-model.h"
#include "gnome-cal.h"
-#include <misc/e-activity-handler.h>
#include "dialogs/comp-editor.h"
-G_BEGIN_DECLS
-
-/*
- * EView - base widget class for the calendar views.
- */
+/* Standard GObject macros */
+#define E_TYPE_CALENDAR_VIEW \
+ (e_calendar_view_get_type ())
+#define E_CALENDAR_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CALENDAR_VIEW, ECalendarView))
+#define E_CALENDAR_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CALENDAR_VIEW, ECalendarViewClass))
+#define E_IS_CALENDAR_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CALENDAR_VIEW))
+#define E_IS_CALENDAR_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CALENDAR_VIEW))
+#define E_CALENDAR_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CALENDAR_VIEW, ECalendarViewClass))
-#define E_TYPE_CALENDAR_VIEW (e_calendar_view_get_type ())
-#define E_CALENDAR_VIEW(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_calendar_view_get_type (), ECalendarView)
-#define E_CALENDAR_VIEW_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_calendar_view_get_type (), ECalendarViewClass)
-#define E_IS_CALENDAR_VIEW(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_calendar_view_get_type ())
+G_BEGIN_DECLS
typedef enum {
E_CALENDAR_VIEW_POS_OUTSIDE,
@@ -61,13 +70,13 @@ typedef enum {
} ECalViewMoveDirection;
#define E_CALENDAR_VIEW_EVENT_FIELDS \
- GnomeCanvasItem *canvas_item; \
- ECalModelComponent *comp_data; \
- time_t start; \
- time_t end; \
- guint16 start_minute; \
- guint16 end_minute; \
- guint different_timezone : 1; \
+ GnomeCanvasItem *canvas_item; \
+ ECalModelComponent *comp_data; \
+ time_t start; \
+ time_t end; \
+ guint16 start_minute; \
+ guint16 end_minute; \
+ guint different_timezone : 1; \
gboolean is_editable; \
GtkWidget *tooltip; \
gint timeout; \
@@ -78,13 +87,12 @@ typedef struct {
E_CALENDAR_VIEW_EVENT_FIELDS
} ECalendarViewEvent;
-typedef struct _ECalendarView ECalendarView;
-typedef struct _ECalendarViewClass ECalendarViewClass;
+typedef struct _ECalendarView ECalendarView;
+typedef struct _ECalendarViewClass ECalendarViewClass;
typedef struct _ECalendarViewPrivate ECalendarViewPrivate;
struct _ECalendarView {
- GtkTable table;
-
+ GtkTable parent;
gboolean in_focus;
ECalendarViewPrivate *priv;
};
@@ -100,6 +108,7 @@ struct _ECalendarViewClass {
GtkTableClass parent_class;
/* Notification signals */
+ void (* popup_event) (ECalendarView *cal_view, GdkEventButton *event);
void (* selection_changed) (ECalendarView *cal_view);
void (* selected_time_changed) (ECalendarView *cal_view);
void (* timezone_changed) (ECalendarView *cal_view, icaltimezone *old_zone, icaltimezone *new_zone);
@@ -122,15 +131,10 @@ GType e_calendar_view_get_type (void);
GnomeCalendar *e_calendar_view_get_calendar (ECalendarView *cal_view);
void e_calendar_view_set_calendar (ECalendarView *cal_view, GnomeCalendar *calendar);
ECalModel *e_calendar_view_get_model (ECalendarView *cal_view);
-void e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model);
icaltimezone *e_calendar_view_get_timezone (ECalendarView *cal_view);
void e_calendar_view_set_timezone (ECalendarView *cal_view, icaltimezone *zone);
const gchar *e_calendar_view_get_default_category (ECalendarView *cal_view);
void e_calendar_view_set_default_category (ECalendarView *cal_view, const gchar *category);
-gboolean e_calendar_view_get_use_24_hour_format (ECalendarView *view);
-void e_calendar_view_set_use_24_hour_format (ECalendarView *view, gboolean use_24_hour);
-
-void e_calendar_view_set_activity_handler (ECalendarView *cal_view, EActivityHandler *activity_handler);
void e_calendar_view_set_status_message (ECalendarView *cal_view, const gchar *message, gint percent);
GList *e_calendar_view_get_selected_events (ECalendarView *cal_view);
@@ -147,7 +151,8 @@ void e_calendar_view_delete_selected_events (ECalendarView *cal_view);
void e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view);
CompEditor* e_calendar_view_open_event_with_flags (ECalendarView *cal_view, ECal *client, icalcomponent *icalcomp, guint32 flags);
-GtkMenu *e_calendar_view_create_popup_menu (ECalendarView *cal_view);
+void e_calendar_view_popup_event (ECalendarView *cal_view,
+ GdkEventButton *event);
void e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart,
icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas);
@@ -181,6 +186,9 @@ void e_calendar_view_move_tip (GtkWidget *widget, gint x, gint y);
const gchar *e_calendar_view_get_icalcomponent_summary (ECal *ecal, icalcomponent *icalcomp, gboolean *free_text);
gchar *e_calendar_view_get_attendees_status_info (ECalComponent *comp, ECal *client);
+void e_calendar_view_emit_user_created
+ (ECalendarView *cal_view);
+
void draw_curved_rectangle (cairo_t *cr,
double x0,
double y0,
@@ -192,4 +200,4 @@ GdkColor get_today_background (GdkColor event_background);
G_END_DECLS
-#endif
+#endif /* E_CALENDAR_VIEW_H */
diff --git a/calendar/gui/e-cell-date-edit-config.c b/calendar/gui/e-cell-date-edit-config.c
deleted file mode 100644
index 5b04791412..0000000000
--- a/calendar/gui/e-cell-date-edit-config.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "calendar-config.h"
-#include "e-mini-calendar-config.h"
-#include "e-cell-date-edit-config.h"
-
-struct _ECellDateEditConfigPrivate {
- ECellDateEdit *cell;
-
- EMiniCalendarConfig *mini_config;
-
- GList *notifications;
-};
-
-/* Property IDs */
-enum props {
- PROP_0,
- PROP_CELL
-};
-
-G_DEFINE_TYPE (ECellDateEditConfig, e_cell_date_edit_config, G_TYPE_OBJECT)
-
-static void
-e_cell_date_edit_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- ECellDateEditConfig *view_config;
-
- view_config = E_CELL_DATE_EDIT_CONFIG (object);
-
- switch (property_id) {
- case PROP_CELL:
- e_cell_date_edit_config_set_cell (view_config, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_cell_date_edit_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- ECellDateEditConfig *view_config;
-
- view_config = E_CELL_DATE_EDIT_CONFIG (object);
-
- switch (property_id) {
- case PROP_CELL:
- g_value_set_object (value, e_cell_date_edit_config_get_cell (view_config));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_cell_date_edit_config_dispose (GObject *object)
-{
- ECellDateEditConfig *view_config = E_CELL_DATE_EDIT_CONFIG (object);
-
- e_cell_date_edit_config_set_cell (view_config, NULL);
-
- if (G_OBJECT_CLASS (e_cell_date_edit_config_parent_class)->dispose)
- G_OBJECT_CLASS (e_cell_date_edit_config_parent_class)->dispose (object);
-}
-
-static void
-e_cell_date_edit_config_finalize (GObject *object)
-{
- ECellDateEditConfig *view_config = E_CELL_DATE_EDIT_CONFIG (object);
- ECellDateEditConfigPrivate *priv;
-
- priv = view_config->priv;
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_cell_date_edit_config_parent_class)->finalize)
- G_OBJECT_CLASS (e_cell_date_edit_config_parent_class)->finalize (object);
-}
-
-static void
-e_cell_date_edit_config_class_init (ECellDateEditConfigClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *spec;
-
- /* Method override */
- gobject_class->set_property = e_cell_date_edit_config_set_property;
- gobject_class->get_property = e_cell_date_edit_config_get_property;
- gobject_class->dispose = e_cell_date_edit_config_dispose;
- gobject_class->finalize = e_cell_date_edit_config_finalize;
-
- spec = g_param_spec_object ("cell", NULL, NULL, e_cell_date_edit_get_type (),
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (gobject_class, PROP_CELL, spec);
-}
-
-static void
-e_cell_date_edit_config_init (ECellDateEditConfig *view_config)
-{
- view_config->priv = g_new0 (ECellDateEditConfigPrivate, 1);
-
-}
-
-ECellDateEditConfig *
-e_cell_date_edit_config_new (ECellDateEdit *cell)
-{
- ECellDateEditConfig *view_config;
-
- view_config = g_object_new (e_cell_date_edit_config_get_type (), "cell", cell, NULL);
-
- return view_config;
-}
-
-ECellDateEdit *
-e_cell_date_edit_config_get_cell (ECellDateEditConfig *view_config)
-{
- ECellDateEditConfigPrivate *priv;
-
- g_return_val_if_fail (view_config != NULL, NULL);
- g_return_val_if_fail (E_IS_CELL_DATE_EDIT_CONFIG (view_config), NULL);
-
- priv = view_config->priv;
-
- return priv->cell;
-}
-
-static void
-set_timezone (ECellDateEdit *cell)
-{
- ECellDateEditText *cell_text;
- ECellPopup *cell_popup;
- icaltimezone *zone;
-
- zone = calendar_config_get_icaltimezone ();
-
- cell_popup = E_CELL_POPUP (cell);
- cell_text = E_CELL_DATE_EDIT_TEXT (cell_popup->child);
- e_cell_date_edit_text_set_timezone (cell_text, zone);
-}
-
-static void
-timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ECellDateEditConfig *view_config = data;
- ECellDateEditConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_timezone (priv->cell);
-}
-
-static void
-set_twentyfour_hour (ECellDateEdit *cell)
-{
- ECellDateEditText *cell_text;
- ECellPopup *cell_popup;
- gboolean use_24_hour;
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- e_cell_date_edit_freeze (cell);
- g_object_set (G_OBJECT (cell),
- "use_24_hour_format", use_24_hour,
- NULL);
- e_cell_date_edit_thaw (cell);
-
- cell_popup = E_CELL_POPUP (cell);
- cell_text = E_CELL_DATE_EDIT_TEXT (cell_popup->child);
- e_cell_date_edit_text_set_use_24_hour_format (cell_text, use_24_hour);
-}
-
-static void
-twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ECellDateEditConfig *view_config = data;
- ECellDateEditConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_twentyfour_hour (priv->cell);
-}
-
-static void
-set_range (ECellDateEdit *cell)
-{
- gint start_hour, end_hour;
-
- start_hour = calendar_config_get_day_start_hour ();
- end_hour = calendar_config_get_day_end_hour ();
-
- /* Round up the end hour. */
- if (calendar_config_get_day_end_minute () != 0)
- end_hour++;
-
- /* Make sure the start hour is ok */
- if (start_hour > end_hour)
- start_hour = end_hour;
-
- /* We use the default 0 - 24 now. */
-#if 0
- g_object_set (G_OBJECT (cell),
- "lower_hour", start_hour,
- "upper_hour", end_hour,
- NULL);
-#endif
-}
-
-static void
-day_start_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ECellDateEditConfig *view_config = data;
- ECellDateEditConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_range (priv->cell);
-}
-
-static void
-day_end_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ECellDateEditConfig *view_config = data;
- ECellDateEditConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_range (priv->cell);
-}
-
-static void
-day_end_minute_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ECellDateEditConfig *view_config = data;
- ECellDateEditConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_range (priv->cell);
-}
-
-void
-e_cell_date_edit_config_set_cell (ECellDateEditConfig *view_config, ECellDateEdit *cell)
-{
- ECellDateEditConfigPrivate *priv;
- guint not;
- GList *l;
-
- g_return_if_fail (view_config != NULL);
- g_return_if_fail (E_IS_CELL_DATE_EDIT_CONFIG (view_config));
-
- priv = view_config->priv;
-
- if (priv->cell) {
- g_object_unref (priv->cell);
- priv->cell = NULL;
- }
-
- if (priv->mini_config) {
- g_object_unref (priv->mini_config);
- priv->mini_config = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
-
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- /* If the new view is NULL, return right now */
- if (!cell)
- return;
-
- priv->cell = g_object_ref (cell);
-
- /* Time zone */
- set_timezone (cell);
-
- not = calendar_config_add_notification_timezone (timezone_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* 24 Hour format */
- set_twentyfour_hour (cell);
-
- not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Popup time range */
- set_range (cell);
-
- not = calendar_config_add_notification_day_start_hour (day_start_hour_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
- not = calendar_config_add_notification_day_end_hour (day_end_hour_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
- not = calendar_config_add_notification_day_end_minute (day_end_minute_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* The mini calendar */
- priv->mini_config = e_mini_calendar_config_new (E_CALENDAR (cell->calendar));
-}
diff --git a/calendar/gui/e-cell-date-edit-config.h b/calendar/gui/e-cell-date-edit-config.h
deleted file mode 100644
index 455cca7287..0000000000
--- a/calendar/gui/e-cell-date-edit-config.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_CELL_DATE_EDIT_CONFIG_H_
-#define _E_CELL_DATE_EDIT_CONFIG_H_
-
-#include <misc/e-cell-date-edit.h>
-#include "e-cell-date-edit-text.h"
-
-G_BEGIN_DECLS
-
-#define E_CELL_DATE_EDIT_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_cell_date_edit_config_get_type (), ECellDateEditConfig)
-#define E_CELL_DATE_EDIT_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_cell_date_edit_config_get_type (), ECellDateEditConfigClass)
-#define E_IS_CELL_DATE_EDIT_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_cell_date_edit_config_get_type ())
-
-typedef struct _ECellDateEditConfig ECellDateEditConfig;
-typedef struct _ECellDateEditConfigClass ECellDateEditConfigClass;
-typedef struct _ECellDateEditConfigPrivate ECellDateEditConfigPrivate;
-
-struct _ECellDateEditConfig {
- GObject parent;
-
- ECellDateEditConfigPrivate *priv;
-};
-
-struct _ECellDateEditConfigClass {
- GObjectClass parent_class;
-};
-
-GType e_cell_date_edit_config_get_type (void);
-ECellDateEditConfig *e_cell_date_edit_config_new (ECellDateEdit *cell);
-ECellDateEdit *e_cell_date_edit_config_get_cell (ECellDateEditConfig *cell_config);
-void e_cell_date_edit_config_set_cell (ECellDateEditConfig *view_config, ECellDateEdit *cell);
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/e-cell-date-edit-text.c b/calendar/gui/e-cell-date-edit-text.c
index 5836b8ac66..97dee085ea 100644
--- a/calendar/gui/e-cell-date-edit-text.c
+++ b/calendar/gui/e-cell-date-edit-text.c
@@ -38,47 +38,107 @@
#include "e-cell-date-edit-text.h"
-G_DEFINE_TYPE (ECellDateEditText, e_cell_date_edit_text, E_CELL_TEXT_TYPE)
+#define E_CELL_DATE_EDIT_TEXT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CELL_DATE_EDIT_TEXT, ECellDateEditTextPrivate))
-void
-e_cell_date_edit_text_set_timezone (ECellDateEditText *ecd,
- icaltimezone *zone)
+struct _ECellDateEditTextPrivate {
+
+ /* The timezone to display the date in. */
+ icaltimezone *timezone;
+
+ /* Whether to display in 24-hour format. */
+ gboolean use_24_hour_format;
+};
+
+enum {
+ PROP_0,
+ PROP_TIMEZONE,
+ PROP_USE_24_HOUR_FORMAT
+};
+
+static gpointer parent_class;
+
+static void
+cell_date_edit_text_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- g_return_if_fail (E_IS_CELL_DATE_EDIT_TEXT (ecd));
+ switch (property_id) {
+ case PROP_TIMEZONE:
+ e_cell_date_edit_text_set_timezone (
+ E_CELL_DATE_EDIT_TEXT (object),
+ g_value_get_pointer (value));
+ return;
- ecd->zone = zone;
+ case PROP_USE_24_HOUR_FORMAT:
+ e_cell_date_edit_text_set_use_24_hour_format (
+ E_CELL_DATE_EDIT_TEXT (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-void
-e_cell_date_edit_text_set_use_24_hour_format (ECellDateEditText *ecd,
- gboolean use_24_hour)
+static void
+cell_date_edit_text_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- g_return_if_fail (E_IS_CELL_DATE_EDIT_TEXT (ecd));
+ switch (property_id) {
+ case PROP_TIMEZONE:
+ g_value_set_pointer (
+ value,
+ e_cell_date_edit_text_get_timezone (
+ E_CELL_DATE_EDIT_TEXT (object)));
+ return;
+
+ case PROP_USE_24_HOUR_FORMAT:
+ g_value_set_boolean (
+ value,
+ e_cell_date_edit_text_get_use_24_hour_format (
+ E_CELL_DATE_EDIT_TEXT (object)));
+ return;
+ }
- ecd->use_24_hour_format = use_24_hour;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static gchar *
-ecd_get_text (ECellText *cell, ETableModel *model, gint col, gint row)
+cell_date_edit_text_get_text (ECellText *cell,
+ ETableModel *model,
+ gint col,
+ gint row)
{
ECellDateEditText *ecd = E_CELL_DATE_EDIT_TEXT (cell);
ECellDateEditValue *dv = e_table_model_value_at (model, col, row);
+ gboolean use_24_hour_format;
+ icaltimezone *timezone;
struct tm tmp_tm;
if (!dv)
return g_strdup ("");
+ timezone = e_cell_date_edit_text_get_timezone (ecd);
+ use_24_hour_format = e_cell_date_edit_text_get_use_24_hour_format (ecd);
+
/* Note that although the property may be in a different
timezone, we convert it to the current timezone to display
it in the table. If the user actually edits the value,
it will be set to the current timezone. See set_value(). */
- tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, ecd->zone);
+ tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, timezone);
- return e_datetime_format_format_tm ("calendar", "table", dv->tt.is_date ? DTFormatKindDate : DTFormatKindDateTime, &tmp_tm);
+ return e_datetime_format_format_tm (
+ "calendar", "table", dv->tt.is_date ?
+ DTFormatKindDate : DTFormatKindDateTime, &tmp_tm);
}
static void
-ecd_free_text (ECellText *cell, gchar *text)
+cell_date_edit_text_free_text (ECellText *cell,
+ gchar *text)
{
g_free (text);
}
@@ -97,7 +157,7 @@ show_date_warning (ECellDateEditText *ecd)
matter. */
tmp_tm = localtime (&t);
- if (ecd->use_24_hour_format)
+ if (e_cell_date_edit_text_get_use_24_hour_format (ecd))
/* strftime format of a weekday, a date and a time, 24-hour. */
format = _("%a %m/%d/%Y %H:%M:%S");
else
@@ -117,8 +177,11 @@ show_date_warning (ECellDateEditText *ecd)
}
static void
-ecd_set_value (ECellText *cell, ETableModel *model, gint col, gint row,
- const gchar *text)
+cell_date_edit_text_set_value (ECellText *cell,
+ ETableModel *model,
+ gint col,
+ gint row,
+ const gchar *text)
{
ECellDateEditText *ecd = E_CELL_DATE_EDIT_TEXT (cell);
ETimeParseStatus status;
@@ -159,7 +222,7 @@ ecd_set_value (ECellText *cell, ETableModel *model, gint col, gint row,
if (is_date) {
dv.zone = NULL;
} else {
- dv.zone = ecd->zone;
+ dv.zone = e_cell_date_edit_text_get_timezone (ecd);
}
value = &dv;
@@ -169,20 +232,76 @@ ecd_set_value (ECellText *cell, ETableModel *model, gint col, gint row,
}
static void
-e_cell_date_edit_text_class_init (ECellDateEditTextClass *ecdet)
+cell_date_edit_text_class_init (ECellDateEditTextClass *class)
{
- ECellTextClass *ectc = E_CELL_TEXT_CLASS (ecdet);
-
- ectc->get_text = ecd_get_text;
- ectc->free_text = ecd_free_text;
- ectc->set_value = ecd_set_value;
+ GObjectClass *object_class;
+ ECellTextClass *cell_text_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECellDateEditTextPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = cell_date_edit_text_set_property;
+ object_class->get_property = cell_date_edit_text_get_property;
+
+ cell_text_class = E_CELL_TEXT_CLASS (class);
+ cell_text_class->get_text = cell_date_edit_text_get_text;
+ cell_text_class->free_text = cell_date_edit_text_free_text;
+ cell_text_class->set_value = cell_date_edit_text_set_value;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TIMEZONE,
+ g_param_spec_pointer (
+ "timezone",
+ "Time Zone",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USE_24_HOUR_FORMAT,
+ g_param_spec_boolean (
+ "use-24-hour-format",
+ "Use 24-Hour Format",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
}
static void
-e_cell_date_edit_text_init (ECellDateEditText *ecd)
+cell_date_edit_text_init (ECellDateEditText *ecd)
{
- ecd->zone = icaltimezone_get_utc_timezone ();
- ecd->use_24_hour_format = TRUE;
+ ecd->priv = E_CELL_DATE_EDIT_TEXT_GET_PRIVATE (ecd);
+
+ ecd->priv->timezone = icaltimezone_get_utc_timezone ();
+ ecd->priv->use_24_hour_format = TRUE;
+}
+
+GType
+e_cell_date_edit_text_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (ECellDateEditTextClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cell_date_edit_text_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECellDateEditText),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) cell_date_edit_text_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_CELL_TEXT_TYPE, "ECellDateEditText", &type_info, 0);
+ }
+
+ return type;
}
/**
@@ -198,10 +317,49 @@ ECell *
e_cell_date_edit_text_new (const gchar *fontname,
GtkJustification justify)
{
- ECellDateEditText *ecd = g_object_new (e_cell_date_edit_text_get_type (), NULL);
+ ECell *cell;
+
+ cell = g_object_new (E_TYPE_CELL_DATE_EDIT_TEXT, NULL);
+ e_cell_text_construct (E_CELL_TEXT (cell), fontname, justify);
+
+ return cell;
+}
+
+icaltimezone *
+e_cell_date_edit_text_get_timezone (ECellDateEditText *ecd)
+{
+ g_return_val_if_fail (E_IS_CELL_DATE_EDIT_TEXT (ecd), NULL);
+
+ return ecd->priv->timezone;
+}
+
+void
+e_cell_date_edit_text_set_timezone (ECellDateEditText *ecd,
+ icaltimezone *timezone)
+{
+ g_return_if_fail (E_IS_CELL_DATE_EDIT_TEXT (ecd));
+
+ ecd->priv->timezone = timezone;
+
+ g_object_notify (G_OBJECT (ecd), "timezone");
+}
+
+gboolean
+e_cell_date_edit_text_get_use_24_hour_format (ECellDateEditText *ecd)
+{
+ g_return_val_if_fail (E_IS_CELL_DATE_EDIT_TEXT (ecd), FALSE);
+
+ return ecd->priv->use_24_hour_format;
+}
+
+void
+e_cell_date_edit_text_set_use_24_hour_format (ECellDateEditText *ecd,
+ gboolean use_24_hour)
+{
+ g_return_if_fail (E_IS_CELL_DATE_EDIT_TEXT (ecd));
- e_cell_text_construct (E_CELL_TEXT (ecd), fontname, justify);
+ ecd->priv->use_24_hour_format = use_24_hour;
- return (ECell *) ecd;
+ g_object_notify (G_OBJECT (ecd), "use-24-hour-format");
}
diff --git a/calendar/gui/e-cell-date-edit-text.h b/calendar/gui/e-cell-date-edit-text.h
index 5dc1f0c4bd..a49b68d36b 100644
--- a/calendar/gui/e-cell-date-edit-text.h
+++ b/calendar/gui/e-cell-date-edit-text.h
@@ -27,42 +27,60 @@
#include <libical/ical.h>
#include <table/e-cell-text.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_CELL_DATE_EDIT_TEXT \
+ (e_cell_date_edit_text_get_type ())
+#define E_CELL_DATE_EDIT_TEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CELL_DATE_EDIT_TEXT, ECellDateEditText))
+#define E_CELL_DATE_EDIT_TEXT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CELL_DATE_EDIT_TEXT, ECellDateEditTextClass))
+#define E_IS_CELL_DATE_EDIT_TEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CELL_DATE_EDIT_TEXT))
+#define E_IS_CELL_DATE_EDIT_TEXT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CELL_DATE_EDIT_TEXT))
+#define E_CELL_DATE_EDIT_TEXT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CELL_DATE_EDIT_TEXT, ECellDateEditTextClass))
-#define E_CELL_DATE_EDIT_TEXT_TYPE (e_cell_date_edit_text_get_type ())
-#define E_CELL_DATE_EDIT_TEXT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_CELL_DATE_EDIT_TEXT_TYPE, ECellDateEditText))
-#define E_CELL_DATE_EDIT_TEXT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_CELL_DATE_EDIT_TEXT_TYPE, ECellDateEditTextClass))
-#define E_IS_CELL_DATE_EDIT_TEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_CELL_DATE_EDIT_TEXT_TYPE))
-#define E_IS_CELL_DATE_EDIT_TEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_CELL_DATE_EDIT_TEXT_TYPE))
+G_BEGIN_DECLS
+typedef struct _ECellDateEditText ECellDateEditText;
+typedef struct _ECellDateEditTextClass ECellDateEditTextClass;
+typedef struct _ECellDateEditTextPrivate ECellDateEditTextPrivate;
typedef struct _ECellDateEditValue ECellDateEditValue;
+
struct _ECellDateEditValue {
struct icaltimetype tt;
icaltimezone *zone;
};
-typedef struct {
- ECellText base;
-
- /* The timezone to display the date in. */
- icaltimezone *zone;
-
- /* Whether to display in 24-hour format. */
- gboolean use_24_hour_format;
-} ECellDateEditText;
+struct _ECellDateEditText {
+ ECellText parent;
+ ECellDateEditTextPrivate *priv;
+};
-typedef struct {
+struct _ECellDateEditTextClass {
ECellTextClass parent_class;
-} ECellDateEditTextClass;
+};
-GType e_cell_date_edit_text_get_type (void);
-ECell *e_cell_date_edit_text_new (const gchar *fontname,
- GtkJustification justify);
+GType e_cell_date_edit_text_get_type (void);
+ECell * e_cell_date_edit_text_new (const gchar *fontname,
+ GtkJustification justify);
+icaltimezone * e_cell_date_edit_text_get_timezone
+ (ECellDateEditText *ecd);
+void e_cell_date_edit_text_set_timezone
+ (ECellDateEditText *ecd,
+ icaltimezone *timezone);
+gboolean e_cell_date_edit_text_get_use_24_hour_format
+ (ECellDateEditText *ecd);
+void e_cell_date_edit_text_set_use_24_hour_format
+ (ECellDateEditText *ecd,
+ gboolean use_24_hour);
-void e_cell_date_edit_text_set_timezone (ECellDateEditText *ecd,
- icaltimezone *zone);
-void e_cell_date_edit_text_set_use_24_hour_format (ECellDateEditText *ecd,
- gboolean use_24_hour);
G_END_DECLS
#endif /* _E_CELL_DATE_EDIT_TEXT_H_ */
diff --git a/calendar/gui/e-date-edit-config.c b/calendar/gui/e-date-edit-config.c
deleted file mode 100644
index bead58f5d2..0000000000
--- a/calendar/gui/e-date-edit-config.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "calendar-config.h"
-#include "e-date-edit-config.h"
-
-struct _EDateEditConfigPrivate {
- EDateEdit *edit;
-
- GList *notifications;
-};
-
-/* Property IDs */
-enum props {
- PROP_0,
- PROP_EDIT
-};
-
-G_DEFINE_TYPE (EDateEditConfig, e_date_edit_config, G_TYPE_OBJECT)
-
-static void
-e_date_edit_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- EDateEditConfig *edit_config;
-
- edit_config = E_DATE_EDIT_CONFIG (object);
-
- switch (property_id) {
- case PROP_EDIT:
- e_date_edit_config_set_edit (edit_config, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_date_edit_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- EDateEditConfig *edit_config;
-
- edit_config = E_DATE_EDIT_CONFIG (object);
-
- switch (property_id) {
- case PROP_EDIT:
- g_value_set_object (value, e_date_edit_config_get_edit (edit_config));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_date_edit_config_dispose (GObject *object)
-{
- EDateEditConfig *edit_config = E_DATE_EDIT_CONFIG (object);
-
- e_date_edit_config_set_edit (edit_config, NULL);
-
- if (G_OBJECT_CLASS (e_date_edit_config_parent_class)->dispose)
- G_OBJECT_CLASS (e_date_edit_config_parent_class)->dispose (object);
-}
-
-static void
-e_date_edit_config_finalize (GObject *object)
-{
- EDateEditConfig *edit_config = E_DATE_EDIT_CONFIG (object);
- EDateEditConfigPrivate *priv;
-
- priv = edit_config->priv;
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_date_edit_config_parent_class)->finalize)
- G_OBJECT_CLASS (e_date_edit_config_parent_class)->finalize (object);
-}
-
-static void
-e_date_edit_config_class_init (EDateEditConfigClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *spec;
-
- /* Method override */
- gobject_class->set_property = e_date_edit_config_set_property;
- gobject_class->get_property = e_date_edit_config_get_property;
- gobject_class->dispose = e_date_edit_config_dispose;
- gobject_class->finalize = e_date_edit_config_finalize;
-
- spec = g_param_spec_object ("edit", NULL, NULL, e_date_edit_get_type (),
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (gobject_class, PROP_EDIT, spec);
-}
-
-static void
-e_date_edit_config_init (EDateEditConfig *edit_config)
-{
- edit_config->priv = g_new0 (EDateEditConfigPrivate, 1);
-
-}
-
-EDateEditConfig *
-e_date_edit_config_new (EDateEdit *date_edit)
-{
- EDateEditConfig *edit_config;
-
- edit_config = g_object_new (e_date_edit_config_get_type (), "edit", date_edit, NULL);
-
- return edit_config;
-}
-
-EDateEdit *
-e_date_edit_config_get_edit (EDateEditConfig *edit_config)
-{
- EDateEditConfigPrivate *priv;
-
- g_return_val_if_fail (edit_config != NULL, NULL);
- g_return_val_if_fail (E_IS_DATE_EDIT_CONFIG (edit_config), NULL);
-
- priv = edit_config->priv;
-
- return priv->edit;
-}
-
-static void
-set_week_start (EDateEdit *date_edit)
-{
- gint week_start_day;
-
- week_start_day = calendar_config_get_week_start_day ();
-
- /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
- week_start_day = (week_start_day + 6) % 7;
-
- e_date_edit_set_week_start_day (date_edit, week_start_day);
-}
-
-static void
-week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDateEditConfig *edit_config = data;
- EDateEditConfigPrivate *priv;
-
- priv = edit_config->priv;
-
- set_week_start (priv->edit);
-}
-
-static void
-set_twentyfour_hour (EDateEdit *date_edit)
-{
- gboolean use_24_hour;
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- e_date_edit_set_use_24_hour_format (date_edit, use_24_hour);
-}
-
-static void
-twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDateEditConfig *edit_config = data;
- EDateEditConfigPrivate *priv;
-
- priv = edit_config->priv;
-
- set_twentyfour_hour (priv->edit);
-}
-
-static void
-set_dnav_show_week_no (EDateEdit *date_edit)
-{
- gboolean show_week_no;
-
- show_week_no = calendar_config_get_dnav_show_week_no ();
-
- e_date_edit_set_show_week_numbers (date_edit, show_week_no);
-}
-
-static void
-dnav_show_week_no_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDateEditConfig *edit_config = data;
- EDateEditConfigPrivate *priv;
-
- priv = edit_config->priv;
-
- set_dnav_show_week_no (priv->edit);
-}
-void
-e_date_edit_config_set_edit (EDateEditConfig *edit_config, EDateEdit *date_edit)
-{
- EDateEditConfigPrivate *priv;
- guint not;
- GList *l;
-
- g_return_if_fail (edit_config != NULL);
- g_return_if_fail (E_IS_DATE_EDIT_CONFIG (edit_config));
-
- priv = edit_config->priv;
-
- if (priv->edit) {
- g_object_unref (priv->edit);
- priv->edit = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
-
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- /* If the new edit is NULL, return right now */
- if (!date_edit)
- return;
-
- priv->edit = g_object_ref (date_edit);
-
- /* Week start */
- set_week_start (date_edit);
-
- not = calendar_config_add_notification_week_start_day (week_start_changed_cb, edit_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* 24 Hour format */
- set_twentyfour_hour (date_edit);
-
- not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, edit_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Show week numbers */
- set_dnav_show_week_no (date_edit);
-
- not = calendar_config_add_notification_dnav_show_week_no (dnav_show_week_no_changed_cb, edit_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-}
diff --git a/calendar/gui/e-date-edit-config.h b/calendar/gui/e-date-edit-config.h
deleted file mode 100644
index 4065ec74e7..0000000000
--- a/calendar/gui/e-date-edit-config.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_DATE_EDIT_CONFIG_H_
-#define _E_DATE_EDIT_CONFIG_H_
-
-#include <misc/e-dateedit.h>
-
-G_BEGIN_DECLS
-
-#define E_DATE_EDIT_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_date_edit_config_get_type (), EDateEditConfig)
-#define E_DATE_EDIT_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_date_edit_config_get_type (), EDateEditConfigClass)
-#define E_IS_DATE_EDIT_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_date_edit_config_get_type ())
-
-typedef struct _EDateEditConfig EDateEditConfig;
-typedef struct _EDateEditConfigClass EDateEditConfigClass;
-typedef struct _EDateEditConfigPrivate EDateEditConfigPrivate;
-
-struct _EDateEditConfig {
- GObject parent;
-
- EDateEditConfigPrivate *priv;
-};
-
-struct _EDateEditConfigClass {
- GObjectClass parent_class;
-};
-
-GType e_date_edit_config_get_type (void);
-EDateEditConfig *e_date_edit_config_new (EDateEdit *date_edit);
-EDateEdit *e_date_edit_config_get_edit (EDateEditConfig *edit_config);
-void e_date_edit_config_set_edit (EDateEditConfig *edit_config, EDateEdit *date_edit);
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/e-day-view-config.c b/calendar/gui/e-day-view-config.c
deleted file mode 100644
index a193e7bfa0..0000000000
--- a/calendar/gui/e-day-view-config.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "calendar-config.h"
-#include "e-day-view-config.h"
-
-struct _EDayViewConfigPrivate {
- EDayView *view;
-
- GList *notifications;
-};
-
-/* Property IDs */
-enum props {
- PROP_0,
- PROP_VIEW
-};
-
-G_DEFINE_TYPE (EDayViewConfig, e_day_view_config, G_TYPE_OBJECT)
-
-static void
-e_day_view_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- EDayViewConfig *view_config;
-
- view_config = E_DAY_VIEW_CONFIG (object);
-
- switch (property_id) {
- case PROP_VIEW:
- e_day_view_config_set_view (view_config, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_day_view_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- EDayViewConfig *view_config;
-
- view_config = E_DAY_VIEW_CONFIG (object);
-
- switch (property_id) {
- case PROP_VIEW:
- g_value_set_object (value, e_day_view_config_get_view (view_config));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_day_view_config_dispose (GObject *object)
-{
- EDayViewConfig *view_config = E_DAY_VIEW_CONFIG (object);
-
- e_day_view_config_set_view (view_config, NULL);
-
- if (G_OBJECT_CLASS (e_day_view_config_parent_class)->dispose)
- G_OBJECT_CLASS (e_day_view_config_parent_class)->dispose (object);
-}
-
-static void
-e_day_view_config_finalize (GObject *object)
-{
- EDayViewConfig *view_config = E_DAY_VIEW_CONFIG (object);
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_day_view_config_parent_class)->finalize)
- G_OBJECT_CLASS (e_day_view_config_parent_class)->finalize (object);
-}
-
-static void
-e_day_view_config_class_init (EDayViewConfigClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *spec;
-
- /* Method override */
- gobject_class->set_property = e_day_view_config_set_property;
- gobject_class->get_property = e_day_view_config_get_property;
- gobject_class->dispose = e_day_view_config_dispose;
- gobject_class->finalize = e_day_view_config_finalize;
-
- spec = g_param_spec_object ("view", NULL, NULL, e_day_view_get_type (),
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (gobject_class, PROP_VIEW, spec);
-}
-
-static void
-e_day_view_config_init (EDayViewConfig *view_config)
-{
- view_config->priv = g_new0 (EDayViewConfigPrivate, 1);
-
-}
-
-EDayViewConfig *
-e_day_view_config_new (EDayView *day_view)
-{
- EDayViewConfig *view_config;
-
- view_config = g_object_new (e_day_view_config_get_type (), "view", day_view, NULL);
-
- return view_config;
-}
-
-EDayView *
-e_day_view_config_get_view (EDayViewConfig *view_config)
-{
- EDayViewConfigPrivate *priv;
-
- g_return_val_if_fail (view_config != NULL, NULL);
- g_return_val_if_fail (E_IS_DAY_VIEW_CONFIG (view_config), NULL);
-
- priv = view_config->priv;
-
- return priv->view;
-}
-
-static void
-set_week_start (EDayView *day_view)
-{
- gint week_start_day;
-
- week_start_day = calendar_config_get_week_start_day ();
-
- /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
- week_start_day = (week_start_day + 6) % 7;
-
- e_day_view_set_week_start_day (day_view, week_start_day);
-}
-
-static void
-week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_week_start (priv->view);
-}
-
-static void
-set_twentyfour_hour (EDayView *day_view)
-{
- gboolean use_24_hour;
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- e_calendar_view_set_use_24_hour_format (E_CALENDAR_VIEW (day_view), use_24_hour);
-
- /* To redraw the times */
- gtk_widget_queue_draw (day_view->time_canvas);
-}
-
-static void
-twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_twentyfour_hour (priv->view);
-}
-
-static void
-set_working_days (EDayView *day_view)
-{
- CalWeekdays working_days;
-
- working_days = calendar_config_get_working_days ();
-
- e_day_view_set_working_days (day_view, working_days);
-}
-
-static void
-working_days_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_working_days (priv->view);
-}
-
-static void
-set_day_start_hour (EDayView *day_view)
-{
- gint start_hour, start_minute, end_hour, end_minute;
-
- e_day_view_get_working_day (day_view, &start_hour, &start_minute, &end_hour, &end_minute);
-
- start_hour = calendar_config_get_day_start_hour ();
-
- e_day_view_set_working_day (day_view, start_hour, start_minute, end_hour, end_minute);
-}
-
-static void
-day_start_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_day_start_hour (priv->view);
-}
-
-static void
-set_day_start_minute (EDayView *day_view)
-{
- gint start_hour, start_minute, end_hour, end_minute;
-
- e_day_view_get_working_day (day_view, &start_hour, &start_minute, &end_hour, &end_minute);
-
- start_minute = calendar_config_get_day_start_minute ();
-
- e_day_view_set_working_day (day_view, start_hour, start_minute, end_hour, end_minute);
-}
-
-static void
-day_start_minute_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_day_start_minute (priv->view);
-}
-
-static void
-set_day_end_hour (EDayView *day_view)
-{
- gint start_hour, start_minute, end_hour, end_minute;
-
- e_day_view_get_working_day (day_view, &start_hour, &start_minute, &end_hour, &end_minute);
-
- end_hour = calendar_config_get_day_end_hour ();
-
- e_day_view_set_working_day (day_view, start_hour, start_minute, end_hour, end_minute);
-}
-
-static void
-day_end_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_day_end_hour (priv->view);
-}
-
-static void
-set_day_end_minute (EDayView *day_view)
-{
- gint start_hour, start_minute, end_hour, end_minute;
-
- e_day_view_get_working_day (day_view, &start_hour, &start_minute, &end_hour, &end_minute);
-
- end_minute = calendar_config_get_day_end_minute ();
-
- e_day_view_set_working_day (day_view, start_hour, start_minute, end_hour, end_minute);
-}
-
-static void
-day_end_minute_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_day_end_minute (priv->view);
-}
-
-static void
-set_time_divisions (EDayView *day_view)
-{
- gint time_divisions;
-
- time_divisions = calendar_config_get_time_divisions ();
-
- e_day_view_set_mins_per_row (day_view, time_divisions);
-}
-
-static void
-time_divisions_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_time_divisions (priv->view);
-}
-
-static void
-set_marcus_bains (EDayView *day_view)
-{
- gboolean show_marcus_bains_line;
- const gchar *dayview_color, *timebar_color;
-
- calendar_config_get_marcus_bains (&show_marcus_bains_line, &dayview_color, &timebar_color);
-
- e_day_view_set_marcus_bains (day_view, show_marcus_bains_line, dayview_color, timebar_color);
-}
-
-static void
-marcus_bains_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_marcus_bains (priv->view);
-}
-
-static void
-set_show_event_end (EDayView *day_view)
-{
- gboolean show_event_end;
-
- show_event_end = calendar_config_get_show_event_end ();
-
- e_day_view_set_show_event_end_times (day_view, show_event_end);
-}
-
-static void
-show_event_end_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EDayViewConfig *view_config = data;
- EDayViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_show_event_end (priv->view);
-}
-
-void
-e_day_view_config_set_view (EDayViewConfig *view_config, EDayView *day_view)
-{
- EDayViewConfigPrivate *priv;
- gint not_1, not_2, mbnot;
- guint not;
- GList *l;
-
- g_return_if_fail (view_config != NULL);
- g_return_if_fail (E_IS_DAY_VIEW_CONFIG (view_config));
-
- priv = view_config->priv;
-
- if (priv->view) {
- g_object_unref (priv->view);
- priv->view = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
-
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- /* If the new view is NULL, return right now */
- if (!day_view)
- return;
-
- priv->view = g_object_ref (day_view);
-
- /* Week start */
- set_week_start (day_view);
-
- not = calendar_config_add_notification_week_start_day (week_start_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* 24 Hour format */
- set_twentyfour_hour (day_view);
-
- not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Working days */
- set_working_days (day_view);
-
- not = calendar_config_add_notification_working_days (working_days_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Day start hour */
- set_day_start_hour (day_view);
-
- not = calendar_config_add_notification_day_start_hour (day_start_hour_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Day start minute */
- set_day_start_minute (day_view);
-
- not = calendar_config_add_notification_day_start_minute (day_start_minute_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Day end hour */
- set_day_end_hour (day_view);
-
- not = calendar_config_add_notification_day_end_hour (day_end_hour_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Day start minute */
- set_day_end_minute (day_view);
-
- not = calendar_config_add_notification_day_end_minute (day_end_minute_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Time divisions */
- set_time_divisions (day_view);
-
- not = calendar_config_add_notification_time_divisions (time_divisions_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Showing Marcus Bains Line */
- set_marcus_bains (day_view);
-
- calendar_config_add_notification_marcus_bains (marcus_bains_changed_cb, view_config, &mbnot, &not_1, &not_2);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (mbnot));
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not_1));
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not_2));
-
- /* Showing event end */
- set_show_event_end (day_view);
-
- not = calendar_config_add_notification_show_event_end (show_event_end_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-}
diff --git a/calendar/gui/e-day-view-config.h b/calendar/gui/e-day-view-config.h
deleted file mode 100644
index 25d208b432..0000000000
--- a/calendar/gui/e-day-view-config.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_DAY_VIEW_CONFIG_H_
-#define _E_DAY_VIEW_CONFIG_H_
-
-#include "e-day-view.h"
-
-G_BEGIN_DECLS
-
-#define E_DAY_VIEW_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_day_view_config_get_type (), EDayViewConfig)
-#define E_DAY_VIEW_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_day_view_config_get_type (), EDayViewConfigClass)
-#define E_IS_DAY_VIEW_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_day_view_config_get_type ())
-
-typedef struct _EDayViewConfig EDayViewConfig;
-typedef struct _EDayViewConfigClass EDayViewConfigClass;
-typedef struct _EDayViewConfigPrivate EDayViewConfigPrivate;
-
-struct _EDayViewConfig {
- GObject parent;
-
- EDayViewConfigPrivate *priv;
-};
-
-struct _EDayViewConfigClass {
- GObjectClass parent_class;
-};
-
-GType e_day_view_config_get_type (void);
-EDayViewConfig *e_day_view_config_new (EDayView *day_view);
-EDayView *e_day_view_config_get_view (EDayViewConfig *view_config);
-void e_day_view_config_set_view (EDayViewConfig *view_config, EDayView *day_view);
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c
index c211a456f8..a3f951b276 100644
--- a/calendar/gui/e-day-view-main-item.c
+++ b/calendar/gui/e-day-view-main-item.c
@@ -392,7 +392,7 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
day, draw_region);
}
- if (e_day_view_get_show_marcus_bains (day_view)) {
+ if (e_day_view_marcus_bains_get_show_line (day_view)) {
icaltimezone *zone;
struct icaltimetype time_now, day_start;
gint marcus_bains_y;
@@ -610,6 +610,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem,
{
EDayView *day_view;
EDayViewEvent *event;
+ ECalModel *model;
gint item_x, item_y, item_w, item_h, bar_y1, bar_y2;
GdkGC *gc;
GdkColor bg_color;
@@ -643,6 +644,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem,
gint row_y;
day_view = dvmitem->day_view;
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
/* If the event is currently being dragged, don't draw it. It will
be drawn in the special drag items. */
@@ -975,7 +977,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem,
cairo_clip (cr);
cairo_new_path (cr);
- if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
+ if (e_cal_model_get_use_24_hour_format (model)) {
cairo_translate (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH - 32, item_y + item_h - 8);
end_regsizeime = g_strdup_printf ("%2i:%02i",
end_display_hour, end_minute);
@@ -1177,7 +1179,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem,
&end_suffix,
&end_suffix_width);
- if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
+ if (e_cal_model_get_use_24_hour_format (model)) {
if (day_view->show_event_end_times && show_span) {
/* 24 hour format with end time. */
text = g_strdup_printf
diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c
index 7d0b5a6467..8c4a2fdf07 100644
--- a/calendar/gui/e-day-view-time-item.c
+++ b/calendar/gui/e-day-view-time-item.c
@@ -279,6 +279,7 @@ edvti_draw_zone (GnomeCanvasItem *canvas_item,
{
EDayView *day_view;
EDayViewTimeItem *dvtmitem;
+ ECalModel *model;
GtkStyle *style;
const gchar *suffix;
gchar buffer[64], *midnight_day = NULL, *midnight_month = NULL;
@@ -302,6 +303,8 @@ edvti_draw_zone (GnomeCanvasItem *canvas_item,
day_view = dvtmitem->day_view;
g_return_if_fail (day_view != NULL);
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+
style = gtk_widget_get_style (GTK_WIDGET (day_view));
small_font_desc = style->font_desc;
@@ -410,7 +413,7 @@ edvti_draw_zone (GnomeCanvasItem *canvas_item,
E_DVTMI_LARGE_HOUR_Y_PAD);
/* Draw the Marcus Bains Line first, so it appears under other elements. */
- if (e_day_view_get_show_marcus_bains (day_view)) {
+ if (e_day_view_marcus_bains_get_show_line (day_view)) {
struct icaltimetype time_now;
gint marcus_bains_y;
@@ -485,7 +488,7 @@ edvti_draw_zone (GnomeCanvasItem *canvas_item,
strcpy (buffer, midnight_day);
strcat (buffer, " ");
strcat (buffer, midnight_month);
- } else if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
+ } else if (e_cal_model_get_use_24_hour_format (model)) {
g_snprintf (buffer, sizeof (buffer), "%i:%02i",
display_hour, minute);
} else {
@@ -565,7 +568,7 @@ edvti_draw_zone (GnomeCanvasItem *canvas_item,
if (show_midnight_date)
strcpy (buffer, midnight_month);
else if (minute == 0
- && !e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
+ && !e_cal_model_get_use_24_hour_format (model)) {
strcpy (buffer, suffix);
} else {
g_snprintf (buffer, sizeof (buffer),
diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c
index 6ebbde46a5..a1f083e1b8 100644
--- a/calendar/gui/e-day-view-top-item.c
+++ b/calendar/gui/e-day-view-top-item.c
@@ -369,6 +369,7 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem,
gint start_day, end_day;
gint item_x, item_y, item_w, item_h;
gint text_x, icon_x, icon_y, icon_x_inc;
+ ECalModel *model;
ECalComponent *comp;
gchar buffer[16];
gint hour, display_hour, minute, offset, time_width, time_x;
@@ -389,6 +390,8 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem,
gdouble x0, y0, rect_height, rect_width, radius;
day_view = dvtitem->day_view;
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+
cr = gdk_cairo_create (drawable);
gradient = calendar_config_get_display_events_gradient ();
@@ -561,7 +564,7 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem,
e_day_view_convert_time_to_display (day_view, hour,
&display_hour,
&suffix, &suffix_width);
- if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
+ if (e_cal_model_get_use_24_hour_format (model)) {
g_snprintf (buffer, sizeof (buffer), "%i:%02i",
display_hour, minute);
} else {
@@ -610,7 +613,7 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem,
&display_hour,
&suffix,
&suffix_width);
- if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
+ if (e_cal_model_get_use_24_hour_format (model)) {
g_snprintf (buffer, sizeof (buffer),
"%i:%02i", display_hour, minute);
} else {
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index ed83c9d855..cb69eecf50 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -35,9 +35,10 @@
#include <misc/e-canvas-utils.h>
#include <misc/e-popup-menu.h>
#include <misc/e-gui-utils.h>
-#include <misc/e-unicode.h>
+#include <e-util/e-unicode.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
#include <glib/gi18n.h>
+#include <e-util/e-binding.h>
#include <e-util/e-categories-config.h>
#include <e-util/e-dialog-utils.h>
@@ -51,7 +52,6 @@
#include "print.h"
#include "comp-util.h"
#include "itip-utils.h"
-#include "calendar-commands.h"
#include "calendar-config.h"
#include "goto.h"
#include "e-cal-model-calendar.h"
@@ -261,7 +261,7 @@ static void e_day_view_on_event_right_click (EDayView *day_view,
gint day,
gint event_num);
static void e_day_view_show_popup_menu (EDayView *day_view,
- GdkEvent *gdk_event,
+ GdkEventButton *event,
gint day,
gint event_num);
@@ -432,38 +432,364 @@ static void e_day_view_queue_layout (EDayView *day_view);
static void e_day_view_cancel_layout (EDayView *day_view);
static gboolean e_day_view_layout_timeout_cb (gpointer data);
+enum {
+ PROP_0,
+ PROP_MARCUS_BAINS_SHOW_LINE,
+ PROP_MARCUS_BAINS_DAY_VIEW_COLOR,
+ PROP_MARCUS_BAINS_TIME_BAR_COLOR,
+ PROP_MINS_PER_ROW,
+ PROP_WORK_DAY_END_HOUR,
+ PROP_WORK_DAY_END_MINUTE,
+ PROP_WORK_DAY_START_HOUR,
+ PROP_WORK_DAY_START_MINUTE,
+ PROP_WORKING_DAYS
+};
+
G_DEFINE_TYPE (EDayView, e_day_view, E_TYPE_CALENDAR_VIEW)
static void
-e_day_view_class_init (EDayViewClass *class)
+day_view_notify_week_start_day_cb (EDayView *day_view)
{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- ECalendarViewClass *view_class;
+ /* XXX Write a EWorkWeekView subclass, like EMonthView. */
+
+ if (day_view->work_week_view)
+ e_day_view_recalc_work_week (day_view);
+}
+
+static void
+day_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MARCUS_BAINS_SHOW_LINE:
+ e_day_view_marcus_bains_set_show_line (
+ E_DAY_VIEW (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_MARCUS_BAINS_DAY_VIEW_COLOR:
+ e_day_view_marcus_bains_set_day_view_color (
+ E_DAY_VIEW (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_MARCUS_BAINS_TIME_BAR_COLOR:
+ e_day_view_marcus_bains_set_time_bar_color (
+ E_DAY_VIEW (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_MINS_PER_ROW:
+ e_day_view_set_mins_per_row (
+ E_DAY_VIEW (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_WORK_DAY_END_HOUR:
+ e_day_view_set_work_day_end_hour (
+ E_DAY_VIEW (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_WORK_DAY_END_MINUTE:
+ e_day_view_set_work_day_end_minute (
+ E_DAY_VIEW (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_WORK_DAY_START_HOUR:
+ e_day_view_set_work_day_start_hour (
+ E_DAY_VIEW (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_WORK_DAY_START_MINUTE:
+ e_day_view_set_work_day_start_minute (
+ E_DAY_VIEW (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_WORKING_DAYS:
+ e_day_view_set_working_days (
+ E_DAY_VIEW (object),
+ g_value_get_int (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+day_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MARCUS_BAINS_SHOW_LINE:
+ g_value_set_boolean (
+ value,
+ e_day_view_marcus_bains_get_show_line (
+ E_DAY_VIEW (object)));
+ return;
+
+ case PROP_MARCUS_BAINS_DAY_VIEW_COLOR:
+ g_value_set_string (
+ value,
+ e_day_view_marcus_bains_get_day_view_color (
+ E_DAY_VIEW (object)));
+ return;
+
+ case PROP_MARCUS_BAINS_TIME_BAR_COLOR:
+ g_value_set_string (
+ value,
+ e_day_view_marcus_bains_get_time_bar_color (
+ E_DAY_VIEW (object)));
+ return;
+
+ case PROP_MINS_PER_ROW:
+ g_value_set_int (
+ value,
+ e_day_view_get_mins_per_row (
+ E_DAY_VIEW (object)));
+ return;
+
+ case PROP_WORK_DAY_END_HOUR:
+ g_value_set_int (
+ value,
+ e_day_view_get_work_day_end_hour (
+ E_DAY_VIEW (object)));
+ return;
+
+ case PROP_WORK_DAY_END_MINUTE:
+ g_value_set_int (
+ value,
+ e_day_view_get_work_day_end_minute (
+ E_DAY_VIEW (object)));
+ return;
+
+ case PROP_WORK_DAY_START_HOUR:
+ g_value_set_int (
+ value,
+ e_day_view_get_work_day_start_hour (
+ E_DAY_VIEW (object)));
+ return;
+
+ case PROP_WORK_DAY_START_MINUTE:
+ g_value_set_int (
+ value,
+ e_day_view_get_work_day_start_minute (
+ E_DAY_VIEW (object)));
+ return;
+
+ case PROP_WORKING_DAYS:
+ g_value_set_int (
+ value,
+ e_day_view_get_working_days (
+ E_DAY_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+day_view_constructed (GObject *object)
+{
+ ECalModel *model;
+ EDayView *day_view;
+ EShellSettings *shell_settings;
+
+ day_view = E_DAY_VIEW (object);
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+ shell_settings = e_cal_model_get_shell_settings (model);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-day-view-show-week-numbers",
+ G_OBJECT (day_view->week_number_label), "visible");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-marcus-bains-show-line",
+ G_OBJECT (day_view), "marcus-bains-show-line");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-marcus-bains-day-view-color",
+ G_OBJECT (day_view), "marcus-bains-day-view-color");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-marcus-bains-time-bar-color",
+ G_OBJECT (day_view), "marcus-bains-time-bar-color");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-time-divisions",
+ G_OBJECT (day_view), "mins-per-row");
- object_class = (GtkObjectClass *) class;
- widget_class = (GtkWidgetClass *) class;
- view_class = (ECalendarViewClass *) class;
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-work-day-end-hour",
+ G_OBJECT (day_view), "work-day-end-hour");
- /* Method override */
- object_class->destroy = e_day_view_destroy;
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-work-day-end-minute",
+ G_OBJECT (day_view), "work-day-end-minute");
- widget_class->realize = e_day_view_realize;
- widget_class->unrealize = e_day_view_unrealize;
- widget_class->style_set = e_day_view_style_set;
- widget_class->size_allocate = e_day_view_size_allocate;
- widget_class->focus_in_event = e_day_view_focus_in;
- widget_class->focus_out_event = e_day_view_focus_out;
- widget_class->key_press_event = e_day_view_key_press;
- widget_class->focus = e_day_view_focus;
- widget_class->popup_menu = e_day_view_popup_menu;
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-work-day-start-hour",
+ G_OBJECT (day_view), "work-day-start-hour");
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-work-day-start-minute",
+ G_OBJECT (day_view), "work-day-start-minute");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-working-days-bitset",
+ G_OBJECT (day_view), "working-days");
+
+ g_signal_connect_swapped (
+ model, "notify::week-start-day",
+ G_CALLBACK (day_view_notify_week_start_day_cb), day_view);
+}
+
+static void
+e_day_view_class_init (EDayViewClass *class)
+{
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+ GtkWidgetClass *widget_class;
+ ECalendarViewClass *view_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = day_view_set_property;
+ object_class->get_property = day_view_get_property;
+ object_class->constructed = day_view_constructed;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = e_day_view_destroy;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = e_day_view_realize;
+ widget_class->unrealize = e_day_view_unrealize;
+ widget_class->style_set = e_day_view_style_set;
+ widget_class->size_allocate = e_day_view_size_allocate;
+ widget_class->focus_in_event = e_day_view_focus_in;
+ widget_class->focus_out_event = e_day_view_focus_out;
+ widget_class->key_press_event = e_day_view_key_press;
+ widget_class->focus = e_day_view_focus;
+ widget_class->popup_menu = e_day_view_popup_menu;
+
+ view_class = E_CALENDAR_VIEW_CLASS (class);
view_class->get_selected_events = e_day_view_get_selected_events;
view_class->get_selected_time_range = e_day_view_get_selected_time_range;
view_class->set_selected_time_range = e_day_view_set_selected_time_range;
view_class->get_visible_time_range = e_day_view_get_visible_time_range;
view_class->paste_text = e_day_view_paste_text;
+ /* XXX Should these be constructor properties? */
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MARCUS_BAINS_SHOW_LINE,
+ g_param_spec_boolean (
+ "marcus-bains-show-line",
+ "Marcus Bains Show Line",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MARCUS_BAINS_DAY_VIEW_COLOR,
+ g_param_spec_string (
+ "marcus-bains-day-view-color",
+ "Marcus Bains Day View Color",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MARCUS_BAINS_TIME_BAR_COLOR,
+ g_param_spec_string (
+ "marcus-bains-time-bar-color",
+ "Marcus Bains Time Bar Color",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MINS_PER_ROW,
+ g_param_spec_int (
+ "mins-per-row",
+ "Minutes Per Row",
+ NULL,
+ 5, /* not a continuous range */
+ 60, /* valid values: 5, 10, 15, 30, 60 */
+ 30,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WORK_DAY_END_HOUR,
+ g_param_spec_int (
+ "work-day-end-hour",
+ "Work Day End Hour",
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WORK_DAY_END_MINUTE,
+ g_param_spec_int (
+ "work-day-end-minute",
+ "Work Day End Minute",
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WORK_DAY_START_HOUR,
+ g_param_spec_int (
+ "work-day-start-hour",
+ "Work Day Start Hour",
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WORK_DAY_START_MINUTE,
+ g_param_spec_int (
+ "work-day-start-minute",
+ "Work Day Start Minute",
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ /* FIXME Make this a real GFlags type. */
+ g_object_class_install_property (
+ object_class,
+ PROP_WORKING_DAYS,
+ g_param_spec_int (
+ "working-days",
+ "Working Days",
+ NULL,
+ 0x00,
+ 0x7f,
+ 0,
+ G_PARAM_READWRITE));
+
/* init the accessibility support for e_day_view */
e_day_view_a11y_init ();
}
@@ -703,12 +1029,6 @@ timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone,
}
static void
-dview_show_week_no_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- e_day_view_set_show_week_number (data, calendar_config_get_dview_show_week_no ());
-}
-
-static void
e_day_view_init (EDayView *day_view)
{
gint day;
@@ -764,10 +1084,9 @@ e_day_view_init (EDayView *day_view)
day_view->work_day_end_hour = 17;
day_view->work_day_end_minute = 0;
day_view->show_event_end_times = TRUE;
- day_view->week_start_day = 0;
day_view->scroll_to_work_day = TRUE;
- day_view->show_marcus_bains_line = TRUE;
+ day_view->marcus_bains_show_line = TRUE;
day_view->marcus_bains_day_view_color = NULL;
day_view->marcus_bains_time_bar_color = NULL;
@@ -813,9 +1132,6 @@ e_day_view_init (EDayView *day_view)
day_view->week_number_label = gtk_label_new ("");
gtk_table_attach (GTK_TABLE (day_view), day_view->week_number_label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
- day_view->wn_notif_id = calendar_config_add_notification_dview_show_week_no (dview_show_week_no_changed_cb, day_view);
- if (calendar_config_get_dview_show_week_no ())
- gtk_widget_show (day_view->week_number_label);
/*
* Top Canvas
@@ -1064,16 +1380,17 @@ e_day_view_on_canvas_realized (GtkWidget *widget,
*
* Creates a new #EDayView.
**/
-GtkWidget *
+ECalendarView *
e_day_view_new (ECalModel *model)
{
- GObject *day_view;
+ ECalendarView *day_view;
- day_view = g_object_new (e_day_view_get_type (), NULL);
- e_calendar_view_set_model ((ECalendarView *)day_view, model);
- init_model ((EDayView *) day_view, model);
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
- return GTK_WIDGET (day_view);
+ day_view = g_object_new (E_TYPE_DAY_VIEW, "model", model, NULL);
+ init_model (E_DAY_VIEW (day_view), model);
+
+ return day_view;
}
static void
@@ -1088,11 +1405,6 @@ e_day_view_destroy (GtkObject *object)
e_day_view_stop_auto_scroll (day_view);
- if (day_view->wn_notif_id) {
- calendar_config_remove_notification (day_view->wn_notif_id);
- day_view->wn_notif_id = 0;
- }
-
if (day_view->large_font_desc) {
pango_font_description_free (day_view->large_font_desc);
day_view->large_font_desc = NULL;
@@ -2127,10 +2439,15 @@ e_day_view_find_work_week_start (EDayView *day_view,
time_t start_time)
{
GDate date;
+ ECalModel *model;
+ gint week_start_day;
gint weekday, day, i;
guint offset;
struct icaltimetype tt = icaltime_null_time ();
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+ week_start_day = e_cal_model_get_week_start_day (model);
+
time_to_gdate_with_zone (&date, start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
/* The start of the work-week is the first working day after the
@@ -2142,7 +2459,7 @@ e_day_view_find_work_week_start (EDayView *day_view,
/* Calculate the first working day of the week, 0 (Sun) to 6 (Sat).
It will automatically default to the week start day if no days
are set as working days. */
- day = (day_view->week_start_day + 1) % 7;
+ day = (week_start_day + 1) % 7;
for (i = 0; i < 7; i++) {
if (day_view->working_days & (1 << day))
break;
@@ -2311,27 +2628,6 @@ e_day_view_recalc_day_starts (EDayView *day_view,
g_free (str);
}
-gboolean
-e_day_view_get_show_week_number (EDayView *day_view)
-{
- g_return_val_if_fail (day_view != NULL, FALSE);
-
- return GTK_WIDGET_VISIBLE (day_view->week_number_label);
-}
-
-void
-e_day_view_set_show_week_number (EDayView *day_view, gboolean show)
-{
- g_return_if_fail (day_view != NULL);
-
- if (e_day_view_get_show_week_number (day_view) != show) {
- if (show)
- gtk_widget_show (day_view->week_number_label);
- else
- gtk_widget_hide (day_view->week_number_label);
- }
-}
-
/* Whether we are displaying a work-week, in which case the display always
starts on the first day of the working week. */
gboolean
@@ -2389,7 +2685,7 @@ e_day_view_set_days_shown (EDayView *day_view,
}
gint
-e_day_view_get_mins_per_row (EDayView *day_view)
+e_day_view_get_mins_per_row (EDayView *day_view)
{
g_return_val_if_fail (E_IS_DAY_VIEW (day_view), -1);
@@ -2397,8 +2693,8 @@ e_day_view_get_mins_per_row (EDayView *day_view)
}
void
-e_day_view_set_mins_per_row (EDayView *day_view,
- gint mins_per_row)
+e_day_view_set_mins_per_row (EDayView *day_view,
+ gint mins_per_row)
{
gint day;
@@ -2416,6 +2712,8 @@ e_day_view_set_mins_per_row (EDayView *day_view,
day_view->mins_per_row = mins_per_row;
e_day_view_recalc_num_rows (day_view);
+ g_object_notify (G_OBJECT (day_view), "mins-per-row");
+
/* If we aren't visible, we'll sort it out later. */
if (!E_CALENDAR_VIEW (day_view)->in_focus)
return;
@@ -2440,7 +2738,7 @@ e_day_view_set_mins_per_row (EDayView *day_view,
/* This specifies the working days in the week. The value is a bitwise
combination of day flags. Defaults to Mon-Fri. */
EDayViewDays
-e_day_view_get_working_days (EDayView *day_view)
+e_day_view_get_working_days (EDayView *day_view)
{
g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0);
@@ -2448,8 +2746,8 @@ e_day_view_get_working_days (EDayView *day_view)
}
void
-e_day_view_set_working_days (EDayView *day_view,
- EDayViewDays days)
+e_day_view_set_working_days (EDayView *day_view,
+ EDayViewDays days)
{
g_return_if_fail (E_IS_DAY_VIEW (day_view));
@@ -2464,16 +2762,23 @@ e_day_view_set_working_days (EDayView *day_view,
/* We have to do this, as the new working days may have no effect on
the days shown, but we still want the background color to change. */
gtk_widget_queue_draw (day_view->main_canvas);
+
+ g_object_notify (G_OBJECT (day_view), "working-days");
}
static void
e_day_view_recalc_work_week_days_shown (EDayView *day_view)
{
+ ECalModel *model;
+ gint week_start_day;
gint first_day, last_day, i, days_shown;
gboolean has_working_days = FALSE;
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+ week_start_day = e_cal_model_get_week_start_day (model);
+
/* Find the first working day in the week, 0 (Sun) to 6 (Sat). */
- first_day = (day_view->week_start_day + 1) % 7;
+ first_day = (week_start_day + 1) % 7;
for (i = 0; i < 7; i++) {
if (day_view->working_days & (1 << first_day)) {
has_working_days = TRUE;
@@ -2484,7 +2789,7 @@ e_day_view_recalc_work_week_days_shown (EDayView *day_view)
if (has_working_days) {
/* Now find the last working day of the week, backwards. */
- last_day = day_view->week_start_day % 7;
+ last_day = week_start_day % 7;
for (i = 0; i < 7; i++) {
if (day_view->working_days & (1 << last_day))
break;
@@ -2503,86 +2808,162 @@ e_day_view_recalc_work_week_days_shown (EDayView *day_view)
/* The start and end time of the working day. This only affects the background
colors. */
+gint
+e_day_view_get_work_day_start_hour (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), -1);
+
+ return day_view->work_day_start_hour;
+}
+
void
-e_day_view_get_working_day (EDayView *day_view,
- gint *start_hour,
- gint *start_minute,
- gint *end_hour,
- gint *end_minute)
+e_day_view_set_work_day_start_hour (EDayView *day_view,
+ gint work_day_start_hour)
{
g_return_if_fail (E_IS_DAY_VIEW (day_view));
- *start_hour = day_view->work_day_start_hour;
- *start_minute = day_view->work_day_start_minute;
- *end_hour = day_view->work_day_end_hour;
- *end_minute = day_view->work_day_end_minute;
+ day_view->work_day_start_hour = work_day_start_hour;
+
+ gtk_widget_queue_draw (day_view->main_canvas);
+
+ g_object_notify (G_OBJECT (day_view), "work-day-start-hour");
+}
+
+gint
+e_day_view_get_work_day_start_minute (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), -1);
+
+ return day_view->work_day_start_minute;
}
void
-e_day_view_set_working_day (EDayView *day_view,
- gint start_hour,
- gint start_minute,
- gint end_hour,
- gint end_minute)
+e_day_view_set_work_day_start_minute (EDayView *day_view,
+ gint work_day_start_minute)
{
g_return_if_fail (E_IS_DAY_VIEW (day_view));
- day_view->work_day_start_hour = start_hour;
- day_view->work_day_start_minute = start_minute;
- day_view->work_day_end_hour = end_hour;
- day_view->work_day_end_minute = end_minute;
+ day_view->work_day_start_minute = work_day_start_minute;
gtk_widget_queue_draw (day_view->main_canvas);
+
+ g_object_notify (G_OBJECT (day_view), "work-day-start-minute");
}
-/* Whether we display the Marcus Bains Line in the main canvas and time canvas. */
-gboolean
-e_day_view_get_show_marcus_bains (EDayView *day_view)
+gint
+e_day_view_get_work_day_end_hour (EDayView *day_view)
{
- g_return_val_if_fail (E_IS_DAY_VIEW (day_view), TRUE);
- return day_view->show_marcus_bains_line;
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), -1);
+
+ return day_view->work_day_end_hour;
+}
+
+void
+e_day_view_set_work_day_end_hour (EDayView *day_view,
+ gint work_day_end_hour)
+{
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ day_view->work_day_end_hour = work_day_end_hour;
+
+ gtk_widget_queue_draw (day_view->main_canvas);
+
+ g_object_notify (G_OBJECT (day_view), "work-day-end-hour");
+}
+
+gint
+e_day_view_get_work_day_end_minute (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), -1);
+
+ return day_view->work_day_end_minute;
+}
+
+void
+e_day_view_set_work_day_end_minute (EDayView *day_view,
+ gint work_day_end_minute)
+{
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ day_view->work_day_end_minute = work_day_end_minute;
+
+ gtk_widget_queue_draw (day_view->main_canvas);
+
+ g_object_notify (G_OBJECT (day_view), "work-day-end-minute");
}
/* Force a redraw of the Marcus Bains Lines */
void
-e_day_view_update_marcus_bains (EDayView *day_view)
+e_day_view_marcus_bains_update (EDayView *day_view)
{
g_return_if_fail (E_IS_DAY_VIEW (day_view));
gtk_widget_queue_draw (day_view->main_canvas);
gtk_widget_queue_draw (day_view->time_canvas);
}
-/* Update the variables controlling the Marcus Bains Line (display toggle, and colors). */
+gboolean
+e_day_view_marcus_bains_get_show_line (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), FALSE);
+
+ return day_view->marcus_bains_show_line;
+}
+
void
-e_day_view_set_marcus_bains (EDayView *day_view,
- gboolean show_line,
- const gchar *dayview_color,
- const gchar *timebar_color)
+e_day_view_marcus_bains_set_show_line (EDayView *day_view,
+ gboolean show_line)
{
g_return_if_fail (E_IS_DAY_VIEW (day_view));
- if ((day_view->show_marcus_bains_line != show_line) |
- (day_view->marcus_bains_day_view_color != dayview_color) |
- (day_view->marcus_bains_time_bar_color != timebar_color)) {
+ day_view->marcus_bains_show_line = show_line;
- if (day_view->marcus_bains_day_view_color)
- g_free (day_view->marcus_bains_day_view_color);
- if (day_view->marcus_bains_time_bar_color)
- g_free (day_view->marcus_bains_time_bar_color);
+ e_day_view_marcus_bains_update (day_view);
- day_view->show_marcus_bains_line = show_line;
- if (dayview_color)
- day_view->marcus_bains_day_view_color = g_strdup (dayview_color);
- else
- day_view->marcus_bains_day_view_color = NULL;
+ g_object_notify (G_OBJECT (day_view), "marcus-bains-show-line");
+}
- if (timebar_color)
- day_view->marcus_bains_time_bar_color = g_strdup (timebar_color);
- else
- day_view->marcus_bains_time_bar_color = NULL;
+const gchar *
+e_day_view_marcus_bains_get_day_view_color (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL);
- e_day_view_update_marcus_bains (day_view);
- }
+ return day_view->marcus_bains_day_view_color;
+}
+
+void
+e_day_view_marcus_bains_set_day_view_color (EDayView *day_view,
+ const gchar *day_view_color)
+{
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ g_free (day_view->marcus_bains_day_view_color);
+ day_view->marcus_bains_day_view_color = g_strdup (day_view_color);
+
+ e_day_view_marcus_bains_update (day_view);
+
+ g_object_notify (G_OBJECT (day_view), "marcus-bains-day-view-color");
+}
+
+const gchar *
+e_day_view_marcus_bains_get_time_bar_color (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL);
+
+ return day_view->marcus_bains_time_bar_color;
+}
+
+void
+e_day_view_marcus_bains_set_time_bar_color (EDayView *day_view,
+ const gchar *time_bar_color)
+{
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ g_free (day_view->marcus_bains_time_bar_color);
+ day_view->marcus_bains_time_bar_color = g_strdup (time_bar_color);
+
+ e_day_view_marcus_bains_update (day_view);
+
+ g_object_notify (G_OBJECT (day_view), "marcus-bains-time-bar-color");
}
/* Whether we display event end times in the main canvas. */
@@ -2621,32 +3002,6 @@ e_day_view_set_show_times_cb (EDayView *day_view,
return TRUE;
}
-/* The first day of the week, 0 (Monday) to 6 (Sunday). */
-gint
-e_day_view_get_week_start_day (EDayView *day_view)
-{
- g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0);
-
- return day_view->week_start_day;
-}
-
-void
-e_day_view_set_week_start_day (EDayView *day_view,
- gint week_start_day)
-{
- g_return_if_fail (E_IS_DAY_VIEW (day_view));
- g_return_if_fail (week_start_day >= 0);
- g_return_if_fail (week_start_day < 7);
-
- if (day_view->week_start_day == week_start_day)
- return;
-
- day_view->week_start_day = week_start_day;
-
- if (day_view->work_week_view)
- e_day_view_recalc_work_week (day_view);
-}
-
static void
e_day_view_recalc_work_week (EDayView *day_view)
{
@@ -3345,28 +3700,15 @@ e_day_view_on_event_double_click (EDayView *day_view,
}
static void
-popup_destroyed_cb (gpointer data, GObject *where_object_was)
-{
- EDayView *day_view = data;
-
- day_view->popup_event_day = -1;
- day_view->popup_event_num = -1;
-}
-
-static void
e_day_view_show_popup_menu (EDayView *day_view,
- GdkEvent *gdk_event,
+ GdkEventButton *event,
gint day,
gint event_num)
{
- GtkMenu *popup;
-
day_view->popup_event_day = day;
day_view->popup_event_num = event_num;
- popup = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (day_view));
- g_object_weak_ref (G_OBJECT (popup), popup_destroyed_cb, day_view);
- gtk_menu_popup (popup, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0, gdk_event?gdk_event->button.time:gtk_get_current_event_time());
+ e_calendar_view_popup_event (E_CALENDAR_VIEW (day_view), event);
}
static gboolean
@@ -3448,8 +3790,7 @@ e_day_view_on_event_right_click (EDayView *day_view,
gint day,
gint event_num)
{
- e_day_view_show_popup_menu (day_view, (GdkEvent*)bevent,
- day, event_num);
+ e_day_view_show_popup_menu (day_view, bevent, day, event_num);
}
static gboolean
@@ -3521,8 +3862,7 @@ e_day_view_update_calendar_selection_time (EDayView *day_view)
#if 0
calendar = e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view));
if (calendar)
- gnome_calendar_set_selected_time_range (calendar,
- start, end);
+ gnome_calendar_set_selected_time_range (calendar, start);
#endif
}
@@ -6322,7 +6662,8 @@ e_day_view_on_editing_stopped (EDayView *day_view,
if (!e_cal_create_object (client, icalcomp, NULL, NULL))
g_message (G_STRLOC ": Could not create the object!");
else
- gnome_calendar_emit_user_created_signal (day_view, e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)), client);
+ e_calendar_view_emit_user_created (
+ E_CALENDAR_VIEW (day_view));
/* we remove the object since we either got the update from the server or failed */
e_day_view_remove_event_cb (day_view, day, event_num, NULL);
@@ -7776,10 +8117,14 @@ e_day_view_convert_time_to_display (EDayView *day_view,
const gchar **suffix,
gint *suffix_width)
{
+ ECalModel *model;
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+
/* Calculate the actual hour number to display. For 12-hour
format we convert 0-23 to 12-11am/12-11pm. */
*display_hour = hour;
- if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) {
+ if (e_cal_model_get_use_24_hour_format (model)) {
*suffix = "";
*suffix_width = 0;
} else {
@@ -7801,11 +8146,13 @@ e_day_view_convert_time_to_display (EDayView *day_view,
gint
e_day_view_get_time_string_width (EDayView *day_view)
{
+ ECalModel *model;
gint time_width;
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
time_width = day_view->digit_width * 4 + day_view->colon_width;
- if (!e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view)))
+ if (!e_cal_model_get_use_24_hour_format (model))
time_width += MAX (day_view->am_string_width,
day_view->pm_string_width);
diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h
index d4f1ca680c..6729186b21 100644
--- a/calendar/gui/e-day-view.h
+++ b/calendar/gui/e-day-view.h
@@ -182,16 +182,30 @@ struct _EDayViewEvent {
guint8 num_columns;
};
-#define E_DAY_VIEW(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_day_view_get_type (), EDayView)
-#define E_DAY_VIEW_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_day_view_get_type (), EDayViewClass)
-#define E_IS_DAY_VIEW(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_day_view_get_type ())
+/* Standard GObject macros */
+#define E_TYPE_DAY_VIEW \
+ (e_day_view_get_type ())
+#define E_DAY_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_DAY_VIEW, EDayView))
+#define E_DAY_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_DAY_VIEW, EDayViewClass))
+#define E_IS_DAY_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_DAY_VIEW))
+#define E_IS_DAY_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_DAY_VIEW))
+#define E_DAY_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_DAY_VIEW, EDayViewClass))
typedef struct _EDayView EDayView;
typedef struct _EDayViewClass EDayViewClass;
-struct _EDayView
-{
- ECalendarView cal_view;
+struct _EDayView {
+ ECalendarView parent;
/* The top canvas where the dates are shown. */
GtkWidget *top_dates_canvas;
@@ -219,8 +233,6 @@ struct _EDayView
/* label showing week number in upper-left corner */
GtkWidget *week_number_label;
- /* option change notification id for week number */
- guint wn_notif_id;
/* S-expression for query and the query object */
ECalView *query;
@@ -295,16 +307,13 @@ struct _EDayView
gint work_day_end_minute;
/* Whether we show the Marcus Bains Line in the main canvas and time canvas. */
- gboolean show_marcus_bains_line;
+ gboolean marcus_bains_show_line;
gchar *marcus_bains_day_view_color;
gchar *marcus_bains_time_bar_color;
/* Whether we use show event end times in the main canvas. */
gboolean show_event_end_times;
- /* The first day of the week, 0 (Monday) to 6 (Sunday). */
- gint week_start_day;
-
/* This is set to TRUE when the widget is created, so it scrolls to
the start of the working day when first shown. */
gboolean scroll_to_work_day;
@@ -483,7 +492,7 @@ struct _EDayViewClass
};
GType e_day_view_get_type (void);
-GtkWidget* e_day_view_new (ECalModel *model);
+ECalendarView * e_day_view_new (ECalModel *model);
/* Whether we are displaying a work-week, in which case the display always
starts on the first day of the working week. */
@@ -511,34 +520,42 @@ void e_day_view_set_working_days (EDayView *day_view,
/* The start and end time of the working day. This only affects the background
colors. */
-void e_day_view_get_working_day (EDayView *day_view,
- gint *start_hour,
- gint *start_minute,
- gint *end_hour,
- gint *end_minute);
-void e_day_view_set_working_day (EDayView *day_view,
- gint start_hour,
- gint start_minute,
- gint end_hour,
- gint end_minute);
+gint e_day_view_get_work_day_start_hour (EDayView *day_view);
+void e_day_view_set_work_day_start_hour (EDayView *day_view,
+ gint work_day_start_hour);
+gint e_day_view_get_work_day_start_minute (EDayView *day_view);
+void e_day_view_set_work_day_start_minute (EDayView *day_view,
+ gint work_day_start_minute);
+gint e_day_view_get_work_day_end_hour (EDayView *day_view);
+void e_day_view_set_work_day_end_hour (EDayView *day_view,
+ gint work_day_end_hour);
+gint e_day_view_get_work_day_end_minute (EDayView *day_view);
+void e_day_view_set_work_day_end_minute (EDayView *day_view,
+ gint work_day_end_minute);
/* Whether we display the Marcus Bains Line in the main canvas and time canvas. */
-gboolean e_day_view_get_show_marcus_bains (EDayView *day_view);
-void e_day_view_set_marcus_bains (EDayView *day_view,
- gboolean show_line,
- const gchar *dayview_color,
- const gchar *timebar_color);
+void e_day_view_marcus_bains_update (EDayView *day_view);
+gboolean e_day_view_marcus_bains_get_show_line(EDayView *day_view);
+void e_day_view_marcus_bains_set_show_line(EDayView *day_view,
+ gboolean show_line);
+const gchar *
+ e_day_view_marcus_bains_get_day_view_color
+ (EDayView *day_view);
+void e_day_view_marcus_bains_set_day_view_color
+ (EDayView *day_view,
+ const gchar *day_view_color);
+const gchar *
+ e_day_view_marcus_bains_get_time_bar_color
+ (EDayView *day_view);
+void e_day_view_marcus_bains_set_time_bar_color
+ (EDayView *day_view,
+ const gchar *time_bar_color);
/* Whether we display event end times in the main canvas. */
gboolean e_day_view_get_show_event_end_times (EDayView *day_view);
void e_day_view_set_show_event_end_times (EDayView *day_view,
gboolean show);
-/* The first day of the week, 0 (Monday) to 6 (Sunday). */
-gint e_day_view_get_week_start_day (EDayView *day_view);
-void e_day_view_set_week_start_day (EDayView *day_view,
- gint week_start_day);
-
void e_day_view_delete_occurrence (EDayView *day_view);
/* Returns the number of selected events (0 or 1 at present). */
@@ -607,12 +624,6 @@ void e_day_view_ensure_rows_visible (EDayView *day_view,
gint start_row,
gint end_row);
-void e_day_view_update_marcus_bains (EDayView *day_view);
-
-/* Week number in upper-left corner of the day view widget */
-gboolean e_day_view_get_show_week_number (EDayView *day_view);
-void e_day_view_set_show_week_number (EDayView *day_view, gboolean show);
-
G_END_DECLS
#endif /* _E_DAY_VIEW_H_ */
diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c
index 85b0accc33..dd231548e1 100644
--- a/calendar/gui/e-itip-control.c
+++ b/calendar/gui/e-itip-control.c
@@ -31,8 +31,6 @@
#include <unistd.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-exception.h>
#include <gtkhtml/gtkhtml.h>
#include <gtkhtml/gtkhtml-embedded.h>
#include <gtkhtml/gtkhtml-stream.h>
@@ -52,6 +50,7 @@
#include "itip-utils.h"
#include "e-itip-control.h"
#include "common/authentication.h"
+#include <shell/e-shell.h>
struct _EItipControlPrivate {
GtkWidget *html;
@@ -243,12 +242,18 @@ source_changed_cb (ESourceComboBox *escb, EItipControl *itip)
static void
find_cal_opened_cb (ECal *ecal, ECalendarStatus status, gpointer data)
{
+ EShell *shell;
+ EShellSettings *shell_settings;
EItipControlFindData *fd = data;
EItipControlPrivate *priv;
ESource *source;
ECalSourceType source_type;
icalcomponent *icalcomp;
+ /* FIXME Pass this in. */
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
source_type = e_cal_get_source_type (ecal);
source = e_cal_get_source (ecal);
@@ -275,20 +280,24 @@ find_cal_opened_cb (ECal *ecal, ECalendarStatus status, gpointer data)
if (fd->count == 0) {
if (fd->show_selector && !priv->current_ecal && priv->vbox.widget) {
GtkWidget *escb;
+ const gchar *property_name;
gchar *uid;
switch (priv->type) {
case E_CAL_SOURCE_TYPE_EVENT:
- uid = calendar_config_get_primary_calendar ();
+ property_name = "cal-primary-calendar";
break;
case E_CAL_SOURCE_TYPE_TODO:
- uid = calendar_config_get_primary_tasks ();
+ property_name = "cal-primary-tasks";
break;
default:
uid = NULL;
g_return_if_reached ();
}
+ uid = e_shell_settings_get_string (
+ shell_settings, property_name);
+
if (uid) {
source = e_source_list_peek_source_by_uid (priv->source_lists[priv->type], uid);
g_free (uid);
diff --git a/calendar/gui/e-meeting-list-view.c b/calendar/gui/e-meeting-list-view.c
index 29a4f535d3..980370e3af 100644
--- a/calendar/gui/e-meeting-list-view.c
+++ b/calendar/gui/e-meeting-list-view.c
@@ -27,9 +27,6 @@
#include <string.h>
#include <gtk/gtk.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-widget.h>
-#include <bonobo/bonobo-exception.h>
#include <glib/gi18n.h>
#include <libebook/e-book.h>
#include <libebook/e-vcard.h>
@@ -830,7 +827,7 @@ process_section (EMeetingListView *view, GList *destinations, icalparameter_role
name = e_destination_get_name (dest);
/* Get the field as attendee from the backend */
- if (e_cal_get_ldap_attribute (e_meeting_store_get_e_cal (priv->store),
+ if (e_cal_get_ldap_attribute (e_meeting_store_get_client (priv->store),
&attr, NULL)) {
/* FIXME this should be more general */
if (!g_ascii_strcasecmp (attr, "icscalendar")) {
diff --git a/calendar/gui/e-meeting-store.c b/calendar/gui/e-meeting-store.c
index 20bc6388da..8b9f02c5a5 100644
--- a/calendar/gui/e-meeting-store.c
+++ b/calendar/gui/e-meeting-store.c
@@ -31,13 +31,17 @@
#include <libecal/e-cal-util.h>
#include <libecal/e-cal-time-util.h>
#include <libedataserver/e-data-server-util.h>
-#include "calendar-config.h"
#include "itip-utils.h"
#include "e-meeting-utils.h"
#include "e-meeting-attendee.h"
#include "e-meeting-store.h"
-#define ROW_VALID(store, row) (row >= 0 && row < store->priv->attendees->len)
+#define ROW_VALID(store, row) \
+ (row >= 0 && row < store->priv->attendees->len)
+
+#define E_MEETING_STORE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEETING_STORE, EMeetingStorePrivate))
struct _EMeetingStorePrivate {
GPtrArray *attendees;
@@ -76,7 +80,14 @@ struct _EMeetingStoreQueueData {
GPtrArray *data;
};
-static GObjectClass *parent_class = NULL;
+enum {
+ PROP_0,
+ PROP_CLIENT,
+ PROP_FREE_BUSY_TEMPLATE,
+ PROP_TIMEZONE
+};
+
+static gpointer parent_class;
static icalparameter_cutype
text_to_type (const gchar *type)
@@ -523,13 +534,73 @@ refresh_queue_remove (EMeetingStore *store, EMeetingAttendee *attendee)
}
static void
-ems_finalize (GObject *obj)
+meeting_store_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CLIENT:
+ e_meeting_store_set_client (
+ E_MEETING_STORE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_FREE_BUSY_TEMPLATE:
+ e_meeting_store_set_free_busy_template (
+ E_MEETING_STORE (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_TIMEZONE:
+ e_meeting_store_set_timezone (
+ E_MEETING_STORE (object),
+ g_value_get_pointer (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+meeting_store_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CLIENT:
+ g_value_set_object (
+ value,
+ e_meeting_store_get_client (
+ E_MEETING_STORE (object)));
+ return;
+
+ case PROP_FREE_BUSY_TEMPLATE:
+ g_value_set_string (
+ value,
+ e_meeting_store_get_free_busy_template (
+ E_MEETING_STORE (object)));
+ return;
+
+ case PROP_TIMEZONE:
+ g_value_set_pointer (
+ value,
+ e_meeting_store_get_timezone (
+ E_MEETING_STORE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+meeting_store_finalize (GObject *object)
{
- EMeetingStore *store = E_MEETING_STORE (obj);
EMeetingStorePrivate *priv;
gint i;
- priv = store->priv;
+ priv = E_MEETING_STORE_GET_PRIVATE (object);
for (i = 0; i < priv->attendees->len; i++)
g_object_unref (g_ptr_array_index (priv->attendees, i));
@@ -539,7 +610,9 @@ ems_finalize (GObject *obj)
g_object_unref (priv->client);
while (priv->refresh_queue->len > 0)
- refresh_queue_remove (store, g_ptr_array_index (priv->refresh_queue, 0));
+ refresh_queue_remove (
+ E_MEETING_STORE (object),
+ g_ptr_array_index (priv->refresh_queue, 0));
g_ptr_array_free (priv->refresh_queue, TRUE);
g_hash_table_destroy (priv->refresh_data);
@@ -550,75 +623,100 @@ ems_finalize (GObject *obj)
g_mutex_free (priv->mutex);
- g_free (priv);
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (obj);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-ems_class_init (GObjectClass *klass)
+meeting_store_class_init (GObjectClass *class)
{
- parent_class = g_type_class_peek_parent (klass);
-
- klass->finalize = ems_finalize;
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMeetingStorePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = meeting_store_set_property;
+ object_class->get_property = meeting_store_get_property;
+ object_class->finalize = meeting_store_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "Client",
+ NULL,
+ E_TYPE_CAL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FREE_BUSY_TEMPLATE,
+ g_param_spec_string (
+ "free-busy-template",
+ "Free/Busy Template",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TIMEZONE,
+ g_param_spec_pointer (
+ "timezone",
+ "Timezone",
+ NULL,
+ G_PARAM_READWRITE));
}
static void
-ems_init (EMeetingStore *store)
+meeting_store_init (EMeetingStore *store)
{
- EMeetingStorePrivate *priv;
-
- priv = g_new0 (EMeetingStorePrivate, 1);
-
- store->priv = priv;
-
- priv->attendees = g_ptr_array_new ();
-
- priv->zone = calendar_config_get_icaltimezone ();
+ store->priv = E_MEETING_STORE_GET_PRIVATE (store);
- priv->fb_uri = calendar_config_get_free_busy_template ();
+ store->priv->attendees = g_ptr_array_new ();
+ store->priv->refresh_queue = g_ptr_array_new ();
+ store->priv->refresh_data = g_hash_table_new (g_str_hash, g_str_equal);
- priv->refresh_queue = g_ptr_array_new ();
- priv->refresh_data = g_hash_table_new (g_str_hash, g_str_equal);
+ store->priv->mutex = g_mutex_new ();
- priv->mutex = g_mutex_new ();
-
- priv->num_queries = 0;
+ store->priv->num_queries = 0;
}
GType
e_meeting_store_get_type (void)
{
- static GType ems_type = 0;
-
- if (!ems_type) {
- static const GTypeInfo ems_info = {
- sizeof (EMeetingStoreClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) ems_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMeetingStore),
- 0,
- (GInstanceInitFunc) ems_init };
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMeetingStoreClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) meeting_store_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMeetingStore),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) meeting_store_init,
+ NULL /* value_table */
+ };
static const GInterfaceInfo tree_model_info = {
- (GInterfaceInitFunc) ems_tree_model_init,
- NULL,
- NULL };
+ (GInterfaceInitFunc) ems_tree_model_init,
+ NULL,
+ NULL
+ };
- ems_type = g_type_register_static (GTK_TYPE_LIST_STORE,
- "EMeetingStore",
- &ems_info, 0);
+ type = g_type_register_static (
+ GTK_TYPE_LIST_STORE, "EMeetingStore", &type_info, 0);
- g_type_add_interface_static (ems_type,
- GTK_TYPE_TREE_MODEL,
- &tree_model_info);
+ g_type_add_interface_static (
+ type, GTK_TYPE_TREE_MODEL, &tree_model_info);
}
- return ems_type;
+ return type;
}
GObject *
@@ -628,53 +726,69 @@ e_meeting_store_new (void)
}
ECal *
-e_meeting_store_get_e_cal (EMeetingStore *store)
+e_meeting_store_get_client (EMeetingStore *store)
{
+ g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL);
+
return store->priv->client;
}
void
-e_meeting_store_set_e_cal (EMeetingStore *store, ECal *client)
+e_meeting_store_set_client (EMeetingStore *store,
+ ECal *client)
{
+ g_return_if_fail (E_IS_MEETING_STORE (store));
+
+ if (client != NULL) {
+ g_return_if_fail (E_IS_CAL (client));
+ g_object_ref (client);
+ }
+
if (store->priv->client != NULL)
g_object_unref (store->priv->client);
- if (client != NULL)
- g_object_ref (client);
store->priv->client = client;
+
+ g_object_notify (G_OBJECT (store), "client");
}
-icaltimezone *
-e_meeting_store_get_zone (EMeetingStore *store)
+const gchar *
+e_meeting_store_get_free_busy_template (EMeetingStore *store)
{
g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL);
- return store->priv->zone;
+ return store->priv->fb_uri;
}
void
-e_meeting_store_set_zone (EMeetingStore *store, icaltimezone *zone)
+e_meeting_store_set_free_busy_template (EMeetingStore *store,
+ const gchar *free_busy_template)
{
g_return_if_fail (E_IS_MEETING_STORE (store));
- store->priv->zone = zone;
+ g_free (store->priv->fb_uri);
+ store->priv->fb_uri = g_strdup (free_busy_template);
+
+ g_object_notify (G_OBJECT (store), "free-busy-template");
}
-gchar *
-e_meeting_store_get_fb_uri (EMeetingStore *store)
+icaltimezone *
+e_meeting_store_get_timezone (EMeetingStore *store)
{
g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL);
- return g_strdup (store->priv->fb_uri);
+ return store->priv->zone;
}
void
-e_meeting_store_set_fb_uri (EMeetingStore *store, const gchar *fb_uri)
+e_meeting_store_set_timezone (EMeetingStore *store,
+ icaltimezone *timezone)
{
g_return_if_fail (E_IS_MEETING_STORE (store));
- g_free (store->priv->fb_uri);
- store->priv->fb_uri = g_strdup (fb_uri);
+ store->priv->zone = timezone;
+
+ g_object_notify (G_OBJECT (store), "timezone");
}
static void
diff --git a/calendar/gui/e-meeting-store.h b/calendar/gui/e-meeting-store.h
index f67ad92ddd..62287a7b7e 100644
--- a/calendar/gui/e-meeting-store.h
+++ b/calendar/gui/e-meeting-store.h
@@ -20,24 +20,37 @@
*
*/
-#ifndef _E_MEETING_STORE_H_
-#define _E_MEETING_STORE_H_
+#ifndef E_MEETING_STORE_H
+#define E_MEETING_STORE_H
#include <gtk/gtk.h>
#include <libecal/e-cal.h>
#include "e-meeting-attendee.h"
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_MEETING_STORE \
+ (e_meeting_store_get_type ())
+#define E_MEETING_STORE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEETING_STORE, EMeetingStore))
+#define E_MEETING_STORE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEETING_STORE, EMeetingStoreClass))
+#define E_IS_MEETING_STORE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEETING_STORE))
+#define E_IS_MEETING_STORE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_MEETING_STORE))
+#define E_MEETING_STORE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEETING_STORE, EMeetingStoreClass))
-#define E_TYPE_MEETING_STORE (e_meeting_store_get_type ())
-#define E_MEETING_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MEETING_STORE, EMeetingStore))
-#define E_MEETING_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_STORE, EMeetingStoreClass))
-#define E_IS_MEETING_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MEETING_STORE))
-#define E_IS_MEETING_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MEETING_STORE))
+G_BEGIN_DECLS
-typedef struct _EMeetingStore EMeetingStore;
+typedef struct _EMeetingStore EMeetingStore;
+typedef struct _EMeetingStoreClass EMeetingStoreClass;
typedef struct _EMeetingStorePrivate EMeetingStorePrivate;
-typedef struct _EMeetingStoreClass EMeetingStoreClass;
typedef enum {
E_MEETING_STORE_ADDRESS_COL,
@@ -57,7 +70,6 @@ typedef enum {
struct _EMeetingStore {
GtkListStore parent;
-
EMeetingStorePrivate *priv;
};
@@ -65,48 +77,64 @@ struct _EMeetingStoreClass {
GtkListStoreClass parent_class;
};
-typedef gboolean (* EMeetingStoreRefreshCallback) (gpointer data);
-
-GType e_meeting_store_get_type (void);
-GObject *e_meeting_store_new (void);
-
-void e_meeting_store_set_value (EMeetingStore *im, gint row, gint col, const gchar *val);
-
-ECal *e_meeting_store_get_e_cal (EMeetingStore *im);
-void e_meeting_store_set_e_cal (EMeetingStore *im, ECal *client);
-
-icaltimezone *e_meeting_store_get_zone (EMeetingStore *im);
-void e_meeting_store_set_zone (EMeetingStore *im, icaltimezone *zone);
-
-gchar *e_meeting_store_get_fb_uri (EMeetingStore *im);
-void e_meeting_store_set_fb_uri (EMeetingStore *im, const gchar *fb_uri);
-
-void e_meeting_store_add_attendee (EMeetingStore *im, EMeetingAttendee *ia);
-EMeetingAttendee *e_meeting_store_add_attendee_with_defaults (EMeetingStore *im);
-
-void e_meeting_store_remove_attendee (EMeetingStore *im, EMeetingAttendee *ia);
-void e_meeting_store_remove_all_attendees (EMeetingStore *im);
-
-EMeetingAttendee *e_meeting_store_find_attendee (EMeetingStore *im, const gchar *address, gint *row);
-EMeetingAttendee *e_meeting_store_find_attendee_at_row (EMeetingStore *im, gint row);
-GtkTreePath *e_meeting_store_find_attendee_path (EMeetingStore *store, EMeetingAttendee *attendee);
-
-gint e_meeting_store_count_actual_attendees (EMeetingStore *im);
-const GPtrArray *e_meeting_store_get_attendees (EMeetingStore *im);
-
-void e_meeting_store_refresh_all_busy_periods (EMeetingStore *im,
- EMeetingTime *start,
- EMeetingTime *end,
- EMeetingStoreRefreshCallback call_back,
- gpointer data);
-void e_meeting_store_refresh_busy_periods (EMeetingStore *im,
- gint row,
- EMeetingTime *start,
- EMeetingTime *end,
- EMeetingStoreRefreshCallback call_back,
- gpointer data);
-
-guint e_meeting_store_get_num_queries (EMeetingStore *store);
+typedef gboolean (*EMeetingStoreRefreshCallback) (gpointer data);
+
+GType e_meeting_store_get_type (void);
+GObject * e_meeting_store_new (void);
+void e_meeting_store_set_value (EMeetingStore *meeting_store,
+ gint row,
+ gint col,
+ const gchar *val);
+ECal * e_meeting_store_get_client (EMeetingStore *meeting_store);
+void e_meeting_store_set_client (EMeetingStore *meeting_store,
+ ECal *client);
+const gchar * e_meeting_store_get_free_busy_template
+ (EMeetingStore *meeting_store);
+void e_meeting_store_set_free_busy_template
+ (EMeetingStore *meeting_store,
+ const gchar *free_busy_template);
+icaltimezone * e_meeting_store_get_timezone (EMeetingStore *meeting_store);
+void e_meeting_store_set_timezone (EMeetingStore *meeting_store,
+ icaltimezone *timezone);
+void e_meeting_store_add_attendee (EMeetingStore *meeting_store,
+ EMeetingAttendee *attendee);
+EMeetingAttendee *
+ e_meeting_store_add_attendee_with_defaults
+ (EMeetingStore *meeting_store);
+void e_meeting_store_remove_attendee (EMeetingStore *meeting_store,
+ EMeetingAttendee *attendee);
+void e_meeting_store_remove_all_attendees
+ (EMeetingStore *meeting_store);
+EMeetingAttendee *
+ e_meeting_store_find_attendee (EMeetingStore *meeting_store,
+ const gchar *address,
+ gint *row);
+EMeetingAttendee *
+ e_meeting_store_find_attendee_at_row
+ (EMeetingStore *meeting_store,
+ gint row);
+GtkTreePath * e_meeting_store_find_attendee_path
+ (EMeetingStore *meeting_store,
+ EMeetingAttendee *attendee);
+gint e_meeting_store_count_actual_attendees
+ (EMeetingStore *meeting_store);
+const GPtrArray *
+ e_meeting_store_get_attendees (EMeetingStore *meeting_store);
+void e_meeting_store_refresh_all_busy_periods
+ (EMeetingStore *meeting_store,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingStoreRefreshCallback call_back,
+ gpointer data);
+void e_meeting_store_refresh_busy_periods
+ (EMeetingStore *meeting_store,
+ gint row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingStoreRefreshCallback call_back,
+ gpointer data);
+
+guint e_meeting_store_get_num_queries (EMeetingStore *meeting_store);
G_END_DECLS
diff --git a/calendar/gui/e-meeting-time-sel.c b/calendar/gui/e-meeting-time-sel.c
index 1f4f953c9c..ea6fca83c9 100644
--- a/calendar/gui/e-meeting-time-sel.c
+++ b/calendar/gui/e-meeting-time-sel.c
@@ -35,19 +35,28 @@
#include <glib/gi18n.h>
#include <libgnomecanvas/gnome-canvas-widget.h>
-#include <misc/e-canvas.h>
-#include <misc/e-canvas-utils.h>
+#include "misc/e-canvas.h"
+#include "misc/e-canvas-utils.h"
-#include <misc/e-dateedit.h>
-#include <e-util/e-cursor.h>
-#include <e-util/e-util.h>
+#include "misc/e-dateedit.h"
+#include "e-util/e-binding.h"
+#include "e-util/e-cursor.h"
+#include "e-util/e-util.h"
-#include "calendar-component.h"
-#include "calendar-config.h"
#include "e-meeting-utils.h"
#include "e-meeting-list-view.h"
#include "e-meeting-time-sel-item.h"
+#define E_MEETING_TIME_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEETING_TIME_SELECTOR, EMeetingTimeSelectorPrivate))
+
+struct _EMeetingTimeSelectorPrivate {
+ gint week_start_day;
+ guint show_week_numbers : 1;
+ guint use_24_hour_format : 1;
+};
+
/* An array of hour strings for 24 hour time, "0:00" .. "23:00". */
const gchar *EMeetingTimeSelectorHours[24] = {
"0:00", "1:00", "2:00", "3:00", "4:00", "5:00", "6:00", "7:00",
@@ -76,15 +85,20 @@ const gchar *EMeetingTimeSelectorHours12[24] = {
/* This is the maximum scrolling speed. */
#define E_MEETING_TIME_SELECTOR_MAX_SCROLL_SPEED 4
-/* Signals */
+enum {
+ PROP_0,
+ PROP_SHOW_WEEK_NUMBERS,
+ PROP_USE_24_HOUR_FORMAT,
+ PROP_WEEK_START_DAY
+};
+
enum {
CHANGED,
LAST_SIGNAL
};
-static gint mts_signals [LAST_SIGNAL] = { 0 };
+static gint signals [LAST_SIGNAL] = { 0 };
-static void e_meeting_time_selector_destroy (GtkObject *object);
static void e_meeting_time_selector_alloc_named_color (EMeetingTimeSelector * mts,
const gchar *name, GdkColor *c);
static void e_meeting_time_selector_add_key_color (EMeetingTimeSelector * mts,
@@ -188,40 +202,179 @@ static void row_inserted_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter
static void row_changed_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
static void row_deleted_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data);
-static void free_busy_template_changed_cb (GConfClient *client, guint cnxn_id,
- GConfEntry *entry, gpointer user_data);
+static void free_busy_template_changed_cb (EMeetingTimeSelector *mts);
G_DEFINE_TYPE (EMeetingTimeSelector, e_meeting_time_selector, GTK_TYPE_TABLE)
static void
-e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * klass)
+meeting_time_selector_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHOW_WEEK_NUMBERS:
+ e_meeting_time_selector_set_show_week_numbers (
+ E_MEETING_TIME_SELECTOR (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_USE_24_HOUR_FORMAT:
+ e_meeting_time_selector_set_use_24_hour_format (
+ E_MEETING_TIME_SELECTOR (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_WEEK_START_DAY:
+ e_meeting_time_selector_set_week_start_day (
+ E_MEETING_TIME_SELECTOR (object),
+ g_value_get_int (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+meeting_time_selector_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHOW_WEEK_NUMBERS:
+ g_value_set_boolean (
+ value,
+ e_meeting_time_selector_get_show_week_numbers (
+ E_MEETING_TIME_SELECTOR (object)));
+ return;
+
+ case PROP_USE_24_HOUR_FORMAT:
+ g_value_set_boolean (
+ value,
+ e_meeting_time_selector_get_use_24_hour_format (
+ E_MEETING_TIME_SELECTOR (object)));
+ return;
+
+ case PROP_WEEK_START_DAY:
+ g_value_set_int (
+ value,
+ e_meeting_time_selector_get_week_start_day (
+ E_MEETING_TIME_SELECTOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+meeting_time_selector_destroy (GtkObject *object)
+{
+ EMeetingTimeSelector *mts;
+
+ mts = E_MEETING_TIME_SELECTOR (object);
+
+ e_meeting_time_selector_remove_timeout (mts);
+
+ if (mts->stipple) {
+ g_object_unref (mts->stipple);
+ mts->stipple = NULL;
+ }
+
+ if (mts->model) {
+ g_signal_handlers_disconnect_matched (
+ mts->model, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, mts);
+ g_object_unref (mts->model);
+ mts->model = NULL;
+ }
+
+ mts->display_top = NULL;
+ mts->display_main = NULL;
+
+ if (mts->fb_refresh_not != 0) {
+ g_source_remove (mts->fb_refresh_not);
+ mts->fb_refresh_not = 0;
+ }
+
+ if (mts->style_change_idle_id != 0) {
+ g_source_remove (mts->style_change_idle_id);
+ mts->style_change_idle_id = 0;
+ }
+
+ if (GTK_OBJECT_CLASS (e_meeting_time_selector_parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (e_meeting_time_selector_parent_class)->destroy)(object);
+}
+
+static void
+e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
GtkWidgetClass *widget_class;
- object_class = (GtkObjectClass *) klass;
- widget_class = (GtkWidgetClass *) klass;
+ g_type_class_add_private (class, sizeof (EMeetingTimeSelectorPrivate));
- mts_signals [CHANGED] =
- g_signal_new ("changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMeetingTimeSelectorClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = meeting_time_selector_set_property;
+ object_class->get_property = meeting_time_selector_get_property;
- object_class->destroy = e_meeting_time_selector_destroy;
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = meeting_time_selector_destroy;
- widget_class->realize = e_meeting_time_selector_realize;
- widget_class->unrealize = e_meeting_time_selector_unrealize;
- widget_class->style_set = e_meeting_time_selector_style_set;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = e_meeting_time_selector_realize;
+ widget_class->unrealize = e_meeting_time_selector_unrealize;
+ widget_class->style_set = e_meeting_time_selector_style_set;
widget_class->expose_event = e_meeting_time_selector_expose_event;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_WEEK_NUMBERS,
+ g_param_spec_boolean (
+ "show-week-numbers",
+ "Show Week Numbers",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USE_24_HOUR_FORMAT,
+ g_param_spec_boolean (
+ "use-24-hour-format",
+ "Use 24-Hour Format",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WEEK_START_DAY,
+ g_param_spec_int (
+ "week-start-day",
+ "Week Start Day",
+ NULL,
+ 0, /* Monday */
+ 6, /* Sunday */
+ 0,
+ G_PARAM_READWRITE));
+
+ signals[CHANGED] = g_signal_new (
+ "changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMeetingTimeSelectorClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
e_meeting_time_selector_init (EMeetingTimeSelector * mts)
{
+ mts->priv = E_MEETING_TIME_SELECTOR_GET_PRIVATE (mts);
+
/* The shadow is drawn in the border so it must be >= 2 pixels. */
gtk_container_set_border_width (GTK_CONTAINER (mts), 2);
@@ -237,10 +390,6 @@ e_meeting_time_selector_init (EMeetingTimeSelector * mts)
mts->list_view = NULL;
- mts->fb_uri_not =
- calendar_config_add_notification_free_busy_template ((GConfClientNotifyFunc) free_busy_template_changed_cb,
- mts);
-
mts->fb_refresh_not = 0;
mts->style_change_idle_id = 0;
}
@@ -301,6 +450,10 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
if (mts->model)
g_object_ref (mts->model);
+ g_signal_connect_swapped (
+ mts->model, "notify::free-busy-template",
+ G_CALLBACK (free_busy_template_changed_cb), mts);
+
g_signal_connect (mts->model, "row_inserted", G_CALLBACK (row_inserted_cb), mts);
g_signal_connect (mts->model, "row_changed", G_CALLBACK (row_changed_cb), mts);
g_signal_connect (mts->model, "row_deleted", G_CALLBACK (row_deleted_cb), mts);
@@ -587,8 +740,18 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
a11y_label);
}
e_date_edit_set_show_time (E_DATE_EDIT (mts->start_date_edit), TRUE);
- e_date_edit_set_use_24_hour_format (E_DATE_EDIT (mts->start_date_edit),
- calendar_config_get_24_hour_format ());
+
+ e_binding_new (
+ G_OBJECT (mts), "show-week-numbers",
+ G_OBJECT (mts->start_date_edit), "show-week-numbers");
+
+ e_binding_new (
+ G_OBJECT (mts), "use-24-hour-format",
+ G_OBJECT (mts->start_date_edit), "use-24-hour-format");
+
+ e_binding_new (
+ G_OBJECT (mts), "week-start-day",
+ G_OBJECT (mts->start_date_edit), "week-start-day");
gtk_table_attach (GTK_TABLE (table), mts->start_date_edit,
1, 2, 0, 1, GTK_FILL, 0, 0, 0);
@@ -614,8 +777,18 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
a11y_label);
}
e_date_edit_set_show_time (E_DATE_EDIT (mts->end_date_edit), TRUE);
- e_date_edit_set_use_24_hour_format (E_DATE_EDIT (mts->end_date_edit),
- calendar_config_get_24_hour_format ());
+
+ e_binding_new (
+ G_OBJECT (mts), "show-week-numbers",
+ G_OBJECT (mts->end_date_edit), "show-week-numbers");
+
+ e_binding_new (
+ G_OBJECT (mts), "use-24-hour-format",
+ G_OBJECT (mts->end_date_edit), "use-24-hour-format");
+
+ e_binding_new (
+ G_OBJECT (mts), "week-start-day",
+ G_OBJECT (mts->end_date_edit), "week-start-day");
gtk_table_attach (GTK_TABLE (table), mts->end_date_edit,
1, 2, 1, 2, GTK_FILL, 0, 0, 0);
@@ -667,7 +840,7 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
e_meeting_time_selector_update_end_date_edit (mts);
e_meeting_time_selector_update_date_popup_menus (mts);
- g_signal_emit (mts, mts_signals [CHANGED], 0);
+ g_signal_emit (mts, signals [CHANGED], 0);
}
/* This adds a color to the color key beneath the main display. If color is
@@ -755,7 +928,7 @@ e_meeting_time_selector_options_menu_detacher (GtkWidget *widget,
EMeetingTimeSelector *mts;
g_return_if_fail (widget != NULL);
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (widget));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (widget));
mts = E_MEETING_TIME_SELECTOR (widget);
g_return_if_fail (mts->options_menu == (GtkWidget*) menu);
@@ -770,7 +943,7 @@ e_meeting_time_selector_autopick_menu_detacher (GtkWidget *widget,
EMeetingTimeSelector *mts;
g_return_if_fail (widget != NULL);
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (widget));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (widget));
mts = E_MEETING_TIME_SELECTOR (widget);
g_return_if_fail (mts->autopick_menu == (GtkWidget*) menu);
@@ -783,52 +956,68 @@ e_meeting_time_selector_new (EMeetingStore *ems)
{
GtkWidget *mts;
- mts = GTK_WIDGET (g_object_new (e_meeting_time_selector_get_type (), NULL));
+ mts = g_object_new (E_TYPE_MEETING_TIME_SELECTOR, NULL);
e_meeting_time_selector_construct (E_MEETING_TIME_SELECTOR (mts), ems);
return mts;
}
-static void
-e_meeting_time_selector_destroy (GtkObject *object)
+gboolean
+e_meeting_time_selector_get_show_week_numbers (EMeetingTimeSelector *mts)
{
- EMeetingTimeSelector *mts;
+ g_return_val_if_fail (E_IS_MEETING_TIME_SELECTOR (mts), FALSE);
- mts = E_MEETING_TIME_SELECTOR (object);
+ return mts->priv->show_week_numbers;
+}
- e_meeting_time_selector_remove_timeout (mts);
+void
+e_meeting_time_selector_set_show_week_numbers (EMeetingTimeSelector *mts,
+ gboolean show_week_numbers)
+{
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
- if (mts->stipple) {
- g_object_unref (mts->stipple);
- mts->stipple = NULL;
- }
+ mts->priv->show_week_numbers = show_week_numbers;
- if (mts->model) {
- g_object_unref (mts->model);
- mts->model = NULL;
- }
+ g_object_notify (G_OBJECT (mts), "show-week-numbers");
+}
- mts->display_top = NULL;
- mts->display_main = NULL;
+gboolean
+e_meeting_time_selector_get_use_24_hour_format (EMeetingTimeSelector *mts)
+{
+ g_return_val_if_fail (E_IS_MEETING_TIME_SELECTOR (mts), FALSE);
- if (mts->fb_uri_not) {
- calendar_config_remove_notification (mts->fb_uri_not);
- mts->fb_uri_not = 0;
- }
+ return mts->priv->use_24_hour_format;
+}
- if (mts->fb_refresh_not != 0) {
- g_source_remove (mts->fb_refresh_not);
- mts->fb_refresh_not = 0;
- }
+void
+e_meeting_time_selector_set_use_24_hour_format (EMeetingTimeSelector *mts,
+ gboolean use_24_hour_format)
+{
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
- if (mts->style_change_idle_id != 0) {
- g_source_remove (mts->style_change_idle_id);
- mts->style_change_idle_id = 0;
- }
+ mts->priv->use_24_hour_format = use_24_hour_format;
- if (GTK_OBJECT_CLASS (e_meeting_time_selector_parent_class)->destroy)
- (*GTK_OBJECT_CLASS (e_meeting_time_selector_parent_class)->destroy)(object);
+ g_object_notify (G_OBJECT (mts), "use-24-hour-format");
+}
+
+gint
+e_meeting_time_selector_get_week_start_day (EMeetingTimeSelector *mts)
+{
+ g_return_val_if_fail (E_IS_MEETING_TIME_SELECTOR (mts), 0);
+
+ return mts->priv->week_start_day;
+}
+
+void
+e_meeting_time_selector_set_week_start_day (EMeetingTimeSelector *mts,
+ gint week_start_day)
+{
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
+
+ mts->priv->week_start_day = week_start_day;
+
+ g_object_notify (G_OBJECT (mts), "week-start-day");
}
static void
@@ -896,7 +1085,7 @@ style_change_idle_func (gpointer widget)
/* Calculate the widths of the hour strings in the style's font. */
max_hour_width = 0;
for (hour = 0; hour < 24; hour++) {
- if (calendar_config_get_24_hour_format ())
+ if (e_meeting_time_selector_get_use_24_hour_format (mts))
pango_layout_set_text (layout, EMeetingTimeSelectorHours [hour], -1);
else
pango_layout_set_text (layout, EMeetingTimeSelectorHours12 [hour], -1);
@@ -1054,7 +1243,7 @@ e_meeting_time_selector_set_meeting_time (EMeetingTimeSelector *mts,
gint end_hour,
gint end_minute)
{
- g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), FALSE);
+ g_return_val_if_fail (E_IS_MEETING_TIME_SELECTOR (mts), FALSE);
/* Check the dates are valid. */
if (!g_date_valid_dmy (start_day, start_month, start_year)
@@ -1083,7 +1272,7 @@ e_meeting_time_selector_set_meeting_time (EMeetingTimeSelector *mts,
e_meeting_time_selector_update_start_date_edit (mts);
e_meeting_time_selector_update_end_date_edit (mts);
- g_signal_emit (mts, mts_signals [CHANGED], 0);
+ g_signal_emit (mts, signals [CHANGED], 0);
return TRUE;
}
@@ -1116,7 +1305,7 @@ e_meeting_time_selector_set_working_hours_only (EMeetingTimeSelector *mts,
{
EMeetingTime saved_time;
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
if (mts->working_hours_only == working_hours_only)
return;
@@ -1141,7 +1330,7 @@ e_meeting_time_selector_set_working_hours (EMeetingTimeSelector *mts,
{
EMeetingTime saved_time;
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
if (mts->day_start_hour == day_start_hour
&& mts->day_start_minute == day_start_minute
@@ -1176,7 +1365,7 @@ e_meeting_time_selector_set_zoomed_out (EMeetingTimeSelector *mts,
{
EMeetingTime saved_time;
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
if (mts->zoomed_out == zoomed_out)
return;
@@ -1270,7 +1459,7 @@ void
e_meeting_time_selector_set_autopick_option (EMeetingTimeSelector *mts,
EMeetingTimeSelectorAutopickOption autopick_option)
{
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
switch (autopick_option) {
case E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_RESOURCES:
@@ -1295,7 +1484,7 @@ e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector *mts,
{
EMeetingTimeSelectorAttendee *attendee;
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
g_return_if_fail (row >= 0);
g_return_if_fail (row < mts->attendees->len);
@@ -1308,7 +1497,7 @@ e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector *mts,
void
e_meeting_time_selector_set_read_only (EMeetingTimeSelector *mts, gboolean read_only)
{
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
gtk_widget_set_sensitive (GTK_WIDGET (mts->list_view), !read_only);
gtk_widget_set_sensitive (mts->display_main, !read_only);
@@ -1335,7 +1524,7 @@ e_meeting_time_selector_dump (EMeetingTimeSelector *mts)
gint row, period_num;
gchar buffer[128];
- g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts));
+ g_return_if_fail (E_IS_MEETING_TIME_SELECTOR (mts));
g_print ("\n\nAttendee Information:\n");
@@ -1628,7 +1817,7 @@ e_meeting_time_selector_autopick (EMeetingTimeSelector *mts,
e_meeting_time_selector_update_start_date_edit (mts);
e_meeting_time_selector_update_end_date_edit (mts);
- g_signal_emit (mts, mts_signals [CHANGED], 0);
+ g_signal_emit (mts, signals [CHANGED], 0);
return;
}
@@ -2181,7 +2370,7 @@ e_meeting_time_selector_on_start_time_changed (GtkWidget *widget,
gtk_widget_queue_draw (mts->display_top);
gtk_widget_queue_draw (mts->display_main);
- g_signal_emit (mts, mts_signals [CHANGED], 0);
+ g_signal_emit (mts, signals [CHANGED], 0);
}
/* This is called when the meeting end time GnomeDateEdit is changed,
@@ -2230,7 +2419,7 @@ e_meeting_time_selector_on_end_time_changed (GtkWidget *widget,
gtk_widget_queue_draw (mts->display_top);
gtk_widget_queue_draw (mts->display_main);
- g_signal_emit (mts, mts_signals [CHANGED], 0);
+ g_signal_emit (mts, signals [CHANGED], 0);
}
/* This updates the ranges shown in the GnomeDateEdit popup menus, according
@@ -2444,7 +2633,7 @@ e_meeting_time_selector_drag_meeting_time (EMeetingTimeSelector *mts,
if (set_both_times
|| mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END
|| mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START)
- g_signal_emit (mts, mts_signals [CHANGED], 0);
+ g_signal_emit (mts, signals [CHANGED], 0);
}
/* This is the timeout function which handles auto-scrolling when the user is
@@ -2583,7 +2772,7 @@ e_meeting_time_selector_timeout_handler (gpointer data)
if (set_both_times
|| mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END
|| mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START)
- g_signal_emit (mts, mts_signals [CHANGED], 0);
+ g_signal_emit (mts, signals [CHANGED], 0);
scroll:
/* Redraw the canvases. We freeze and thaw the layouts so that they
@@ -2862,14 +3051,8 @@ row_deleted_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data)
static gboolean
free_busy_timeout_refresh (gpointer data)
{
- gchar *fb_uri;
-
EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data);
- fb_uri = calendar_config_get_free_busy_template ();
- e_meeting_store_set_fb_uri (mts->model, fb_uri);
- g_free (fb_uri);
-
/* Update all free/busy info, so we use the new template uri */
e_meeting_time_selector_refresh_free_busy (mts, 0, TRUE);
@@ -2879,19 +3062,12 @@ free_busy_timeout_refresh (gpointer data)
}
static void
-free_busy_template_changed_cb (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- gpointer data)
+free_busy_template_changed_cb (EMeetingTimeSelector *mts)
{
- EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data);
-
/* Wait REFRESH_PAUSE before refreshing, using the latest uri value */
- if (mts->fb_refresh_not != 0) {
+ if (mts->fb_refresh_not != 0)
g_source_remove (mts->fb_refresh_not);
- }
- mts->fb_refresh_not = g_timeout_add_seconds (REFRESH_PAUSE,
- free_busy_timeout_refresh,
- data);
+ mts->fb_refresh_not = g_timeout_add_seconds (
+ REFRESH_PAUSE, free_busy_timeout_refresh, mts);
}
diff --git a/calendar/gui/e-meeting-time-sel.h b/calendar/gui/e-meeting-time-sel.h
index b38dd98f74..1c61353c7b 100644
--- a/calendar/gui/e-meeting-time-sel.h
+++ b/calendar/gui/e-meeting-time-sel.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef _E_MEETING_TIME_SELECTOR_H_
-#define _E_MEETING_TIME_SELECTOR_H_
+#ifndef E_MEETING_TIME_SELECTOR_H
+#define E_MEETING_TIME_SELECTOR_H
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas.h>
@@ -31,14 +31,31 @@
#include "e-meeting-store.h"
#include "e-meeting-list-view.h"
-G_BEGIN_DECLS
-
/*
* EMeetingTimeSelector displays a list of attendees for a meeting and a
* graphical summary of the times which they are free and busy, allowing the
* user to select an appropriate time for a meeting.
*/
+/* Standard GObject macros */
+#define E_TYPE_MEETING_TIME_SELECTOR \
+ (e_meeting_time_selector_get_type ())
+#define E_MEETING_TIME_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEETING_TIME_SELECTOR, EMeetingTimeSelector))
+#define E_MEETING_TIME_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEETING_TIME_SELECTOR, EMeetingTimeSelectorClass))
+#define E_IS_MEETING_TIME_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEETING_TIME_SELECTOR))
+#define E_IS_MEETING_TIME_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MEETING_TIME_SELECTOR))
+#define E_MEETING_TIME_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEETING_TIME_SELECTOR))
+
/* Define this to include the debugging functions. */
#undef E_MEETING_TIME_SELECTOR_DEBUG
@@ -48,6 +65,8 @@ G_BEGIN_DECLS
#define E_MEETING_TIME_SELECTOR_TEXT_Y_PAD 3
#define E_MEETING_TIME_SELECTOR_TEXT_X_PAD 2
+G_BEGIN_DECLS
+
/* This is used to specify the format used when displaying the dates.
The full format is like 'Sunday, September 12, 1999'. The abbreviated format
is like 'Sun 12/9/99'. The short format is like '12/9/99'. The actual
@@ -84,19 +103,17 @@ extern const gchar *EMeetingTimeSelectorHours[24];
/* An array of hour strings for 12 hour time, "12:00am" .. "11:00pm". */
extern const gchar *EMeetingTimeSelectorHours12[24];
-#define E_MEETING_TIME_SELECTOR(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_meeting_time_selector_get_type (), EMeetingTimeSelector)
-#define E_MEETING_TIME_SELECTOR_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_meeting_time_selector_get_type (), EMeetingTimeSelectorClass)
-#define IS_E_MEETING_TIME_SELECTOR(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_meeting_time_selector_get_type ())
+typedef struct _EMeetingTimeSelector EMeetingTimeSelector;
+typedef struct _EMeetingTimeSelectorClass EMeetingTimeSelectorClass;
+typedef struct _EMeetingTimeSelectorPrivate EMeetingTimeSelectorPrivate;
-typedef struct _EMeetingTimeSelector EMeetingTimeSelector;
-typedef struct _EMeetingTimeSelectorClass EMeetingTimeSelectorClass;
-
-struct _EMeetingTimeSelector
-{
+struct _EMeetingTimeSelector {
/* We subclass a GtkTable which makes it easy to add extra widgets
if neccesary. */
GtkTable table;
+ EMeetingTimeSelectorPrivate *priv;
+
/*
* User Interface stuff - widgets, colors etc.
*/
@@ -246,9 +263,6 @@ struct _EMeetingTimeSelector
/* This is used to determine the delay between scrolls. */
gint scroll_count;
- /* The notification function id for Free/Busy template uri changes */
- guint fb_uri_not;
-
/* The notification function id for Free/Busy refreshes */
gboolean fb_refresh_not;
@@ -257,8 +271,7 @@ struct _EMeetingTimeSelector
guint style_change_idle_id;
};
-struct _EMeetingTimeSelectorClass
-{
+struct _EMeetingTimeSelectorClass {
GtkTableClass parent_class;
void (* changed) (EMeetingTimeSelector *mts);
@@ -269,9 +282,26 @@ struct _EMeetingTimeSelectorClass
* know where the data is coming from. This is mainly just for testing for now.
*/
-GType e_meeting_time_selector_get_type (void);
-GtkWidget* e_meeting_time_selector_new (EMeetingStore *ems);
-void e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *ems);
+GType e_meeting_time_selector_get_type (void);
+GtkWidget * e_meeting_time_selector_new (EMeetingStore *ems);
+void e_meeting_time_selector_construct
+ (EMeetingTimeSelector *mts,
+ EMeetingStore *ems);
+gboolean e_meeting_time_selector_get_show_week_numbers
+ (EMeetingTimeSelector *mts);
+void e_meeting_time_selector_set_show_week_numbers
+ (EMeetingTimeSelector *mts,
+ gboolean show_week_numbers);
+gboolean e_meeting_time_selector_get_use_24_hour_format
+ (EMeetingTimeSelector *mts);
+void e_meeting_time_selector_set_use_24_hour_format
+ (EMeetingTimeSelector *mts,
+ gboolean use_24_hour_format);
+gint e_meeting_time_selector_get_week_start_day
+ (EMeetingTimeSelector *mts);
+void e_meeting_time_selector_set_week_start_day
+ (EMeetingTimeSelector *mts,
+ gint week_start_day);
/* This returns the currently selected meeting time.
Note that months are 1-12 and days are 1-31. The start time is guaranteed to
@@ -383,4 +413,4 @@ gchar * e_meeting_time_selector_dump_date (GDate *date);
G_END_DECLS
-#endif /* _E_MEETING_TIME_SELECTOR_H_ */
+#endif /* E_MEETING_TIME_SELECTOR_H */
diff --git a/calendar/gui/e-memo-list-selector.c b/calendar/gui/e-memo-list-selector.c
new file mode 100644
index 0000000000..e31a9d4b6e
--- /dev/null
+++ b/calendar/gui/e-memo-list-selector.c
@@ -0,0 +1,287 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-memo-list-selector.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "e-memo-list-selector.h"
+
+#include <string.h>
+#include <libecal/e-cal.h>
+#include "calendar/common/authentication.h"
+#include "calendar/gui/comp-util.h"
+
+#define E_MEMO_LIST_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorPrivate))
+
+struct _EMemoListSelectorPrivate {
+ gint dummy_value;
+};
+
+enum {
+ DND_TARGET_TYPE_CALENDAR_LIST
+};
+
+static GtkTargetEntry drag_types[] = {
+ { (gchar *) "text/calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST },
+ { (gchar *) "text/x-calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST }
+};
+
+static gpointer parent_class;
+
+static gboolean
+memo_list_selector_update_single_object (ECal *client,
+ icalcomponent *icalcomp)
+{
+ gchar *uid;
+ icalcomponent *tmp_icalcomp;
+
+ uid = (gchar *) icalcomponent_get_uid (icalcomp);
+
+ if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL))
+ return e_cal_modify_object (
+ client, icalcomp, CALOBJ_MOD_ALL, NULL);
+
+ return e_cal_create_object (client, icalcomp, &uid, NULL);
+}
+
+static gboolean
+memo_list_selector_update_objects (ECal *client,
+ icalcomponent *icalcomp)
+{
+ icalcomponent *subcomp;
+ icalcomponent_kind kind;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VJOURNAL_COMPONENT)
+ return memo_list_selector_update_single_object (
+ client, icalcomp);
+ else if (kind != ICAL_VCALENDAR_COMPONENT)
+ return FALSE;
+
+ subcomp = icalcomponent_get_first_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ while (subcomp != NULL) {
+ gboolean success;
+
+ kind = icalcomponent_isa (subcomp);
+ if (kind == ICAL_VTIMEZONE_COMPONENT) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+
+ success = e_cal_add_timezone (client, zone, NULL);
+ icaltimezone_free (zone, 1);
+ if (!success)
+ return FALSE;
+ } else if (kind == ICAL_VJOURNAL_COMPONENT) {
+ success = memo_list_selector_update_single_object (
+ client, subcomp);
+ if (!success)
+ return FALSE;
+ }
+
+ subcomp = icalcomponent_get_next_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+memo_list_selector_process_data (ESourceSelector *selector,
+ ECal *client,
+ const gchar *source_uid,
+ icalcomponent *icalcomp,
+ GdkDragAction action)
+{
+ ESourceList *source_list;
+ ESource *source;
+ icalcomponent *tmp_icalcomp = NULL;
+ const gchar *uid;
+ gchar *old_uid = NULL;
+ gboolean success = FALSE;
+ gboolean read_only = TRUE;
+ GError *error = NULL;
+
+ /* FIXME Deal with GDK_ACTION_ASK. */
+ if (action == GDK_ACTION_COPY) {
+ old_uid = g_strdup (icalcomponent_get_uid (icalcomp));
+ uid = e_cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp, uid);
+ }
+
+ uid = icalcomponent_get_uid (icalcomp);
+ if (old_uid == NULL)
+ old_uid = g_strdup (uid);
+
+ if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, &error)) {
+ icalcomponent_free (tmp_icalcomp);
+ success = TRUE;
+ goto exit;
+ }
+
+ if (error != NULL && error->code != E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
+ g_message (
+ "Failed to search the object in destination "
+ "task list: %s", error->message);
+ g_error_free (error);
+ goto exit;
+ }
+
+ success = memo_list_selector_update_objects (client, icalcomp);
+
+ if (!success || action != GDK_ACTION_MOVE)
+ goto exit;
+
+ source_list = e_source_selector_get_source_list (selector);
+ source = e_source_list_peek_source_by_uid (source_list, source_uid);
+
+ if (!E_IS_SOURCE (source) || e_source_get_readonly (source))
+ goto exit;
+
+ client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+ if (client == NULL) {
+ g_message ("Cannot create source client to remove old memo");
+ goto exit;
+ }
+
+ e_cal_is_read_only (client, &read_only, NULL);
+ if (!read_only && e_cal_open (client, TRUE, NULL))
+ e_cal_remove_object (client, old_uid, NULL);
+ else if (!read_only)
+ g_message ("Cannot open source client to remove old memo");
+
+ g_object_unref (client);
+
+exit:
+ g_free (old_uid);
+
+ return success;
+}
+
+static gboolean
+memo_list_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
+{
+ ECal *client;
+ GSList *list, *iter;
+ gboolean success = FALSE;
+
+ client = auth_new_cal_from_source (
+ destination, E_CAL_SOURCE_TYPE_JOURNAL);
+
+ if (client == NULL || !e_cal_open (client, TRUE, NULL))
+ goto exit;
+
+ list = cal_comp_selection_get_string_list (selection_data);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ gchar *source_uid = iter->data;
+ icalcomponent *icalcomp;
+ gchar *component_string;
+
+ /* Each string is "source_uid\ncomponent_string". */
+ component_string = strchr (source_uid, '\n');
+ if (component_string == NULL)
+ continue;
+
+ *component_string++ = '\0';
+ icalcomp = icalparser_parse_string (component_string);
+ if (icalcomp == NULL)
+ continue;
+
+ success = memo_list_selector_process_data (
+ selector, client, source_uid, icalcomp, action);
+
+ icalcomponent_free (icalcomp);
+ }
+
+ g_slist_foreach (list, (GFunc) g_free, NULL);
+ g_slist_free (list);
+
+exit:
+ if (client != NULL)
+ g_object_unref (client);
+
+ return success;
+}
+
+static void
+memo_list_selector_class_init (EMemoListSelectorClass *class)
+{
+ ESourceSelectorClass *source_selector_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMemoListSelectorPrivate));
+
+ source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ source_selector_class->data_dropped = memo_list_selector_data_dropped;
+}
+
+static void
+memo_list_selector_init (EMemoListSelector *selector)
+{
+ selector->priv = E_MEMO_LIST_SELECTOR_GET_PRIVATE (selector);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+}
+
+GType
+e_memo_list_selector_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EMemoListSelectorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) memo_list_selector_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMemoListSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) memo_list_selector_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_SOURCE_SELECTOR, "EMemoListSelector",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_memo_list_selector_new (ESourceList *source_list)
+{
+ g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
+
+ return g_object_new (
+ E_TYPE_MEMO_LIST_SELECTOR,
+ "source-list", source_list, NULL);
+}
diff --git a/calendar/gui/e-memo-list-selector.h b/calendar/gui/e-memo-list-selector.h
new file mode 100644
index 0000000000..c10cff2a2e
--- /dev/null
+++ b/calendar/gui/e-memo-list-selector.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-memo-list-selector.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* XXX This widget is nearly identical to ETaskListSelector. If
+ * ECalendarSelector ever learns how to move selections from
+ * one source to another, perhaps these ESourceSelector sub-
+ * classes could someday be combined. */
+
+#ifndef E_MEMO_LIST_SELECTOR_H
+#define E_MEMO_LIST_SELECTOR_H
+
+#include <libedataserver/e-source-list.h>
+#include <libedataserverui/e-source-selector.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MEMO_LIST_SELECTOR \
+ (e_memo_list_selector_get_type ())
+#define E_MEMO_LIST_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelector))
+#define E_MEMO_LIST_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorClass))
+#define E_IS_MEMO_LIST_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEMO_LIST_SELECTOR))
+#define E_IS_MEMO_LIST_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MEMO_LIST_SELECTOR))
+#define E_MEMO_LIST_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMemoListSelector EMemoListSelector;
+typedef struct _EMemoListSelectorClass EMemoListSelectorClass;
+typedef struct _EMemoListSelectorPrivate EMemoListSelectorPrivate;
+
+struct _EMemoListSelector {
+ ESourceSelector parent;
+ EMemoListSelectorPrivate *priv;
+};
+
+struct _EMemoListSelectorClass {
+ ESourceSelectorClass parent_class;
+};
+
+GType e_memo_list_selector_get_type (void);
+GtkWidget * e_memo_list_selector_new (ESourceList *source_list);
+
+G_END_DECLS
+
+#endif /* E_MEMO_LIST_SELECTOR_H */
diff --git a/calendar/gui/e-memo-table-config.c b/calendar/gui/e-memo-table-config.c
deleted file mode 100644
index d79dac7073..0000000000
--- a/calendar/gui/e-memo-table-config.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "calendar-config.h"
-#include "e-cell-date-edit-config.h"
-#include "e-memo-table-config.h"
-
-struct _EMemoTableConfigPrivate {
- EMemoTable *table;
-
- ECellDateEditConfig *cell_config;
-
- GList *notifications;
-};
-
-G_DEFINE_TYPE (EMemoTableConfig, e_memo_table_config, G_TYPE_OBJECT)
-
-/* Property IDs */
-enum props {
- PROP_0,
- PROP_TABLE
-};
-
-static void
-e_memo_table_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- EMemoTableConfig *table_config;
-
- table_config = E_MEMO_TABLE_CONFIG (object);
-
- switch (property_id) {
- case PROP_TABLE:
- e_memo_table_config_set_table (table_config, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_memo_table_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- EMemoTableConfig *table_config;
-
- table_config = E_MEMO_TABLE_CONFIG (object);
-
- switch (property_id) {
- case PROP_TABLE:
- g_value_set_object (value, e_memo_table_config_get_table (table_config));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_memo_table_config_dispose (GObject *object)
-{
- EMemoTableConfig *table_config = E_MEMO_TABLE_CONFIG (object);
-
- e_memo_table_config_set_table (table_config, NULL);
-
- if (G_OBJECT_CLASS (e_memo_table_config_parent_class)->dispose)
- G_OBJECT_CLASS (e_memo_table_config_parent_class)->dispose (object);
-}
-
-static void
-e_memo_table_config_finalize (GObject *object)
-{
- EMemoTableConfig *table_config = E_MEMO_TABLE_CONFIG (object);
- EMemoTableConfigPrivate *priv;
-
- priv = table_config->priv;
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_memo_table_config_parent_class)->finalize)
- G_OBJECT_CLASS (e_memo_table_config_parent_class)->finalize (object);
-}
-
-static void
-e_memo_table_config_class_init (EMemoTableConfigClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *spec;
-
- /* Method override */
- gobject_class->set_property = e_memo_table_config_set_property;
- gobject_class->get_property = e_memo_table_config_get_property;
- gobject_class->dispose = e_memo_table_config_dispose;
- gobject_class->finalize = e_memo_table_config_finalize;
-
- spec = g_param_spec_object ("table", NULL, NULL, e_memo_table_get_type (),
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (gobject_class, PROP_TABLE, spec);
-}
-
-static void
-e_memo_table_config_init (EMemoTableConfig *table_config)
-{
- table_config->priv = g_new0 (EMemoTableConfigPrivate, 1);
-
-}
-
-EMemoTableConfig *
-e_memo_table_config_new (EMemoTable *table)
-{
- EMemoTableConfig *table_config;
-
- table_config = g_object_new (e_memo_table_config_get_type (), "table", table, NULL);
-
- return table_config;
-}
-
-EMemoTable *
-e_memo_table_config_get_table (EMemoTableConfig *table_config)
-{
- EMemoTableConfigPrivate *priv;
-
- g_return_val_if_fail (table_config != NULL, NULL);
- g_return_val_if_fail (E_IS_MEMO_TABLE_CONFIG (table_config), NULL);
-
- priv = table_config->priv;
-
- return priv->table;
-}
-
-static void
-set_timezone (EMemoTable *table)
-{
- ECalModel *model;
- icaltimezone *zone;
-
- zone = calendar_config_get_icaltimezone ();
- model = e_memo_table_get_model (table);
- if (model)
- e_cal_model_set_timezone (model, zone);
-}
-
-static void
-timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EMemoTableConfig *table_config = data;
- EMemoTableConfigPrivate *priv;
-
- priv = table_config->priv;
-
- set_timezone (priv->table);
-}
-
-static void
-set_twentyfour_hour (EMemoTable *table)
-{
- ECalModel *model;
- gboolean use_24_hour;
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- model = e_memo_table_get_model (table);
- if (model)
- e_cal_model_set_use_24_hour_format (model, use_24_hour);
-}
-
-static void
-twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EMemoTableConfig *table_config = data;
- EMemoTableConfigPrivate *priv;
-
- priv = table_config->priv;
-
- set_twentyfour_hour (priv->table);
-}
-
-void
-e_memo_table_config_set_table (EMemoTableConfig *table_config, EMemoTable *table)
-{
- EMemoTableConfigPrivate *priv;
- guint not;
- GList *l;
-
- g_return_if_fail (table_config != NULL);
- g_return_if_fail (E_IS_MEMO_TABLE_CONFIG (table_config));
-
- priv = table_config->priv;
-
- if (priv->table) {
- g_object_unref (priv->table);
- priv->table = NULL;
- }
-
- if (priv->cell_config) {
- g_object_unref (priv->cell_config);
- priv->cell_config = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
-
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- /* If the new view is NULL, return right now */
- if (!table)
- return;
-
- priv->table = g_object_ref (table);
-
- /* Time zone */
- set_timezone (table);
-
- not = calendar_config_add_notification_timezone (timezone_changed_cb, table_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* 24 Hour format */
- set_twentyfour_hour (table);
-
- not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, table_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Date cell */
- priv->cell_config = e_cell_date_edit_config_new (table->dates_cell);
-}
diff --git a/calendar/gui/e-memo-table-config.h b/calendar/gui/e-memo-table-config.h
deleted file mode 100644
index 68960d58dc..0000000000
--- a/calendar/gui/e-memo-table-config.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_MEMO_TABLE_CONFIG_H_
-#define _E_MEMO_TABLE_CONFIG_H_
-
-#include "e-memo-table.h"
-
-G_BEGIN_DECLS
-
-#define E_MEMO_TABLE_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_memo_table_config_get_type (), EMemoTableConfig)
-#define E_MEMO_TABLE_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_memo_table_config_get_type (), EMemoTableConfigClass)
-#define E_IS_MEMO_TABLE_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_memo_table_config_get_type ())
-
-typedef struct _EMemoTableConfig EMemoTableConfig;
-typedef struct _EMemoTableConfigClass EMemoTableConfigClass;
-typedef struct _EMemoTableConfigPrivate EMemoTableConfigPrivate;
-
-struct _EMemoTableConfig {
- GObject parent;
-
- EMemoTableConfigPrivate *priv;
-};
-
-struct _EMemoTableConfigClass {
- GObjectClass parent_class;
-};
-
-GType e_memo_table_config_get_type (void);
-EMemoTableConfig *e_memo_table_config_new (EMemoTable *table);
-EMemoTable *e_memo_table_config_get_table (EMemoTableConfig *view_config);
-void e_memo_table_config_set_table (EMemoTableConfig *view_config, EMemoTable *table);
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index 50158899ac..dddaa52132 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -24,7 +24,7 @@
/*
* EMemoTable - displays the ECalComponent objects in a table (an ETable).
- * Used for memos.
+ * Used for calendar events and tasks.
*/
#ifdef HAVE_CONFIG_H
@@ -35,7 +35,7 @@
#include <unistd.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
-#include <gdk/gdkkeysyms.h>
+#include <e-util/e-binding.h>
#include <widgets/misc/e-gui-utils.h>
#include <table/e-cell-checkbox.h>
#include <table/e-cell-toggle.h>
@@ -43,110 +43,108 @@
#include <table/e-cell-combo.h>
#include <table/e-cell-date.h>
#include <e-util/e-dialog-utils.h>
-#include <widgets/misc/e-cell-date-edit.h>
-#include <widgets/misc/e-cell-percent.h>
+#include <e-util/e-util-private.h>
+#include <table/e-cell-date-edit.h>
+#include <table/e-cell-percent.h>
+#include <libecal/e-cal-time-util.h>
+#include <libedataserver/e-time-utils.h>
-#include "calendar-config.h"
#include "dialogs/delete-comp.h"
#include "dialogs/delete-error.h"
#include "dialogs/memo-editor.h"
#include "e-cal-model-memos.h"
#include "e-memo-table.h"
+#include "e-calendar-view.h"
#include "e-cell-date-edit-text.h"
-#include "e-comp-editor-registry.h"
#include "print.h"
#include <e-util/e-icon-factory.h>
-#include <e-util/e-util-private.h>
-#include "e-cal-popup.h"
-#include "e-calendar-table.h"
+#include "misc.h"
-enum TargetType{
- TARGET_TYPE_VCALENDAR
-};
+#define E_MEMO_TABLE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEMO_TABLE, EMemoTablePrivate))
-static GtkTargetEntry target_types[] = {
- { (gchar *) "text/x-calendar", 0, TARGET_TYPE_VCALENDAR },
- { (gchar *) "text/calendar", 0, TARGET_TYPE_VCALENDAR }
+struct _EMemoTablePrivate {
+ gpointer shell_view; /* weak pointer */
+ ECalModel *model;
};
-static guint n_target_types = G_N_ELEMENTS (target_types);
-
-extern ECompEditorRegistry *comp_editor_registry;
-
-static void e_memo_table_destroy (GtkObject *object);
-
-static void e_memo_table_on_double_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- EMemoTable *memo_table);
-static gint e_memo_table_show_popup_menu (ETable *table,
- GdkEvent *gdk_event,
- EMemoTable *memo_table);
-
-static gint e_memo_table_on_right_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- EMemoTable *memo_table);
-static gboolean e_memo_table_on_popup_menu (GtkWidget *widget,
- gpointer data);
-
-static gint e_memo_table_on_key_press (ETable *table,
- gint row,
- gint col,
- GdkEventKey *event,
- EMemoTable *memo_table);
-static struct tm e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data);
-
-static ECalModelComponent *get_selected_comp (EMemoTable *memo_table);
-static void open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data);
+enum {
+ PROP_0,
+ PROP_MODEL,
+ PROP_SHELL_VIEW
+};
-/* Signal IDs */
enum {
+ OPEN_COMPONENT,
+ POPUP_EVENT,
+ STATUS_MESSAGE,
USER_CREATED,
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0 };
+enum {
+ TARGET_TYPE_VCALENDAR
+};
+
+static GtkTargetEntry target_types[] = {
+ { (gchar *) "text/calendar", 0, TARGET_TYPE_VCALENDAR },
+ { (gchar *) "text/x-calendar", 0, TARGET_TYPE_VCALENDAR }
+};
+
+static struct tm e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data);
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+static GdkAtom clipboard_atom;
/* The icons to represent the task. */
-#define E_MEMO_MODEL_NUM_ICONS 2
-static const gchar * icon_names[E_MEMO_MODEL_NUM_ICONS] = {
- "stock_notes", "stock_insert-note"
+#define NUM_ICONS 2
+static const gchar *icon_names[NUM_ICONS] = {
+ "stock_notes",
+ "stock_insert-note"
};
-static GdkPixbuf* icon_pixbufs[E_MEMO_MODEL_NUM_ICONS] = { NULL };
+static GdkPixbuf *icon_pixbufs[NUM_ICONS] = { NULL };
-static GdkAtom clipboard_atom = GDK_NONE;
+static void
+memo_table_emit_open_component (EMemoTable *memo_table,
+ ECalModelComponent *comp_data)
+{
+ guint signal_id = signals[OPEN_COMPONENT];
-G_DEFINE_TYPE (EMemoTable, e_memo_table, GTK_TYPE_TABLE)
+ g_signal_emit (memo_table, signal_id, 0, comp_data);
+}
static void
-e_memo_table_class_init (EMemoTableClass *klass)
+memo_table_emit_popup_event (EMemoTable *memo_table,
+ GdkEvent *event)
{
- GtkObjectClass *object_class;
+ guint signal_id = signals[POPUP_EVENT];
- object_class = (GtkObjectClass *) klass;
+ g_signal_emit (memo_table, signal_id, 0, event);
+}
- /* Method override */
- object_class->destroy = e_memo_table_destroy;
+static void
+memo_table_emit_status_message (EMemoTable *memo_table,
+ const gchar *message,
+ gdouble percent)
+{
+ guint signal_id = signals[STATUS_MESSAGE];
- signals[USER_CREATED] =
- g_signal_new ("user_created",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMemoTableClass, user_created),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ g_signal_emit (memo_table, signal_id, 0, message, percent);
+}
+
+static void
+memo_table_emit_user_created (EMemoTable *memo_table)
+{
+ guint signal_id = signals[USER_CREATED];
- /* clipboard atom */
- if (!clipboard_atom)
- clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+ g_signal_emit (memo_table, signal_id, 0);
}
static gint
-date_compare_cb (gconstpointer a, gconstpointer b)
+memo_table_date_compare_cb (gconstpointer a,
+ gconstpointer b)
{
ECellDateEditValue *dv1 = (ECellDateEditValue *) a;
ECellDateEditValue *dv2 = (ECellDateEditValue *) b;
@@ -174,87 +172,443 @@ date_compare_cb (gconstpointer a, gconstpointer b)
}
static void
-row_appended_cb (ECalModel *model, EMemoTable *memo_table)
+memo_table_double_click_cb (EMemoTable *memo_table,
+ gint row,
+ gint col,
+ GdkEvent *event)
{
- g_signal_emit (memo_table, signals[USER_CREATED], 0);
+ ECalModel *model;
+ ECalModelComponent *comp_data;
+
+ model = e_memo_table_get_model (memo_table);
+ comp_data = e_cal_model_get_component_at (model, row);
+ memo_table_emit_open_component (memo_table, comp_data);
+}
+
+static void
+memo_table_model_cal_view_progress_cb (EMemoTable *memo_table,
+ const gchar *message,
+ gint progress,
+ ECalSourceType type)
+{
+ gdouble percent = (gdouble) progress;
+
+ memo_table_emit_status_message (memo_table, message, percent);
+}
+
+static void
+memo_table_model_cal_view_done_cb (EMemoTable *memo_table,
+ ECalendarStatus status,
+ ECalSourceType type)
+{
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
}
static gboolean
-query_tooltip_cb (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data)
+memo_table_query_tooltip_cb (EMemoTable *memo_table,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip)
{
- EMemoTable *memo_table;
+ ECalModel *model;
+ ECalModelComponent *comp_data;
+ gint row = -1, col = -1;
+ GtkWidget *box, *l, *w;
+ GtkStyle *style = gtk_widget_get_default_style ();
+ gchar *tmp;
+ const gchar *str;
+ GString *tmp2;
+ gchar buff[1001];
+ gboolean free_text = FALSE;
+ gboolean use_24_hour_format;
+ ECalComponent *new_comp;
+ ECalComponentOrganizer organizer;
+ ECalComponentDateTime dtstart, dtdue;
+ icalcomponent *clone;
+ icaltimezone *zone, *default_zone;
+ GSList *desc, *p;
+ gint len;
+ ETable *etable;
+ ESelectionModel *esm;
+ struct tm tmp_tm;
+
+ if (keyboard_mode)
+ return FALSE;
+
+ etable = e_memo_table_get_table (memo_table);
+ e_table_get_mouse_over_cell (etable, &row, &col);
+ if (row == -1 || !etable)
+ return FALSE;
+
+ /* Respect sorting option; the 'e_table_get_mouse_over_cell'
+ * returns sorted row, not the model one. */
+ esm = e_table_get_selection_model (etable);
+ if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter))
+ row = e_sorter_sorted_to_model (esm->sorter, row);
+
+ model = e_memo_table_get_model (memo_table);
+ comp_data = e_cal_model_get_component_at (model, row);
+ if (!comp_data || !comp_data->icalcomp)
+ return FALSE;
+
+ new_comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ if (!e_cal_component_set_icalcomponent (new_comp, clone)) {
+ g_object_unref (new_comp);
+ return FALSE;
+ }
+
+ box = gtk_vbox_new (FALSE, 0);
+
+ str = e_calendar_view_get_icalcomponent_summary (
+ comp_data->client, comp_data->icalcomp, &free_text);
+ if (!(str && *str)) {
+ if (free_text)
+ g_free ((gchar *)str);
+ free_text = FALSE;
+ str = _("* No Summary *");
+ }
+
+ l = gtk_label_new (NULL);
+ tmp = g_markup_printf_escaped ("<b>%s</b>", str);
+ gtk_label_set_line_wrap (GTK_LABEL (l), TRUE);
+ gtk_label_set_markup (GTK_LABEL (l), tmp);
+ gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
+ w = gtk_event_box_new ();
+
+ gtk_widget_modify_bg (w, GTK_STATE_NORMAL, &(style->bg[GTK_STATE_SELECTED]));
+ gtk_widget_modify_fg (l, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED]));
+ gtk_container_add (GTK_CONTAINER (w), l);
+ gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
+ g_free (tmp);
+
+ if (free_text)
+ g_free ((gchar *)str);
+ free_text = FALSE;
+
+ w = gtk_event_box_new ();
+ gtk_widget_modify_bg (w, GTK_STATE_NORMAL, &(style->bg[GTK_STATE_NORMAL]));
+
+ l = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (w), l);
+ gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+ w = l;
+
+ e_cal_component_get_organizer (new_comp, &organizer);
+ if (organizer.cn) {
+ gchar *ptr;
+ ptr = strchr( organizer.value, ':');
+
+ if (ptr) {
+ ptr++;
+ /* To Translators: It will display "Organizer: NameOfTheUser <email@ofuser.com>" */
+ tmp = g_strdup_printf (_("Organizer: %s <%s>"), organizer.cn, ptr);
+ } else {
+ /* With SunOne accounts, there may be no ':' in organiser.value */
+ tmp = g_strdup_printf (_("Organizer: %s"), organizer.cn);
+ }
+
+ l = gtk_label_new (tmp);
+ gtk_label_set_line_wrap (GTK_LABEL (l), FALSE);
+ gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
+ g_free (tmp);
+ }
+
+ e_cal_component_get_dtstart (new_comp, &dtstart);
+ e_cal_component_get_due (new_comp, &dtdue);
+
+ default_zone = e_cal_model_get_timezone (model);
+
+ if (dtstart.tzid) {
+ zone = icalcomponent_get_timezone (e_cal_component_get_icalcomponent (new_comp), dtstart.tzid);
+ if (!zone)
+ e_cal_get_timezone (
+ comp_data->client, dtstart.tzid, &zone, NULL);
+ if (!zone)
+ zone = default_zone;
+ } else {
+ zone = NULL;
+ }
+
+ tmp2 = g_string_new ("");
+ use_24_hour_format = e_cal_model_get_use_24_hour_format (model);
+
+ if (dtstart.value) {
+ buff[0] = 0;
+
+ tmp_tm = icaltimetype_to_tm_with_zone (
+ dtstart.value, zone, default_zone);
+ e_time_format_date_and_time (
+ &tmp_tm, use_24_hour_format,
+ FALSE, FALSE, buff, 1000);
+
+ if (buff [0]) {
+ g_string_append (tmp2, _("Start: "));
+ g_string_append (tmp2, buff);
+ }
+ }
+
+ if (dtdue.value) {
+ buff[0] = 0;
+
+ tmp_tm = icaltimetype_to_tm_with_zone (
+ dtdue.value, zone, default_zone);
+ e_time_format_date_and_time (
+ &tmp_tm, use_24_hour_format,
+ FALSE, FALSE, buff, 1000);
+
+ if (buff [0]) {
+ if (tmp2->len)
+ g_string_append (tmp2, "; ");
+
+ g_string_append (tmp2, _("Due: "));
+ g_string_append (tmp2, buff);
+ }
+ }
+
+ if (tmp2->len) {
+ l = gtk_label_new (tmp2->str);
+ gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0);
+ }
+
+ g_string_free (tmp2, TRUE);
+
+ e_cal_component_free_datetime (&dtstart);
+ e_cal_component_free_datetime (&dtdue);
+
+ tmp2 = g_string_new ("");
+ e_cal_component_get_description_list (new_comp, &desc);
+ for (len = 0, p = desc; p != NULL; p = p->next) {
+ ECalComponentText *text = p->data;
+
+ if (text->value != NULL) {
+ len += strlen (text->value);
+ g_string_append (tmp2, text->value);
+ if (len > 1024) {
+ g_string_set_size (tmp2, 1020);
+ g_string_append (tmp2, "...");
+ break;
+ }
+ }
+ }
+ e_cal_component_free_text_list (desc);
+
+ if (tmp2->len) {
+ l = gtk_label_new (tmp2->str);
+ gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (box), l, FALSE, FALSE, 0);
+ }
+
+ g_string_free (tmp2, TRUE);
+
+ gtk_widget_show_all (box);
+ gtk_tooltip_set_custom (tooltip, box);
+
+ g_object_unref (new_comp);
+
+ return TRUE;
+}
+
+static gboolean
+memo_table_popup_menu_cb (EMemoTable *memo_table)
+{
+ memo_table_emit_popup_event (memo_table, NULL);
+
+ return TRUE;
+}
+
+static gint
+memo_table_right_click_cb (EMemoTable *memo_table,
+ gint row,
+ gint col,
+ GdkEvent *event)
+{
+ memo_table_emit_popup_event (memo_table, event);
+
+ return TRUE;
+}
+
+static void
+memo_table_set_model (EMemoTable *memo_table,
+ ECalModel *model)
+{
+ g_return_if_fail (memo_table->priv->model == NULL);
+
+ memo_table->priv->model = g_object_ref (model);
+
+ g_signal_connect_swapped (
+ model, "row-appended",
+ G_CALLBACK (memo_table_emit_user_created), memo_table);
+
+ g_signal_connect_swapped (
+ model, "cal-view-progress",
+ G_CALLBACK (memo_table_model_cal_view_progress_cb),
+ memo_table);
+
+ g_signal_connect_swapped (
+ model, "cal-view-done",
+ G_CALLBACK (memo_table_model_cal_view_done_cb),
+ memo_table);
+}
+
+static void
+memo_table_set_shell_view (EMemoTable *memo_table,
+ EShellView *shell_view)
+{
+ g_return_if_fail (memo_table->priv->shell_view == NULL);
+
+ memo_table->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &memo_table->priv->shell_view);
+}
- g_return_val_if_fail (E_IS_MEMO_TABLE (user_data), FALSE);
+static void
+memo_table_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODEL:
+ memo_table_set_model (
+ E_MEMO_TABLE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SHELL_VIEW:
+ memo_table_set_shell_view (
+ E_MEMO_TABLE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+memo_table_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (
+ value, e_memo_table_get_model (
+ E_MEMO_TABLE (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_memo_table_get_shell_view (
+ E_MEMO_TABLE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+memo_table_dispose (GObject *object)
+{
+ EMemoTablePrivate *priv;
- memo_table = E_MEMO_TABLE (user_data);
+ priv = E_MEMO_TABLE_GET_PRIVATE (object);
- return ec_query_tooltip (widget, x, y, keyboard_mode, tooltip, GTK_WIDGET (e_memo_table_get_table (memo_table)), memo_table->model);
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view), &priv->shell_view);
+ priv->shell_view = NULL;
+ }
+
+ if (priv->model != NULL) {
+ g_object_unref (priv->model);
+ priv->model = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-e_memo_table_init (EMemoTable *memo_table)
+memo_table_constructed (GObject *object)
{
- GtkWidget *table;
- ETable *e_table;
+ EMemoTable *memo_table;
+ GtkWidget *widget;
+ ECalModel *model;
+ ETable *table;
ECell *cell, *popup_cell;
ETableExtras *extras;
gint i;
AtkObject *a11y;
gchar *etspecfile;
- /* Create the model */
-
- memo_table->model = (ECalModel *) e_cal_model_memos_new ();
- g_signal_connect (memo_table->model, "row_appended", G_CALLBACK (row_appended_cb), memo_table);
-
- memo_table->user_created_cal = NULL;
+ memo_table = E_MEMO_TABLE (object);
+ model = e_memo_table_get_model (memo_table);
/* Create the header columns */
- extras = e_table_extras_new();
+ extras = e_table_extras_new ();
/*
* Normal string fields.
*/
cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
- g_object_set (G_OBJECT (cell),
- "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
- NULL);
-
+ g_object_set (cell, "bg_color_column", E_CAL_MODEL_FIELD_COLOR, NULL);
e_table_extras_add_cell (extras, "calstring", cell);
/*
* Date fields.
*/
cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT);
- g_object_set (G_OBJECT (cell),
- "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
- NULL);
+ g_object_set (cell, "bg_color_column", E_CAL_MODEL_FIELD_COLOR, NULL);
+
+ e_mutual_binding_new (
+ G_OBJECT (model), "timezone",
+ G_OBJECT (cell), "timezone");
+
+ e_mutual_binding_new (
+ G_OBJECT (model), "use-24-hour-format",
+ G_OBJECT (cell), "use-24-hour-format");
popup_cell = e_cell_date_edit_new ();
e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
g_object_unref (cell);
+
+ e_mutual_binding_new (
+ G_OBJECT (model), "use-24-hour-format",
+ G_OBJECT (popup_cell), "use-24-hour-format");
+
e_table_extras_add_cell (extras, "dateedit", popup_cell);
memo_table->dates_cell = E_CELL_DATE_EDIT (popup_cell);
- e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell),
- e_memo_table_get_current_time,
- memo_table, NULL);
+ e_cell_date_edit_set_get_time_callback (
+ E_CELL_DATE_EDIT (popup_cell),
+ e_memo_table_get_current_time, memo_table, NULL);
/* Sorting */
- e_table_extras_add_compare (extras, "date-compare",
- date_compare_cb);
+ e_table_extras_add_compare (
+ extras, "date-compare", memo_table_date_compare_cb);
/* Create pixmaps */
if (!icon_pixbufs[0])
- for (i = 0; i < E_MEMO_MODEL_NUM_ICONS; i++) {
+ for (i = 0; i < NUM_ICONS; i++) {
icon_pixbufs[i] = e_icon_factory_get_icon (icon_names[i], GTK_ICON_SIZE_MENU);
}
- cell = e_cell_toggle_new (0, E_MEMO_MODEL_NUM_ICONS, icon_pixbufs);
- e_table_extras_add_cell(extras, "icon", cell);
- e_table_extras_add_pixbuf(extras, "icon", icon_pixbufs[0]);
+ cell = e_cell_toggle_new (0, NUM_ICONS, icon_pixbufs);
+ e_table_extras_add_cell (extras, "icon", cell);
+ e_table_extras_add_pixbuf (extras, "icon", icon_pixbufs[0]);
+
+ /* set proper format component for a default 'date' cell renderer */
+ cell = e_table_extras_get_cell (extras, "date");
+ e_cell_date_set_format_component (E_CELL_DATE (cell), "calendar");
/* set proper format component for a default 'date' cell renderer */
cell = e_table_extras_get_cell (extras, "date");
@@ -262,51 +616,166 @@ e_memo_table_init (EMemoTable *memo_table)
/* Create the table */
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "e-memo-table.etspec",
- NULL);
- table = e_table_scrolled_new_from_spec_file (E_TABLE_MODEL (memo_table->model),
- extras,
- etspecfile,
- NULL);
+ etspecfile = g_build_filename (
+ EVOLUTION_ETSPECDIR, "e-memo-table.etspec", NULL);
+ widget = e_table_scrolled_new_from_spec_file (
+ E_TABLE_MODEL (model), extras, etspecfile, NULL);
+ gtk_table_attach (
+ GTK_TABLE (memo_table), widget, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ memo_table->etable = widget;
+ gtk_widget_show (widget);
g_free (etspecfile);
- /* FIXME: this causes a message from GLib about 'extras' having only a floating
- reference */
- /* g_object_unref (extras); */
+ table = e_table_scrolled_get_table (E_TABLE_SCROLLED (widget));
+ g_signal_connect_swapped (
+ table, "double-click",
+ G_CALLBACK (memo_table_double_click_cb), memo_table);
+ g_signal_connect_swapped (
+ table, "query-tooltip",
+ G_CALLBACK (memo_table_query_tooltip_cb), memo_table);
+ g_signal_connect_swapped (
+ table, "popup-menu",
+ G_CALLBACK (memo_table_popup_menu_cb), memo_table);
+ g_signal_connect_swapped (
+ table, "right-click",
+ G_CALLBACK (memo_table_right_click_cb), memo_table);
+ gtk_widget_set_has_tooltip (GTK_WIDGET (table), TRUE);
+
+ a11y = gtk_widget_get_accessible (GTK_WIDGET (table));
+ if (a11y)
+ atk_object_set_name (a11y, _("Memos"));
+}
- memo_table->etable = table;
- gtk_table_attach (GTK_TABLE (memo_table), table, 0, 1, 0, 1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- gtk_widget_show (table);
+static void
+memo_table_class_init (EMemoTableClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMemoTablePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = memo_table_set_property;
+ object_class->get_property = memo_table_get_property;
+ object_class->dispose = memo_table_dispose;
+ object_class->constructed = memo_table_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ _("Model"),
+ NULL,
+ E_TYPE_CAL_MODEL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ _("Shell View"),
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[OPEN_COMPONENT] = g_signal_new (
+ "open-component",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMemoTableClass, open_component),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CAL_MODEL_COMPONENT);
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMemoTableClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status-message",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMemoTableClass, status_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[USER_CREATED] = g_signal_new (
+ "user-created",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMemoTableClass, user_created),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+}
- e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (table));
- g_signal_connect (e_table, "double_click", G_CALLBACK (e_memo_table_on_double_click), memo_table);
- g_signal_connect (e_table, "right_click", G_CALLBACK (e_memo_table_on_right_click), memo_table);
- g_signal_connect (e_table, "key_press", G_CALLBACK (e_memo_table_on_key_press), memo_table);
- g_signal_connect (e_table, "popup_menu", G_CALLBACK (e_memo_table_on_popup_menu), memo_table);
- g_signal_connect (e_table, "query-tooltip", G_CALLBACK (query_tooltip_cb), memo_table);
- gtk_widget_set_has_tooltip (GTK_WIDGET (e_table), TRUE);
+static void
+memo_table_init (EMemoTable *memo_table)
+{
+ memo_table->priv = E_MEMO_TABLE_GET_PRIVATE (memo_table);
+}
- a11y = gtk_widget_get_accessible (GTK_WIDGET(e_table));
- if (a11y)
- atk_object_set_name (a11y, _("Memos"));
+GType
+e_memo_table_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMemoTableClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) memo_table_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMemoTable),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) memo_table_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "EMemoTable", &type_info, 0);
+ }
+
+ return type;
}
/**
* e_memo_table_new:
- * @Returns: a new #EMemoTable.
+ * @shell_view: an #EShellView
+ * @model: an #ECalModel for the table
+ *
+ * Returns a new #EMemoTable.
*
- * Creates a new #EMemoTable.
+ * Returns: a new #EMemoTable
**/
GtkWidget *
-e_memo_table_new (void)
+e_memo_table_new (EShellView *shell_view,
+ ECalModel *model)
{
- GtkWidget *memo_table;
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
- memo_table = GTK_WIDGET (g_object_new (e_memo_table_get_type (), NULL));
-
- return memo_table;
+ return g_object_new (
+ E_TYPE_MEMO_TABLE,
+ "model", model, "shell-view", shell_view, NULL);
}
/**
@@ -323,22 +792,7 @@ e_memo_table_get_model (EMemoTable *memo_table)
g_return_val_if_fail (memo_table != NULL, NULL);
g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL);
- return memo_table->model;
-}
-
-static void
-e_memo_table_destroy (GtkObject *object)
-{
- EMemoTable *memo_table;
-
- memo_table = E_MEMO_TABLE (object);
-
- if (memo_table->model) {
- g_object_unref (memo_table->model);
- memo_table->model = NULL;
- }
-
- GTK_OBJECT_CLASS (e_memo_table_parent_class)->destroy (object);
+ return memo_table->priv->model;
}
/**
@@ -353,20 +807,21 @@ e_memo_table_destroy (GtkObject *object)
ETable *
e_memo_table_get_table (EMemoTable *memo_table)
{
- g_return_val_if_fail (memo_table != NULL, NULL);
+ ETableScrolled *table_scrolled;
+
g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL);
- return e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+ table_scrolled = E_TABLE_SCROLLED (memo_table->etable);
+
+ return e_table_scrolled_get_table (table_scrolled);
}
-void
-e_memo_table_open_selected (EMemoTable *memo_table)
+EShellView *
+e_memo_table_get_shell_view (EMemoTable *memo_table)
{
- ECalModelComponent *comp_data;
+ g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL);
- comp_data = get_selected_comp (memo_table);
- if (comp_data != NULL)
- open_memo (memo_table, comp_data);
+ return memo_table->priv->shell_view;
}
/* Used from e_table_selected_row_foreach(); puts the selected row number in an
@@ -388,10 +843,12 @@ get_selected_row_cb (gint model_row, gpointer data)
static ECalModelComponent *
get_selected_comp (EMemoTable *memo_table)
{
+ ECalModel *model;
ETable *etable;
gint row;
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+ model = e_memo_table_get_model (memo_table);
+ etable = e_memo_table_get_table (memo_table);
if (e_table_selected_count (etable) != 1)
return NULL;
@@ -401,7 +858,7 @@ get_selected_comp (EMemoTable *memo_table)
&row);
g_return_val_if_fail (row != -1, NULL);
- return e_cal_model_get_component_at (memo_table->model, row);
+ return e_cal_model_get_component_at (model, row);
}
struct get_selected_uids_closure {
@@ -415,38 +872,27 @@ add_uid_cb (gint model_row, gpointer data)
{
struct get_selected_uids_closure *closure;
ECalModelComponent *comp_data;
+ ECalModel *model;
closure = data;
- comp_data = e_cal_model_get_component_at (closure->memo_table->model, model_row);
+ model = e_memo_table_get_model (closure->memo_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
closure->objects = g_slist_prepend (closure->objects, comp_data);
}
-static GSList *
-get_selected_objects (EMemoTable *memo_table)
-{
- struct get_selected_uids_closure closure;
- ETable *etable;
-
- closure.memo_table = memo_table;
- closure.objects = NULL;
-
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
- e_table_selected_row_foreach (etable, add_uid_cb, &closure);
-
- return closure.objects;
-}
-
/* Deletes all of the selected components in the table */
static void
delete_selected_components (EMemoTable *memo_table)
{
GSList *objs, *l;
+ const gchar *status_message;
- objs = get_selected_objects (memo_table);
+ objs = e_memo_table_get_selected (memo_table);
- e_memo_table_set_status_message (memo_table, _("Deleting selected objects"));
+ status_message = _("Deleting selected objects");
+ memo_table_emit_status_message (memo_table, status_message, -1.0);
for (l = objs; l; l = l->next) {
ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
@@ -458,27 +904,12 @@ delete_selected_components (EMemoTable *memo_table)
g_clear_error (&error);
}
- e_memo_table_set_status_message (memo_table, NULL);
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
g_slist_free (objs);
}
/**
- * e_memo_table_get_selected:
- * @memo_table:
- *
- * Get the currently selected ECalModelComponent's on the table.
- *
- * Return value: A GSList of the components, which should be
- * g_slist_free'd when finished with.
- **/
-GSList *
-e_memo_table_get_selected (EMemoTable *memo_table)
-{
- return get_selected_objects(memo_table);
-}
-
-/**
* e_memo_table_delete_selected:
* @memo_table: A memo table.
*
@@ -495,7 +926,7 @@ e_memo_table_delete_selected (EMemoTable *memo_table)
g_return_if_fail (memo_table != NULL);
g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+ etable = e_memo_table_get_table (memo_table);
n_selected = e_table_selected_count (etable);
if (n_selected <= 0)
@@ -523,6 +954,30 @@ e_memo_table_delete_selected (EMemoTable *memo_table)
}
/**
+ * e_memo_table_get_selected:
+ * @memo_table:
+ *
+ * Get the currently selected ECalModelComponent's on the table.
+ *
+ * Return value: A GSList of the components, which should be
+ * g_slist_free'd when finished with.
+ **/
+GSList *
+e_memo_table_get_selected (EMemoTable *memo_table)
+{
+ struct get_selected_uids_closure closure;
+ ETable *etable;
+
+ closure.memo_table = memo_table;
+ closure.objects = NULL;
+
+ etable = e_memo_table_get_table (memo_table);
+ e_table_selected_row_foreach (etable, add_uid_cb, &closure);
+
+ return closure.objects;
+}
+
+/**
* e_memo_table_cut_clipboard:
* @memo_table: A calendar table.
*
@@ -537,12 +992,33 @@ e_memo_table_cut_clipboard (EMemoTable *memo_table)
delete_selected_components (memo_table);
}
+static void
+clipboard_get_calendar_cb (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ gpointer data)
+{
+ gchar *comp_str = (gchar *) data;
+
+ switch (info) {
+ case TARGET_TYPE_VCALENDAR:
+ gtk_selection_data_set (selection_data,
+ gdk_atom_intern (target_types[info].target, FALSE), 8,
+ (const guchar *) comp_str,
+ (gint) strlen (comp_str));
+ break;
+ default:
+ break;
+ }
+}
+
/* callback for e_table_selected_row_foreach */
static void
copy_row_cb (gint model_row, gpointer data)
{
EMemoTable *memo_table;
ECalModelComponent *comp_data;
+ ECalModel *model;
gchar *comp_str;
icalcomponent *child;
@@ -550,7 +1026,8 @@ copy_row_cb (gint model_row, gpointer data)
g_return_if_fail (memo_table->tmp_vcal != NULL);
- comp_data = e_cal_model_get_component_at (memo_table->model, model_row);
+ model = e_memo_table_get_model (memo_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
if (!comp_data)
return;
@@ -568,26 +1045,6 @@ copy_row_cb (gint model_row, gpointer data)
g_free (comp_str);
}
-static void
-clipboard_get_calendar_cb (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- guint info,
- gpointer data)
-{
- gchar *comp_str = (gchar *) data;
-
- switch (info) {
- case TARGET_TYPE_VCALENDAR:
- gtk_selection_data_set (selection_data,
- gdk_atom_intern (target_types[info].target, FALSE), 8,
- (const guchar *) comp_str,
- (gint) strlen (comp_str));
- break;
- default:
- break;
- }
-}
-
/**
* e_memo_table_copy_clipboard:
* @memo_table: A calendar table.
@@ -606,16 +1063,18 @@ e_memo_table_copy_clipboard (EMemoTable *memo_table)
/* create temporary VCALENDAR object */
memo_table->tmp_vcal = e_cal_util_new_top_level ();
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+ etable = e_memo_table_get_table (memo_table);
e_table_selected_row_foreach (etable, copy_row_cb, memo_table);
comp_str = icalcomponent_as_ical_string_r (memo_table->tmp_vcal);
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (memo_table), clipboard_atom);
- if (!gtk_clipboard_set_with_data(clipboard, target_types, n_target_types,
- clipboard_get_calendar_cb,
- NULL, comp_str)) {
+ if (!gtk_clipboard_set_with_data (
+ clipboard, target_types, G_N_ELEMENTS (target_types),
+ clipboard_get_calendar_cb, NULL, comp_str)) {
/* no-op */
} else {
- gtk_clipboard_set_can_store (clipboard, target_types + 1, n_target_types - 1);
+ gtk_clipboard_set_can_store (
+ clipboard, target_types + 1,
+ G_N_ELEMENTS (target_types) - 1);
}
/* free memory */
@@ -631,7 +1090,9 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text)
gchar *uid;
ECalComponent *comp;
ECal *client;
+ ECalModel *model;
icalcomponent_kind kind;
+ const gchar *status_message;
g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
@@ -645,13 +1106,17 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text)
/* check the type of the component */
kind = icalcomponent_isa (icalcomp);
if (kind != ICAL_VCALENDAR_COMPONENT &&
+ kind != ICAL_VEVENT_COMPONENT &&
+ kind != ICAL_VTODO_COMPONENT &&
kind != ICAL_VJOURNAL_COMPONENT) {
return;
}
- client = e_cal_model_get_default_client (memo_table->model);
+ model = e_memo_table_get_model (memo_table);
+ client = e_cal_model_get_default_client (model);
- e_memo_table_set_status_message (memo_table, _("Updating objects"));
+ status_message = _("Updating objects");
+ memo_table_emit_status_message (memo_table, status_message, -1.0);
if (kind == ICAL_VCALENDAR_COMPONENT) {
icalcomponent_kind child_kind;
@@ -663,7 +1128,9 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text)
vcal_comp, ICAL_ANY_COMPONENT);
while (subcomp) {
child_kind = icalcomponent_isa (subcomp);
- if (child_kind == ICAL_VJOURNAL_COMPONENT) {
+ if (child_kind == ICAL_VEVENT_COMPONENT ||
+ child_kind == ICAL_VTODO_COMPONENT ||
+ child_kind == ICAL_VJOURNAL_COMPONENT) {
ECalComponent *tmp_comp;
uid = e_cal_component_gen_uid ();
@@ -694,7 +1161,7 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text)
g_object_unref (comp);
}
- e_memo_table_set_status_message (memo_table, NULL);
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
}
static void
@@ -703,7 +1170,7 @@ clipboard_paste_received_cb (GtkClipboard *clipboard,
gpointer data)
{
EMemoTable *memo_table = E_MEMO_TABLE (data);
- ETable *e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+ ETable *e_table = e_memo_table_get_table (memo_table);
GnomeCanvas *canvas = e_table->table_canvas;
GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item;
@@ -738,332 +1205,43 @@ void
e_memo_table_paste_clipboard (EMemoTable *memo_table)
{
GtkClipboard *clipboard;
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- clipboard = gtk_widget_get_clipboard (GTK_WIDGET (memo_table), clipboard_atom);
- g_object_ref (memo_table);
-
- gtk_clipboard_request_contents (clipboard,
- gdk_atom_intern (target_types[0].target, FALSE),
- clipboard_paste_received_cb, memo_table);
-}
-
-/* Opens a task in the task editor */
-static void
-open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data)
-{
- CompEditor *medit;
- const gchar *uid;
-
- uid = icalcomponent_get_uid (comp_data->icalcomp);
-
- medit = e_comp_editor_registry_find (comp_editor_registry, uid);
- if (medit == NULL) {
- ECalComponent *comp;
- CompEditorFlags flags = 0;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
-
- if (e_cal_component_has_organizer (comp))
- flags |= COMP_EDITOR_IS_SHARED;
-
- if (itip_organizer_is_user (comp, comp_data->client))
- flags |= COMP_EDITOR_USER_ORG;
-
- medit = memo_editor_new (comp_data->client, flags);
-
- comp_editor_edit_comp (medit, comp);
- g_object_unref (comp);
-
- e_comp_editor_registry_add (comp_editor_registry, medit, FALSE);
- }
-
- gtk_window_present (GTK_WINDOW (medit));
-}
-
-/* Opens the task in the specified row */
-static void
-open_memo_by_row (EMemoTable *memo_table, gint row)
-{
- ECalModelComponent *comp_data;
-
- comp_data = e_cal_model_get_component_at (memo_table->model, row);
- open_memo (memo_table, comp_data);
-}
-
-static void
-e_memo_table_on_double_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- EMemoTable *memo_table)
-{
- open_memo_by_row (memo_table, row);
-}
-
-static void
-e_memo_table_on_open_memo (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
- ECalModelComponent *comp_data;
-
- comp_data = get_selected_comp (memo_table);
- if (comp_data)
- open_memo (memo_table, comp_data);
-}
-
-static void
-e_memo_table_on_save_as (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
- ECalModelComponent *comp_data;
- gchar *filename;
- gchar *ical_string;
-
- comp_data = get_selected_comp (memo_table);
- if (comp_data == NULL)
- return;
-
- filename = e_file_dialog_save (_("Save as..."), NULL);
- if (filename == NULL)
- return;
-
- ical_string = e_cal_get_component_as_string (comp_data->client, comp_data->icalcomp);
- if (ical_string == NULL) {
- g_warning ("Couldn't convert item to a string");
- return;
- }
-
- e_write_file_uri (filename, ical_string);
- g_free (ical_string);
-}
-
-static void
-e_memo_table_on_print_memo (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
- ECalModelComponent *comp_data;
- ECalComponent *comp;
-
- comp_data = get_selected_comp (memo_table);
- if (comp_data == NULL)
- return;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- print_comp (comp, comp_data->client, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-
- g_object_unref (comp);
-}
-
-static void
-e_memo_table_on_cut (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
- e_memo_table_cut_clipboard (memo_table);
-}
-
-static void
-e_memo_table_on_copy (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
-
- e_memo_table_copy_clipboard (memo_table);
-}
-
-static void
-e_memo_table_on_paste (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
-
- e_memo_table_paste_clipboard (memo_table);
-}
-
-static void
-e_memo_table_on_forward (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
- ECalModelComponent *comp_data;
-
- comp_data = get_selected_comp (memo_table);
- if (comp_data) {
- ECalComponent *comp;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
-
- g_object_unref (comp);
- }
-}
-
-/* Opens the URL of the memo */
-static void
-open_url_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
- ECalModelComponent *comp_data;
- icalproperty *prop;
-
- comp_data = get_selected_comp (memo_table);
- if (!comp_data)
- return;
-
- prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY);
- if (!prop)
- return;
-
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, icalproperty_get_url (prop));
-}
-
-/* Callback for the "delete tasks" menu item */
-static void
-delete_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMemoTable *memo_table = E_MEMO_TABLE (data);
-
- e_memo_table_delete_selected (memo_table);
-}
-
-static EPopupItem memos_popup_items [] = {
- { E_POPUP_ITEM, (gchar *) "00.open", (gchar *) N_("_Open"), e_memo_table_on_open_memo, NULL, (gchar *) GTK_STOCK_OPEN, E_CAL_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "05.openweb", (gchar *) N_("Open _Web Page"), open_url_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_HASURL },
- { E_POPUP_ITEM, (gchar *) "10.saveas", (gchar *) N_("_Save As..."), e_memo_table_on_save_as, NULL, (gchar *) GTK_STOCK_SAVE_AS, E_CAL_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "20.print", (gchar *) N_("P_rint..."), e_memo_table_on_print_memo, NULL, (gchar *) GTK_STOCK_PRINT, E_CAL_POPUP_SELECT_ONE },
-
- { E_POPUP_BAR, (gchar *) "30.bar" },
-
- { E_POPUP_ITEM, (gchar *) "40.cut", (gchar *) N_("C_ut"), e_memo_table_on_cut, NULL, (gchar *) GTK_STOCK_CUT, 0, E_CAL_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "50.copy", (gchar *) N_("_Copy"), e_memo_table_on_copy, NULL, (gchar *) GTK_STOCK_COPY, 0, 0 },
- { E_POPUP_ITEM, (gchar *) "60.paste", (gchar *) N_("_Paste"), e_memo_table_on_paste, NULL, (gchar *) GTK_STOCK_PASTE, 0, E_CAL_POPUP_SELECT_EDITABLE },
-
- { E_POPUP_BAR, (gchar *) "70.bar" },
-
- { E_POPUP_ITEM, (gchar *) "80.forward", (gchar *) N_("_Forward as iCalendar"), e_memo_table_on_forward, NULL, (gchar *) "mail-forward", E_CAL_POPUP_SELECT_ONE },
-
- { E_POPUP_BAR, (gchar *) "90.bar" },
-
- { E_POPUP_ITEM, (gchar *) "a0.delete", (gchar *) N_("_Delete"), delete_cb, NULL, (gchar *) GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE },
- { E_POPUP_ITEM, (gchar *) "b0.deletemany", (gchar *) N_("_Delete Selected Memos"), delete_cb, NULL, (gchar *) GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE },
-};
-
-static void
-emt_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static gint
-e_memo_table_show_popup_menu (ETable *table,
- GdkEvent *gdk_event,
- EMemoTable *memo_table)
-{
- GtkMenu *menu;
- GSList *selection, *l, *menus = NULL;
- GPtrArray *events;
- ECalPopup *ep;
- ECalPopupTargetSelect *t;
- gint i;
-
- selection = get_selected_objects (memo_table);
- if (!selection)
- return TRUE;
-
- /** @HookPoint-ECalPopup: Tasks Table Context Menu
- * @Id: org.gnome.evolution.tasks.table.popup
- * @Class: org.gnome.evolution.calendar.popup:1.0
- * @Target: ECalPopupTargetSelect
- *
- * The context menu on the tasks table.
- */
- ep = e_cal_popup_new("org.gnome.evolution.memos.table.popup");
-
- events = g_ptr_array_new();
- for (l=selection;l;l=g_slist_next(l))
- g_ptr_array_add(events, e_cal_model_copy_component_data((ECalModelComponent *)l->data));
- g_slist_free(selection);
-
- t = e_cal_popup_target_new_select(ep, memo_table->model, events);
- t->target.widget = (GtkWidget *)memo_table;
-
- for (i=0;i<sizeof(memos_popup_items)/sizeof(memos_popup_items[0]);i++)
- menus = g_slist_prepend(menus, &memos_popup_items[i]);
- e_popup_add_items((EPopup *)ep, menus, NULL, emt_popup_free, memo_table);
-
- menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
-
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0,
- gdk_event?gdk_event->button.time:gtk_get_current_event_time());
-
- return TRUE;
-}
-
-static gint
-e_memo_table_on_right_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- EMemoTable *memo_table)
-{
- return e_memo_table_show_popup_menu (table, event, memo_table);
-}
+ g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-static gboolean
-e_memo_table_on_popup_menu (GtkWidget *widget, gpointer data)
-{
- ETable *table = E_TABLE(widget);
- g_return_val_if_fail(table, FALSE);
+ clipboard = gtk_widget_get_clipboard (
+ GTK_WIDGET (memo_table), clipboard_atom);
- return e_memo_table_show_popup_menu (table, NULL,
- E_MEMO_TABLE(data));
-}
-
-static gint
-e_memo_table_on_key_press (ETable *table,
- gint row,
- gint col,
- GdkEventKey *event,
- EMemoTable *memo_table)
-{
- if (event->keyval == GDK_Delete) {
- delete_cb (NULL, NULL, memo_table);
- return TRUE;
- } else if ((event->keyval == GDK_o)
- &&(event->state & GDK_CONTROL_MASK)) {
- open_memo_by_row (memo_table, row);
- return TRUE;
- }
-
- return FALSE;
+ gtk_clipboard_request_contents (
+ clipboard, gdk_atom_intern (target_types[0].target, FALSE),
+ clipboard_paste_received_cb, g_object_ref (memo_table));
}
/* Loads the state of the table (headers shown etc.) from the given file. */
void
e_memo_table_load_state (EMemoTable *memo_table,
- gchar *filename)
+ const gchar *filename)
{
- struct stat st;
+ ETable *table;
g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+ g_return_if_fail (filename != NULL);
- if (g_stat (filename, &st) == 0 && st.st_size > 0
- && S_ISREG (st.st_mode)) {
- e_table_load_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)), filename);
- }
+ table = e_memo_table_get_table (memo_table);
+ e_table_load_state (table, filename);
}
/* Saves the state of the table (headers shown etc.) to the given file. */
void
-e_memo_table_save_state (EMemoTable *memo_table,
- gchar *filename)
+e_memo_table_save_state (EMemoTable *memo_table,
+ const gchar *filename)
{
+ ETable *table;
+
g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+ g_return_if_fail (filename != NULL);
- e_table_save_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)),
- filename);
+ table = e_memo_table_get_table (memo_table);
+ e_table_save_state (table, filename);
}
/* Returns the current time, for the ECellDateEdit items.
@@ -1072,12 +1250,15 @@ e_memo_table_save_state (EMemoTable *memo_table,
static struct tm
e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data)
{
+ EMemoTable *memo_table = data;
+ ECalModel *model;
icaltimezone *zone;
struct tm tmp_tm = { 0 };
struct icaltimetype tt;
/* Get the current timezone. */
- zone = calendar_config_get_icaltimezone ();
+ model = e_memo_table_get_model (memo_table);
+ zone = e_cal_model_get_timezone (model);
tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
@@ -1092,44 +1273,3 @@ e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data)
return tmp_tm;
}
-
-#ifdef TRANSLATORS_ONLY
-
-static gchar *test[] = {
- N_("Click to add a memo")
-};
-
-#endif
-
-void
-e_memo_table_set_activity_handler (EMemoTable *memo_table, EActivityHandler *activity_handler)
-{
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- memo_table->activity_handler = activity_handler;
-}
-
-void
-e_memo_table_set_status_message (EMemoTable *memo_table, const gchar *message)
-{
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- if (!memo_table->activity_handler)
- return;
-
- if (!message || !*message) {
- if (memo_table->activity_id != 0) {
- e_activity_handler_operation_finished (memo_table->activity_handler, memo_table->activity_id);
- memo_table->activity_id = 0;
- }
- } else if (memo_table->activity_id == 0) {
- gchar *client_id = g_strdup_printf ("%p", (gpointer) memo_table);
-
- memo_table->activity_id = e_activity_handler_operation_started (
- memo_table->activity_handler, client_id, message, TRUE);
-
- g_free (client_id);
- } else {
- e_activity_handler_operation_progressing (memo_table->activity_handler, memo_table->activity_id, message, -1.0);
- }
-}
diff --git a/calendar/gui/e-memo-table.h b/calendar/gui/e-memo-table.h
index 7fbb7d0f3e..d7f1857374 100644
--- a/calendar/gui/e-memo-table.h
+++ b/calendar/gui/e-memo-table.h
@@ -25,31 +25,47 @@
#ifndef _E_MEMO_TABLE_H_
#define _E_MEMO_TABLE_H_
-#include <gtk/gtk.h>
+#include <shell/e-shell-view.h>
#include <table/e-table-scrolled.h>
-#include <widgets/misc/e-cell-date-edit.h>
-#include "e-activity-handler.h"
+#include <table/e-cell-date-edit.h>
#include "e-cal-model.h"
-G_BEGIN_DECLS
-
/*
* EMemoTable - displays the iCalendar objects in a table (an ETable).
* Used for memo events and tasks.
+ *
+ * XXX We should look at merging this back into ECalendarTable, or at
+ * least making ECalendarTable subclassable so we don't have so
+ * much duplicate code.
*/
-#define E_MEMO_TABLE(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_memo_table_get_type (), EMemoTable)
-#define E_MEMO_TABLE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_memo_table_get_type (), EMemoTableClass)
-#define E_IS_MEMO_TABLE(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_memo_table_get_type ())
+/* Standard GObject macros */
+#define E_TYPE_MEMO_TABLE \
+ (e_memo_table_get_type ())
+#define E_MEMO_TABLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEMO_TABLE, EMemoTable))
+#define E_MEMO_TABLE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEMO_TABLE, EMemoTableClass))
+#define E_IS_MEMO_TABLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEMO_TABLE))
+#define E_IS_MEMO_TABLE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MEMO_TABLE))
+#define E_MEMO_TABLE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEMO_TABLE, EMemoTableClass))
-typedef struct _EMemoTable EMemoTable;
-typedef struct _EMemoTableClass EMemoTableClass;
+G_BEGIN_DECLS
-struct _EMemoTable {
- GtkTable table;
+typedef struct _EMemoTable EMemoTable;
+typedef struct _EMemoTableClass EMemoTableClass;
+typedef struct _EMemoTablePrivate EMemoTablePrivate;
- /* The model that we use */
- ECalModel *model;
+struct _EMemoTable {
+ GtkTable parent;
GtkWidget *etable;
@@ -59,50 +75,51 @@ struct _EMemoTable {
/* Fields used for cut/copy/paste */
icalcomponent *tmp_vcal;
- /* Activity ID for the EActivityHandler (i.e. the status bar). */
- EActivityHandler *activity_handler;
- guint activity_id;
-
- /* We should know which calendar has been used to create object, so store it here
- before emitting "user_created" signal and make it NULL just after the emit. */
- ECal *user_created_cal;
+ EMemoTablePrivate *priv;
};
struct _EMemoTableClass {
GtkTableClass parent_class;
- /* Notification signals */
- void (* user_created) (EMemoTable *memo_table);
+ /* Signals */
+ void (*open_component) (EMemoTable *memo_table,
+ ECalModelComponent *comp_data);
+ void (*popup_event) (EMemoTable *memo_table,
+ GdkEvent *event);
+ void (*status_message) (EMemoTable *memo_table,
+ const gchar *message,
+ gdouble percent);
+ void (*user_created) (EMemoTable *memo_table);
};
-GType e_memo_table_get_type (void);
-GtkWidget* e_memo_table_new (void);
-
-ECalModel *e_memo_table_get_model (EMemoTable *memo_table);
-
-ETable *e_memo_table_get_table (EMemoTable *memo_table);
-
-void e_memo_table_open_selected (EMemoTable *memo_table);
-void e_memo_table_delete_selected (EMemoTable *memo_table);
-
-GSList *e_memo_table_get_selected (EMemoTable *memo_table);
+GType e_memo_table_get_type (void);
+GtkWidget * e_memo_table_new (EShellView *shell_view,
+ ECalModel *model);
+ECalModel * e_memo_table_get_model (EMemoTable *memo_table);
+ETable * e_memo_table_get_table (EMemoTable *memo_table);
+EShellView * e_memo_table_get_shell_view (EMemoTable *memo_table);
+icaltimezone * e_memo_table_get_timezone (EMemoTable *memo_table);
+void e_memo_table_set_timezone (EMemoTable *memo_table,
+ icaltimezone *timezone);
+gboolean e_memo_table_get_use_24_hour_format
+ (EMemoTable *memo_table);
+void e_memo_table_set_use_24_hour_format
+ (EMemoTable *memo_table,
+ gboolean use_24_hour_format);
+void e_memo_table_delete_selected (EMemoTable *memo_table);
+GSList * e_memo_table_get_selected (EMemoTable *memo_table);
/* Clipboard related functions */
-void e_memo_table_cut_clipboard (EMemoTable *memo_table);
-void e_memo_table_copy_clipboard (EMemoTable *memo_table);
-void e_memo_table_paste_clipboard (EMemoTable *memo_table);
+void e_memo_table_cut_clipboard (EMemoTable *memo_table);
+void e_memo_table_copy_clipboard (EMemoTable *memo_table);
+void e_memo_table_paste_clipboard (EMemoTable *memo_table);
/* These load and save the state of the table (headers shown etc.) to/from
the given file. */
-void e_memo_table_load_state (EMemoTable *memo_table,
- gchar *filename);
-void e_memo_table_save_state (EMemoTable *memo_table,
- gchar *filename);
-
-void e_memo_table_set_activity_handler (EMemoTable *memo_table,
- EActivityHandler *activity_handler);
-void e_memo_table_set_status_message (EMemoTable *memo_table,
- const gchar *message);
+void e_memo_table_load_state (EMemoTable *memo_table,
+ const gchar *filename);
+void e_memo_table_save_state (EMemoTable *memo_table,
+ const gchar *filename);
G_END_DECLS
diff --git a/calendar/gui/e-memos.c b/calendar/gui/e-memos.c
deleted file mode 100644
index 82f6d91c33..0000000000
--- a/calendar/gui/e-memos.c
+++ /dev/null
@@ -1,1229 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena Quintero <federico@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- * Rodrigo Moya <rodrigo@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <glib/gi18n.h>
-#include <libedataserver/e-time-utils.h>
-#include <table/e-table-scrolled.h>
-#include <widgets/menus/gal-view-instance.h>
-#include <widgets/menus/gal-view-factory-etable.h>
-#include <widgets/menus/gal-view-etable.h>
-
-#include "e-util/e-error.h"
-#include "e-util/e-categories-config.h"
-#include "e-util/e-util-private.h"
-#include "shell/e-user-creatable-items-handler.h"
-#include <libecal/e-cal-time-util.h>
-#include <libedataserver/e-url.h>
-#include <libedataserver/e-categories.h>
-#include "widgets/menus/gal-view-menus.h"
-#include "dialogs/delete-error.h"
-#include "calendar-config.h"
-#include "cal-search-bar.h"
-#include "calendar-component.h"
-#include "comp-util.h"
-#include "e-memo-table-config.h"
-#include "misc.h"
-#include "memos-component.h"
-#include "e-cal-component-memo-preview.h"
-#include "e-memos.h"
-#include "common/authentication.h"
-
-/* Private part of the GnomeCalendar structure */
-struct _EMemosPrivate {
- /* The memo lists for display */
- GHashTable *clients;
- GList *clients_list;
- ECal *default_client;
-
- ECalView *query;
-
- /* The EMemoTable showing the memos. */
- GtkWidget *memos_view;
- EMemoTableConfig *memos_view_config;
-
- /* Calendar search bar for memos */
- GtkWidget *search_bar;
-
- /* Paned widget */
- GtkWidget *paned;
-
- /* The preview */
- GtkWidget *preview;
-
- gchar *current_uid;
- gchar *sexp;
-
- /* View instance and the view menus handler */
- GalViewInstance *view_instance;
- GalViewMenus *view_menus;
-
- GList *notifications;
-};
-
-static void setup_widgets (EMemos *memos);
-static void e_memos_destroy (GtkObject *object);
-static void update_view (EMemos *memos);
-
-static void categories_changed_cb (gpointer object, gpointer user_data);
-static void backend_error_cb (ECal *client, const gchar *message, gpointer data);
-
-/* Signal IDs */
-enum {
- SELECTION_CHANGED,
- SOURCE_ADDED,
- SOURCE_REMOVED,
- LAST_SIGNAL
-};
-
-enum DndTargetType {
- TARGET_VCALENDAR
-};
-
-static GtkTargetEntry list_drag_types[] = {
- { (gchar *) "text/calendar", 0, TARGET_VCALENDAR },
- { (gchar *) "text/x-calendar", 0, TARGET_VCALENDAR }
-};
-static const gint num_list_drag_types = sizeof (list_drag_types) / sizeof (list_drag_types[0]);
-
-static guint e_memos_signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (EMemos, e_memos, GTK_TYPE_TABLE)
-
-/* Callback used when the cursor changes in the table */
-static void
-table_cursor_change_cb (ETable *etable, gint row, gpointer data)
-{
- EMemos *memos;
- EMemosPrivate *priv;
- ECalModel *model;
- ECalModelComponent *comp_data;
- ECalComponent *comp;
- const gchar *uid;
-
- gint n_selected;
-
- memos = E_MEMOS (data);
- priv = memos->priv;
-
- n_selected = e_table_selected_count (etable);
-
- /* update the HTML widget */
- if (n_selected != 1) {
- e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview));
-
- return;
- }
-
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
-
- comp_data = e_cal_model_get_component_at (model, e_table_get_cursor_row (etable));
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
-
- e_cal_component_memo_preview_display (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), comp_data->client, comp);
-
- e_cal_component_get_uid (comp, &uid);
- if (priv->current_uid)
- g_free (priv->current_uid);
- priv->current_uid = g_strdup (uid);
-
- g_object_unref (comp);
-}
-
-/* Callback used when the selection changes in the table. */
-static void
-table_selection_change_cb (ETable *etable, gpointer data)
-{
- EMemos *memos;
- gint n_selected;
-
- memos = E_MEMOS (data);
-
- n_selected = e_table_selected_count (etable);
- g_signal_emit (memos, e_memos_signals[SELECTION_CHANGED], 0, n_selected);
-
- if (n_selected != 1)
- e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (memos->priv->preview));
-
-}
-
-static void
-user_created_cb (GtkWidget *view, EMemos *memos)
-{
- EMemosPrivate *priv;
- EMemoTable *memo_table;
- ECal *ecal;
-
- priv = memos->priv;
- memo_table = E_MEMO_TABLE (priv->memos_view);
-
- if (memo_table->user_created_cal)
- ecal = memo_table->user_created_cal;
- else {
- ECalModel *model;
-
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
- ecal = e_cal_model_get_default_client (model);
- }
-
- e_memos_add_memo_source (memos, e_cal_get_source (ecal));
-}
-
-/* Callback used when the sexp in the search bar changes */
-static void
-search_bar_sexp_changed_cb (CalSearchBar *cal_search, const gchar *sexp, gpointer data)
-{
- EMemos *memos;
- EMemosPrivate *priv;
-
- memos = E_MEMOS (data);
- priv = memos->priv;
-
- if (priv->sexp)
- g_free (priv->sexp);
-
- priv->sexp = g_strdup (sexp);
-
- update_view (memos);
-}
-
-/* Callback used when the selected category in the search bar changes */
-static void
-search_bar_category_changed_cb (CalSearchBar *cal_search, const gchar *category, gpointer data)
-{
- EMemos *memos;
- EMemosPrivate *priv;
- ECalModel *model;
-
- memos = E_MEMOS (data);
- priv = memos->priv;
-
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
- e_cal_model_set_default_category (model, category);
-}
-
-static gboolean
-vpaned_resized_cb (GtkWidget *widget, GdkEventButton *event, EMemos *memos)
-{
- calendar_config_set_task_vpane_pos (gtk_paned_get_position (GTK_PANED (widget)));
-
- return FALSE;
-}
-
-static void
-set_timezone (EMemos *memos)
-{
- EMemosPrivate *priv;
- icaltimezone *zone;
- GList *l;
-
- priv = memos->priv;
-
- zone = calendar_config_get_icaltimezone ();
- for (l = priv->clients_list; l != NULL; l = l->next) {
- ECal *client = l->data;
-
- if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
- /* FIXME Error checking */
- e_cal_set_default_timezone (client, zone, NULL);
- }
-
- if (priv->default_client && e_cal_get_load_state (priv->default_client) == E_CAL_LOAD_LOADED)
- /* FIXME Error checking */
- e_cal_set_default_timezone (priv->default_client, zone, NULL);
-
- if (priv->preview)
- e_cal_component_memo_preview_set_default_timezone (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), zone);
-}
-
-static void
-timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EMemos *memos = data;
-
- set_timezone (memos);
-}
-
-static void
-update_view (EMemos *memos)
-{
- EMemosPrivate *priv;
- ECalModel *model;
-
- priv = memos->priv;
-
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
-
- e_cal_model_set_search_query (model, priv->sexp);
-
- e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview));
-}
-
-static void
-model_row_changed_cb (ETableModel *etm, gint row, gpointer data)
-{
- EMemos *memos;
- EMemosPrivate *priv;
- ECalModelComponent *comp_data;
-
- memos = E_MEMOS (data);
- priv = memos->priv;
-
- if (priv->current_uid) {
- const gchar *uid;
-
- comp_data = e_cal_model_get_component_at (E_CAL_MODEL (etm), row);
- if (comp_data) {
- uid = icalcomponent_get_uid (comp_data->icalcomp);
- if (!strcmp (uid ? uid : "", priv->current_uid)) {
- ETable *etable;
-
- etable = e_table_scrolled_get_table (
- E_TABLE_SCROLLED (E_MEMO_TABLE (priv->memos_view)->etable));
- table_cursor_change_cb (etable, 0, memos);
- }
- }
- }
-}
-
-static void
-setup_config (EMemos *memos)
-{
- EMemosPrivate *priv;
- guint not;
-
- priv = memos->priv;
-
- /* Timezone */
- set_timezone (memos);
-
- not = calendar_config_add_notification_timezone (timezone_changed_cb, memos);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-}
-
-struct AffectedComponents {
- EMemoTable *memo_table;
- GSList *components; /* contains pointers to ECalModelComponent */
-};
-
-/**
- * get_selected_components_cb
- * Helper function to fill list of selected components in EMemoTable.
- * This function is called from e_table_selected_row_foreach.
- **/
-static void
-get_selected_components_cb (gint model_row, gpointer data)
-{
- struct AffectedComponents *ac = (struct AffectedComponents *) data;
-
- if (!ac || !ac->memo_table)
- return;
-
- ac->components = g_slist_prepend (ac->components, e_cal_model_get_component_at (E_CAL_MODEL (e_memo_table_get_model (ac->memo_table)), model_row));
-}
-
-/**
- * do_for_selected_components
- * Calls function func for all selected components in memo_table.
- *
- * @param memo_table Table with selected components of our interest.
- * @param func Function to be called on each selected component from cal_table.
- * The first parameter of this function is a pointer to ECalModelComponent and
- * the second parameter of this function is pointer to cal_table
- * @param user_data User data, will be passed to func.
- **/
-static void
-do_for_selected_components (EMemoTable *memo_table, GFunc func, gpointer user_data)
-{
- ETable *etable;
- struct AffectedComponents ac;
-
- g_return_if_fail (memo_table != NULL);
-
- ac.memo_table = memo_table;
- ac.components = NULL;
-
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
- e_table_selected_row_foreach (etable, get_selected_components_cb, &ac);
-
- g_slist_foreach (ac.components, func, user_data);
- g_slist_free (ac.components);
-}
-
-/**
- * obtain_list_of_components
- * As a callback function to convert each ECalModelComponent to string
- * of format "source_uid\ncomponent_str" and add this newly allocated
- * string to the list of components. Strings should be freed with g_free.
- *
- * @param data ECalModelComponent object.
- * @param user_data Pointer to GSList list, where to put new strings.
- **/
-static void
-obtain_list_of_components (gpointer data, gpointer user_data)
-{
- GSList **list;
- ECalModelComponent *comp_data;
-
- list = (GSList **) user_data;
- comp_data = (ECalModelComponent *) data;
-
- if (list && comp_data) {
- gchar *comp_str;
- icalcomponent *vcal;
-
- vcal = e_cal_util_new_top_level ();
- e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
- icalcomponent_add_component (vcal, icalcomponent_new_clone (comp_data->icalcomp));
-
- comp_str = icalcomponent_as_ical_string_r (vcal);
- if (comp_str) {
- ESource *source = e_cal_get_source (comp_data->client);
- const gchar *source_uid = e_source_peek_uid (source);
-
- *list = g_slist_prepend (*list, g_strdup_printf ("%s\n%s", source_uid, comp_str));
-
- /* do not free this pointer, it owns libical */
- /* g_free (comp_str); */
- }
-
- icalcomponent_free (vcal);
- g_free (comp_str);
- }
-}
-
-static void
-table_drag_data_get (ETable *table,
- gint row,
- gint col,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- EMemos *memos)
-{
- EMemosPrivate *priv;
-
- priv = memos->priv;
-
- if (info == TARGET_VCALENDAR) {
- /* we will pass an icalcalendar component for both types */
- GSList *components = NULL;
-
- do_for_selected_components (E_MEMO_TABLE (priv->memos_view), obtain_list_of_components, &components);
-
- if (components) {
- cal_comp_selection_set_string_list (selection_data, components);
-
- g_slist_foreach (components, (GFunc)g_free, NULL);
- g_slist_free (components);
- }
- }
-}
-
-static void
-table_drag_data_delete (ETable *table,
- gint row,
- gint col,
- GdkDragContext *context,
- EMemos *memos)
-{
- /* Moved components are deleted from source immediately when moved,
- because some of them can be part of destination source, and we
- don't want to delete not-moved tasks. There is no such information
- which event has been moved and which not, so skip this method.
- */
-}
-
-#define E_MEMOS_TABLE_DEFAULT_STATE \
- "<?xml version=\"1.0\"?>" \
- "<ETableState>" \
- "<column source=\"1\"/>" \
- "<column source=\"0\"/>" \
- "<column source=\"2\"/>" \
- "<grouping></grouping>" \
- "</ETableState>"
-
-static void
-pane_realized (GtkWidget *widget, EMemos *memos)
-{
- gtk_paned_set_position ((GtkPaned *)widget, calendar_config_get_task_vpane_pos ());
-}
-
-static void
-setup_widgets (EMemos *memos)
-{
- EMemosPrivate *priv;
- ETable *etable;
- ECalModel *model;
-
- priv = memos->priv;
-
- priv->search_bar = cal_search_bar_new (CAL_SEARCH_MEMOS_DEFAULT);
- g_signal_connect (priv->search_bar, "sexp_changed",
- G_CALLBACK (search_bar_sexp_changed_cb), memos);
- g_signal_connect (priv->search_bar, "category_changed",
- G_CALLBACK (search_bar_category_changed_cb), memos);
-
- categories_changed_cb (NULL, memos);
-
- gtk_table_attach (GTK_TABLE (memos), priv->search_bar, 0, 1, 0, 1,
- GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0, 0);
- gtk_widget_show (priv->search_bar);
-
- /* add the paned widget for the memo list and memo detail areas */
- priv->paned = gtk_vpaned_new ();
- g_signal_connect (priv->paned, "realize", G_CALLBACK (pane_realized), memos);
-
- g_signal_connect (G_OBJECT (priv->paned), "button_release_event",
- G_CALLBACK (vpaned_resized_cb), memos);
- gtk_table_attach (GTK_TABLE (memos), priv->paned, 0, 1, 1, 2,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- gtk_widget_show (priv->paned);
-
- /* create the memo list */
- priv->memos_view = e_memo_table_new ();
- priv->memos_view_config = e_memo_table_config_new (E_MEMO_TABLE (priv->memos_view));
-
- g_signal_connect (priv->memos_view, "user_created", G_CALLBACK (user_created_cb), memos);
-
- etable = e_table_scrolled_get_table (
- E_TABLE_SCROLLED (E_MEMO_TABLE (priv->memos_view)->etable));
- e_table_set_state (etable, E_MEMOS_TABLE_DEFAULT_STATE);
-
- gtk_paned_add1 (GTK_PANED (priv->paned), priv->memos_view);
- gtk_widget_show (priv->memos_view);
-
- e_table_drag_source_set (etable, GDK_BUTTON1_MASK,
- list_drag_types, num_list_drag_types,
- GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_ASK);
-
- g_signal_connect (etable, "table_drag_data_get",
- G_CALLBACK(table_drag_data_get), memos);
- g_signal_connect (etable, "table_drag_data_delete",
- G_CALLBACK(table_drag_data_delete), memos);
-
- g_signal_connect (etable, "cursor_change", G_CALLBACK (table_cursor_change_cb), memos);
- g_signal_connect (etable, "selection_change", G_CALLBACK (table_selection_change_cb), memos);
-
- /* create the memo detail */
- priv->preview = e_cal_component_memo_preview_new ();
- e_cal_component_memo_preview_set_default_timezone (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), calendar_config_get_icaltimezone ());
- gtk_paned_add2 (GTK_PANED (priv->paned), priv->preview);
- gtk_widget_show (priv->preview);
-
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
- g_signal_connect (G_OBJECT (model), "model_row_changed",
- G_CALLBACK (model_row_changed_cb), memos);
-}
-
-/* Class initialization function for the gnome calendar */
-static void
-e_memos_class_init (EMemosClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) klass;
-
- e_memos_signals[SELECTION_CHANGED] =
- g_signal_new ("selection_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMemosClass, selection_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- e_memos_signals[SOURCE_ADDED] =
- g_signal_new ("source_added",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMemosClass, source_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
-
- e_memos_signals[SOURCE_REMOVED] =
- g_signal_new ("source_removed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMemosClass, source_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
-
- object_class->destroy = e_memos_destroy;
-
- klass->selection_changed = NULL;
- klass->source_added = NULL;
- klass->source_removed = NULL;
-}
-
-static void
-categories_changed_cb (gpointer object, gpointer user_data)
-{
- GList *cat_list;
- GPtrArray *cat_array;
- EMemosPrivate *priv;
- EMemos *memos = user_data;
-
- priv = memos->priv;
-
- cat_array = g_ptr_array_new ();
- cat_list = e_categories_get_list ();
- while (cat_list != NULL) {
- if (e_categories_is_searchable ((const gchar *) cat_list->data))
- g_ptr_array_add (cat_array, cat_list->data);
- cat_list = g_list_remove (cat_list, cat_list->data);
- }
-
- cal_search_bar_set_categories (CAL_SEARCH_BAR(priv->search_bar), cat_array);
-
- g_ptr_array_free (cat_array, TRUE);
-}
-
-/* Object initialization function for the gnome calendar */
-static void
-e_memos_init (EMemos *memos)
-{
- EMemosPrivate *priv;
-
- priv = g_new0 (EMemosPrivate, 1);
- memos->priv = priv;
-
- setup_config (memos);
- setup_widgets (memos);
-
- e_categories_register_change_listener (G_CALLBACK (categories_changed_cb), memos);
-
- priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
- priv->query = NULL;
- priv->view_instance = NULL;
- priv->view_menus = NULL;
- priv->current_uid = NULL;
- priv->sexp = g_strdup ("#t");
- priv->default_client = NULL;
- update_view (memos);
-}
-
-GtkWidget *
-e_memos_new (void)
-{
- EMemos *memos;
-
- memos = g_object_new (e_memos_get_type (), NULL);
-
- return GTK_WIDGET (memos);
-}
-
-void
-e_memos_set_ui_component (EMemos *memos,
- BonoboUIComponent *ui_component)
-{
- g_return_if_fail (E_IS_MEMOS (memos));
- g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component));
-
- e_search_bar_set_ui_component (E_SEARCH_BAR (memos->priv->search_bar), ui_component);
-}
-
-static void
-e_memos_destroy (GtkObject *object)
-{
- EMemos *memos;
- EMemosPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (E_IS_MEMOS (object));
-
- memos = E_MEMOS (object);
- priv = memos->priv;
-
- if (priv) {
- GList *l;
-
- e_categories_unregister_change_listener (G_CALLBACK (categories_changed_cb), memos);
-
- /* disconnect from signals on all the clients */
- for (l = priv->clients_list; l != NULL; l = l->next) {
- g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, memos);
- }
-
- g_hash_table_destroy (priv->clients);
- g_list_free (priv->clients_list);
-
- if (priv->default_client)
- g_object_unref (priv->default_client);
- priv->default_client = NULL;
-
- if (priv->current_uid) {
- g_free (priv->current_uid);
- priv->current_uid = NULL;
- }
-
- if (priv->sexp) {
- g_free (priv->sexp);
- priv->sexp = NULL;
- }
-
- if (priv->memos_view_config) {
- g_object_unref (priv->memos_view_config);
- priv->memos_view_config = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
- priv->notifications = NULL;
-
- g_free (priv);
- memos->priv = NULL;
- }
-
- if (GTK_OBJECT_CLASS (e_memos_parent_class)->destroy)
- (* GTK_OBJECT_CLASS (e_memos_parent_class)->destroy) (object);
-}
-
-static void
-set_status_message (EMemos *memos, const gchar *message, ...)
-{
- EMemosPrivate *priv;
- va_list args;
- gchar sz[2048], *msg_string = NULL;
-
- if (message) {
- va_start (args, message);
- vsnprintf (sz, sizeof sz, message, args);
- va_end (args);
- msg_string = sz;
- }
-
- priv = memos->priv;
-
- e_memo_table_set_status_message (E_MEMO_TABLE (priv->memos_view), msg_string);
-}
-
-/* Callback from the calendar client when an error occurs in the backend */
-static void
-backend_error_cb (ECal *client, const gchar *message, gpointer data)
-{
- EMemos *memos;
- GtkWidget *dialog;
- gchar *urinopwd;
-
- memos = E_MEMOS (data);
-
- urinopwd = get_uri_without_password (e_cal_get_uri (client));
-
- dialog = gtk_message_dialog_new (
- GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _("Error on %s:\n %s"), urinopwd, message);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- g_free (urinopwd);
-}
-
-/* Callback from the calendar client when the backend dies */
-static void
-backend_died_cb (ECal *client, gpointer data)
-{
- EMemos *memos;
- EMemosPrivate *priv;
- ESource *source;
-
- memos = E_MEMOS (data);
- priv = memos->priv;
-
- source = g_object_ref (e_cal_get_source (client));
-
- priv->clients_list = g_list_remove (priv->clients_list, client);
- g_hash_table_remove (priv->clients, e_source_peek_uid (source));
-
- g_signal_emit (memos, e_memos_signals[SOURCE_REMOVED], 0, source);
-
- e_memo_table_set_status_message (E_MEMO_TABLE (e_memos_get_calendar_table (memos)), NULL);
-
- e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))),
- "calendar:memos-crashed", NULL);
-
- g_object_unref (source);
-}
-
-/* Callback from the calendar client when the calendar is opened */
-static void
-client_cal_opened_cb (ECal *ecal, ECalendarStatus status, EMemos *memos)
-{
- ECalModel *model;
- ESource *source;
- EMemosPrivate *priv;
-
- priv = memos->priv;
-
- source = e_cal_get_source (ecal);
-
- if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
- auth_cal_forget_password (ecal);
-
- switch (status) {
- case E_CALENDAR_STATUS_OK :
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL);
-
- set_status_message (memos, _("Loading memos"));
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
- e_cal_model_add_client (model, ecal);
-
- set_timezone (memos);
- set_status_message (memos, NULL);
- break;
- case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
- /* try to reopen calendar - it'll ask for a password once again */
- e_cal_open_async (ecal, FALSE);
- return;
- case E_CALENDAR_STATUS_BUSY :
- break;
- case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
- e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))), "calendar:prompt-no-contents-offline-memos", NULL);
- default :
- /* Make sure the source doesn't disappear on us */
- g_object_ref (source);
-
- priv->clients_list = g_list_remove (priv->clients_list, ecal);
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, memos);
-
- /* Do this last because it unrefs the client */
- g_hash_table_remove (priv->clients, e_source_peek_uid (source));
-
- g_signal_emit (memos, e_memos_signals[SOURCE_REMOVED], 0, source);
-
- set_status_message (memos, NULL);
- g_object_unref (source);
-
- break;
- }
-}
-
-static void
-default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, EMemos *memos)
-{
- ECalModel *model;
- ESource *source;
- EMemosPrivate *priv;
-
- priv = memos->priv;
-
- source = e_cal_get_source (ecal);
-
- if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
- auth_cal_forget_password (ecal);
-
- switch (status) {
- case E_CALENDAR_STATUS_OK :
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL);
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
-
- set_timezone (memos);
- e_cal_model_set_default_client (model, ecal);
- set_status_message (memos, NULL);
- break;
- case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
- /* try to reopen calendar - it'll ask for a password once again */
- e_cal_open_async (ecal, FALSE);
- return;
- case E_CALENDAR_STATUS_BUSY:
- break;
- default :
- /* Make sure the source doesn't disappear on us */
- g_object_ref (source);
-
- priv->clients_list = g_list_remove (priv->clients_list, ecal);
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, memos);
-
- /* Do this last because it unrefs the client */
- g_hash_table_remove (priv->clients, e_source_peek_uid (source));
-
- g_signal_emit (memos, e_memos_signals[SOURCE_REMOVED], 0, source);
-
- set_status_message (memos, NULL);
- g_object_unref (priv->default_client);
- priv->default_client = NULL;
- g_object_unref (source);
-
- break;
- }
-}
-
-typedef void (*open_func) (ECal *, ECalendarStatus, EMemos *);
-
-static gboolean
-open_ecal (EMemos *memos, ECal *cal, gboolean only_if_exists, open_func of)
-{
- set_status_message (memos, _("Opening memos at %s"), e_cal_get_uri (cal));
-
- g_signal_connect (G_OBJECT (cal), "cal_opened", G_CALLBACK (of), memos);
- e_cal_open_async (cal, only_if_exists);
-
- return TRUE;
-}
-
-void
-e_memos_open_memo (EMemos *memos)
-{
- EMemoTable *cal_table;
-
- cal_table = e_memos_get_calendar_table (memos);
- e_memo_table_open_selected (cal_table);
-}
-
-void
-e_memos_new_memo (EMemos *memos)
-{
- /* used for click_to_add ?? Can't figure out anything else it's used for */
-}
-
-gboolean
-e_memos_add_memo_source (EMemos *memos, ESource *source)
-{
- EMemosPrivate *priv;
- ECal *client;
- const gchar *uid;
-
- g_return_val_if_fail (memos != NULL, FALSE);
- g_return_val_if_fail (E_IS_MEMOS (memos), FALSE);
- g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
-
- priv = memos->priv;
-
- uid = e_source_peek_uid (source);
- client = g_hash_table_lookup (priv->clients, uid);
- if (client) {
- /* We already have it */
-
- return TRUE;
- } else {
- ESource *default_source;
-
- if (priv->default_client) {
- default_source = e_cal_get_source (priv->default_client);
-
- /* We don't have it but the default client is it */
- if (!strcmp (e_source_peek_uid (default_source), uid))
- client = g_object_ref (priv->default_client);
- }
-
- /* Create a new one */
- if (!client) {
- client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
- if (!client)
- return FALSE;
- }
- }
-
- g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), memos);
- g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), memos);
-
- /* add the client to internal structure */
- g_hash_table_insert (priv->clients, g_strdup (uid) , client);
- priv->clients_list = g_list_prepend (priv->clients_list, client);
-
- g_signal_emit (memos, e_memos_signals[SOURCE_ADDED], 0, source);
-
- open_ecal (memos, client, FALSE, client_cal_opened_cb);
-
- return TRUE;
-}
-
-gboolean
-e_memos_remove_memo_source (EMemos *memos, ESource *source)
-{
- EMemosPrivate *priv;
- ECal *client;
- ECalModel *model;
- const gchar *uid;
-
- g_return_val_if_fail (memos != NULL, FALSE);
- g_return_val_if_fail (E_IS_MEMOS (memos), FALSE);
- g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
-
- priv = memos->priv;
-
- uid = e_source_peek_uid (source);
- client = g_hash_table_lookup (priv->clients, uid);
- if (!client)
- return TRUE;
-
- priv->clients_list = g_list_remove (priv->clients_list, client);
- g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, memos);
-
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
- e_cal_model_remove_client (model, client);
-
- g_hash_table_remove (priv->clients, uid);
-
- g_signal_emit (memos, e_memos_signals[SOURCE_REMOVED], 0, source);
-
- return TRUE;
-}
-
-gboolean
-e_memos_set_default_source (EMemos *memos, ESource *source)
-{
- EMemosPrivate *priv;
- ECal *ecal;
-
- g_return_val_if_fail (memos != NULL, FALSE);
- g_return_val_if_fail (E_IS_MEMOS (memos), FALSE);
- g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
-
- priv = memos->priv;
-
- ecal = g_hash_table_lookup (priv->clients, e_source_peek_uid (source));
-
- if (priv->default_client)
- g_object_unref (priv->default_client);
-
- if (ecal) {
- priv->default_client = g_object_ref (ecal);
- } else {
- priv->default_client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
- if (!priv->default_client)
- return FALSE;
- }
-
- open_ecal (memos, priv->default_client, FALSE, default_client_cal_opened_cb);
-
- return TRUE;
-}
-
-ECal *
-e_memos_get_default_client (EMemos *memos)
-{
- EMemosPrivate *priv;
-
- g_return_val_if_fail (memos != NULL, NULL);
- g_return_val_if_fail (E_IS_MEMOS (memos), NULL);
-
- priv = memos->priv;
-
- return e_cal_model_get_default_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view)));
-}
-
-/**
- * e_memos_delete_selected:
- * @memos: A memos control widget.
- *
- * Deletes the selected memos in the memo list.
- **/
-void
-e_memos_delete_selected (EMemos *memos)
-{
- EMemosPrivate *priv;
- EMemoTable *cal_table;
-
- g_return_if_fail (memos != NULL);
- g_return_if_fail (E_IS_MEMOS (memos));
-
- priv = memos->priv;
-
- cal_table = E_MEMO_TABLE (priv->memos_view);
- set_status_message (memos, _("Deleting selected objects..."));
- e_memo_table_delete_selected (cal_table);
- set_status_message (memos, NULL);
-
- e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview));
-}
-
-/* Callback used from the view collection when we need to display a new view */
-static void
-display_view_cb (GalViewInstance *instance, GalView *view, gpointer data)
-{
- EMemos *memos;
-
- memos = E_MEMOS (data);
-
- if (GAL_IS_VIEW_ETABLE (view)) {
- gal_view_etable_attach_table (GAL_VIEW_ETABLE (view), e_table_scrolled_get_table (E_TABLE_SCROLLED (E_MEMO_TABLE (memos->priv->memos_view)->etable)));
- }
-
- gtk_paned_set_position ((GtkPaned *)memos->priv->paned, calendar_config_get_task_vpane_pos ());
-}
-
-/**
- * e_memos_setup_view_menus:
- * @memos: A memos widget.
- * @uic: UI controller to use for the menus.
- *
- * Sets up the #GalView menus for a memos control. This function should be
- * called from the Bonobo control activation callback for this memos control.
- * Also, the menus should be discarded using e_memos_discard_view_menus().
- */
-void
-e_memos_setup_view_menus (EMemos *memos, BonoboUIComponent *uic)
-{
- EMemosPrivate *priv;
- GalViewFactory *factory;
- ETableSpecification *spec;
- gchar *dir0, *dir1, *filename;
- static GalViewCollection *collection = NULL;
-
- g_return_if_fail (memos != NULL);
- g_return_if_fail (E_IS_MEMOS (memos));
- g_return_if_fail (uic != NULL);
- g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
-
- priv = memos->priv;
-
- g_return_if_fail (priv->view_instance == NULL);
-
- g_return_if_fail (priv->view_instance == NULL);
- g_return_if_fail (priv->view_menus == NULL);
-
- /* Create the view instance */
-
- if (collection == NULL) {
- collection = gal_view_collection_new ();
-
- gal_view_collection_set_title (collection, _("Memos"));
-
- dir0 = g_build_filename (EVOLUTION_GALVIEWSDIR,
- "memos",
- NULL);
- dir1 = g_build_filename (memos_component_peek_base_directory (memos_component_peek ()),
- "views", NULL);
- gal_view_collection_set_storage_directories (collection,
- dir0,
- dir1);
- g_free (dir1);
- g_free (dir0);
-
- /* Create the views */
-
- spec = e_table_specification_new ();
- filename = g_build_filename (EVOLUTION_ETSPECDIR,
- "e-memo-table.etspec",
- NULL);
- if (!e_table_specification_load_from_file (spec, filename))
- g_error ("Unable to load ETable specification file "
- "for memos");
- g_free (filename);
-
- factory = gal_view_factory_etable_new (spec);
- g_object_unref (spec);
- gal_view_collection_add_factory (collection, factory);
- g_object_unref (factory);
-
- /* Load the collection and create the menus */
-
- gal_view_collection_load (collection);
- }
-
- priv->view_instance = gal_view_instance_new (collection, NULL);
-
- priv->view_menus = gal_view_menus_new (priv->view_instance);
- gal_view_menus_apply (priv->view_menus, uic, NULL);
- g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), memos);
- display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), memos);
-}
-
-/**
- * e_memos_discard_view_menus:
- * @memos: A memos widget.
- *
- * Discards the #GalView menus used by a memos control. This function should be
- * called from the Bonobo control deactivation callback for this memos control.
- * The menus should have been set up with e_memos_setup_view_menus().
- **/
-void
-e_memos_discard_view_menus (EMemos *memos)
-{
- EMemosPrivate *priv;
-
- g_return_if_fail (memos != NULL);
- g_return_if_fail (E_IS_MEMOS (memos));
-
- priv = memos->priv;
-
- g_return_if_fail (priv->view_instance != NULL);
-
- g_return_if_fail (priv->view_instance != NULL);
- g_return_if_fail (priv->view_menus != NULL);
-
- g_object_unref (priv->view_instance);
- priv->view_instance = NULL;
-
- g_object_unref (priv->view_menus);
- priv->view_menus = NULL;
-}
-
-/**
- * e_memos_get_calendar_table:
- * @memos: A memos widget.
- *
- * Queries the #EMemoTable contained in a memos widget.
- *
- * Return value: The #EMemoTable that the memos widget uses to display its
- * information.
- **/
-EMemoTable *
-e_memos_get_calendar_table (EMemos *memos)
-{
- EMemosPrivate *priv;
-
- g_return_val_if_fail (memos != NULL, NULL);
- g_return_val_if_fail (E_IS_MEMOS (memos), NULL);
-
- priv = memos->priv;
- return E_MEMO_TABLE (priv->memos_view);
-}
-
-/**
- * e_memos_get_preview:
- * @memos: A memos widget.
- *
- * Queries the #ECalComponentMemoPreview contained in a memos widget.
- **/
-GtkWidget *
-e_memos_get_preview (EMemos *memos)
-{
- g_return_val_if_fail (memos != NULL, NULL);
- g_return_val_if_fail (E_IS_MEMOS (memos), NULL);
-
- return memos->priv->preview;
-}
diff --git a/calendar/gui/e-memos.h b/calendar/gui/e-memos.h
deleted file mode 100644
index a03541c6d6..0000000000
--- a/calendar/gui/e-memos.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena Quintero <federico@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_MEMOS_H_
-#define _E_MEMOS_H_
-
-#include <bonobo/bonobo-ui-component.h>
-#include <gtk/gtk.h>
-#include <libedataserver/e-source.h>
-#include <libecal/e-cal.h>
-#include "e-memo-table.h"
-
-#define E_TYPE_MEMOS (e_memos_get_type ())
-#define E_MEMOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MEMOS, EMemos))
-#define E_MEMOS_CLASS(klass) (G_TYPE_CHECK_INSTANCE_CAST_CLASS ((klass), E_TYPE_MEMOS, \
- EMemosClass))
-#define E_IS_MEMOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MEMOS))
-#define E_IS_MEMOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_MEMOS))
-
-typedef struct _EMemos EMemos;
-typedef struct _EMemosClass EMemosClass;
-typedef struct _EMemosPrivate EMemosPrivate;
-
-struct _EMemos {
- GtkTable table;
-
- /* Private data */
- EMemosPrivate *priv;
-};
-
-struct _EMemosClass {
- GtkTableClass parent_class;
-
- /* Notification signals */
- void (* selection_changed) (EMemos *memos, gint n_selected);
- void (* source_added) (EMemos *memos, ESource *source);
- void (* source_removed) (EMemos *memos, ESource *source);
-};
-
-GType e_memos_get_type (void);
-GtkWidget *e_memos_construct (EMemos *memos);
-
-GtkWidget *e_memos_new (void);
-
-void e_memos_set_ui_component (EMemos *memos,
- BonoboUIComponent *ui_component);
-
-gboolean e_memos_add_memo_source (EMemos *memos, ESource *source);
-gboolean e_memos_remove_memo_source (EMemos *memos, ESource *source);
-gboolean e_memos_set_default_source (EMemos *memos, ESource *source);
-ECal *e_memos_get_default_client (EMemos *memos);
-
-void e_memos_open_memo (EMemos *memos);
-void e_memos_new_memo (EMemos *memos);
-void e_memos_complete_selected (EMemos *memos);
-void e_memos_delete_selected (EMemos *memos);
-
-void e_memos_setup_view_menus (EMemos *memos, BonoboUIComponent *uic);
-void e_memos_discard_view_menus (EMemos *memos);
-
-EMemoTable *e_memos_get_calendar_table (EMemos *memos);
-GtkWidget *e_memos_get_preview (EMemos *memos);
-
-#endif /* _E_MEMOS_H_ */
diff --git a/calendar/gui/e-mini-calendar-config.c b/calendar/gui/e-mini-calendar-config.c
deleted file mode 100644
index d9b2192ad2..0000000000
--- a/calendar/gui/e-mini-calendar-config.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "calendar-config.h"
-#include "e-mini-calendar-config.h"
-
-struct _EMiniCalendarConfigPrivate {
- ECalendar *mini_cal;
-
- GList *notifications;
-};
-
-/* Property IDs */
-enum props {
- PROP_0,
- PROP_CALENDAR
-};
-
-G_DEFINE_TYPE (EMiniCalendarConfig, e_mini_calendar_config, G_TYPE_OBJECT)
-
-static void
-e_mini_calendar_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- EMiniCalendarConfig *mini_config;
-
- mini_config = E_MINI_CALENDAR_CONFIG (object);
-
- switch (property_id) {
- case PROP_CALENDAR:
- e_mini_calendar_config_set_calendar (mini_config, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_mini_calendar_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- EMiniCalendarConfig *mini_config;
-
- mini_config = E_MINI_CALENDAR_CONFIG (object);
-
- switch (property_id) {
- case PROP_CALENDAR:
- g_value_set_object (value, e_mini_calendar_config_get_calendar (mini_config));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_mini_calendar_config_dispose (GObject *object)
-{
- EMiniCalendarConfig *mini_config = E_MINI_CALENDAR_CONFIG (object);
-
- e_mini_calendar_config_set_calendar (mini_config, NULL);
-
- if (G_OBJECT_CLASS (e_mini_calendar_config_parent_class)->dispose)
- G_OBJECT_CLASS (e_mini_calendar_config_parent_class)->dispose (object);
-}
-
-static void
-e_mini_calendar_config_finalize (GObject *object)
-{
- EMiniCalendarConfig *mini_config = E_MINI_CALENDAR_CONFIG (object);
- EMiniCalendarConfigPrivate *priv;
-
- priv = mini_config->priv;
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_mini_calendar_config_parent_class)->finalize)
- G_OBJECT_CLASS (e_mini_calendar_config_parent_class)->finalize (object);
-}
-
-static void
-e_mini_calendar_config_class_init (EMiniCalendarConfigClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *spec;
-
- /* Method override */
- gobject_class->set_property = e_mini_calendar_config_set_property;
- gobject_class->get_property = e_mini_calendar_config_get_property;
- gobject_class->dispose = e_mini_calendar_config_dispose;
- gobject_class->finalize = e_mini_calendar_config_finalize;
-
- spec = g_param_spec_object ("calendar", NULL, NULL, e_calendar_get_type (),
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (gobject_class, PROP_CALENDAR, spec);
-}
-
-static void
-e_mini_calendar_config_init (EMiniCalendarConfig *mini_config)
-{
- mini_config->priv = g_new0 (EMiniCalendarConfigPrivate, 1);
-
-}
-
-EMiniCalendarConfig *
-e_mini_calendar_config_new (ECalendar *mini_cal)
-{
- EMiniCalendarConfig *mini_config;
-
- mini_config = g_object_new (e_mini_calendar_config_get_type (), "calendar", mini_cal, NULL);
-
- return mini_config;
-}
-
-ECalendar *
-e_mini_calendar_config_get_calendar (EMiniCalendarConfig *mini_config)
-{
- EMiniCalendarConfigPrivate *priv;
-
- g_return_val_if_fail (mini_config != NULL, NULL);
- g_return_val_if_fail (E_IS_MINI_CALENDAR_CONFIG (mini_config), NULL);
-
- priv = mini_config->priv;
-
- return priv->mini_cal;
-}
-
-static void
-set_week_start (ECalendar *mini_cal)
-{
- gint week_start_day;
-
- week_start_day = calendar_config_get_week_start_day ();
-
- /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
- week_start_day = (week_start_day + 6) % 7;
-
- gnome_canvas_item_set (GNOME_CANVAS_ITEM (mini_cal->calitem),
- "week_start_day", week_start_day,
- NULL);
-}
-
-static void
-week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EMiniCalendarConfig *mini_config = data;
- EMiniCalendarConfigPrivate *priv;
-
- priv = mini_config->priv;
-
- set_week_start (priv->mini_cal);
-}
-
-static void
-set_dnav_show_week_no (ECalendar *mini_cal)
-{
- gboolean show_week_no;
-
- show_week_no = calendar_config_get_dnav_show_week_no ();
-
- gnome_canvas_item_set (GNOME_CANVAS_ITEM (mini_cal->calitem),
- "show_week_numbers", show_week_no,
- NULL);
-}
-
-static void
-dnav_show_week_no_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EMiniCalendarConfig *mini_config = data;
- EMiniCalendarConfigPrivate *priv;
-
- priv = mini_config->priv;
-
- set_dnav_show_week_no (priv->mini_cal);
-}
-
-void
-e_mini_calendar_config_set_calendar (EMiniCalendarConfig *mini_config, ECalendar *mini_cal)
-{
- EMiniCalendarConfigPrivate *priv;
- guint not;
- GList *l;
-
- g_return_if_fail (mini_config != NULL);
- g_return_if_fail (E_IS_MINI_CALENDAR_CONFIG (mini_config));
-
- priv = mini_config->priv;
-
- if (priv->mini_cal) {
- g_object_unref (priv->mini_cal);
- priv->mini_cal = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
-
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- /* If the new view is NULL, return right now */
- if (!mini_cal)
- return;
-
- priv->mini_cal = g_object_ref (mini_cal);
-
- /* Week start */
- set_week_start (mini_cal);
-
- not = calendar_config_add_notification_week_start_day (week_start_changed_cb, mini_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Show week numbers */
- set_dnav_show_week_no (mini_cal);
-
- not = calendar_config_add_notification_dnav_show_week_no (dnav_show_week_no_changed_cb, mini_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-}
diff --git a/calendar/gui/e-mini-calendar-config.h b/calendar/gui/e-mini-calendar-config.h
deleted file mode 100644
index 60c88a1b9c..0000000000
--- a/calendar/gui/e-mini-calendar-config.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_MINI_CALENDAR_CONFIG_H_
-#define _E_MINI_CALENDAR_CONFIG_H_
-
-#include <misc/e-calendar.h>
-
-G_BEGIN_DECLS
-
-#define E_MINI_CALENDAR_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_mini_calendar_config_get_type (), EMiniCalendarConfig)
-#define E_MINI_CALENDAR_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_mini_calendar_config_get_type (), EMiniCalendarConfigClass)
-#define E_IS_MINI_CALENDAR_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_mini_calendar_config_get_type ())
-
-typedef struct _EMiniCalendarConfig EMiniCalendarConfig;
-typedef struct _EMiniCalendarConfigClass EMiniCalendarConfigClass;
-typedef struct _EMiniCalendarConfigPrivate EMiniCalendarConfigPrivate;
-
-struct _EMiniCalendarConfig {
- GObject parent;
-
- EMiniCalendarConfigPrivate *priv;
-};
-
-struct _EMiniCalendarConfigClass {
- GObjectClass parent_class;
-};
-
-GType e_mini_calendar_config_get_type (void);
-EMiniCalendarConfig *e_mini_calendar_config_new (ECalendar *mini_cal);
-ECalendar *e_mini_calendar_config_get_calendar (EMiniCalendarConfig *mini_config);
-void e_mini_calendar_config_set_calendar (EMiniCalendarConfig *mini_config, ECalendar *mini_cal);
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/e-month-view.c b/calendar/gui/e-month-view.c
new file mode 100644
index 0000000000..238492c92c
--- /dev/null
+++ b/calendar/gui/e-month-view.c
@@ -0,0 +1,213 @@
+/*
+ * e-month-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-month-view.h"
+
+#include <libecal/e-cal-time-util.h>
+
+#define E_MONTH_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MONTH_VIEW, EMonthViewPrivate))
+
+struct _EMonthViewPrivate {
+ gint placeholder;
+};
+
+static gpointer parent_class;
+
+static void
+month_view_cursor_key_up (EWeekView *week_view)
+{
+ if (week_view->selection_start_day == -1)
+ return;
+
+ if (week_view->selection_start_day < 7) {
+ /* No easy way to calculate new selection_start_day, so
+ * calculate a time_t value and set_selected_time_range. */
+ time_t current;
+
+ if (e_calendar_view_get_selected_time_range (
+ E_CALENDAR_VIEW (week_view), &current, NULL)) {
+
+ current = time_add_week (current, -1);
+ e_week_view_scroll_a_step (
+ week_view, E_CAL_VIEW_MOVE_PAGE_UP);
+ e_week_view_set_selected_time_range_visible (
+ week_view, current, current);
+ }
+ } else {
+ week_view->selection_start_day -= 7;
+ week_view->selection_end_day = week_view->selection_start_day;
+ }
+
+ g_signal_emit_by_name (week_view, "selected-time-changed");
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+
+static void
+month_view_cursor_key_down (EWeekView *week_view)
+{
+ gint weeks_shown;
+
+ if (week_view->selection_start_day == -1)
+ return;
+
+ weeks_shown = e_week_view_get_weeks_shown (week_view);
+
+ if (week_view->selection_start_day >= (weeks_shown - 1) * 7) {
+ /* No easy way to calculate new selection_start_day, so
+ * calculate a time_t value and set_selected_time_range. */
+ time_t current;
+
+ if (e_calendar_view_get_selected_time_range (
+ E_CALENDAR_VIEW (week_view), &current, NULL)) {
+
+ current = time_add_week (current, -1);
+ e_week_view_scroll_a_step (
+ week_view, E_CAL_VIEW_MOVE_PAGE_DOWN);
+ e_week_view_set_selected_time_range_visible (
+ week_view, current, current);
+ }
+ } else {
+ week_view->selection_start_day += 7;
+ week_view->selection_end_day = week_view->selection_start_day;
+ }
+
+ g_signal_emit_by_name (week_view, "selected-time-changed");
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+
+static void
+month_view_cursor_key_left (EWeekView *week_view)
+{
+ if (week_view->selection_start_day == -1)
+ return;
+
+ if (week_view->selection_start_day == 0) {
+ /* No easy way to calculate new selection_start_day, so
+ * calculate a time_t value and set_selected_time_range. */
+ time_t current;
+
+ if (e_calendar_view_get_selected_time_range (
+ E_CALENDAR_VIEW (week_view), &current, NULL)) {
+
+ current = time_add_day (current, -1);
+ e_week_view_scroll_a_step (
+ week_view, E_CAL_VIEW_MOVE_PAGE_UP);
+ e_week_view_set_selected_time_range_visible (
+ week_view, current, current);
+ }
+ } else {
+ week_view->selection_start_day--;
+ week_view->selection_end_day = week_view->selection_start_day;
+ }
+
+ g_signal_emit_by_name (week_view, "selected-time-changed");
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+
+static void
+month_view_cursor_key_right (EWeekView *week_view)
+{
+ gint weeks_shown;
+
+ if (week_view->selection_start_day == -1)
+ return;
+
+ weeks_shown = e_week_view_get_weeks_shown (week_view);
+
+ if (week_view->selection_start_day == weeks_shown * 7 - 1) {
+ /* No easy way to calculate new selection_start_day, so
+ * calculate a time_t value and set_selected_time_range. */
+ time_t current;
+
+ if (e_calendar_view_get_selected_time_range (
+ E_CALENDAR_VIEW (week_view), &current, NULL)) {
+
+ current = time_add_day (current, 1);
+ e_week_view_scroll_a_step (
+ week_view, E_CAL_VIEW_MOVE_PAGE_DOWN);
+ e_week_view_set_selected_time_range_visible (
+ week_view, current, current);
+ }
+ } else {
+ week_view->selection_start_day++;
+ week_view->selection_end_day = week_view->selection_start_day;
+ }
+
+ g_signal_emit_by_name (week_view, "selected-time-changed");
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+
+static void
+month_view_class_init (EMonthViewClass *class)
+{
+ EWeekViewClass *week_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMonthViewPrivate));
+
+ week_view_class = E_WEEK_VIEW_CLASS (class);
+ week_view_class->cursor_key_up = month_view_cursor_key_up;
+ week_view_class->cursor_key_down = month_view_cursor_key_down;
+ week_view_class->cursor_key_left = month_view_cursor_key_left;
+ week_view_class->cursor_key_right = month_view_cursor_key_right;
+}
+
+static void
+month_view_init (EMonthView *month_view)
+{
+ month_view->priv = E_MONTH_VIEW_GET_PRIVATE (month_view);
+}
+
+GType
+e_month_view_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EMonthViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) month_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMonthView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) month_view_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_WEEK_VIEW, "EMonthView", &type_info, 0);
+ }
+
+ return type;
+}
+
+ECalendarView *
+e_month_view_new (ECalModel *model)
+{
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
+
+ return g_object_new (E_TYPE_MONTH_VIEW, "model", model, NULL);
+}
diff --git a/calendar/gui/e-month-view.h b/calendar/gui/e-month-view.h
new file mode 100644
index 0000000000..0ff91a963f
--- /dev/null
+++ b/calendar/gui/e-month-view.h
@@ -0,0 +1,66 @@
+/*
+ * e-month-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MONTH_VIEW_H
+#define E_MONTH_VIEW_H
+
+#include "e-week-view.h"
+
+/* Standard GObject macros */
+#define E_TYPE_MONTH_VIEW \
+ (e_month_view_get_type ())
+#define E_MONTH_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MONTH_VIEW, EMonthView))
+#define E_MONTH_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((obj), E_TYPE_MONTH_VIEW, EMonthViewClass))
+#define E_IS_MONTH_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MONTH_VIEW))
+#define E_IS_MONTH_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MONTH_VIEW))
+#define E_MONTH_VIEW_GET_CLASS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MONTH_VIEW, EMonthViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMonthView EMonthView;
+typedef struct _EMonthViewClass EMonthViewClass;
+typedef struct _EMonthViewPrivate EMonthViewPrivate;
+
+struct _EMonthView {
+ EWeekView parent;
+ EMonthViewPrivate *priv;
+};
+
+struct _EMonthViewClass {
+ EWeekViewClass parent_class;
+};
+
+GType e_month_view_get_type (void);
+ECalendarView * e_month_view_new (ECalModel *model);
+
+G_END_DECLS
+
+#endif /* E_MONTH_VIEW_H */
diff --git a/calendar/gui/e-task-list-selector.c b/calendar/gui/e-task-list-selector.c
new file mode 100644
index 0000000000..fa6bd328d9
--- /dev/null
+++ b/calendar/gui/e-task-list-selector.c
@@ -0,0 +1,288 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-task-list-selector.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "e-task-list-selector.h"
+
+#include <string.h>
+#include <libecal/e-cal.h>
+#include "calendar/common/authentication.h"
+#include "calendar/gui/comp-util.h"
+
+#define E_TASK_LIST_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorPrivate))
+
+struct _ETaskListSelectorPrivate {
+ gint dummy_value;
+};
+
+enum {
+ DND_TARGET_TYPE_CALENDAR_LIST
+};
+
+static GtkTargetEntry drag_types[] = {
+ { (gchar *) "text/calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST },
+ { (gchar *) "text/x-calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST }
+};
+
+static gpointer parent_class;
+
+static gboolean
+task_list_selector_update_single_object (ECal *client,
+ icalcomponent *icalcomp)
+{
+ gchar *uid;
+ icalcomponent *tmp_icalcomp;
+
+ uid = (gchar *) icalcomponent_get_uid (icalcomp);
+
+ if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL))
+ return e_cal_modify_object (
+ client, icalcomp, CALOBJ_MOD_ALL, NULL);
+
+ return e_cal_create_object (client, icalcomp, &uid, NULL);
+}
+
+static gboolean
+task_list_selector_update_objects (ECal *client,
+ icalcomponent *icalcomp)
+{
+ icalcomponent *subcomp;
+ icalcomponent_kind kind;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VTODO_COMPONENT || kind == ICAL_VEVENT_COMPONENT)
+ return task_list_selector_update_single_object (
+ client, icalcomp);
+ else if (kind != ICAL_VCALENDAR_COMPONENT)
+ return FALSE;
+
+ subcomp = icalcomponent_get_first_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ while (subcomp != NULL) {
+ gboolean success;
+
+ kind = icalcomponent_isa (subcomp);
+ if (kind == ICAL_VTIMEZONE_COMPONENT) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+
+ success = e_cal_add_timezone (client, zone, NULL);
+ icaltimezone_free (zone, 1);
+ if (!success)
+ return FALSE;
+ } else if (kind == ICAL_VTODO_COMPONENT ||
+ kind == ICAL_VEVENT_COMPONENT) {
+ success = task_list_selector_update_single_object (
+ client, subcomp);
+ if (!success)
+ return FALSE;
+ }
+
+ subcomp = icalcomponent_get_next_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+task_list_selector_process_data (ESourceSelector *selector,
+ ECal *client,
+ const gchar *source_uid,
+ icalcomponent *icalcomp,
+ GdkDragAction action)
+{
+ ESourceList *source_list;
+ ESource *source;
+ icalcomponent *tmp_icalcomp = NULL;
+ const gchar *uid;
+ gchar *old_uid = NULL;
+ gboolean success = FALSE;
+ gboolean read_only = TRUE;
+ GError *error = NULL;
+
+ /* FIXME Deal with GDK_ACTION_ASK. */
+ if (action == GDK_ACTION_COPY) {
+ old_uid = g_strdup (icalcomponent_get_uid (icalcomp));
+ uid = e_cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp, uid);
+ }
+
+ uid = icalcomponent_get_uid (icalcomp);
+ if (old_uid == NULL)
+ old_uid = g_strdup (uid);
+
+ if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, &error)) {
+ icalcomponent_free (tmp_icalcomp);
+ success = TRUE;
+ goto exit;
+ }
+
+ if (error != NULL && error->code != E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
+ g_message (
+ "Failed to search the object in destination "
+ "task list: %s", error->message);
+ g_error_free (error);
+ goto exit;
+ }
+
+ success = task_list_selector_update_objects (client, icalcomp);
+
+ if (!success || action != GDK_ACTION_MOVE)
+ goto exit;
+
+ source_list = e_source_selector_get_source_list (selector);
+ source = e_source_list_peek_source_by_uid (source_list, source_uid);
+
+ if (!E_IS_SOURCE (source) || e_source_get_readonly (source))
+ goto exit;
+
+ client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
+ if (client == NULL) {
+ g_message ("Cannot create source client to remove old task");
+ goto exit;
+ }
+
+ e_cal_is_read_only (client, &read_only, NULL);
+ if (!read_only && e_cal_open (client, TRUE, NULL))
+ e_cal_remove_object (client, old_uid, NULL);
+ else if (!read_only)
+ g_message ("Cannot open source client to remove old task");
+
+ g_object_unref (client);
+
+exit:
+ g_free (old_uid);
+
+ return success;
+}
+
+static gboolean
+task_list_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
+{
+ ECal *client;
+ GSList *list, *iter;
+ gboolean success = FALSE;
+
+ client = auth_new_cal_from_source (
+ destination, E_CAL_SOURCE_TYPE_TODO);
+
+ if (client == NULL || !e_cal_open (client, TRUE, NULL))
+ goto exit;
+
+ list = cal_comp_selection_get_string_list (selection_data);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ gchar *source_uid = iter->data;
+ icalcomponent *icalcomp;
+ gchar *component_string;
+
+ /* Each string is "source_uid\ncomponent_string". */
+ component_string = strchr (source_uid, '\n');
+ if (component_string == NULL)
+ continue;
+
+ *component_string++ = '\0';
+ icalcomp = icalparser_parse_string (component_string);
+ if (icalcomp == NULL)
+ continue;
+
+ success = task_list_selector_process_data (
+ selector, client, source_uid, icalcomp, action);
+
+ icalcomponent_free (icalcomp);
+ }
+
+ g_slist_foreach (list, (GFunc) g_free, NULL);
+ g_slist_free (list);
+
+exit:
+ if (client != NULL)
+ g_object_unref (client);
+
+ return success;
+}
+
+static void
+task_list_selector_class_init (ETaskListSelectorClass *class)
+{
+ ESourceSelectorClass *source_selector_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETaskListSelectorPrivate));
+
+ source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ source_selector_class->data_dropped = task_list_selector_data_dropped;
+}
+
+static void
+task_list_selector_init (ETaskListSelector *selector)
+{
+ selector->priv = E_TASK_LIST_SELECTOR_GET_PRIVATE (selector);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+}
+
+GType
+e_task_list_selector_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (ETaskListSelectorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) task_list_selector_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ETaskListSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) task_list_selector_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_SOURCE_SELECTOR, "ETaskListSelector",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_task_list_selector_new (ESourceList *source_list)
+{
+ g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
+
+ return g_object_new (
+ E_TYPE_TASK_LIST_SELECTOR,
+ "source-list", source_list, NULL);
+}
diff --git a/calendar/gui/e-task-list-selector.h b/calendar/gui/e-task-list-selector.h
new file mode 100644
index 0000000000..847a221ba4
--- /dev/null
+++ b/calendar/gui/e-task-list-selector.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-task-list-selector.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* XXX This widget is nearly identical to EMemoListSelector. If
+ * ECalendarSelector ever learns how to move selections from
+ * one source to another, perhaps these ESourceSelector sub-
+ * classes could someday be combined. */
+
+#ifndef E_TASK_LIST_SELECTOR_H
+#define E_TASK_LIST_SELECTOR_H
+
+#include <libedataserver/e-source-list.h>
+#include <libedataserverui/e-source-selector.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TASK_LIST_SELECTOR \
+ (e_task_list_selector_get_type ())
+#define E_TASK_LIST_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelector))
+#define E_TASK_LIST_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorClass))
+#define E_IS_TASK_LIST_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TASK_LIST_SELECTOR))
+#define E_IS_TASK_LIST_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TASK_LIST_SELECTOR))
+#define E_TASK_LIST_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETaskListSelector ETaskListSelector;
+typedef struct _ETaskListSelectorClass ETaskListSelectorClass;
+typedef struct _ETaskListSelectorPrivate ETaskListSelectorPrivate;
+
+struct _ETaskListSelector {
+ ESourceSelector parent;
+ ETaskListSelectorPrivate *priv;
+};
+
+struct _ETaskListSelectorClass {
+ ESourceSelectorClass parent_class;
+};
+
+GType e_task_list_selector_get_type (void);
+GtkWidget * e_task_list_selector_new (ESourceList *source_list);
+
+G_END_DECLS
+
+#endif /* E_TASK_LIST_SELECTOR_H */
diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c
deleted file mode 100644
index bf400590a8..0000000000
--- a/calendar/gui/e-tasks.c
+++ /dev/null
@@ -1,1569 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena Quintero <federico@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib/gi18n.h>
-#include <libedataserver/e-time-utils.h>
-#include <table/e-table-scrolled.h>
-#include <widgets/menus/gal-view-instance.h>
-#include <widgets/menus/gal-view-factory-etable.h>
-#include <widgets/menus/gal-view-etable.h>
-
-#include "e-util/e-error.h"
-#include "e-util/e-categories-config.h"
-#include "e-util/e-util-private.h"
-#include "shell/e-user-creatable-items-handler.h"
-#include <libedataserver/e-url.h>
-#include <libedataserver/e-categories.h>
-#include <libecal/e-cal-time-util.h>
-#include "widgets/menus/gal-view-menus.h"
-#include "dialogs/delete-error.h"
-#include "dialogs/task-editor.h"
-#include "cal-search-bar.h"
-#include "calendar-config.h"
-#include "calendar-component.h"
-#include "comp-util.h"
-#include "e-calendar-table-config.h"
-#include "misc.h"
-#include "tasks-component.h"
-#include "e-cal-component-preview.h"
-#include "e-tasks.h"
-#include "common/authentication.h"
-#include "e-cal-menu.h"
-#include "e-cal-model-tasks.h"
-
-/* Private part of the GnomeCalendar structure */
-struct _ETasksPrivate {
- /* The task lists for display */
- GHashTable *clients;
- GList *clients_list;
- ECal *default_client;
-
- ECalView *query;
-
- /* The ECalendarTable showing the tasks. */
- GtkWidget *tasks_view;
- ECalendarTableConfig *tasks_view_config;
-
- /* Calendar search bar for tasks */
- GtkWidget *search_bar;
-
- /* Tasks menu */
- ECalMenu *tasks_menu;
-
- /* Paned widget */
- GtkWidget *paned;
-
- /* The preview */
- GtkWidget *preview;
-
- gchar *current_uid;
- gchar *sexp;
- guint update_timeout;
-
- /* View instance and the view menus handler */
- GalViewInstance *view_instance;
- GalViewMenus *view_menus;
-
- GList *notifications;
-};
-
-static void setup_widgets (ETasks *tasks);
-static void e_tasks_destroy (GtkObject *object);
-static void update_view (ETasks *tasks);
-
-static void categories_changed_cb (gpointer object, gpointer user_data);
-static void backend_error_cb (ECal *client, const gchar *message, gpointer data);
-
-/* Signal IDs */
-enum {
- SELECTION_CHANGED,
- SOURCE_ADDED,
- SOURCE_REMOVED,
- LAST_SIGNAL
-};
-
-enum DndTargetType {
- TARGET_VCALENDAR
-};
-
-static GtkTargetEntry list_drag_types[] = {
- { (gchar *) "text/calendar", 0, TARGET_VCALENDAR },
- { (gchar *) "text/x-calendar", 0, TARGET_VCALENDAR }
-};
-static const gint num_list_drag_types = sizeof (list_drag_types) / sizeof (list_drag_types[0]);
-
-static guint e_tasks_signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (ETasks, e_tasks, GTK_TYPE_TABLE)
-
-/* Callback used when the cursor changes in the table */
-static void
-table_cursor_change_cb (ETable *etable, gint row, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
- ECalModel *model;
- ECalModelComponent *comp_data;
- ECalComponent *comp;
- const gchar *uid;
-
- gint n_selected;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- n_selected = e_table_selected_count (etable);
-
- /* update the HTML widget */
- if (n_selected != 1) {
- e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview));
-
- return;
- }
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
-
- comp_data = e_cal_model_get_component_at (model, e_table_get_cursor_row (etable));
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
-
- e_cal_component_preview_display (E_CAL_COMPONENT_PREVIEW (priv->preview), comp_data->client, comp);
-
- e_cal_component_get_uid (comp, &uid);
- if (priv->current_uid)
- g_free (priv->current_uid);
- priv->current_uid = g_strdup (uid);
-
- g_object_unref (comp);
-}
-
-ECalMenu *
-e_tasks_get_tasks_menu (ETasks *tasks)
-{
- g_return_val_if_fail (E_IS_TASKS (tasks), NULL);
-
- return tasks->priv->tasks_menu;
-}
-
-/* Callback used when the selection changes in the table. */
-static void
-table_selection_change_cb (ETable *etable, gpointer data)
-{
- ETasks *tasks;
- gint n_selected;
-
- tasks = E_TASKS (data);
-
- n_selected = e_table_selected_count (etable);
- g_signal_emit (tasks, e_tasks_signals[SELECTION_CHANGED], 0, n_selected);
-
- if (n_selected != 1)
- e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (tasks->priv->preview));
-}
-
-static void
-user_created_cb (GtkWidget *view, ETasks *tasks)
-{
- ETasksPrivate *priv;
- ECalendarTable *cal_table;
- ECal *ecal;
-
- priv = tasks->priv;
- cal_table = E_CALENDAR_TABLE (priv->tasks_view);
-
- if (cal_table->user_created_cal)
- ecal = cal_table->user_created_cal;
- else {
- ECalModel *model;
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
- ecal = e_cal_model_get_default_client (model);
- }
-
- e_tasks_add_todo_source (tasks, e_cal_get_source (ecal));
-}
-
-/* Callback used when the sexp in the search bar changes */
-static void
-search_bar_sexp_changed_cb (CalSearchBar *cal_search, const gchar *sexp, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- if (priv->sexp)
- g_free (priv->sexp);
-
- priv->sexp = g_strdup (sexp);
-
- update_view (tasks);
-}
-
-/* Callback used when the selected category in the search bar changes */
-static void
-search_bar_category_changed_cb (CalSearchBar *cal_search, const gchar *category, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
- ECalModel *model;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
- e_cal_model_set_default_category (model, category);
-}
-
-static gboolean
-vpaned_resized_cb (GtkWidget *widget, GdkEventButton *event, ETasks *tasks)
-{
- calendar_config_set_task_vpane_pos (gtk_paned_get_position (GTK_PANED (widget)));
-
- return FALSE;
-}
-
-static void
-set_timezone (ETasks *tasks)
-{
- ETasksPrivate *priv;
- icaltimezone *zone;
- GList *l;
-
- priv = tasks->priv;
-
- zone = calendar_config_get_icaltimezone ();
- for (l = priv->clients_list; l != NULL; l = l->next) {
- ECal *client = l->data;
- /* FIXME Error checking */
- e_cal_set_default_timezone (client, zone, NULL);
- }
-
- if (priv->default_client)
- /* FIXME Error checking */
- e_cal_set_default_timezone (priv->default_client, zone, NULL);
-
- if (priv->preview)
- e_cal_component_preview_set_default_timezone (E_CAL_COMPONENT_PREVIEW (priv->preview), zone);
-}
-
-static void
-timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- ETasks *tasks = data;
-
- set_timezone (tasks);
-}
-
-static void
-update_view (ETasks *tasks)
-{
- ETasksPrivate *priv;
- ECalModel *model;
- gchar *real_sexp = NULL;
- gchar *new_sexp = NULL;
-
- priv = tasks->priv;
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
-
- if ((new_sexp = calendar_config_get_hide_completed_tasks_sexp (FALSE)) != NULL) {
- real_sexp = g_strdup_printf ("(and %s %s)", new_sexp, priv->sexp);
- e_cal_model_set_search_query (model, real_sexp);
- g_free (new_sexp);
- g_free (real_sexp);
- } else
- e_cal_model_set_search_query (model, priv->sexp);
-
- e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview));
-}
-
-static void
-process_completed_tasks (ETasks *tasks, gboolean config_changed)
-{
- ETasksPrivate *priv;
-
- g_return_if_fail (tasks != NULL);
- g_return_if_fail (E_IS_TASKS (tasks));
-
- priv = tasks->priv;
-
- e_calendar_table_process_completed_tasks (e_tasks_get_calendar_table (tasks), priv->clients_list, config_changed);
-}
-
-static gboolean
-update_view_cb (ETasks *tasks)
-{
- ECalModel *model;
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (tasks->priv->tasks_view));
-
- process_completed_tasks (tasks, FALSE);
- e_cal_model_tasks_update_due_tasks (E_CAL_MODEL_TASKS (model));
-
- return TRUE;
-}
-
-static void
-config_hide_completed_tasks_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- process_completed_tasks (data, TRUE);
- update_view (data);
-}
-
-static void
-model_row_changed_cb (ETableModel *etm, gint row, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
- ECalModelComponent *comp_data;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- if (priv->current_uid) {
- const gchar *uid;
-
- comp_data = e_cal_model_get_component_at (E_CAL_MODEL (etm), row);
- if (comp_data) {
- uid = icalcomponent_get_uid (comp_data->icalcomp);
- if (!strcmp (uid ? uid : "", priv->current_uid)) {
- ETable *etable;
-
- etable = e_table_scrolled_get_table (
- E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable));
- table_cursor_change_cb (etable, 0, tasks);
- }
- }
- }
-}
-
-static void
-view_progress_cb (ECalModel *model, const gchar *message, gint percent, ECalSourceType type, ETasks *tasks)
-{
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks)),
- message, percent);
-}
-
-static void
-view_done_cb (ECalModel *model, ECalendarStatus status, ECalSourceType type, ETasks *tasks)
-{
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks)),
- NULL, -1);
-
-}
-
-static void
-config_preview_state_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- gboolean state;
- GConfValue *value;
- ETasks *tasks = (ETasks *)data;
-
- g_return_if_fail (gconf_entry_get_key (entry) != NULL);
- g_return_if_fail ((value = gconf_entry_get_value (entry)) != NULL);
-
- state = gconf_value_get_bool (value);
- e_tasks_show_preview (tasks, state);
- bonobo_ui_component_set_prop (E_SEARCH_BAR (tasks->priv->search_bar)->ui_component, "/commands/ViewPreview", "state", state ? "1" : "0", NULL);
-}
-
-static void
-setup_config (ETasks *tasks)
-{
- ETasksPrivate *priv;
- guint not;
-
- priv = tasks->priv;
-
- /* Timezone */
- set_timezone (tasks);
-
- not = calendar_config_add_notification_timezone (timezone_changed_cb, tasks);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- not = calendar_config_add_notification_hide_completed_tasks (config_hide_completed_tasks_changed_cb,
- tasks);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- not = calendar_config_add_notification_hide_completed_tasks_units (config_hide_completed_tasks_changed_cb,
- tasks);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- not = calendar_config_add_notification_hide_completed_tasks_value (config_hide_completed_tasks_changed_cb,
- tasks);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- not = calendar_config_add_notification_preview_state (config_preview_state_changed_cb, tasks);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-}
-
-struct AffectedComponents {
- ECalendarTable *cal_table;
- GSList *components; /* contains pointers to ECalModelComponent */
-};
-
-/**
- * get_selected_components_cb
- * Helper function to fill list of selected components in ECalendarTable.
- * This function is called from e_table_selected_row_foreach.
- **/
-static void
-get_selected_components_cb (gint model_row, gpointer data)
-{
- struct AffectedComponents *ac = (struct AffectedComponents *) data;
-
- if (!ac || !ac->cal_table)
- return;
-
- ac->components = g_slist_prepend (ac->components, e_cal_model_get_component_at (E_CAL_MODEL (ac->cal_table->model), model_row));
-}
-
-/**
- * do_for_selected_components
- * Calls function func for all selected components in cal_table.
- *
- * @param cal_table Table with selected components of our interest.
- * @param func Function to be called on each selected component from cal_table.
- * The first parameter of this function is a pointer to ECalModelComponent and
- * the second parameter of this function is pointer to cal_table
- * @param user_data User data, will be passed to func.
- **/
-static void
-do_for_selected_components (ECalendarTable *cal_table, GFunc func, gpointer user_data)
-{
- ETable *etable;
- struct AffectedComponents ac;
-
- g_return_if_fail (cal_table != NULL);
-
- ac.cal_table = cal_table;
- ac.components = NULL;
-
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
- e_table_selected_row_foreach (etable, get_selected_components_cb, &ac);
-
- g_slist_foreach (ac.components, func, user_data);
- g_slist_free (ac.components);
-}
-
-/**
- * obtain_list_of_components
- * As a callback function to convert each ECalModelComponent to string
- * of format "source_uid\ncomponent_str" and add this newly allocated
- * string to the list of components. Strings should be freed with g_free.
- *
- * @param data ECalModelComponent object.
- * @param user_data Pointer to GSList list, where to put new strings.
- **/
-static void
-obtain_list_of_components (gpointer data, gpointer user_data)
-{
- GSList **list;
- ECalModelComponent *comp_data;
-
- list = (GSList **) user_data;
- comp_data = (ECalModelComponent *) data;
-
- if (list && comp_data) {
- gchar *comp_str;
- icalcomponent *vcal;
-
- vcal = e_cal_util_new_top_level ();
- e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
- icalcomponent_add_component (vcal, icalcomponent_new_clone (comp_data->icalcomp));
-
- comp_str = icalcomponent_as_ical_string_r (vcal);
- if (comp_str) {
- ESource *source = e_cal_get_source (comp_data->client);
- const gchar *source_uid = e_source_peek_uid (source);
-
- *list = g_slist_prepend (*list, g_strdup_printf ("%s\n%s", source_uid, comp_str));
-
- /* do not free this pointer, it owns libical */
- /* g_free (comp_str); */
- }
-
- icalcomponent_free (vcal);
- g_free (comp_str);
- }
-}
-
-static void
-table_drag_data_get (ETable *table,
- gint row,
- gint col,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- ETasks *tasks)
-{
- ETasksPrivate *priv;
-
- priv = tasks->priv;
-
- if (info == TARGET_VCALENDAR) {
- /* we will pass an icalcalendar component for both types */
- GSList *components = NULL;
-
- do_for_selected_components (E_CALENDAR_TABLE (priv->tasks_view), obtain_list_of_components, &components);
-
- if (components) {
- cal_comp_selection_set_string_list (selection_data, components);
-
- g_slist_foreach (components, (GFunc)g_free, NULL);
- g_slist_free (components);
- }
- }
-}
-
-/*
-static void
-table_drag_begin (ETable *table,
- gint row,
- gint col,
- GdkDragContext *context,
- ETasks *tasks)
-{
-
-}
-
-static void
-table_drag_end (ETable *table,
- gint row,
- gint col,
- GdkDragContext *context,
- ETasks *tasks)
-{
-
-}
-*/
-
-static void
-table_drag_data_delete (ETable *table,
- gint row,
- gint col,
- GdkDragContext *context,
- ETasks *tasks)
-{
- /* Moved components are deleted from source immediately when moved,
- because some of them can be part of destination source, and we
- don't want to delete not-moved tasks. There is no such information
- which event has been moved and which not, so skip this method.
- */
-}
-
-#define E_TASKS_TABLE_DEFAULT_STATE \
- "<?xml version=\"1.0\"?>" \
- "<ETableState>" \
- "<column source=\"13\"/>" \
- "<column source=\"14\"/>" \
- "<column source=\"9\"/>" \
- "<column source=\"5\"/>" \
- "<grouping/>" \
- "</ETableState>"
-
-static void
-pane_realized (GtkWidget *widget, ETasks *tasks)
-{
- gtk_paned_set_position ((GtkPaned *)widget, calendar_config_get_task_vpane_pos ());
-}
-
-static void
-setup_widgets (ETasks *tasks)
-{
- ETasksPrivate *priv;
- ETable *etable;
- ECalModel *model;
- gboolean state;
-
- priv = tasks->priv;
-
- priv->search_bar = cal_search_bar_new (CAL_SEARCH_TASKS_DEFAULT);
- g_signal_connect (priv->search_bar, "sexp_changed",
- G_CALLBACK (search_bar_sexp_changed_cb), tasks);
- g_signal_connect (priv->search_bar, "category_changed",
- G_CALLBACK (search_bar_category_changed_cb), tasks);
- categories_changed_cb (NULL, tasks);
-
- gtk_table_attach (GTK_TABLE (tasks), priv->search_bar, 0, 1, 0, 1,
- GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0, 0);
- gtk_widget_show (priv->search_bar);
-
- /* add the paned widget for the task list and task detail areas */
- priv->paned = gtk_vpaned_new ();
- g_signal_connect (priv->paned, "realize", G_CALLBACK (pane_realized), tasks);
-
- g_signal_connect (G_OBJECT (priv->paned), "button_release_event",
- G_CALLBACK (vpaned_resized_cb), tasks);
- gtk_table_attach (GTK_TABLE (tasks), priv->paned, 0, 1, 1, 2,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- gtk_widget_show (priv->paned);
-
- /* create the task list */
- priv->tasks_view = e_calendar_table_new ();
- g_object_set_data (G_OBJECT (priv->tasks_view), "tasks", tasks);
- priv->tasks_view_config = e_calendar_table_config_new (E_CALENDAR_TABLE (priv->tasks_view));
-
- g_signal_connect (priv->tasks_view, "user_created", G_CALLBACK (user_created_cb), tasks);
-
- etable = e_table_scrolled_get_table (
- E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable));
- e_table_set_state (etable, E_TASKS_TABLE_DEFAULT_STATE);
- gtk_paned_add1 (GTK_PANED (priv->paned), priv->tasks_view);
- gtk_widget_show (priv->tasks_view);
-
- e_table_drag_source_set (etable, GDK_BUTTON1_MASK,
- list_drag_types, num_list_drag_types,
- GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_ASK);
-
- g_signal_connect (etable, "table_drag_data_get",
- G_CALLBACK(table_drag_data_get), tasks);
- g_signal_connect (etable, "table_drag_data_delete",
- G_CALLBACK(table_drag_data_delete), tasks);
-
- /*
- e_table_drag_dest_set (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- 0, list_drag_types, num_list_drag_types, GDK_ACTION_LINK);
-
- g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- "table_drag_motion", G_CALLBACK(table_drag_motion_cb), editor);
- g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- "table_drag_drop", G_CALLBACK (table_drag_drop_cb), editor);
- g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- "table_drag_data_received", G_CALLBACK(table_drag_data_received_cb), editor);
- */
-
- g_signal_connect (etable, "cursor_change", G_CALLBACK (table_cursor_change_cb), tasks);
- g_signal_connect (etable, "selection_change", G_CALLBACK (table_selection_change_cb), tasks);
-
- /* Timeout check to hide completed items */
- priv->update_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_view_cb, tasks, NULL);
-
- /* create the task detail */
- priv->preview = e_cal_component_preview_new ();
- e_cal_component_preview_set_default_timezone (E_CAL_COMPONENT_PREVIEW (priv->preview), calendar_config_get_icaltimezone ());
- gtk_paned_add2 (GTK_PANED (priv->paned), priv->preview);
- state = calendar_config_get_preview_state ();
-
- if (state)
- gtk_widget_show (priv->preview);
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
- g_signal_connect (G_OBJECT (model), "model_row_changed",
- G_CALLBACK (model_row_changed_cb), tasks);
-
- g_signal_connect (G_OBJECT (model), "cal_view_progress",
- G_CALLBACK (view_progress_cb), tasks);
- g_signal_connect (G_OBJECT (model), "cal_view_done",
- G_CALLBACK (view_done_cb), tasks);
-}
-
-/* Class initialization function for the gnome calendar */
-static void
-e_tasks_class_init (ETasksClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- e_tasks_signals[SELECTION_CHANGED] =
- g_signal_new ("selection_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ETasksClass, selection_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- e_tasks_signals[SOURCE_ADDED] =
- g_signal_new ("source_added",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (ETasksClass, source_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
-
- e_tasks_signals[SOURCE_REMOVED] =
- g_signal_new ("source_removed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (ETasksClass, source_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
-
- object_class->destroy = e_tasks_destroy;
-
- class->selection_changed = NULL;
- class->source_added = NULL;
- class->source_removed = NULL;
-}
-
-static void
-categories_changed_cb (gpointer object, gpointer user_data)
-{
- GList *cat_list;
- GPtrArray *cat_array;
- ETasksPrivate *priv;
- ETasks *tasks = user_data;
-
- priv = tasks->priv;
-
- cat_array = g_ptr_array_new ();
- cat_list = e_categories_get_list ();
- while (cat_list != NULL) {
- if (e_categories_is_searchable ((const gchar *) cat_list->data))
- g_ptr_array_add (cat_array, cat_list->data);
- cat_list = g_list_remove (cat_list, cat_list->data);
- }
-
- cal_search_bar_set_categories ((CalSearchBar *)priv->search_bar, cat_array);
-
- g_ptr_array_free (cat_array, TRUE);
-}
-
-/* Object initialization function for the gnome calendar */
-static void
-e_tasks_init (ETasks *tasks)
-{
- ETasksPrivate *priv;
-
- priv = g_new0 (ETasksPrivate, 1);
- tasks->priv = priv;
-
- e_categories_register_change_listener (G_CALLBACK (categories_changed_cb), tasks);
-
- setup_config (tasks);
- setup_widgets (tasks);
-
- priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
- priv->query = NULL;
- priv->view_instance = NULL;
- priv->view_menus = NULL;
- priv->current_uid = NULL;
- priv->sexp = g_strdup ("#t");
- priv->default_client = NULL;
- priv->tasks_menu = e_cal_menu_new ("org.gnome.evolution.tasks.view");
- update_view (tasks);
-}
-
-GtkWidget *
-e_tasks_new (void)
-{
- ETasks *tasks;
-
- tasks = g_object_new (e_tasks_get_type (), NULL);
-
- return GTK_WIDGET (tasks);
-}
-
-void
-e_tasks_set_ui_component (ETasks *tasks,
- BonoboUIComponent *ui_component)
-{
- g_return_if_fail (E_IS_TASKS (tasks));
- g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component));
-
- e_search_bar_set_ui_component (E_SEARCH_BAR (tasks->priv->search_bar), ui_component);
-}
-
-static void
-e_tasks_destroy (GtkObject *object)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (E_IS_TASKS (object));
-
- tasks = E_TASKS (object);
- priv = tasks->priv;
-
- if (priv) {
- GList *l;
-
- e_categories_unregister_change_listener (G_CALLBACK (categories_changed_cb), tasks);
-
- /* disconnect from signals on all the clients */
- for (l = priv->clients_list; l != NULL; l = l->next) {
- g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, tasks);
- }
-
- g_hash_table_destroy (priv->clients);
- g_list_free (priv->clients_list);
-
- if (priv->default_client)
- g_object_unref (priv->default_client);
- priv->default_client = NULL;
-
- if (priv->current_uid) {
- g_free (priv->current_uid);
- priv->current_uid = NULL;
- }
-
- if (priv->sexp) {
- g_free (priv->sexp);
- priv->sexp = NULL;
- }
-
- if (priv->update_timeout) {
- g_source_remove (priv->update_timeout);
- priv->update_timeout = 0;
- }
-
- if (priv->tasks_view_config) {
- g_object_unref (priv->tasks_view_config);
- priv->tasks_view_config = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
- priv->notifications = NULL;
-
- g_free (priv);
- tasks->priv = NULL;
- }
-
- if (GTK_OBJECT_CLASS (e_tasks_parent_class)->destroy)
- (* GTK_OBJECT_CLASS (e_tasks_parent_class)->destroy) (object);
-}
-
-static void
-set_status_message (ETasks *tasks, const gchar *message, ...)
-{
- ETasksPrivate *priv;
- va_list args;
- gchar sz[2048], *msg_string = NULL;
-
- if (message) {
- va_start (args, message);
- vsnprintf (sz, sizeof sz, message, args);
- va_end (args);
- msg_string = sz;
- }
-
- priv = tasks->priv;
-
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->tasks_view), msg_string, -1);
-}
-
-/* Callback from the calendar client when an error occurs in the backend */
-static void
-backend_error_cb (ECal *client, const gchar *message, gpointer data)
-{
- ETasks *tasks;
- GtkWidget *dialog;
- gchar *urinopwd;
-
- tasks = E_TASKS (data);
-
- urinopwd = get_uri_without_password (e_cal_get_uri (client));
-
- dialog = gtk_message_dialog_new (
- GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks))),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _("Error on %s:\n %s"),
- urinopwd, message);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- g_free (urinopwd);
-}
-
-/* Callback from the calendar client when the backend dies */
-static void
-backend_died_cb (ECal *client, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
- ESource *source;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- source = g_object_ref (e_cal_get_source (client));
-
- priv->clients_list = g_list_remove (priv->clients_list, client);
- g_hash_table_remove (priv->clients, e_source_peek_uid (source));
-
- g_signal_emit (tasks, e_tasks_signals[SOURCE_REMOVED], 0, source);
-
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks)), NULL, -1);
-
- e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks))),
- "calendar:tasks-crashed", NULL);
-
- g_object_unref (source);
-}
-
-/* Callback from the calendar client when the calendar is opened */
-static void
-client_cal_opened_cb (ECal *ecal, ECalendarStatus status, ETasks *tasks)
-{
- ECalModel *model;
- ESource *source;
- ETasksPrivate *priv;
-
- priv = tasks->priv;
-
- source = e_cal_get_source (ecal);
-
- if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
- auth_cal_forget_password (ecal);
-
- switch (status) {
- case E_CALENDAR_STATUS_OK :
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL);
-
- set_status_message (tasks, _("Loading tasks"));
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
- e_cal_model_add_client (model, ecal);
-
- set_status_message (tasks, NULL);
- break;
- case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
- /* try to reopen calendar - it'll ask for a password once again */
- e_cal_open_async (ecal, FALSE);
- return;
- case E_CALENDAR_STATUS_BUSY :
- break;
- case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
- e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks))), "calendar:prompt-no-contents-offline-tasks", NULL);
- default :
- /* Make sure the source doesn't disappear on us */
- g_object_ref (source);
-
- priv->clients_list = g_list_remove (priv->clients_list, ecal);
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, tasks);
-
- /* Do this last because it unrefs the client */
- g_hash_table_remove (priv->clients, e_source_peek_uid (source));
-
- g_signal_emit (tasks, e_tasks_signals[SOURCE_REMOVED], 0, source);
-
- set_status_message (tasks, NULL);
- g_object_unref (source);
-
- break;
- }
-}
-
-static void
-default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, ETasks *tasks)
-{
- ECalModel *model;
- ESource *source;
- ETasksPrivate *priv;
-
- priv = tasks->priv;
-
- source = e_cal_get_source (ecal);
-
- if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
- auth_cal_forget_password (ecal);
-
- switch (status) {
- case E_CALENDAR_STATUS_OK :
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL);
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
-
- e_cal_model_set_default_client (model, ecal);
- set_status_message (tasks, NULL);
- break;
- case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
- /* try to reopen calendar - it'll ask for a password once again */
- e_cal_open_async (ecal, FALSE);
- return;
- case E_CALENDAR_STATUS_BUSY:
- break;
- default :
- /* Make sure the source doesn't disappear on us */
- g_object_ref (source);
-
- priv->clients_list = g_list_remove (priv->clients_list, ecal);
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, tasks);
-
- /* Do this last because it unrefs the client */
- g_hash_table_remove (priv->clients, e_source_peek_uid (source));
-
- g_signal_emit (tasks, e_tasks_signals[SOURCE_REMOVED], 0, source);
-
- set_status_message (tasks, NULL);
- g_object_unref (priv->default_client);
- priv->default_client = NULL;
- g_object_unref (source);
-
- break;
- }
-}
-
-typedef void (*open_func) (ECal *, ECalendarStatus, ETasks *);
-
-static gboolean
-open_ecal (ETasks *tasks, ECal *cal, gboolean only_if_exists, open_func of)
-{
- ETasksPrivate *priv;
- icaltimezone *zone;
-
- priv = tasks->priv;
-
- zone = calendar_config_get_icaltimezone ();
- e_cal_set_default_timezone (cal, zone, NULL);
-
- set_status_message (tasks, _("Opening tasks at %s"), e_cal_get_uri (cal));
-
- g_signal_connect (G_OBJECT (cal), "cal_opened", G_CALLBACK (of), tasks);
- e_cal_open_async (cal, only_if_exists);
-
- return TRUE;
-}
-
-void
-e_tasks_open_task (ETasks *tasks)
-{
- ECalendarTable *cal_table;
-
- cal_table = e_tasks_get_calendar_table (tasks);
- e_calendar_table_open_selected (cal_table);
-}
-
-void
-e_tasks_new_task (ETasks *tasks)
-{
- ETasksPrivate *priv;
- CompEditor *editor;
- ECalComponent *comp;
- const gchar *category;
- ECal *ecal;
- guint32 flags = 0;
-
- g_return_if_fail (E_IS_TASKS (tasks));
-
- priv = tasks->priv;
-
- /* FIXME What to do about no default client */
- ecal = e_tasks_get_default_client (tasks);
- if (!ecal)
- return;
-
- flags |= COMP_EDITOR_NEW_ITEM | COMP_EDITOR_USER_ORG;
-
- comp = cal_comp_task_new_with_defaults (ecal);
-
- category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar));
- e_cal_component_set_categories (comp, category);
-
- editor = task_editor_new (ecal, flags);
- comp_editor_edit_comp (editor, comp);
- g_object_unref (comp);
-
- gtk_window_present (GTK_WINDOW (editor));
-}
-
-void
-e_tasks_show_preview (ETasks *tasks, gboolean state)
-{
- ETasksPrivate *priv;
-
- g_return_if_fail (tasks != NULL);
- g_return_if_fail (E_IS_TASKS (tasks));
- priv = tasks->priv;
-
- if (state) {
- ECalModel *model;
- ECalModelComponent *comp_data;
- ECalComponent *comp;
- ETable *etable;
- const gchar *uid;
- gint n_selected;
-
- etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable));
- n_selected = e_table_selected_count (etable);
-
- if (n_selected != 1) {
- e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview));
- } else {
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
-
- comp_data = e_cal_model_get_component_at (model, e_table_get_cursor_row (etable));
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
-
- e_cal_component_preview_display (E_CAL_COMPONENT_PREVIEW (priv->preview), comp_data->client, comp);
-
- e_cal_component_get_uid (comp, &uid);
- if (priv->current_uid)
- g_free (priv->current_uid);
- priv->current_uid = g_strdup (uid);
-
- g_object_unref (comp);
- }
- gtk_widget_show (priv->preview);
-
- } else {
- e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview));
- gtk_widget_hide (priv->preview);
- }
-}
-
-gboolean
-e_tasks_add_todo_source (ETasks *tasks, ESource *source)
-{
- ETasksPrivate *priv;
- ECal *client;
- const gchar *uid;
-
- g_return_val_if_fail (tasks != NULL, FALSE);
- g_return_val_if_fail (E_IS_TASKS (tasks), FALSE);
- g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
-
- priv = tasks->priv;
-
- uid = e_source_peek_uid (source);
- client = g_hash_table_lookup (priv->clients, uid);
- if (client) {
- /* We already have it */
-
- return TRUE;
- } else {
- ESource *default_source;
-
- if (priv->default_client) {
- default_source = e_cal_get_source (priv->default_client);
-
- /* We don't have it but the default client is it */
- if (!strcmp (e_source_peek_uid (default_source), uid))
- client = g_object_ref (priv->default_client);
- }
-
- /* Create a new one */
- if (!client) {
- client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
- if (!client)
- return FALSE;
- }
- }
-
- g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), tasks);
- g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), tasks);
-
- /* add the client to internal structure */
- g_hash_table_insert (priv->clients, g_strdup (uid) , client);
- priv->clients_list = g_list_prepend (priv->clients_list, client);
-
- g_signal_emit (tasks, e_tasks_signals[SOURCE_ADDED], 0, source);
-
- open_ecal (tasks, client, FALSE, client_cal_opened_cb);
-
- return TRUE;
-}
-
-gboolean
-e_tasks_remove_todo_source (ETasks *tasks, ESource *source)
-{
- ETasksPrivate *priv;
- ECal *client;
- ECalModel *model;
- const gchar *uid;
-
- g_return_val_if_fail (tasks != NULL, FALSE);
- g_return_val_if_fail (E_IS_TASKS (tasks), FALSE);
- g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
-
- priv = tasks->priv;
-
- uid = e_source_peek_uid (source);
- client = g_hash_table_lookup (priv->clients, uid);
- if (!client)
- return TRUE;
-
- priv->clients_list = g_list_remove (priv->clients_list, client);
- g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, tasks);
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
- e_cal_model_remove_client (model, client);
-
- g_hash_table_remove (priv->clients, uid);
-
- g_signal_emit (tasks, e_tasks_signals[SOURCE_REMOVED], 0, source);
-
- return TRUE;
-}
-
-gboolean
-e_tasks_set_default_source (ETasks *tasks, ESource *source)
-{
- ETasksPrivate *priv;
- ECal *ecal;
-
- g_return_val_if_fail (tasks != NULL, FALSE);
- g_return_val_if_fail (E_IS_TASKS (tasks), FALSE);
- g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
-
- priv = tasks->priv;
-
- ecal = g_hash_table_lookup (priv->clients, e_source_peek_uid (source));
-
- if (priv->default_client)
- g_object_unref (priv->default_client);
-
- if (ecal) {
- priv->default_client = g_object_ref (ecal);
- } else {
- priv->default_client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
- if (!priv->default_client)
- return FALSE;
- }
-
- open_ecal (tasks, priv->default_client, FALSE, default_client_cal_opened_cb);
-
- return TRUE;
-}
-
-ECal *
-e_tasks_get_default_client (ETasks *tasks)
-{
- ETasksPrivate *priv;
-
- g_return_val_if_fail (tasks != NULL, NULL);
- g_return_val_if_fail (E_IS_TASKS (tasks), NULL);
-
- priv = tasks->priv;
-
- return e_cal_model_get_default_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)));
-}
-
-/**
- * e_tasks_complete_selected:
- * @tasks: A tasks control widget
- *
- * Marks the selected tasks complete
- **/
-void
-e_tasks_complete_selected (ETasks *tasks)
-{
- ETasksPrivate *priv;
- ECalendarTable *cal_table;
-
- g_return_if_fail (tasks != NULL);
- g_return_if_fail (E_IS_TASKS (tasks));
-
- priv = tasks->priv;
-
- cal_table = E_CALENDAR_TABLE (priv->tasks_view);
-
- set_status_message (tasks, _("Completing tasks..."));
- e_calendar_table_complete_selected (cal_table);
- set_status_message (tasks, NULL);
-}
-
-/**
- * e_tasks_delete_selected:
- * @tasks: A tasks control widget.
- *
- * Deletes the selected tasks in the task list.
- **/
-void
-e_tasks_delete_selected (ETasks *tasks)
-{
- ETasksPrivate *priv;
- ECalendarTable *cal_table;
-
- g_return_if_fail (tasks != NULL);
- g_return_if_fail (E_IS_TASKS (tasks));
-
- priv = tasks->priv;
-
- cal_table = E_CALENDAR_TABLE (priv->tasks_view);
- set_status_message (tasks, _("Deleting selected objects..."));
- e_calendar_table_delete_selected (cal_table);
- set_status_message (tasks, NULL);
-
- e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview));
-}
-
-/**
- * e_tasks_expunge:
- * @tasks: A tasks control widget
- *
- * Removes all tasks marked as completed
- **/
-void
-e_tasks_delete_completed (ETasks *tasks)
-{
- ETasksPrivate *priv;
- gchar *sexp;
- GList *l;
-
- g_return_if_fail (tasks != NULL);
- g_return_if_fail (E_IS_TASKS (tasks));
-
- priv = tasks->priv;
-
- sexp = g_strdup ("(is-completed?)");
-
- set_status_message (tasks, _("Expunging"));
-
- for (l = priv->clients_list; l != NULL; l = l->next) {
- ECal *client = l->data;
- GList *objects, *m;
- gboolean read_only = TRUE;
-
- e_cal_is_read_only (client, &read_only, NULL);
- if (read_only)
- continue;
-
- if (!e_cal_get_object_list (client, sexp, &objects, NULL)) {
- g_warning (G_STRLOC ": Could not get the objects");
-
- continue;
- }
-
- for (m = objects; m; m = m->next) {
- /* FIXME Better error handling */
- e_cal_remove_object (client, icalcomponent_get_uid (m->data), NULL);
- }
-
- g_list_foreach (objects, (GFunc) icalcomponent_free, NULL);
- g_list_free (objects);
- }
-
- set_status_message (tasks, NULL);
-
- g_free (sexp);
-}
-
-/* Callback used from the view collection when we need to display a new view */
-static void
-display_view_cb (GalViewInstance *instance, GalView *view, gpointer data)
-{
- ETasks *tasks;
-
- tasks = E_TASKS (data);
-
- if (GAL_IS_VIEW_ETABLE (view)) {
- gal_view_etable_attach_table (GAL_VIEW_ETABLE (view), e_table_scrolled_get_table (E_TABLE_SCROLLED (E_CALENDAR_TABLE (tasks->priv->tasks_view)->etable)));
- }
-
- gtk_paned_set_position ((GtkPaned *)tasks->priv->paned, calendar_config_get_task_vpane_pos ());
-}
-
-/**
- * e_tasks_setup_view_menus:
- * @tasks: A tasks widget.
- * @uic: UI controller to use for the menus.
- *
- * Sets up the #GalView menus for a tasks control. This function should be
- * called from the Bonobo control activation callback for this tasks control.
- * Also, the menus should be discarded using e_tasks_discard_view_menus().
- **/
-void
-e_tasks_setup_view_menus (ETasks *tasks, BonoboUIComponent *uic)
-{
- ETasksPrivate *priv;
- GalViewFactory *factory;
- ETableSpecification *spec;
- gchar *dir0, *dir1, *filename;
- static GalViewCollection *collection = NULL;
-
- g_return_if_fail (tasks != NULL);
- g_return_if_fail (E_IS_TASKS (tasks));
- g_return_if_fail (uic != NULL);
- g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
-
- priv = tasks->priv;
-
- g_return_if_fail (priv->view_instance == NULL);
-
- g_return_if_fail (priv->view_instance == NULL);
- g_return_if_fail (priv->view_menus == NULL);
-
- /* Create the view instance */
-
- if (collection == NULL) {
- collection = gal_view_collection_new ();
-
- gal_view_collection_set_title (collection, _("Tasks"));
-
- dir0 = g_build_filename (EVOLUTION_GALVIEWSDIR,
- "tasks",
- NULL);
- dir1 = g_build_filename (tasks_component_peek_base_directory (tasks_component_peek ()),
- "tasks", "views", NULL);
- gal_view_collection_set_storage_directories (collection,
- dir0,
- dir1);
- g_free (dir1);
- g_free (dir0);
-
- /* Create the views */
-
- spec = e_table_specification_new ();
- filename = g_build_filename (EVOLUTION_ETSPECDIR,
- "e-calendar-table.etspec",
- NULL);
- if (!e_table_specification_load_from_file (spec, filename))
- g_error ("Unable to load ETable specification file "
- "for tasks");
- g_free (filename);
-
- factory = gal_view_factory_etable_new (spec);
- g_object_unref (spec);
- gal_view_collection_add_factory (collection, factory);
- g_object_unref (factory);
-
- /* Load the collection and create the menus */
-
- gal_view_collection_load (collection);
- }
-
- priv->view_instance = gal_view_instance_new (collection, NULL);
-
- priv->view_menus = gal_view_menus_new (priv->view_instance);
- gal_view_menus_apply (priv->view_menus, uic, NULL);
- g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), tasks);
- display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), tasks);
-}
-
-/**
- * e_tasks_discard_view_menus:
- * @tasks: A tasks widget.
- *
- * Discards the #GalView menus used by a tasks control. This function should be
- * called from the Bonobo control deactivation callback for this tasks control.
- * The menus should have been set up with e_tasks_setup_view_menus().
- **/
-void
-e_tasks_discard_view_menus (ETasks *tasks)
-{
- ETasksPrivate *priv;
-
- g_return_if_fail (tasks != NULL);
- g_return_if_fail (E_IS_TASKS (tasks));
-
- priv = tasks->priv;
-
- g_return_if_fail (priv->view_instance != NULL);
- g_return_if_fail (priv->view_menus != NULL);
-
- g_object_unref (priv->view_instance);
- priv->view_instance = NULL;
-
- g_object_unref (priv->view_menus);
- priv->view_menus = NULL;
-}
-
-void
-e_tasks_open_task_id (ETasks *tasks,
- const gchar *src_uid,
- const gchar *comp_uid,
- const gchar *comp_rid)
-{
- ECal *client = NULL;
- GList *l;
- icalcomponent* icalcomp = NULL;
- icalproperty *attendee_prop = NULL;
-
- if (!src_uid || !comp_uid)
- return;
-
- for (l = tasks->priv->clients_list; l != NULL; l = l->next) {
- ESource *client_src;
-
- client = l->data;
- client_src = e_cal_get_source (client);
-
- if (!strcmp (src_uid, e_source_peek_uid (client_src)))
- break;
- }
-
- if (!client)
- return;
-
- e_cal_get_object (client, comp_uid, comp_rid, &icalcomp, NULL);
-
- if (!icalcomp)
- return;
-
- attendee_prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
- e_calendar_table_open_task (E_CALENDAR_TABLE (tasks->priv->tasks_view), client, icalcomp, attendee_prop != NULL);
- icalcomponent_free (icalcomp);
-
- return;
-}
-
-/**
- * e_tasks_get_calendar_table:
- * @tasks: A tasks widget.
- *
- * Queries the #ECalendarTable contained in a tasks widget.
- *
- * Return value: The #ECalendarTable that the tasks widget uses to display its
- * information.
- **/
-ECalendarTable *
-e_tasks_get_calendar_table (ETasks *tasks)
-{
- ETasksPrivate *priv;
-
- g_return_val_if_fail (tasks != NULL, NULL);
- g_return_val_if_fail (E_IS_TASKS (tasks), NULL);
-
- priv = tasks->priv;
- return E_CALENDAR_TABLE (priv->tasks_view);
-}
-
-/**
- * e_tasks_get_preview:
- * @tasks: A tasks widget.
- *
- * Queries the #ECalComponentPreview contained in a tasks widget.
- **/
-GtkWidget *
-e_tasks_get_preview (ETasks *tasks)
-{
- g_return_val_if_fail (tasks != NULL, NULL);
- g_return_val_if_fail (E_IS_TASKS (tasks), NULL);
-
- return tasks->priv->preview;
-}
diff --git a/calendar/gui/e-tasks.h b/calendar/gui/e-tasks.h
deleted file mode 100644
index f9eacb7819..0000000000
--- a/calendar/gui/e-tasks.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena Quintero <federico@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_TASKS_H_
-#define _E_TASKS_H_
-
-#include <bonobo/bonobo-ui-component.h>
-#include <gtk/gtk.h>
-#include <libedataserver/e-source.h>
-#include <libecal/e-cal.h>
-#include "e-calendar-table.h"
-
-#define E_TYPE_TASKS (e_tasks_get_type ())
-#define E_TASKS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TASKS, ETasks))
-#define E_TASKS_CLASS(klass) (G_TYPE_CHECK_INSTANCE_CAST_CLASS ((klass), E_TYPE_TASKS, \
- ETasksClass))
-#define E_IS_TASKS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TASKS))
-#define E_IS_TASKS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_TASKS))
-
-typedef struct _ETasks ETasks;
-typedef struct _ETasksClass ETasksClass;
-typedef struct _ETasksPrivate ETasksPrivate;
-
-struct _ETasks {
- GtkTable table;
-
- /* Private data */
- ETasksPrivate *priv;
-};
-
-struct _ETasksClass {
- GtkTableClass parent_class;
-
- /* Notification signals */
- void (* selection_changed) (ETasks *tasks, gint n_selected);
- void (* source_added) (ETasks *tasks, ESource *source);
- void (* source_removed) (ETasks *tasks, ESource *source);
-};
-
-GType e_tasks_get_type (void);
-GtkWidget *e_tasks_construct (ETasks *tasks);
-
-GtkWidget *e_tasks_new (void);
-
-void e_tasks_set_ui_component (ETasks *tasks,
- BonoboUIComponent *ui_component);
-
-gboolean e_tasks_add_todo_source (ETasks *tasks, ESource *source);
-gboolean e_tasks_remove_todo_source (ETasks *tasks, ESource *source);
-gboolean e_tasks_set_default_source (ETasks *tasks, ESource *source);
-ECal *e_tasks_get_default_client (ETasks *tasks);
-
-void e_tasks_open_task (ETasks *tasks);
-void e_tasks_open_task_id (ETasks *tasks,
- const gchar *src_uid,
- const gchar *comp_uid,
- const gchar *comp_rid);
-void e_tasks_new_task (ETasks *tasks);
-void e_tasks_complete_selected (ETasks *tasks);
-void e_tasks_delete_selected (ETasks *tasks);
-void e_tasks_delete_completed (ETasks *tasks);
-
-void e_tasks_show_preview (ETasks *tasks, gboolean state);
-void e_tasks_setup_view_menus (ETasks *tasks, BonoboUIComponent *uic);
-void e_tasks_discard_view_menus (ETasks *tasks);
-
-struct _ECalMenu *e_tasks_get_tasks_menu (ETasks *tasks);
-ECalendarTable *e_tasks_get_calendar_table (ETasks *tasks);
-GtkWidget *e_tasks_get_preview (ETasks *tasks);
-
-#endif /* _E_TASKS_H_ */
diff --git a/calendar/gui/e-timezone-entry.c b/calendar/gui/e-timezone-entry.c
index f3e239aa63..53a8a4498b 100644
--- a/calendar/gui/e-timezone-entry.c
+++ b/calendar/gui/e-timezone-entry.c
@@ -33,12 +33,16 @@
#include <glib/gi18n.h>
#include "e-timezone-entry.h"
+#define E_TIMEZONE_ENTRY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TIMEZONE_ENTRY, ETimezoneEntryPrivate))
+
struct _ETimezoneEntryPrivate {
/* The current timezone, set in e_timezone_entry_set_timezone()
or from the timezone dialog. Note that we don't copy it or
use a ref count - we assume it is never destroyed for the
lifetime of this widget. */
- icaltimezone *zone;
+ icaltimezone *timezone;
/* This can be set to the default timezone. If the current timezone
setting in the ETimezoneEntry matches this, then the entry field
@@ -50,314 +54,320 @@ struct _ETimezoneEntryPrivate {
};
enum {
- CHANGED,
- LAST_SIGNAL
+ PROP_0,
+ PROP_TIMEZONE
};
-static void e_timezone_entry_destroy (GtkObject *object);
-
-static gboolean e_timezone_entry_mnemonic_activate (GtkWidget *widget,
- gboolean group_cycling);
-static gboolean e_timezone_entry_focus (GtkWidget *widget,
- GtkDirectionType direction);
-static void on_entry_changed (GtkEntry *entry,
- ETimezoneEntry *tentry);
-static void on_button_clicked (GtkWidget *widget,
- ETimezoneEntry *tentry);
-static void add_relation (ETimezoneEntry *tentry,
- GtkWidget *widget);
-
-static void e_timezone_entry_set_entry (ETimezoneEntry *tentry);
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
-static guint timezone_entry_signals[LAST_SIGNAL] = { 0 };
+static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE (ETimezoneEntry, e_timezone_entry, GTK_TYPE_HBOX)
static void
-e_timezone_entry_class_init (ETimezoneEntryClass *class)
+timezone_entry_emit_changed (ETimezoneEntry *timezone_entry)
{
- GtkObjectClass *object_class = (GtkObjectClass *) class;
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
-
- object_class = (GtkObjectClass*) class;
-
- widget_class->mnemonic_activate = e_timezone_entry_mnemonic_activate;
- widget_class->focus = e_timezone_entry_focus;
- timezone_entry_signals[CHANGED] =
- g_signal_new ("changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ETimezoneEntryClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- object_class->destroy = e_timezone_entry_destroy;
-
- class->changed = NULL;
+ g_signal_emit (timezone_entry, signals[CHANGED], 0);
}
static void
-e_timezone_entry_init (ETimezoneEntry *tentry)
+timezone_entry_update_entry (ETimezoneEntry *timezone_entry)
{
- ETimezoneEntryPrivate *priv;
- AtkObject *a11y;
-
- tentry->priv = priv = g_new0 (ETimezoneEntryPrivate, 1);
+ const gchar *display_name;
+ gchar *name_buffer;
+ icaltimezone *timezone;
- priv->zone = NULL;
- priv->default_zone = NULL;
+ timezone = e_timezone_entry_get_timezone (timezone_entry);
- priv->entry = gtk_entry_new ();
- gtk_editable_set_editable (GTK_EDITABLE (priv->entry), FALSE);
- /*gtk_widget_set_usize (priv->date_entry, 90, 0);*/
- gtk_box_pack_start (GTK_BOX (tentry), priv->entry, TRUE, TRUE, 0);
- gtk_widget_show (priv->entry);
- g_signal_connect (priv->entry, "changed", G_CALLBACK (on_entry_changed), tentry);
+ if (timezone != NULL) {
+ display_name = icaltimezone_get_display_name (timezone);
- priv->button = gtk_button_new_with_label (_("Select..."));
- g_signal_connect (priv->button, "clicked", G_CALLBACK (on_button_clicked), tentry);
- gtk_box_pack_start (GTK_BOX (tentry), priv->button, FALSE, FALSE, 6);
- gtk_widget_show (priv->button);
- a11y = gtk_widget_get_accessible (priv->button);
- if (a11y != NULL) {
- atk_object_set_name (a11y, _("Select Timezone"));
- }
-}
+ /* We check if it is one of our builtin timezone
+ names, in which case we call gettext to translate
+ it. If it isn't a builtin timezone name, we don't. */
+ if (icaltimezone_get_builtin_timezone (display_name))
+ display_name = _(display_name);
+ } else
+ display_name = "";
-/**
- * e_timezone_entry_new:
- *
- * Description: Creates a new #ETimezoneEntry widget which can be used
- * to provide an easy to use way for entering dates and times.
- *
- * Returns: a new #ETimezoneEntry widget.
- */
-GtkWidget *
-e_timezone_entry_new (void)
-{
- ETimezoneEntry *tentry;
+ name_buffer = g_strdup (display_name);
- tentry = g_object_new (e_timezone_entry_get_type (), NULL);
+ gtk_entry_set_text (GTK_ENTRY (timezone_entry->priv->entry), name_buffer);
- GTK_WIDGET_SET_FLAGS (GTK_WIDGET(tentry), GTK_CAN_FOCUS);
+ /* XXX Do we need to hide the timezone entry at all? I know
+ * this overrules the previous case of hiding the timezone
+ * entry field when we select the default timezone. */
+ gtk_widget_show (timezone_entry->priv->entry);
- return GTK_WIDGET (tentry);
+ g_free (name_buffer);
}
-
static void
-e_timezone_entry_destroy (GtkObject *object)
+timezone_entry_add_relation (ETimezoneEntry *timezone_entry)
{
- ETimezoneEntry *tentry;
+ AtkObject *a11y_timezone_entry;
+ AtkObject *a11y_widget;
+ AtkRelationSet *set;
+ AtkRelation *relation;
+ GtkWidget *widget;
+ GPtrArray *target;
+ gpointer target_object;
- g_return_if_fail (E_IS_TIMEZONE_ENTRY (object));
+ /* add a labelled_by relation for widget for accessibility */
- tentry = E_TIMEZONE_ENTRY (object);
+ widget = GTK_WIDGET (timezone_entry);
+ a11y_timezone_entry = gtk_widget_get_accessible (widget);
- g_free (tentry->priv);
- tentry->priv = NULL;
+ widget = timezone_entry->priv->entry;
+ a11y_widget = gtk_widget_get_accessible (widget);
- if (GTK_OBJECT_CLASS (e_timezone_entry_parent_class)->destroy)
- (* GTK_OBJECT_CLASS (e_timezone_entry_parent_class)->destroy) (object);
+ set = atk_object_ref_relation_set (a11y_widget);
+ if (set != NULL) {
+ relation = atk_relation_set_get_relation_by_type (
+ set, ATK_RELATION_LABELLED_BY);
+ /* check whether has a labelled_by relation already */
+ if (relation != NULL)
+ return;
+ }
+
+ set = atk_object_ref_relation_set (a11y_timezone_entry);
+ if (!set)
+ return;
+
+ relation = atk_relation_set_get_relation_by_type (
+ set, ATK_RELATION_LABELLED_BY);
+ if (relation != NULL) {
+ target = atk_relation_get_target (relation);
+ target_object = g_ptr_array_index (target, 0);
+ if (ATK_IS_OBJECT (target_object)) {
+ atk_object_add_relationship (
+ a11y_widget,
+ ATK_RELATION_LABELLED_BY,
+ ATK_OBJECT (target_object));
+ }
+ }
}
/* The arrow button beside the date field has been clicked, so we show the
popup with the ECalendar in. */
static void
-on_button_clicked (GtkWidget *widget,
- ETimezoneEntry *tentry)
+timezone_entry_button_clicked_cb (ETimezoneEntry *timezone_entry)
{
- ETimezoneEntryPrivate *priv;
ETimezoneDialog *timezone_dialog;
GtkWidget *dialog;
-
- priv = tentry->priv;
+ icaltimezone *timezone;
timezone_dialog = e_timezone_dialog_new ();
- e_timezone_dialog_set_timezone (timezone_dialog, priv->zone);
+ timezone = e_timezone_entry_get_timezone (timezone_entry);
+ e_timezone_dialog_set_timezone (timezone_dialog, timezone);
dialog = e_timezone_dialog_get_toplevel (timezone_dialog);
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
- priv->zone = e_timezone_dialog_get_timezone (timezone_dialog);
- e_timezone_entry_set_entry (tentry);
- }
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT)
+ goto exit;
+ timezone = e_timezone_dialog_get_timezone (timezone_dialog);
+ e_timezone_entry_set_timezone (timezone_entry, timezone);
+ timezone_entry_update_entry (timezone_entry);
+
+exit:
g_object_unref (timezone_dialog);
}
static void
-on_entry_changed (GtkEntry *entry,
- ETimezoneEntry *tentry)
+timezone_entry_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- g_signal_emit (GTK_OBJECT (tentry), timezone_entry_signals[CHANGED], 0);
-}
-
-icaltimezone*
-e_timezone_entry_get_timezone (ETimezoneEntry *tentry)
-{
- ETimezoneEntryPrivate *priv;
-
- g_return_val_if_fail (E_IS_TIMEZONE_ENTRY (tentry), NULL);
-
- priv = tentry->priv;
+ switch (property_id) {
+ case PROP_TIMEZONE:
+ e_timezone_entry_set_timezone (
+ E_TIMEZONE_ENTRY (object),
+ g_value_get_pointer (value));
+ return;
+ }
- return priv->zone;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-add_relation (ETimezoneEntry *tentry,
- GtkWidget *widget)
+timezone_entry_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- AtkObject *a11ytentry, *a11yWidget;
- AtkRelationSet *set;
- AtkRelation *relation;
- GPtrArray *target;
- gpointer target_object;
-
- /* add a labelled_by relation for widget for accessibility */
-
- a11ytentry = gtk_widget_get_accessible (GTK_WIDGET (tentry));
- a11yWidget = gtk_widget_get_accessible (widget);
-
- set = atk_object_ref_relation_set (a11yWidget);
- if (set != NULL) {
- relation = atk_relation_set_get_relation_by_type (set,
- ATK_RELATION_LABELLED_BY);
- /* check whether has a labelled_by relation already */
- if (relation != NULL)
+ switch (property_id) {
+ case PROP_TIMEZONE:
+ g_value_set_pointer (
+ value, e_timezone_entry_get_timezone (
+ E_TIMEZONE_ENTRY (object)));
return;
}
- set = atk_object_ref_relation_set (a11ytentry);
- if (!set)
- return;
-
- relation = atk_relation_set_get_relation_by_type (set,
- ATK_RELATION_LABELLED_BY);
- if (relation != NULL) {
- target = atk_relation_get_target (relation);
- target_object = g_ptr_array_index (target, 0);
- if (ATK_IS_OBJECT (target_object)) {
- atk_object_add_relationship (a11yWidget,
- ATK_RELATION_LABELLED_BY,
- ATK_OBJECT (target_object));
- }
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-void
-e_timezone_entry_set_timezone (ETimezoneEntry *tentry,
- icaltimezone *zone)
+static gboolean
+timezone_entry_mnemonic_activate (GtkWidget *widget,
+ gboolean group_cycling)
{
ETimezoneEntryPrivate *priv;
- g_return_if_fail (E_IS_TIMEZONE_ENTRY (tentry));
+ priv = E_TIMEZONE_ENTRY_GET_PRIVATE (widget);
- priv = tentry->priv;
-
- priv->zone = zone;
-
- e_timezone_entry_set_entry (tentry);
+ if (GTK_WIDGET_CAN_FOCUS (widget)) {
+ if (priv->button != NULL)
+ gtk_widget_grab_focus (priv->button);
+ }
- add_relation (tentry, priv->entry);
+ return TRUE;
}
-/* Sets the default timezone. If the current timezone matches this, then the
- entry field is hidden. This is useful since most people do not use timezones
- so it makes the user interface simpler. */
-void
-e_timezone_entry_set_default_timezone (ETimezoneEntry *tentry,
- icaltimezone *zone)
+static gboolean
+timezone_entry_focus (GtkWidget *widget,
+ GtkDirectionType direction)
{
ETimezoneEntryPrivate *priv;
- g_return_if_fail (E_IS_TIMEZONE_ENTRY (tentry));
+ priv = E_TIMEZONE_ENTRY_GET_PRIVATE (widget);
- priv = tentry->priv;
+ if (direction == GTK_DIR_TAB_FORWARD) {
+ if (GTK_WIDGET_HAS_FOCUS (priv->entry))
+ gtk_widget_grab_focus (priv->button);
+ else if (GTK_WIDGET_HAS_FOCUS (priv->button))
+ return FALSE;
+ else if (GTK_WIDGET_VISIBLE (priv->entry))
+ gtk_widget_grab_focus (priv->entry);
+ else
+ gtk_widget_grab_focus (priv->button);
- priv->default_zone = zone;
+ } else if (direction == GTK_DIR_TAB_BACKWARD) {
+ if (GTK_WIDGET_HAS_FOCUS (priv->entry))
+ return FALSE;
+ else if (GTK_WIDGET_HAS_FOCUS (priv->button)) {
+ if (GTK_WIDGET_VISIBLE (priv->entry))
+ gtk_widget_grab_focus (priv->entry);
+ else
+ return FALSE;
+ } else
+ gtk_widget_grab_focus (priv->button);
+ } else
+ return FALSE;
- e_timezone_entry_set_entry (tentry);
+ return TRUE;
}
static void
-e_timezone_entry_set_entry (ETimezoneEntry *tentry)
+e_timezone_entry_class_init (ETimezoneEntryClass *class)
{
- ETimezoneEntryPrivate *priv;
- const gchar *display_name;
- gchar *name_buffer;
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ g_type_class_add_private (class, sizeof (ETimezoneEntryPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = timezone_entry_set_property;
+ object_class->get_property = timezone_entry_get_property;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->mnemonic_activate = timezone_entry_mnemonic_activate;
+ widget_class->focus = timezone_entry_focus;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TIMEZONE,
+ g_param_spec_pointer (
+ "timezone",
+ "Timezone",
+ NULL,
+ G_PARAM_READWRITE));
+
+ signals[CHANGED] = g_signal_new (
+ "changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ETimezoneEntryClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
- priv = tentry->priv;
+static void
+e_timezone_entry_init (ETimezoneEntry *timezone_entry)
+{
+ AtkObject *a11y;
+ GtkWidget *widget;
- if (priv->zone) {
- display_name = icaltimezone_get_display_name (priv->zone);
+ timezone_entry->priv = E_TIMEZONE_ENTRY_GET_PRIVATE (timezone_entry);
- /* We check if it is one of our builtin timezone
- names, in which case we call gettext to translate
- it. If it isn't a builtin timezone name, we
- don't. */
- if (icaltimezone_get_builtin_timezone (display_name))
- display_name = _(display_name);
- } else
- display_name = "";
+ GTK_WIDGET_SET_FLAGS (GTK_WIDGET (timezone_entry), GTK_CAN_FOCUS);
- name_buffer = g_strdup (display_name);
+ widget = gtk_entry_new ();
+ gtk_editable_set_editable (GTK_EDITABLE (widget), FALSE);
+ gtk_box_pack_start (GTK_BOX (timezone_entry), widget, TRUE, TRUE, 0);
+ timezone_entry->priv->entry = widget;
+ gtk_widget_show (widget);
- gtk_entry_set_text (GTK_ENTRY (priv->entry), name_buffer);
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (timezone_entry_emit_changed), timezone_entry);
- /* do we need to hide the timezone entry at all? i know this overrules the previous case of hiding the timezone
- * entry field when we select the default timezone
- */
- gtk_widget_show (priv->entry);
+ widget = gtk_button_new_with_label (_("Select..."));
+ gtk_box_pack_start (GTK_BOX (timezone_entry), widget, FALSE, FALSE, 6);
+ timezone_entry->priv->button = widget;
+ gtk_widget_show (widget);
- g_free (name_buffer);
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (timezone_entry_button_clicked_cb), timezone_entry);
+
+ a11y = gtk_widget_get_accessible (timezone_entry->priv->button);
+ if (a11y != NULL)
+ atk_object_set_name (a11y, _("Select Timezone"));
}
-static gboolean
-e_timezone_entry_mnemonic_activate (GtkWidget *widget,
- gboolean group_cycling)
+GtkWidget *
+e_timezone_entry_new (void)
{
- GtkButton *button = NULL;
+ return g_object_new (E_TYPE_TIMEZONE_ENTRY, NULL);
+}
- if (GTK_WIDGET_CAN_FOCUS (widget)) {
- button = GTK_BUTTON (((ETimezoneEntryPrivate *) ((ETimezoneEntry *) widget)->priv)->button);
- if (button != NULL)
- gtk_widget_grab_focus (GTK_WIDGET (button));
- }
+icaltimezone *
+e_timezone_entry_get_timezone (ETimezoneEntry *timezone_entry)
+{
+ g_return_val_if_fail (E_IS_TIMEZONE_ENTRY (timezone_entry), NULL);
- return TRUE;
+ return timezone_entry->priv->timezone;
}
-static gboolean
-e_timezone_entry_focus (GtkWidget *widget, GtkDirectionType direction)
+void
+e_timezone_entry_set_timezone (ETimezoneEntry *timezone_entry,
+ icaltimezone *timezone)
{
- ETimezoneEntry *tentry;
+ g_return_if_fail (E_IS_TIMEZONE_ENTRY (timezone_entry));
- tentry = E_TIMEZONE_ENTRY (widget);
+ timezone_entry->priv->timezone = timezone;
- if (direction == GTK_DIR_TAB_FORWARD) {
- if (GTK_WIDGET_HAS_FOCUS (tentry->priv->entry))
- gtk_widget_grab_focus (tentry->priv->button);
- else if (GTK_WIDGET_HAS_FOCUS (tentry->priv->button))
- return FALSE;
- else if (GTK_WIDGET_VISIBLE (tentry->priv->entry))
- gtk_widget_grab_focus (tentry->priv->entry);
- else
- gtk_widget_grab_focus (tentry->priv->button);
- } else if (direction == GTK_DIR_TAB_BACKWARD) {
- if (GTK_WIDGET_HAS_FOCUS (tentry->priv->entry))
- return FALSE;
- else if (GTK_WIDGET_HAS_FOCUS (tentry->priv->button)) {
- if (GTK_WIDGET_VISIBLE (tentry->priv->entry))
- gtk_widget_grab_focus (tentry->priv->entry);
- else
- return FALSE;
- } else
- gtk_widget_grab_focus (tentry->priv->button);
- } else
- return FALSE;
- return TRUE;
+ timezone_entry_update_entry (timezone_entry);
+ timezone_entry_add_relation (timezone_entry);
+
+ g_object_notify (G_OBJECT (timezone_entry), "timezone");
}
+/* Sets the default timezone. If the current timezone matches this,
+ * then the entry field is hidden. This is useful since most people
+ * do not use timezones so it makes the user interface simpler. */
+void
+e_timezone_entry_set_default_timezone (ETimezoneEntry *timezone_entry,
+ icaltimezone *timezone)
+{
+ g_return_if_fail (E_IS_TIMEZONE_ENTRY (timezone_entry));
+
+ timezone_entry->priv->default_zone = timezone;
+
+ timezone_entry_update_entry (timezone_entry);
+}
diff --git a/calendar/gui/e-timezone-entry.h b/calendar/gui/e-timezone-entry.h
index c1bf482aef..6c0cd1dc6b 100644
--- a/calendar/gui/e-timezone-entry.h
+++ b/calendar/gui/e-timezone-entry.h
@@ -29,50 +29,61 @@
* timezone.
*/
-#ifndef __E_TIMEZONE_ENTRY_H_
-#define __E_TIMEZONE_ENTRY_H_
+#ifndef E_TIMEZONE_ENTRY_H
+#define E_TIMEZONE_ENTRY_H
#include <gtk/gtk.h>
#include <libecal/e-cal.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_TIMEZONE_ENTRY \
+ (e_timezone_entry_get_type ())
+#define E_TIMEZONE_ENTRY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TIMEZONE_ENTRY, ETimezoneEntry))
+#define E_TIMEZONE_ENTRY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TIMEZONE_ENTRY, ETimezoneEntryClass))
+#define E_IS_TIMEZONE_ENTRY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TIMEZONE_ENTRY))
+#define E_IS_TIMEZONE_ENTRY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TIMEZONE_ENTRY))
+#define E_IS_TIMEZONE_ENTRY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TIMEZONE_ENTRY, ETimezoneEntryClass))
-#define E_TYPE_TIMEZONE_ENTRY (e_timezone_entry_get_type ())
-#define E_TIMEZONE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TIMEZONE_ENTRY, ETimezoneEntry))
-#define E_TIMEZONE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_TIMEZONE_ENTRY, ETimezoneEntryClass))
-#define E_IS_TIMEZONE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TIMEZONE_ENTRY))
-#define E_IS_TIMEZONE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_TIMEZONE_ENTRY))
+G_BEGIN_DECLS
-typedef struct _ETimezoneEntry ETimezoneEntry;
+typedef struct _ETimezoneEntry ETimezoneEntry;
+typedef struct _ETimezoneEntryClass ETimezoneEntryClass;
typedef struct _ETimezoneEntryPrivate ETimezoneEntryPrivate;
-typedef struct _ETimezoneEntryClass ETimezoneEntryClass;
struct _ETimezoneEntry {
- GtkHBox hbox;
-
- /*< private >*/
+ GtkHBox parent;
ETimezoneEntryPrivate *priv;
};
struct _ETimezoneEntryClass {
GtkHBoxClass parent_class;
- void (* changed) (ETimezoneEntry *tentry);
+ void (*changed) (ETimezoneEntry *timezone_entry);
};
-GType e_timezone_entry_get_type (void);
-GtkWidget* e_timezone_entry_new (void);
-
-icaltimezone* e_timezone_entry_get_timezone (ETimezoneEntry *tentry);
-void e_timezone_entry_set_timezone (ETimezoneEntry *tentry,
- icaltimezone *zone);
+GType e_timezone_entry_get_type (void);
+GtkWidget * e_timezone_entry_new (void);
+icaltimezone * e_timezone_entry_get_timezone (ETimezoneEntry *timezone_entry);
+void e_timezone_entry_set_timezone (ETimezoneEntry *timezone_entry,
+ icaltimezone *timezone);
-/* Sets the default timezone. If the current timezone matches this, then the
- entry field is hidden. This is useful since most people do not use timezones
- so it makes the user interface simpler. */
-void e_timezone_entry_set_default_timezone(ETimezoneEntry *tentry,
- icaltimezone *zone);
+/* Sets the default timezone. If the current timezone matches this,
+ * then the entry field is hidden. This is useful since most people
+ * do not use timezones so it makes the user interface simpler. */
+void e_timezone_entry_set_default_timezone
+ (ETimezoneEntry *timezone_entry,
+ icaltimezone *timezone);
G_END_DECLS
-#endif /* __E_TIMEZONE_ENTRY_H_ */
+#endif /* E_TIMEZONE_ENTRY_H */
diff --git a/calendar/gui/e-week-view-config.c b/calendar/gui/e-week-view-config.c
deleted file mode 100644
index 423a12a2d9..0000000000
--- a/calendar/gui/e-week-view-config.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "calendar-config.h"
-#include "e-week-view-config.h"
-
-struct _EWeekViewConfigPrivate {
- EWeekView *view;
-
- GList *notifications;
-};
-
-/* Property IDs */
-enum props {
- PROP_0,
- PROP_VIEW,
-};
-
-G_DEFINE_TYPE (EWeekViewConfig, e_week_view_config, G_TYPE_OBJECT)
-
-static void
-e_week_view_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- EWeekViewConfig *view_config;
-
- view_config = E_WEEK_VIEW_CONFIG (object);
-
- switch (property_id) {
- case PROP_VIEW:
- e_week_view_config_set_view (view_config, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_week_view_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- EWeekViewConfig *view_config;
-
- view_config = E_WEEK_VIEW_CONFIG (object);
-
- switch (property_id) {
- case PROP_VIEW:
- g_value_set_object (value, e_week_view_config_get_view (view_config));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-e_week_view_config_dispose (GObject *object)
-{
- EWeekViewConfig *view_config = E_WEEK_VIEW_CONFIG (object);
-
- e_week_view_config_set_view (view_config, NULL);
-
- if (G_OBJECT_CLASS (e_week_view_config_parent_class)->dispose)
- G_OBJECT_CLASS (e_week_view_config_parent_class)->dispose (object);
-}
-
-static void
-e_week_view_config_finalize (GObject *object)
-{
- EWeekViewConfig *view_config = E_WEEK_VIEW_CONFIG (object);
- EWeekViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- g_free (priv);
-
- if (G_OBJECT_CLASS (e_week_view_config_parent_class)->finalize)
- G_OBJECT_CLASS (e_week_view_config_parent_class)->finalize (object);
-}
-
-static void
-e_week_view_config_class_init (EWeekViewConfigClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GParamSpec *spec;
-
- /* Method override */
- gobject_class->set_property = e_week_view_config_set_property;
- gobject_class->get_property = e_week_view_config_get_property;
- gobject_class->dispose = e_week_view_config_dispose;
- gobject_class->finalize = e_week_view_config_finalize;
-
- spec = g_param_spec_object ("view", NULL, NULL, e_week_view_get_type (),
- G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (gobject_class, PROP_VIEW, spec);
-}
-
-static void
-e_week_view_config_init (EWeekViewConfig *view_config)
-{
- view_config->priv = g_new0 (EWeekViewConfigPrivate, 1);
-
-}
-
-EWeekViewConfig *
-e_week_view_config_new (EWeekView *week_view)
-{
- EWeekViewConfig *view_config;
-
- view_config = g_object_new (e_week_view_config_get_type (), "view", week_view, NULL);
-
- return view_config;
-}
-
-EWeekView *
-e_week_view_config_get_view (EWeekViewConfig *view_config)
-{
- EWeekViewConfigPrivate *priv;
-
- g_return_val_if_fail (view_config != NULL, NULL);
- g_return_val_if_fail (E_IS_WEEK_VIEW_CONFIG (view_config), NULL);
-
- priv = view_config->priv;
-
- return priv->view;
-}
-
-static void
-set_week_start (EWeekView *week_view)
-{
- gint week_start_week;
-
- week_start_week = calendar_config_get_week_start_day ();
-
- /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
- week_start_week = (week_start_week + 6) % 7;
-
- e_week_view_set_week_start_day (week_view, week_start_week);
-}
-
-static void
-week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EWeekViewConfig *view_config = data;
- EWeekViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_week_start (priv->view);
-}
-
-static void
-set_twentyfour_hour (EWeekView *week_view)
-{
- gboolean use_24_hour;
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- e_calendar_view_set_use_24_hour_format (E_CALENDAR_VIEW (week_view), use_24_hour);
-}
-
-static void
-twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EWeekViewConfig *view_config = data;
- EWeekViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_twentyfour_hour (priv->view);
-}
-
-static void
-set_show_event_end (EWeekView *week_view)
-{
- gboolean show_event_end;
-
- show_event_end = calendar_config_get_show_event_end ();
-
- e_week_view_set_show_event_end_times (week_view, show_event_end);
-}
-
-static void
-show_event_end_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EWeekViewConfig *view_config = data;
- EWeekViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_show_event_end (priv->view);
-}
-
-static void
-set_compress_weekend (EWeekView *week_view)
-{
- gboolean compress_weekend;
-
- compress_weekend = calendar_config_get_compress_weekend ();
-
- e_week_view_set_compress_weekend (week_view, compress_weekend);
-}
-
-static void
-compress_weekend_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EWeekViewConfig *view_config = data;
- EWeekViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_compress_weekend (priv->view);
-}
-
-void
-e_week_view_config_set_view (EWeekViewConfig *view_config, EWeekView *week_view)
-{
- EWeekViewConfigPrivate *priv;
- guint not;
- GList *l;
-
- g_return_if_fail (view_config != NULL);
- g_return_if_fail (E_IS_WEEK_VIEW_CONFIG (view_config));
-
- priv = view_config->priv;
-
- if (priv->view) {
- g_object_unref (priv->view);
- priv->view = NULL;
- }
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
-
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- /* If the new view is NULL, return right now */
- if (!week_view)
- return;
-
- priv->view = g_object_ref (week_view);
-
- /* Week start */
- set_week_start (week_view);
-
- not = calendar_config_add_notification_week_start_day (week_start_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* 24 Hour format */
- set_twentyfour_hour (week_view);
-
- not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Show event end */
- set_show_event_end (week_view);
-
- not = calendar_config_add_notification_show_event_end (show_event_end_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Compress weekend */
- set_compress_weekend (week_view);
-
- not = calendar_config_add_notification_compress_weekend (compress_weekend_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-}
-
diff --git a/calendar/gui/e-week-view-config.h b/calendar/gui/e-week-view-config.h
deleted file mode 100644
index e86e0fa968..0000000000
--- a/calendar/gui/e-week-view-config.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_WEEK_VIEW_CONFIG_H_
-#define _E_WEEK_VIEW_CONFIG_H_
-
-#include "e-week-view.h"
-
-G_BEGIN_DECLS
-
-#define E_WEEK_VIEW_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_week_view_config_get_type (), EWeekViewConfig)
-#define E_WEEK_VIEW_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_week_view_config_get_type (), EWeekViewConfigClass)
-#define E_IS_WEEK_VIEW_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_week_view_config_get_type ())
-
-typedef struct _EWeekViewConfig EWeekViewConfig;
-typedef struct _EWeekViewConfigClass EWeekViewConfigClass;
-typedef struct _EWeekViewConfigPrivate EWeekViewConfigPrivate;
-
-struct _EWeekViewConfig {
- GObject parent;
-
- EWeekViewConfigPrivate *priv;
-};
-
-struct _EWeekViewConfigClass {
- GObjectClass parent_class;
-};
-
-GType e_week_view_config_get_type (void);
-EWeekViewConfig *e_week_view_config_new (EWeekView *week_view);
-EWeekView *e_week_view_config_get_view (EWeekViewConfig *view_config);
-void e_week_view_config_set_view (EWeekViewConfig *view_config, EWeekView *week_view);
-
-G_END_DECLS
-
-#endif
diff --git a/calendar/gui/e-week-view-event-item.c b/calendar/gui/e-week-view-event-item.c
index ed939feb10..dc31e20696 100644
--- a/calendar/gui/e-week-view-event-item.c
+++ b/calendar/gui/e-week-view-event-item.c
@@ -629,6 +629,7 @@ e_week_view_draw_time (EWeekView *week_view,
gint hour,
gint minute)
{
+ ECalModel *model;
GtkStyle *style;
GdkGC *gc;
gint hour_to_display, suffix_width;
@@ -638,6 +639,8 @@ e_week_view_draw_time (EWeekView *week_view,
PangoLayout *layout;
PangoFontDescription *small_font_desc;
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+
style = gtk_widget_get_style (GTK_WIDGET (week_view));
small_font_desc = week_view->small_font_desc;
gc = week_view->main_gc;
@@ -687,7 +690,7 @@ e_week_view_draw_time (EWeekView *week_view,
time_x += week_view->small_digit_width * 2;
/* Draw the 'am'/'pm' suffix, if 12-hour format. */
- if (!e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (week_view))) {
+ if (!e_cal_model_get_use_24_hour_format (model)) {
pango_layout_set_text (layout, suffix, -1);
gdk_draw_layout (drawable, gc,
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 4d21eae9d0..d4043ff4fe 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -39,7 +39,8 @@
#include <text/e-text.h>
#include <misc/e-canvas-utils.h>
#include <misc/e-gui-utils.h>
-#include <misc/e-unicode.h>
+#include <e-util/e-binding.h>
+#include <e-util/e-unicode.h>
#include <e-util/e-categories-config.h>
#include <e-util/e-dialog-utils.h>
#include <e-util/e-util.h>
@@ -51,7 +52,6 @@
#include "comp-util.h"
#include "itip-utils.h"
#include <libecal/e-cal-time-util.h>
-#include "calendar-commands.h"
#include "calendar-config.h"
#include "print.h"
#include "goto.h"
@@ -169,7 +169,6 @@ static gboolean e_week_view_on_text_item_event (GnomeCanvasItem *item,
EWeekView *week_view);
static gboolean e_week_view_event_move (ECalendarView *cal_view, ECalViewMoveDirection direction);
static gint e_week_view_get_day_offset_of_event (EWeekView *week_view, time_t event_time);
-static void e_week_view_scroll_a_step (EWeekView *week_view, ECalViewMoveDirection direction);
static void e_week_view_change_event_time (EWeekView *week_view, time_t start_dt, time_t end_dt, gboolean is_all_day);
static gboolean e_week_view_on_jump_button_event (GnomeCanvasItem *item,
GdkEvent *event,
@@ -195,42 +194,409 @@ static gboolean e_week_view_layout_timeout_cb (gpointer data);
G_DEFINE_TYPE (EWeekView, e_week_view, E_TYPE_CALENDAR_VIEW)
+enum {
+ PROP_0,
+ PROP_COMPRESS_WEEKEND,
+ PROP_SHOW_EVENT_END_TIMES
+};
+
+static gint map_left[] = {0, 1, 2, 0, 1, 2, 2};
+static gint map_right[] = {3, 4, 5, 3, 4, 5, 6};
+
static void
-e_week_view_class_init (EWeekViewClass *class)
+timezone_changed_cb (ECalendarView *cal_view,
+ icaltimezone *old_zone,
+ icaltimezone *new_zone,
+ gpointer user_data)
{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- ECalendarViewClass *view_class;
+ struct icaltimetype tt = icaltime_null_time ();
+ time_t lower;
+ EWeekView *week_view = (EWeekView *) cal_view;
+
+ g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+
+ if (!cal_view->in_focus)
+ return;
+
+ /* If we don't have a valid date set yet, just return. */
+ if (!g_date_valid (&week_view->first_day_shown))
+ return;
+
+ /* Recalculate the new start of the first week. We just use exactly
+ the same time, but with the new timezone. */
+ tt.year = g_date_get_year (&week_view->first_day_shown);
+ tt.month = g_date_get_month (&week_view->first_day_shown);
+ tt.day = g_date_get_day (&week_view->first_day_shown);
+
+ lower = icaltime_as_timet_with_zone (tt, new_zone);
+
+ e_week_view_recalc_day_starts (week_view, lower);
+ e_week_view_update_query (week_view);
+}
+
+static void
+week_view_notify_week_start_day_cb (EWeekView *week_view)
+{
+ GDate *first_day_shown;
+
+ first_day_shown = &week_view->first_day_shown;
+
+ e_week_view_recalc_display_start_day (week_view);
+
+ /* Recalculate the days shown and reload if necessary. */
+ if (g_date_valid (first_day_shown))
+ e_week_view_set_first_day_shown (week_view, first_day_shown);
+
+ gtk_widget_queue_draw (week_view->titles_canvas);
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+
+static void
+week_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COMPRESS_WEEKEND:
+ e_week_view_set_compress_weekend (
+ E_WEEK_VIEW (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SHOW_EVENT_END_TIMES:
+ e_week_view_set_show_event_end_times (
+ E_WEEK_VIEW (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+week_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COMPRESS_WEEKEND:
+ g_value_set_boolean (
+ value,
+ e_week_view_get_compress_weekend (
+ E_WEEK_VIEW (object)));
+ return;
+
+ case PROP_SHOW_EVENT_END_TIMES:
+ g_value_set_boolean (
+ value,
+ e_week_view_get_show_event_end_times (
+ E_WEEK_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+week_view_constructed (GObject *object)
+{
+ ECalModel *model;
+ EWeekView *week_view;
+ EShellSettings *shell_settings;
+
+ week_view = E_WEEK_VIEW (object);
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+ shell_settings = e_cal_model_get_shell_settings (model);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-compress-weekend",
+ G_OBJECT (week_view), "compress-weekend");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-show-event-end-times",
+ G_OBJECT (week_view), "show-event-end-times");
+
+ g_signal_connect_swapped (
+ model, "notify::week-start-day",
+ G_CALLBACK (week_view_notify_week_start_day_cb), week_view);
+}
+
+static void
+week_view_cursor_key_up (EWeekView *week_view)
+{
+ if (week_view->selection_start_day == -1)
+ return;
+
+ week_view->selection_start_day--;
+
+ if (week_view->selection_start_day < 0) {
+ e_week_view_scroll_a_step (week_view, E_CAL_VIEW_MOVE_UP);
+ week_view->selection_start_day = 6;
+ }
+
+ week_view->selection_end_day = week_view->selection_start_day;
+ g_signal_emit_by_name (week_view, "selected_time_changed");
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+
+static void
+week_view_cursor_key_down (EWeekView *week_view)
+{
+ if (week_view->selection_start_day == -1)
+ return;
+
+ week_view->selection_start_day++;
+
+ if (week_view->selection_start_day > 6) {
+ e_week_view_scroll_a_step (week_view, E_CAL_VIEW_MOVE_DOWN);
+ week_view->selection_start_day = 0;
+ }
- object_class = (GtkObjectClass *) class;
- widget_class = (GtkWidgetClass *) class;
- view_class = (ECalendarViewClass *) class;
+ week_view->selection_end_day = week_view->selection_start_day;
+ g_signal_emit_by_name (week_view, "selected_time_changed");
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
- /* Method override */
- object_class->destroy = e_week_view_destroy;
+static void
+week_view_cursor_key_left (EWeekView *week_view)
+{
+ if (week_view->selection_start_day == -1)
+ return;
- widget_class->realize = e_week_view_realize;
- widget_class->unrealize = e_week_view_unrealize;
- widget_class->style_set = e_week_view_style_set;
- widget_class->size_allocate = e_week_view_size_allocate;
- widget_class->focus_in_event = e_week_view_focus_in;
- widget_class->focus_out_event = e_week_view_focus_out;
- widget_class->key_press_event = e_week_view_key_press;
- widget_class->popup_menu = e_week_view_popup_menu;
- widget_class->expose_event = e_week_view_expose_event;
- widget_class->focus = e_week_view_focus;
+ week_view->selection_start_day = map_left[week_view->selection_start_day];
+ week_view->selection_end_day = week_view->selection_start_day;
+ g_signal_emit_by_name (week_view, "selected_time_changed");
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+static void
+week_view_cursor_key_right (EWeekView *week_view)
+{
+ if (week_view->selection_start_day == -1)
+ return;
+
+ week_view->selection_start_day = map_right[week_view->selection_start_day];
+ week_view->selection_end_day = week_view->selection_start_day;
+ g_signal_emit_by_name (week_view, "selected_time_changed");
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+
+static void
+e_week_view_class_init (EWeekViewClass *class)
+{
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+ GtkWidgetClass *widget_class;
+ ECalendarViewClass *view_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = week_view_set_property;
+ object_class->get_property = week_view_get_property;
+ object_class->constructed = week_view_constructed;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = e_week_view_destroy;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = e_week_view_realize;
+ widget_class->unrealize = e_week_view_unrealize;
+ widget_class->style_set = e_week_view_style_set;
+ widget_class->size_allocate = e_week_view_size_allocate;
+ widget_class->focus_in_event = e_week_view_focus_in;
+ widget_class->focus_out_event = e_week_view_focus_out;
+ widget_class->key_press_event = e_week_view_key_press;
+ widget_class->popup_menu = e_week_view_popup_menu;
+ widget_class->expose_event = e_week_view_expose_event;
+ widget_class->focus = e_week_view_focus;
+
+ view_class = E_CALENDAR_VIEW_CLASS (class);
view_class->get_selected_events = e_week_view_get_selected_events;
view_class->get_selected_time_range = e_week_view_get_selected_time_range;
view_class->set_selected_time_range = e_week_view_set_selected_time_range;
view_class->get_visible_time_range = e_week_view_get_visible_time_range;
view_class->paste_text = e_week_view_paste_text;
+ class->cursor_key_up = week_view_cursor_key_up;
+ class->cursor_key_down = week_view_cursor_key_down;
+ class->cursor_key_left = week_view_cursor_key_left;
+ class->cursor_key_right = week_view_cursor_key_right;
+
+ /* XXX This property really belongs in EMonthView,
+ * but too much drawing code is tied to it. */
+ g_object_class_install_property (
+ object_class,
+ PROP_COMPRESS_WEEKEND,
+ g_param_spec_boolean (
+ "compress-weekend",
+ "Compress Weekend",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_EVENT_END_TIMES,
+ g_param_spec_boolean (
+ "show-event-end-times",
+ "Show Event End Times",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
/* init the accessibility support for e_week_view */
e_week_view_a11y_init ();
}
static void
+e_week_view_init (EWeekView *week_view)
+{
+ GnomeCanvasGroup *canvas_group;
+ GtkObject *adjustment;
+ GdkPixbuf *pixbuf;
+ gint i;
+
+ GTK_WIDGET_SET_FLAGS (week_view, GTK_CAN_FOCUS);
+
+ week_view->query = NULL;
+ week_view->event_destroyed = FALSE;
+ week_view->events = g_array_new (FALSE, FALSE,
+ sizeof (EWeekViewEvent));
+ week_view->events_sorted = TRUE;
+ week_view->events_need_layout = FALSE;
+ week_view->events_need_reshape = FALSE;
+
+ week_view->layout_timeout_id = 0;
+
+ week_view->spans = NULL;
+
+ week_view->multi_week_view = FALSE;
+ week_view->month_scroll_by_week = FALSE;
+ week_view->scroll_by_week_notif_id = 0;
+ week_view->update_base_date = TRUE;
+ week_view->weeks_shown = 6;
+ week_view->rows = 6;
+ week_view->columns = 2;
+ week_view->compress_weekend = TRUE;
+ week_view->show_event_end_times = TRUE;
+ week_view->display_start_day = 0; /* Monday. */
+
+ g_date_clear (&week_view->base_date, 1);
+ g_date_clear (&week_view->first_day_shown, 1);
+
+ week_view->row_height = 10;
+ week_view->rows_per_cell = 1;
+
+ week_view->selection_start_day = -1;
+ week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_NONE;
+
+ week_view->pressed_event_num = -1;
+ week_view->editing_event_num = -1;
+
+ week_view->last_edited_comp_string = NULL;
+
+ week_view->main_gc = NULL;
+
+ /* Create the small font. */
+ week_view->use_small_font = TRUE;
+
+ week_view->small_font_desc =
+ pango_font_description_copy (gtk_widget_get_style (GTK_WIDGET (week_view))->font_desc);
+ pango_font_description_set_size (week_view->small_font_desc,
+ E_WEEK_VIEW_SMALL_FONT_PTSIZE * PANGO_SCALE);
+
+ /* String to use in 12-hour time format for times in the morning. */
+ week_view->am_string = _("am");
+
+ /* String to use in 12-hour time format for times in the afternoon. */
+ week_view->pm_string = _("pm");
+
+ week_view->bc_event_time = 0;
+ week_view->before_click_dtstart = 0;
+ week_view->before_click_dtend = 0;
+
+ /*
+ * Titles Canvas. Note that we don't show it is only shown in the
+ * Month view.
+ */
+ week_view->titles_canvas = e_canvas_new ();
+ gtk_table_attach (GTK_TABLE (week_view), week_view->titles_canvas,
+ 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+
+ canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->titles_canvas)->root);
+
+ week_view->titles_canvas_item =
+ gnome_canvas_item_new (canvas_group,
+ e_week_view_titles_item_get_type (),
+ "EWeekViewTitlesItem::week_view", week_view,
+ NULL);
+
+ /*
+ * Main Canvas
+ */
+ week_view->main_canvas = e_canvas_new ();
+ gtk_table_attach (GTK_TABLE (week_view), week_view->main_canvas,
+ 1, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 1, 1);
+ gtk_widget_show (week_view->main_canvas);
+
+ canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root);
+
+ week_view->main_canvas_item =
+ gnome_canvas_item_new (canvas_group,
+ e_week_view_main_item_get_type (),
+ "EWeekViewMainItem::week_view", week_view,
+ NULL);
+
+ g_signal_connect_after (week_view->main_canvas, "button_press_event",
+ G_CALLBACK (e_week_view_on_button_press), week_view);
+ g_signal_connect (week_view->main_canvas, "button_release_event",
+ G_CALLBACK (e_week_view_on_button_release), week_view);
+ g_signal_connect (week_view->main_canvas, "scroll_event",
+ G_CALLBACK (e_week_view_on_scroll), week_view);
+ g_signal_connect (week_view->main_canvas, "motion_notify_event",
+ G_CALLBACK (e_week_view_on_motion), week_view);
+
+ /* Create the buttons to jump to each days. */
+ pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) jump_xpm);
+
+ for (i = 0; i < E_WEEK_VIEW_MAX_WEEKS * 7; i++) {
+ week_view->jump_buttons[i] = gnome_canvas_item_new
+ (canvas_group,
+ gnome_canvas_pixbuf_get_type (),
+ "GnomeCanvasPixbuf::pixbuf", pixbuf,
+ NULL);
+
+ g_signal_connect (week_view->jump_buttons[i], "event",
+ G_CALLBACK (e_week_view_on_jump_button_event), week_view);
+ }
+ week_view->focused_jump_button = E_WEEK_VIEW_JUMP_BUTTON_NO_FOCUS;
+
+ g_object_unref (pixbuf);
+
+ /*
+ * Scrollbar.
+ */
+ adjustment = gtk_adjustment_new (0, -52, 52, 1, 1, 1);
+
+ week_view->vscrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (adjustment));
+ gtk_table_attach (GTK_TABLE (week_view), week_view->vscrollbar,
+ 2, 3, 1, 2, 0, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (week_view->vscrollbar);
+
+ /* Create the cursors. */
+ week_view->normal_cursor = gdk_cursor_new (GDK_LEFT_PTR);
+ week_view->move_cursor = gdk_cursor_new (GDK_FLEUR);
+ week_view->resize_width_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
+ week_view->last_cursor_set = NULL;
+
+ /* connect to ECalendarView's signals */
+ g_signal_connect (G_OBJECT (week_view), "timezone_changed",
+ G_CALLBACK (timezone_changed_cb), NULL);
+}
+
+static void
time_range_changed_cb (ECalModel *model, time_t start_time, time_t end_time, gpointer user_data)
{
EWeekView *week_view = E_WEEK_VIEW (user_data);
@@ -451,183 +817,6 @@ model_comps_deleted_cb (ETableModel *etm, gpointer data, gpointer user_data)
}
static void
-timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone,
- icaltimezone *new_zone, gpointer user_data)
-{
- struct icaltimetype tt = icaltime_null_time ();
- time_t lower;
- EWeekView *week_view = (EWeekView *) cal_view;
-
- g_return_if_fail (E_IS_WEEK_VIEW (week_view));
-
- if (!cal_view->in_focus)
- return;
-
- /* If we don't have a valid date set yet, just return. */
- if (!g_date_valid (&week_view->first_day_shown))
- return;
-
- /* Recalculate the new start of the first week. We just use exactly
- the same time, but with the new timezone. */
- tt.year = g_date_get_year (&week_view->first_day_shown);
- tt.month = g_date_get_month (&week_view->first_day_shown);
- tt.day = g_date_get_day (&week_view->first_day_shown);
-
- lower = icaltime_as_timet_with_zone (tt, new_zone);
-
- e_week_view_recalc_day_starts (week_view, lower);
- e_week_view_update_query (week_view);
-}
-
-static void
-e_week_view_init (EWeekView *week_view)
-{
- GnomeCanvasGroup *canvas_group;
- GtkObject *adjustment;
- GdkPixbuf *pixbuf;
- gint i;
-
- GTK_WIDGET_SET_FLAGS (week_view, GTK_CAN_FOCUS);
-
- week_view->query = NULL;
- week_view->event_destroyed = FALSE;
- week_view->events = g_array_new (FALSE, FALSE,
- sizeof (EWeekViewEvent));
- week_view->events_sorted = TRUE;
- week_view->events_need_layout = FALSE;
- week_view->events_need_reshape = FALSE;
-
- week_view->layout_timeout_id = 0;
-
- week_view->spans = NULL;
-
- week_view->multi_week_view = FALSE;
- week_view->month_scroll_by_week = FALSE;
- week_view->scroll_by_week_notif_id = 0;
- week_view->update_base_date = TRUE;
- week_view->weeks_shown = 6;
- week_view->rows = 6;
- week_view->columns = 2;
- week_view->compress_weekend = TRUE;
- week_view->show_event_end_times = TRUE;
- week_view->week_start_day = 0; /* Monday. */
- week_view->display_start_day = 0; /* Monday. */
-
- g_date_clear (&week_view->base_date, 1);
- g_date_clear (&week_view->first_day_shown, 1);
-
- week_view->row_height = 10;
- week_view->rows_per_cell = 1;
-
- week_view->selection_start_day = -1;
- week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_NONE;
-
- week_view->pressed_event_num = -1;
- week_view->editing_event_num = -1;
-
- week_view->last_edited_comp_string = NULL;
-
- week_view->main_gc = NULL;
-
- /* Create the small font. */
- week_view->use_small_font = TRUE;
-
- week_view->small_font_desc =
- pango_font_description_copy (gtk_widget_get_style (GTK_WIDGET (week_view))->font_desc);
- pango_font_description_set_size (week_view->small_font_desc,
- E_WEEK_VIEW_SMALL_FONT_PTSIZE * PANGO_SCALE);
-
- /* String to use in 12-hour time format for times in the morning. */
- week_view->am_string = _("am");
-
- /* String to use in 12-hour time format for times in the afternoon. */
- week_view->pm_string = _("pm");
-
- week_view->bc_event_time = 0;
- week_view->before_click_dtstart = 0;
- week_view->before_click_dtend = 0;
-
- /*
- * Titles Canvas. Note that we don't show it is only shown in the
- * Month view.
- */
- week_view->titles_canvas = e_canvas_new ();
- gtk_table_attach (GTK_TABLE (week_view), week_view->titles_canvas,
- 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
-
- canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->titles_canvas)->root);
-
- week_view->titles_canvas_item =
- gnome_canvas_item_new (canvas_group,
- e_week_view_titles_item_get_type (),
- "EWeekViewTitlesItem::week_view", week_view,
- NULL);
-
- /*
- * Main Canvas
- */
- week_view->main_canvas = e_canvas_new ();
- gtk_table_attach (GTK_TABLE (week_view), week_view->main_canvas,
- 1, 2, 1, 2,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 1, 1);
- gtk_widget_show (week_view->main_canvas);
-
- canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root);
-
- week_view->main_canvas_item =
- gnome_canvas_item_new (canvas_group,
- e_week_view_main_item_get_type (),
- "EWeekViewMainItem::week_view", week_view,
- NULL);
-
- g_signal_connect_after (week_view->main_canvas, "button_press_event",
- G_CALLBACK (e_week_view_on_button_press), week_view);
- g_signal_connect (week_view->main_canvas, "button_release_event",
- G_CALLBACK (e_week_view_on_button_release), week_view);
- g_signal_connect (week_view->main_canvas, "scroll_event",
- G_CALLBACK (e_week_view_on_scroll), week_view);
- g_signal_connect (week_view->main_canvas, "motion_notify_event",
- G_CALLBACK (e_week_view_on_motion), week_view);
-
- /* Create the buttons to jump to each days. */
- pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) jump_xpm);
-
- for (i = 0; i < E_WEEK_VIEW_MAX_WEEKS * 7; i++) {
- week_view->jump_buttons[i] = gnome_canvas_item_new
- (canvas_group,
- gnome_canvas_pixbuf_get_type (),
- "GnomeCanvasPixbuf::pixbuf", pixbuf,
- NULL);
-
- g_signal_connect (week_view->jump_buttons[i], "event",
- G_CALLBACK (e_week_view_on_jump_button_event), week_view);
- }
- week_view->focused_jump_button = E_WEEK_VIEW_JUMP_BUTTON_NO_FOCUS;
-
- g_object_unref (pixbuf);
-
- /*
- * Scrollbar.
- */
- adjustment = gtk_adjustment_new (0, -52, 52, 1, 1, 1);
-
- week_view->vscrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (adjustment));
- gtk_table_attach (GTK_TABLE (week_view), week_view->vscrollbar,
- 2, 3, 1, 2, 0, GTK_EXPAND | GTK_FILL, 0, 0);
- gtk_widget_show (week_view->vscrollbar);
-
- /* Create the cursors. */
- week_view->normal_cursor = gdk_cursor_new (GDK_LEFT_PTR);
- week_view->move_cursor = gdk_cursor_new (GDK_FLEUR);
- week_view->resize_width_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
- week_view->last_cursor_set = NULL;
-
- /* connect to ECalendarView's signals */
- g_signal_connect (G_OBJECT (week_view), "timezone_changed",
- G_CALLBACK (timezone_changed_cb), NULL);
-}
-
-static void
init_model (EWeekView *week_view, ECalModel *model)
{
/* connect to ECalModel's signals */
@@ -650,14 +839,15 @@ init_model (EWeekView *week_view, ECalModel *model)
*
* Creates a new #EWeekView.
**/
-GtkWidget *
+ECalendarView *
e_week_view_new (ECalModel *model)
{
- GtkWidget *week_view;
+ ECalendarView *week_view;
- week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), NULL));
- e_calendar_view_set_model ((ECalendarView *) week_view, model);
- init_model ((EWeekView *) week_view, model);
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
+
+ week_view = g_object_new (E_TYPE_WEEK_VIEW, "model", model, NULL);
+ init_model (E_WEEK_VIEW (week_view), model);
return week_view;
}
@@ -1796,7 +1986,7 @@ e_week_view_set_weeks_shown (EWeekView *week_view,
}
gboolean
-e_week_view_get_compress_weekend (EWeekView *week_view)
+e_week_view_get_compress_weekend (EWeekView *week_view)
{
g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE);
@@ -1804,17 +1994,17 @@ e_week_view_get_compress_weekend (EWeekView *week_view)
}
void
-e_week_view_set_compress_weekend (EWeekView *week_view,
- gboolean compress)
+e_week_view_set_compress_weekend (EWeekView *week_view,
+ gboolean compress_weekend)
{
gboolean need_reload = FALSE;
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
- if (week_view->compress_weekend == compress)
+ if (week_view->compress_weekend == compress_weekend)
return;
- week_view->compress_weekend = compress;
+ week_view->compress_weekend = compress_weekend;
/* The option only affects the month view. */
if (!week_view->multi_week_view)
@@ -1838,11 +2028,13 @@ e_week_view_set_compress_weekend (EWeekView *week_view,
gtk_widget_queue_draw (week_view->titles_canvas);
gtk_widget_queue_draw (week_view->main_canvas);
+
+ g_object_notify (G_OBJECT (week_view), "compress-weekend");
}
/* Whether we display event end times. */
gboolean
-e_week_view_get_show_event_end_times (EWeekView *week_view)
+e_week_view_get_show_event_end_times (EWeekView *week_view)
{
g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), TRUE);
@@ -1850,61 +2042,36 @@ e_week_view_get_show_event_end_times (EWeekView *week_view)
}
void
-e_week_view_set_show_event_end_times (EWeekView *week_view,
- gboolean show)
+e_week_view_set_show_event_end_times (EWeekView *week_view,
+ gboolean show_event_end_times)
{
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
- if (week_view->show_event_end_times != show) {
- week_view->show_event_end_times = show;
- e_week_view_recalc_cell_sizes (week_view);
- week_view->events_need_reshape = TRUE;
- e_week_view_check_layout (week_view);
- }
-}
-
-/* The first day of the week, 0 (Monday) to 6 (Sunday). */
-gint
-e_week_view_get_week_start_day (EWeekView *week_view)
-{
- g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), 0);
-
- return week_view->week_start_day;
-}
-
-void
-e_week_view_set_week_start_day (EWeekView *week_view,
- gint week_start_day)
-{
- g_return_if_fail (E_IS_WEEK_VIEW (week_view));
- g_return_if_fail (week_start_day >= 0);
- g_return_if_fail (week_start_day < 7);
-
- if (week_view->week_start_day == week_start_day)
+ if (week_view->show_event_end_times != show_event_end_times)
return;
- week_view->week_start_day = week_start_day;
-
- e_week_view_recalc_display_start_day (week_view);
-
- /* Recalculate the days shown and reload if necessary. */
- if (g_date_valid (&week_view->first_day_shown))
- e_week_view_set_first_day_shown (week_view,
- &week_view->first_day_shown);
+ week_view->show_event_end_times = show_event_end_times;
+ e_week_view_recalc_cell_sizes (week_view);
+ week_view->events_need_reshape = TRUE;
+ e_week_view_check_layout (week_view);
- gtk_widget_queue_draw (week_view->titles_canvas);
- gtk_widget_queue_draw (week_view->main_canvas);
+ g_object_notify (G_OBJECT (week_view), "show-event-end-times");
}
static gboolean
e_week_view_recalc_display_start_day (EWeekView *week_view)
{
+ ECalModel *model;
+ gint week_start_day;
gint display_start_day;
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+ week_start_day = e_cal_model_get_week_start_day (model);
+
/* The display start day defaults to week_start_day, but we have
to use Saturday if the weekend is compressed and week_start_day
is Sunday. */
- display_start_day = week_view->week_start_day;
+ display_start_day = week_start_day;
if (display_start_day == 6
&& (!week_view->multi_week_view || week_view->compress_weekend))
@@ -1940,6 +2107,9 @@ set_text_as_bold (EWeekViewEvent *event, EWeekViewEventSpan *span)
break;
}
}
+ e_cal_component_free_attendee_list (attendees);
+ g_free (address);
+ g_object_unref (comp);
/* The attendee has not yet accepted the meeting, display the summary as bolded.
If the attendee is not present, it might have come through a mailing list.
@@ -3426,7 +3596,7 @@ e_week_view_get_day_offset_of_event (EWeekView *week_view, time_t event_time)
return (event_time - first_day) / (24 * 60 * 60);
}
-static void
+void
e_week_view_scroll_a_step (EWeekView *week_view, ECalViewMoveDirection direction)
{
GtkAdjustment *adj = GTK_RANGE (week_view->vscrollbar)->adjustment;
@@ -3627,7 +3797,8 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
if (!e_cal_create_object (client, icalcomp, NULL, NULL))
g_message (G_STRLOC ": Could not create the object!");
else
- gnome_calendar_emit_user_created_signal (week_view, e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)), client);
+ e_calendar_view_emit_user_created (
+ E_CALENDAR_VIEW (week_view));
/* we remove the object since we either got the update from the server or failed */
e_week_view_remove_event_cb (week_view, event_num, NULL);
@@ -3817,227 +3988,48 @@ e_week_view_is_one_day_event (EWeekView *week_view,
return FALSE;
}
-static gint map_left[] = {0, 1, 2, 0, 1, 2, 2};
-static gint map_right[] = {3, 4, 5, 3, 4, 5, 6};
-
static void
-e_week_view_do_cursor_key_up (EWeekView *week_view)
+e_week_view_cursor_key_up (EWeekView *week_view)
{
- if (week_view->selection_start_day == -1)
- return;
-
- week_view->selection_start_day--;
+ EWeekViewClass *week_view_class;
- if (week_view->selection_start_day < 0) {
- e_week_view_scroll_a_step (week_view, E_CAL_VIEW_MOVE_UP);
- week_view->selection_start_day = 6;
- }
+ week_view_class = E_WEEK_VIEW_GET_CLASS (week_view);
+ g_return_if_fail (week_view_class->cursor_key_up != NULL);
- week_view->selection_end_day = week_view->selection_start_day;
- g_signal_emit_by_name (week_view, "selected_time_changed");
- gtk_widget_queue_draw (week_view->main_canvas);
+ week_view_class->cursor_key_up (week_view);
}
static void
-e_week_view_do_cursor_key_down (EWeekView *week_view)
+e_week_view_cursor_key_down (EWeekView *week_view)
{
- if (week_view->selection_start_day == -1)
- return;
-
- week_view->selection_start_day++;
+ EWeekViewClass *week_view_class;
- if (week_view->selection_start_day > 6) {
- e_week_view_scroll_a_step (week_view, E_CAL_VIEW_MOVE_DOWN);
- week_view->selection_start_day = 0;
- }
+ week_view_class = E_WEEK_VIEW_GET_CLASS (week_view);
+ g_return_if_fail (week_view_class->cursor_key_down != NULL);
- week_view->selection_end_day = week_view->selection_start_day;
- g_signal_emit_by_name (week_view, "selected_time_changed");
- gtk_widget_queue_draw (week_view->main_canvas);
+ week_view_class->cursor_key_down (week_view);
}
static void
-e_week_view_do_cursor_key_left (EWeekView *week_view)
+e_week_view_cursor_key_left (EWeekView *week_view)
{
- if (week_view->selection_start_day == -1)
- return;
-
- week_view->selection_start_day = map_left[week_view->selection_start_day];
- week_view->selection_end_day = week_view->selection_start_day;
- g_signal_emit_by_name (week_view, "selected_time_changed");
- gtk_widget_queue_draw (week_view->main_canvas);
-}
+ EWeekViewClass *week_view_class;
-static void
-e_week_view_do_cursor_key_right (EWeekView *week_view)
-{
- if (week_view->selection_start_day == -1)
- return;
+ week_view_class = E_WEEK_VIEW_GET_CLASS (week_view);
+ g_return_if_fail (week_view_class->cursor_key_left != NULL);
- week_view->selection_start_day = map_right[week_view->selection_start_day];
- week_view->selection_end_day = week_view->selection_start_day;
- g_signal_emit_by_name (week_view, "selected_time_changed");
- gtk_widget_queue_draw (week_view->main_canvas);
+ week_view_class->cursor_key_left (week_view);
}
static void
-e_month_view_do_cursor_key_up (EWeekView *week_view)
+e_week_view_cursor_key_right (EWeekView *week_view)
{
- if (week_view->selection_start_day == -1)
- return;
+ EWeekViewClass *week_view_class;
- if (week_view->selection_start_day < 7) {
- /* no easy way to calculate new selection_start_day, therefore
- * calculate a time_t value and set_selected_time_range */
- time_t current;
- if (e_calendar_view_get_selected_time_range(&week_view->cal_view, &current, NULL)) {
- current = time_add_week(current,-1);
- e_week_view_scroll_a_step(week_view, E_CAL_VIEW_MOVE_PAGE_UP);
- e_week_view_set_selected_time_range_visible(week_view,current,current);
- }
- } else {
- week_view->selection_start_day -= 7;
- week_view->selection_end_day = week_view->selection_start_day;
- }
+ week_view_class = E_WEEK_VIEW_GET_CLASS (week_view);
+ g_return_if_fail (week_view_class->cursor_key_right != NULL);
- g_signal_emit_by_name (week_view, "selected_time_changed");
- gtk_widget_queue_draw (week_view->main_canvas);
-}
-
-static void
-e_month_view_do_cursor_key_down (EWeekView *week_view)
-{
- gint weeks_shown = e_week_view_get_weeks_shown (week_view);
-
- if (week_view->selection_start_day == -1)
- return;
-
- if (week_view->selection_start_day >= (weeks_shown - 1) * 7) {
- /* no easy way to calculate new selection_start_day, therefore
- * calculate a time_t value and set_selected_time_range */
- time_t current;
- if (e_calendar_view_get_selected_time_range(&week_view->cal_view, &current, NULL)) {
- current = time_add_week(current,1);
- e_week_view_scroll_a_step(week_view, E_CAL_VIEW_MOVE_PAGE_DOWN);
- e_week_view_set_selected_time_range_visible(week_view,current,current);
- }
- } else {
- week_view->selection_start_day += 7;
- week_view->selection_end_day = week_view->selection_start_day;
- }
-
- g_signal_emit_by_name (week_view, "selected_time_changed");
- gtk_widget_queue_draw (week_view->main_canvas);
-}
-
-static void
-e_month_view_do_cursor_key_left (EWeekView *week_view)
-{
- if (week_view->selection_start_day == -1)
- return;
-
- if (week_view->selection_start_day == 0) {
- /* no easy way to calculate new selection_start_day, therefore
- * calculate a time_t value and set_selected_time_range */
- time_t current;
- if (e_calendar_view_get_selected_time_range(&week_view->cal_view, &current, NULL)) {
- current = time_add_day(current,-1);
- e_week_view_scroll_a_step(week_view, E_CAL_VIEW_MOVE_PAGE_UP);
- e_week_view_set_selected_time_range_visible(week_view,current,current);
- }
- } else {
- week_view->selection_start_day--;
- week_view->selection_end_day = week_view->selection_start_day;
- }
-
- g_signal_emit_by_name (week_view, "selected_time_changed");
- gtk_widget_queue_draw (week_view->main_canvas);
-}
-
-static void
-e_month_view_do_cursor_key_right (EWeekView *week_view)
-{
- gint weeks_shown = e_week_view_get_weeks_shown (week_view);
-
- if (week_view->selection_start_day == -1)
- return;
-
- if (week_view->selection_start_day == weeks_shown * 7 - 1) {
- /* no easy way to calculate new selection_start_day, therefore
- * calculate a time_t value and set_selected_time_range */
- time_t current;
- if (e_calendar_view_get_selected_time_range(&week_view->cal_view, &current, NULL)) {
- current = time_add_day(current,1);
- e_week_view_scroll_a_step(week_view, E_CAL_VIEW_MOVE_PAGE_DOWN);
- e_week_view_set_selected_time_range_visible(week_view,current,current);
- }
- } else {
- week_view->selection_start_day++;
- week_view->selection_end_day = week_view->selection_start_day;
- }
-
- g_signal_emit_by_name (week_view, "selected_time_changed");
- gtk_widget_queue_draw (week_view->main_canvas);
-}
-
-static void
-e_week_view_cursor_key_up (EWeekView *week_view, GnomeCalendarViewType view_type)
-{
- switch (view_type) {
- case GNOME_CAL_WEEK_VIEW:
- e_week_view_do_cursor_key_up (week_view);
- break;
- case GNOME_CAL_MONTH_VIEW:
- e_month_view_do_cursor_key_up (week_view);
- break;
- default:
- g_return_if_reached ();
- }
-}
-
-static void
-e_week_view_cursor_key_down (EWeekView *week_view, GnomeCalendarViewType view_type)
-{
- switch (view_type) {
- case GNOME_CAL_WEEK_VIEW:
- e_week_view_do_cursor_key_down (week_view);
- break;
- case GNOME_CAL_MONTH_VIEW:
- e_month_view_do_cursor_key_down (week_view);
- break;
- default:
- g_return_if_reached ();
- }
-}
-
-static void
-e_week_view_cursor_key_left (EWeekView *week_view, GnomeCalendarViewType view_type)
-{
- switch (view_type) {
- case GNOME_CAL_WEEK_VIEW:
- e_week_view_do_cursor_key_left (week_view);
- break;
- case GNOME_CAL_MONTH_VIEW:
- e_month_view_do_cursor_key_left (week_view);
- break;
- default:
- g_return_if_reached ();
- }
-}
-
-static void
-e_week_view_cursor_key_right (EWeekView *week_view, GnomeCalendarViewType view_type)
-{
- switch (view_type) {
- case GNOME_CAL_WEEK_VIEW:
- e_week_view_do_cursor_key_right (week_view);
- break;
- case GNOME_CAL_MONTH_VIEW:
- e_month_view_do_cursor_key_right (week_view);
- break;
- default:
- g_return_if_reached ();
- }
+ week_view_class->cursor_key_right (week_view);
}
static gboolean
@@ -4138,7 +4130,6 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
guint keyval;
gboolean stop_emission;
gboolean ret_val;
- GnomeCalendarViewType view_type;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (E_IS_WEEK_VIEW (widget), FALSE);
@@ -4158,7 +4149,6 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
#endif
/* Handle the cursor keys for moving the selection */
- view_type = gnome_calendar_get_view (e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)));
stop_emission = FALSE;
if (!(event->state & GDK_SHIFT_MASK)
&& !(event->state & GDK_MOD1_MASK)) {
@@ -4177,16 +4167,16 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
e_week_view_scroll_a_step (week_view, E_CAL_VIEW_MOVE_PAGE_DOWN);
break;
case GDK_Up:
- e_week_view_cursor_key_up (week_view, view_type);
+ e_week_view_cursor_key_up (week_view);
break;
case GDK_Down:
- e_week_view_cursor_key_down (week_view, view_type);
+ e_week_view_cursor_key_down (week_view);
break;
case GDK_Left:
- e_week_view_cursor_key_left (week_view, view_type);
+ e_week_view_cursor_key_left (week_view);
break;
case GDK_Right:
- e_week_view_cursor_key_right (week_view, view_type);
+ e_week_view_cursor_key_right (week_view);
break;
default:
stop_emission = FALSE;
@@ -4275,26 +4265,14 @@ e_week_view_key_press (GtkWidget *widget, GdkEventKey *event)
return handled;
}
-static void
-popup_destroyed_cb (gpointer data, GObject *where_object_was)
-{
- EWeekView *week_view = data;
-
- week_view->popup_event_num = -1;
-}
-
void
e_week_view_show_popup_menu (EWeekView *week_view,
GdkEventButton *bevent,
gint event_num)
{
- GtkMenu *popup;
-
week_view->popup_event_num = event_num;
- popup = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (week_view));
- g_object_weak_ref (G_OBJECT (popup), popup_destroyed_cb, week_view);
- gtk_menu_popup (popup, NULL, NULL, NULL, NULL, bevent?bevent->button:0, bevent?bevent->time:gtk_get_current_event_time());
+ e_calendar_view_popup_event (E_CALENDAR_VIEW (week_view), bevent);
}
static gboolean
@@ -4391,10 +4369,14 @@ e_week_view_convert_time_to_display (EWeekView *week_view,
const gchar **suffix,
gint *suffix_width)
{
+ ECalModel *model;
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+
/* Calculate the actual hour number to display. For 12-hour
format we convert 0-23 to 12-11am/12-11pm. */
*display_hour = hour;
- if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (week_view))) {
+ if (e_cal_model_get_use_24_hour_format (model)) {
*suffix = "";
*suffix_width = 0;
} else {
@@ -4416,8 +4398,11 @@ e_week_view_convert_time_to_display (EWeekView *week_view,
gint
e_week_view_get_time_string_width (EWeekView *week_view)
{
+ ECalModel *model;
gint time_width;
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+
if (week_view->use_small_font && week_view->small_font_desc)
time_width = week_view->digit_width * 2
+ week_view->small_digit_width * 2;
@@ -4425,7 +4410,7 @@ e_week_view_get_time_string_width (EWeekView *week_view)
time_width = week_view->digit_width * 4
+ week_view->colon_width;
- if (!e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (week_view)))
+ if (!e_cal_model_get_use_24_hour_format (model))
time_width += MAX (week_view->am_string_width,
week_view->pm_string_width);
diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h
index b536e5d5a3..0712e1ac6f 100644
--- a/calendar/gui/e-week-view.h
+++ b/calendar/gui/e-week-view.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef _E_WEEK_VIEW_H_
-#define _E_WEEK_VIEW_H_
+#ifndef E_WEEK_VIEW_H
+#define E_WEEK_VIEW_H
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas.h>
@@ -29,12 +29,29 @@
#include "e-calendar-view.h"
#include "gnome-cal.h"
-G_BEGIN_DECLS
-
/*
* EWeekView - displays the Week & Month views of the calendar.
*/
+/* Standard GObject macros */
+#define E_TYPE_WEEK_VIEW \
+ (e_week_view_get_type ())
+#define E_WEEK_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_WEEK_VIEW, EWeekView))
+#define E_WEEK_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_WEEK_VIEW, EWeekViewClass))
+#define E_IS_WEEK_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_WEEK_VIEW))
+#define E_IS_WEEK_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_WEEK_VIEW))
+#define E_WEEK_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_WEEK_VIEW, EWeekViewClass))
+
/* The maximum number of weeks we show. 5 is usually enough for 1 month,
but we allow 6 for longer selections. */
#define E_WEEK_VIEW_MAX_WEEKS 6
@@ -91,6 +108,8 @@ G_BEGIN_DECLS
reached anyway. */
#define E_WEEK_VIEW_MAX_ROWS_PER_CELL 127
+G_BEGIN_DECLS
+
/* These index our colors array. */
typedef enum
{
@@ -147,16 +166,11 @@ struct _EWeekViewEvent {
guint8 num_spans;
};
-#define E_WEEK_VIEW(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_week_view_get_type (), EWeekView)
-#define E_WEEK_VIEW_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_week_view_get_type (), EWeekViewClass)
-#define E_IS_WEEK_VIEW(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_week_view_get_type ())
-
-typedef struct _EWeekView EWeekView;
-typedef struct _EWeekViewClass EWeekViewClass;
+typedef struct _EWeekView EWeekView;
+typedef struct _EWeekViewClass EWeekViewClass;
-struct _EWeekView
-{
- ECalendarView cal_view;
+struct _EWeekView {
+ ECalendarView parent;
/* The top canvas where the dates are shown. */
GtkWidget *titles_canvas;
@@ -342,110 +356,120 @@ struct _EWeekView
time_t before_click_dtend;
};
-struct _EWeekViewClass
-{
+struct _EWeekViewClass {
ECalendarViewClass parent_class;
+
+ void (*cursor_key_up) (EWeekView *week_view);
+ void (*cursor_key_down) (EWeekView *week_view);
+ void (*cursor_key_left) (EWeekView *week_view);
+ void (*cursor_key_right) (EWeekView *week_view);
};
-GType e_week_view_get_type (void);
-GtkWidget* e_week_view_new (ECalModel *model);
+GType e_week_view_get_type (void);
+ECalendarView * e_week_view_new (ECalModel *model);
/* The first day shown. Note that it will be rounded down to the start of a
week when set. The returned value will be invalid if no date has been set
yet. */
-void e_week_view_get_first_day_shown (EWeekView *week_view,
- GDate *date);
-void e_week_view_set_first_day_shown (EWeekView *week_view,
- GDate *date);
+void e_week_view_get_first_day_shown (EWeekView *week_view,
+ GDate *date);
+void e_week_view_set_first_day_shown (EWeekView *week_view,
+ GDate *date);
/* The selected time range. The EWeekView will show the corresponding
month and the days between start_time and end_time will be selected.
To select a single day, use the same value for start_time & end_time. */
-void e_week_view_set_selected_time_range_visible (EWeekView *week_view,
- time_t start_time,
- time_t end_time);
+void e_week_view_set_selected_time_range_visible
+ (EWeekView *week_view,
+ time_t start_time,
+ time_t end_time);
/* Whether to display 1 week or 1 month (5 weeks). It defaults to 1 week. */
-gboolean e_week_view_get_multi_week_view (EWeekView *week_view);
-void e_week_view_set_multi_week_view (EWeekView *week_view,
- gboolean multi_week_view);
+gboolean e_week_view_get_multi_week_view (EWeekView *week_view);
+void e_week_view_set_multi_week_view (EWeekView *week_view,
+ gboolean multi_week_view);
/* Whether to update the base date when the time range changes */
-gboolean e_week_view_get_update_base_date (EWeekView *week_view);
-void e_week_view_set_update_base_date (EWeekView *week_view, gboolean update_base_date);
+gboolean e_week_view_get_update_base_date(EWeekView *week_view);
+void e_week_view_set_update_base_date(EWeekView *week_view,
+ gboolean update_base_date);
/* The number of weeks shown in the multi-week view. */
-gint e_week_view_get_weeks_shown (EWeekView *week_view);
-void e_week_view_set_weeks_shown (EWeekView *week_view,
- gint weeks_shown);
+gint e_week_view_get_weeks_shown (EWeekView *week_view);
+void e_week_view_set_weeks_shown (EWeekView *week_view,
+ gint weeks_shown);
/* Whether the weekend (Sat/Sun) should be compressed into 1 cell in the Month
view. In the Week view they are always compressed. */
-gboolean e_week_view_get_compress_weekend (EWeekView *week_view);
-void e_week_view_set_compress_weekend (EWeekView *week_view,
- gboolean compress);
+gboolean e_week_view_get_compress_weekend(EWeekView *week_view);
+void e_week_view_set_compress_weekend(EWeekView *week_view,
+ gboolean compress_weekend);
/* Whether we display event end times. */
-gboolean e_week_view_get_show_event_end_times (EWeekView *week_view);
-void e_week_view_set_show_event_end_times (EWeekView *week_view,
- gboolean show);
+gboolean e_week_view_get_show_event_end_times
+ (EWeekView *week_view);
+void e_week_view_set_show_event_end_times
+ (EWeekView *week_view,
+ gboolean show_event_end_times);
-/* The first day of the week, 0 (Monday) to 6 (Sunday). */
-gint e_week_view_get_week_start_day (EWeekView *week_view);
-void e_week_view_set_week_start_day (EWeekView *week_view,
- gint week_start_day);
-
-void e_week_view_delete_occurrence (EWeekView *week_view);
+void e_week_view_delete_occurrence (EWeekView *week_view);
/* Returns the number of selected events (0 or 1 at present). */
-gint e_week_view_get_num_events_selected (EWeekView *week_view);
+gint e_week_view_get_num_events_selected
+ (EWeekView *week_view);
/*
* Internal functions called by the associated canvas items.
*/
-void e_week_view_get_day_position (EWeekView *week_view,
- gint day,
- gint *day_x,
- gint *day_y,
- gint *day_w,
- gint *day_h);
-gboolean e_week_view_get_span_position (EWeekView *week_view,
- gint event_num,
- gint span_num,
- gint *span_x,
- gint *span_y,
- gint *span_w);
-gboolean e_week_view_is_one_day_event (EWeekView *week_view,
- gint event_num);
-gboolean e_week_view_start_editing_event (EWeekView *week_view,
- gint event_num,
- gint span_num,
- gchar *initial_text);
-void e_week_view_stop_editing_event (EWeekView *week_view);
-
-void e_week_view_show_popup_menu (EWeekView *week_view,
+void e_week_view_get_day_position (EWeekView *week_view,
+ gint day,
+ gint *day_x,
+ gint *day_y,
+ gint *day_w,
+ gint *day_h);
+gboolean e_week_view_get_span_position (EWeekView *week_view,
+ gint event_num,
+ gint span_num,
+ gint *span_x,
+ gint *span_y,
+ gint *span_w);
+gboolean e_week_view_is_one_day_event (EWeekView *week_view,
+ gint event_num);
+gboolean e_week_view_start_editing_event (EWeekView *week_view,
+ gint event_num,
+ gint span_num,
+ gchar *initial_text);
+void e_week_view_stop_editing_event (EWeekView *week_view);
+
+void e_week_view_show_popup_menu (EWeekView *week_view,
GdkEventButton *event,
- gint event_num);
-
-void e_week_view_convert_time_to_display (EWeekView *week_view,
- gint hour,
- gint *display_hour,
- const gchar **suffix,
- gint *suffix_width);
-gint e_week_view_get_time_string_width (EWeekView *week_view);
-
-gint e_week_view_event_sort_func (const void *arg1,
- const void *arg2);
-
-gboolean e_week_view_find_event_from_item (EWeekView *week_view,
- GnomeCanvasItem *item,
- gint *event_num_return,
- gint *span_num_return);
-
-gboolean e_week_view_is_jump_button_visible (EWeekView *week_view,
- gint day);
-void e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item);
+ gint event_num);
+
+void e_week_view_convert_time_to_display
+ (EWeekView *week_view,
+ gint hour,
+ gint *display_hour,
+ const gchar **suffix,
+ gint *suffix_width);
+gint e_week_view_get_time_string_width
+ (EWeekView *week_view);
+
+gint e_week_view_event_sort_func (gconstpointer arg1,
+ gconstpointer arg2);
+
+gboolean e_week_view_find_event_from_item (EWeekView *week_view,
+ GnomeCanvasItem *item,
+ gint *event_num_return,
+ gint *span_num_return);
+
+gboolean e_week_view_is_jump_button_visible
+ (EWeekView *week_view,
+ gint day);
+void e_week_view_jump_to_button_item (EWeekView *week_view,
+ GnomeCanvasItem *item);
+void e_week_view_scroll_a_step (EWeekView *week_view,
+ ECalViewMoveDirection direction);
G_END_DECLS
-#endif /* _E_WEEK_VIEW_H_ */
+#endif /* E_WEEK_VIEW_H */
diff --git a/a11y/calendar/ea-cal-view-event.c b/calendar/gui/ea-cal-view-event.c
index 5f0af90261..5f0af90261 100644
--- a/a11y/calendar/ea-cal-view-event.c
+++ b/calendar/gui/ea-cal-view-event.c
diff --git a/a11y/calendar/ea-cal-view-event.h b/calendar/gui/ea-cal-view-event.h
index b4b193de2d..b4b193de2d 100644
--- a/a11y/calendar/ea-cal-view-event.h
+++ b/calendar/gui/ea-cal-view-event.h
diff --git a/a11y/calendar/ea-cal-view.c b/calendar/gui/ea-cal-view.c
index 952afcc791..bca4710260 100644
--- a/a11y/calendar/ea-cal-view.c
+++ b/calendar/gui/ea-cal-view.c
@@ -24,7 +24,6 @@
#include "ea-calendar-helpers.h"
#include "e-day-view.h"
#include "e-week-view.h"
-#include "calendar-commands.h"
#include "goto.h"
#include <glib.h>
#include <glib/gi18n.h>
@@ -353,6 +352,7 @@ action_interface_do_action (AtkAction *action, gint index)
e_calendar_view_new_appointment_for (cal_view,
dtstart, dtend, FALSE, TRUE);
break;
+#if 0 /* FIXME Have to go through GnomeCalendar */
case 3:
/* Go to today */
break;
@@ -361,6 +361,7 @@ action_interface_do_action (AtkAction *action, gint index)
/* Go to date */
goto_dialog (e_calendar_view_get_calendar (cal_view));
break;
+#endif
default:
return_value = FALSE;
break;
diff --git a/a11y/calendar/ea-cal-view.h b/calendar/gui/ea-cal-view.h
index 959f7816b5..959f7816b5 100644
--- a/a11y/calendar/ea-cal-view.h
+++ b/calendar/gui/ea-cal-view.h
diff --git a/a11y/calendar/ea-calendar-helpers.c b/calendar/gui/ea-calendar-helpers.c
index f07cdfa086..f07cdfa086 100644
--- a/a11y/calendar/ea-calendar-helpers.c
+++ b/calendar/gui/ea-calendar-helpers.c
diff --git a/a11y/calendar/ea-calendar-helpers.h b/calendar/gui/ea-calendar-helpers.h
index a4045cd7af..a4045cd7af 100644
--- a/a11y/calendar/ea-calendar-helpers.h
+++ b/calendar/gui/ea-calendar-helpers.h
diff --git a/a11y/calendar/ea-calendar.c b/calendar/gui/ea-calendar.c
index 0dfb5e5067..dcdf8bd650 100644
--- a/a11y/calendar/ea-calendar.c
+++ b/calendar/gui/ea-calendar.c
@@ -23,16 +23,16 @@
#include <text/e-text.h>
#include <libgnomecanvas/gnome-canvas-pixbuf.h>
#include "ea-calendar-helpers.h"
-#include "ea-factory.h"
+#include "a11y/ea-factory.h"
#include "ea-calendar.h"
-#include "calendar/ea-cal-view.h"
-#include "calendar/ea-cal-view-event.h"
-#include "calendar/ea-day-view.h"
-#include "calendar/ea-day-view-main-item.h"
-#include "calendar/ea-week-view.h"
-#include "calendar/ea-week-view-main-item.h"
-#include "calendar/ea-gnome-calendar.h"
+#include "calendar/gui/ea-cal-view.h"
+#include "calendar/gui/ea-cal-view-event.h"
+#include "calendar/gui/ea-day-view.h"
+#include "calendar/gui/ea-day-view-main-item.h"
+#include "calendar/gui/ea-week-view.h"
+#include "calendar/gui/ea-week-view-main-item.h"
+#include "calendar/gui/ea-gnome-calendar.h"
EA_FACTORY (EA_TYPE_CAL_VIEW, ea_cal_view, ea_cal_view_new)
EA_FACTORY (EA_TYPE_DAY_VIEW, ea_day_view, ea_day_view_new)
@@ -61,7 +61,7 @@ gnome_calendar_a11y_init (void)
e_text_type = g_type_class_ref (E_TYPE_TEXT);
pixbuf_type = g_type_class_ref (GNOME_TYPE_CANVAS_PIXBUF);
e_day_view_type = g_type_class_ref (e_day_view_get_type ());
- e_week_view_type = g_type_class_ref (e_week_view_get_type ());
+ e_week_view_type = g_type_class_ref (E_TYPE_WEEK_VIEW);
e_day_view_main_item_type = g_type_class_ref (e_day_view_main_item_get_type ());
e_week_view_main_item_type = g_type_class_ref (e_week_view_main_item_get_type ());
@@ -80,7 +80,7 @@ gnome_calendar_a11y_init (void)
0, ea_calendar_focus_watcher,
NULL, (GDestroyNotify) NULL);
g_signal_add_emission_hook (g_signal_lookup ("event-after",
- e_week_view_get_type()),
+ E_TYPE_WEEK_VIEW),
0, ea_calendar_focus_watcher,
NULL, (GDestroyNotify) NULL);
g_signal_add_emission_hook (g_signal_lookup ("event",
@@ -112,7 +112,7 @@ e_day_view_main_item_a11y_init (void)
void
e_week_view_a11y_init (void)
{
- EA_SET_FACTORY (e_week_view_get_type(), ea_week_view);
+ EA_SET_FACTORY (E_TYPE_WEEK_VIEW, ea_week_view);
}
void
diff --git a/a11y/calendar/ea-calendar.h b/calendar/gui/ea-calendar.h
index b2238ffdbc..b2238ffdbc 100644
--- a/a11y/calendar/ea-calendar.h
+++ b/calendar/gui/ea-calendar.h
diff --git a/a11y/calendar/ea-day-view-cell.c b/calendar/gui/ea-day-view-cell.c
index ffc059b87d..2d42a47fc6 100644
--- a/a11y/calendar/ea-day-view-cell.c
+++ b/calendar/gui/ea-day-view-cell.c
@@ -24,7 +24,7 @@
#include "ea-day-view-cell.h"
#include "ea-day-view-main-item.h"
#include "ea-day-view.h"
-#include "ea-factory.h"
+#include "a11y/ea-factory.h"
/* EDayViewCell */
diff --git a/a11y/calendar/ea-day-view-cell.h b/calendar/gui/ea-day-view-cell.h
index 669fb1abae..669fb1abae 100644
--- a/a11y/calendar/ea-day-view-cell.h
+++ b/calendar/gui/ea-day-view-cell.h
diff --git a/a11y/calendar/ea-day-view-main-item.c b/calendar/gui/ea-day-view-main-item.c
index 89b6f1a57b..89b6f1a57b 100644
--- a/a11y/calendar/ea-day-view-main-item.c
+++ b/calendar/gui/ea-day-view-main-item.c
diff --git a/a11y/calendar/ea-day-view-main-item.h b/calendar/gui/ea-day-view-main-item.h
index c782e6acc8..c782e6acc8 100644
--- a/a11y/calendar/ea-day-view-main-item.h
+++ b/calendar/gui/ea-day-view-main-item.h
diff --git a/a11y/calendar/ea-day-view.c b/calendar/gui/ea-day-view.c
index 9eb3e343f3..1e6842905f 100644
--- a/a11y/calendar/ea-day-view.c
+++ b/calendar/gui/ea-day-view.c
@@ -25,7 +25,6 @@
#include "ea-calendar-helpers.h"
#include "ea-gnome-calendar.h"
-#include "calendar-commands.h"
#include <glib.h>
#include <glib/gi18n.h>
diff --git a/a11y/calendar/ea-day-view.h b/calendar/gui/ea-day-view.h
index 33399f6600..33399f6600 100644
--- a/a11y/calendar/ea-day-view.h
+++ b/calendar/gui/ea-day-view.h
diff --git a/a11y/calendar/ea-gnome-calendar.c b/calendar/gui/ea-gnome-calendar.c
index e5d9654c1a..58ecad70fd 100644
--- a/a11y/calendar/ea-gnome-calendar.c
+++ b/calendar/gui/ea-gnome-calendar.c
@@ -22,7 +22,7 @@
*/
#include "ea-gnome-calendar.h"
-#include "calendar-commands.h"
+#include "e-calendar-view.h"
#include <string.h>
#include <gtk/gtk.h>
#include <libecal/e-cal-time-util.h>
@@ -36,8 +36,6 @@ static G_CONST_RETURN gchar * ea_gnome_calendar_get_description (AtkObject *acce
static gint ea_gnome_calendar_get_n_children (AtkObject* obj);
static AtkObject * ea_gnome_calendar_ref_child (AtkObject *obj, gint i);
-static void ea_gcal_switch_view_cb (GtkNotebook *widget, GtkNotebookPage *page,
- guint index, gpointer data);
static void ea_gcal_dates_change_cb (GnomeCalendar *gcal, gpointer data);
static gpointer parent_class = NULL;
@@ -104,7 +102,6 @@ ea_gnome_calendar_new (GtkWidget *widget)
GObject *object;
AtkObject *accessible;
GnomeCalendar *gcal;
- GtkWidget *notebook;
g_return_val_if_fail (GNOME_IS_CALENDAR (widget), NULL);
@@ -122,12 +119,6 @@ ea_gnome_calendar_new (GtkWidget *widget)
g_signal_connect (widget, "dates_shown_changed",
G_CALLBACK (ea_gcal_dates_change_cb),
accessible);
- notebook = gnome_calendar_get_view_notebook_widget (gcal);
- if (notebook) {
- g_signal_connect (notebook, "switch_page",
- G_CALLBACK (ea_gcal_switch_view_cb),
- accessible);
- }
#ifdef ACC_DEBUG
printf ("EvoAcc: ea-gnome-calendar created: %p\n", (gpointer)accessible);
@@ -139,6 +130,9 @@ ea_gnome_calendar_new (GtkWidget *widget)
const gchar *
ea_gnome_calendar_get_label_description (GnomeCalendar *gcal)
{
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ ECalModel *model;
icaltimezone *zone;
struct icaltimetype start_tt, end_tt;
time_t start_time, end_time;
@@ -147,8 +141,14 @@ ea_gnome_calendar_get_label_description (GnomeCalendar *gcal)
gchar end_buffer[256];
GnomeCalendarViewType view;
- gnome_calendar_get_visible_time_range (gcal, &start_time, &end_time);
- zone = gnome_calendar_get_timezone (gcal);
+ model = gnome_calendar_get_model (gcal);
+ zone = e_cal_model_get_timezone (model);
+
+ view_type = gnome_calendar_get_view (gcal);
+ calendar_view = gnome_calendar_get_calendar_view (gcal, view_type);
+
+ e_calendar_view_get_visible_time_range (
+ calendar_view, &start_time, &end_time);
start_tt = icaltime_from_timet_with_zone (start_time, FALSE, zone);
start_tm.tm_year = start_tt.year - 1900;
@@ -260,7 +260,7 @@ ea_gnome_calendar_get_n_children (AtkObject* obj)
if (!GTK_ACCESSIBLE (obj)->widget)
return -1;
- return 4;
+ return 2;
}
static AtkObject *
@@ -268,6 +268,9 @@ ea_gnome_calendar_ref_child (AtkObject *obj, gint i)
{
AtkObject * child = NULL;
GnomeCalendar * calendarWidget;
+ GnomeCalendarViewType view_type;
+ ECalendarView *view;
+ ECalendar *date_navigator;
GtkWidget *childWidget;
g_return_val_if_fail (EA_IS_GNOME_CALENDAR (obj), NULL);
@@ -281,27 +284,17 @@ ea_gnome_calendar_ref_child (AtkObject *obj, gint i)
switch (i) {
case 0:
- /* for the search bar */
- childWidget = gnome_calendar_get_search_bar_widget (calendarWidget);
- child = gtk_widget_get_accessible (childWidget);
- atk_object_set_parent (child, obj);
- atk_object_set_name (child, _("search bar"));
- atk_object_set_description (child, _("evolution calendar search bar"));
- break;
- case 1:
/* for the day/week view */
- childWidget = gnome_calendar_get_current_view_widget (calendarWidget);
+ view_type = gnome_calendar_get_view (calendarWidget);
+ view = gnome_calendar_get_calendar_view (calendarWidget, view_type);
+ childWidget = GTK_WIDGET (view);
child = gtk_widget_get_accessible (childWidget);
atk_object_set_parent (child, obj);
break;
- case 2:
+ case 1:
/* for calendar */
- childWidget = gnome_calendar_get_e_calendar_widget (calendarWidget);
- child = gtk_widget_get_accessible (childWidget);
- break;
- case 3:
- /* for todo list */
- childWidget = GTK_WIDGET (gnome_calendar_get_task_pad (calendarWidget));
+ date_navigator = gnome_calendar_get_date_navigator (calendarWidget);
+ childWidget = GTK_WIDGET (date_navigator);
child = gtk_widget_get_accessible (childWidget);
break;
default:
@@ -313,26 +306,6 @@ ea_gnome_calendar_ref_child (AtkObject *obj, gint i)
}
static void
-ea_gcal_switch_view_cb (GtkNotebook *widget, GtkNotebookPage *page,
- guint index, gpointer data)
-{
- GtkWidget *new_widget;
-
- new_widget = gtk_notebook_get_nth_page (widget, index);
-
- /* views are always the second child in gnome calendar
- */
- if (new_widget)
- g_signal_emit_by_name (G_OBJECT(data), "children_changed::add",
- 1, gtk_widget_get_accessible (new_widget), NULL);
-
-#ifdef ACC_DEBUG
- printf ("AccDebug: view switch to widget %p (index=%d) \n",
- (gpointer)new_widget, index);
-#endif
-}
-
-static void
ea_gcal_dates_change_cb (GnomeCalendar *gcal, gpointer data)
{
const gchar *new_name;
diff --git a/a11y/calendar/ea-gnome-calendar.h b/calendar/gui/ea-gnome-calendar.h
index db9acdb47e..db9acdb47e 100644
--- a/a11y/calendar/ea-gnome-calendar.h
+++ b/calendar/gui/ea-gnome-calendar.h
diff --git a/a11y/calendar/ea-jump-button.c b/calendar/gui/ea-jump-button.c
index a6775ade55..a6775ade55 100644
--- a/a11y/calendar/ea-jump-button.c
+++ b/calendar/gui/ea-jump-button.c
diff --git a/a11y/calendar/ea-jump-button.h b/calendar/gui/ea-jump-button.h
index be0a357a14..be0a357a14 100644
--- a/a11y/calendar/ea-jump-button.h
+++ b/calendar/gui/ea-jump-button.h
diff --git a/a11y/calendar/ea-week-view-cell.c b/calendar/gui/ea-week-view-cell.c
index ce27a20486..e4b28e3d59 100644
--- a/a11y/calendar/ea-week-view-cell.c
+++ b/calendar/gui/ea-week-view-cell.c
@@ -24,7 +24,7 @@
#include "ea-week-view-cell.h"
#include "ea-week-view-main-item.h"
-#include "ea-factory.h"
+#include "a11y/ea-factory.h"
/* EWeekViewCell */
diff --git a/a11y/calendar/ea-week-view-cell.h b/calendar/gui/ea-week-view-cell.h
index 1524e9d3a8..1524e9d3a8 100644
--- a/a11y/calendar/ea-week-view-cell.h
+++ b/calendar/gui/ea-week-view-cell.h
diff --git a/a11y/calendar/ea-week-view-main-item.c b/calendar/gui/ea-week-view-main-item.c
index 3d0bd9e8e8..3d0bd9e8e8 100644
--- a/a11y/calendar/ea-week-view-main-item.c
+++ b/calendar/gui/ea-week-view-main-item.c
diff --git a/a11y/calendar/ea-week-view-main-item.h b/calendar/gui/ea-week-view-main-item.h
index d9110160c4..d9110160c4 100644
--- a/a11y/calendar/ea-week-view-main-item.h
+++ b/calendar/gui/ea-week-view-main-item.h
diff --git a/a11y/calendar/ea-week-view.c b/calendar/gui/ea-week-view.c
index 97a8dae25d..6e9751eb27 100644
--- a/a11y/calendar/ea-week-view.c
+++ b/calendar/gui/ea-week-view.c
@@ -24,7 +24,6 @@
#include "ea-cal-view-event.h"
#include "ea-calendar-helpers.h"
#include "ea-gnome-calendar.h"
-#include "calendar-commands.h"
#include <text/e-text.h>
#include <glib/gi18n.h>
diff --git a/a11y/calendar/ea-week-view.h b/calendar/gui/ea-week-view.h
index 09409ec4cf..09409ec4cf 100644
--- a/a11y/calendar/ea-week-view.h
+++ b/calendar/gui/ea-week-view.h
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 576dfc81d2..defda15875 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -36,42 +36,30 @@
#include <glib.h>
#include <gdk/gdkkeysyms.h>
#include <glib/gi18n.h>
-#include <bonobo/bonobo-exception.h>
#include <libedataserver/e-categories.h>
#include <libedataserver/e-url.h>
#include <libedataserverui/e-passwords.h>
-#include "shell/e-user-creatable-items-handler.h"
#include <libecal/e-cal-time-util.h>
#include <widgets/menus/gal-view-factory-etable.h>
#include <widgets/menus/gal-view-etable.h>
#include <widgets/menus/gal-define-views-dialog.h>
-#include "widgets/menus/gal-view-menus.h"
+#include "e-util/e-binding.h"
#include "e-util/e-util.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
+#include "shell/e-shell.h"
#include "e-comp-editor-registry.h"
#include "dialogs/delete-error.h"
#include "dialogs/event-editor.h"
-#include "dialogs/task-editor.h"
#include "comp-util.h"
#include "e-cal-model-calendar.h"
#include "e-day-view.h"
-#include "e-day-view-config.h"
#include "e-day-view-time-item.h"
+#include "e-month-view.h"
#include "e-week-view.h"
-#include "e-week-view-config.h"
#include "e-cal-list-view.h"
-#include "e-cal-list-view-config.h"
-#include "e-mini-calendar-config.h"
-#include "e-calendar-table-config.h"
-#include "e-memo-table-config.h"
-#include "evolution-calendar.h"
#include "gnome-cal.h"
-#include "calendar-component.h"
-#include "memos-component.h"
-#include "cal-search-bar.h"
-#include "calendar-commands.h"
#include "calendar-config.h"
#include "calendar-view.h"
#include "calendar-view-factory.h"
@@ -79,14 +67,6 @@
#include "misc.h"
#include "ea-calendar.h"
#include "common/authentication.h"
-#include "e-cal-popup.h"
-#include "e-cal-menu.h"
-#include "e-cal-model-tasks.h"
-
-/* FIXME glib 2.4 and above has this */
-#ifndef G_MAXINT32
-#define G_MAXINT32 ((gint32) 0x7fffffff)
-#endif
#define d(x)
@@ -95,11 +75,14 @@ static GHashTable *non_intrusive_error_table = NULL;
/* Private part of the GnomeCalendar structure */
struct _GnomeCalendarPrivate {
- /* The clients for display */
+ EShellSettings *shell_settings;
- GHashTable *clients[E_CAL_SOURCE_TYPE_LAST];
- GList *clients_list[E_CAL_SOURCE_TYPE_LAST];
- ECal *default_client[E_CAL_SOURCE_TYPE_LAST];
+ ECalModel *model;
+
+ /* The clients for display */
+ GHashTable *clients;
+ GList *clients_list;
+ ECal *default_client;
/*
* Fields for the calendar view
@@ -110,33 +93,9 @@ struct _GnomeCalendarPrivate {
/* Widgets */
- GtkWidget *search_bar;
-
GtkWidget *hpane;
- GtkWidget *notebook;
- GtkWidget *vpane;
ECalendar *date_navigator;
- EMiniCalendarConfig *date_navigator_config;
- GtkWidget *todo;
- ECalendarTableConfig *todo_config;
-
- GtkWidget *memo;
- EMemoTableConfig *memo_config;
-
- GtkWidget *day_view;
- GtkWidget *work_week_view;
- GtkWidget *week_view;
- GtkWidget *month_view;
- GtkWidget *list_view;
-
- /* Activity */
- EActivityHandler *activity_handler;
-
- /* plugin menu managers */
- ECalMenu *calendar_menu;
- ECalMenu *taskpad_menu;
- ECalMenu *memopad_menu;
/* Calendar query for the date navigator */
GList *dn_queries; /* list of CalQueries */
@@ -150,7 +109,6 @@ struct _GnomeCalendarPrivate {
positions of the panes. range_selected is TRUE if a range of dates
was selected in the date navigator to show the view. */
ECalendarView *views[GNOME_CAL_LAST_VIEW];
- GObject *configs[GNOME_CAL_LAST_VIEW];
GnomeCalendarViewType current_view_type;
GList *notifications;
@@ -161,22 +119,10 @@ struct _GnomeCalendarPrivate {
will work OK after theme changes. */
gint hpane_pos;
gint hpane_pos_month_view;
- gint vpane_pos;
- gint vpane_pos_month_view;
/* The signal handler id for our GtkCalendar "day_selected" handler. */
guint day_selected_id;
- /* View instance and menus for the control */
- GalViewInstance *view_instance;
- GalViewMenus *view_menus;
-
- /* Our current week start */
- gint week_start;
-
- /* Our current timezone. */
- icaltimezone *zone;
-
/* The dates currently shown. If they are -1 then we have no dates
shown. We only use these to check if we need to emit a
'dates-shown-changed' signal.*/
@@ -188,24 +134,20 @@ struct _GnomeCalendarPrivate {
it uses the date range set in search bar */
gboolean lview_select_daten_range;
- /* We should know which calendar has been used to create object, so store it here
- before emitting "user_created" signal and make it NULL just after the emit. */
- ECal *user_created_cal;
-
/* used in update_todo_view, to prevent interleaving when called in separate thread */
GMutex *todo_update_lock;
};
-/* Signal IDs */
+enum {
+ PROP_0,
+ PROP_DATE_NAVIGATOR,
+ PROP_SHELL_SETTINGS,
+ PROP_VIEW
+};
enum {
DATES_SHOWN_CHANGED,
CALENDAR_SELECTION_CHANGED,
- TASKPAD_SELECTION_CHANGED,
- MEMOPAD_SELECTION_CHANGED,
- CALENDAR_FOCUS_CHANGE,
- TASKPAD_FOCUS_CHANGE,
- MEMOPAD_FOCUS_CHANGE,
GOTO_DATE,
SOURCE_ADDED,
SOURCE_REMOVED,
@@ -213,41 +155,15 @@ enum {
LAST_SIGNAL
};
-/* Used to indicate who has the focus within the calendar view */
-typedef enum {
- FOCUS_CALENDAR,
- FOCUS_TASKPAD,
- FOCUS_MEMOPAD,
- FOCUS_OTHER
-} FocusLocation;
-
-static guint gnome_calendar_signals[LAST_SIGNAL];
-
-
+static guint signals[LAST_SIGNAL];
static void gnome_calendar_destroy (GtkObject *object);
static void gnome_calendar_goto_date (GnomeCalendar *gcal,
GnomeCalendarGotoDateType goto_date);
-static void gnome_calendar_change_view (GnomeCalendar *gcal,
- GnomeCalendarViewType view_type);
-static void gnome_calendar_set_pane_positions (GnomeCalendar *gcal);
-static void update_view_times (GnomeCalendar *gcal, time_t start_time);
static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal);
-static void gnome_calendar_hpane_realized (GtkWidget *w, GnomeCalendar *gcal);
-static void gnome_calendar_date_navigator_scrolled (GtkWidget *widget, GdkEventScroll *event, gpointer user_data);
static gboolean gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal);
-static void gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal);
-static gboolean gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal);
-
-static void gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem,
- GnomeCalendar *gcal);
-static void gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem,
- GnomeCalendar *gcal);
-static void gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal);
-
-static void update_query (GnomeCalendar *gcal);
static void update_todo_view (GnomeCalendar *gcal);
static void update_memo_view (GnomeCalendar *gcal);
@@ -289,16 +205,340 @@ message_push (Message *msg)
G_DEFINE_TYPE (GnomeCalendar, gnome_calendar, GTK_TYPE_VBOX)
+static void
+update_adjustment (GnomeCalendar *gcal,
+ GtkAdjustment *adjustment,
+ EWeekView *week_view)
+{
+ GDate date;
+ ECalModel *model;
+ gint week_offset;
+ struct icaltimetype start_tt = icaltime_null_time ();
+ time_t lower;
+ guint32 old_first_day_julian, new_first_day_julian;
+ icaltimezone *timezone;
+
+ /* If we don't have a valid date set yet, just return. */
+ if (!g_date_valid (&week_view->first_day_shown))
+ return;
+
+ /* Determine the first date shown. */
+ date = week_view->base_date;
+ week_offset = floor (adjustment->value + 0.5);
+ g_date_add_days (&date, week_offset * 7);
+
+ /* Convert the old & new first days shown to julian values. */
+ old_first_day_julian = g_date_get_julian (&week_view->first_day_shown);
+ new_first_day_julian = g_date_get_julian (&date);
+
+ /* If we are already showing the date, just return. */
+ if (old_first_day_julian == new_first_day_julian)
+ return;
+
+ /* Convert it to a time_t. */
+ start_tt.year = g_date_get_year (&date);
+ start_tt.month = g_date_get_month (&date);
+ start_tt.day = g_date_get_day (&date);
+
+ model = gnome_calendar_get_model (gcal);
+ timezone = e_cal_model_get_timezone (model);
+ lower = icaltime_as_timet_with_zone (start_tt, timezone);
+
+ e_week_view_set_update_base_date (week_view, FALSE);
+ gnome_calendar_set_selected_time_range (gcal, lower);
+ e_week_view_set_update_base_date (week_view, TRUE);
+}
+
+static void
+week_view_adjustment_changed_cb (GtkAdjustment *adjustment,
+ GnomeCalendar *gcal)
+{
+ ECalendarView *view;
+
+ view = gnome_calendar_get_calendar_view (gcal, GNOME_CAL_WEEK_VIEW);
+ update_adjustment (gcal, adjustment, E_WEEK_VIEW (view));
+}
+
+static void
+month_view_adjustment_changed_cb (GtkAdjustment *adjustment,
+ GnomeCalendar *gcal)
+{
+ ECalendarView *view;
+
+ view = gnome_calendar_get_calendar_view (gcal, GNOME_CAL_MONTH_VIEW);
+ update_adjustment (gcal, adjustment, E_WEEK_VIEW (view));
+}
+
+static void
+view_selection_changed_cb (GnomeCalendar *gcal)
+{
+ g_signal_emit (gcal, signals[CALENDAR_SELECTION_CHANGED], 0);
+}
+
+static void
+view_progress_cb (ECalModel *model,
+ const gchar *message,
+ gint percent,
+ ECalSourceType type,
+ GnomeCalendar *gcal)
+{
+#if 0 /* KILL-BONOBO */
+ ECalendarView *view;
+
+ view = gnome_calendar_get_calendar_view (gcal, GNOME_CAL_WEEK_VIEW);
+ e_calendar_view_set_status_message (view, message, percent);
+#endif
+}
+
+static void
+view_done_cb (ECalModel *model,
+ ECalendarStatus status,
+ ECalSourceType type,
+ GnomeCalendar *gcal)
+{
+#if 0 /* KILL-BONOBO */
+ ECalendarView *view;
+
+ view = gnome_calendar_get_calendar_view (gcal, GNOME_CAL_WEEK_VIEW);
+ e_calendar_view_set_status_message (view, NULL, -1);
+#endif
+}
+
+static void
+gnome_calendar_notify_week_start_day_cb (GnomeCalendar *gcal)
+{
+ time_t start_time;
+
+ start_time = gcal->priv->base_view_time;
+ gnome_calendar_set_selected_time_range (gcal, start_time);
+}
+
+static void
+gnome_calendar_update_time_range (GnomeCalendar *gcal)
+{
+ time_t start_time;
+
+ start_time = gcal->priv->base_view_time;
+ gnome_calendar_set_selected_time_range (gcal, start_time);
+}
+
+static void
+gnome_calendar_set_shell_settings (GnomeCalendar *gcal,
+ EShellSettings *shell_settings)
+{
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (gcal->priv->shell_settings == NULL);
+
+ gcal->priv->shell_settings = g_object_ref (shell_settings);
+}
+
+static void
+gnome_calendar_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_DATE_NAVIGATOR:
+ gnome_calendar_set_date_navigator (
+ GNOME_CALENDAR (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SHELL_SETTINGS:
+ gnome_calendar_set_shell_settings (
+ GNOME_CALENDAR (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_VIEW:
+ gnome_calendar_set_view (
+ GNOME_CALENDAR (object),
+ g_value_get_int (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+gnome_calendar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_DATE_NAVIGATOR:
+ g_value_set_object (
+ value, gnome_calendar_get_date_navigator (
+ GNOME_CALENDAR (object)));
+ return;
+
+ case PROP_SHELL_SETTINGS:
+ g_value_set_object (
+ value, gnome_calendar_get_shell_settings (
+ GNOME_CALENDAR (object)));
+ return;
+
+ case PROP_VIEW:
+ g_value_set_int (
+ value, gnome_calendar_get_view (
+ GNOME_CALENDAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+gnome_calendar_constructed (GObject *object)
+{
+ GnomeCalendar *gcal = GNOME_CALENDAR (object);
+ EShellSettings *shell_settings;
+ ECalendarView *calendar_view;
+ ECalModel *model;
+ GtkAdjustment *adjustment;
+
+ shell_settings = gnome_calendar_get_shell_settings (gcal);
+
+ /* Create the model for the views. */
+ model = e_cal_model_calendar_new (shell_settings);
+ e_cal_model_set_flags (model, E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES);
+ gcal->priv->model = model;
+
+ g_signal_connect (
+ model, "cal-view-progress",
+ G_CALLBACK (view_progress_cb), gcal);
+
+ g_signal_connect (
+ model, "cal-view-done",
+ G_CALLBACK (view_done_cb), gcal);
+
+ /* Day View */
+ calendar_view = e_day_view_new (model);
+ e_calendar_view_set_calendar (calendar_view, gcal);
+ gcal->priv->views[GNOME_CAL_DAY_VIEW] = calendar_view;
+
+ g_signal_connect_swapped (
+ calendar_view, "selection-changed",
+ G_CALLBACK (view_selection_changed_cb), gcal);
+
+ /* Work Week View */
+ calendar_view = e_day_view_new (model);
+ e_day_view_set_work_week_view (E_DAY_VIEW (calendar_view), TRUE);
+ e_day_view_set_days_shown (E_DAY_VIEW (calendar_view), 5);
+ e_calendar_view_set_calendar (calendar_view, gcal);
+ gcal->priv->views[GNOME_CAL_WORK_WEEK_VIEW] = calendar_view;
+
+ g_signal_connect_swapped (
+ calendar_view, "notify::working-days",
+ G_CALLBACK (gnome_calendar_update_time_range), gcal);
+
+ /* Week View */
+ calendar_view = e_week_view_new (model);
+ e_calendar_view_set_calendar (calendar_view, gcal);
+ gcal->priv->views[GNOME_CAL_WEEK_VIEW] = calendar_view;
+
+ g_signal_connect_swapped (
+ calendar_view, "selection-changed",
+ G_CALLBACK (view_selection_changed_cb), gcal);
+
+ adjustment = gtk_range_get_adjustment (
+ GTK_RANGE (E_WEEK_VIEW (calendar_view)->vscrollbar));
+ g_signal_connect (
+ adjustment, "value-changed",
+ G_CALLBACK (week_view_adjustment_changed_cb), gcal);
+
+ /* Month View */
+ calendar_view = e_month_view_new (model);
+ e_week_view_set_multi_week_view (E_WEEK_VIEW (calendar_view), TRUE);
+ e_week_view_set_weeks_shown (E_WEEK_VIEW (calendar_view), 6);
+ e_calendar_view_set_calendar (calendar_view, gcal);
+ gcal->priv->views[GNOME_CAL_MONTH_VIEW] = calendar_view;
+
+ g_signal_connect_swapped (
+ calendar_view, "selection-changed",
+ G_CALLBACK (view_selection_changed_cb), gcal);
+
+ adjustment = gtk_range_get_adjustment (
+ GTK_RANGE (E_WEEK_VIEW (calendar_view)->vscrollbar));
+ g_signal_connect (
+ adjustment, "value-changed",
+ G_CALLBACK (month_view_adjustment_changed_cb), gcal);
+
+ /* List View */
+ calendar_view = e_cal_list_view_new (model);
+ e_calendar_view_set_calendar (calendar_view, gcal);
+ gcal->priv->views[GNOME_CAL_LIST_VIEW] = calendar_view;
+
+ g_signal_connect_swapped (
+ calendar_view, "selection-changed",
+ G_CALLBACK (view_selection_changed_cb), gcal);
+
+ g_signal_connect_swapped (
+ model, "notify::week-start-day",
+ G_CALLBACK (gnome_calendar_notify_week_start_day_cb), gcal);
+
+ gnome_calendar_update_time_range (gcal);
+}
+
/* Class initialization function for the gnome calendar */
static void
gnome_calendar_class_init (GnomeCalendarClass *class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
GtkBindingSet *binding_set;
- object_class = (GtkObjectClass *) class;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = gnome_calendar_set_property;
+ object_class->get_property = gnome_calendar_get_property;
+ object_class->constructed = gnome_calendar_constructed;
- gnome_calendar_signals[DATES_SHOWN_CHANGED] =
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = gnome_calendar_destroy;
+
+ class->dates_shown_changed = NULL;
+ class->calendar_selection_changed = NULL;
+ class->source_added = NULL;
+ class->source_removed = NULL;
+ class->goto_date = gnome_calendar_goto_date;
+ class->change_view = gnome_calendar_set_view;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_DATE_NAVIGATOR,
+ g_param_spec_object (
+ "date-navigator",
+ "Date Navigator",
+ NULL,
+ E_TYPE_CALENDAR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_SETTINGS,
+ g_param_spec_object (
+ "shell-settings",
+ _("Shell Settings"),
+ _("Application-wide settings"),
+ E_TYPE_SHELL_SETTINGS,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_VIEW,
+ g_param_spec_int (
+ "view",
+ "View",
+ NULL,
+ GNOME_CAL_DAY_VIEW,
+ GNOME_CAL_LIST_VIEW,
+ 0,
+ G_PARAM_READWRITE));
+
+ signals[DATES_SHOWN_CHANGED] =
g_signal_new ("dates_shown_changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
@@ -307,7 +547,7 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- gnome_calendar_signals[CALENDAR_SELECTION_CHANGED] =
+ signals[CALENDAR_SELECTION_CHANGED] =
g_signal_new ("calendar_selection_changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
@@ -316,55 +556,7 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- gnome_calendar_signals[TASKPAD_SELECTION_CHANGED] =
- g_signal_new ("taskpad_selection_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GnomeCalendarClass, taskpad_selection_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED] =
- g_signal_new ("memopad_selection_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GnomeCalendarClass, memopad_selection_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- gnome_calendar_signals[CALENDAR_FOCUS_CHANGE] =
- g_signal_new ("calendar_focus_change",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GnomeCalendarClass, calendar_focus_change),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1,
- G_TYPE_BOOLEAN);
-
- gnome_calendar_signals[TASKPAD_FOCUS_CHANGE] =
- g_signal_new ("taskpad_focus_change",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GnomeCalendarClass, taskpad_focus_change),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1,
- G_TYPE_BOOLEAN);
-
- gnome_calendar_signals[MEMOPAD_FOCUS_CHANGE] =
- g_signal_new ("memopad_focus_change",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GnomeCalendarClass, memopad_focus_change),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1,
- G_TYPE_BOOLEAN);
-
- gnome_calendar_signals[SOURCE_ADDED] =
+ signals[SOURCE_ADDED] =
g_signal_new ("source_added",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
@@ -375,7 +567,7 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
2,
G_TYPE_INT, G_TYPE_OBJECT);
- gnome_calendar_signals[SOURCE_REMOVED] =
+ signals[SOURCE_REMOVED] =
g_signal_new ("source_removed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
@@ -386,7 +578,7 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
2,
G_TYPE_INT, G_TYPE_OBJECT);
- gnome_calendar_signals[GOTO_DATE] =
+ signals[GOTO_DATE] =
g_signal_new ("goto_date",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
@@ -397,7 +589,7 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
1,
G_TYPE_INT);
- gnome_calendar_signals[CHANGE_VIEW] =
+ signals[CHANGE_VIEW] =
g_signal_new ("change_view",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
@@ -408,20 +600,6 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
1,
G_TYPE_INT);
- object_class->destroy = gnome_calendar_destroy;
-
- class->dates_shown_changed = NULL;
- class->calendar_selection_changed = NULL;
- class->taskpad_selection_changed = NULL;
- class->memopad_selection_changed = NULL;
- class->calendar_focus_change = NULL;
- class->taskpad_focus_change = NULL;
- class->memopad_focus_change = NULL;
- class->source_added = NULL;
- class->source_removed = NULL;
- class->goto_date = gnome_calendar_goto_date;
- class->change_view = gnome_calendar_change_view;
-
/*
* Key bindings
*/
@@ -527,26 +705,31 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
}
-/* We do this check since the calendar items are downloaded from the server in the open_method,
- since the default timezone might not be set there */
+/* We do this check since the calendar items are downloaded from the server
+ * in the open_method, since the default timezone might not be set there. */
static void
-ensure_dates_are_in_default_zone (icalcomponent *icalcomp)
+ensure_dates_are_in_default_zone (GnomeCalendar *gcal,
+ icalcomponent *icalcomp)
{
+ ECalModel *model;
+ icaltimezone *timezone;
icaltimetype dt;
- icaltimezone *zone = calendar_config_get_icaltimezone ();
- if (!zone)
+ model = gnome_calendar_get_model (gcal);
+ timezone = e_cal_model_get_timezone (model);
+
+ if (timezone == NULL)
return;
dt = icalcomponent_get_dtstart (icalcomp);
if (dt.is_utc) {
- dt = icaltime_convert_to_zone (dt, zone);
+ dt = icaltime_convert_to_zone (dt, timezone);
icalcomponent_set_dtstart (icalcomp, dt);
}
dt = icalcomponent_get_dtend (icalcomp);
if (dt.is_utc) {
- dt = icaltime_convert_to_zone (dt, zone);
+ dt = icaltime_convert_to_zone (dt, timezone);
icalcomponent_set_dtend (icalcomp, dt);
}
}
@@ -565,7 +748,7 @@ dn_e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer data)
for (l = objects; l; l = l->next) {
ECalComponent *comp = NULL;
- ensure_dates_are_in_default_zone (l->data);
+ ensure_dates_are_in_default_zone (gcal, l->data);
comp = e_cal_component_new ();
if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) {
g_object_unref (comp);
@@ -590,7 +773,7 @@ dn_e_cal_view_objects_modified_cb (ECalView *query, GList *objects, gpointer dat
* and the tag_calendar_by_comp() below would not know how to
* untag the old dates.
*/
- update_query (gcal);
+ gnome_calendar_update_query (gcal);
}
/* Callback used when the calendar query reports of a removed object */
@@ -602,7 +785,7 @@ dn_e_cal_view_objects_removed_cb (ECalView *query, GList *ids, gpointer data)
gcal = GNOME_CALENDAR (data);
/* Just retag the whole thing */
- update_query (gcal);
+ gnome_calendar_update_query (gcal);
}
/* Callback used when the calendar query is done */
@@ -614,39 +797,48 @@ dn_e_cal_view_done_cb (ECalView *query, ECalendarStatus status, gpointer data)
g_warning (G_STRLOC ": Query did not successfully complete");
}
-/* Returns the current view widget, an EDayView, EWeekView or ECalListView. */
-GtkWidget*
-gnome_calendar_get_current_view_widget (GnomeCalendar *gcal)
+ECalendarView *
+gnome_calendar_get_calendar_view (GnomeCalendar *gcal,
+ GnomeCalendarViewType view_type)
{
- GnomeCalendarPrivate *priv;
-
- priv = gcal->priv;
+ g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
+ g_return_val_if_fail (view_type < GNOME_CAL_LAST_VIEW, NULL);
- return GTK_WIDGET (priv->views[priv->current_view_type]);
+ return gcal->priv->views[view_type];
}
static void
get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_t *start_time, time_t *end_time, time_t *select_time)
{
GnomeCalendarPrivate *priv;
+ ECalModel *model;
gint shown, display_start;
GDate date;
+ gint week_start_day;
gint weekday, first_day, last_day, days_shown, i;
gboolean has_working_days = FALSE;
guint offset;
struct icaltimetype tt = icaltime_null_time ();
+ icaltimezone *timezone;
+ gboolean range_selected;
+
+ model = gnome_calendar_get_model (gcal);
+ range_selected = gnome_calendar_get_range_selected (gcal);
+
+ timezone = e_cal_model_get_timezone (model);
+ week_start_day = e_cal_model_get_week_start_day (model);
priv = gcal->priv;
switch (view_type) {
case GNOME_CAL_DAY_VIEW:
shown = e_day_view_get_days_shown (E_DAY_VIEW (priv->views[view_type]));
- *start_time = time_day_begin_with_zone (*start_time, priv->zone);
- *end_time = time_add_day_with_zone (*start_time, shown, priv->zone);
+ *start_time = time_day_begin_with_zone (*start_time, timezone);
+ *end_time = time_add_day_with_zone (*start_time, shown, timezone);
break;
case GNOME_CAL_WORK_WEEK_VIEW:
/* FIXME Kind of gross, but it works */
- time_to_gdate_with_zone (&date, *start_time, priv->zone);
+ time_to_gdate_with_zone (&date, *start_time, timezone);
/* The start of the work-week is the first working day after the
week start day. */
@@ -655,7 +847,7 @@ get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_
weekday = g_date_get_weekday (&date) % 7;
/* Find the first working day in the week, 0 (Sun) to 6 (Sat). */
- first_day = (E_DAY_VIEW (priv->views[view_type])->week_start_day + 1) % 7;
+ first_day = (week_start_day + 1) % 7;
for (i = 0; i < 7; i++) {
if (E_DAY_VIEW (priv->views[view_type])->working_days & (1 << first_day)) {
has_working_days = TRUE;
@@ -666,7 +858,7 @@ get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_
if (has_working_days) {
/* Now find the last working day of the week, backwards. */
- last_day = E_DAY_VIEW (priv->views[view_type])->week_start_day % 7;
+ last_day = week_start_day % 7;
for (i = 0; i < 7; i++) {
if (E_DAY_VIEW (priv->views[view_type])->working_days & (1 << last_day))
break;
@@ -693,8 +885,8 @@ get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_
tt.month = g_date_get_month (&date);
tt.day = g_date_get_day (&date);
- *start_time = icaltime_as_timet_with_zone (tt, priv->zone);
- *end_time = time_add_day_with_zone (*start_time, days_shown, priv->zone);
+ *start_time = icaltime_as_timet_with_zone (tt, timezone);
+ *end_time = time_add_day_with_zone (*start_time, days_shown, timezone);
if (select_time && E_DAY_VIEW (priv->views[view_type])->selection_start_day == -1)
time (select_time);
@@ -703,8 +895,8 @@ get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_
/* FIXME We should be using the same day of the week enum every where */
display_start = (E_WEEK_VIEW (priv->views[view_type])->display_start_day + 1) % 7;
- *start_time = time_week_begin_with_zone (*start_time, display_start, priv->zone);
- *end_time = time_add_week_with_zone (*start_time, 1, priv->zone);
+ *start_time = time_week_begin_with_zone (*start_time, display_start, timezone);
+ *end_time = time_add_week_with_zone (*start_time, 1, timezone);
if (select_time && E_WEEK_VIEW (priv->views[view_type])->selection_start_day == -1)
time (select_time);
@@ -714,108 +906,45 @@ get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_
/* FIXME We should be using the same day of the week enum every where */
display_start = (E_WEEK_VIEW (priv->views[view_type])->display_start_day + 1) % 7;
- if (!priv->range_selected && (!E_WEEK_VIEW (priv->views[view_type])->multi_week_view || !E_WEEK_VIEW (priv->views[view_type])->month_scroll_by_week))
- *start_time = time_month_begin_with_zone (*start_time, priv->zone);
- *start_time = time_week_begin_with_zone (*start_time, display_start, priv->zone);
- *end_time = time_add_week_with_zone (*start_time, shown, priv->zone);
+ if (!range_selected && (!E_WEEK_VIEW (priv->views[view_type])->multi_week_view || !E_WEEK_VIEW (priv->views[view_type])->month_scroll_by_week))
+ *start_time = time_month_begin_with_zone (*start_time, timezone);
+ *start_time = time_week_begin_with_zone (*start_time, display_start, timezone);
+ *end_time = time_add_week_with_zone (*start_time, shown, timezone);
if (select_time && E_WEEK_VIEW (priv->views[view_type])->selection_start_day == -1)
time (select_time);
break;
case GNOME_CAL_LIST_VIEW:
/* FIXME What to do here? */
- *start_time = time_month_begin_with_zone (*start_time, priv->zone);
- *end_time = time_add_month_with_zone (*start_time, 1, priv->zone);
+ *start_time = time_month_begin_with_zone (*start_time, timezone);
+ *end_time = time_add_month_with_zone (*start_time, 1, timezone);
break;
default:
g_return_if_reached ();
}
}
-/* Gets the focus location based on who is the focused widget within the
- * calendar view.
- */
-static FocusLocation
-get_focus_location (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- ETable *etable, *m_etable;
-
- priv = gcal->priv;
-
- etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo));
- m_etable = e_memo_table_get_table (E_MEMO_TABLE (priv->memo));
-
- if (GTK_WIDGET_HAS_FOCUS (etable->table_canvas))
- return FOCUS_TASKPAD;
- else if (GTK_WIDGET_HAS_FOCUS (m_etable->table_canvas))
- return FOCUS_MEMOPAD;
- else {
- GtkWidget *widget;
- EDayView *dv;
- EWeekView *wv;
- ECalListView *lv;
-
- widget = gnome_calendar_get_current_view_widget (gcal);
-
- switch (priv->current_view_type) {
- case GNOME_CAL_DAY_VIEW:
- case GNOME_CAL_WORK_WEEK_VIEW:
- dv = E_DAY_VIEW (widget);
-
- if (GTK_WIDGET_HAS_FOCUS (dv->top_canvas)
- || GNOME_CANVAS (dv->top_canvas)->focused_item != NULL
- || GTK_WIDGET_HAS_FOCUS (dv->main_canvas)
- || GNOME_CANVAS (dv->main_canvas)->focused_item != NULL
- || GTK_WIDGET_HAS_FOCUS (dv))
- return FOCUS_CALENDAR;
- else
- return FOCUS_OTHER;
-
- case GNOME_CAL_WEEK_VIEW:
- case GNOME_CAL_MONTH_VIEW:
- wv = E_WEEK_VIEW (widget);
-
- if (GTK_WIDGET_HAS_FOCUS (wv->main_canvas)
- || GNOME_CANVAS (wv->main_canvas)->focused_item != NULL
- || GTK_WIDGET_HAS_FOCUS (wv))
- return FOCUS_CALENDAR;
- else
- return FOCUS_OTHER;
-
- case GNOME_CAL_LIST_VIEW:
- lv = E_CAL_LIST_VIEW (widget);
-
- if (GTK_WIDGET_HAS_FOCUS (e_table_scrolled_get_table (lv->table_scrolled))
- || GTK_WIDGET_HAS_FOCUS (lv))
- return FOCUS_CALENDAR;
- else
- return FOCUS_OTHER;
-
- default:
- g_return_val_if_reached (FOCUS_OTHER);
- }
- }
-}
-
/* Computes the range of time that the date navigator is showing */
static void
get_date_navigator_range (GnomeCalendar *gcal, time_t *start_time, time_t *end_time)
{
- GnomeCalendarPrivate *priv;
+ ECalModel *model;
gint start_year, start_month, start_day;
gint end_year, end_month, end_day;
struct icaltimetype start_tt;
struct icaltimetype end_tt;
+ icaltimezone *timezone;
- priv = gcal->priv;
+ model = gnome_calendar_get_model (gcal);
+ timezone = e_cal_model_get_timezone (model);
start_tt = icaltime_null_time ();
end_tt = icaltime_null_time ();
- if (!e_calendar_item_get_date_range (priv->date_navigator->calitem,
- &start_year, &start_month, &start_day,
- &end_year, &end_month, &end_day)) {
+ if (!e_calendar_item_get_date_range (
+ gcal->priv->date_navigator->calitem,
+ &start_year, &start_month, &start_day,
+ &end_year, &end_month, &end_day)) {
*start_time = -1;
*end_time = -1;
return;
@@ -831,8 +960,8 @@ get_date_navigator_range (GnomeCalendar *gcal, time_t *start_time, time_t *end_t
icaltime_adjust (&end_tt, 1, 0, 0, 0);
- *start_time = icaltime_as_timet_with_zone (start_tt, priv->zone);
- *end_time = icaltime_as_timet_with_zone (end_tt, priv->zone);
+ *start_time = icaltime_as_timet_with_zone (start_tt, timezone);
+ *end_time = icaltime_as_timet_with_zone (end_tt, timezone);
}
/* Adjusts a given query sexp with the time range of the date navigator */
@@ -901,7 +1030,7 @@ update_query_async (struct _date_query_msg *msg)
}
/* create queries for each loaded client */
- for (l = priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) {
+ for (l = priv->clients_list; l != NULL; l = l->next) {
GError *error = NULL;
gint tries = 0;
@@ -951,11 +1080,13 @@ try_again:
}
/* Restarts a query for the date navigator in the calendar */
-static void
-update_query (GnomeCalendar *gcal)
+void
+gnome_calendar_update_query (GnomeCalendar *gcal)
{
struct _date_query_msg *msg;
+ g_return_if_fail (GNOME_IS_CALENDAR (gcal));
+
e_calendar_item_clear_marks (gcal->priv->date_navigator->calitem);
msg = g_slice_new0 (struct _date_query_msg);
@@ -965,353 +1096,79 @@ update_query (GnomeCalendar *gcal)
message_push ((Message *) msg);
}
-static void
-set_search_query (GnomeCalendar *gcal, const gchar *sexp)
+void
+gnome_calendar_set_search_query (GnomeCalendar *gcal,
+ const gchar *sexp,
+ gboolean range_search,
+ time_t start_range,
+ time_t end_range)
{
GnomeCalendarPrivate *priv;
+ ECalModel *model;
gint i;
time_t start, end;
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
g_return_if_fail (sexp != NULL);
priv = gcal->priv;
- /* Set the query on the date navigator */
+ model = gnome_calendar_get_model (gcal);
- if (priv->sexp)
- g_free (priv->sexp);
+ /* Set the query on the date navigator */
+ g_free (priv->sexp);
priv->sexp = g_strdup (sexp);
+ priv->lview_select_daten_range = range_search;
+ start = start_range;
+ end = end_range;
+
d(g_print ("Changing the queries %s \n", sexp));
- update_query (gcal);
+ gnome_calendar_update_query (gcal);
i = priv->current_view_type;
/* Set the query on the views */
if (i == GNOME_CAL_LIST_VIEW) {
if (!priv->lview_select_daten_range) {
- cal_search_bar_get_time_range ((CalSearchBar *)priv->search_bar, &start, &end);
- e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end);
+ e_cal_model_set_search_query_with_time_range (
+ model, sexp, start, end);
} else {
start = priv->base_view_time;
get_times_for_views (gcal, GNOME_CAL_LIST_VIEW, &start, &end, NULL);
- e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end);
+ e_cal_model_set_search_query_with_time_range (
+ model, sexp, start, end);
if (priv->current_view_type == GNOME_CAL_LIST_VIEW)
gnome_calendar_update_date_navigator (gcal);
}
} else
- e_cal_model_set_search_query (e_calendar_view_get_model (priv->views[i]), sexp);
+ e_cal_model_set_search_query (model, sexp);
/* Set the query on the task pad */
update_todo_view (gcal);
}
-/* Returns the current time, for the ECalendarItem. */
-static struct tm
-get_current_time (ECalendarItem *calitem, gpointer data)
-{
- GnomeCalendar *cal = data;
- struct tm tmp_tm = { 0 };
- struct icaltimetype tt;
-
- g_return_val_if_fail (cal != NULL, tmp_tm);
- g_return_val_if_fail (GNOME_IS_CALENDAR (cal), tmp_tm);
-
- tt = icaltime_from_timet_with_zone (time (NULL), FALSE,
- cal->priv->zone);
-
- /* Now copy it to the struct tm and return it. */
- tmp_tm = icaltimetype_to_tm (&tt);
-
- return tmp_tm;
-}
-
-/* Callback used when the sexp changes in the calendar search bar */
-static void
-search_bar_sexp_changed_cb (CalSearchBar *cal_search, const gchar *sexp, gpointer data)
-{
- GnomeCalendar *gcal;
- const gchar *d_sexp = "occur-in-time-range?";
-
- gcal = GNOME_CALENDAR (data);
-
- /* Choose List view if the search made in the search bar is based on date */
- if (sexp != NULL && strstr (sexp, d_sexp ) != NULL) {
- gcal->priv->lview_select_daten_range = FALSE;
- gtk_widget_hide (GTK_WIDGET (gcal->priv->date_navigator));
- gnome_calendar_set_view (gcal, GNOME_CAL_LIST_VIEW);
- } else {
- gcal->priv->lview_select_daten_range = TRUE;
- gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
- }
-
- set_search_query (gcal, sexp);
-}
-
-/* Callback used when the selected category in the search bar changes */
static void
-search_bar_category_changed_cb (CalSearchBar *cal_search, const gchar *category, gpointer data)
+set_timezone (GnomeCalendar *gcal)
{
- GnomeCalendar *gcal;
- GnomeCalendarPrivate *priv;
ECalModel *model;
- gint i;
-
- gcal = GNOME_CALENDAR (data);
- priv = gcal->priv;
-
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
- e_calendar_view_set_default_category (E_CALENDAR_VIEW (priv->views[i]),
- category);
- }
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
- e_cal_model_set_default_category (model, category);
-}
-
-static void
-view_selection_changed_cb (GtkWidget *view, GnomeCalendar *gcal)
-{
- g_signal_emit (gcal, gnome_calendar_signals[CALENDAR_SELECTION_CHANGED], 0);
-}
-
-/**
- * gnome_calendar_emit_user_created_signal
- * Emits "user_created" signal on a gcal and use calendar as a store where was event created.
- *
- * @param instance Instance on which emit signal.
- * @param gcal GnomeCalendar, it will store info about used calendar here.
- * @param calendar Used calendar, where was event created.
- **/
-void
-gnome_calendar_emit_user_created_signal (gpointer instance, GnomeCalendar *gcal, ECal *calendar)
-{
- GnomeCalendarPrivate *priv;
-
- g_return_if_fail (gcal != NULL);
-
- priv = gcal->priv;
- priv->user_created_cal = calendar;
- g_signal_emit_by_name (instance, "user_created");
- priv->user_created_cal = NULL;
-}
-
-static void
-user_created_cb (GtkWidget *view, GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- ECal *ecal;
-
- priv = gcal->priv;
- ecal = priv->user_created_cal;
-
- if (!ecal) {
- ECalModel *model;
-
- model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
- ecal = e_cal_model_get_default_client (model);
- }
-
- gnome_calendar_add_source (gcal, E_CAL_SOURCE_TYPE_EVENT, e_cal_get_source (ecal));
-}
-
-/* Callback used when the taskpad receives a focus event. We emit the
- * corresponding signal so that parents can change the menus as appropriate.
- */
-static gint
-table_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- g_signal_emit (gcal, gnome_calendar_signals [TASKPAD_FOCUS_CHANGE], 0,
- event->in ? TRUE : FALSE);
-
- return FALSE;
-}
-
-static gint
-memo_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- g_signal_emit (gcal, gnome_calendar_signals [MEMOPAD_FOCUS_CHANGE], 0,
- event->in ? TRUE : FALSE);
-
- return FALSE;
-}
-
-static gint
-calendar_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- g_signal_emit (gcal, gnome_calendar_signals [CALENDAR_FOCUS_CHANGE], 0,
- event->in ? TRUE : FALSE);
-
- return FALSE;
-}
-
-/* Connects to the focus change signals of a day view widget */
-static void
-connect_day_view_focus (GnomeCalendar *gcal, EDayView *dv)
-{
- g_signal_connect_after (dv->top_canvas, "focus_in_event",
- G_CALLBACK (calendar_focus_change_cb), gcal);
- g_signal_connect_after (dv->top_canvas, "focus_out_event",
- G_CALLBACK (calendar_focus_change_cb), gcal);
-
- g_signal_connect_after (dv->main_canvas, "focus_in_event",
- G_CALLBACK (calendar_focus_change_cb), gcal);
- g_signal_connect_after (dv->main_canvas, "focus_out_event",
- G_CALLBACK (calendar_focus_change_cb), gcal);
-}
-
-/* Connects to the focus change signals of a week view widget */
-static void
-connect_week_view_focus (GnomeCalendar *gcal, EWeekView *wv)
-{
- if (!E_IS_WEEK_VIEW (wv))
- return;
-
- g_signal_connect (wv->main_canvas, "focus_in_event",
- G_CALLBACK (calendar_focus_change_cb), gcal);
- g_signal_connect (wv->main_canvas, "focus_out_event",
- G_CALLBACK (calendar_focus_change_cb), gcal);
-}
-
-static void
-connect_list_view_focus (GnomeCalendar *gcal, ECalListView *lv)
-{
- ETable *etable;
-
- etable = e_table_scrolled_get_table (lv->table_scrolled);
-
- g_signal_connect (etable->table_canvas, "focus_in_event",
- G_CALLBACK (calendar_focus_change_cb), gcal);
- g_signal_connect (etable->table_canvas, "focus_out_event",
- G_CALLBACK (calendar_focus_change_cb), gcal);
-}
-
-/* Callback used when the selection in the taskpad table changes. We just proxy
- * the signal with our own one.
- */
-static void
-table_selection_change_cb (ETable *etable, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- g_signal_emit (gcal, gnome_calendar_signals[TASKPAD_SELECTION_CHANGED], 0);
-}
-
-static void
-memo_selection_change_cb (ETable *etable, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- g_signal_emit (gcal, gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED], 0);
-}
-
-static void
-set_week_start (GnomeCalendar *calendar)
-{
- GnomeCalendarPrivate *priv;
-
- priv = calendar->priv;
-
- priv->week_start = calendar_config_get_week_start_day ();
-
- /* Only do this if views exist */
- if (priv->day_view && priv->work_week_view && priv->week_view && priv->month_view && priv->list_view) {
- update_view_times (calendar, priv->base_view_time);
- gnome_calendar_update_date_navigator (calendar);
- gnome_calendar_notify_dates_shown_changed (calendar);
- }
-}
-
-static void
-week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- GnomeCalendar *calendar = data;
-
- set_week_start (calendar);
-}
-
-static void
-set_working_days (GnomeCalendar *calendar)
-{
- GnomeCalendarPrivate *priv;
-
- priv = calendar->priv;
-
- /* Only do this if views exist */
- if (priv->day_view && priv->work_week_view && priv->week_view && priv->month_view && priv->list_view) {
- update_view_times (calendar, priv->base_view_time);
- gnome_calendar_update_date_navigator (calendar);
- gnome_calendar_notify_dates_shown_changed (calendar);
- }
-}
-
-static void
-working_days_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- GnomeCalendar *calendar = data;
-
- set_working_days (calendar);
-}
-
-static void
-set_timezone (GnomeCalendar *calendar)
-{
- GnomeCalendarPrivate *priv;
- gint i;
-
- priv = calendar->priv;
-
- priv->zone = calendar_config_get_icaltimezone ();
-
- for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) {
- GList *l;
+ icaltimezone *timezone;
+ GList *l;
- for (l = priv->clients_list[i]; l != NULL; l = l->next) {
- ECal *client = l->data;
+ model = gnome_calendar_get_model (gcal);
+ timezone = e_cal_model_get_timezone (model);
- if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
- /* FIXME Error checking */
- e_cal_set_default_timezone (client, priv->zone, NULL);
- }
+ for (l = gcal->priv->clients_list; l != NULL; l = l->next) {
+ ECal *client = l->data;
- if (priv->default_client[i]
- && e_cal_get_load_state (priv->default_client[i]) == E_CAL_LOAD_LOADED)
+ if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
/* FIXME Error checking */
- e_cal_set_default_timezone (priv->default_client[i], priv->zone, NULL);
+ e_cal_set_default_timezone (client, timezone, NULL);
}
-
- if (priv->views [priv->current_view_type])
- e_calendar_view_set_timezone (priv->views [priv->current_view_type], priv->zone);
-}
-
-static void
-timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- GnomeCalendar *calendar = data;
-
- set_timezone (calendar);
}
struct _mupdate_todo_msg {
@@ -1319,6 +1176,7 @@ struct _mupdate_todo_msg {
GnomeCalendar *gcal;
};
+#if 0 /* KILL-BONOBO */
static void
update_todo_view_async (struct _mupdate_todo_msg *msg)
{
@@ -1357,10 +1215,12 @@ update_todo_view_async (struct _mupdate_todo_msg *msg)
g_object_unref (msg->gcal);
g_slice_free (struct _mupdate_todo_msg, msg);
}
+#endif
static void
update_todo_view (GnomeCalendar *gcal)
{
+#if 0 /* KILL-BONOBO */
struct _mupdate_todo_msg *msg;
msg = g_slice_new0 (struct _mupdate_todo_msg);
@@ -1368,11 +1228,13 @@ update_todo_view (GnomeCalendar *gcal)
msg->gcal = g_object_ref (gcal);
message_push ((Message *) msg);
+#endif
}
static void
update_memo_view (GnomeCalendar *gcal)
{
+#if 0 /* KILL-BONOBO */
GnomeCalendarPrivate *priv;
ECalModel *model, *view_model;
time_t start, end;
@@ -1382,7 +1244,7 @@ update_memo_view (GnomeCalendar *gcal)
/* Set the query on the memo pad*/
model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo));
- view_model = e_calendar_view_get_model(priv->views[priv->current_view_type]);
+ view_model = gnome_calendar_get_model (gcal);
e_cal_model_get_time_range (view_model, &start, &end);
if (start != -1 && end != -1) {
@@ -1404,21 +1266,24 @@ update_memo_view (GnomeCalendar *gcal)
g_free (iso_start);
g_free (iso_end);
}
+#endif
}
static void
process_completed_tasks (GnomeCalendar *gcal, gboolean config_changed)
{
+#if 0 /* KILL-BONOBO */
GnomeCalendarPrivate *priv;
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR(gcal));
priv = gcal->priv;
e_calendar_table_process_completed_tasks (E_CALENDAR_TABLE (priv->todo), priv->clients_list[E_CAL_SOURCE_TYPE_TODO], config_changed);
+#endif
}
+#if 0 /* KILL-BONOBO */
static gboolean
update_todo_view_cb (GnomeCalendar *gcal)
{
@@ -1431,26 +1296,29 @@ update_todo_view_cb (GnomeCalendar *gcal)
return TRUE;
}
+#endif
static gboolean
update_marcus_bains_line_cb (GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
+ GnomeCalendarViewType view_type;
+ ECalendarView *view;
time_t now, day_begin;
priv = gcal->priv;
- if ((priv->current_view_type == GNOME_CAL_DAY_VIEW) ||
- (priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW)) {
- e_day_view_update_marcus_bains (E_DAY_VIEW (gnome_calendar_get_current_view_widget (gcal)));
- }
+ view_type = gnome_calendar_get_view (gcal);
+ view = gnome_calendar_get_calendar_view (gcal, view_type);
+
+ if (E_IS_DAY_VIEW (view))
+ e_day_view_marcus_bains_update (E_DAY_VIEW (view));
time (&now);
day_begin = time_day_begin (now);
/* check in the first two minutes */
if (now >= day_begin && now <= day_begin + 120) {
- ECalendarView *view = priv->views[priv->current_view_type];
time_t start_time = 0, end_time = 0;
g_return_val_if_fail (view != NULL, TRUE);
@@ -1466,175 +1334,6 @@ update_marcus_bains_line_cb (GnomeCalendar *gcal)
}
static void
-config_hide_completed_tasks_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- process_completed_tasks (data, TRUE);
-}
-
-static void
-setup_config (GnomeCalendar *calendar)
-{
- GnomeCalendarPrivate *priv;
- guint not;
-
- priv = calendar->priv;
-
- /* Week Start */
- set_week_start (calendar);
- not = calendar_config_add_notification_week_start_day (week_start_changed_cb, calendar);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Working Days */
- set_working_days (calendar);
- not = calendar_config_add_notification_working_days (working_days_changed_cb, calendar);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Timezone */
- set_timezone (calendar);
- not = calendar_config_add_notification_timezone (timezone_changed_cb, calendar);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Hide completed tasks */
- not = calendar_config_add_notification_hide_completed_tasks (config_hide_completed_tasks_changed_cb,
- calendar);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- not = calendar_config_add_notification_hide_completed_tasks_units (config_hide_completed_tasks_changed_cb,
- calendar);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- not = calendar_config_add_notification_hide_completed_tasks_value (config_hide_completed_tasks_changed_cb,
- calendar);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Pane positions */
- priv->hpane_pos = calendar_config_get_hpane_pos ();
- priv->vpane_pos = calendar_config_get_vpane_pos ();
- priv->hpane_pos_month_view = calendar_config_get_month_hpane_pos ();
- priv->vpane_pos_month_view = calendar_config_get_month_vpane_pos ();
-}
-
-static void
-update_adjustment (GnomeCalendar *gcal, GtkAdjustment *adjustment, EWeekView *week_view)
-{
- GDate date;
- gint week_offset;
- struct icaltimetype start_tt = icaltime_null_time ();
- time_t lower;
- guint32 old_first_day_julian, new_first_day_julian;
-
- /* If we don't have a valid date set yet, just return. */
- if (!g_date_valid (&week_view->first_day_shown))
- return;
-
- /* Determine the first date shown. */
- date = week_view->base_date;
- week_offset = floor (adjustment->value + 0.5);
- g_date_add_days (&date, week_offset * 7);
-
- /* Convert the old & new first days shown to julian values. */
- old_first_day_julian = g_date_get_julian (&week_view->first_day_shown);
- new_first_day_julian = g_date_get_julian (&date);
-
- /* If we are already showing the date, just return. */
- if (old_first_day_julian == new_first_day_julian)
- return;
-
- /* Convert it to a time_t. */
- start_tt.year = g_date_get_year (&date);
- start_tt.month = g_date_get_month (&date);
- start_tt.day = g_date_get_day (&date);
-
- lower = icaltime_as_timet_with_zone (start_tt, gcal->priv->zone);
-
- e_week_view_set_update_base_date (week_view, FALSE);
- update_view_times (gcal, lower);
- gnome_calendar_update_date_navigator (gcal);
- gnome_calendar_notify_dates_shown_changed (gcal);
- e_week_view_set_update_base_date (week_view, TRUE);
-}
-
-static void
-week_view_adjustment_changed_cb (GtkAdjustment *adjustment, GnomeCalendar *gcal)
-{
- update_adjustment (gcal, adjustment, E_WEEK_VIEW (gcal->priv->week_view));
-}
-
-static void
-month_view_adjustment_changed_cb (GtkAdjustment *adjustment, GnomeCalendar *gcal)
-{
- update_adjustment (gcal, adjustment, E_WEEK_VIEW (gcal->priv->month_view));
-}
-
-static void
-categories_changed_cb (gpointer object, gpointer user_data)
-{
- GList *cat_list;
- GPtrArray *cat_array;
- GnomeCalendarPrivate *priv;
- GnomeCalendar *gcal = user_data;
-
- priv = gcal->priv;
-
- cat_array = g_ptr_array_new ();
- cat_list = e_categories_get_list ();
- while (cat_list != NULL) {
- if (e_categories_is_searchable ((const gchar *) cat_list->data))
- g_ptr_array_add (cat_array, cat_list->data);
- cat_list = g_list_remove (cat_list, cat_list->data);
- }
-
- cal_search_bar_set_categories ((CalSearchBar *)priv->search_bar, cat_array);
-
- g_ptr_array_free (cat_array, TRUE);
-}
-
-static void
-view_progress_cb (ECalModel *model, const gchar *message, gint percent, ECalSourceType type, GnomeCalendar *gcal)
-{
- if (type == E_CAL_SOURCE_TYPE_EVENT) {
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (gcal->priv->week_view), message, percent);
- } else if (type == E_CAL_SOURCE_TYPE_TODO) {
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (gcal->priv->todo), message, percent);
- } else if (type == E_CAL_SOURCE_TYPE_JOURNAL) {
- e_memo_table_set_status_message (E_MEMO_TABLE (gcal->priv->memo), message);
- }
-}
-
-static void
-view_done_cb (ECalModel *model, ECalendarStatus status, ECalSourceType type, GnomeCalendar *gcal)
-{
- if (type == E_CAL_SOURCE_TYPE_EVENT) {
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (gcal->priv->week_view), NULL, -1);
- } else if (type == E_CAL_SOURCE_TYPE_TODO) {
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (gcal->priv->todo), NULL, -1);
- } else if (type == E_CAL_SOURCE_TYPE_JOURNAL) {
- e_memo_table_set_status_message (E_MEMO_TABLE (gcal->priv->memo), NULL);
- }
-
-}
-
-GtkWidget *
-gnome_calendar_get_tag (GnomeCalendar *gcal)
-{
- return GTK_WIDGET (gcal->priv->date_navigator);
-}
-
-static time_t
-gc_get_default_time (ECalModel *model, gpointer user_data)
-{
- GnomeCalendar *gcal = user_data;
- time_t res = 0, end;
-
- g_return_val_if_fail (model != NULL, 0);
- g_return_val_if_fail (GNOME_IS_CALENDAR (user_data), 0);
-
- gnome_calendar_get_current_time_range (gcal, &res, &end);
-
- return res;
-}
-
-static void
setup_widgets (GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
@@ -1642,7 +1341,6 @@ setup_widgets (GnomeCalendar *gcal)
gchar *filename;
ETable *etable;
GtkAdjustment *adjustment;
- ECalModel *w_model;
GtkWidget *vbox;
GtkWidget *label;
ECalModel *cal_model;
@@ -1651,234 +1349,17 @@ setup_widgets (GnomeCalendar *gcal)
priv = gcal->priv;
- priv->search_bar = cal_search_bar_new (CAL_SEARCH_CALENDAR_DEFAULT);
- g_signal_connect (priv->search_bar, "sexp_changed",
- G_CALLBACK (search_bar_sexp_changed_cb), gcal);
- g_signal_connect (priv->search_bar, "category_changed",
- G_CALLBACK (search_bar_category_changed_cb), gcal);
- categories_changed_cb (NULL, gcal);
-
- gtk_widget_show (priv->search_bar);
- gtk_box_pack_start (GTK_BOX (gcal), priv->search_bar, FALSE, FALSE, 6);
-
- /* The main HPaned, with the notebook of calendar views on the left
- and the ECalendar and ToDo list on the right. */
- priv->hpane = gtk_hpaned_new ();
- g_signal_connect_after(priv->hpane, "realize",
- G_CALLBACK(gnome_calendar_hpane_realized), gcal);
- g_signal_connect (priv->hpane, "button_release_event",
- G_CALLBACK (gnome_calendar_hpane_resized), gcal);
- gtk_widget_show (priv->hpane);
- gtk_box_pack_start (GTK_BOX (gcal), priv->hpane, TRUE, TRUE, 6);
-
- /* The Notebook containing the 4 calendar views. */
- priv->notebook = gtk_notebook_new ();
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
- gtk_widget_show (priv->notebook);
- gtk_paned_pack1 (GTK_PANED (priv->hpane), priv->notebook, FALSE, TRUE);
-
- /* The ECalendar. */
- w = e_calendar_new ();
- priv->date_navigator = E_CALENDAR (w);
- priv->date_navigator_config = e_mini_calendar_config_new (priv->date_navigator);
- e_calendar_item_set_days_start_week_sel (priv->date_navigator->calitem, 9);
- e_calendar_item_set_max_days_sel (priv->date_navigator->calitem, 42);
- gtk_widget_show (w);
- e_calendar_item_set_get_time_callback (priv->date_navigator->calitem,
- (ECalendarItemGetTimeCallback) get_current_time,
- gcal, NULL);
-
- g_signal_connect (priv->date_navigator->calitem, "selection_changed",
- G_CALLBACK (gnome_calendar_on_date_navigator_selection_changed), gcal);
- g_signal_connect (priv->date_navigator->calitem, "date_range_changed",
- G_CALLBACK (gnome_calendar_on_date_navigator_date_range_changed), gcal);
- g_signal_connect (w, "scroll-event",
- G_CALLBACK (gnome_calendar_date_navigator_scrolled), gcal);
-
- /* The VPaned widget, to contain the ToDo list & Memo list */
- priv->vpane = gtk_vpaned_new ();
- g_signal_connect_after (priv->vpane, "realize",
- G_CALLBACK(gnome_calendar_vpane_realized), gcal);
- g_signal_connect (priv->vpane, "button_release_event",
- G_CALLBACK (gnome_calendar_vpane_resized), gcal);
- gtk_widget_show (priv->vpane);
- gtk_paned_pack2 (GTK_PANED (priv->hpane), priv->vpane, TRUE, TRUE);
-
- /* The ToDo list. */
- vbox = gtk_vbox_new (FALSE, 0);
- sep = gtk_hseparator_new ();
- gtk_box_pack_start ((GtkBox *)vbox, sep, FALSE, TRUE, 0);
-
- label = gtk_label_new (NULL);
- tmp = g_strdup_printf ("<b> %s </b>", _("Tasks"));
- gtk_label_set_markup ((GtkLabel *)label, tmp);
- g_free (tmp);
- gtk_box_pack_start ((GtkBox *)vbox, label, FALSE, TRUE, 0);
-
- priv->todo = e_calendar_table_new ();
- priv->todo_config = e_calendar_table_config_new (E_CALENDAR_TABLE (priv->todo));
- gtk_paned_pack1 (GTK_PANED (priv->vpane), vbox, FALSE, FALSE);
- gtk_box_pack_end ((GtkBox *)vbox, priv->todo, TRUE, TRUE, 0);
-
- gtk_widget_show (priv->todo);
- gtk_widget_show (label);
- gtk_widget_show (vbox);
- gtk_widget_show (sep);
-
- filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
- "TaskPad", NULL);
- e_calendar_table_load_state (E_CALENDAR_TABLE (priv->todo), filename);
-
/* update_todo_view (gcal); */
- g_free (filename);
-
- etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo));
- g_signal_connect (etable->table_canvas, "focus_in_event",
- G_CALLBACK (table_canvas_focus_change_cb), gcal);
- g_signal_connect (etable->table_canvas, "focus_out_event",
- G_CALLBACK (table_canvas_focus_change_cb), gcal);
-
- g_signal_connect (etable, "selection_change",
- G_CALLBACK (table_selection_change_cb), gcal);
-
- g_signal_connect (e_calendar_table_get_model ((ECalendarTable *)priv->todo), "cal_view_progress",
- G_CALLBACK (view_progress_cb), gcal);
- g_signal_connect (e_calendar_table_get_model ((ECalendarTable *)priv->todo), "cal_view_done",
- G_CALLBACK (view_done_cb), gcal);
/* Timeout check to hide completed items */
+#if 0 /* KILL-BONOBO */
priv->update_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_todo_view_cb, gcal, NULL);
-
- /* Create the model for the views */
- cal_model = (ECalModel *) e_cal_model_calendar_new ();
- e_cal_model_set_flags (cal_model, E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES);
-
- /* The Day View. */
- priv->day_view = e_day_view_new (cal_model);
- e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->day_view), gcal);
- e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->day_view), priv->zone);
- g_signal_connect (priv->day_view, "selection_changed",
- G_CALLBACK (view_selection_changed_cb), gcal);
- connect_day_view_focus (gcal, E_DAY_VIEW (priv->day_view));
-
- /* The Work Week View. */
- priv->work_week_view = e_day_view_new (cal_model);
- e_day_view_set_work_week_view (E_DAY_VIEW (priv->work_week_view),
- TRUE);
- e_day_view_set_days_shown (E_DAY_VIEW (priv->work_week_view), 5);
- e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->work_week_view), gcal);
- e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->work_week_view), priv->zone);
- connect_day_view_focus (gcal, E_DAY_VIEW (priv->work_week_view));
+#endif
/* The Marcus Bains line */
priv->update_marcus_bains_line_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_marcus_bains_line_cb, gcal, NULL);
- /* The Week View. */
- priv->week_view = e_week_view_new (cal_model);
- e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->week_view), gcal);
- e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->week_view), priv->zone);
- g_signal_connect (priv->week_view, "selection_changed",
- G_CALLBACK (view_selection_changed_cb), gcal);
-
- connect_week_view_focus (gcal, E_WEEK_VIEW (priv->week_view));
-
- adjustment = gtk_range_get_adjustment (GTK_RANGE (E_WEEK_VIEW (priv->week_view)->vscrollbar));
- g_signal_connect (adjustment, "value_changed",
- G_CALLBACK (week_view_adjustment_changed_cb),
- gcal);
- w_model = e_calendar_view_get_model ((ECalendarView *)priv->week_view);
- g_signal_connect (w_model, "cal_view_progress",
- G_CALLBACK (view_progress_cb), gcal);
- g_signal_connect (w_model, "cal_view_done",
- G_CALLBACK (view_done_cb), gcal);
-
- /* The Month View. */
- priv->month_view = e_week_view_new (cal_model);
- e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->month_view), gcal);
- e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->month_view), priv->zone);
- e_week_view_set_multi_week_view (E_WEEK_VIEW (priv->month_view), TRUE);
- e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 6);
- g_signal_connect (priv->month_view, "selection_changed",
- G_CALLBACK (view_selection_changed_cb), gcal);
-
- connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view));
-
- adjustment = gtk_range_get_adjustment (GTK_RANGE (E_WEEK_VIEW (priv->month_view)->vscrollbar));
- g_signal_connect (adjustment, "value_changed",
- G_CALLBACK (month_view_adjustment_changed_cb),
- gcal);
-
- /* The List View. */
- priv->list_view = e_cal_list_view_new (cal_model);
-
- e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->list_view), gcal);
- e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->list_view), priv->zone);
- g_signal_connect (priv->list_view, "selection_changed",
- G_CALLBACK (view_selection_changed_cb), gcal);
-
- connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view));
-
- priv->views[GNOME_CAL_DAY_VIEW] = E_CALENDAR_VIEW (priv->day_view);
- priv->configs[GNOME_CAL_DAY_VIEW] = G_OBJECT (e_day_view_config_new (E_DAY_VIEW (priv->views[GNOME_CAL_DAY_VIEW])));
- priv->views[GNOME_CAL_WORK_WEEK_VIEW] = E_CALENDAR_VIEW (priv->work_week_view);
- priv->configs[GNOME_CAL_WORK_WEEK_VIEW] = G_OBJECT (e_day_view_config_new (E_DAY_VIEW (priv->views[GNOME_CAL_WORK_WEEK_VIEW])));
- priv->views[GNOME_CAL_WEEK_VIEW] = E_CALENDAR_VIEW (priv->week_view);
- priv->configs[GNOME_CAL_WEEK_VIEW] = G_OBJECT (e_week_view_config_new (E_WEEK_VIEW (priv->views[GNOME_CAL_WEEK_VIEW])));
- priv->views[GNOME_CAL_MONTH_VIEW] = E_CALENDAR_VIEW (priv->month_view);
- priv->configs[GNOME_CAL_MONTH_VIEW] = G_OBJECT (e_week_view_config_new (E_WEEK_VIEW (priv->views[GNOME_CAL_MONTH_VIEW])));
- priv->views[GNOME_CAL_LIST_VIEW] = E_CALENDAR_VIEW (priv->list_view);
- priv->configs[GNOME_CAL_LIST_VIEW] = G_OBJECT (e_cal_list_view_config_new (E_CAL_LIST_VIEW (priv->views[GNOME_CAL_LIST_VIEW])));
-
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
- GTK_WIDGET (priv->views[i]), gtk_label_new (""));
-
- g_signal_connect (priv->views[i], "user_created",
- G_CALLBACK (user_created_cb), gcal);
-
- gtk_widget_show (GTK_WIDGET (priv->views[i]));
- }
-
- /* Memo view */
- vbox = gtk_vbox_new (FALSE, 0);
- label = gtk_label_new (NULL);
- tmp = g_strdup_printf ("<b> %s </b>", _("Memos"));
- gtk_label_set_markup ((GtkLabel *)label, tmp);
- g_free (tmp);
- gtk_box_pack_start ((GtkBox *)vbox, label, FALSE, TRUE, 0);
- priv->memo = e_memo_table_new ();
- priv->memo_config = e_memo_table_config_new (E_MEMO_TABLE (priv->memo));
- gtk_paned_pack2 (GTK_PANED (priv->vpane), vbox, TRUE, FALSE);
- gtk_box_pack_end ((GtkBox *)vbox, priv->memo, TRUE, TRUE, 0);
-
- gtk_widget_show (priv->memo);
- gtk_widget_show (label);
- gtk_widget_show (vbox);
-
- filename = g_build_filename (memos_component_peek_config_directory (memos_component_peek ()),
- "MemoPad", NULL);
- e_memo_table_load_state (E_MEMO_TABLE (priv->memo), filename);
-
- e_cal_model_set_default_time_func (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), gc_get_default_time, gcal);
-
update_memo_view (gcal);
- g_free (filename);
-
- etable = e_memo_table_get_table (E_MEMO_TABLE (priv->memo));
- g_signal_connect (etable->table_canvas, "focus_in_event",
- G_CALLBACK (memo_canvas_focus_change_cb), gcal);
- g_signal_connect (etable->table_canvas, "focus_out_event",
- G_CALLBACK (memo_canvas_focus_change_cb), gcal);
-
- g_signal_connect (etable, "selection_change",
- G_CALLBACK (memo_selection_change_cb), gcal);
-
- g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_progress",
- G_CALLBACK (view_progress_cb), gcal);
- g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_done",
- G_CALLBACK (view_done_cb), gcal);
-
}
/* Object initialization function for the gnome calendar */
@@ -1886,18 +1367,17 @@ static void
gnome_calendar_init (GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
- gint i;
priv = g_new0 (GnomeCalendarPrivate, 1);
gcal->priv = priv;
- for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++)
- priv->clients[i] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
if (non_intrusive_error_table == NULL)
non_intrusive_error_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
- e_categories_register_change_listener (G_CALLBACK (categories_changed_cb), gcal);
+ if (non_intrusive_error_table == NULL)
+ non_intrusive_error_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
priv->todo_update_lock = g_mutex_new ();
@@ -1905,21 +1385,13 @@ gnome_calendar_init (GnomeCalendar *gcal)
priv->range_selected = FALSE;
priv->lview_select_daten_range = TRUE;
- setup_config (gcal);
setup_widgets (gcal);
- priv->calendar_menu = e_cal_menu_new("org.gnome.evolution.calendar.view");
- priv->taskpad_menu = e_cal_menu_new("org.gnome.evolution.calendar.taskpad");
- priv->memopad_menu = e_cal_menu_new ("org.gnome.evolution.calendar.memopad");
-
priv->dn_queries = NULL;
priv->sexp = g_strdup ("#t"); /* Match all */
priv->todo_sexp = g_strdup ("#t");
priv->memo_sexp = g_strdup ("#t");
- priv->view_instance = NULL;
- priv->view_menus = NULL;
-
priv->visible_start = -1;
priv->visible_end = -1;
priv->updating = FALSE;
@@ -1931,7 +1403,6 @@ gnome_calendar_destroy (GtkObject *object)
GnomeCalendar *gcal;
GnomeCalendarPrivate *priv;
gchar *filename;
- ECalModel *cal_model;
g_return_if_fail (object != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (object));
@@ -1943,67 +1414,45 @@ gnome_calendar_destroy (GtkObject *object)
GList *l;
gint i;
- e_categories_unregister_change_listener (G_CALLBACK (categories_changed_cb), gcal);
-
- /* Clean up the clients */
- for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) {
- for (l = priv->clients_list[i]; l != NULL; l = l->next) {
- ESource *source = e_cal_get_source (l->data);
-
- g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
-
- if (source)
- g_signal_handlers_disconnect_matched (source, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
- }
-
- g_hash_table_destroy (priv->clients[i]);
- g_list_free (priv->clients_list[i]);
-
- priv->clients[i] = NULL;
- priv->clients_list[i] = NULL;
+ if (priv->shell_settings != NULL) {
+ g_object_unref (priv->shell_settings);
+ priv->shell_settings = NULL;
+ }
- if (priv->default_client[i]) {
- ESource *source = e_cal_get_source (priv->default_client[i]);
+ if (priv->model != NULL) {
+ g_signal_handlers_disconnect_by_func (
+ priv->model, view_progress_cb, gcal);
+ g_signal_handlers_disconnect_by_func (
+ priv->model, view_done_cb, gcal);
+ g_object_unref (priv->model);
+ priv->model = NULL;
+ }
- g_signal_handlers_disconnect_matched (priv->default_client[i],
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
+ /* Clean up the clients */
+ for (l = priv->clients_list; l != NULL; l = l->next) {
+ g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, gcal);
+ }
- if (source)
- g_signal_handlers_disconnect_matched (source, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
+ g_hash_table_destroy (priv->clients);
+ g_list_free (priv->clients_list);
- g_object_unref (priv->default_client[i]);
- }
- priv->default_client[i] = NULL;
- }
+ priv->clients = NULL;
+ priv->clients_list = NULL;
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
- if (priv->configs[i])
- g_object_unref (priv->configs[i]);
- priv->configs[i] = NULL;
+ if (priv->default_client) {
+ g_signal_handlers_disconnect_matched (priv->default_client,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, gcal);
+ g_object_unref (priv->default_client);
}
- g_object_unref (priv->date_navigator_config);
- g_object_unref (priv->todo_config);
- g_object_unref (priv->memo_config);
+ priv->default_client = NULL;
for (l = priv->notifications; l; l = l->next)
calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
g_list_free (priv->notifications);
priv->notifications = NULL;
- /* Save the TaskPad layout. */
- filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
- "TaskPad", NULL);
- e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename);
- g_free (filename);
-
- /* Save the MemoPad layout. */
- filename = g_build_filename (memos_component_peek_config_directory (memos_component_peek ()),
- "MemoPad", NULL);
- e_memo_table_save_state (E_MEMO_TABLE (priv->memo), filename);
- g_free (filename);
-
if (priv->dn_queries) {
for (l = priv->dn_queries; l != NULL; l = l->next) {
g_signal_handlers_disconnect_matched ((ECalView *) l->data, G_SIGNAL_MATCH_DATA,
@@ -2025,69 +1474,16 @@ gnome_calendar_destroy (GtkObject *object)
priv->sexp = NULL;
}
- if (priv->todo_sexp) {
- g_free (priv->todo_sexp);
- priv->todo_sexp = NULL;
- }
-
- if (priv->memo_sexp) {
- g_free (priv->memo_sexp);
- priv->memo_sexp = NULL;
- }
-
if (priv->update_timeout) {
g_source_remove (priv->update_timeout);
priv->update_timeout = 0;
}
- if (priv->view_instance) {
- g_object_unref (priv->view_instance);
- priv->view_instance = NULL;
- }
-
if (priv->update_marcus_bains_line_timeout) {
g_source_remove (priv->update_marcus_bains_line_timeout);
priv->update_marcus_bains_line_timeout = 0;
}
- if (priv->view_menus) {
- g_object_unref (priv->view_menus);
- priv->view_menus = NULL;
- }
-
- if (priv->calendar_menu) {
- g_object_unref (priv->calendar_menu);
- priv->calendar_menu = NULL;
- }
-
- if (priv->taskpad_menu) {
- g_object_unref (priv->taskpad_menu);
- priv->taskpad_menu = NULL;
- }
-
- if (priv->memopad_menu) {
- g_object_unref (priv->memopad_menu);
- priv->memopad_menu = NULL;
- }
- /* Disconnect all handlers */
- cal_model = e_calendar_view_get_model ((ECalendarView *)priv->week_view);
- g_signal_handlers_disconnect_by_func (cal_model,
- G_CALLBACK (view_progress_cb), gcal);
- g_signal_handlers_disconnect_by_func (cal_model,
- G_CALLBACK (view_done_cb), gcal);
-
- cal_model = e_calendar_table_get_model ((ECalendarTable *) priv->todo);
- g_signal_handlers_disconnect_by_func (cal_model,
- G_CALLBACK (view_progress_cb), gcal);
- g_signal_handlers_disconnect_by_func (cal_model,
- G_CALLBACK (view_done_cb), gcal);
-
- cal_model = e_memo_table_get_model ((EMemoTable *)priv->memo);
- g_signal_handlers_disconnect_by_func (cal_model,
- G_CALLBACK (view_progress_cb), gcal);
- g_signal_handlers_disconnect_by_func (cal_model,
- G_CALLBACK (view_done_cb), gcal);
-
g_mutex_free (priv->todo_update_lock);
g_free (priv);
@@ -2114,14 +1510,17 @@ static void
gnome_calendar_goto_date (GnomeCalendar *gcal,
GnomeCalendarGotoDateType goto_date)
{
- GnomeCalendarPrivate *priv;
+ ECalModel *model;
time_t new_time = 0;
+ gint week_start_day;
gboolean need_updating = FALSE;
+ icaltimezone *timezone;
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR(gcal));
- priv = gcal->priv;
+ model = gnome_calendar_get_model (gcal);
+ week_start_day = e_cal_model_get_week_start_day (model);
+ timezone = e_cal_model_get_timezone (model);
switch (goto_date) {
/* GNOME_CAL_GOTO_TODAY and GNOME_CAL_GOTO_DATE are
@@ -2132,39 +1531,45 @@ gnome_calendar_goto_date (GnomeCalendar *gcal,
case GNOME_CAL_GOTO_DATE:
break;
case GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH:
- new_time = time_month_begin_with_zone (priv->base_view_time, priv->zone);
+ new_time = time_month_begin_with_zone (
+ gcal->priv->base_view_time, timezone);
need_updating = TRUE;
break;
case GNOME_CAL_GOTO_LAST_DAY_OF_MONTH:
- new_time = time_add_month_with_zone (priv->base_view_time, 1, priv->zone);
- new_time = time_month_begin_with_zone (new_time, priv->zone);
- new_time = time_add_day_with_zone (new_time, -1, priv->zone);
+ new_time = time_add_month_with_zone (
+ gcal->priv->base_view_time, 1, timezone);
+ new_time = time_month_begin_with_zone (new_time, timezone);
+ new_time = time_add_day_with_zone (new_time, -1, timezone);
need_updating = TRUE;
break;
case GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK:
- new_time = time_week_begin_with_zone (priv->base_view_time, priv->week_start, priv->zone);
+ new_time = time_week_begin_with_zone (
+ gcal->priv->base_view_time, week_start_day, timezone);
need_updating = TRUE;
break;
case GNOME_CAL_GOTO_LAST_DAY_OF_WEEK:
- new_time = time_week_begin_with_zone (priv->base_view_time, priv->week_start, priv->zone);
- if (priv->current_view_type == GNOME_CAL_DAY_VIEW ||
- priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) {
+ new_time = time_week_begin_with_zone (
+ gcal->priv->base_view_time, week_start_day, timezone);
+ if (gcal->priv->current_view_type == GNOME_CAL_DAY_VIEW ||
+ gcal->priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) {
/* FIXME Shouldn't hard code work week end */
/* goto Friday of this week */
- new_time = time_add_day_with_zone (new_time, 4, priv->zone);
+ new_time = time_add_day_with_zone (new_time, 4, timezone);
} else {
/* goto Sunday of this week */
/* FIXME Shouldn't hard code week end */
- new_time = time_add_day_with_zone (new_time, 6, priv->zone);
+ new_time = time_add_day_with_zone (new_time, 6, timezone);
}
need_updating = TRUE;
break;
case GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK:
- new_time = time_add_week_with_zone (priv->base_view_time, -1, priv->zone);
+ new_time = time_add_week_with_zone (
+ gcal->priv->base_view_time, -1, timezone);
need_updating = TRUE;
break;
case GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK:
- new_time = time_add_week_with_zone (priv->base_view_time, 1, priv->zone);
+ new_time = time_add_week_with_zone (
+ gcal->priv->base_view_time, 1, timezone);
need_updating = TRUE;
break;
default:
@@ -2172,9 +1577,7 @@ gnome_calendar_goto_date (GnomeCalendar *gcal,
}
if (need_updating) {
- update_view_times (gcal, new_time);
- gnome_calendar_update_date_navigator (gcal);
- gnome_calendar_notify_dates_shown_changed (gcal);
+ gnome_calendar_set_selected_time_range (gcal, new_time);
notify_selected_time_changed (gcal);
}
}
@@ -2185,15 +1588,12 @@ gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time)
GnomeCalendarPrivate *priv;
gint i;
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
g_return_if_fail (new_time != -1);
priv = gcal->priv;
- update_view_times (gcal, new_time);
- gnome_calendar_update_date_navigator (gcal);
- gnome_calendar_notify_dates_shown_changed (gcal);
+ gnome_calendar_set_selected_time_range (gcal, new_time);
for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (priv->views[i]))->set_selected_time_range)
@@ -2201,19 +1601,23 @@ gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time)
}
}
-static void
-update_view_times (GnomeCalendar *gcal, time_t start_time)
+void
+gnome_calendar_update_view_times (GnomeCalendar *gcal,
+ time_t start_time)
{
GnomeCalendarPrivate *priv;
ECalModel *model;
time_t real_start_time = start_time;
time_t end_time, select_time = 0;
+ g_return_if_fail (GNOME_IS_CALENDAR (gcal));
+
priv = gcal->priv;
priv->base_view_time = start_time;
- model = e_calendar_view_get_model (priv->views [priv->current_view_type]);
+ model = gnome_calendar_get_model (gcal);
+
get_times_for_views (gcal, priv->current_view_type, &real_start_time, &end_time, &select_time);
if (priv->current_view_type == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range)
@@ -2222,42 +1626,44 @@ update_view_times (GnomeCalendar *gcal, time_t start_time)
e_cal_model_set_time_range (model, real_start_time, end_time);
if (select_time != 0 && select_time >= real_start_time && select_time <= end_time)
- e_calendar_view_set_selected_time_range (priv->views [priv->current_view_type], select_time, select_time);
+ e_calendar_view_set_selected_time_range (priv->views[priv->current_view_type], select_time, select_time);
}
static void
gnome_calendar_direction (GnomeCalendar *gcal, gint direction)
{
- GnomeCalendarPrivate *priv;
+ ECalModel *model;
+ icaltimezone *timezone;
- priv = gcal->priv;
+ model = gnome_calendar_get_model (gcal);
+ timezone = e_cal_model_get_timezone (model);
- switch (priv->current_view_type) {
+ switch (gnome_calendar_get_view (gcal)) {
case GNOME_CAL_DAY_VIEW:
- priv->base_view_time = time_add_day_with_zone (priv->base_view_time, direction, priv->zone);
+ gcal->priv->base_view_time = time_add_day_with_zone (
+ gcal->priv->base_view_time, direction, timezone);
break;
case GNOME_CAL_WORK_WEEK_VIEW:
case GNOME_CAL_WEEK_VIEW:
- priv->base_view_time = time_add_week_with_zone (priv->base_view_time, direction, priv->zone);
+ gcal->priv->base_view_time = time_add_week_with_zone (
+ gcal->priv->base_view_time, direction, timezone);
break;
- case GNOME_CAL_LIST_VIEW:
- g_warning ("Using month view time interval for list view.");
case GNOME_CAL_MONTH_VIEW:
- priv->base_view_time = time_add_month_with_zone (priv->base_view_time, direction, priv->zone);
+ case GNOME_CAL_LIST_VIEW:
+ gcal->priv->base_view_time = time_add_month_with_zone (
+ gcal->priv->base_view_time, direction, timezone);
break;
default:
g_return_if_reached ();
}
- update_view_times (gcal, priv->base_view_time);
- gnome_calendar_update_date_navigator (gcal);
- gnome_calendar_notify_dates_shown_changed (gcal);
+ gnome_calendar_set_selected_time_range (
+ gcal, gcal->priv->base_view_time);
}
void
gnome_calendar_next (GnomeCalendar *gcal)
{
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
gnome_calendar_direction (gcal, 1);
@@ -2266,7 +1672,6 @@ gnome_calendar_next (GnomeCalendar *gcal)
void
gnome_calendar_previous (GnomeCalendar *gcal)
{
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
gnome_calendar_direction (gcal, -1);
@@ -2275,33 +1680,34 @@ gnome_calendar_previous (GnomeCalendar *gcal)
void
gnome_calendar_dayjump (GnomeCalendar *gcal, time_t time)
{
- GnomeCalendarPrivate *priv;
+ ECalModel *model;
+ icaltimezone *timezone;
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- priv = gcal->priv;
+ model = gnome_calendar_get_model (gcal);
+ timezone = e_cal_model_get_timezone (model);
- priv->base_view_time = time_day_begin_with_zone (time, priv->zone);
+ gcal->priv->base_view_time =
+ time_day_begin_with_zone (time, timezone);
- update_view_times (gcal, priv->base_view_time);
+ gnome_calendar_update_view_times (gcal, gcal->priv->base_view_time);
gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW);
}
-static void
-focus_current_view (GnomeCalendar *gcal)
-{
- gtk_widget_grab_focus (gnome_calendar_get_current_view_widget (gcal));
-}
-
void
gnome_calendar_goto_today (GnomeCalendar *gcal)
{
- g_return_if_fail (gcal != NULL);
+ GnomeCalendarViewType view_type;
+ ECalendarView *view;
+
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
+ view_type = gnome_calendar_get_view (gcal);
+ view = gnome_calendar_get_calendar_view (gcal, view_type);
+
gnome_calendar_goto (gcal, time (NULL));
- focus_current_view (gcal);
+ gtk_widget_grab_focus (GTK_WIDGET (view));
}
/**
@@ -2315,56 +1721,9 @@ gnome_calendar_goto_today (GnomeCalendar *gcal)
GnomeCalendarViewType
gnome_calendar_get_view (GnomeCalendar *gcal)
{
- GnomeCalendarPrivate *priv;
-
- g_return_val_if_fail (gcal != NULL, GNOME_CAL_DAY_VIEW);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), GNOME_CAL_DAY_VIEW);
- priv = gcal->priv;
- return priv->current_view_type;
-}
-
-static void
-set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean range_selected)
-{
- GnomeCalendarPrivate *priv;
- const gchar *view_id;
-
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- priv = gcal->priv;
-
- switch (view_type) {
- case GNOME_CAL_DAY_VIEW:
- view_id = "Day_View";
- break;
-
- case GNOME_CAL_WORK_WEEK_VIEW:
- view_id = "Work_Week_View";
- break;
-
- case GNOME_CAL_WEEK_VIEW:
- view_id = "Week_View";
- break;
-
- case GNOME_CAL_MONTH_VIEW:
- view_id = "Month_View";
- break;
-
- case GNOME_CAL_LIST_VIEW:
- view_id = "List_View";
- break;
-
- default:
- g_return_if_reached ();
- }
-
- priv->range_selected = range_selected;
- priv->current_view_type = view_type;
-
- gal_view_instance_set_current_view_id (priv->view_instance, view_id);
- focus_current_view (gcal);
+ return gcal->priv->current_view_type;
}
/**
@@ -2377,34 +1736,46 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean range_s
* the view; otherwise the last configuration will be kept.
**/
void
-gnome_calendar_set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type)
+gnome_calendar_set_view (GnomeCalendar *gcal,
+ GnomeCalendarViewType view_type)
{
- g_return_if_fail (gcal != NULL);
+ ECalendarView *calendar_view;
+
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- set_view (gcal, view_type, FALSE);
+ gcal->priv->current_view_type = view_type;
+ gnome_calendar_set_range_selected (gcal, FALSE);
+
+ calendar_view = gnome_calendar_get_calendar_view (gcal, view_type);
+ gtk_widget_grab_focus (GTK_WIDGET (calendar_view));
+
+ g_object_notify (G_OBJECT (gcal), "view");
}
-/* Sets the view without changing the selection or updating the date
- * navigator. If a range of dates isn't selected it will also reset the number
- * of days/weeks shown to the default (i.e. 1 day for the day view or 5 weeks
- * for the month view).
- */
-static void
-display_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean grab_focus)
+void
+gnome_calendar_display_view (GnomeCalendar *gcal,
+ GnomeCalendarViewType view_type)
{
- GnomeCalendarPrivate *priv;
+ CalendarView *cal_view;
+ ECalendarView *view;
gboolean preserve_day;
- gint i;
+ gboolean range_selected;
+ time_t start_time;
+ gint ii;
- priv = gcal->priv;
+ view = gnome_calendar_get_calendar_view (gcal, view_type);
+
+ /* Set the view without changing the selection or updating the date
+ * navigator. If a range of dates isn't selected, also reset the
+ * number of days/weeks shown to the default (i.e. 1 day for the
+ * day view or 6 weeks for the month view). */
preserve_day = FALSE;
switch (view_type) {
case GNOME_CAL_DAY_VIEW:
- if (!priv->range_selected)
- e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), 1);
+ if (!gnome_calendar_get_range_selected (gcal))
+ e_day_view_set_days_shown (E_DAY_VIEW (view), 1);
gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
break;
@@ -2420,15 +1791,15 @@ display_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean gra
break;
case GNOME_CAL_MONTH_VIEW:
- if (!priv->range_selected)
- e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 6);
+ if (!gnome_calendar_get_range_selected (gcal))
+ e_week_view_set_weeks_shown (E_WEEK_VIEW (view), 6);
preserve_day = TRUE;
gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
break;
case GNOME_CAL_LIST_VIEW:
- if (!priv->lview_select_daten_range)
+ if (!gcal->priv->lview_select_daten_range)
gtk_widget_hide (GTK_WIDGET (gcal->priv->date_navigator));
else
gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
@@ -2438,345 +1809,32 @@ display_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean gra
g_return_if_reached ();
}
- priv->current_view_type = view_type;
- E_CALENDAR_VIEW (priv->views [view_type])->in_focus = TRUE;
+ range_selected = gnome_calendar_get_range_selected (gcal);
+ gnome_calendar_set_view (gcal, view_type);
+ gnome_calendar_set_range_selected (gcal, range_selected);
- gtk_notebook_set_current_page (
- GTK_NOTEBOOK (priv->notebook), (gint) view_type);
-
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
- if (i == view_type)
+ /* XXX Move this to set_view()? */
+ E_CALENDAR_VIEW (gcal->priv->views[view_type])->in_focus = TRUE;
+ for (ii = 0; ii < GNOME_CAL_LAST_VIEW; ii++) {
+ if (ii == view_type)
continue;
- E_CALENDAR_VIEW (priv->views [i])->in_focus = FALSE;
+ E_CALENDAR_VIEW (gcal->priv->views[ii])->in_focus = FALSE;
}
- if (grab_focus)
- focus_current_view (gcal);
-
- gnome_calendar_set_pane_positions (gcal);
-
/* For the week & month views we want the selection in the date
navigator to be rounded to the nearest week when the arrow buttons
are pressed to move to the previous/next month. */
- g_object_set (G_OBJECT (priv->date_navigator->calitem),
- "preserve_day_when_moving", preserve_day,
- NULL);
-}
-
-static void gnome_calendar_change_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type)
-{
- if (gnome_calendar_get_view(gcal) == view_type)
- return;
-
- gnome_calendar_set_view(gcal, view_type);
-}
-
-/* Callback used when the view collection asks us to display a particular view */
-static void
-display_view_cb (GalViewInstance *view_instance, GalView *view, gpointer data)
-{
- GnomeCalendar *gcal;
- GnomeCalendarPrivate *priv;
- CalendarView *cal_view;
- GnomeCalendarViewType view_type;
-
- gcal = GNOME_CALENDAR (data);
- priv = gcal->priv;
+ g_object_set (
+ gcal->priv->date_navigator->calitem,
+ "preserve_day_when_moving", preserve_day, NULL);
- if (GAL_IS_VIEW_ETABLE(view)) {
- ETable *table;
-
- view_type = GNOME_CAL_LIST_VIEW;
-
- table = e_table_scrolled_get_table (E_CAL_LIST_VIEW (priv->list_view)->table_scrolled);
- gal_view_etable_attach_table (GAL_VIEW_ETABLE (view), table);
- } else if (IS_CALENDAR_VIEW (view)) {
- cal_view = CALENDAR_VIEW (view);
-
- view_type = calendar_view_get_view_type (cal_view);
- } else {
- g_error (G_STRLOC ": Unknown type of view for GnomeCalendar");
- return;
- }
-
- display_view (gcal, view_type, TRUE);
-
- if (!priv->base_view_time)
- update_view_times (gcal, time (NULL));
+ if (!gcal->priv->base_view_time)
+ start_time = time (NULL);
else
- update_view_times (gcal, priv->base_view_time);
-
- gnome_calendar_update_date_navigator (gcal);
- gnome_calendar_notify_dates_shown_changed (gcal);
-
-}
-
-/**
- * gnome_calendar_setup_view_menus:
- * @gcal: A calendar.
- * @uic: UI controller to use for the menus.
- *
- * Sets up the #GalView menus for a calendar. This function should be called
- * from the Bonobo control activation callback for this calendar. Also, the
- * menus should be discarded using gnome_calendar_discard_view_menus().
- **/
-void
-gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic)
-{
- GnomeCalendarPrivate *priv;
- gchar *path0, *path1, *etspecfile;
- CalendarViewFactory *factory;
- GalViewFactory *gal_factory;
- static GalViewCollection *collection = NULL;
-
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- g_return_if_fail (uic != NULL);
- g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
-
- priv = gcal->priv;
-
- g_return_if_fail (priv->view_instance == NULL);
- g_return_if_fail (priv->view_menus == NULL);
-
- /* Create the view instance */
- if (collection == NULL) {
- ETableSpecification *spec;
-
- collection = gal_view_collection_new ();
-
- gal_view_collection_set_title (collection, _("Calendar"));
-
- path0 = g_build_filename (EVOLUTION_GALVIEWSDIR,
- "calendar",
- NULL);
- path1 = g_build_filename (calendar_component_peek_base_directory (calendar_component_peek ()),
- "views", NULL);
- gal_view_collection_set_storage_directories (collection,
- path0,
- path1);
- g_free (path1);
- g_free (path0);
-
- /* Create the views */
-
- factory = calendar_view_factory_new (GNOME_CAL_DAY_VIEW);
- gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
- g_object_unref (factory);
-
- factory = calendar_view_factory_new (GNOME_CAL_WORK_WEEK_VIEW);
- gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
- g_object_unref (factory);
-
- factory = calendar_view_factory_new (GNOME_CAL_WEEK_VIEW);
- gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
- g_object_unref (factory);
-
- factory = calendar_view_factory_new (GNOME_CAL_MONTH_VIEW);
- gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
- g_object_unref (factory);
-
- spec = e_table_specification_new ();
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "e-cal-list-view.etspec",
- NULL);
- if (!e_table_specification_load_from_file (spec, etspecfile))
- g_error ("Unable to load ETable specification file "
- "for calendar");
- g_free (etspecfile);
- gal_factory = gal_view_factory_etable_new (spec);
- g_object_unref (spec);
- gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (gal_factory));
- g_object_unref (gal_factory);
-
- /* Load the collection and create the menus */
-
- gal_view_collection_load (collection);
-
- }
-
- priv->view_instance = gal_view_instance_new (collection, NULL);
- priv->view_menus = gal_view_menus_new (priv->view_instance);
- gal_view_menus_apply (priv->view_menus, uic, NULL);
-
- g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), gcal);
- display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), gcal);
-}
-
-/**
- * gnome_calendar_discard_view_menus:
- * @gcal: A calendar.
- *
- * Discards the #GalView menus used by a calendar. This function should be
- * called from the Bonobo control deactivation callback for this calendar. The
- * menus should have been set up with gnome_calendar_setup_view_menus().
- **/
-void
-gnome_calendar_discard_view_menus (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
-
- g_return_if_fail (gcal != NULL);
-
- priv = gcal->priv;
-
- g_return_if_fail (priv->view_instance != NULL);
- g_return_if_fail (priv->view_menus != NULL);
-
- g_object_unref (priv->view_instance);
- priv->view_instance = NULL;
-
- g_object_unref (priv->view_menus);
- priv->view_menus = NULL;
-}
-
-/* This is copied/moved from gal-view-instance, only the calendar uses this for a popup menu */
-static void
-gc_set_view(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- GnomeCalendar *gcal = data;
-
- if (pitem->type & E_POPUP_ACTIVE)
- gal_view_instance_set_current_view_id(gcal->priv->view_instance, (gchar *)pitem->user_data);
-}
-
-static void
-gc_save_custom_view(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- GnomeCalendar *gcal = data;
-
- gal_view_instance_save_as(gcal->priv->view_instance);
-}
-
-static void
-gc_define_views_response(GtkWidget *d, gint id, GnomeCalendar *gcal)
-{
- if (id == GTK_RESPONSE_OK)
- gal_view_collection_save(gcal->priv->view_instance->collection);
-
- gtk_widget_destroy(d);
-}
-
-static void
-gc_define_views(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- GnomeCalendar *gcal = data;
- GtkWidget *dialog = gal_define_views_dialog_new(gcal->priv->view_instance->collection);
-
- g_signal_connect(dialog, "response", G_CALLBACK(gc_define_views_response), data);
- gtk_widget_show(dialog);
-}
-
-static EPopupItem gc_popups[] = {
- /* Code generates the path to fit */
- { E_POPUP_BAR, NULL },
- { E_POPUP_RADIO|E_POPUP_ACTIVE, NULL, (gchar *) N_("_Custom View"), },
- { E_POPUP_ITEM, NULL, (gchar *) N_("_Save Custom View"), gc_save_custom_view },
-
- /* index == 3, when we have non-custom view */
-
- { E_POPUP_BAR, NULL },
- { E_POPUP_ITEM, NULL, (gchar *) N_("_Define Views..."), gc_define_views },
-};
-
-static void
-gc_popup_free (EPopup *ep, GSList *list, gpointer data)
-{
- while (list) {
- GSList *n = list->next;
- EPopupItem *pitem = list->data;
-
- g_free(pitem->path);
- g_free(pitem->label);
- g_free(pitem->user_data);
- g_free(pitem);
- g_slist_free_1(list);
- list = n;
- }
-}
-
-static void
-gc_popup_free_static (EPopup *ep, GSList *list, gpointer data)
-{
- while (list) {
- GSList *n = list->next;
- EPopupItem *pitem = list->data;
-
- g_free(pitem->path);
- g_free(pitem);
- g_slist_free_1(list);
- list = n;
- }
-}
-
-void
-gnome_calendar_view_popup_factory (GnomeCalendar *gcal, EPopup *ep, const gchar *prefix)
-{
- GnomeCalendarPrivate *priv;
- gint length;
- gint i;
- gboolean found = FALSE;
- gchar *id;
- GSList *menus = NULL;
- EPopupItem *pitem;
-
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- g_return_if_fail (prefix != NULL);
+ start_time = gcal->priv->base_view_time;
- priv = gcal->priv;
-
- g_return_if_fail (priv->view_instance != NULL);
-
- length = gal_view_collection_get_count(priv->view_instance->collection);
- id = gal_view_instance_get_current_view_id (priv->view_instance);
-
- for (i = 0; i < length; i++) {
- GalViewCollectionItem *item = gal_view_collection_get_view_item(priv->view_instance->collection, i);
-
- pitem = g_malloc0(sizeof(*pitem));
- pitem->type = E_POPUP_RADIO;
- pitem->path = g_strdup_printf("%s/%02d.item", prefix, i);
- pitem->label = g_strdup(item->title);
- pitem->activate = gc_set_view;
- pitem->user_data = g_strdup(item->id);
-
- if (!found && id && !strcmp (id, item->id)) {
- found = TRUE;
- pitem->type |= E_POPUP_ACTIVE;
- }
-
- menus = g_slist_prepend(menus, pitem);
- }
+ gnome_calendar_set_selected_time_range (gcal, start_time);
- if (menus)
- e_popup_add_items(ep, menus, NULL, gc_popup_free, gcal);
-
- menus = NULL;
- for (i = found?3:0; i<sizeof(gc_popups)/sizeof(gc_popups[0]);i++) {
- pitem = g_malloc0(sizeof(*pitem));
- memcpy(pitem, &gc_popups[i], sizeof(*pitem));
- pitem->path = g_strdup_printf("%s/%02d.item", prefix, i+length);
- menus = g_slist_prepend(menus, pitem);
- }
-
- e_popup_add_items(ep, menus, NULL, gc_popup_free_static, gcal);
-}
-
-static void
-gnome_calendar_set_pane_positions (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
-
- priv = gcal->priv;
-
- if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
- gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos_month_view);
- gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view);
- } else {
- gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos);
- gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos);
- }
}
struct _mclient_msg {
@@ -2818,7 +1876,6 @@ static void
client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
- ECalSourceType source_type;
ESource *source;
ECalModel *model;
ECalLoadState state;
@@ -2828,23 +1885,9 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
priv = gcal->priv;
- source_type = e_cal_get_source_type (ecal);
source = e_cal_get_source (ecal);
state = e_cal_get_load_state (ecal);
- switch (source_type) {
- case E_CAL_SOURCE_TYPE_EVENT:
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
- break;
- case E_CAL_SOURCE_TYPE_TODO:
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
- break;
- case E_CAL_SOURCE_TYPE_JOURNAL:
- e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
- default:
- break;
- }
-
if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
auth_cal_forget_password (ecal);
@@ -2865,7 +1908,7 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
}
w = e_error_new(NULL, "calendar:server-version", NULL);
- e_calendar_utils_show_error_silent (w);
+ /*e_calendar_utils_show_error_silent (w); KILL-BONOBO */
g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w));
g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id);
@@ -2876,32 +1919,27 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
e_cal_open_async (ecal, FALSE);
return;
case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
- if (source_type == E_CAL_SOURCE_TYPE_EVENT)
- {
- /* check to see if we have dialog already running for this operation */
- id = g_strdup ("calendar:unable-to-load-the-calendar");
-
- if (g_hash_table_lookup(non_intrusive_error_table, id)) {
- /* We already have it */
- g_message("Error occurred while existing dialog active:\n");
- return;
- }
+ /* check to see if we have dialog already running for this operation */
+ id = g_strdup ("calendar:unable-to-load-the-calendar");
- w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:unable-to-load-the-calendar", e_cal_get_error_message (status), NULL);
- e_calendar_utils_show_error_silent (w);
- g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w));
- g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id);
+ if (g_hash_table_lookup(non_intrusive_error_table, id)) {
+ /* We already have it */
+ g_message("Error occurred while existing dialog active:\n");
+ return;
}
+
+ w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:unable-to-load-the-calendar", e_cal_get_error_message (status), NULL);
+ /*e_calendar_utils_show_error_silent (w); KILL-BONOBO */
+ g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w));
+ g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id);
default:
/* Make sure the source doesn't disappear on us */
g_object_ref (source);
- g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
-
- priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal);
- g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source));
+ priv->clients_list = g_list_remove (priv->clients_list, ecal);
+ g_hash_table_remove (priv->clients, e_source_peek_uid (source));
- g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
+ g_signal_emit (gcal, signals[SOURCE_REMOVED], 0, source);
g_object_unref (source);
g_warning ("Unable to load the calendar %s \n", e_cal_get_error_message (status));
@@ -2911,74 +1949,36 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL);
- switch (source_type) {
- case E_CAL_SOURCE_TYPE_EVENT :
- msg = g_strdup_printf (_("Loading appointments at %s"), e_cal_get_uri (ecal));
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1);
- g_free (msg);
-
- /* add client to the views */
- model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
- add_mclient (model, ecal);
-
- /* update date navigator query */
- update_query (gcal);
-
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
- break;
+ msg = g_strdup_printf (_("Loading appointments at %s"), e_cal_get_uri (ecal));
+ /*e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); KILL-BONOBO */
+ g_free (msg);
- case E_CAL_SOURCE_TYPE_TODO :
- msg = g_strdup_printf (_("Loading tasks at %s"), e_cal_get_uri (ecal));
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), msg, -1);
- g_free (msg);
+ /* add client to the views */
+ model = gnome_calendar_get_model (gcal);
+ add_mclient (model, ecal);
- e_cal_model_add_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)), ecal);
+ /* update date navigator query */
+ gnome_calendar_update_query (gcal);
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
- break;
- case E_CAL_SOURCE_TYPE_JOURNAL:
- msg = g_strdup_printf (_("Loading memos at %s"), e_cal_get_uri (ecal));
- e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), msg);
- g_free (msg);
- e_cal_model_add_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), ecal);
- e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
- break;
- default:
- g_return_if_reached ();
- }
+ /*e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); KILL-BONOBO */
}
static void
default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
- ECalSourceType source_type;
ESource *source;
ECalLoadState state;
+ ECalModel *model;
priv = gcal->priv;
- source_type = e_cal_get_source_type (ecal);
source = e_cal_get_source (ecal);
state = e_cal_get_load_state (ecal);
if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
auth_cal_forget_password (ecal);
- switch (source_type) {
- case E_CAL_SOURCE_TYPE_EVENT:
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
- break;
- case E_CAL_SOURCE_TYPE_TODO:
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
- break;
- case E_CAL_SOURCE_TYPE_JOURNAL:
- e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
- break;
- default:
- break;
- }
-
switch (status) {
case E_CALENDAR_STATUS_OK:
break;
@@ -2999,15 +1999,15 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar
g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
/* FIXME should we do this to prevent multiple error dialogs? */
- priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal);
- g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source));
+ priv->clients_list = g_list_remove (priv->clients_list, ecal);
+ g_hash_table_remove (priv->clients, e_source_peek_uid (source));
/* FIXME Is there a better way to handle this? */
- if (priv->default_client[source_type])
- g_object_unref (priv->default_client[source_type]);
- priv->default_client[source_type] = NULL;
+ if (priv->default_client)
+ g_object_unref (priv->default_client);
+ priv->default_client = NULL;
- g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
+ g_signal_emit (gcal, signals[SOURCE_REMOVED], 0, source);
g_object_unref (source);
g_warning ("Unable to load the calendar %s \n", e_cal_get_error_message (status));
@@ -3017,22 +2017,8 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar
g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL);
- switch (source_type) {
- case E_CAL_SOURCE_TYPE_EVENT:
- e_cal_model_set_default_client (
- e_calendar_view_get_model (E_CALENDAR_VIEW (priv->views[priv->current_view_type])),
- ecal);
- break;
-
- case E_CAL_SOURCE_TYPE_TODO:
- e_cal_model_set_default_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)), ecal);
- break;
- case E_CAL_SOURCE_TYPE_JOURNAL:
- e_cal_model_set_default_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), ecal);
- break;
- default:
- break;
- }
+ model = gnome_calendar_get_model (gcal);
+ e_cal_model_set_default_client (model, ecal);
}
typedef void (*open_func) (ECal *, ECalendarStatus, GnomeCalendar *);
@@ -3050,20 +2036,7 @@ open_ecal (GnomeCalendar *gcal, ECal *cal, gboolean only_if_exists, open_func of
e_cal_set_default_timezone (cal, zone, NULL);
msg = g_strdup_printf (_("Opening %s"), e_cal_get_uri (cal));
- switch (e_cal_get_source_type (cal)) {
- case E_CAL_SOURCE_TYPE_EVENT :
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1);
- break;
- case E_CAL_SOURCE_TYPE_TODO :
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), msg, -1);
- break;
- case E_CAL_SOURCE_TYPE_JOURNAL:
- e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), msg);
- break;
- default:
- g_free (msg);
- g_return_val_if_reached (FALSE);
- }
+ /*e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); KILL-BONOBO */
g_free (msg);
@@ -3094,7 +2067,7 @@ backend_error_cb (ECal *client, const gchar *message, gpointer data)
}
dialog = (GtkDialog *)e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:error-on-loading-the-calendar", uristr, message, NULL);
- e_calendar_utils_show_error_silent(GTK_WIDGET (dialog));
+ /* e_calendar_utils_show_error_silent(GTK_WIDGET (dialog)); KILL-BONOBO */
g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(dialog));
g_signal_connect(GTK_WIDGET (dialog), "destroy", G_CALLBACK(non_intrusive_error_remove), id);
@@ -3108,7 +2081,6 @@ backend_died_cb (ECal *ecal, gpointer data)
{
GnomeCalendar *gcal;
GnomeCalendarPrivate *priv;
- ECalSourceType source_type;
ESource *source;
const gchar *id;
GtkWidget *w = NULL;
@@ -3119,39 +2091,16 @@ backend_died_cb (ECal *ecal, gpointer data)
/* FIXME What about default sources? */
/* Make sure the source doesn't go away on us since we use it below */
- source_type = e_cal_get_source_type (ecal);
source = g_object_ref (e_cal_get_source (ecal));
- priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal);
- g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source));
-
- switch (source_type) {
- case E_CAL_SOURCE_TYPE_EVENT:
- id = g_strdup ("calendar:calendar-crashed");
-
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
-
- g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
- break;
-
- case E_CAL_SOURCE_TYPE_TODO:
- id = g_strdup ("calendar:calendar-crashed");
-
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
-
- g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
- break;
+ priv->clients_list = g_list_remove (priv->clients_list, ecal);
+ g_hash_table_remove (priv->clients, e_source_peek_uid (source));
- case E_CAL_SOURCE_TYPE_JOURNAL:
- id = g_strdup ("calendar:calendar-crashed");
+ id = g_strdup ("calendar:calendar-crashed");
- e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
+ /* e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); KILL-BONOBO */
- g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
- break;
- default:
- g_return_if_reached ();
- }
+ g_signal_emit (gcal, signals[SOURCE_REMOVED], 0, source);
g_object_unref (source);
@@ -3162,71 +2111,58 @@ backend_died_cb (ECal *ecal, gpointer data)
}
w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:backend_died", NULL);
- e_calendar_utils_show_error_silent (w);
+ /* e_calendar_utils_show_error_silent (w); KILL-BONOBO */
g_hash_table_insert (non_intrusive_error_table, (gpointer) id, g_object_ref(w));
g_signal_connect((GtkObject *)w, "destroy", G_CALLBACK(non_intrusive_error_remove), (gpointer) id);
}
GtkWidget *
-gnome_calendar_construct (GnomeCalendar *gcal)
+gnome_calendar_new (EShellSettings *shell_settings)
{
- GnomeCalendarPrivate *priv;
-
- g_return_val_if_fail (gcal != NULL, NULL);
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- priv = gcal->priv;
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
- return GTK_WIDGET (gcal);
+ return g_object_new (
+ GNOME_TYPE_CALENDAR,
+ "shell-settings", shell_settings, NULL);
}
-GtkWidget *
-gnome_calendar_new (void)
+EShellSettings *
+gnome_calendar_get_shell_settings (GnomeCalendar *gcal)
{
- GnomeCalendar *gcal;
-
- gcal = g_object_new (gnome_calendar_get_type (), NULL);
-
- if (!gnome_calendar_construct (gcal)) {
- g_message (G_STRLOC ": Could not construct the calendar GUI");
- g_object_unref (gcal);
- return NULL;
- }
+ g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
- return GTK_WIDGET (gcal);
+ return gcal->priv->shell_settings;
}
-void
-gnome_calendar_set_activity_handler (GnomeCalendar *cal, EActivityHandler *activity_handler)
+ECalendar *
+gnome_calendar_get_date_navigator (GnomeCalendar *gcal)
{
- GnomeCalendarPrivate *priv;
- gint i;
-
- g_return_if_fail (cal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (cal));
-
- priv = cal->priv;
-
- priv->activity_handler = activity_handler;
-
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++)
- e_calendar_view_set_activity_handler (priv->views[i], activity_handler);
+ g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
- e_calendar_table_set_activity_handler (E_CALENDAR_TABLE (priv->todo), activity_handler);
+ return gcal->priv->date_navigator;
}
void
-gnome_calendar_set_ui_component (GnomeCalendar *gcal,
- BonoboUIComponent *ui_component)
+gnome_calendar_set_date_navigator (GnomeCalendar *gcal,
+ ECalendar *date_navigator)
{
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component));
- e_search_bar_set_ui_component (E_SEARCH_BAR (gcal->priv->search_bar), ui_component);
+ if (date_navigator != NULL) {
+ g_return_if_fail (E_IS_CALENDAR (date_navigator));
+ g_object_ref (date_navigator);
+ }
+
+ if (gcal->priv->date_navigator != NULL)
+ g_object_unref (gcal->priv->date_navigator);
+
+ gcal->priv->date_navigator = date_navigator;
+
+ g_object_notify (G_OBJECT (gcal), "date-navigator");
}
/**
- * gnome_calendar_get_calendar_model:
+ * gnome_calendar_get_model:
* @gcal: A calendar view.
*
* Queries the calendar model object that a calendar view is using.
@@ -3234,92 +2170,11 @@ gnome_calendar_set_ui_component (GnomeCalendar *gcal,
* Return value: A calendar client interface object.
**/
ECalModel *
-gnome_calendar_get_calendar_model (GnomeCalendar *gcal)
+gnome_calendar_get_model (GnomeCalendar *gcal)
{
- GnomeCalendarPrivate *priv;
-
- g_return_val_if_fail (gcal != NULL, NULL);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
- priv = gcal->priv;
-
- return e_calendar_view_get_model (priv->views[priv->current_view_type]);
-}
-
-/**
- * gnome_calendar_get_default_client
- */
-ECal *
-gnome_calendar_get_default_client (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
-
- g_return_val_if_fail (gcal != NULL, NULL);
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- priv = gcal->priv;
-
- return e_cal_model_get_default_client (e_calendar_view_get_model (gcal->priv->views[priv->current_view_type]));
-}
-
-/**
- * gnome_calendar_add_source:
- * @gcal: A GnomeCalendar.
- * @source: #ESource to add to the calendar views.
- *
- * Adds the given calendar source to the calendar views.
- *
- * Returns: TRUE if successful, FALSE if error.
- */
-gboolean
-gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source)
-{
- GnomeCalendarPrivate *priv;
- ECal *client;
-
- g_return_val_if_fail (gcal != NULL, FALSE);
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
- g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
-
- priv = gcal->priv;
-
- client = g_hash_table_lookup (priv->clients[source_type], e_source_peek_uid (source));
- if (client) {
- /* We already have it */
-
- return TRUE;
- } else {
- ESource *default_source;
-
- if (priv->default_client[source_type]) {
- default_source = e_cal_get_source (priv->default_client[source_type]);
-
- g_message ("Check if default client matches (%s %s)", e_source_peek_uid (default_source), e_source_peek_uid (source));
- /* We don't have it but the default client is it */
- if (!strcmp (e_source_peek_uid (default_source), e_source_peek_uid (source)))
- client = g_object_ref (priv->default_client[source_type]);
- }
-
- /* Create a new one */
- if (!client) {
- client = auth_new_cal_from_source (source, source_type);
- if (!client)
- return FALSE;
- }
- }
-
- g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), gcal);
- g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), gcal);
-
- /* add the client to internal structure */
- g_hash_table_insert (priv->clients[source_type], g_strdup (e_source_peek_uid (source)), client);
- priv->clients_list[source_type] = g_list_prepend (priv->clients_list[source_type], client);
-
- g_signal_emit (gcal, gnome_calendar_signals[SOURCE_ADDED], 0, source_type, source);
-
- open_ecal (gcal, client, FALSE, client_cal_opened_cb);
-
- return TRUE;
+ return gcal->priv->model;
}
/**
@@ -3333,80 +2188,61 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou
* Returns: TRUE if successful, FALSE otherwise.
*/
gboolean
-gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source)
+gnome_calendar_remove_source (GnomeCalendar *gcal, ESource *source)
{
gboolean result;
- g_return_val_if_fail (gcal != NULL, FALSE);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
- result = gnome_calendar_remove_source_by_uid (gcal, source_type, e_source_peek_uid (source));
+ result = gnome_calendar_remove_source_by_uid (gcal, e_source_peek_uid (source));
if (result)
- g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
+ g_signal_emit (gcal, signals[SOURCE_REMOVED], 0, source);
return result;
}
gboolean
-gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_type, const gchar *uid)
+gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, const gchar *uid)
{
GnomeCalendarPrivate *priv;
ECal *client;
ECalModel *model;
GList *l;
- g_return_val_if_fail (gcal != NULL, FALSE);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
g_return_val_if_fail (uid != NULL, FALSE);
priv = gcal->priv;
- client = g_hash_table_lookup (priv->clients[source_type], uid);
+ client = g_hash_table_lookup (priv->clients, uid);
if (!client)
return TRUE;
- priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], client);
+ priv->clients_list = g_list_remove (priv->clients_list, client);
g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, gcal);
- switch (source_type) {
- case E_CAL_SOURCE_TYPE_EVENT:
- /* remove the query for this client */
- for (l = priv->dn_queries; l != NULL; l = l->next) {
- ECalView *query = l->data;
+ /* remove the query for this client */
+ for (l = priv->dn_queries; l != NULL; l = l->next) {
+ ECalView *query = l->data;
- if (query && (client == e_cal_view_get_client (query))) {
- g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
- priv->dn_queries = g_list_remove (priv->dn_queries, query);
- g_object_unref (query);
- break;
- }
+ if (query && (client == e_cal_view_get_client (query))) {
+ g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, gcal);
+ priv->dn_queries = g_list_remove (priv->dn_queries, query);
+ g_object_unref (query);
+ break;
}
+ }
- model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
- e_cal_model_remove_client (model, client);
-
- /* update date navigator query */
- update_query (gcal);
- break;
-
- case E_CAL_SOURCE_TYPE_TODO:
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
- e_cal_model_remove_client (model, client);
- break;
-
- case E_CAL_SOURCE_TYPE_JOURNAL:
- model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo));
- e_cal_model_remove_client (model, client);
- break;
+ model = gnome_calendar_get_model (gcal);
+ e_cal_model_remove_client (model, client);
- default:
- g_return_val_if_reached (TRUE);
- }
+ /* update date navigator query */
+ gnome_calendar_update_query (gcal);
- g_hash_table_remove (priv->clients[source_type], uid);
+ g_hash_table_remove (priv->clients, uid);
return TRUE;
}
@@ -3424,68 +2260,58 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_
* otherwise
**/
gboolean
-gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source)
+gnome_calendar_set_default_source (GnomeCalendar *gcal, ESource *source)
{
GnomeCalendarPrivate *priv;
ECal *client;
- g_return_val_if_fail (gcal != NULL, FALSE);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
priv = gcal->priv;
- client = g_hash_table_lookup (priv->clients[source_type], e_source_peek_uid (source));
+ client = g_hash_table_lookup (priv->clients, e_source_peek_uid (source));
- if (priv->default_client[source_type])
- g_object_unref (priv->default_client[source_type]);
+ if (priv->default_client)
+ g_object_unref (priv->default_client);
if (client) {
- priv->default_client[source_type] = g_object_ref (client);
+ priv->default_client = g_object_ref (client);
} else {
- priv->default_client[source_type] = auth_new_cal_from_source (source, source_type);
- if (!priv->default_client[source_type])
+ priv->default_client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT);
+ if (!priv->default_client)
return FALSE;
}
- open_ecal (gcal, priv->default_client[source_type], FALSE, default_client_cal_opened_cb);
+ open_ecal (gcal, priv->default_client, FALSE, default_client_cal_opened_cb);
return TRUE;
}
-void
-gnome_calendar_set_selected_time_range (GnomeCalendar *gcal,
- time_t start_time,
- time_t end_time)
+gboolean
+gnome_calendar_get_range_selected (GnomeCalendar *gcal)
{
- update_view_times (gcal, start_time);
- gnome_calendar_update_date_navigator (gcal);
- gnome_calendar_notify_dates_shown_changed (gcal);
+ g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
+
+ return gcal->priv->range_selected;
}
-/**
- * gnome_calendar_get_selected_time_range:
- * @gcal: A calendar view.
- * @start_time: Return value for the start of the time selection.
- * @end_time: Return value for the end of the time selection.
- *
- * Queries the time selection range on the calendar view.
- **/
void
-gnome_calendar_get_selected_time_range (GnomeCalendar *gcal,
- time_t *start_time,
- time_t *end_time)
+gnome_calendar_set_range_selected (GnomeCalendar *gcal,
+ gboolean range_selected)
{
- GnomeCalendarPrivate *priv;
- ECalModel *model;
-
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- priv = gcal->priv;
+ gcal->priv->range_selected = range_selected;
+}
- model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
- e_cal_model_get_time_range (model, start_time, end_time);
+void
+gnome_calendar_set_selected_time_range (GnomeCalendar *gcal,
+ time_t start_time)
+{
+ gnome_calendar_update_view_times (gcal, start_time);
+ gnome_calendar_update_date_navigator (gcal);
+ gnome_calendar_notify_dates_shown_changed (gcal);
}
/**
@@ -3496,6 +2322,7 @@ gnome_calendar_get_selected_time_range (GnomeCalendar *gcal,
*
* Opens a task editor dialog for a new task. dtstart or dtend can be NULL.
**/
+#if 0 /* KILL-BONOBO */
void
gnome_calendar_new_task (GnomeCalendar *gcal, time_t *dtstart, time_t *dtend)
{
@@ -3510,7 +2337,6 @@ gnome_calendar_new_task (GnomeCalendar *gcal, time_t *dtstart, time_t *dtend)
ECalComponentDateTime dt;
struct icaltimetype itt;
- g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
priv = gcal->priv;
@@ -3526,9 +2352,6 @@ gnome_calendar_new_task (GnomeCalendar *gcal, time_t *dtstart, time_t *dtend)
comp = e_cal_component_new ();
e_cal_component_set_icalcomponent (comp, icalcomp);
- category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar));
- e_cal_component_set_categories (comp, category);
-
dt.value = &itt;
dt.tzid = icaltimezone_get_tzid (e_cal_model_get_timezone (model));
@@ -3550,6 +2373,7 @@ gnome_calendar_new_task (GnomeCalendar *gcal, time_t *dtstart, time_t *dtend)
gtk_window_present (GTK_WINDOW (editor));
}
+#endif
/* Returns the selected time range for the current view. Note that this may be
different from the fields in the GnomeCalendar, since the view may clip
@@ -3559,25 +2383,13 @@ gnome_calendar_get_current_time_range (GnomeCalendar *gcal,
time_t *start_time,
time_t *end_time)
{
- e_calendar_view_get_selected_time_range (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)),
- start_time, end_time);
-}
-
-/* Gets the visible time range for the current view. Returns FALSE if no
- time range has been set yet. */
-gboolean
-gnome_calendar_get_visible_time_range (GnomeCalendar *gcal,
- time_t *start_time,
- time_t *end_time)
-{
- gboolean retval = FALSE;
-
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
+ GnomeCalendarViewType view_type;
+ ECalendarView *view;
- retval = e_calendar_view_get_visible_time_range (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)),
- start_time, end_time);
+ view_type = gnome_calendar_get_view (gcal);
+ view = gnome_calendar_get_calendar_view (gcal, view_type);
- return retval;
+ e_calendar_view_get_selected_time_range (view, start_time, end_time);
}
/* This updates the month shown and the days selected in the calendar, if
@@ -3588,10 +2400,16 @@ gnome_calendar_update_date_navigator (GnomeCalendar *gcal)
GnomeCalendarPrivate *priv;
ECalModel *model;
time_t start, end;
+ gint week_start_day;
GDate start_date, end_date;
+ icaltimezone *timezone;
priv = gcal->priv;
+ /* If the ECalendar is not yet set, we just return. */
+ if (priv->date_navigator == NULL)
+ return;
+
/* If the ECalendar isn't visible, we just return. */
if (!GTK_WIDGET_VISIBLE (priv->date_navigator))
return;
@@ -3599,163 +2417,39 @@ gnome_calendar_update_date_navigator (GnomeCalendar *gcal)
if (priv->current_view_type == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range)
return;
- model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
+ model = gnome_calendar_get_model (gcal);
+ timezone = e_cal_model_get_timezone (model);
+ week_start_day = e_cal_model_get_week_start_day (model);
e_cal_model_get_time_range (model, &start, &end);
- time_to_gdate_with_zone (&start_date, start, priv->zone);
+ time_to_gdate_with_zone (&start_date, start, timezone);
if (priv->current_view_type == GNOME_CAL_MONTH_VIEW) {
EWeekView *week_view = E_WEEK_VIEW (priv->views[priv->current_view_type]);
- if (priv->week_start == 0
+ if (week_start_day == 0
&& (!week_view->multi_week_view || week_view->compress_weekend))
g_date_add_days (&start_date, 1);
}
- time_to_gdate_with_zone (&end_date, end, priv->zone);
+ time_to_gdate_with_zone (&end_date, end, timezone);
g_date_subtract_days (&end_date, 1);
e_calendar_item_set_selection (priv->date_navigator->calitem,
&start_date, &end_date);
}
-static void
-gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- GnomeCalendarViewType view_type;
- ECalModel *model;
- GDate start_date, end_date, new_start_date, new_end_date;
- gint new_days_shown;
- gboolean starts_on_week_start_day;
- time_t new_time, start, end;
- struct icaltimetype tt;
-
- priv = gcal->priv;
-
- starts_on_week_start_day = FALSE;
-
- model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
- e_cal_model_get_time_range (model, &start, &end);
-
- time_to_gdate_with_zone (&start_date, start, priv->zone);
- if (priv->current_view_type == GNOME_CAL_MONTH_VIEW) {
- EWeekView *week_view = E_WEEK_VIEW (priv->views[priv->current_view_type]);
-
- if (priv->week_start == 0 && (!week_view->multi_week_view || week_view->compress_weekend))
- g_date_add_days (&start_date, 1);
- }
- time_to_gdate_with_zone (&end_date, end, priv->zone);
- g_date_subtract_days (&end_date, 1);
-
- e_calendar_item_get_selection (calitem, &new_start_date, &new_end_date);
-
- /* If the selection hasn't changed just return. */
- if (!g_date_compare (&start_date, &new_start_date)
- && !g_date_compare (&end_date, &new_end_date)) {
- return;
- }
-
- new_days_shown = g_date_get_julian (&new_end_date) - g_date_get_julian (&new_start_date) + 1;
-
- /* If a complete week is selected we show the Week view.
- Note that if weekends are compressed and the week start day is set
- to Sunday we don't actually show complete weeks in the Week view,
- so this may need tweaking. */
- if (g_date_get_weekday (&new_start_date) % 7 == priv->week_start)
- starts_on_week_start_day = TRUE;
-
- /* Update selection to be in the new time range */
- tt = icaltime_null_time ();
- tt.year = g_date_get_year (&new_start_date);
- tt.month = g_date_get_month (&new_start_date);
- tt.day = g_date_get_day (&new_start_date);
- new_time = icaltime_as_timet_with_zone (tt, priv->zone);
-
- /* Switch views as appropriate, and change the number of days or weeks
- shown. */
- if (new_days_shown > 9) {
- /* FIXME Gross hack so that the view times are updated properly */
- priv->range_selected = TRUE;
-
- if (priv->current_view_type != GNOME_CAL_LIST_VIEW) {
- e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view),
- (new_days_shown + 6) / 7);
- view_type = GNOME_CAL_MONTH_VIEW;
- } else
- view_type = GNOME_CAL_LIST_VIEW;
- } else if (new_days_shown == 7 && starts_on_week_start_day) {
- view_type = GNOME_CAL_WEEK_VIEW;
- } else {
- e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), new_days_shown);
-
- if (new_days_shown == 5 && starts_on_week_start_day
- && priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW)
- view_type = GNOME_CAL_WORK_WEEK_VIEW;
- else
- view_type = GNOME_CAL_DAY_VIEW;
- }
-
- /* Make the views display things properly */
- update_view_times (gcal, new_time);
- set_view (gcal, view_type, TRUE);
-
- gnome_calendar_notify_dates_shown_changed (gcal);
-}
-
-static void
-gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem, GnomeCalendar *gcal)
-{
- update_query (gcal);
-}
-
-static void
-gnome_calendar_hpane_realized (GtkWidget *w, GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
-
- priv = gcal->priv;
-
- if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
- gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos_month_view);
- } else {
- gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos);
- }
-}
-
-static void
-gnome_calendar_date_navigator_scrolled (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
-{
- GnomeCalendar *gcal = user_data;
- ECalendarItem *calitem = gcal->priv->date_navigator->calitem;
- GDate start_date, end_date;
-
- if (e_calendar_item_get_selection (calitem, &start_date, &end_date)) {
- switch (event->direction) {
- case GDK_SCROLL_UP:
- g_date_subtract_months (&start_date, 1);
- g_date_subtract_months (&end_date, 1);
- break;
- case GDK_SCROLL_DOWN:
- g_date_add_months (&start_date, 1);
- g_date_add_months (&end_date, 1);
- break;
- default:
- break;
-
- }
- e_calendar_item_set_selection (calitem, &start_date, &end_date);
- gnome_calendar_on_date_navigator_selection_changed (calitem, gcal);
- }
-}
-
static gboolean
gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
+ ECalendarView *view;
+ gboolean range_selected;
gint times_width;
priv = gcal->priv;
- if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
+ range_selected = gnome_calendar_get_range_selected (gcal);
+
+ if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !range_selected) {
priv->hpane_pos_month_view = gtk_paned_get_position (GTK_PANED (priv->hpane));
calendar_config_set_month_hpane_pos (priv->hpane_pos_month_view);
} else {
@@ -3764,124 +2458,37 @@ gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gc
}
/* adjust the size of the EDayView's time column */
+ view = gnome_calendar_get_calendar_view (gcal, GNOME_CAL_DAY_VIEW);
times_width = e_day_view_time_item_get_column_width (
- E_DAY_VIEW_TIME_ITEM (E_DAY_VIEW (priv->day_view)->time_canvas_item));
+ E_DAY_VIEW_TIME_ITEM (E_DAY_VIEW (view)->time_canvas_item));
if (times_width < priv->hpane_pos - 20)
- gtk_widget_set_size_request (E_DAY_VIEW (priv->day_view)->time_canvas, times_width, -1);
+ gtk_widget_set_size_request (E_DAY_VIEW (view)->time_canvas, times_width, -1);
else
- gtk_widget_set_size_request (E_DAY_VIEW (priv->day_view)->time_canvas, priv->hpane_pos - 20, -1);
-
- return FALSE;
-}
-static void
-gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
-
- priv = gcal->priv;
-
- if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
- gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view);
- } else {
- gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos);
- }
-}
-
-static gboolean
-gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
-
- priv = gcal->priv;
-
- if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
- priv->vpane_pos_month_view = gtk_paned_get_position (GTK_PANED (priv->vpane));
- calendar_config_set_month_vpane_pos (priv->vpane_pos_month_view);
- } else {
- priv->vpane_pos = gtk_paned_get_position (GTK_PANED (priv->vpane));
- calendar_config_set_vpane_pos (priv->vpane_pos);
- }
+ gtk_widget_set_size_request (E_DAY_VIEW (view)->time_canvas, priv->hpane_pos - 20, -1);
return FALSE;
}
void
-gnome_calendar_cut_clipboard (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- FocusLocation location;
-
- priv = gcal->priv;
-
- location = get_focus_location (gcal);
-
- if (location == FOCUS_CALENDAR) {
- e_calendar_view_cut_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
- } else if (location == FOCUS_TASKPAD)
- e_calendar_table_cut_clipboard (E_CALENDAR_TABLE (priv->todo));
- else if (location == FOCUS_MEMOPAD)
- e_memo_table_cut_clipboard (E_MEMO_TABLE (priv->memo));
-}
-
-void
-gnome_calendar_copy_clipboard (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- FocusLocation location;
-
- priv = gcal->priv;
-
- location = get_focus_location (gcal);
-
- if (location == FOCUS_CALENDAR) {
- e_calendar_view_copy_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
- } else if (location == FOCUS_TASKPAD)
- e_calendar_table_copy_clipboard (E_CALENDAR_TABLE (priv->todo));
- else if (location == FOCUS_MEMOPAD)
- e_memo_table_copy_clipboard (E_MEMO_TABLE (priv->memo));
-}
-
-void
-gnome_calendar_paste_clipboard (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- FocusLocation location;
-
- priv = gcal->priv;
-
- location = get_focus_location (gcal);
-
- if (location == FOCUS_CALENDAR) {
- e_calendar_view_paste_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
- } else if (location == FOCUS_TASKPAD)
- e_calendar_table_paste_clipboard (E_CALENDAR_TABLE (priv->todo));
- else if (location == FOCUS_MEMOPAD)
- e_memo_table_paste_clipboard (E_MEMO_TABLE (priv->memo));
-}
-
-/* Get the current timezone. */
-icaltimezone*
-gnome_calendar_get_timezone (GnomeCalendar *gcal)
-{
- g_return_val_if_fail (gcal != NULL, NULL);
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- return gcal->priv->zone;
-}
-
-static void
gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal)
{
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
GnomeCalendarPrivate *priv;
time_t start_time, end_time;
+ gboolean has_time_range;
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
priv = gcal->priv;
+ view_type = gnome_calendar_get_view (gcal);
+ calendar_view = gnome_calendar_get_calendar_view (gcal, view_type);
+
/* If no time range is set yet, just return. */
- if (!gnome_calendar_get_visible_time_range (gcal, &start_time,
- &end_time))
+ has_time_range = e_calendar_view_get_visible_time_range (
+ calendar_view, &start_time, &end_time);
+ if (!has_time_range)
return;
/* We check if the visible date range has changed, and only emit the
@@ -3892,7 +2499,7 @@ gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal)
priv->visible_start = start_time;
priv->visible_end = end_time;
- g_signal_emit (gcal, gnome_calendar_signals[DATES_SHOWN_CHANGED], 0);
+ g_signal_emit (gcal, signals[DATES_SHOWN_CHANGED], 0);
}
update_memo_view (gcal);
}
@@ -3901,12 +2508,15 @@ gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal)
gint
gnome_calendar_get_num_events_selected (GnomeCalendar *gcal)
{
- GtkWidget *view;
+ GnomeCalendarViewType view_type;
+ ECalendarView *view;
gint retval = 0;
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), 0);
- view = gnome_calendar_get_current_view_widget (gcal);
+ view_type = gnome_calendar_get_view (gcal);
+ view = gnome_calendar_get_calendar_view (gcal, view_type);
+
if (E_IS_DAY_VIEW (view))
retval = e_day_view_get_num_events_selected (E_DAY_VIEW (view));
else
@@ -3915,70 +2525,6 @@ gnome_calendar_get_num_events_selected (GnomeCalendar *gcal)
return retval;
}
-/**
- * gnome_calendar_get_num_tasks_selected:
- * @gcal: A calendar view.
- *
- * Queries the number of tasks that are currently selected in the task pad of a
- * calendar view.
- *
- * Return value: Number of selected tasks.
- **/
-gint
-gnome_calendar_get_num_tasks_selected (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- ETable *etable;
-
- g_return_val_if_fail (gcal != NULL, -1);
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), -1);
-
- priv = gcal->priv;
-
- etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo));
- return e_table_selected_count (etable);
-}
-
-void
-gnome_calendar_delete_selection (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- FocusLocation location;
- GtkWidget *view;
-
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- priv = gcal->priv;
-
- location = get_focus_location (gcal);
-
- if (location == FOCUS_CALENDAR) {
- view = gnome_calendar_get_current_view_widget (gcal);
-
- e_calendar_view_delete_selected_events (E_CALENDAR_VIEW (view));
- } else if (location == FOCUS_TASKPAD)
- e_calendar_table_delete_selected (E_CALENDAR_TABLE (priv->todo));
- else if (location == FOCUS_MEMOPAD)
- e_memo_table_delete_selected (E_MEMO_TABLE (priv->memo));
-}
-
-void
-gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal)
-{
- FocusLocation location;
- GtkWidget *view;
-
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- location = get_focus_location (gcal);
-
- if (location == FOCUS_CALENDAR) {
-
- view = gnome_calendar_get_current_view_widget (gcal);
- e_calendar_view_delete_selected_occurrence (E_CALENDAR_VIEW (view));
- }
-}
-
static gboolean
check_instance_cb (ECalComponent *comp,
time_t instance_start,
@@ -4009,10 +2555,10 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than)
" (make-time \"%s\"))",
start, end);
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), _("Purging"), -1);
+ /*e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), _("Purging"), -1); KILL-BONOBO */
/* FIXME Confirm expunge */
- for (l = priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) {
+ for (l = priv->clients_list; l != NULL; l = l->next) {
ECal *client = l->data;
GList *objects, *m;
gboolean read_only;
@@ -4067,101 +2613,10 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than)
g_list_free (objects);
}
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
+ /* e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); KILL-BONOBO */
g_free (sexp);
g_free (start);
g_free (end);
}
-
-ECalendarTable*
-gnome_calendar_get_task_pad (GnomeCalendar *gcal)
-{
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- return E_CALENDAR_TABLE (gcal->priv->todo);
-}
-
-GtkWidget *
-gnome_calendar_get_e_calendar_widget (GnomeCalendar *gcal)
-{
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- return GTK_WIDGET(gcal->priv->date_navigator);
-}
-
-GtkWidget *
-gnome_calendar_get_search_bar_widget (GnomeCalendar *gcal)
-{
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- return GTK_WIDGET(gcal->priv->search_bar);
-}
-
-GtkWidget *
-gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal)
-{
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- return GTK_WIDGET(gcal->priv->notebook);
-}
-
-ECalMenu *gnome_calendar_get_taskpad_menu (GnomeCalendar *gcal)
-{
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- return gcal->priv->taskpad_menu;
-}
-
-ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal)
-{
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- return gcal->priv->calendar_menu;
-}
-
-ECalMenu *gnome_calendar_get_memopad_menu (GnomeCalendar *gcal)
-{
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
-
- return gcal->priv->memopad_menu;
-}
-
-void
-gnome_calendar_edit_appointment (GnomeCalendar *gcal,
- const gchar * src_uid,
- const gchar * comp_uid,
- const gchar * comp_rid)
-{
- ECal *client = NULL;
- GList *l;
- icalcomponent* icalcomp = NULL;
- icalproperty *attendee_prop = NULL;
-
- if (!src_uid || !comp_uid)
- return;
-
- for (l = gcal->priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) {
- ESource *client_src;
-
- client = l->data;
- client_src = e_cal_get_source (client);
-
- if (!strcmp (src_uid, e_source_peek_uid (client_src)))
- break;
- }
-
- if (!client)
- return;
-
- e_cal_get_object (client, comp_uid, comp_rid, &icalcomp, NULL);
-
- if (!icalcomp)
- return;
-
- attendee_prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
- e_calendar_view_edit_appointment (gcal->priv->views[gcal->priv->current_view_type],
- client, icalcomp, attendee_prop ? TRUE:FALSE);
- icalcomponent_free (icalcomp);
-}
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index 2a5e2f847d..0cc528fe3c 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -24,29 +24,40 @@
*
*/
-#ifndef GNOME_CALENDAR_APP_H
-#define GNOME_CALENDAR_APP_H
+#ifndef GNOME_CALENDAR_H
+#define GNOME_CALENDAR_H
#include <time.h>
#include <gtk/gtk.h>
-#include <bonobo/bonobo-ui-component.h>
#include <misc/e-calendar.h>
#include <libecal/e-cal.h>
-#include <e-util/e-popup.h>
+#include <shell/e-shell-settings.h>
-#include "e-cal-menu.h"
#include "e-calendar-table.h"
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define GNOME_TYPE_CALENDAR \
+ (gnome_calendar_get_type ())
+#define GNOME_CALENDAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), GNOME_TYPE_CALENDAR, GnomeCalendar))
+#define GNOME_CALENDAR_CLASS(cls) \
+ (G_TYPE_CHECK_INSTANCE_CAST_CLASS \
+ ((cls), GNOME_TYPE_CALENDAR, GnomeCalendarClass))
+#define GNOME_IS_CALENDAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), GNOME_TYPE_CALENDAR))
+#define GNOME_IS_CALENDAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), GNOME_TYPE_CALENDAR))
+#define GNOME_CALENDAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), GNOME_TYPE_CALENDAR, GnomeCalendarClass))
-
+G_BEGIN_DECLS
-#define GNOME_TYPE_CALENDAR (gnome_calendar_get_type ())
-#define GNOME_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_CALENDAR, GnomeCalendar))
-#define GNOME_CALENDAR_CLASS(klass) (G_TYPE_CHECK_INSTANCE_CAST_CLASS ((klass), GNOME_TYPE_CALENDAR, \
- GnomeCalendarClass))
-#define GNOME_IS_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_CALENDAR))
-#define GNOME_IS_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_CALENDAR))
+/* Avoid circular inclusion. */
+struct _ECalendarView;
typedef struct _GnomeCalendar GnomeCalendar;
typedef struct _GnomeCalendarClass GnomeCalendarClass;
@@ -75,8 +86,6 @@ typedef enum {
struct _GnomeCalendar {
GtkVBox vbox;
-
- /* Private data */
GnomeCalendarPrivate *priv;
};
@@ -87,118 +96,94 @@ struct _GnomeCalendarClass {
void (* dates_shown_changed) (GnomeCalendar *gcal);
void (* calendar_selection_changed) (GnomeCalendar *gcal);
- void (* taskpad_selection_changed) (GnomeCalendar *gcal);
- void (* memopad_selection_changed) (GnomeCalendar *gcal);
void (* calendar_focus_change) (GnomeCalendar *gcal, gboolean in);
- void (* taskpad_focus_change) (GnomeCalendar *gcal, gboolean in);
- void (* memopad_focus_change) (GnomeCalendar *gcal, gboolean in);
void (* change_view) (GnomeCalendar *gcal,
GnomeCalendarViewType view_type);
- void (* source_added) (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source);
- void (* source_removed) (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source);
+ void (* source_added) (GnomeCalendar *gcal, ESource *source);
+ void (* source_removed) (GnomeCalendar *gcal, ESource *source);
/* Action signals */
void (* goto_date) (GnomeCalendar *gcal, GnomeCalendarGotoDateType date);
};
-GType gnome_calendar_get_type (void);
-GtkWidget *gnome_calendar_construct (GnomeCalendar *gcal);
-
-GtkWidget *gnome_calendar_new (void);
-
-void gnome_calendar_set_activity_handler (GnomeCalendar *cal, EActivityHandler *activity_handler);
-void gnome_calendar_set_ui_component (GnomeCalendar *cal, BonoboUIComponent *ui_component);
-
-ECalModel *gnome_calendar_get_calendar_model (GnomeCalendar *gcal);
-ECal *gnome_calendar_get_default_client (GnomeCalendar *gcal);
-
-gboolean gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source);
-gboolean gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source);
-gboolean gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_type, const gchar *uid);
-gboolean gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source);
-
-void gnome_calendar_next (GnomeCalendar *gcal);
-void gnome_calendar_previous (GnomeCalendar *gcal);
-void gnome_calendar_goto (GnomeCalendar *gcal,
+GType gnome_calendar_get_type (void);
+GtkWidget * gnome_calendar_new (EShellSettings *shell_settings);
+EShellSettings *gnome_calendar_get_shell_settings
+ (GnomeCalendar *gcal);
+ECalendar * gnome_calendar_get_date_navigator
+ (GnomeCalendar *gcal);
+void gnome_calendar_set_date_navigator
+ (GnomeCalendar *gcal,
+ ECalendar *date_navigator);
+ECalModel * gnome_calendar_get_model (GnomeCalendar *gcal);
+gboolean gnome_calendar_remove_source (GnomeCalendar *gcal,
+ ESource *source);
+gboolean gnome_calendar_remove_source_by_uid
+ (GnomeCalendar *gcal,
+ const gchar *uid);
+gboolean gnome_calendar_set_default_source
+ (GnomeCalendar *gcal,
+ ESource *source);
+void gnome_calendar_update_query (GnomeCalendar *gcal);
+void gnome_calendar_set_search_query (GnomeCalendar *gcal,
+ const gchar *sexp,
+ gboolean range_search,
+ time_t start_range,
+ time_t end_range);
+
+void gnome_calendar_next (GnomeCalendar *gcal);
+void gnome_calendar_previous (GnomeCalendar *gcal);
+void gnome_calendar_goto (GnomeCalendar *gcal,
time_t new_time);
-void gnome_calendar_dayjump (GnomeCalendar *gcal,
+void gnome_calendar_update_view_times(GnomeCalendar *gcal,
+ time_t start_time);
+void gnome_calendar_dayjump (GnomeCalendar *gcal,
time_t time);
-/* Jumps to the current day */
-void gnome_calendar_goto_today (GnomeCalendar *gcal);
-
-GnomeCalendarViewType gnome_calendar_get_view (GnomeCalendar *gcal);
-void gnome_calendar_set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type);
-
-GtkWidget *gnome_calendar_get_current_view_widget (GnomeCalendar *gcal);
-
-ECalendarTable *gnome_calendar_get_task_pad (GnomeCalendar *gcal);
-GtkWidget *gnome_calendar_get_e_calendar_widget (GnomeCalendar *gcal);
-GtkWidget *gnome_calendar_get_search_bar_widget (GnomeCalendar *gcal);
-GtkWidget *gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal);
-GtkWidget *gnome_calendar_get_tag (GnomeCalendar *gcal);
-
-ECalMenu *gnome_calendar_get_taskpad_menu (GnomeCalendar *gcal);
-ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal);
-ECalMenu *gnome_calendar_get_memopad_menu (GnomeCalendar *gcal);
-
-void gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic);
-void gnome_calendar_discard_view_menus (GnomeCalendar *gcal);
-
-void gnome_calendar_view_popup_factory (GnomeCalendar *gcal, EPopup *ep, const gchar *prefix);
-
-void gnome_calendar_set_selected_time_range (GnomeCalendar *gcal,
- time_t start_time,
- time_t end_time);
-void gnome_calendar_get_selected_time_range (GnomeCalendar *gcal,
- time_t *start_time,
- time_t *end_time);
-
-void gnome_calendar_new_task (GnomeCalendar *gcal, time_t *dtstart, time_t *dtend);
+void gnome_calendar_goto_today (GnomeCalendar *gcal);
+
+GnomeCalendarViewType
+ gnome_calendar_get_view (GnomeCalendar *gcal);
+void gnome_calendar_set_view (GnomeCalendar *gcal,
+ GnomeCalendarViewType view_type);
+void gnome_calendar_display_view (GnomeCalendar *gcal,
+ GnomeCalendarViewType view_type);
+
+struct _ECalendarView *
+ gnome_calendar_get_calendar_view(GnomeCalendar *gcal,
+ GnomeCalendarViewType view_type);
+
+gboolean gnome_calendar_get_range_selected
+ (GnomeCalendar *gcal);
+void gnome_calendar_set_range_selected
+ (GnomeCalendar *gcal,
+ gboolean range_selected);
+void gnome_calendar_set_selected_time_range
+ (GnomeCalendar *gcal,
+ time_t start_time);
+void gnome_calendar_new_task (GnomeCalendar *gcal,
+ time_t *dtstart,
+ time_t *dtend);
/* Returns the selected time range for the current view. Note that this may be
different from the fields in the GnomeCalendar, since the view may clip
this or choose a more appropriate time. */
-void gnome_calendar_get_current_time_range (GnomeCalendar *gcal,
- time_t *start_time,
- time_t *end_time);
+void gnome_calendar_get_current_time_range
+ (GnomeCalendar *gcal,
+ time_t *start_time,
+ time_t *end_time);
-/* Gets the visible time range for the current view. Returns FALSE if no
- time range has been set yet. */
-gboolean gnome_calendar_get_visible_time_range (GnomeCalendar *gcal,
- time_t *start_time,
- time_t *end_time);
+void gnome_calendar_notify_dates_shown_changed
+ (GnomeCalendar *gcal);
/* Returns the number of selected events (0 or 1 at present). */
-gint gnome_calendar_get_num_events_selected (GnomeCalendar *gcal);
-
-/* Returns the number of selected tasks */
-gint gnome_calendar_get_num_tasks_selected (GnomeCalendar *gcal);
+gint gnome_calendar_get_num_events_selected
+ (GnomeCalendar *gcal);
-/* Get the current timezone. */
-icaltimezone *gnome_calendar_get_timezone (GnomeCalendar *gcal);
-
-/* Clipboard operations */
-void gnome_calendar_cut_clipboard (GnomeCalendar *gcal);
-void gnome_calendar_copy_clipboard (GnomeCalendar *gcal);
-void gnome_calendar_paste_clipboard (GnomeCalendar *gcal);
-
-void gnome_calendar_delete_selection (GnomeCalendar *gcal);
-void gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal);
-void gnome_calendar_purge (GnomeCalendar *gcal,
+void gnome_calendar_purge (GnomeCalendar *gcal,
time_t older_than);
-
-
-/* Direct calendar component operations */
-void gnome_calendar_edit_appointment (GnomeCalendar *gcal,
- const gchar * src_uid,
- const gchar * comp_uid,
- const gchar * comp_rid);
-
-void gnome_calendar_emit_user_created_signal (gpointer instance, GnomeCalendar *gcal, ECal *calendar);
-
G_END_DECLS
#endif
diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c
index 06986efdd6..6e68ec71ee 100644
--- a/calendar/gui/goto.c
+++ b/calendar/gui/goto.c
@@ -28,7 +28,6 @@
#include <gtk/gtk.h>
#include <glade/glade.h>
#include "e-util/e-util-private.h"
-#include "calendar-commands.h"
#include "calendar-config.h"
#include "tag-calendar.h"
#include "goto.h"
@@ -77,9 +76,11 @@ static void
ecal_date_range_changed (ECalendarItem *calitem, gpointer user_data)
{
GoToDialog *dlg = user_data;
+ ECalModel *model;
ECal *client;
- client = gnome_calendar_get_default_client (dlg->gcal);
+ model = gnome_calendar_get_model (dlg->gcal);
+ client = e_cal_model_get_default_client (model);
if (client)
tag_calendar_by_client (dlg->ecal, client);
}
@@ -92,16 +93,20 @@ ecal_event (ECalendarItem *calitem, gpointer user_data)
{
GoToDialog *dlg = user_data;
GDate start_date, end_date;
+ ECalModel *model;
struct icaltimetype tt = icaltime_null_time ();
+ icaltimezone *timezone;
time_t et;
+ model = gnome_calendar_get_model (dlg->gcal);
e_calendar_item_get_selection (calitem, &start_date, &end_date);
+ timezone = e_cal_model_get_timezone (model);
tt.year = g_date_get_year (&start_date);
tt.month = g_date_get_month (&start_date);
tt.day = g_date_get_day (&start_date);
- et = icaltime_as_timet_with_zone (tt, gnome_calendar_get_timezone (dlg->gcal));
+ et = icaltime_as_timet_with_zone (tt, timezone);
gnome_calendar_goto (dlg->gcal, et);
@@ -201,8 +206,10 @@ goto_dialog_init_widgets (GoToDialog *dlg)
void
goto_dialog (GnomeCalendar *gcal)
{
+ ECalModel *model;
time_t start_time;
struct icaltimetype tt;
+ icaltimezone *timezone;
gint b;
gchar *gladefile;
@@ -231,8 +238,10 @@ goto_dialog (GnomeCalendar *gcal)
}
dlg->gcal = gcal;
- gnome_calendar_get_selected_time_range (dlg->gcal, &start_time, NULL);
- tt = icaltime_from_timet_with_zone (start_time, FALSE, gnome_calendar_get_timezone (gcal));
+ model = gnome_calendar_get_model (gcal);
+ timezone = e_cal_model_get_timezone (model);
+ e_cal_model_get_time_range (model, &start_time, NULL);
+ tt = icaltime_from_timet_with_zone (start_time, FALSE, timezone);
dlg->year_val = tt.year;
dlg->month_val = tt.month - 1;
dlg->day_val = tt.day;
diff --git a/calendar/gui/itip-bonobo-control.c b/calendar/gui/itip-bonobo-control.c
deleted file mode 100644
index 10599f2a17..0000000000
--- a/calendar/gui/itip-bonobo-control.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Evolution calendar - Control for displaying iTIP mail messages
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jesse Pavel <jpavel@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <config.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-property-bag.h>
-#include <bonobo/bonobo-persist-stream.h>
-#include <bonobo/bonobo-stream-client.h>
-#include <bonobo/bonobo-context.h>
-#include <bonobo/bonobo-exception.h>
-#include <libical/ical.h>
-
-#include "e-itip-control.h"
-#include "itip-bonobo-control.h"
-
-extern gchar *evolution_dir;
-
-enum E_ITIP_BONOBO_ARGS {
- FROM_ADDRESS_ARG_ID,
- VIEW_ONLY_ARG_ID
-};
-
-/*
- * Bonobo::PersistStream
- *
- * These two functions implement the Bonobo::PersistStream load and
- * save methods which allow data to be loaded into and out of the
- * BonoboObject.
- */
-
-static gchar *
-stream_read (Bonobo_Stream stream)
-{
- Bonobo_Stream_iobuf *buffer;
- CORBA_Environment ev;
- gchar *data = NULL;
- gint length = 0;
-
- CORBA_exception_init (&ev);
- do {
-#define READ_CHUNK_SIZE 65536
- Bonobo_Stream_read (stream, READ_CHUNK_SIZE,
- &buffer, &ev);
-
- if (BONOBO_EX (&ev)) {
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- if (buffer->_length <= 0)
- break;
-
- data = g_realloc (data, length + buffer->_length + 1);
- memcpy (data + length, buffer->_buffer, buffer->_length);
- length += buffer->_length;
- data[length] = '\0';
-
- CORBA_free (buffer);
-#undef READ_CHUNK_SIZE
- } while (1);
-
- CORBA_free (buffer);
- CORBA_exception_free (&ev);
-
- if (data == NULL)
- data = g_strdup("");
-
- return data;
-} /* stream_read */
-
-/*
- * This function implements the Bonobo::PersistStream:load method.
- */
-typedef struct {
- EItipControl *itip;
- gchar *text;
-} idle_data;
-
-static gboolean
-set_data_idle_cb (gpointer data)
-{
- idle_data *id = data;
-
- e_itip_control_set_data (id->itip, id->text);
- g_object_unref (id->itip);
- g_free (id->text);
- g_free (id);
-
- return FALSE;
-}
-
-static void
-pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, gpointer data,
- CORBA_Environment *ev)
-{
- EItipControl *itip = data;
- idle_data *id;
-
- if (type && g_ascii_strcasecmp (type, "text/calendar") != 0 &&
- g_ascii_strcasecmp (type, "text/x-calendar") != 0) {
- bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType);
- return;
- }
-
- id = g_new0 (idle_data, 1);
- if ((id->text = stream_read (stream)) == NULL) {
- bonobo_exception_set (ev, ex_Bonobo_Persist_FileNotFound);
- g_free (id);
- return;
- }
- g_object_ref (itip);
- id->itip = itip;
-
- g_idle_add (set_data_idle_cb, id);
-}
-/*
- * This function implements the Bonobo::PersistStream:save method.
- */
-static void
-pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, gpointer data,
- CORBA_Environment *ev)
-{
- EItipControl *itip = data;
- gchar *text;
- gint len;
-
- if (type && g_ascii_strcasecmp (type, "text/calendar") != 0 &&
- g_ascii_strcasecmp (type, "text/x-calendar") != 0) {
- bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType);
- return;
- }
-
- text = e_itip_control_get_data (itip);
- len = e_itip_control_get_data_size (itip);
-
- bonobo_stream_client_write (stream, text, len, ev);
- g_free (text);
-} /* pstream_save */
-
-/* static CORBA_long */
-/* pstream_get_max_size (BonoboPersistStream *ps, gpointer data, */
-/* CORBA_Environment *ev) */
-/* { */
-/* EItipControl *itip = data; */
-/* gint len; */
-
-/* len = e_itip_control_get_data_size (itip); */
-
-/* if (len > 0) */
-/* return len; */
-
-/* return 0L; */
-/* } */
-
-static Bonobo_Persist_ContentTypeList *
-pstream_get_content_types (BonoboPersistStream *ps, gpointer closure,
- CORBA_Environment *ev)
-{
- return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar");
-}
-
-static void
-get_prop (BonoboPropertyBag *bag,
- BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- EItipControl *itip = user_data;
-
- switch (arg_id) {
- case FROM_ADDRESS_ARG_ID:
- BONOBO_ARG_SET_STRING (arg, e_itip_control_get_from_address (itip));
- break;
- case VIEW_ONLY_ARG_ID:
- BONOBO_ARG_SET_INT (arg, e_itip_control_get_view_only (itip));
- break;
- }
-}
-
-static void
-set_prop ( BonoboPropertyBag *bag,
- const BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- EItipControl *itip = user_data;
-
- switch (arg_id) {
- case FROM_ADDRESS_ARG_ID:
- e_itip_control_set_from_address (itip, BONOBO_ARG_GET_STRING (arg));
- break;
- case VIEW_ONLY_ARG_ID:
- e_itip_control_set_view_only (itip, BONOBO_ARG_GET_INT (arg));
- break;
- }
-}
-
-BonoboControl *
-itip_bonobo_control_new (void)
-{
- BonoboControl *control;
- BonoboPropertyBag *prop_bag;
- BonoboPersistStream *stream;
- GtkWidget *itip;
-
- itip = e_itip_control_new ();
- gtk_widget_show (itip);
- control = bonobo_control_new (itip);
-
- /* create a property bag */
- prop_bag = bonobo_property_bag_new (get_prop, set_prop, itip);
- bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL,
- "from_address", 0 );
- bonobo_property_bag_add (prop_bag, "view_only", VIEW_ONLY_ARG_ID, BONOBO_ARG_INT, NULL,
- "view_only", 0 );
-
- bonobo_control_set_properties (control, bonobo_object_corba_objref (BONOBO_OBJECT (prop_bag)), NULL);
- bonobo_object_unref (BONOBO_OBJECT (prop_bag));
-
- bonobo_control_set_automerge (control, TRUE);
-
- stream = bonobo_persist_stream_new (pstream_load, pstream_save,
- pstream_get_content_types,
- "OAFIID:GNOME_Evolution_Calendar_iTip_Control:" BASE_VERSION,
- itip);
-
- if (stream == NULL) {
- bonobo_object_unref (BONOBO_OBJECT (control));
- return NULL;
- }
-
- bonobo_object_add_interface (BONOBO_OBJECT (control),
- BONOBO_OBJECT (stream));
-
- return control;
-}
diff --git a/calendar/gui/itip-bonobo-control.h b/calendar/gui/itip-bonobo-control.h
deleted file mode 100644
index c79b8f7d09..0000000000
--- a/calendar/gui/itip-bonobo-control.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *
- * Evolution calendar - Control for displaying iTIP mail messages
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jesse Pavel <jpavel@ximian.com>
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __ITIP_CONTROL_FACTORY_H__
-#define __ITIP_CONTROL_FACTORY_H__
-
-#include <bonobo/bonobo-control.h>
-
-BonoboControl *itip_bonobo_control_new (void);
-
-#endif /* __ITIP_CONTROL_H__ */
diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c
index 10751a3629..38fcb46bb7 100644
--- a/calendar/gui/itip-utils.c
+++ b/calendar/gui/itip-utils.c
@@ -38,7 +38,6 @@
#include "dialogs/comp-editor-util.h"
#include <composer/e-msg-composer.h>
-#include <mail/em-composer-utils.h>
#include <camel/camel-mime-filter-tohtml.h>
static const gchar *itip_methods[] = {
@@ -1260,7 +1259,6 @@ itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp,
composer = e_msg_composer_new ();
table = e_msg_composer_get_header_table (composer);
- em_composer_utils_setup_default_callbacks (composer);
e_composer_header_table_set_subject (table, subject);
e_composer_header_table_set_account_name (table, from);
@@ -1368,7 +1366,6 @@ reply_to_calendar_comp (ECalComponentItipMethod method,
composer = e_msg_composer_new ();
table = e_msg_composer_get_header_table (composer);
- em_composer_utils_setup_default_callbacks (composer);
e_composer_header_table_set_subject (table, subject);
e_composer_header_table_set_account_name (table, from);
diff --git a/calendar/gui/main.c b/calendar/gui/main.c
deleted file mode 100644
index 9d078edbd9..0000000000
--- a/calendar/gui/main.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <libgnome/gnome-init.h>
-#include <glade/glade.h>
-
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-shlib-factory.h>
-#include <bonobo/bonobo-exception.h>
-
-#include "dialogs/cal-prefs-dialog.h"
-#include "calendar-commands.h"
-#include "calendar-config.h"
-#include "calendar-component.h"
-#include "e-comp-editor-registry.h"
-#include "comp-editor-factory.h"
-#include "control-factory.h"
-#include "itip-bonobo-control.h"
-#include "tasks-control.h"
-#include "tasks-component.h"
-#include "memos-component.h"
-
-#include <e-util/e-plugin.h>
-#include <e-util/e-import.h>
-#include "e-cal-config.h"
-#include "e-cal-popup.h"
-#include "e-cal-menu.h"
-#include "e-cal-event.h"
-#include "calendar/importers/evolution-calendar-importer.h"
-
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_Factory:" BASE_VERSION
-
-#define CALENDAR_COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_Component:" BASE_VERSION
-#define TASKS_COMPONENT_ID "OAFIID:GNOME_Evolution_Tasks_Component:" BASE_VERSION
-#define MEMOS_COMPONENT_ID "OAFIID:GNOME_Evolution_Memos_Component:" BASE_VERSION
-#define ITIP_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_iTip_Control:" BASE_VERSION
-#define CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_ConfigControl:" BASE_VERSION
-#define COMP_EDITOR_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_CompEditorFactory:" BASE_VERSION
-
-ECompEditorRegistry *comp_editor_registry = NULL;
-
-/* The component editor factory */
-static CompEditorFactory *comp_editor_factory = NULL;
-
-/* Factory function for the calendar component factory; just creates and
- * references a singleton service object.
- */
-static BonoboObject *
-comp_editor_factory_fn (void)
-{
- if (!comp_editor_factory) {
- comp_editor_factory = comp_editor_factory_new ();
- if (!comp_editor_factory)
- return NULL;
- }
-
- bonobo_object_ref (BONOBO_OBJECT (comp_editor_factory));
- return BONOBO_OBJECT (comp_editor_factory);
-}
-
-/* Does a simple activation and unreffing of the alarm notification service so
- * that the daemon will be launched if it is not running yet.
- */
-static gboolean
-launch_alarm_daemon_cb (gpointer data)
-{
- CORBA_Environment ev;
- CORBA_Object an;
-
- /* activate the alarm daemon */
- CORBA_exception_init (&ev);
- an = bonobo_activation_activate_from_id (
- (Bonobo_ActivationID) "OAFIID:GNOME_Evolution_Calendar_AlarmNotify:" BASE_VERSION, 0, NULL, &ev);
-
- if (BONOBO_EX (&ev)) {
- g_message ("launch_alarm_daemon_cb(): %s", bonobo_exception_get_text (&ev));
- CORBA_exception_free (&ev);
- return FALSE;
- }
- CORBA_exception_free (&ev);
-
- /* Just get rid of it; what we are interested in is that it gets launched */
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (an, &ev);
- if (BONOBO_EX (&ev))
- g_message ("add_alarms(): Could not unref the alarm notification service");
-
- CORBA_exception_free (&ev);
-
- return FALSE;
-}
-
-static void
-launch_alarm_daemon (void)
-{
- g_idle_add ((GSourceFunc) launch_alarm_daemon_cb, NULL);
-}
-
-static void
-initialize (void)
-{
- EImportClass *klass;
-
- comp_editor_registry = E_COMP_EDITOR_REGISTRY (e_comp_editor_registry_new ());
-
-#if 0
- itip_control_factory_init ();
- component_editor_factory_init ();
-#endif
-
- launch_alarm_daemon ();
-
- /* Initialize plugin system */
- e_plugin_hook_register_type (e_cal_popup_hook_get_type());
- e_plugin_hook_register_type (e_cal_menu_hook_get_type());
- e_plugin_hook_register_type (e_cal_config_hook_get_type ());
- e_plugin_hook_register_type (e_cal_event_hook_get_type ());
-
- klass = g_type_class_ref(e_import_get_type());
- e_import_class_add_importer(klass, gnome_calendar_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, ical_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, vcal_importer_peek(), NULL, NULL);
-}
-
-static BonoboObject *
-factory (BonoboGenericFactory *factory,
- const gchar *component_id,
- gpointer closure)
-{
- static gboolean initialized = FALSE;
-
- if (! initialized) {
- initialize ();
- initialized = TRUE;
- }
-
- if (strcmp (component_id, CALENDAR_COMPONENT_ID) == 0) {
- BonoboObject *object = BONOBO_OBJECT (calendar_component_peek ());
- bonobo_object_ref (object);
- return object;
- } else if (strcmp (component_id, TASKS_COMPONENT_ID) == 0) {
- BonoboObject *object = BONOBO_OBJECT (tasks_component_peek ());
- bonobo_object_ref (object);
- return object;
- } else if (strcmp (component_id, MEMOS_COMPONENT_ID) == 0) {
- BonoboObject *object = BONOBO_OBJECT (memos_component_peek ());
- bonobo_object_ref (object);
- return object;
- } else if (strcmp (component_id, ITIP_CONTROL_ID) == 0)
- return BONOBO_OBJECT (itip_bonobo_control_new ());
- else if (strcmp (component_id, CONFIG_CONTROL_ID) == 0) {
- GtkWidget *prefs;
- EvolutionConfigControl *control;
-
- prefs = calendar_prefs_dialog_new ();
- gtk_widget_show (prefs);
- control = evolution_config_control_new (prefs);
-
- return BONOBO_OBJECT (control);
- } else if (strcmp (component_id, COMP_EDITOR_FACTORY_ID) == 0)
- return BONOBO_OBJECT (comp_editor_factory_fn ());
-
- g_warning (FACTORY_ID ": Don't know what to do with %s", component_id);
- return NULL;
-}
-
-BONOBO_ACTIVATION_SHLIB_FACTORY (FACTORY_ID, "Evolution Calendar component factory", factory, NULL)
diff --git a/calendar/gui/memos-component.c b/calendar/gui/memos-component.c
deleted file mode 100644
index f4e3200e8c..0000000000
--- a/calendar/gui/memos-component.c
+++ /dev/null
@@ -1,1222 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-#include <glib/gi18n-lib.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-exception.h>
-#include <gconf/gconf-client.h>
-#include <libecal/e-cal.h>
-#include <libedataserver/e-data-server-util.h>
-#include <libedataserverui/e-source-selector.h>
-#include <shell/e-user-creatable-items-handler.h>
-#include <shell/e-component-view.h>
-#include "e-cal-model.h"
-#include "e-memos.h"
-#include "memos-component.h"
-#include "memos-control.h"
-#include "e-comp-editor-registry.h"
-#include "migration.h"
-#include "comp-util.h"
-#include "calendar-config.h"
-#include "e-cal-popup.h"
-#include "common/authentication.h"
-#include "dialogs/calendar-setup.h"
-#include "dialogs/comp-editor.h"
-#include "dialogs/copy-source-dialog.h"
-#include "dialogs/memo-editor.h"
-#include "widgets/misc/e-info-label.h"
-#include "e-util/e-error.h"
-#include "calendar-component.h"
-
-#define CREATE_MEMO_ID "memo"
-#define CREATE_SHARED_MEMO_ID "shared-memo"
-#define CREATE_MEMO_LIST_ID "memo-list"
-
-enum DndTargetType {
- DND_TARGET_TYPE_CALENDAR_LIST
-};
-#define CALENDAR_TYPE "text/calendar"
-#define XCALENDAR_TYPE "text/x-calendar"
-#define WEB_BASE_URI "webcal://"
-#define PERSONAL_RELATIVE_URI "system"
-
-static GtkTargetEntry drag_types[] = {
- { (gchar *) CALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST },
- { (gchar *) XCALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST }
-};
-static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
-
-#define PARENT_TYPE bonobo_object_get_type ()
-
-static BonoboObjectClass *parent_class = NULL;
-
-/* Memos should have their own registry */
-extern ECompEditorRegistry *comp_editor_registry;
-
-typedef struct _MemosComponentView
-{
- ESourceList *source_list;
-
- GSList *source_selection;
-
- EMemos *memos;
- ETable *table;
- ETableModel *model;
-
- EInfoLabel *info_label;
- GtkWidget *source_selector;
-
- BonoboControl *view_control;
- BonoboControl *sidebar_control;
- BonoboControl *statusbar_control;
-
- GList *notifications;
-
- EUserCreatableItemsHandler *creatable_items_handler;
-
- EActivityHandler *activity_handler;
-} MemosComponentView;
-
-struct _MemosComponentPrivate {
- gchar *base_directory;
- gchar *config_directory;
-
- ESourceList *source_list;
- GSList *source_selection;
-
- GList *views;
-
- ECal *create_ecal;
-
- GList *notifications;
-};
-
-#define d(x)
-
-static void
-ensure_sources (MemosComponent *component)
-{
- ESourceList *source_list;
- ESourceGroup *on_this_computer;
- ESource *personal_source;
- gchar *base_uri, *base_uri_proto, base_uri_proto_seventh;
- const gchar *base_dir;
-
- personal_source = NULL;
-
- if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL)) {
- g_warning ("Could not get memo source list from GConf!");
- return;
- }
-
- base_dir = memos_component_peek_base_directory (component);
- base_uri = g_build_filename (base_dir, "local", NULL);
-
- base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
- if (strlen (base_uri_proto) > 7) {
- /* compare only file:// part. If user home dir name changes we do not want to create
- one more group */
- base_uri_proto_seventh = base_uri_proto[7];
- base_uri_proto[7] = 0;
- } else {
- base_uri_proto_seventh = -1;
- }
-
- on_this_computer = e_source_list_ensure_group (source_list, _("On This Computer"), base_uri_proto, TRUE);
- e_source_list_ensure_group (source_list, _("On The Web"), WEB_BASE_URI, FALSE);
-
- if (base_uri_proto_seventh != -1) {
- base_uri_proto[7] = base_uri_proto_seventh;
- }
-
- if (on_this_computer) {
- /* make sure "Personal" shows up as a source under
- this group */
- GSList *sources = e_source_group_peek_sources (on_this_computer);
- GSList *s;
- for (s = sources; s; s = s->next) {
- ESource *source = E_SOURCE (s->data);
- const gchar *relative_uri;
-
- relative_uri = e_source_peek_relative_uri (source);
- if (relative_uri == NULL)
- continue;
- if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
- personal_source = source;
- break;
- }
- }
- /* Make sure we have the correct base uri. This can change when user's
- homedir name changes */
- if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) {
- e_source_group_set_base_uri (on_this_computer, base_uri_proto);
-
- /* *sigh* . We shouldn't need this sync call here as set_base_uri
- call results in synching to gconf, but that happens in idle loop
- and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/
- e_source_list_sync (source_list,NULL);
- }
- }
-
- if (personal_source) {
- /* ensure the source name is in current locale, not read from configuration */
- e_source_set_name (personal_source, _("Personal"));
- } else {
- GSList *memos_selected;
- /* Create the default Person addressbook */
- ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
- e_source_group_add_source (on_this_computer, source, -1);
- g_object_unref (source);
-
- memos_selected = calendar_config_get_memos_selected ();
-
- if (!calendar_config_get_primary_memos () && !memos_selected) {
- GSList selected;
-
- calendar_config_set_primary_memos (e_source_peek_uid (source));
-
- selected.data = (gpointer)e_source_peek_uid (source);
- selected.next = NULL;
- calendar_config_set_memos_selected (&selected);
- }
-
- if (memos_selected) {
- g_slist_foreach (memos_selected, (GFunc) g_free, NULL);
- g_slist_free (memos_selected);
- }
-
- e_source_set_color_spec (source, "#BECEDD");
- personal_source = source;
- }
-
- component->priv->source_list = source_list;
-
- g_object_unref (on_this_computer);
- g_free (base_uri_proto);
- g_free (base_uri);
-}
-
-/* Utility functions. */
-/* FIXME Some of these are duplicated from calendar-component.c */
-static gboolean
-is_in_selection (GSList *selection, ESource *source)
-{
- GSList *l;
-
- for (l = selection; l; l = l->next) {
- ESource *selected_source = l->data;
-
- if (!strcmp (e_source_peek_uid (selected_source), e_source_peek_uid (source)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-is_in_uids (GSList *uids, ESource *source)
-{
- GSList *l;
-
- for (l = uids; l; l = l->next) {
- const gchar *uid = l->data;
-
- if (!strcmp (uid, e_source_peek_uid (source)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-update_uris_for_selection (MemosComponentView *component_view)
-{
- GSList *selection, *l, *uids_selected = NULL;
-
- selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
-
- for (l = component_view->source_selection; l; l = l->next) {
- ESource *old_selected_source = l->data;
-
- if (!is_in_selection (selection, old_selected_source))
- e_memos_remove_memo_source (component_view->memos, old_selected_source);
- }
-
- for (l = selection; l; l = l->next) {
- ESource *selected_source = l->data;
-
- e_memos_add_memo_source (component_view->memos, selected_source);
- uids_selected = g_slist_append (uids_selected, (gchar *)e_source_peek_uid (selected_source));
- }
-
- e_source_selector_free_selection (component_view->source_selection);
- component_view->source_selection = selection;
-
- /* Save the selection for next time we start up */
- calendar_config_set_memos_selected (uids_selected);
- g_slist_free (uids_selected);
-}
-
-static void
-update_uri_for_primary_selection (MemosComponentView *component_view)
-{
- ESource *source;
- EMemoTable *cal_table;
- ETable *etable;
-
- source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!source)
- return;
-
- /* Set the default */
- e_memos_set_default_source (component_view->memos, source);
-
- cal_table = e_memos_get_calendar_table (component_view->memos);
- etable = e_memo_table_get_table (cal_table);
-
- memos_control_sensitize_commands (component_view->view_control, component_view->memos, e_table_selected_count (etable));
-
- /* Save the selection for next time we start up */
- calendar_config_set_primary_memos (e_source_peek_uid (source));
-}
-
-static void
-update_selection (MemosComponentView *component_view)
-{
- GSList *selection, *uids_selected, *l;
-
- d(g_message("memos-component.c: update_selection called");)
-
- /* Get the selection in gconf */
- uids_selected = calendar_config_get_memos_selected ();
-
- /* Remove any that aren't there any more */
- selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
-
- for (l = selection; l; l = l->next) {
- ESource *source = l->data;
-
- if (!is_in_uids (uids_selected, source))
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
- }
-
- e_source_selector_free_selection (selection);
-
- /* Make sure the whole selection is there */
- for (l = uids_selected; l; l = l->next) {
- gchar *uid = l->data;
- ESource *source;
-
- source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
- if (source)
- e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
-
- g_free (uid);
- }
- g_slist_free (uids_selected);
-}
-
-static void
-update_primary_selection (MemosComponentView *component_view)
-{
- ESource *source = NULL;
- gchar *uid;
-
- uid = calendar_config_get_primary_memos ();
- if (uid) {
- source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
- g_free (uid);
- }
-
- if (source) {
- e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source);
- } else {
- /* Try to create a default if there isn't one */
- source = e_source_list_peek_source_any (component_view->source_list);
- if (source)
- e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source);
- }
-
-}
-
-/* Callbacks. */
-/* TODO: doesn't work! */
-static void
-copy_memo_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- MemosComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source, E_CAL_SOURCE_TYPE_JOURNAL);
-}
-
-static void
-delete_memo_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- MemosComponentView *component_view = data;
- ESource *selected_source;
- ECal *cal;
- gchar *uri;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- if (e_error_run((GtkWindow *)gtk_widget_get_toplevel(ep->target->widget),
- "calendar:prompt-delete-memo-list", e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES)
- return;
-
- /* first, ask the backend to remove the memo list */
- uri = e_source_get_uri (selected_source);
- cal = e_cal_model_get_client_for_uri (
- e_memo_table_get_model (E_MEMO_TABLE (e_memos_get_calendar_table (component_view->memos))),
- uri);
- if (!cal)
- cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_JOURNAL);
- g_free (uri);
- if (cal) {
- if (e_cal_remove (cal, NULL)) {
- if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source)) {
- e_memos_remove_memo_source (component_view->memos, selected_source);
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source);
- }
-
- e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
- e_source_list_sync (component_view->source_list, NULL);
- }
- }
-}
-
-static void
-new_memo_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- calendar_setup_new_memo_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)));
-}
-
-static void
-rename_memo_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- MemosComponentView *component_view = data;
- ESourceSelector *selector;
-
- selector = E_SOURCE_SELECTOR (component_view->source_selector);
- e_source_selector_edit_primary_selection (selector);
-}
-
-static void
-edit_memo_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- MemosComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- calendar_setup_edit_memo_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source);
-}
-
-static void
-set_offline_availability (EPopup *ep, EPopupItem *pitem, gpointer data, const gchar *value)
-{
- MemosComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- e_source_set_property (selected_source, "offline_sync", value);
-}
-
-static void
-mark_no_offline_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- set_offline_availability (ep, pitem, data, "0");
-}
-
-static void
-mark_offline_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- set_offline_availability (ep, pitem, data, "1");
-}
-
-static EPopupItem emc_source_popups[] = {
- { E_POPUP_ITEM, (gchar *) "10.new", (gchar *) N_("_New Memo List"), new_memo_list_cb, NULL, (gchar *) "stock_notes", 0, 0 },
- { E_POPUP_ITEM, (gchar *) "15.copy", (gchar *) N_("_Copy..."), copy_memo_list_cb, NULL, (gchar *) "edit-copy", 0, E_CAL_POPUP_SOURCE_PRIMARY },
- { E_POPUP_ITEM, (gchar *) "18.rename", (gchar *) N_("_Rename..."), rename_memo_list_cb, NULL, NULL, 0, E_CAL_POPUP_SOURCE_PRIMARY },
-
- { E_POPUP_BAR, (gchar *) "20.bar" },
- { E_POPUP_ITEM, (gchar *) "20.delete", (gchar *) N_("_Delete"), delete_memo_list_cb, NULL, (gchar *) "edit-delete", 0, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY },
- { E_POPUP_ITEM, (gchar *) "30.mark_memos_offline", (gchar *) N_("_Make available for offline use"), mark_offline_cb, NULL, (gchar *) "stock_disconnect", E_CAL_POPUP_SOURCE_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_OFFLINE },
- { E_POPUP_ITEM, (gchar *) "40.mark_memos_no_offline", (gchar *) N_("_Do not make available for offline use"), mark_no_offline_cb, NULL, (gchar *) "stock_connect", E_CAL_POPUP_SOURCE_NO_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_NO_OFFLINE },
-
- { E_POPUP_BAR, (gchar *) "99.bar" },
- { E_POPUP_ITEM, (gchar *) "99.properties", (gchar *) N_("_Properties"), edit_memo_list_cb, NULL, (gchar *) "document-properties", 0, E_CAL_POPUP_SOURCE_PRIMARY },
-};
-
-static void
-emc_source_popup_free(EPopup *ep, GSList *list, gpointer data)
-{
- g_slist_free(list);
-}
-
-static gboolean
-popup_event_cb(ESourceSelector *selector, ESource *insource, GdkEventButton *event, MemosComponentView *component_view)
-{
- ECalPopup *ep;
- ECalPopupTargetSource *t;
- GSList *menus = NULL;
- gint i;
- GtkMenu *menu;
-
- /** @HookPoint-ECalPopup: Memos Source Selector Context Menu
- * @Id: org.gnome.evolution.memos.source.popup
- * @Class: org.gnome.evolution.calendar.popup:1.0
- * @Target: ECalPopupTargetSource
- *
- * The context menu on the source selector in the memos window.
- */
- ep = e_cal_popup_new("org.gnome.evolution.memos.source.popup");
- t = e_cal_popup_target_new_source(ep, selector);
- t->target.widget = (GtkWidget *)component_view->memos;
-
- for (i=0;i<sizeof(emc_source_popups)/sizeof(emc_source_popups[0]);i++)
- menus = g_slist_prepend(menus, &emc_source_popups[i]);
-
- e_popup_add_items((EPopup *)ep, menus, NULL,emc_source_popup_free, component_view);
-
- menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time());
-
- return TRUE;
-}
-
-static void
-source_selection_changed_cb (ESourceSelector *selector, MemosComponentView *component_view)
-{
- update_uris_for_selection (component_view);
-}
-
-static void
-primary_source_selection_changed_cb (ESourceSelector *selector, MemosComponentView *component_view)
-{
- update_uri_for_primary_selection (component_view);
-}
-
-static void
-source_added_cb (EMemos *memos, ESource *source, MemosComponentView *component_view)
-{
- e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
-}
-
-static void
-source_removed_cb (EMemos *memos, ESource *source, MemosComponentView *component_view)
-{
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
-}
-
-static void
-set_info (MemosComponentView *component_view)
-{
- GString *message = g_string_new (NULL);
- gint rows, selected_rows;
-
- rows = e_table_model_row_count (component_view->model);
- selected_rows = e_table_selected_count (component_view->table);
-
- g_string_append_printf(message, ngettext("%d memo", "%d memos", rows), rows);
- if (selected_rows > 0)
- g_string_append_printf(message, ngettext(", %d selected", ", %d selected", selected_rows), selected_rows);
-
- e_info_label_set_info (component_view->info_label, _("Memos"), message->str);
-
- g_string_free (message, TRUE);
-}
-
-static void
-table_selection_change_cb (ETableModel *etm, MemosComponentView *component_view)
-{
- set_info (component_view);
-}
-
-static void
-model_changed_cb (ETableModel *etm, MemosComponentView *component_view)
-{
- set_info (component_view);
-}
-
-static void
-model_rows_inserted_cb (ETableModel *etm, gint row, gint count, MemosComponentView *component_view)
-{
- set_info (component_view);
-}
-
-static void
-model_rows_deleted_cb (ETableModel *etm, gint row, gint count, MemosComponentView *component_view)
-{
- set_info (component_view);
-}
-
-/* Evolution::Component CORBA methods */
-
-static void
-impl_upgradeFromVersion (PortableServer_Servant servant,
- CORBA_short major,
- CORBA_short minor,
- CORBA_short revision,
- CORBA_Environment *ev)
-{
- GError *err = NULL;
- MemosComponent *component = MEMOS_COMPONENT (bonobo_object_from_servant (servant));
-
- if (!migrate_memos(component, major, minor, revision, &err)) {
- GNOME_Evolution_Component_UpgradeFailed *failedex;
-
- failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
- failedex->what = CORBA_string_dup(_("Failed upgrading memos."));
- failedex->why = CORBA_string_dup(err->message);
- CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
- }
-
- if (err)
- g_error_free(err);
-}
-
-static gboolean
-selector_tree_data_dropped (ESourceSelector *selector,
- GtkSelectionData *data,
- ESource *destination,
- GdkDragAction action,
- guint info,
- MemosComponent *component)
-{
- gboolean success = FALSE;
- icalcomponent *icalcomp = NULL;
- ECal *client = NULL;
- GSList *components, *p;
-
- client = auth_new_cal_from_source (
- destination, E_CAL_SOURCE_TYPE_JOURNAL);
-
- if (!client || !e_cal_open (client, TRUE, NULL))
- goto finish;
-
- components = cal_comp_selection_get_string_list (data);
- success = components != NULL;
- for (p = components; p && success; p = p->next) {
- gchar *comp_str; /* do not free this! */
-
- /* p->data is "source_uid\ncomponent_string" */
- comp_str = strchr (p->data, '\n');
- if (!comp_str)
- continue;
-
- comp_str [0] = 0;
- comp_str++;
- icalcomp = icalparser_parse_string (comp_str);
-
- if (!icalcomp)
- continue;
-
- success = cal_comp_process_source_list_drop (client, icalcomp, action, p->data, component->priv->source_list);
- icalcomponent_free (icalcomp);
- }
-
- g_slist_foreach (components, (GFunc)g_free, NULL);
- g_slist_free (components);
-
- finish:
- if (client)
- g_object_unref (client);
-
- return success;
-}
-
-static void
-control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
-{
- MemosComponentView *component_view = data;
-
- if (activate) {
- BonoboUIComponent *uic;
- uic = bonobo_control_get_ui_component (component_view->view_control);
-
- e_user_creatable_items_handler_activate (component_view->creatable_items_handler, uic);
- }
-}
-
-static void
-config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- MemosComponent *component = data;
- MemosComponentPrivate *priv;
-
- priv = component->priv;
-
- g_object_unref (priv->create_ecal);
- priv->create_ecal = NULL;
-
- priv->notifications = g_list_remove (priv->notifications, GUINT_TO_POINTER (id));
-}
-
-static ECal *
-setup_create_ecal (MemosComponent *component, MemosComponentView *component_view)
-{
- MemosComponentPrivate *priv;
- ESource *source = NULL;
- gchar *uid;
- guint not;
-
- priv = component->priv;
-
- if (component_view) {
- ECal *default_ecal;
-
- default_ecal = e_memos_get_default_client (component_view->memos);
- if (default_ecal)
- return default_ecal;
- }
-
- if (priv->create_ecal)
- return priv->create_ecal;
-
- /* Get the current primary calendar, or try to set one if it doesn't already exist */
- uid = calendar_config_get_primary_memos ();
- if (uid) {
- source = e_source_list_peek_source_by_uid (priv->source_list, uid);
- g_free (uid);
-
- priv->create_ecal = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
- }
-
- if (!priv->create_ecal) {
- /* Try to create a default if there isn't one */
- source = e_source_list_peek_source_any (priv->source_list);
- if (source)
- priv->create_ecal = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
- }
-
- if (priv->create_ecal) {
-
- if (!e_cal_open (priv->create_ecal, FALSE, NULL)) {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
- _("Unable to open the memo list '%s' for creating events and meetings"),
- e_source_peek_name (source));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- return NULL;
- }
-
- } else {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
- "%s", _("There is no calendar available for creating memos"));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- return NULL;
- }
-
- /* Handle the fact it may change on us */
- not = calendar_config_add_notification_primary_memos (config_create_ecal_changed_cb,
- component);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Save the primary source for use elsewhere */
- calendar_config_set_primary_memos (e_source_peek_uid (source));
-
- return priv->create_ecal;
-}
-
-/* Ensures the calendar is selected */
-static void
-object_created_cb (CompEditor *ce, EMemoTable *memo_table)
-{
- g_return_if_fail (memo_table != NULL);
-
- memo_table->user_created_cal = comp_editor_get_client (ce);
- g_signal_emit_by_name (memo_table, "user_created");
- memo_table->user_created_cal = NULL;
-}
-
-static gboolean
-create_new_memo (MemosComponent *memo_component, gboolean is_assigned, MemosComponentView *component_view)
-{
- ECal *ecal;
- ECalComponent *comp;
- CompEditor *editor;
- CompEditorFlags flags = 0;
-
- ecal = setup_create_ecal (memo_component, component_view);
- if (!ecal)
- return FALSE;
-
- flags |= COMP_EDITOR_NEW_ITEM;
- if (is_assigned) {
- flags |= COMP_EDITOR_IS_SHARED;
- flags |= COMP_EDITOR_USER_ORG;
- }
-
- editor = memo_editor_new (ecal, flags);
- comp = cal_comp_memo_new_with_defaults (ecal);
-
- if (component_view)
- g_signal_connect (editor, "object_created", G_CALLBACK (object_created_cb), e_memos_get_calendar_table (component_view->memos));
-
- comp_editor_edit_comp (editor, comp);
- gtk_window_present (GTK_WINDOW (editor));
-
- e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
-
- return TRUE;
-}
-
-static void
-create_local_item_cb (EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data)
-{
- MemosComponent *memos_component = data;
- MemosComponentPrivate *priv;
- MemosComponentView *component_view = NULL;
- GList *l;
-
- priv = memos_component->priv;
-
- for (l = priv->views; l; l = l->next) {
- component_view = l->data;
-
- if (component_view->creatable_items_handler == handler)
- break;
-
- component_view = NULL;
- }
-
- if (strcmp (item_type_name, CREATE_MEMO_ID) == 0) {
- create_new_memo (memos_component, FALSE, component_view);
- } else if (strcmp (item_type_name, CREATE_SHARED_MEMO_ID) == 0) {
- create_new_memo (memos_component, TRUE, component_view);
- } else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) {
- calendar_setup_new_memo_list (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->memos))));
- }
-}
-
-static MemosComponentView *
-create_component_view (MemosComponent *memos_component)
-{
- MemosComponentPrivate *priv;
- MemosComponentView *component_view;
- GtkWidget *selector_scrolled_window, *vbox;
- GtkWidget *statusbar_widget;
- AtkObject *a11y;
-
- priv = memos_component->priv;
-
- /* Create the calendar component view */
- component_view = g_new0 (MemosComponentView, 1);
-
- /* Add the source lists */
- component_view->source_list = g_object_ref (priv->source_list);
-
- /* Create sidebar selector */
- component_view->source_selector = e_source_selector_new (memos_component->priv->source_list);
- e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE);
- a11y = gtk_widget_get_accessible (GTK_WIDGET (component_view->source_selector));
- atk_object_set_name (a11y, _("Memo Source Selector"));
-
- g_signal_connect (
- component_view->source_selector, "data-dropped",
- G_CALLBACK (selector_tree_data_dropped), memos_component);
-
- gtk_drag_dest_set(component_view->source_selector, GTK_DEST_DEFAULT_ALL, drag_types,
- num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
- gtk_widget_show (component_view->source_selector);
-
- selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_container_add (GTK_CONTAINER (selector_scrolled_window), component_view->source_selector);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window),
- GTK_SHADOW_IN);
- gtk_widget_show (selector_scrolled_window);
-
- component_view->info_label = (EInfoLabel *)e_info_label_new("evolution-memos");
- e_info_label_set_info(component_view->info_label, _("Memos"), "");
- gtk_widget_show (GTK_WIDGET (component_view->info_label));
-
- vbox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX (vbox), GTK_WIDGET (component_view->info_label), FALSE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX (vbox), selector_scrolled_window, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- component_view->sidebar_control = bonobo_control_new (vbox);
-
- /* Create main view */
- component_view->view_control = memos_control_new ();
- if (!component_view->view_control) {
- /* FIXME free memory */
-
- return NULL;
- }
-
- component_view->memos = (EMemos *) bonobo_control_get_widget (component_view->view_control);
- component_view->table = e_memo_table_get_table (e_memos_get_calendar_table (component_view->memos));
- component_view->model = E_TABLE_MODEL (e_memo_table_get_model (e_memos_get_calendar_table (component_view->memos)));
-
- /* This signal is thrown if backends die - we update the selector */
- g_signal_connect (component_view->memos, "source_added",
- G_CALLBACK (source_added_cb), component_view);
- g_signal_connect (component_view->memos, "source_removed",
- G_CALLBACK (source_removed_cb), component_view);
-
- /* Create status bar */
- statusbar_widget = e_task_bar_new ();
- component_view->activity_handler = e_activity_handler_new ();
- e_activity_handler_attach_task_bar (component_view->activity_handler, E_TASK_BAR (statusbar_widget));
- gtk_widget_show (statusbar_widget);
-
- component_view->statusbar_control = bonobo_control_new (statusbar_widget);
-
- e_memo_table_set_activity_handler (e_memos_get_calendar_table (component_view->memos), component_view->activity_handler);
-
- /* connect after setting the initial selections, or we'll get unwanted calls
- to calendar_control_sensitize_calendar_commands */
- g_signal_connect (component_view->source_selector, "selection_changed",
- G_CALLBACK (source_selection_changed_cb), component_view);
- g_signal_connect (component_view->source_selector, "primary_selection_changed",
- G_CALLBACK (primary_source_selection_changed_cb), component_view);
- g_signal_connect (component_view->source_selector, "popup_event",
- G_CALLBACK (popup_event_cb), component_view);
-
- /* Set up the "new" item handler */
- component_view->creatable_items_handler = e_user_creatable_items_handler_new ("memos", create_local_item_cb, memos_component);
- g_signal_connect (component_view->view_control, "activate", G_CALLBACK (control_activate_cb), component_view);
-
- /* We use this to update the component information */
- set_info (component_view);
- g_signal_connect (component_view->table, "selection_change",
- G_CALLBACK (table_selection_change_cb), component_view);
- g_signal_connect (component_view->model, "model_changed",
- G_CALLBACK (model_changed_cb), component_view);
- g_signal_connect (component_view->model, "model_rows_inserted",
- G_CALLBACK (model_rows_inserted_cb), component_view);
- g_signal_connect (component_view->model, "model_rows_deleted",
- G_CALLBACK (model_rows_deleted_cb), component_view);
-
- /* Load the selection from the last run */
- update_selection (component_view);
- update_primary_selection (component_view);
-
- return component_view;
-}
-
-static void
-destroy_component_view (MemosComponentView *component_view)
-{
- GList *l;
-
- if (component_view->source_list)
- g_object_unref (component_view->source_list);
-
- if (component_view->source_selection)
- e_source_selector_free_selection (component_view->source_selection);
-
- for (l = component_view->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
- g_list_free (component_view->notifications);
-
- if (component_view->creatable_items_handler)
- g_object_unref (component_view->creatable_items_handler);
-
- if (component_view->activity_handler)
- g_object_unref (component_view->activity_handler);
-
- g_free (component_view);
-}
-
-static void
-view_destroyed_cb (gpointer data, GObject *where_the_object_was)
-{
- MemosComponent *memos_component = data;
- MemosComponentPrivate *priv;
- GList *l;
-
- priv = memos_component->priv;
-
- for (l = priv->views; l; l = l->next) {
- MemosComponentView *component_view = l->data;
-
- if (G_OBJECT (component_view->view_control) == where_the_object_was) {
- priv->views = g_list_remove (priv->views, component_view);
- destroy_component_view (component_view);
-
- break;
- }
- }
-}
-
-static GNOME_Evolution_ComponentView
-impl_createView (PortableServer_Servant servant,
- GNOME_Evolution_ShellView parent,
- CORBA_boolean select_item,
- CORBA_Environment *ev)
-{
- MemosComponent *component = MEMOS_COMPONENT (bonobo_object_from_servant (servant));
- MemosComponentPrivate *priv;
- MemosComponentView *component_view;
- EComponentView *ecv;
-
- priv = component->priv;
-
- /* Create the calendar component view */
- component_view = create_component_view (component);
- if (!component_view) {
- /* FIXME Should we describe the problem in a control? */
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
-
- return CORBA_OBJECT_NIL;
- }
-
- g_object_weak_ref (G_OBJECT (component_view->view_control), view_destroyed_cb, component);
- priv->views = g_list_append (priv->views, component_view);
-
- /* TODO: Make CalendarComponentView just subclass EComponentView */
- ecv = e_component_view_new_controls (parent, "memos", component_view->sidebar_control,
- component_view->view_control, component_view->statusbar_control);
-
- return BONOBO_OBJREF(ecv);
-}
-
-static GNOME_Evolution_CreatableItemTypeList *
-impl__get_userCreatableItems (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
-
- list->_length = 3;
- list->_maximum = list->_length;
- list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
-
- CORBA_sequence_set_release (list, FALSE);
-
- list->_buffer[0].id = (gchar *) CREATE_MEMO_ID;
- list->_buffer[0].description = (gchar *) _("New memo");
- list->_buffer[0].menuDescription = (gchar *) C_("New", "Mem_o");
- list->_buffer[0].tooltip = (gchar *) _("Create a new memo");
- list->_buffer[0].menuShortcut = 'o';
- list->_buffer[0].iconName = (gchar *) "stock_insert-note";
- list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[1].id = (gchar *) CREATE_SHARED_MEMO_ID;
- list->_buffer[1].description = (gchar *) _("New shared memo");
- list->_buffer[1].menuDescription = (gchar *) C_("New", "_Shared memo");
- list->_buffer[1].tooltip = (gchar *) _("Create a shared new memo");
- list->_buffer[1].menuShortcut = 'h';
- list->_buffer[1].iconName = (gchar *) "stock_insert-note";
- list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[2].id = (gchar *) CREATE_MEMO_LIST_ID;
- list->_buffer[2].description = (gchar *) _("New memo list");
- list->_buffer[2].menuDescription = (gchar *) C_("New", "Memo li_st");
- list->_buffer[2].tooltip = (gchar *) _("Create a new memo list");
- list->_buffer[2].menuShortcut = '\0';
- list->_buffer[2].iconName = (gchar *) "stock_notes";
- list->_buffer[2].type = GNOME_Evolution_CREATABLE_FOLDER;
-
- return list;
-}
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
- const CORBA_char *item_type_name,
- CORBA_Environment *ev)
-{
- MemosComponent *memos_component = MEMOS_COMPONENT (bonobo_object_from_servant (servant));
-
- if (strcmp (item_type_name, CREATE_MEMO_ID) == 0) {
- if (!create_new_memo (memos_component, FALSE, NULL))
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
- }
- else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) {
- /* FIXME Should we use the last opened window? */
- calendar_setup_new_memo_list (NULL);
- } else if (strcmp (item_type_name, CREATE_SHARED_MEMO_ID) == 0) {
- if (!create_new_memo (memos_component, TRUE, NULL))
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
- }
- else {
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType);
- }
-}
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- MemosComponent *memos_component = MEMOS_COMPONENT (object);
- MemosComponentPrivate *priv = memos_component->priv;
- GList *l;
-
- if (priv->source_list != NULL) {
- g_object_unref (priv->source_list);
- priv->source_list = NULL;
- }
- if (priv->source_selection != NULL) {
- e_source_selector_free_selection (priv->source_selection);
- priv->source_selection = NULL;
- }
-
- if (priv->create_ecal) {
- g_object_unref (priv->create_ecal);
- priv->create_ecal = NULL;
- }
-
- for (l = priv->views; l; l = l->next) {
- MemosComponentView *component_view = l->data;
-
- g_object_weak_unref (G_OBJECT (component_view->view_control), view_destroyed_cb, memos_component);
- }
- g_list_free (priv->views);
- priv->views = NULL;
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- MemosComponentPrivate *priv = MEMOS_COMPONENT (object)->priv;
- GList *l;
-
- for (l = priv->views; l; l = l->next) {
- MemosComponentView *component_view = l->data;
-
- destroy_component_view (component_view);
- }
- g_list_free (priv->views);
-
- g_free (priv->base_directory);
- g_free (priv->config_directory);
- g_free (priv);
-
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-static void
-memos_component_class_init (MemosComponentClass *klass)
-{
- POA_GNOME_Evolution_Component__epv *epv = &klass->epv;
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- parent_class = g_type_class_peek_parent (klass);
-
- epv->upgradeFromVersion = impl_upgradeFromVersion;
- epv->createView = impl_createView;
- epv->_get_userCreatableItems = impl__get_userCreatableItems;
- epv->requestCreateItem = impl_requestCreateItem;
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-}
-
-static void
-memos_component_init (MemosComponent *component, MemosComponentClass *klass)
-{
- MemosComponentPrivate *priv;
-
- priv = g_new0 (MemosComponentPrivate, 1);
-
- priv->base_directory = g_build_filename (e_get_user_data_dir (), "memos", NULL);
- priv->config_directory = g_build_filename (priv->base_directory, "config", NULL);
-
- component->priv = priv;
- ensure_sources (component);
-}
-
-/* Public API */
-
-MemosComponent *
-memos_component_peek (void)
-{
- static MemosComponent *component = NULL;
-
- if (component == NULL) {
- component = g_object_new (memos_component_get_type (), NULL);
-
- if (g_mkdir_with_parents (component->priv->config_directory, 0777) != 0) {
- g_warning (G_STRLOC ": Cannot create directory %s: %s",
- component->priv->config_directory, g_strerror (errno));
- g_object_unref (component);
- component = NULL;
- }
- }
-
- return component;
-}
-
-const gchar *
-memos_component_peek_base_directory (MemosComponent *component)
-{
- return component->priv->base_directory;
-}
-
-const gchar *
-memos_component_peek_config_directory (MemosComponent *component)
-{
- return component->priv->config_directory;
-}
-
-ESourceList *
-memos_component_peek_source_list (MemosComponent *component)
-{
- return component->priv->source_list;
-}
-
-BONOBO_TYPE_FUNC_FULL (MemosComponent, GNOME_Evolution_Component, PARENT_TYPE, memos_component)
diff --git a/calendar/gui/memos-component.h b/calendar/gui/memos-component.h
deleted file mode 100644
index 54f522ba9c..0000000000
--- a/calendar/gui/memos-component.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _MEMOS_COMPONENT_H_
-#define _MEMOS_COMPONENT_H_
-
-#include <bonobo/bonobo-object.h>
-#include <libedataserver/e-source-list.h>
-#include <widgets/misc/e-activity-handler.h>
-#include "Evolution.h"
-
-#define MEMOS_TYPE_COMPONENT (memos_component_get_type ())
-#define MEMOS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MEMOS_TYPE_COMPONENT, MemosComponent))
-#define MEMOS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MEMOS_TYPE_COMPONENT, MemosComponentClass))
-#define MEMOS_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MEMOS_TYPE_COMPONENT))
-#define MEMOS_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), MEMOS_TYPE_COMPONENT))
-
-typedef struct _MemosComponent MemosComponent;
-typedef struct _MemosComponentPrivate MemosComponentPrivate;
-typedef struct _MemosComponentClass MemosComponentClass;
-
-struct _MemosComponent {
- BonoboObject parent;
-
- MemosComponentPrivate *priv;
-};
-
-struct _MemosComponentClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Component__epv epv;
-};
-
-GType memos_component_get_type (void);
-MemosComponent *memos_component_peek (void);
-
-const gchar *memos_component_peek_base_directory (MemosComponent *component);
-const gchar *memos_component_peek_config_directory (MemosComponent *component);
-ESourceList *memos_component_peek_source_list (MemosComponent *component);
-
-#endif /* _MEMOS_COMPONENT_H_ */
diff --git a/calendar/gui/memos-control.c b/calendar/gui/memos-control.c
deleted file mode 100644
index a7983779a7..0000000000
--- a/calendar/gui/memos-control.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Damon Chaplin <damon@ximian.com>
- * Ettore Perazzoli
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <e-util/e-dialog-utils.h>
-#include <e-util/e-icon-factory.h>
-#include <e-util/e-print.h>
-#include <e-util/e-util-private.h>
-#include <gtkhtml/gtkhtml.h>
-
-#include "calendar-config.h"
-#include "e-memos.h"
-#include "e-memo-table.h"
-#include "print.h"
-#include "memos-control.h"
-#include "e-cal-component-memo-preview.h"
-#include "evolution-shell-component-utils.h"
-
-#define FIXED_MARGIN .05
-
-static void memos_control_activate_cb (BonoboControl *control,
- gboolean activate,
- gpointer user_data);
-static void memos_control_open_memo_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void memos_control_new_memo_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void memos_control_cut_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void memos_control_copy_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void memos_control_paste_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void memos_control_delete_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void memos_control_print_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void memos_control_print_preview_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-
-struct focus_changed_data {
- BonoboControl *control;
- EMemos *memos;
-};
-
-static gboolean memos_control_focus_changed (GtkWidget *widget, GdkEventFocus *event, struct focus_changed_data *fc_data);
-
-BonoboControl *
-memos_control_new (void)
-{
- BonoboControl *control;
- GtkWidget *memos, *preview;
- struct focus_changed_data *fc_data;
-
- memos = e_memos_new ();
- if (!memos)
- return NULL;
- gtk_widget_show (memos);
-
- control = bonobo_control_new (memos);
- if (!control) {
- gtk_widget_destroy (memos);
- g_message ("control_factory_fn(): could not create the control!");
- return NULL;
- }
-
- g_signal_connect (control, "activate", G_CALLBACK (memos_control_activate_cb), memos);
-
- fc_data = g_new0 (struct focus_changed_data, 1);
- fc_data->control = control;
- fc_data->memos = E_MEMOS (memos);
-
- preview = e_cal_component_memo_preview_get_html (E_CAL_COMPONENT_MEMO_PREVIEW (e_memos_get_preview (fc_data->memos)));
- g_object_set_data_full (G_OBJECT (preview), "memos-ctrl-fc-data", fc_data, g_free);
- g_signal_connect (preview, "focus-in-event", G_CALLBACK (memos_control_focus_changed), fc_data);
- g_signal_connect (preview, "focus-out-event", G_CALLBACK (memos_control_focus_changed), fc_data);
-
- return control;
-}
-
-static void
-memos_control_activate_cb (BonoboControl *control,
- gboolean activate,
- gpointer user_data)
-{
- EMemos *memos;
-
- memos = E_MEMOS (user_data);
-
- if (activate)
- memos_control_activate (control, memos);
- else
- memos_control_deactivate (control, memos);
-}
-
-/* Sensitizes the UI Component menu/toolbar commands based on the number of
- * selected memos.
- */
-void
-memos_control_sensitize_commands (BonoboControl *control, EMemos *memos, gint n_selected)
-{
- BonoboUIComponent *uic;
- gboolean read_only = TRUE, preview_active;
- ECal *ecal;
- ECalModel *model;
- GtkWidget *preview;
-
- uic = bonobo_control_get_ui_component (control);
- g_return_if_fail (uic != NULL);
-
- if (bonobo_ui_component_get_container (uic) == CORBA_OBJECT_NIL)
- return;
-
- preview = e_cal_component_memo_preview_get_html (E_CAL_COMPONENT_MEMO_PREVIEW (e_memos_get_preview (memos)));
- preview_active = preview && GTK_WIDGET_VISIBLE (preview) && GTK_WIDGET_HAS_FOCUS (preview);
-
- model = e_memo_table_get_model (e_memos_get_calendar_table (memos));
- ecal = e_cal_model_get_default_client (model);
- if (ecal)
- e_cal_is_read_only (ecal, &read_only, NULL);
-
- bonobo_ui_component_set_prop (uic, "/commands/MemosOpenMemo", "sensitive",
- n_selected != 1 ? "0" : "1",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/MemosCut", "sensitive",
- n_selected == 0 || read_only || preview_active ? "0" : "1",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/MemosCopy", "sensitive",
- n_selected == 0 ? "0" : "1",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/MemosPaste", "sensitive",
- read_only || preview_active ? "0" : "1",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/MemosDelete", "sensitive",
- n_selected == 0 || read_only ? "0" : "1",
- NULL);
-}
-
-/* Callback used when the selection in the table changes */
-static void
-selection_changed_cb (EMemos *memos, gint n_selected, gpointer data)
-{
- BonoboControl *control;
-
- control = BONOBO_CONTROL (data);
-
- memos_control_sensitize_commands (control, memos, n_selected);
-}
-
-static gboolean
-memos_control_focus_changed (GtkWidget *widget, GdkEventFocus *event, struct focus_changed_data *fc_data)
-{
- g_return_val_if_fail (fc_data != NULL, FALSE);
-
- memos_control_sensitize_commands (fc_data->control, fc_data->memos, e_table_selected_count (e_memo_table_get_table (e_memos_get_calendar_table (fc_data->memos))));
-
- return FALSE;
-}
-
-static BonoboUIVerb verbs [] = {
- BONOBO_UI_VERB ("MemosOpenMemo", memos_control_open_memo_cmd),
- BONOBO_UI_VERB ("MemosNewMemo", memos_control_new_memo_cmd),
- BONOBO_UI_VERB ("MemosCut", memos_control_cut_cmd),
- BONOBO_UI_VERB ("MemosCopy", memos_control_copy_cmd),
- BONOBO_UI_VERB ("MemosPaste", memos_control_paste_cmd),
- BONOBO_UI_VERB ("MemosDelete", memos_control_delete_cmd),
- BONOBO_UI_VERB ("MemosPrint", memos_control_print_cmd),
- BONOBO_UI_VERB ("MemosPrintPreview", memos_control_print_preview_cmd),
-
- BONOBO_UI_VERB_END
-};
-
-static EPixmap pixmaps [] = {
- E_PIXMAP ("/commands/MemosCopy", "edit-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MemosCut", "edit-cut", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MemosDelete", "edit-delete", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MemosPaste", "edit-paste", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MemosPrint", "document-print", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MemosPrintPreview", "document-print-preview", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP ("/Toolbar/Cut", "edit-cut", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Copy", "edit-copy", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Paste", "edit-paste", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Print", "document-print", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Delete", "edit-delete", GTK_ICON_SIZE_LARGE_TOOLBAR),
-
- E_PIXMAP_END
-};
-
-void
-memos_control_activate (BonoboControl *control, EMemos *memos)
-{
- Bonobo_UIContainer remote_uih;
- BonoboUIComponent *uic;
- gint n_selected;
- EMemoTable *cal_table;
- ETable *etable;
- gchar *xmlfile;
-
- uic = bonobo_control_get_ui_component (control);
- g_return_if_fail (uic != NULL);
-
- remote_uih = bonobo_control_get_remote_ui_container (control, NULL);
- bonobo_ui_component_set_container (uic, remote_uih, NULL);
- bonobo_object_release_unref (remote_uih, NULL);
-
- e_memos_set_ui_component (memos, uic);
-
- bonobo_ui_component_add_verb_list_with_data (uic, verbs, memos);
-
- bonobo_ui_component_freeze (uic, NULL);
-
- xmlfile = g_build_filename (EVOLUTION_UIDIR,
- "evolution-memos.xml",
- NULL);
- bonobo_ui_util_set_ui (uic, PREFIX,
- xmlfile,
- "evolution-memos",
- NULL);
- g_free (xmlfile);
-
- e_pixmaps_update (uic, pixmaps);
-
- e_memos_setup_view_menus (memos, uic);
-
- /* Signals from the memos widget; also sensitize the menu items as appropriate */
-
- g_signal_connect (memos, "selection_changed", G_CALLBACK (selection_changed_cb), control);
-
- cal_table = e_memos_get_calendar_table (memos);
- etable = e_memo_table_get_table (cal_table);
- n_selected = e_table_selected_count (etable);
-
- memos_control_sensitize_commands (control, memos, n_selected);
-
- bonobo_ui_component_thaw (uic, NULL);
-}
-
-void
-memos_control_deactivate (BonoboControl *control, EMemos *memos)
-{
- BonoboUIComponent *uic = bonobo_control_get_ui_component (control);
-
- g_return_if_fail (uic != NULL);
-
- e_memos_set_ui_component (memos, NULL);
-
- e_memos_discard_view_menus (memos);
-
- /* Stop monitoring the "selection_changed" signal */
- g_signal_handlers_disconnect_matched (memos, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, control);
-
- bonobo_ui_component_rm (uic, "/", NULL);
- bonobo_ui_component_unset_container (uic, NULL);
-}
-
-static void memos_control_open_memo_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- EMemos *memos;
-
- memos = E_MEMOS (data);
- e_memos_open_memo (memos);
-}
-
-static void
-memos_control_new_memo_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- EMemos *memos;
-
- memos = E_MEMOS (data);
- e_memos_new_memo (memos);
-}
-
-static void
-memos_control_cut_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- EMemos *memos;
- EMemoTable *cal_table;
-
- memos = E_MEMOS (data);
- cal_table = e_memos_get_calendar_table (memos);
- e_memo_table_cut_clipboard (cal_table);
-}
-
-static void
-memos_control_copy_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- EMemos *memos;
- EMemoTable *cal_table;
- GtkWidget *preview;
-
- memos = E_MEMOS (data);
-
- preview = e_cal_component_memo_preview_get_html (E_CAL_COMPONENT_MEMO_PREVIEW (e_memos_get_preview (memos)));
- if (preview && GTK_WIDGET_VISIBLE (preview) && GTK_WIDGET_HAS_FOCUS (preview)) {
- /* copy selected text in a preview when that's shown and focused */
- gtk_html_copy (GTK_HTML (preview));
- } else {
- cal_table = e_memos_get_calendar_table (memos);
- e_memo_table_copy_clipboard (cal_table);
- }
-}
-
-static void
-memos_control_paste_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- EMemos *memos;
- EMemoTable *cal_table;
-
- memos = E_MEMOS (data);
- cal_table = e_memos_get_calendar_table (memos);
- e_memo_table_paste_clipboard (cal_table);
-}
-
-static void
-memos_control_delete_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- EMemos *memos;
-
- memos = E_MEMOS (data);
- e_memos_delete_selected (memos);
-}
-
-/* File/Print callback */
-static void
-memos_control_print_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- EMemos *memos = E_MEMOS (data);
- ETable *table;
-
- table = e_memo_table_get_table (
- E_MEMO_TABLE (e_memos_get_calendar_table (memos)));
-
- print_table (
- table, _("Print Memos"), _("Memos"),
- GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-}
-
-static void
-memos_control_print_preview_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- EMemos *memos = E_MEMOS (data);
- ETable *table;
-
- table = e_memo_table_get_table (
- E_MEMO_TABLE (e_memos_get_calendar_table (memos)));
-
- print_table (
- table, _("Print Memos"), _("Memos"),
- GTK_PRINT_OPERATION_ACTION_PREVIEW);
-}
diff --git a/calendar/gui/memos-control.h b/calendar/gui/memos-control.h
deleted file mode 100644
index 854f5f9d9b..0000000000
--- a/calendar/gui/memos-control.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena Quintero <federico@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- * Nathan Owens <pianocomp81@yahoo.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _MEMOS_CONTROL_H_
-#define _MEMOS_CONTROL_H_
-
-#include "e-memos.h"
-
-BonoboControl *memos_control_new (void);
-void memos_control_activate (BonoboControl *control, EMemos *memos);
-void memos_control_deactivate (BonoboControl *control, EMemos *memos);
-void memos_control_sensitize_commands (BonoboControl *control, EMemos *memos, gint n_selected);
-
-#endif /* _MEMOS_CONTROL_H_ */
diff --git a/calendar/gui/migration.h b/calendar/gui/migration.h
deleted file mode 100644
index 78bc501599..0000000000
--- a/calendar/gui/migration.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef MIGRATION_H
-#define MIGRATION_H
-
-#include <libedataserver/e-source-group.h>
-#include "calendar-component.h"
-#include "tasks-component.h"
-#include "memos-component.h"
-
-gboolean migrate_calendars (CalendarComponent *component, gint major, gint minor, gint revision, GError **err);
-gboolean migrate_tasks (TasksComponent *component, gint major, gint minor, gint revision, GError **err);
-gboolean migrate_memos (MemosComponent *component, gint major, gint minor, gint revision, GError **err);
-#endif
diff --git a/calendar/gui/print.c b/calendar/gui/print.c
index 48be727e40..e6563cd846 100644
--- a/calendar/gui/print.c
+++ b/calendar/gui/print.c
@@ -43,7 +43,6 @@
#include <e-util/e-print.h>
#include <libecal/e-cal-time-util.h>
#include <libecal/e-cal-component.h>
-#include "calendar-commands.h"
#include "calendar-config.h"
#include "e-cal-model.h"
#include "e-day-view.h"
@@ -677,7 +676,7 @@ print_month_small (GtkPrintContext *context, GnomeCalendar *gcal, time_t month,
sprintf (buf, "%d", day);
/* this is a slow messy way to do this ... but easy ... */
- e_cal_model_generate_instances (gnome_calendar_get_calendar_model (gcal), now,
+ e_cal_model_generate_instances (gnome_calendar_get_model (gcal), now,
time_day_end_with_zone (now, zone),
instance_cb, &found);
@@ -1248,7 +1247,7 @@ print_day_details (GtkPrintContext *context, GnomeCalendar *gcal, time_t whence,
double font_size, max_font_size;
cairo_t *cr;
- ECalModel *model = gnome_calendar_get_calendar_model (gcal);
+ ECalModel *model = gnome_calendar_get_model (gcal);
start = time_day_begin_with_zone (whence, zone);
end = time_day_end_with_zone (start, zone);
@@ -1734,7 +1733,7 @@ print_week_summary (GtkPrintContext *context, GnomeCalendar *gcal,
GArray *spans;
PangoFontDescription *font;
double cell_width, cell_height;
- ECalModel *model = gnome_calendar_get_calendar_model (gcal);
+ ECalModel *model = gnome_calendar_get_model (gcal);
psi.days_shown = weeks_shown * 7;
psi.events = g_array_new (FALSE, FALSE, sizeof (EWeekViewEvent));
@@ -1947,6 +1946,7 @@ print_todo_details (GtkPrintContext *context, GnomeCalendar *gcal,
time_t start, time_t end,
double left, double right, double top, double bottom)
{
+#if 0 /* KILL-BONOBO */
PangoFontDescription *font_summary;
double y, yend, x, xend;
struct icaltimetype *tt;
@@ -2035,6 +2035,7 @@ print_todo_details (GtkPrintContext *context, GnomeCalendar *gcal,
}
pango_font_description_free (font_summary);
+#endif
}
static void
@@ -2389,7 +2390,8 @@ print_calendar_draw_page (GtkPrintOperation *operation,
}
void
-print_calendar (GnomeCalendar *gcal, GtkPrintOperationAction action,
+print_calendar (GnomeCalendar *gcal,
+ GtkPrintOperationAction action,
time_t start)
{
GtkPrintOperation *operation;
@@ -2398,6 +2400,34 @@ print_calendar (GnomeCalendar *gcal, GtkPrintOperationAction action,
g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
+ if (gnome_calendar_get_view (gcal) == GNOME_CAL_MONTH_VIEW) {
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ EWeekView *week_view;
+
+ view_type = gnome_calendar_get_view (gcal);
+ calendar_view = gnome_calendar_get_calendar_view (gcal, view_type);
+ week_view = E_WEEK_VIEW (calendar_view);
+
+ if (week_view && week_view->multi_week_view &&
+ week_view->weeks_shown >= 4 &&
+ g_date_valid (&week_view->first_day_shown)) {
+
+ GDate date = week_view->first_day_shown;
+ struct icaltimetype start_tt;
+
+ g_date_add_days (&date, 7);
+
+ start_tt = icaltime_null_time ();
+ start_tt.is_date = TRUE;
+ start_tt.year = g_date_get_year (&date);
+ start_tt.month = g_date_get_month (&date);
+ start_tt.day = g_date_get_day (&date);
+
+ start = icaltime_as_timet (start_tt);
+ }
+ }
+
pcali.gcal = (GnomeCalendar *)gcal;
pcali.start = start;
diff --git a/calendar/gui/print.h b/calendar/gui/print.h
index 39482b33f2..39d5608222 100644
--- a/calendar/gui/print.h
+++ b/calendar/gui/print.h
@@ -25,9 +25,7 @@
#ifndef PRINT_H
#define PRINT_H
-#include "gnome-cal.h"
-
-
+#include "calendar/gui/gnome-cal.h"
typedef enum {
PRINT_VIEW_DAY,
diff --git a/calendar/gui/tasks-component.c b/calendar/gui/tasks-component.c
deleted file mode 100644
index f7934742d2..0000000000
--- a/calendar/gui/tasks-component.c
+++ /dev/null
@@ -1,1293 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-#include <glib/gi18n-lib.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-exception.h>
-#include <gconf/gconf-client.h>
-#include <libecal/e-cal.h>
-#include <libedataserver/e-data-server-util.h>
-#include <libedataserver/e-url.h>
-#include <libedataserverui/e-source-selector.h>
-#include <shell/e-user-creatable-items-handler.h>
-#include <shell/e-component-view.h>
-#include "e-cal-model.h"
-#include "e-tasks.h"
-#include "tasks-component.h"
-#include "tasks-control.h"
-#include "e-comp-editor-registry.h"
-#include "migration.h"
-#include "comp-util.h"
-#include "calendar-config.h"
-#include "e-cal-popup.h"
-#include "common/authentication.h"
-#include "dialogs/calendar-setup.h"
-#include "dialogs/comp-editor.h"
-#include "dialogs/copy-source-dialog.h"
-#include "dialogs/task-editor.h"
-#include "misc/e-info-label.h"
-#include "e-util/e-error.h"
-
-#define CREATE_TASK_ID "task"
-#define CREATE_TASK_ASSIGNED_ID "task-assigned"
-#define CREATE_TASK_LIST_ID "task-list"
-
-enum DndTargetType {
- DND_TARGET_TYPE_CALENDAR_LIST
-};
-#define CALENDAR_TYPE "text/calendar"
-#define XCALENDAR_TYPE "text/x-calendar"
-#define WEB_BASE_URI "webcal://"
-#define PERSONAL_RELATIVE_URI "system"
-
-static GtkTargetEntry drag_types[] = {
- { (gchar *) CALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST },
- { (gchar *) XCALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST }
-};
-static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
-
-#define PARENT_TYPE bonobo_object_get_type ()
-
-static BonoboObjectClass *parent_class = NULL;
-
-/* Tasks should have their own registry */
-extern ECompEditorRegistry *comp_editor_registry;
-
-typedef struct
-{
- ESourceList *source_list;
-
- GSList *source_selection;
-
- ETasks *tasks;
- ETable *table;
- ETableModel *model;
-
- EInfoLabel *info_label;
- GtkWidget *source_selector;
-
- BonoboControl *view_control;
- BonoboControl *sidebar_control;
- BonoboControl *statusbar_control;
-
- GList *notifications;
-
- EUserCreatableItemsHandler *creatable_items_handler;
-
- EActivityHandler *activity_handler;
-} TasksComponentView;
-
-struct _TasksComponentPrivate {
- gchar *base_directory;
- gchar *config_directory;
-
- ESourceList *source_list;
- GSList *source_selection;
-
- GList *views;
-
- ECal *create_ecal;
-
- GList *notifications;
-};
-
-static void
-ensure_sources (TasksComponent *component)
-{
- ESourceList *source_list;
- ESourceGroup *on_this_computer;
- ESource *personal_source;
- gchar *base_uri, *base_uri_proto, base_uri_proto_seventh;
- const gchar *base_dir;
-
- personal_source = NULL;
-
- if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_TODO, NULL)) {
- g_warning ("Could not get task source list from GConf!");
- return;
- }
-
- base_dir = tasks_component_peek_base_directory (component);
- base_uri = g_build_filename (base_dir, "local", NULL);
-
- base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
- if (strlen (base_uri_proto) > 7) {
- /* compare only file:// part. If user home dir name changes we do not want to create
- one more group */
- base_uri_proto_seventh = base_uri_proto[7];
- base_uri_proto[7] = 0;
- } else {
- base_uri_proto_seventh = -1;
- }
-
- on_this_computer = e_source_list_ensure_group (source_list, _("On This Computer"), base_uri_proto, TRUE);
- e_source_list_ensure_group (source_list, _("On The Web"), WEB_BASE_URI, FALSE);
-
- if (base_uri_proto_seventh != -1) {
- base_uri_proto[7] = base_uri_proto_seventh;
- }
-
- if (on_this_computer) {
- /* make sure "Personal" shows up as a source under
- this group */
- GSList *sources = e_source_group_peek_sources (on_this_computer);
- GSList *s;
- for (s = sources; s; s = s->next) {
- ESource *source = E_SOURCE (s->data);
- const gchar *relative_uri;
-
- relative_uri = e_source_peek_relative_uri (source);
- if (relative_uri == NULL)
- continue;
- if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
- personal_source = source;
- break;
- }
- }
- /* Make sure we have the correct base uri. This can change when user's
- homedir name changes */
- if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) {
- e_source_group_set_base_uri (on_this_computer, base_uri_proto);
-
- /* *sigh* . We shouldn't need this sync call here as set_base_uri
- call results in synching to gconf, but that happens in idle loop
- and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/
- e_source_list_sync (source_list,NULL);
- }
- }
-
- if (personal_source) {
- /* ensure the source name is in current locale, not read from configuration */
- e_source_set_name (personal_source, _("Personal"));
- } else {
- GSList *tasks_selected;
- /* Create the default Person addressbook */
- ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
- e_source_group_add_source (on_this_computer, source, -1);
- g_object_unref (source);
-
- tasks_selected = calendar_config_get_tasks_selected ();
-
- if (!calendar_config_get_primary_tasks () && !tasks_selected) {
- GSList selected;
-
- calendar_config_set_primary_tasks (e_source_peek_uid (source));
-
- selected.data = (gpointer)e_source_peek_uid (source);
- selected.next = NULL;
- calendar_config_set_tasks_selected (&selected);
- }
-
- if (tasks_selected) {
- g_slist_foreach (tasks_selected, (GFunc) g_free, NULL);
- g_slist_free (tasks_selected);
- }
-
- e_source_set_color_spec (source, "#BECEDD");
- personal_source = source;
- }
-
- component->priv->source_list = source_list;
-
- g_object_unref (on_this_computer);
- g_free (base_uri_proto);
- g_free (base_uri);
-}
-
-/* Utility functions. */
-/* FIXME Some of these are duplicated from calendar-component.c */
-static gboolean
-is_in_selection (GSList *selection, ESource *source)
-{
- GSList *l;
-
- for (l = selection; l; l = l->next) {
- ESource *selected_source = l->data;
-
- if (!strcmp (e_source_peek_uid (selected_source), e_source_peek_uid (source)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-is_in_uids (GSList *uids, ESource *source)
-{
- GSList *l;
-
- for (l = uids; l; l = l->next) {
- const gchar *uid = l->data;
-
- if (!strcmp (uid, e_source_peek_uid (source)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-update_uris_for_selection (TasksComponentView *component_view)
-{
- GSList *selection, *l, *uids_selected = NULL;
-
- selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
-
- for (l = component_view->source_selection; l; l = l->next) {
- ESource *old_selected_source = l->data;
-
- if (!is_in_selection (selection, old_selected_source))
- e_tasks_remove_todo_source (component_view->tasks, old_selected_source);
- }
-
- for (l = selection; l; l = l->next) {
- ESource *selected_source = l->data;
-
- e_tasks_add_todo_source (component_view->tasks, selected_source);
- uids_selected = g_slist_append (uids_selected, (gchar *)e_source_peek_uid (selected_source));
- }
-
- e_source_selector_free_selection (component_view->source_selection);
- component_view->source_selection = selection;
-
- /* Save the selection for next time we start up */
- calendar_config_set_tasks_selected (uids_selected);
- g_slist_free (uids_selected);
-}
-
-static void
-update_uri_for_primary_selection (TasksComponentView *component_view)
-{
- ESource *source;
- ECalendarTable *cal_table;
- ETable *etable;
-
- source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!source)
- return;
-
- /* Set the default */
- e_tasks_set_default_source (component_view->tasks, source);
-
- cal_table = e_tasks_get_calendar_table (component_view->tasks);
- etable = e_calendar_table_get_table (cal_table);
-
- tasks_control_sensitize_commands (component_view->view_control, component_view->tasks, e_table_selected_count (etable));
-
- /* Save the selection for next time we start up */
- calendar_config_set_primary_tasks (e_source_peek_uid (source));
-}
-
-static void
-update_selection (TasksComponentView *component_view)
-{
- GSList *selection, *uids_selected, *l;
-
- /* Get the selection in gconf */
- uids_selected = calendar_config_get_tasks_selected ();
-
- /* Remove any that aren't there any more */
- selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
-
- for (l = selection; l; l = l->next) {
- ESource *source = l->data;
-
- if (!is_in_uids (uids_selected, source))
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
- }
-
- e_source_selector_free_selection (selection);
-
- /* Make sure the whole selection is there */
- for (l = uids_selected; l; l = l->next) {
- gchar *uid = l->data;
- ESource *source;
-
- source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
- if (source)
- e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
-
- g_free (uid);
- }
- g_slist_free (uids_selected);
-}
-
-static void
-update_primary_selection (TasksComponentView *component_view)
-{
- ESource *source = NULL;
- gchar *uid;
-
- uid = calendar_config_get_primary_tasks ();
- if (uid) {
- source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
- g_free (uid);
- }
-
- if (source) {
- e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source);
- } else {
- /* Try to create a default if there isn't one */
- source = e_source_list_peek_source_any (component_view->source_list);
- if (source)
- e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source);
- }
-}
-
-/* Callbacks. */
-static void
-copy_task_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- TasksComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source, E_CAL_SOURCE_TYPE_TODO);
-}
-
-static void
-delete_task_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- TasksComponentView *component_view = data;
- ESource *selected_source;
- ECal *cal;
- gchar *uri;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- if (e_error_run((GtkWindow *)gtk_widget_get_toplevel(ep->target->widget),
- "calendar:prompt-delete-task-list", e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES)
- return;
-
- /* first, ask the backend to remove the task list */
- uri = e_source_get_uri (selected_source);
- cal = e_cal_model_get_client_for_uri (
- e_calendar_table_get_model (E_CALENDAR_TABLE (e_tasks_get_calendar_table (component_view->tasks))),
- uri);
- if (!cal)
- cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_TODO);
- g_free (uri);
- if (cal) {
- if (e_cal_remove (cal, NULL)) {
- if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source)) {
- e_tasks_remove_todo_source (component_view->tasks, selected_source);
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source);
- }
-
- e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
- e_source_list_sync (component_view->source_list, NULL);
- }
- }
-}
-
-static void
-new_task_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- calendar_setup_new_task_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)));
-}
-
-static void
-rename_task_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- TasksComponentView *component_view = data;
- ESourceSelector *selector;
-
- selector = E_SOURCE_SELECTOR (component_view->source_selector);
- e_source_selector_edit_primary_selection (selector);
-}
-
-static void
-edit_task_list_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- TasksComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- calendar_setup_edit_task_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source);
-}
-
-static void
-set_offline_availability (EPopup *ep, EPopupItem *pitem, gpointer data, const gchar *value)
-{
- TasksComponentView *component_view = data;
- ESource *selected_source;
-
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- if (!selected_source)
- return;
-
- e_source_set_property (selected_source, "offline_sync", value);
-}
-
-static void
-mark_no_offline_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- set_offline_availability (ep, pitem, data, "0");
-}
-
-static void
-mark_offline_cb (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- set_offline_availability (ep, pitem, data, "1");
-}
-
-static EPopupItem etc_source_popups[] = {
- { E_POPUP_ITEM, (gchar *) "10.new", (gchar *) N_("_New Task List"), new_task_list_cb, NULL, (gchar *) "stock_todo", 0, 0 },
- { E_POPUP_ITEM, (gchar *) "15.copy", (gchar *) N_("_Copy..."), copy_task_list_cb, NULL, (gchar *) "edit-copy", 0, E_CAL_POPUP_SOURCE_PRIMARY },
- { E_POPUP_ITEM, (gchar *) "18.rename", (gchar *) N_("_Rename..."), rename_task_list_cb, NULL, NULL, 0, E_CAL_POPUP_SOURCE_PRIMARY },
-
- { E_POPUP_BAR, (gchar *) "20.bar" },
- { E_POPUP_ITEM, (gchar *) "20.delete", (gchar *) N_("_Delete"), delete_task_list_cb, NULL, (gchar *) "edit-delete", 0, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY },
- { E_POPUP_ITEM, (gchar *) "30.mark_tasks_offline", (gchar *) N_("_Make available for offline use"), mark_offline_cb, NULL, (gchar *) "stock_disconnect", E_CAL_POPUP_SOURCE_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_OFFLINE },
- { E_POPUP_ITEM, (gchar *) "40.mark_tasks_no_offline", (gchar *) N_("_Do not make available for offline use"), mark_no_offline_cb, NULL, (gchar *) "stock_connect", E_CAL_POPUP_SOURCE_NO_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_NO_OFFLINE },
-
- { E_POPUP_BAR, (gchar *) "99.bar" },
- { E_POPUP_ITEM, (gchar *) "99.properties", (gchar *) N_("_Properties"), edit_task_list_cb, NULL, (gchar *) "document-properties", 0, E_CAL_POPUP_SOURCE_PRIMARY },
-};
-
-static void
-etc_source_popup_free(EPopup *ep, GSList *list, gpointer data)
-{
- g_slist_free(list);
-}
-
-static gboolean
-popup_event_cb(ESourceSelector *selector, ESource *insource, GdkEventButton *event, TasksComponentView *component_view)
-{
- ECalPopup *ep;
- ECalPopupTargetSource *t;
- GSList *menus = NULL;
- gint i;
- GtkMenu *menu;
-
- /** @HookPoint-ECalPopup: Tasks Source Selector Context Menu
- * @Id: org.gnome.evolution.tasks.source.popup
- * @Class: org.gnome.evolution.calendar.popup:1.0
- * @Target: ECalPopupTargetSource
- *
- * The context menu on the source selector in the tasks window.
- */
- ep = e_cal_popup_new("org.gnome.evolution.tasks.source.popup");
- t = e_cal_popup_target_new_source(ep, selector);
- t->target.widget = (GtkWidget *)component_view->tasks;
-
- for (i=0;i<sizeof(etc_source_popups)/sizeof(etc_source_popups[0]);i++)
- menus = g_slist_prepend(menus, &etc_source_popups[i]);
-
- e_popup_add_items((EPopup *)ep, menus, NULL,etc_source_popup_free, component_view);
-
- menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time());
-
- return TRUE;
-}
-
-static void
-source_selection_changed_cb (ESourceSelector *selector, TasksComponentView *component_view)
-{
- update_uris_for_selection (component_view);
-}
-
-static void
-primary_source_selection_changed_cb (ESourceSelector *selector, TasksComponentView *component_view)
-{
- update_uri_for_primary_selection (component_view);
-}
-
-static void
-source_added_cb (ETasks *tasks, ESource *source, TasksComponentView *component_view)
-{
- e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
-}
-
-static void
-source_removed_cb (ETasks *tasks, ESource *source, TasksComponentView *component_view)
-{
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
-}
-
-static void
-set_info (TasksComponentView *component_view)
-{
- GString *message = g_string_new (NULL);
- gint rows, selected_rows;
-
- rows = e_table_model_row_count (component_view->model);
- selected_rows = e_table_selected_count (component_view->table);
-
- g_string_append_printf(message, ngettext("%d task", "%d tasks", rows), rows);
- if (selected_rows > 0)
- g_string_append_printf(message, ngettext(", %d selected", ", %d selected", selected_rows), selected_rows);
-
- e_info_label_set_info (component_view->info_label, _("Tasks"), message->str);
-
- g_string_free (message, TRUE);
-}
-
-static void
-table_selection_change_cb (ETableModel *etm, TasksComponentView *component_view)
-{
- set_info (component_view);
-}
-
-static void
-model_changed_cb (ETableModel *etm, TasksComponentView *component_view)
-{
- set_info (component_view);
-}
-
-static void
-model_rows_inserted_cb (ETableModel *etm, gint row, gint count, TasksComponentView *component_view)
-{
- set_info (component_view);
-}
-
-static void
-model_rows_deleted_cb (ETableModel *etm, gint row, gint count, TasksComponentView *component_view)
-{
- set_info (component_view);
-}
-
-/* Evolution::Component CORBA methods */
-
-static void
-impl_upgradeFromVersion (PortableServer_Servant servant,
- CORBA_short major,
- CORBA_short minor,
- CORBA_short revision,
- CORBA_Environment *ev)
-{
- GError *err = NULL;
- TasksComponent *component = TASKS_COMPONENT (bonobo_object_from_servant (servant));
-
- if (!migrate_tasks(component, major, minor, revision, &err)) {
- GNOME_Evolution_Component_UpgradeFailed *failedex;
-
- failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
- failedex->what = CORBA_string_dup(_("Failed upgrading tasks."));
- failedex->why = CORBA_string_dup(err->message);
- CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
- }
-
- if (err)
- g_error_free(err);
-}
-
-static gboolean
-selector_tree_data_dropped (ESourceSelector *selector,
- GtkSelectionData *data,
- ESource *destination,
- GdkDragAction action,
- guint info,
- TasksComponent *component)
-{
- gboolean success = FALSE;
- icalcomponent *icalcomp = NULL;
- ECal *client = NULL;
- GSList *components, *p;
-
- client = auth_new_cal_from_source (
- destination, E_CAL_SOURCE_TYPE_TODO);
-
- if (!client || !e_cal_open (client, TRUE, NULL))
- goto finish;
-
- components = cal_comp_selection_get_string_list (data);
- success = components != NULL;
- for (p = components; p && success; p = p->next) {
- gchar *comp_str; /* do not free this! */
-
- /* p->data is "source_uid\ncomponent_string" */
- comp_str = strchr (p->data, '\n');
- if (!comp_str)
- continue;
-
- comp_str [0] = 0;
- comp_str++;
- icalcomp = icalparser_parse_string (comp_str);
-
- if (!icalcomp)
- continue;
-
- success = cal_comp_process_source_list_drop (client, icalcomp, action, p->data, component->priv->source_list);
- icalcomponent_free (icalcomp);
- }
- g_slist_foreach (components, (GFunc)g_free, NULL);
- g_slist_free (components);
-
- finish:
- if (client)
- g_object_unref (client);
-
- return success;
-}
-
-static void
-control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
-{
- TasksComponentView *component_view = data;
-
- if (activate) {
- BonoboUIComponent *uic;
- uic = bonobo_control_get_ui_component (component_view->view_control);
-
- e_user_creatable_items_handler_activate (component_view->creatable_items_handler, uic);
- }
-}
-
-static void
-config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- TasksComponent *component = data;
- TasksComponentPrivate *priv;
-
- priv = component->priv;
-
- g_object_unref (priv->create_ecal);
- priv->create_ecal = NULL;
-
- priv->notifications = g_list_remove (priv->notifications, GUINT_TO_POINTER (id));
-}
-
-static ECal *
-setup_create_ecal (TasksComponent *component, TasksComponentView *component_view)
-{
- TasksComponentPrivate *priv;
- ESource *source = NULL;
- gchar *uid;
- guint not;
-
- priv = component->priv;
-
- if (component_view) {
- ECal *default_ecal;
-
- default_ecal = e_tasks_get_default_client (component_view->tasks);
- if (default_ecal)
- return default_ecal;
- }
-
- if (priv->create_ecal)
- return priv->create_ecal;
-
- /* Get the current primary calendar, or try to set one if it doesn't already exist */
- uid = calendar_config_get_primary_tasks ();
- if (uid) {
- source = e_source_list_peek_source_by_uid (priv->source_list, uid);
- g_free (uid);
-
- priv->create_ecal = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
- }
-
- if (!priv->create_ecal) {
- /* Try to create a default if there isn't one */
- source = e_source_list_peek_source_any (priv->source_list);
- if (source)
- priv->create_ecal = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
- }
-
- if (priv->create_ecal) {
- icaltimezone *zone;
-
- zone = calendar_config_get_icaltimezone ();
- e_cal_set_default_timezone (priv->create_ecal, zone, NULL);
-
- if (!e_cal_open (priv->create_ecal, FALSE, NULL)) {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
- _("Unable to open the task list '%s' for creating events and meetings"),
- e_source_peek_name (source));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- return NULL;
- }
-
- } else {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
- "%s", _("There is no calendar available for creating tasks"));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- return NULL;
- }
-
- /* Handle the fact it may change on us */
- not = calendar_config_add_notification_primary_tasks (config_create_ecal_changed_cb,
- component);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
- /* Save the primary source for use elsewhere */
- calendar_config_set_primary_tasks (e_source_peek_uid (source));
-
- return priv->create_ecal;
-}
-
-/* Ensures the calendar is selected */
-static void
-object_created_cb (CompEditor *ce, ECalendarTable *cal_table)
-{
- g_return_if_fail (cal_table != NULL);
-
- cal_table->user_created_cal = comp_editor_get_client (ce);
- g_signal_emit_by_name (cal_table, "user_created");
- cal_table->user_created_cal = NULL;
-}
-
-static gboolean
-create_new_todo (TasksComponent *task_component, gboolean is_assigned, TasksComponentView *component_view)
-{
- ECal *ecal;
- ECalComponent *comp;
- CompEditor *editor;
- guint32 flags = 0;
-
- ecal = setup_create_ecal (task_component, component_view);
- if (!ecal)
- return FALSE;
-
- if (is_assigned)
- flags |= COMP_EDITOR_IS_ASSIGNED;
-
- flags |= COMP_EDITOR_NEW_ITEM | COMP_EDITOR_USER_ORG;
-
- editor = task_editor_new (ecal, flags);
- comp = cal_comp_task_new_with_defaults (ecal);
-
- if (component_view)
- g_signal_connect (editor, "object_created", G_CALLBACK (object_created_cb), e_tasks_get_calendar_table (component_view->tasks));
-
- comp_editor_edit_comp (editor, comp);
- if (is_assigned)
- task_editor_show_assignment (TASK_EDITOR (editor));
- gtk_window_present (GTK_WINDOW (editor));
-
- e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
-
- return TRUE;
-}
-
-static void
-create_local_item_cb (EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data)
-{
- TasksComponent *tasks_component = data;
- TasksComponentPrivate *priv;
- TasksComponentView *component_view = NULL;
- GList *l;
-
- priv = tasks_component->priv;
-
- for (l = priv->views; l; l = l->next) {
- component_view = l->data;
-
- if (component_view->creatable_items_handler == handler)
- break;
-
- component_view = NULL;
- }
-
- if (strcmp (item_type_name, CREATE_TASK_ID) == 0) {
- create_new_todo (tasks_component, FALSE, component_view);
- } else if (strcmp (item_type_name, CREATE_TASK_ASSIGNED_ID) == 0) {
- create_new_todo (tasks_component, TRUE, component_view);
- } else if (strcmp (item_type_name, CREATE_TASK_LIST_ID) == 0) {
- calendar_setup_new_task_list (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->tasks))));
- }
-}
-
-static TasksComponentView *
-create_component_view (TasksComponent *tasks_component)
-{
- TasksComponentPrivate *priv;
- TasksComponentView *component_view;
- GtkWidget *selector_scrolled_window, *vbox;
- GtkWidget *statusbar_widget;
- AtkObject *a11y;
-
- priv = tasks_component->priv;
-
- /* Create the calendar component view */
- component_view = g_new0 (TasksComponentView, 1);
-
- /* Add the source lists */
- component_view->source_list = g_object_ref (priv->source_list);
-
- /* Create sidebar selector */
- component_view->source_selector = e_source_selector_new (tasks_component->priv->source_list);
- e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE);
- a11y = gtk_widget_get_accessible (GTK_WIDGET (component_view->source_selector));
- atk_object_set_name (a11y, _("Task Source Selector"));
-
- g_signal_connect (
- component_view->source_selector, "data-dropped",
- G_CALLBACK (selector_tree_data_dropped), tasks_component);
-
- gtk_drag_dest_set(component_view->source_selector, GTK_DEST_DEFAULT_ALL, drag_types,
- num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
- gtk_widget_show (component_view->source_selector);
-
- selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_container_add (GTK_CONTAINER (selector_scrolled_window), component_view->source_selector);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window),
- GTK_SHADOW_IN);
- gtk_widget_show (selector_scrolled_window);
-
- component_view->info_label = (EInfoLabel *)e_info_label_new("evolution-tasks");
- e_info_label_set_info(component_view->info_label, _("Tasks"), "");
- gtk_widget_show (GTK_WIDGET (component_view->info_label));
-
- vbox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX (vbox), GTK_WIDGET (component_view->info_label), FALSE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX (vbox), selector_scrolled_window, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- component_view->sidebar_control = bonobo_control_new (vbox);
-
- /* Create main view */
- component_view->view_control = tasks_control_new ();
- if (!component_view->view_control) {
- /* FIXME free memory */
-
- return NULL;
- }
-
- component_view->tasks = (ETasks *) bonobo_control_get_widget (component_view->view_control);
- component_view->table = e_calendar_table_get_table (e_tasks_get_calendar_table (component_view->tasks));
- component_view->model = E_TABLE_MODEL (e_calendar_table_get_model (e_tasks_get_calendar_table (component_view->tasks)));
-
- /* This signal is thrown if backends die - we update the selector */
- g_signal_connect (component_view->tasks, "source_added",
- G_CALLBACK (source_added_cb), component_view);
- g_signal_connect (component_view->tasks, "source_removed",
- G_CALLBACK (source_removed_cb), component_view);
-
- /* Create status bar */
- statusbar_widget = e_task_bar_new ();
- component_view->activity_handler = e_activity_handler_new ();
- e_activity_handler_attach_task_bar (component_view->activity_handler, E_TASK_BAR (statusbar_widget));
- gtk_widget_show (statusbar_widget);
-
- component_view->statusbar_control = bonobo_control_new (statusbar_widget);
-
- e_calendar_table_set_activity_handler (e_tasks_get_calendar_table (component_view->tasks), component_view->activity_handler);
-
- /* connect after setting the initial selections, or we'll get unwanted calls
- to calendar_control_sensitize_calendar_commands */
- g_signal_connect (component_view->source_selector, "selection_changed",
- G_CALLBACK (source_selection_changed_cb), component_view);
- g_signal_connect (component_view->source_selector, "primary_selection_changed",
- G_CALLBACK (primary_source_selection_changed_cb), component_view);
- g_signal_connect (component_view->source_selector, "popup_event",
- G_CALLBACK (popup_event_cb), component_view);
-
- /* Set up the "new" item handler */
- component_view->creatable_items_handler = e_user_creatable_items_handler_new ("tasks", create_local_item_cb, tasks_component);
- g_signal_connect (component_view->view_control, "activate", G_CALLBACK (control_activate_cb), component_view);
-
- /* We use this to update the component information */
- set_info (component_view);
- g_signal_connect (component_view->table, "selection_change",
- G_CALLBACK (table_selection_change_cb), component_view);
- g_signal_connect (component_view->model, "model_changed",
- G_CALLBACK (model_changed_cb), component_view);
- g_signal_connect (component_view->model, "model_rows_inserted",
- G_CALLBACK (model_rows_inserted_cb), component_view);
- g_signal_connect (component_view->model, "model_rows_deleted",
- G_CALLBACK (model_rows_deleted_cb), component_view);
-
- /* Load the selection from the last run */
- update_selection (component_view);
- update_primary_selection (component_view);
-
- return component_view;
-}
-
-static void
-destroy_component_view (TasksComponentView *component_view)
-{
- GList *l;
-
- g_signal_handlers_disconnect_matched (component_view->model, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, component_view);
-
- if (component_view->source_list)
- g_object_unref (component_view->source_list);
-
- if (component_view->source_selection)
- e_source_selector_free_selection (component_view->source_selection);
-
- for (l = component_view->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
- g_list_free (component_view->notifications);
-
- if (component_view->creatable_items_handler)
- g_object_unref (component_view->creatable_items_handler);
-
- if (component_view->activity_handler)
- g_object_unref (component_view->activity_handler);
-
- g_free (component_view);
-}
-
-static void
-view_destroyed_cb (gpointer data, GObject *where_the_object_was)
-{
- TasksComponent *tasks_component = data;
- TasksComponentPrivate *priv;
- GList *l;
-
- priv = tasks_component->priv;
-
- for (l = priv->views; l; l = l->next) {
- TasksComponentView *component_view = l->data;
-
- if (G_OBJECT (component_view->view_control) == where_the_object_was) {
- priv->views = g_list_remove (priv->views, component_view);
- destroy_component_view (component_view);
-
- break;
- }
- }
-}
-
-static GNOME_Evolution_ComponentView
-impl_createView (PortableServer_Servant servant,
- GNOME_Evolution_ShellView parent,
- CORBA_boolean select_item,
- CORBA_Environment *ev)
-{
- TasksComponent *component = TASKS_COMPONENT (bonobo_object_from_servant (servant));
- TasksComponentPrivate *priv;
- TasksComponentView *component_view;
- EComponentView *ecv;
-
- priv = component->priv;
-
- /* Create the calendar component view */
- component_view = create_component_view (component);
- if (!component_view) {
- /* FIXME Should we describe the problem in a control? */
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
-
- return CORBA_OBJECT_NIL;
- }
-
- g_object_weak_ref (G_OBJECT (component_view->view_control), view_destroyed_cb, component);
- priv->views = g_list_append (priv->views, component_view);
-
- /* TODO: Make TasksComponentView just subclass EComponentView */
- ecv = e_component_view_new_controls (parent, "tasks", component_view->sidebar_control,
- component_view->view_control, component_view->statusbar_control);
-
- return BONOBO_OBJREF(ecv);
-}
-
-static void
-impl_handleURI (PortableServer_Servant servant, const gchar *uri, CORBA_Environment *ev)
-{
- TasksComponent *tasks_component = TASKS_COMPONENT (bonobo_object_from_servant (servant));
- TasksComponentPrivate *priv;
- GList *l;
- TasksComponentView *view = NULL;
-
- gchar *src_uid = NULL;
- gchar *uid = NULL;
- gchar *rid = NULL;
-
- priv = tasks_component->priv;
-
- l = g_list_last (priv->views);
- if (!l)
- return;
-
- view = l->data;
-
- if (!strncmp (uri, "task:", 5)) {
- EUri *euri = e_uri_new (uri);
- const gchar *p;
- gchar *header, *content;
- gsize len, clen;
-
- p = euri->query;
- if (p) {
- while (*p) {
- len = strcspn (p, "=&");
-
- /* If it's malformed, give up. */
- if (p[len] != '=')
- break;
-
- header = (gchar *) p;
- header[len] = '\0';
- p += len + 1;
-
- clen = strcspn (p, "&");
-
- content = g_strndup (p, clen);
- if (!g_ascii_strcasecmp (header, "source-uid")) {
- src_uid = g_strdup (content);
- } else if (!g_ascii_strcasecmp (header, "comp-uid")) {
- uid = g_strdup (content);
- } else if (!g_ascii_strcasecmp (header, "comp-rid")) {
- rid = g_strdup (content);
- }
- g_free (content);
-
- p += clen;
- if (*p == '&') {
- p++;
- if (!strcmp (p, "amp;"))
- p += 4;
- }
- }
-
- if (uid && src_uid) {
- e_tasks_open_task_id (view->tasks, src_uid, uid, rid);
- }
-
- g_free (src_uid);
- g_free (uid);
- g_free (rid);
- }
- e_uri_free (euri);
- }
-
- return;
-}
-
-static GNOME_Evolution_CreatableItemTypeList *
-impl__get_userCreatableItems (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
-
- list->_length = 3;
- list->_maximum = list->_length;
- list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
-
- CORBA_sequence_set_release (list, FALSE);
-
- list->_buffer[0].id = (gchar *) CREATE_TASK_ID;
- list->_buffer[0].description = (gchar *) _("New task");
- list->_buffer[0].menuDescription = (gchar *) C_("New", "_Task");
- list->_buffer[0].tooltip = (gchar *) _("Create a new task");
- list->_buffer[0].menuShortcut = 't';
- list->_buffer[0].iconName = (gchar *) "stock_task";
- list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[1].id = (gchar *) CREATE_TASK_ASSIGNED_ID;
- list->_buffer[1].description = (gchar *) _("New assigned task");
- list->_buffer[1].menuDescription = (gchar *) C_("New", "Assigne_d Task");
- list->_buffer[1].tooltip = (gchar *) _("Create a new assigned task");
- list->_buffer[1].menuShortcut = '\0';
- list->_buffer[1].iconName = (gchar *) "stock_task";
- list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[2].id = (gchar *) CREATE_TASK_LIST_ID;
- list->_buffer[2].description = (gchar *) _("New task list");
- list->_buffer[2].menuDescription = (gchar *) C_("New", "Tas_k list");
- list->_buffer[2].tooltip = (gchar *) _("Create a new task list");
- list->_buffer[2].menuShortcut = '\0';
- list->_buffer[2].iconName = (gchar *) "stock_todo";
- list->_buffer[2].type = GNOME_Evolution_CREATABLE_FOLDER;
-
- return list;
-}
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
- const CORBA_char *item_type_name,
- CORBA_Environment *ev)
-{
- TasksComponent *tasks_component = TASKS_COMPONENT (bonobo_object_from_servant (servant));
-
- if (strcmp (item_type_name, CREATE_TASK_ID) == 0) {
- if (!create_new_todo (tasks_component, FALSE, NULL))
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
- } else if (strcmp (item_type_name, CREATE_TASK_ASSIGNED_ID) == 0) {
- if (!create_new_todo (tasks_component, TRUE, NULL))
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
- } else if (strcmp (item_type_name, CREATE_TASK_LIST_ID) == 0) {
- /* FIXME Should we use the last opened window? */
- calendar_setup_new_task_list (NULL);
- } else {
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType);
- }
-}
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- TasksComponent *tasks_component = TASKS_COMPONENT (object);
- TasksComponentPrivate *priv = tasks_component->priv;
- GList *l;
-
- if (priv->source_list != NULL) {
- g_object_unref (priv->source_list);
- priv->source_list = NULL;
- }
- if (priv->source_selection != NULL) {
- e_source_selector_free_selection (priv->source_selection);
- priv->source_selection = NULL;
- }
-
- if (priv->create_ecal) {
- g_object_unref (priv->create_ecal);
- priv->create_ecal = NULL;
- }
-
- for (l = priv->views; l; l = l->next) {
- TasksComponentView *component_view = l->data;
-
- g_object_weak_unref (G_OBJECT (component_view->view_control), view_destroyed_cb, tasks_component);
- }
- g_list_free (priv->views);
- priv->views = NULL;
-
- for (l = priv->notifications; l; l = l->next)
- calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
- g_list_free (priv->notifications);
- priv->notifications = NULL;
-
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- TasksComponentPrivate *priv = TASKS_COMPONENT (object)->priv;
- GList *l;
-
- for (l = priv->views; l; l = l->next) {
- TasksComponentView *component_view = l->data;
-
- destroy_component_view (component_view);
- }
- g_list_free (priv->views);
-
- g_free (priv->base_directory);
- g_free (priv->config_directory);
- g_free (priv);
-
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-static void
-tasks_component_class_init (TasksComponentClass *klass)
-{
- POA_GNOME_Evolution_Component__epv *epv = &klass->epv;
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- parent_class = g_type_class_peek_parent (klass);
-
- epv->upgradeFromVersion = impl_upgradeFromVersion;
- epv->createView = impl_createView;
- epv->_get_userCreatableItems = impl__get_userCreatableItems;
- epv->requestCreateItem = impl_requestCreateItem;
- epv->handleURI = impl_handleURI;
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-}
-
-static void
-tasks_component_init (TasksComponent *component, TasksComponentClass *klass)
-{
- TasksComponentPrivate *priv;
-
- priv = g_new0 (TasksComponentPrivate, 1);
-
- priv->base_directory = g_build_filename (e_get_user_data_dir (), "tasks", NULL);
- priv->config_directory = g_build_filename (priv->base_directory, "config", NULL);
-
- component->priv = priv;
- ensure_sources (component);
-}
-
-/* Public API */
-
-TasksComponent *
-tasks_component_peek (void)
-{
- static TasksComponent *component = NULL;
-
- if (component == NULL) {
- component = g_object_new (tasks_component_get_type (), NULL);
-
- if (g_mkdir_with_parents (component->priv->config_directory, 0777) != 0) {
- g_warning (G_STRLOC ": Cannot create directory %s: %s",
- component->priv->config_directory, g_strerror (errno));
- g_object_unref (component);
- component = NULL;
- }
- }
-
- return component;
-}
-
-const gchar *
-tasks_component_peek_base_directory (TasksComponent *component)
-{
- return component->priv->base_directory;
-}
-
-const gchar *
-tasks_component_peek_config_directory (TasksComponent *component)
-{
- return component->priv->config_directory;
-}
-
-ESourceList *
-tasks_component_peek_source_list (TasksComponent *component)
-{
- return component->priv->source_list;
-}
-
-BONOBO_TYPE_FUNC_FULL (TasksComponent, GNOME_Evolution_Component, PARENT_TYPE, tasks_component)
diff --git a/calendar/gui/tasks-component.h b/calendar/gui/tasks-component.h
deleted file mode 100644
index 9824797640..0000000000
--- a/calendar/gui/tasks-component.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _TASKS_COMPONENT_H_
-#define _TASKS_COMPONENT_H_
-
-#include <bonobo/bonobo-object.h>
-#include <libedataserver/e-source-list.h>
-#include <misc/e-activity-handler.h>
-#include "Evolution.h"
-
-#define TASKS_TYPE_COMPONENT (tasks_component_get_type ())
-#define TASKS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TASKS_TYPE_COMPONENT, TasksComponent))
-#define TASKS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TASKS_TYPE_COMPONENT, TasksComponentClass))
-#define TASKS_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TASKS_TYPE_COMPONENT))
-#define TASKS_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TASKS_TYPE_COMPONENT))
-
-typedef struct _TasksComponent TasksComponent;
-typedef struct _TasksComponentPrivate TasksComponentPrivate;
-typedef struct _TasksComponentClass TasksComponentClass;
-
-struct _TasksComponent {
- BonoboObject parent;
-
- TasksComponentPrivate *priv;
-};
-
-struct _TasksComponentClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Component__epv epv;
-};
-
-GType tasks_component_get_type (void);
-TasksComponent *tasks_component_peek (void);
-
-const gchar *tasks_component_peek_base_directory (TasksComponent *component);
-const gchar *tasks_component_peek_config_directory (TasksComponent *component);
-ESourceList *tasks_component_peek_source_list (TasksComponent *component);
-
-#endif /* _TASKS_COMPONENT_H_ */
diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c
deleted file mode 100644
index 41de092681..0000000000
--- a/calendar/gui/tasks-control.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Damon Chaplin <damon@ximian.com>
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <e-util/e-dialog-utils.h>
-#include <e-util/e-icon-factory.h>
-#include <e-util/e-print.h>
-#include <e-util/e-util-private.h>
-#include "dialogs/cal-prefs-dialog.h"
-#include "calendar-config.h"
-#include "calendar-commands.h"
-#include "e-tasks.h"
-#include "e-calendar-table.h"
-#include "print.h"
-#include "tasks-control.h"
-#include "evolution-shell-component-utils.h"
-#include "e-util/e-menu.h"
-#include "e-cal-menu.h"
-#include "e-cal-component-preview.h"
-#include "e-util/e-menu.h"
-#include "itip-utils.h"
-
-#define FIXED_MARGIN .05
-
-static void tasks_control_activate_cb (BonoboControl *control,
- gboolean activate,
- gpointer user_data);
-static void tasks_control_open_task_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_new_task_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_cut_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_copy_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_paste_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_delete_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_complete_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_purge_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_print_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_print_preview_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-static void tasks_control_assign_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-
-static void tasks_control_forward_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path);
-
-static void tasks_control_view_preview (BonoboUIComponent *uic,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- gpointer data);
-
-struct focus_changed_data {
- BonoboControl *control;
- ETasks *tasks;
-};
-
-static gboolean tasks_control_focus_changed (GtkWidget *widget, GdkEventFocus *event, struct focus_changed_data *fc_data);
-
-BonoboControl *
-tasks_control_new (void)
-{
- BonoboControl *control;
- GtkWidget *tasks, *preview;
- struct focus_changed_data *fc_data;
-
- tasks = e_tasks_new ();
- if (!tasks)
- return NULL;
- gtk_widget_show (tasks);
-
- control = bonobo_control_new (tasks);
- if (!control) {
- gtk_widget_destroy (tasks);
- g_message ("control_factory_fn(): could not create the control!");
- return NULL;
- }
-
- g_signal_connect (control, "activate", G_CALLBACK (tasks_control_activate_cb), tasks);
-
- fc_data = g_new0 (struct focus_changed_data, 1);
- fc_data->control = control;
- fc_data->tasks = E_TASKS (tasks);
-
- preview = e_cal_component_preview_get_html (E_CAL_COMPONENT_PREVIEW (e_tasks_get_preview (fc_data->tasks)));
- g_object_set_data_full (G_OBJECT (preview), "tasks-ctrl-fc-data", fc_data, g_free);
- g_signal_connect (preview, "focus-in-event", G_CALLBACK (tasks_control_focus_changed), fc_data);
- g_signal_connect (preview, "focus-out-event", G_CALLBACK (tasks_control_focus_changed), fc_data);
-
- return control;
-}
-
-static void
-tasks_control_activate_cb (BonoboControl *control,
- gboolean activate,
- gpointer user_data)
-{
- ETasks *tasks;
-
- tasks = E_TASKS (user_data);
-
- if (activate)
- tasks_control_activate (control, tasks);
- else
- tasks_control_deactivate (control, tasks);
-}
-
-struct _tasks_sensitize_item {
- const gchar *command;
- guint32 enable;
-};
-
-static void
-sensitize_items(BonoboUIComponent *uic, struct _tasks_sensitize_item *items, guint32 mask)
-{
- while (items->command) {
- gchar command[32];
-
- if (strlen(items->command)>=21) {
- g_warning ("Size more than 21: %s\n", items->command);
- continue;
- }
-
- sprintf(command, "/commands/%s", items->command);
-
- bonobo_ui_component_set_prop (uic, command, "sensitive",
- (items->enable & mask) == 0 ? "1" : "0",
- NULL);
- items++;
- }
-}
-
-#define E_CAL_TASKS_PREVIEW_ACTIVE (1<<31)
-
-static struct _tasks_sensitize_item tasks_sensitize_table[] = {
- { "TasksOpenTask", E_CAL_MENU_SELECT_ONE },
- { "TasksCut", E_CAL_MENU_SELECT_ANY | E_CAL_MENU_SELECT_EDITABLE | E_CAL_TASKS_PREVIEW_ACTIVE },
- { "TasksCopy", E_CAL_MENU_SELECT_ANY },
- { "TasksPaste", E_CAL_MENU_SELECT_EDITABLE | E_CAL_TASKS_PREVIEW_ACTIVE },
- { "TasksDelete", E_CAL_MENU_SELECT_ANY | E_CAL_MENU_SELECT_EDITABLE },
- { "TasksMarkComplete", E_CAL_MENU_SELECT_ANY | E_CAL_MENU_SELECT_EDITABLE | E_CAL_MENU_SELECT_NOTCOMPLETE},
- { "TasksPurge", E_CAL_MENU_SELECT_EDITABLE },
- { "TasksAssign", E_CAL_MENU_SELECT_ONE | E_CAL_MENU_SELECT_EDITABLE | E_CAL_MENU_SELECT_ASSIGNABLE },
- { "TasksForward", E_CAL_MENU_SELECT_ONE },
- { NULL }
-};
-
-/* Sensitizes the UI Component menu/toolbar commands based on the number of
- * selected tasks.
- */
-void
-tasks_control_sensitize_commands (BonoboControl *control, ETasks *tasks, gint n_selected)
-{
- BonoboUIComponent *uic;
- gboolean read_only = TRUE;
- ECal *ecal;
- ECalModel *model;
- ECalMenu *menu;
- ECalMenuTargetSelect *t;
- GPtrArray *events;
- GSList *selected = NULL, *l = NULL;
- ECalendarTable *cal_table;
- GtkWidget *preview;
-
- uic = bonobo_control_get_ui_component (control);
- g_return_if_fail (uic != NULL);
-
- if (bonobo_ui_component_get_container (uic) == CORBA_OBJECT_NIL)
- return;
-
- menu = e_tasks_get_tasks_menu (tasks);
- cal_table = e_tasks_get_calendar_table (tasks);
- model = e_calendar_table_get_model (cal_table);
- events = g_ptr_array_new ();
- selected = e_calendar_table_get_selected (cal_table);
-
- for (l = selected;l;l = g_slist_next (l)) {
- g_ptr_array_add (events, e_cal_model_copy_component_data ((ECalModelComponent *)l->data));
- }
-
- g_slist_free (selected);
-
- t = e_cal_menu_target_new_select (menu, model, events);
-
- ecal = e_cal_model_get_default_client (model);
-
- if (ecal)
- e_cal_is_read_only (ecal, &read_only, NULL);
-
- preview = e_cal_component_preview_get_html (E_CAL_COMPONENT_PREVIEW (e_tasks_get_preview (tasks)));
- if (preview && GTK_WIDGET_VISIBLE (preview) && GTK_WIDGET_HAS_FOCUS (preview))
- t->target.mask = t->target.mask | E_CAL_TASKS_PREVIEW_ACTIVE;
- else
- t->target.mask = t->target.mask & (~E_CAL_TASKS_PREVIEW_ACTIVE);
-
- sensitize_items (uic, tasks_sensitize_table, t->target.mask);
- e_menu_update_target ((EMenu *)menu, (EMenuTarget *)t);
-}
-
-/* Callback used when the selection in the table changes */
-static void
-selection_changed_cb (ETasks *tasks, gint n_selected, gpointer data)
-{
- BonoboControl *control;
-
- control = BONOBO_CONTROL (data);
-
- tasks_control_sensitize_commands (control, tasks, n_selected);
-}
-
-static gboolean
-tasks_control_focus_changed (GtkWidget *widget, GdkEventFocus *event, struct focus_changed_data *fc_data)
-{
- g_return_val_if_fail (fc_data != NULL, FALSE);
-
- tasks_control_sensitize_commands (fc_data->control, fc_data->tasks, -1);
-
- return FALSE;
-}
-
-static BonoboUIVerb verbs [] = {
- BONOBO_UI_VERB ("TasksOpenTask", tasks_control_open_task_cmd),
- BONOBO_UI_VERB ("TasksNewTask", tasks_control_new_task_cmd),
- BONOBO_UI_VERB ("TasksCut", tasks_control_cut_cmd),
- BONOBO_UI_VERB ("TasksCopy", tasks_control_copy_cmd),
- BONOBO_UI_VERB ("TasksPaste", tasks_control_paste_cmd),
- BONOBO_UI_VERB ("TasksDelete", tasks_control_delete_cmd),
- BONOBO_UI_VERB ("TasksMarkComplete", tasks_control_complete_cmd),
- BONOBO_UI_VERB ("TasksPurge", tasks_control_purge_cmd),
- BONOBO_UI_VERB ("TasksPrint", tasks_control_print_cmd),
- BONOBO_UI_VERB ("TasksPrintPreview", tasks_control_print_preview_cmd),
- BONOBO_UI_VERB ("TasksAssign", tasks_control_assign_cmd),
- BONOBO_UI_VERB ("TasksForward", tasks_control_forward_cmd),
- BONOBO_UI_VERB_END
-};
-
-static EPixmap pixmaps [] = {
- E_PIXMAP ("/commands/TasksCopy", "edit-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TasksCut", "edit-cut", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TasksDelete", "edit-delete", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TasksForward", "mail-forward", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TasksPaste", "edit-paste", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TasksPrint", "document-print", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TasksPrintPreview", "document-print-preview", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP ("/Toolbar/Cut", "edit-cut", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Copy", "edit-copy", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Paste", "edit-paste", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Print", "document-print", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/Delete", "edit-delete", GTK_ICON_SIZE_LARGE_TOOLBAR),
-
- E_PIXMAP_END
-};
-void
-tasks_control_activate (BonoboControl *control, ETasks *tasks)
-{
- Bonobo_UIContainer remote_uih;
- BonoboUIComponent *uic;
- gint n_selected;
- ECalendarTable *cal_table;
- ETable *etable;
- gboolean state;
- gchar *xmlfile;
-
- uic = bonobo_control_get_ui_component (control);
- g_return_if_fail (uic != NULL);
-
- remote_uih = bonobo_control_get_remote_ui_container (control, NULL);
- bonobo_ui_component_set_container (uic, remote_uih, NULL);
- bonobo_object_release_unref (remote_uih, NULL);
-
- e_tasks_set_ui_component (tasks, uic);
-
- bonobo_ui_component_add_verb_list_with_data (uic, verbs, tasks);
-
- bonobo_ui_component_freeze (uic, NULL);
-
- xmlfile = g_build_filename (EVOLUTION_UIDIR,
- "evolution-tasks.xml",
- NULL);
- bonobo_ui_util_set_ui (uic, PREFIX,
- xmlfile,
- "evolution-tasks",
- NULL);
- g_free (xmlfile);
-
- e_pixmaps_update (uic, pixmaps);
-
- e_tasks_setup_view_menus (tasks, uic);
-
- /* Signals from the tasks widget; also sensitize the menu items as appropriate */
-
- g_signal_connect (tasks, "selection_changed", G_CALLBACK (selection_changed_cb), control);
-
- e_menu_activate ((EMenu *)e_tasks_get_tasks_menu (tasks), uic, 1);
- cal_table = e_tasks_get_calendar_table (tasks);
- etable = e_calendar_table_get_table (cal_table);
- n_selected = e_table_selected_count (etable);
-
- tasks_control_sensitize_commands (control, tasks, n_selected);
-
- state = calendar_config_get_preview_state();
-
- bonobo_ui_component_thaw (uic, NULL);
-
- bonobo_ui_component_add_listener(uic, "ViewPreview", tasks_control_view_preview, tasks);
- bonobo_ui_component_set_prop(uic, "/commands/ViewPreview", "state", state?"1":"0", NULL);
-}
-
-void
-tasks_control_deactivate (BonoboControl *control, ETasks *tasks)
-{
- BonoboUIComponent *uic = bonobo_control_get_ui_component (control);
-
- g_return_if_fail (uic != NULL);
-
- e_menu_activate ((EMenu *)e_tasks_get_tasks_menu (tasks), uic, 0);
- e_tasks_set_ui_component (tasks, NULL);
-
- e_tasks_discard_view_menus (tasks);
-
- /* Stop monitoring the "selection_changed" signal */
- g_signal_handlers_disconnect_matched (tasks, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, control);
-
- bonobo_ui_component_rm (uic, "/", NULL);
- bonobo_ui_component_unset_container (uic, NULL);
-}
-
-static void tasks_control_open_task_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
-
- tasks = E_TASKS (data);
- e_tasks_open_task (tasks);
-}
-
-static void
-tasks_control_new_task_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
-
- tasks = E_TASKS (data);
- e_tasks_new_task (tasks);
-}
-
-static void
-tasks_control_cut_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
- ECalendarTable *cal_table;
-
- tasks = E_TASKS (data);
- cal_table = e_tasks_get_calendar_table (tasks);
- e_calendar_table_cut_clipboard (cal_table);
-}
-
-static void
-tasks_control_copy_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
- ECalendarTable *cal_table;
- GtkWidget *preview;
-
- tasks = E_TASKS (data);
-
- preview = e_cal_component_preview_get_html (E_CAL_COMPONENT_PREVIEW (e_tasks_get_preview (tasks)));
- if (preview && GTK_WIDGET_VISIBLE (preview) && GTK_WIDGET_HAS_FOCUS (preview)) {
- /* copy selected text in a preview when that's shown and focused */
- gtk_html_copy (GTK_HTML (preview));
- } else {
- cal_table = e_tasks_get_calendar_table (tasks);
- e_calendar_table_copy_clipboard (cal_table);
- }
-}
-
-static void
-tasks_control_paste_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
- ECalendarTable *cal_table;
-
- tasks = E_TASKS (data);
- cal_table = e_tasks_get_calendar_table (tasks);
- e_calendar_table_paste_clipboard (cal_table);
-}
-
-static void
-tasks_control_delete_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
-
- tasks = E_TASKS (data);
- e_tasks_delete_selected (tasks);
-}
-
-static void
-tasks_control_complete_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
-
- bonobo_ui_component_set_prop (uic, "/commands/TasksMarkComplete", "sensitive",
- "0",
- NULL);
- tasks = E_TASKS (data);
- e_tasks_complete_selected (tasks);
-}
-
-static gboolean
-confirm_purge (ETasks *tasks)
-{
- GtkWidget *dialog, *checkbox, *parent;
- gint button;
-
- if (!calendar_config_get_confirm_purge ())
- return TRUE;
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (tasks));
- dialog = gtk_message_dialog_new (
- (GtkWindow *)parent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_YES_NO,
- "%s",
- _("This operation will permanently erase all tasks marked as completed. If you continue, you will not be able to recover these tasks.\n\nReally erase these tasks?"));
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO);
-
- checkbox = gtk_check_button_new_with_label (_("Do not ask me again."));
- gtk_widget_show (checkbox);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), checkbox, TRUE, TRUE, 6);
-
- button = gtk_dialog_run (GTK_DIALOG (dialog));
- if (button == GTK_RESPONSE_YES && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)))
- calendar_config_set_confirm_purge (FALSE);
- gtk_widget_destroy (dialog);
-
- return button == GTK_RESPONSE_YES ? TRUE : FALSE;
-}
-
-static void
-tasks_control_purge_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
-
- tasks = E_TASKS (data);
- if (confirm_purge (tasks))
- e_tasks_delete_completed (tasks);
-}
-
-/* File/Print callback */
-static void
-tasks_control_print_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks = E_TASKS (data);
- ETable *table;
-
- table = e_calendar_table_get_table (
- E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks)));
-
- print_table (
- table, _("Print Tasks"), _("Tasks"),
- GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-}
-
-static void
-tasks_control_print_preview_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks = E_TASKS (data);
- ETable *table;
-
- table = e_calendar_table_get_table (
- E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks)));
-
- print_table (
- table, _("Print Tasks"), _("Tasks"),
- GTK_PRINT_OPERATION_ACTION_PREVIEW);
-}
-
-static void
-tasks_control_assign_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
- ECalendarTable *cal_table;
- ECalModelComponent *comp_data;
-
- tasks = E_TASKS (data);
- cal_table = e_tasks_get_calendar_table (tasks);
- comp_data = e_calendar_table_get_selected_comp (cal_table);
- if (comp_data)
- e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, TRUE);
-}
-
-static void
-tasks_control_forward_cmd (BonoboUIComponent *uic,
- gpointer data,
- const gchar *path)
-{
- ETasks *tasks;
- ECalendarTable *cal_table;
- ECalModelComponent *comp_data;
-
- tasks = E_TASKS (data);
- cal_table = e_tasks_get_calendar_table (tasks);
- comp_data = e_calendar_table_get_selected_comp (cal_table);
- if (comp_data) {
- ECalComponent *comp;
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
- g_object_unref (comp);
- }
-}
-
-static void
-tasks_control_view_preview (BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- ETasks *tasks;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- tasks = E_TASKS (data);
-
- calendar_config_set_preview_state (state[0] != '0');
- e_tasks_show_preview (tasks, state[0] != '0');
-}
diff --git a/calendar/gui/tasks-control.h b/calendar/gui/tasks-control.h
deleted file mode 100644
index de98914e40..0000000000
--- a/calendar/gui/tasks-control.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Federico Mena Quintero <federico@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _TASKS_CONTROL_H_
-#define _TASKS_CONTROL_H_
-
-#include "e-tasks.h"
-
-BonoboControl *tasks_control_new (void);
-void tasks_control_activate (BonoboControl *control, ETasks *tasks);
-void tasks_control_deactivate (BonoboControl *control, ETasks *tasks);
-void tasks_control_sensitize_commands (BonoboControl *control, ETasks *tasks, gint n_selected);
-
-#endif /* _TASKS_CONTROL_H_ */
diff --git a/calendar/importers/main.c b/calendar/importers/main.c
deleted file mode 100644
index cfb4e0c0bd..0000000000
--- a/calendar/importers/main.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Evolution calendar importer component
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <string.h>
-#include <bonobo/bonobo-shlib-factory.h>
-#include <bonobo/bonobo-context.h>
-#include <bonobo/bonobo-main.h>
-#include "evolution-calendar-importer.h"
-
-#define IMPORTER_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ImporterFactory:" BASE_VERSION
-#define ICALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Calendar_iCalendar_Importer:" BASE_VERSION
-#define VCALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Calendar_vCalendar_Importer:" BASE_VERSION
-#define GNOME_CALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Gnome_Calendar_Intelligent_Importer:" BASE_VERSION
-
-static BonoboObject *
-importer_factory_fn (BonoboGenericFactory *factory, const gchar *id, gpointer closure)
-{
- BonoboObject *object = NULL;
-
- g_return_val_if_fail (id != NULL, NULL);
-
- if (!strcmp (id, ICALENDAR_IMPORTER_ID))
- object = ical_importer_new ();
- else if (!strcmp (id, VCALENDAR_IMPORTER_ID))
- object = vcal_importer_new ();
- else if (!strcmp (id, GNOME_CALENDAR_IMPORTER_ID))
- object = gnome_calendar_importer_new ();
- else
- g_warning ("Component not supported by this factory");
-
- return object;
-}
-
-BONOBO_ACTIVATION_SHLIB_FACTORY (IMPORTER_FACTORY_ID, "Evolution Calendar importer factory", importer_factory_fn, NULL)
diff --git a/composer/Makefile.am b/composer/Makefile.am
index 97af16bec5..e20f3f007e 100644
--- a/composer/Makefile.am
+++ b/composer/Makefile.am
@@ -38,8 +38,6 @@ AM_CPPFLAGS = \
$(EVOLUTION_MAIL_CFLAGS)
libcomposer_la_SOURCES = \
- $(IDL_GENERATED) \
- $(HTML_EDITOR_GENERATED) \
$(libcomposerinclude_HEADERS) \
e-composer-actions.c \
e-composer-autosave.c \
@@ -52,6 +50,9 @@ libcomposer_la_SOURCES = \
e-composer-text-header.c \
e-msg-composer.c
+libcomposer_la_LIBADD = \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/em-format/libemformat.la
uidir = $(evolutionuidir)
ui_DATA = evolution-composer.ui
@@ -61,7 +62,7 @@ EXTRA_DIST = \
mail-composer.error.xml \
ChangeLog.pre-1-4
-BUILT_SOURCES = $(IDL_GENERATED) $(HTML_EDITOR_GENERATED) $(error_DATA)
+BUILT_SOURCES = $(error_DATA)
CLEANFILES = $(BUILT_SOURCES)
dist-hook:
diff --git a/composer/e-composer-actions.c b/composer/e-composer-actions.c
index 3b40d270f0..bceeb1a9f5 100644
--- a/composer/e-composer-actions.c
+++ b/composer/e-composer-actions.c
@@ -21,11 +21,6 @@
#include <errno.h>
#include <fcntl.h>
#include <e-util/e-error.h>
-#include <mail/em-event.h>
-#include <mail/em-format-html-print.h>
-#include <mail/em-composer-utils.h>
-
-#include "misc/e-charset-picker.h"
static void
action_attach_cb (GtkAction *action,
@@ -50,7 +45,7 @@ action_charset_cb (GtkRadioAction *action,
if (action != current)
return;
- charset = gtk_action_get_name (GTK_ACTION (current));
+ charset = g_object_get_data (G_OBJECT (action), "charset");
g_free (composer->priv->charset);
composer->priv->charset = g_strdup (charset);
@@ -128,15 +123,9 @@ action_print_cb (GtkAction *action,
EMsgComposer *composer)
{
GtkPrintOperationAction print_action;
- CamelMimeMessage *message;
- EMFormatHTMLPrint *efhp;
print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
- message = e_msg_composer_get_message (composer, 1);
-
- efhp = em_format_html_print_new (NULL, print_action);
- em_format_html_print_raw_message (efhp, message);
- g_object_unref (efhp);
+ e_msg_composer_print (composer, print_action);
}
static void
@@ -144,15 +133,9 @@ action_print_preview_cb (GtkAction *action,
EMsgComposer *composer)
{
GtkPrintOperationAction print_action;
- CamelMimeMessage *message;
- EMFormatHTMLPrint *efhp;
print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
- message = e_msg_composer_get_message_print (composer, 1);
-
- efhp = em_format_html_print_new (NULL, print_action);
- em_format_html_print_raw_message (efhp, message);
- g_object_unref (efhp);
+ e_msg_composer_print (composer, print_action);
}
static void
@@ -263,6 +246,8 @@ static void
action_send_options_cb (GtkAction *action,
EMsgComposer *composer)
{
+ /* FIXME: KILL-BONOBO - should this be here when -no-undefined removed? */
+ /*
EMEvent *event = em_event_peek ();
EMEventTargetComposer *target;
@@ -274,6 +259,7 @@ action_send_options_cb (GtkAction *action,
(EEvent *) event,
"composer.selectsendoption",
(EEventTarget *) target);
+ */
if (!composer->priv->send_invoked)
e_error_run (
@@ -283,9 +269,12 @@ action_send_options_cb (GtkAction *action,
static void
action_new_message_cb (GtkAction *action,
- EMsgComposer *composer)
+ EMsgComposer *composer)
{
- em_utils_compose_new_message (NULL);
+ EMsgComposer *new_composer;
+
+ new_composer = e_msg_composer_new ();
+ gtk_widget_show (GTK_WIDGET (new_composer));
}
static void
@@ -508,7 +497,7 @@ e_composer_actions_init (EMsgComposer *composer)
gtk_action_group_set_translation_domain (
action_group, GETTEXT_PACKAGE);
e_charset_add_radio_actions (
- action_group, composer->priv->charset,
+ action_group, "charset-", composer->priv->charset,
G_CALLBACK (action_charset_cb), composer);
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
diff --git a/composer/e-composer-from-header.c b/composer/e-composer-from-header.c
index 320768c79c..cade5bfed3 100644
--- a/composer/e-composer-from-header.c
+++ b/composer/e-composer-from-header.c
@@ -111,11 +111,13 @@ e_composer_from_header_new (const gchar *label)
}
EComposerHeader *
-e_composer_from_header_new_with_action (const gchar *label, const gchar *action)
+e_composer_from_header_new_with_action (const gchar *label,
+ const gchar *action)
{
return g_object_new (
E_TYPE_COMPOSER_FROM_HEADER, "label", label,
- "button", FALSE, "addaction_text", action, "addaction", action!= NULL, NULL);
+ "button", FALSE, "addaction_text", action,
+ "addaction", action != NULL, NULL);
}
EAccountList *
diff --git a/composer/e-composer-from-header.h b/composer/e-composer-from-header.h
index 3fbf5a7012..9f9a0e0f82 100644
--- a/composer/e-composer-from-header.h
+++ b/composer/e-composer-from-header.h
@@ -63,7 +63,9 @@ struct _EComposerFromHeaderClass {
GType e_composer_from_header_get_type (void);
EComposerHeader * e_composer_from_header_new (const gchar *label);
-EComposerHeader * e_composer_from_header_new_with_action (const gchar *label, const gchar *action);
+EComposerHeader * e_composer_from_header_new_with_action
+ (const gchar *label,
+ const gchar *action);
EAccountList * e_composer_from_header_get_account_list
(EComposerFromHeader *header);
void e_composer_from_header_set_account_list
diff --git a/composer/e-composer-header-table.c b/composer/e-composer-header-table.c
index 232e902e4a..30e3d5778f 100644
--- a/composer/e-composer-header-table.c
+++ b/composer/e-composer-header-table.c
@@ -160,11 +160,11 @@ composer_header_table_notify_header (EComposerHeader *header,
{
GtkWidget *parent;
- if (composer_lite && strcmp (property_name, "destinations-to") == 0) {
- parent = g_object_get_data((GObject *)header->input_widget, "parent");
- } else {
+ if (composer_lite && strcmp (property_name, "destinations-to") == 0)
+ parent = g_object_get_data (
+ G_OBJECT (header->input_widget), "parent");
+ else
parent = gtk_widget_get_parent (header->input_widget);
- }
g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (parent));
g_object_notify (G_OBJECT (parent), property_name);
}
@@ -177,7 +177,7 @@ composer_header_table_notify_widget (GtkWidget *widget,
if (composer_lite) {
parent = gtk_widget_get_parent (widget);
- parent = g_object_get_data ((GObject *)parent, "pdata");
+ parent = g_object_get_data (G_OBJECT (parent), "pdata");
} else
parent = gtk_widget_get_parent (widget);
g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (parent));
@@ -534,7 +534,6 @@ composer_header_table_constructor (GType type,
if (composer_lite)
gtk_widget_show_all ((GtkWidget *)priv->actions_container);
-
ii = E_COMPOSER_HEADER_FROM;
/* Leave room in the "From" row for signature stuff. */
@@ -559,11 +558,16 @@ composer_header_table_constructor (GType type,
gtk_table_attach (
GTK_TABLE (object), priv->signature_combo_box,
3, 4, ii, ii + 1, composer_lite ? GTK_FILL: 0, 0, 0, 3);
- } else {
+ } else {
GtkWidget *box = gtk_hbox_new (FALSE, 0);
- gtk_box_pack_start ((GtkBox *)box, priv->signature_label, FALSE, FALSE, 4);
- gtk_box_pack_end ((GtkBox *)box, priv->signature_combo_box, TRUE, TRUE, 0);
- g_object_set_data ((GObject *)box, "pdata", object);
+
+ gtk_box_pack_start (
+ GTK_BOX (box), priv->signature_label,
+ FALSE, FALSE, 4);
+ gtk_box_pack_end (
+ GTK_BOX (box), priv->signature_combo_box,
+ TRUE, TRUE, 0);
+ g_object_set_data (G_OBJECT (box), "pdata", object);
gtk_table_attach (
GTK_TABLE (object), box,
3, 4, ii, ii + 1, GTK_FILL, 0, 0, 3);
@@ -962,13 +966,13 @@ composer_header_table_init (EComposerHeaderTable *table)
table->priv->headers[E_COMPOSER_HEADER_TO] = header;
header = e_composer_name_header_new_with_action (
- _("_Cc:"), _("CC"), name_selector);
+ _("_Cc:"), _("Show CC"), name_selector);
e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_CC);
composer_header_table_bind_header ("destinations-cc", "changed", header);
table->priv->headers[E_COMPOSER_HEADER_CC] = header;
header = e_composer_name_header_new_with_action (
- _("_Bcc:"), _("BCC"), name_selector);
+ _("_Bcc:"), _("Show BCC"), name_selector);
e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_BCC);
composer_header_table_bind_header ("destinations-bcc", "changed", header);
table->priv->headers[E_COMPOSER_HEADER_BCC] = header;
@@ -1050,28 +1054,6 @@ e_composer_header_table_get_header (EComposerHeaderTable *table,
return table->priv->headers[type];
}
-void
-e_composer_header_table_set_header_visible (EComposerHeaderTable *table,
- EComposerHeaderType type,
- gboolean visible)
-{
- EComposerHeader *header;
-
- header = e_composer_header_table_get_header (table, type);
- e_composer_header_set_visible (header, visible);
-
- /* Signature widgets track the "From" header. */
- if (type == E_COMPOSER_HEADER_FROM) {
- if (visible) {
- gtk_widget_show (table->priv->signature_label);
- gtk_widget_show (table->priv->signature_combo_box);
- } else {
- gtk_widget_hide (table->priv->signature_label);
- gtk_widget_hide (table->priv->signature_combo_box);
- }
- }
-}
-
EAccount *
e_composer_header_table_get_account (EComposerHeaderTable *table)
{
diff --git a/composer/e-composer-header-table.h b/composer/e-composer-header-table.h
index 146868a864..91ad56da46 100644
--- a/composer/e-composer-header-table.h
+++ b/composer/e-composer-header-table.h
@@ -149,10 +149,7 @@ const gchar * e_composer_header_table_get_subject
void e_composer_header_table_set_subject
(EComposerHeaderTable *table,
const gchar *subject);
-void e_composer_header_table_set_header_visible
- (EComposerHeaderTable *table,
- EComposerHeaderType type,
- gboolean visible);
+
G_END_DECLS
#endif /* E_COMPOSER_HEADER_TABLE_H */
diff --git a/composer/e-composer-header.c b/composer/e-composer-header.c
index 334464eddd..36d0ffb3b6 100644
--- a/composer/e-composer-header.c
+++ b/composer/e-composer-header.c
@@ -21,7 +21,7 @@
*/
#include "e-composer-header.h"
-#include <glib/gi18n.h>
+
#define E_COMPOSER_HEADER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_COMPOSER_HEADER, EComposerHeaderPrivate))
@@ -111,19 +111,9 @@ composer_header_constructor (GType type,
box = gtk_hbox_new (FALSE, 0);
tmp = gtk_image_new_from_stock("gtk-add", GTK_ICON_SIZE_BUTTON);
gtk_box_pack_start((GtkBox *)box, tmp, FALSE, FALSE, 3);
- g_object_set_data ((GObject *)header->priv->action_label, "add", tmp);
- tmp = gtk_image_new_from_stock("gtk-remove", GTK_ICON_SIZE_BUTTON);
- gtk_box_pack_start((GtkBox *)box, tmp, FALSE, FALSE, 3);
- g_object_set_data ((GObject *)header->priv->action_label, "remove", tmp);
- gtk_widget_hide (tmp);
- tmp = header->priv->action_label;
- str = g_strdup_printf ("<span>%s %s</span>", _("Show"), header->priv->addaction_text);
- g_object_set_data ((GObject *)tmp, "show", str);
+ tmp = gtk_label_new (NULL);
+ str = g_strdup_printf ("<span foreground='blue' underline='single' underline_color='blue' >%s</span>", header->priv->addaction_text);
gtk_label_set_markup((GtkLabel *)tmp, str);
- str = g_strdup_printf ("<span>%s %s</span>", _("Hide"), header->priv->addaction_text);
- g_object_set_data ((GObject *)tmp, "hide", str);
-
- header->priv->action_label = tmp;
gtk_box_pack_start((GtkBox *)box, tmp, FALSE, FALSE, 3);
gtk_container_add((GtkContainer *)header->action_widget, box);
gtk_widget_show_all(header->action_widget);
@@ -340,7 +330,8 @@ composer_header_class_init (EComposerHeaderClass *class)
"changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
+ G_STRUCT_OFFSET (EComposerHeaderClass, changed),
+ NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -348,7 +339,8 @@ composer_header_class_init (EComposerHeaderClass *class)
"clicked",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
+ G_STRUCT_OFFSET (EComposerHeaderClass, clicked),
+ NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
@@ -434,6 +426,7 @@ e_composer_header_set_visible (EComposerHeader *header,
header->priv->visible = visible;
+#if 0 /* FIXME This is horrible. Needs completely rethought. */
if (header->priv->action_label) {
if (!visible) {
gtk_label_set_markup ((GtkLabel *)header->priv->action_label, g_object_get_data ((GObject *)header->priv->action_label, "show"));
@@ -446,6 +439,8 @@ e_composer_header_set_visible (EComposerHeader *header,
gtk_widget_show (g_object_get_data((GObject *) header->priv->action_label, "remove"));
}
}
+#endif
+
g_object_notify (G_OBJECT (header), "visible");
}
diff --git a/composer/e-composer-header.h b/composer/e-composer-header.h
index e1d7d923ab..33600900e9 100644
--- a/composer/e-composer-header.h
+++ b/composer/e-composer-header.h
@@ -28,7 +28,7 @@
((obj), E_TYPE_COMPOSER_HEADER, EComposerHeader))
#define E_COMPOSER_HEADER_CLASS(cls) \
(G_TYPE_CHECK_CLASS_CAST \
- ((obj), E_TYPE_COMPOSER_HEADER, EComposerHeaderClass))
+ ((cls), E_TYPE_COMPOSER_HEADER, EComposerHeaderClass))
#define E_IS_COMPOSER_HEADER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE \
((obj), E_TYPE_COMPOSER_HEADER))
@@ -55,6 +55,10 @@ struct _EComposerHeader {
struct _EComposerHeaderClass {
GObjectClass parent_class;
+
+ /* Signals */
+ void (*changed) (EComposerHeader *header);
+ void (*clicked) (EComposerHeader *header);
};
GType e_composer_header_get_type (void);
diff --git a/composer/e-composer-name-header.c b/composer/e-composer-name-header.c
index 47936eeeab..5eed2e42c1 100644
--- a/composer/e-composer-name-header.c
+++ b/composer/e-composer-name-header.c
@@ -48,18 +48,6 @@ struct _EComposerNameHeaderPrivate {
static gpointer parent_class;
static void
-composer_name_header_clicked_cb (EComposerNameHeader *header)
-{
- ENameSelectorDialog *dialog;
-
- dialog = e_name_selector_peek_dialog (header->priv->name_selector);
- e_name_selector_dialog_set_destination_index (
- dialog, header->priv->destination_index);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_hide (GTK_WIDGET (dialog));
-}
-
-static void
composer_name_header_entry_changed_cb (ENameSelectorEntry *entry,
EComposerNameHeader *header)
{
@@ -133,10 +121,6 @@ composer_name_header_constructor (GType type,
NULL);
E_COMPOSER_HEADER (object)->input_widget = g_object_ref_sink (entry);
- g_signal_connect (
- object, "clicked",
- G_CALLBACK (composer_name_header_clicked_cb), NULL);
-
return object;
}
@@ -195,9 +179,25 @@ composer_name_header_dispose (GObject *object)
}
static void
+composer_name_header_clicked (EComposerHeader *header)
+{
+ EComposerNameHeaderPrivate *priv;
+ ENameSelectorDialog *dialog;
+
+ priv = E_COMPOSER_NAME_HEADER_GET_PRIVATE (header);
+
+ dialog = e_name_selector_peek_dialog (priv->name_selector);
+ e_name_selector_dialog_set_destination_index (
+ dialog, priv->destination_index);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_hide (GTK_WIDGET (dialog));
+}
+
+static void
composer_name_header_class_init (EComposerNameHeaderClass *class)
{
GObjectClass *object_class;
+ EComposerHeaderClass *header_class;
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (EComposerNameHeaderPrivate));
@@ -208,6 +208,9 @@ composer_name_header_class_init (EComposerNameHeaderClass *class)
object_class->get_property = composer_name_header_get_property;
object_class->dispose = composer_name_header_dispose;
+ header_class = E_COMPOSER_HEADER_CLASS (class);
+ header_class->clicked = composer_name_header_clicked;
+
g_object_class_install_property (
object_class,
PROP_NAME_SELECTOR,
diff --git a/composer/e-composer-post-header.c b/composer/e-composer-post-header.c
index 59d81b80ac..cb297fe375 100644
--- a/composer/e-composer-post-header.c
+++ b/composer/e-composer-post-header.c
@@ -22,9 +22,7 @@
#include <string.h>
#include <glib/gi18n.h>
-
-#include "mail/em-folder-selector.h"
-#include "mail/em-folder-tree.h"
+#include <camel/camel-url.h>
#define E_COMPOSER_POST_HEADER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -43,10 +41,6 @@ struct _EComposerPostHeaderPrivate {
static gpointer parent_class;
-/* Forward Declarations (to avoid pulling in Bonobo stuff) */
-struct _MailComponent *mail_component_peek (void);
-struct _EMFolderTreeModel *mail_component_peek_tree_model (struct _MailComponent *component);
-
static gchar *
composer_post_header_folder_name_to_string (EComposerPostHeader *header,
const gchar *url)
@@ -106,56 +100,6 @@ composer_post_header_split_csv (const gchar *csv)
return g_list_reverse (list);
}
-static void
-composer_post_header_changed_cb (EComposerPostHeader *header)
-{
- header->priv->custom = TRUE;
-}
-
-static void
-composer_post_header_clicked_cb (EComposerPostHeader *header)
-{
- EMFolderTreeModel *model;
- GtkWidget *folder_tree;
- GtkWidget *dialog;
- GList *list;
-
- model = mail_component_peek_tree_model (mail_component_peek ());
- folder_tree = em_folder_tree_new_with_model (model);
-
- em_folder_tree_set_multiselect (
- EM_FOLDER_TREE (folder_tree), TRUE);
- em_folder_tree_set_excluded (
- EM_FOLDER_TREE (folder_tree),
- EMFT_EXCLUDE_NOSELECT |
- EMFT_EXCLUDE_VIRTUAL |
- EMFT_EXCLUDE_VTRASH);
-
- dialog = em_folder_selector_new (
- EM_FOLDER_TREE (folder_tree),
- EM_FOLDER_SELECTOR_CAN_CREATE,
- _("Posting destination"),
- _("Choose folders to post the message to."),
- NULL);
-
- list = e_composer_post_header_get_folders (header);
- em_folder_selector_set_selected_list (
- EM_FOLDER_SELECTOR (dialog), list);
- g_list_foreach (list, (GFunc) g_free, NULL);
- g_list_free (list);
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
- list = em_folder_selector_get_selected_uris (
- EM_FOLDER_SELECTOR (dialog));
- e_composer_post_header_set_folders (header, list);
- header->priv->custom = FALSE;
- g_list_foreach (list, (GFunc) g_free, NULL);
- g_list_free (list);
- }
-
- gtk_widget_destroy (dialog);
-}
-
static GObject *
composer_post_header_constructor (GType type,
guint n_construct_properties,
@@ -171,14 +115,6 @@ composer_post_header_constructor (GType type,
E_COMPOSER_HEADER (object),
_("Click here to select folders to post to"));
- g_signal_connect (
- object, "changed",
- G_CALLBACK (composer_post_header_changed_cb), NULL);
-
- g_signal_connect (
- object, "clicked",
- G_CALLBACK (composer_post_header_clicked_cb), NULL);
-
return object;
}
@@ -246,9 +182,30 @@ composer_post_header_finalize (GObject *object)
}
static void
+composer_post_header_changed (EComposerHeader *header)
+{
+ EComposerPostHeaderPrivate *priv;
+
+ priv = E_COMPOSER_POST_HEADER_GET_PRIVATE (header);
+
+ priv->custom = TRUE;
+}
+
+static void
+composer_post_header_clicked (EComposerHeader *header)
+{
+ EComposerPostHeaderPrivate *priv;
+
+ priv = E_COMPOSER_POST_HEADER_GET_PRIVATE (header);
+
+ priv->custom = FALSE;
+}
+
+static void
composer_post_header_class_init (EComposerPostHeaderClass *class)
{
GObjectClass *object_class;
+ EComposerHeaderClass *header_class;
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (EComposerPostHeaderPrivate));
@@ -260,6 +217,10 @@ composer_post_header_class_init (EComposerPostHeaderClass *class)
object_class->dispose = composer_post_header_dispose;
object_class->finalize = composer_post_header_finalize;
+ header_class = E_COMPOSER_HEADER_CLASS (class);
+ header_class->changed = composer_post_header_changed;
+ header_class->clicked = composer_post_header_clicked;
+
g_object_class_install_property (
object_class,
PROP_ACCOUNT,
diff --git a/composer/e-composer-post-header.h b/composer/e-composer-post-header.h
index 40dc5a8d58..c38bfe2d17 100644
--- a/composer/e-composer-post-header.h
+++ b/composer/e-composer-post-header.h
@@ -46,6 +46,8 @@
G_BEGIN_DECLS
+/* Avoid including files from the Mail module. */
+
typedef struct _EComposerPostHeader EComposerPostHeader;
typedef struct _EComposerPostHeaderClass EComposerPostHeaderClass;
typedef struct _EComposerPostHeaderPrivate EComposerPostHeaderPrivate;
@@ -60,7 +62,8 @@ struct _EComposerPostHeaderClass {
};
GType e_composer_post_header_get_type (void);
-EComposerHeader * e_composer_post_header_new (const gchar *label);
+EComposerHeader *
+ e_composer_post_header_new (const gchar *label);
EAccount * e_composer_post_header_get_account
(EComposerPostHeader *header);
void e_composer_post_header_set_account
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index 9a506fa862..bfb14b451a 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -17,7 +17,6 @@
#include "e-composer-private.h"
#include "e-util/e-util-private.h"
-#include "widgets/misc/e-attachment-icon-view.h"
static void
composer_setup_charset_menu (EMsgComposer *composer)
@@ -28,10 +27,12 @@ composer_setup_charset_menu (EMsgComposer *composer)
guint merge_id;
ui_manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (composer));
- list = gtk_action_group_list_actions (composer->priv->charset_actions);
path = "/main-menu/edit-menu/pre-spell-check/charset-menu";
merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+ list = gtk_action_group_list_actions (composer->priv->charset_actions);
+ list = g_list_sort (list, (GCompareFunc) e_action_compare_by_label);
+
while (list != NULL) {
GtkAction *action = list->data;
@@ -86,8 +87,8 @@ e_composer_private_init (EMsgComposer *composer)
GtkhtmlEditor *editor;
GtkUIManager *ui_manager;
- GtkWidget *widget;
GtkWidget *container;
+ GtkWidget *widget;
GtkWidget *send_widget;
const gchar *path;
gchar *filename;
@@ -101,7 +102,7 @@ e_composer_private_init (EMsgComposer *composer)
widget = gtkhtml_editor_get_managed_widget (editor, "/main-menu");
gtk_widget_hide (widget);
widget = gtkhtml_editor_get_managed_widget (editor, "/main-toolbar");
- gtk_toolbar_set_style ((GtkToolbar *)widget, GTK_TOOLBAR_BOTH_HORIZ);
+ gtk_toolbar_set_style (GTK_TOOLBAR (widget), GTK_TOOLBAR_BOTH_HORIZ);
gtk_widget_hide (widget);
}
@@ -198,7 +199,6 @@ e_composer_private_init (EMsgComposer *composer)
gtk_container_remove((GtkContainer *)send_widget, gtk_bin_get_child ((GtkBin *)send_widget));
gtk_container_add((GtkContainer *)send_widget, tmp);
gtk_button_set_relief ((GtkButton *)send_widget, GTK_RELIEF_NORMAL);
-
path = "/main-toolbar/pre-main-toolbar/save-draft";
send_widget = gtk_ui_manager_get_widget (ui_manager, path);
tmp = gtk_hbox_new (FALSE, 0);
@@ -297,6 +297,11 @@ e_composer_private_dispose (EMsgComposer *composer)
composer->priv->header_table = NULL;
}
+ if (composer->priv->attachment_paned != NULL) {
+ g_object_unref (composer->priv->attachment_paned);
+ composer->priv->attachment_paned = NULL;
+ }
+
if (composer->priv->charset_actions != NULL) {
g_object_unref (composer->priv->charset_actions);
composer->priv->charset_actions = NULL;
diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h
index 49d9ae6d74..1d0c19f366 100644
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@ -29,7 +29,10 @@
#include "e-composer-autosave.h"
#include "e-composer-header-table.h"
#include "e-util/e-binding.h"
+#include "e-util/e-charset.h"
+#include "e-util/e-util.h"
#include "e-util/gconf-bridge.h"
+#include "widgets/misc/e-attachment-icon-view.h"
#include "widgets/misc/e-attachment-paned.h"
#include "widgets/misc/e-attachment-store.h"
@@ -104,7 +107,6 @@ struct _EMsgComposerPrivate {
gchar *mime_type, *mime_body, *charset;
- guint32 attachment_bar_visible : 1;
guint32 is_alternative : 1;
guint32 autosaved : 1;
guint32 mode_post : 1;
@@ -113,8 +115,6 @@ struct _EMsgComposerPrivate {
CamelMimeMessage *redirect;
- guint notify_id;
-
gboolean send_invoked;
};
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 178f3cdbdd..1b2d5c665c 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -23,17 +23,6 @@
*
*/
-/*
-
- TODO
-
- - Somehow users should be able to see if any file (s) are attached even when
- the attachment bar is not shown.
-
- Should use EventSources to keep track of global changes made to configuration
- values. Right now it ignores the problem olympically. Miguel.
-*/
-
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -59,50 +48,40 @@
#include <glade/glade.h>
#include "e-util/e-dialog-utils.h"
-#include "misc/e-charset-picker.h"
#include "e-util/e-error.h"
+#include "e-util/e-mktemp.h"
#include "e-util/e-plugin-ui.h"
#include "e-util/e-util-private.h"
-#include "e-util/e-util.h"
-#include "e-util/e-mktemp.h"
-#include <mail/em-event.h>
+#include "e-util/e-account-utils.h"
+#include "e-util/e-signature-utils.h"
#include "e-signature-combo-box.h"
+#include "shell/e-shell.h"
+#include "em-format/em-format.h"
+#include "em-format/em-format-quote.h"
-#include <camel/camel-session.h>
#include <camel/camel-charset-map.h>
+#include <camel/camel-cipher-context.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-gpg-context.h>
#include <camel/camel-iconv.h>
-#include <camel/camel-stream-filter.h>
#include <camel/camel-mime-filter-charset.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-stream-fs.h>
#include <camel/camel-mime-filter-tohtml.h>
-#include <camel/camel-multipart-signed.h>
#include <camel/camel-multipart-encrypted.h>
+#include <camel/camel-multipart-signed.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-stream-fs.h>
+#include <camel/camel-stream-mem.h>
#include <camel/camel-string-utils.h>
-#include <camel/camel-cipher-context.h>
#if defined (HAVE_NSS)
#include <camel/camel-smime-context.h>
#endif
-#include "mail/em-utils.h"
-#include "mail/em-composer-utils.h"
-#include "mail/mail-config.h"
-#include "mail/mail-crypto.h"
-#include "mail/mail-tools.h"
-#include "mail/mail-ops.h"
-#include "mail/mail-mt.h"
-#include "mail/mail-session.h"
-#include "mail/em-popup.h"
-#include "mail/em-menu.h"
-
#include "e-msg-composer.h"
#include "e-attachment.h"
#include "e-composer-autosave.h"
#include "e-composer-private.h"
#include "e-composer-header-table.h"
-#include "evolution-shell-component-utils.h"
-
#ifdef HAVE_XFREE
#include <X11/XF86keysym.h>
#endif
@@ -116,6 +95,7 @@
enum {
SEND,
SAVE_DRAFT,
+ PRINT,
LAST_SIGNAL
};
@@ -142,6 +122,104 @@ static void handle_multipart_alternative (EMsgComposer *composer, CamelMultipart
static void handle_multipart_encrypted (EMsgComposer *composer, CamelMimePart *multipart, gint depth);
static void handle_multipart_signed (EMsgComposer *composer, CamelMultipart *multipart, gint depth);
+/**
+ * emcu_part_to_html:
+ * @part:
+ *
+ * Converts a mime part's contents into html text. If @credits is given,
+ * then it will be used as an attribution string, and the
+ * content will be cited. Otherwise no citation or attribution
+ * will be performed.
+ *
+ * Return Value: The part in displayable html format.
+ **/
+static gchar *
+emcu_part_to_html (CamelMimePart *part, gssize *len, EMFormat *source)
+{
+ EMFormatQuote *emfq;
+ CamelStreamMem *mem;
+ GByteArray *buf;
+ gchar *text;
+
+ buf = g_byte_array_new ();
+ mem = (CamelStreamMem *) camel_stream_mem_new ();
+ camel_stream_mem_set_byte_array (mem, buf);
+
+ emfq = em_format_quote_new(NULL, (CamelStream *)mem, 0);
+ ((EMFormat *) emfq)->composer = TRUE;
+ if (source) {
+ /* copy over things we can, other things are internal, perhaps need different api than 'clone' */
+ if (source->default_charset)
+ em_format_set_default_charset((EMFormat *)emfq, source->default_charset);
+ if (source->charset)
+ em_format_set_default_charset((EMFormat *)emfq, source->charset);
+ }
+ em_format_part((EMFormat *) emfq, (CamelStream *)mem, part);
+ g_object_unref(emfq);
+
+ camel_stream_write((CamelStream *) mem, "", 1);
+ camel_object_unref(mem);
+
+ text = (gchar *)buf->data;
+ if (len)
+ *len = buf->len-1;
+ g_byte_array_free (buf, FALSE);
+
+ return text;
+}
+
+/* copy of em_utils_prompt_user from mailer */
+static gboolean
+emcu_prompt_user (GtkWindow *parent, const gchar *promptkey, const gchar *tag, const gchar *arg0, ...)
+{
+ GtkWidget *mbox, *check = NULL;
+ va_list ap;
+ gint button;
+ GConfClient *gconf = gconf_client_get_default ();
+
+ if (promptkey
+ && !gconf_client_get_bool(gconf, promptkey, NULL)) {
+ g_object_unref (gconf);
+ return TRUE;
+ }
+
+ va_start(ap, arg0);
+ mbox = e_error_newv(parent, tag, arg0, ap);
+ va_end(ap);
+
+ if (promptkey) {
+ check = gtk_check_button_new_with_mnemonic (_("_Do not show this message again."));
+ gtk_container_set_border_width((GtkContainer *)check, 12);
+ gtk_box_pack_start ((GtkBox *)((GtkDialog *) mbox)->vbox, check, TRUE, TRUE, 0);
+ gtk_widget_show (check);
+ }
+
+ button = gtk_dialog_run ((GtkDialog *) mbox);
+ if (promptkey)
+ gconf_client_set_bool(gconf, promptkey, !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check)), NULL);
+
+ gtk_widget_destroy(mbox);
+ g_object_unref (gconf);
+
+ return button == GTK_RESPONSE_YES;
+}
+
+/* copy of mail_tool_remove_xevolution_headers */
+static struct _camel_header_raw *
+emcu_remove_xevolution_headers (CamelMimeMessage *message)
+{
+ struct _camel_header_raw *scan, *list = NULL;
+
+ for (scan = ((CamelMimePart *)message)->headers;scan;scan=scan->next)
+ if (!strncmp(scan->name, "X-Evolution", 11))
+ camel_header_raw_append(&list, scan->name, scan->value, scan->offset);
+
+ for (scan=list;scan;scan=scan->next)
+ camel_medium_remove_header((CamelMedium *)message, scan->name);
+
+ return list;
+}
+
static EDestination**
destination_list_to_vector_sized (GList *list, gint n)
{
@@ -476,6 +554,7 @@ build_message (EMsgComposer *composer,
CamelMultipart *body = NULL;
CamelContentType *type;
CamelMimeMessage *new;
+ CamelSession *session;
CamelStream *stream;
CamelMimePart *part;
CamelException ex;
@@ -495,6 +574,7 @@ build_message (EMsgComposer *composer,
account = e_composer_header_table_get_account (table);
view = e_msg_composer_get_attachment_view (composer);
store = e_attachment_view_get_store (view);
+ session = e_msg_composer_get_session (composer);
/* evil kludgy hack for Redirect */
if (p->redirect) {
@@ -746,8 +826,14 @@ build_message (EMsgComposer *composer,
if (pgp_sign) {
CamelMimePart *npart = camel_mime_part_new ();
- cipher = mail_crypto_get_pgp_cipher_context (account);
- camel_cipher_sign (cipher, pgp_userid, CAMEL_CIPHER_HASH_SHA1, part, npart, &ex);
+ cipher = camel_gpg_context_new (session);
+ if (account != NULL)
+ camel_gpg_context_set_always_trust (
+ CAMEL_GPG_CONTEXT (cipher),
+ account->pgp_always_trust);
+ camel_cipher_sign (
+ cipher, pgp_userid, CAMEL_CIPHER_HASH_SHA1,
+ part, npart, &ex);
camel_object_unref (cipher);
if (camel_exception_is_set (&ex)) {
@@ -766,8 +852,14 @@ build_message (EMsgComposer *composer,
if (account && account->pgp_encrypt_to_self && pgp_userid)
g_ptr_array_add (recipients, g_strdup (pgp_userid));
- cipher = mail_crypto_get_pgp_cipher_context (account);
- camel_cipher_encrypt (cipher, pgp_userid, recipients, part, npart, &ex);
+ cipher = camel_gpg_context_new (session);
+ if (account != NULL)
+ camel_gpg_context_set_always_trust (
+ CAMEL_GPG_CONTEXT (cipher),
+ account->pgp_always_trust);
+ camel_cipher_encrypt (
+ cipher, pgp_userid, recipients,
+ part, npart, &ex);
camel_object_unref (cipher);
if (account && account->pgp_encrypt_to_self && pgp_userid)
@@ -841,6 +933,7 @@ build_message (EMsgComposer *composer,
}
if (smime_encrypt) {
+
/* check to see if we should encrypt to self, NB removed after use */
if (account->smime_encrypt_to_self)
g_ptr_array_add (recipients, g_strdup (account->smime_encrypt_key));
@@ -920,103 +1013,6 @@ skip_content:
/* Signatures */
static gchar *
-get_file_content (EMsgComposer *composer,
- const gchar *filename,
- gboolean want_html,
- guint flags,
- gboolean warn)
-{
- CamelStreamFilter *filtered_stream;
- CamelStreamMem *memstream;
- CamelMimeFilter *html, *charenc;
- CamelStream *stream;
- GByteArray *buffer;
- gchar *charset;
- gchar *content;
- gint fd;
-
- fd = g_open (filename, O_RDONLY, 0);
- if (fd == -1) {
- if (warn)
- e_error_run ((GtkWindow *)composer, "mail-composer:no-sig-file",
- filename, g_strerror (errno), NULL);
- return g_strdup ("");
- }
-
- stream = camel_stream_fs_new_with_fd (fd);
-
- if (want_html) {
- filtered_stream = camel_stream_filter_new_with_stream (stream);
- camel_object_unref (stream);
-
- html = camel_mime_filter_tohtml_new (flags, 0);
- camel_stream_filter_add (filtered_stream, html);
- camel_object_unref (html);
-
- stream = (CamelStream *) filtered_stream;
- }
-
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- buffer = g_byte_array_new ();
- camel_stream_mem_set_byte_array (memstream, buffer);
-
- camel_stream_write_to_stream (stream, (CamelStream *) memstream);
- camel_object_unref (stream);
-
- /* The newer signature UI saves signatures in UTF-8, but we still need to check that
- the signature is valid UTF-8 because it is possible that the user imported a
- signature file that is in his/her locale charset. If it's not in UTF-8 and not in
- the charset the composer is in (or their default mail charset) then
- there's nothing we can do. */
- if (buffer->len && !g_utf8_validate ((const gchar *)buffer->data, buffer->len, NULL)) {
- stream = (CamelStream *) memstream;
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (memstream, g_byte_array_new ());
-
- filtered_stream = camel_stream_filter_new_with_stream (stream);
- camel_object_unref (stream);
-
- charset = composer && composer->priv->charset ? composer->priv->charset : NULL;
- charset = charset ? g_strdup (charset) : e_composer_get_default_charset ();
- if ((charenc = (CamelMimeFilter *) camel_mime_filter_charset_new_convert (charset, "UTF-8"))) {
- camel_stream_filter_add (filtered_stream, charenc);
- camel_object_unref (charenc);
- }
-
- g_free (charset);
-
- camel_stream_write_to_stream ((CamelStream *) filtered_stream, (CamelStream *) memstream);
- camel_object_unref (filtered_stream);
- g_byte_array_free (buffer, TRUE);
-
- buffer = memstream->buffer;
- }
-
- camel_object_unref (memstream);
-
- g_byte_array_append (buffer, (const guint8 *)"", 1);
- content = (gchar *)buffer->data;
- g_byte_array_free (buffer, FALSE);
-
- return content;
-}
-
-gchar *
-e_msg_composer_get_sig_file_content (const gchar *sigfile, gboolean in_html)
-{
- if (!sigfile || !*sigfile) {
- return NULL;
- }
-
- return get_file_content (NULL, sigfile, !in_html,
- CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES,
- FALSE);
-}
-
-static gchar *
encode_signature_uid (ESignature *signature)
{
const gchar *uid;
@@ -1109,34 +1105,6 @@ decode_signature_name (const gchar *name)
return dname;
}
-static gboolean
-add_signature_delim (void)
-{
- gboolean res;
- GConfClient *client = gconf_client_get_default ();
-
- res = !gconf_client_get_bool (client, COMPOSER_GCONF_NO_SIGNATURE_DELIM_KEY, NULL);
-
- g_object_unref (client);
-
- return res;
-}
-
-static gboolean
-is_top_signature (void)
-{
- GConfClient *gconf;
- gboolean res = FALSE;
-
- gconf = gconf_client_get_default ();
-
- res = gconf_client_get_bool (gconf, COMPOSER_GCONF_TOP_SIGNATURE_KEY, NULL);
-
- g_object_unref (gconf);
-
- return res;
-}
-
#define CONVERT_SPACES CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES
#define NO_SIGNATURE_TEXT \
"<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"signature\" value=\"1\">-->" \
@@ -1148,7 +1116,7 @@ get_signature_html (EMsgComposer *composer)
EComposerHeaderTable *table;
gchar *text = NULL, *html = NULL;
ESignature *signature;
- gboolean format_html, add_delim;
+ gboolean format_html;
table = e_msg_composer_get_header_table (composer);
signature = e_composer_header_table_get_signature (table);
@@ -1156,8 +1124,6 @@ get_signature_html (EMsgComposer *composer)
if (!signature)
return NULL;
- add_delim = add_signature_delim ();
-
if (!e_signature_get_autogenerated (signature)) {
const gchar *filename;
@@ -1168,9 +1134,9 @@ get_signature_html (EMsgComposer *composer)
format_html = e_signature_get_is_html (signature);
if (e_signature_get_is_script (signature))
- text = mail_config_signature_run_script (filename);
+ text = e_run_signature_script (filename);
else
- text = e_msg_composer_get_sig_file_content (filename, format_html);
+ text = e_read_signature_file (signature, TRUE, NULL);
} else {
EAccount *account;
EAccountIdentity *id;
@@ -1187,8 +1153,7 @@ get_signature_html (EMsgComposer *composer)
name = id->name ? camel_text_to_html (id->name, CONVERT_SPACES, 0) : NULL;
organization = id->organization ? camel_text_to_html (id->organization, CONVERT_SPACES, 0) : NULL;
- text = g_strdup_printf ("%s%s%s%s%s%s%s%s%s",
- add_delim ? "-- <BR>" : "",
+ text = g_strdup_printf ("-- <BR>%s%s%s%s%s%s%s%s",
name ? name : "",
(address && *address) ? " &lt;<A HREF=\"mailto:" : "",
address ? address : "",
@@ -1218,13 +1183,12 @@ get_signature_html (EMsgComposer *composer)
"<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"signature_name\" value=\"uid:%s\">-->"
"<TABLE WIDTH=\"100%%\" CELLSPACING=\"0\" CELLPADDING=\"0\"><TR><TD><BR>"
"%s%s%s%s"
- "%s</TD></TR></TABLE>",
+ "</TD></TR></TABLE>",
encoded_uid ? encoded_uid : "",
format_html ? "" : "<PRE>\n",
- format_html || !add_delim || (!strncmp ("-- \n", text, 4) || strstr (text, "\n-- \n")) ? "" : "-- \n",
+ format_html || (!strncmp ("-- \n", text, 4) || strstr (text, "\n-- \n")) ? "" : "-- \n",
text,
- format_html ? "" : "</PRE>\n",
- is_top_signature () ? "<BR>" : "");
+ format_html ? "" : "</PRE>\n");
g_free (text);
g_free (encoded_uid);
text = html;
@@ -1238,11 +1202,17 @@ set_editor_text (EMsgComposer *composer,
const gchar *text,
gboolean set_signature)
{
- gchar *body = NULL;
+ EShell *shell;
+ EShellSettings *shell_settings;
+ gboolean reply_signature_on_top;
+ gchar *body = NULL, *html = NULL;
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
g_return_if_fail (text != NULL);
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
/*
Keeping Signatures in the beginning of composer
@@ -1257,9 +1227,30 @@ set_editor_text (EMsgComposer *composer,
*/
- if (is_top_signature ()) {
- /* put marker to the top */
- body = g_strdup_printf ("<BR>" NO_SIGNATURE_TEXT "%s", text);
+ reply_signature_on_top = e_shell_settings_get_boolean (
+ shell_settings, "composer-top-signature");
+
+ if (set_signature && reply_signature_on_top) {
+ gchar *tmp = NULL;
+ tmp = get_signature_html (composer);
+ if (tmp) {
+ /* Minimizing the damage. Make it just a part of the body instead of a signature */
+ html = strstr (tmp, "-- \n");
+ if (html) {
+ /* That two consecutive - symbols followed by a space */
+ *(html+1) = ' ';
+ body = g_strdup_printf ("</br>%s</br>%s", tmp, text);
+ } else {
+ /* HTML Signature. Make it as part of body */
+ body = g_strdup_printf ("</br>%s</br>%s", tmp, text);
+ }
+ g_free (tmp);
+ } else {
+ /* No signature set */
+ body = g_strdup_printf ("<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"signature\" value=\"1\">-->"
+ "<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"signature_name\" value=\"uid:Noname\">-->"
+ "<TABLE WIDTH=\"100%%\" CELLSPACING=\"0\" CELLPADDING=\"0\"><TR><TD> </TD></TR></TABLE>%s", text);
+ }
} else {
/* no marker => to the bottom */
body = g_strdup_printf ("%s<BR>", text);
@@ -1310,14 +1301,6 @@ autosave_load_draft (const gchar *filename)
(GAsyncReadyCallback) autosave_load_draft_cb,
g_strdup (filename));
- g_signal_connect (
- composer, "send",
- G_CALLBACK (em_utils_composer_send_cb), NULL);
-
- g_signal_connect (
- composer, "save-draft",
- G_CALLBACK (em_utils_composer_save_draft_cb), NULL);
-
gtk_widget_show (GTK_WIDGET (composer));
}
@@ -1385,7 +1368,7 @@ msg_composer_account_changed_cb (EMsgComposer *composer)
gtk_toggle_action_set_active (action, active);
uid = account->id->sig_uid;
- signature = uid ? mail_config_get_signature_by_uid (uid) : NULL;
+ signature = uid ? e_get_signature_by_uid (uid) : NULL;
e_composer_header_table_set_signature (table, signature);
/* XXX This should be done more generically. The composer
@@ -1439,53 +1422,6 @@ msg_composer_account_list_changed_cb (EMsgComposer *composer)
g_object_unref (iterator);
}
-static void
-msg_composer_update_preferences (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- EMsgComposer *composer)
-{
- GtkhtmlEditor *editor;
- gboolean enable;
- GError *error = NULL;
-
- editor = GTKHTML_EDITOR (composer);
-
- if (entry) {
- if (strcmp(gconf_entry_get_key(entry), COMPOSER_GCONF_INLINE_SPELLING_KEY) != 0 &&
- strcmp(gconf_entry_get_key(entry), COMPOSER_GCONF_MAGIC_LINKS_KEY) != 0 &&
- strcmp(gconf_entry_get_key(entry), COMPOSER_GCONF_MAGIC_SMILEYS_KEY) != 0)
- return;
- }
-
- enable = gconf_client_get_bool (
- client, COMPOSER_GCONF_INLINE_SPELLING_KEY, &error);
- if (error == NULL)
- gtkhtml_editor_set_inline_spelling (editor, enable);
- else {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- }
-
- enable = gconf_client_get_bool (
- client, COMPOSER_GCONF_MAGIC_LINKS_KEY, &error);
- if (error == NULL)
- gtkhtml_editor_set_magic_links (editor, enable);
- else {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- }
-
- enable = gconf_client_get_bool (
- client, COMPOSER_GCONF_MAGIC_SMILEYS_KEY, &error);
- if (error == NULL)
- gtkhtml_editor_set_magic_smileys (editor, enable);
- else {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- }
-}
-
struct _drop_data {
EMsgComposer *composer;
@@ -1496,10 +1432,6 @@ struct _drop_data {
guint32 action;
guint info;
guint time;
-
- guint move:1;
- guint moved:1;
- guint aborted:1;
};
static void
@@ -1516,11 +1448,11 @@ msg_composer_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_properties)
{
+ EShell *shell;
+ EShellSettings *shell_settings;
GObject *object;
EMsgComposer *composer;
GtkToggleAction *action;
- GList *spell_languages;
- GConfClient *client;
GArray *array;
gboolean active;
guint binding_id;
@@ -1530,9 +1462,11 @@ msg_composer_constructor (GType type,
type, n_construct_properties, construct_properties);
composer = E_MSG_COMPOSER (object);
- client = gconf_client_get_default ();
array = composer->priv->gconf_bridge_binding_ids;
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
/* Restore Persistent State */
binding_id = gconf_bridge_bind_property (
@@ -1549,29 +1483,16 @@ msg_composer_constructor (GType type,
/* Honor User Preferences */
- active = gconf_client_get_bool (
- client, COMPOSER_GCONF_SEND_HTML_KEY, NULL);
+ active = e_shell_settings_get_boolean (
+ shell_settings, "composer-format-html");
gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (composer), active);
action = GTK_TOGGLE_ACTION (ACTION (REQUEST_READ_RECEIPT));
- active = gconf_client_get_bool (
- client, COMPOSER_GCONF_REQUEST_RECEIPT_KEY, NULL);
+ active = e_shell_settings_get_boolean (
+ shell_settings, "composer-request-receipt");
gtk_toggle_action_set_active (action, active);
- spell_languages = e_load_spell_languages ();
- gtkhtml_editor_set_spell_languages (
- GTKHTML_EDITOR (composer), spell_languages);
- g_list_free (spell_languages);
-
- gconf_client_add_dir (
- client, COMPOSER_GCONF_PREFIX,
- GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
- composer->priv->notify_id = gconf_client_notify_add (
- client, COMPOSER_GCONF_PREFIX, (GConfClientNotifyFunc)
- msg_composer_update_preferences, composer, NULL, NULL);
- msg_composer_update_preferences (client, 0, NULL, composer);
-
- g_object_unref (client);
+ e_shell_watch_window (shell, GTK_WINDOW (object));
return object;
}
@@ -1618,15 +1539,6 @@ msg_composer_destroy (GtkObject *object)
composer->priv->address_dialog = NULL;
}
- if (composer->priv->notify_id) {
- GConfClient *client;
-
- client = gconf_client_get_default ();
- gconf_client_notify_remove (client, composer->priv->notify_id);
- composer->priv->notify_id = 0;
- g_object_unref (client);
- }
-
/* Chain up to parent's destroy() method. */
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
@@ -1834,7 +1746,7 @@ msg_composer_paste_clipboard (GtkhtmlEditor *editor)
clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
/* Assume the clipboard has an image. The return
- * value will be NULL we we assumed wrong. */
+ * value will be NULL if we assumed wrong. */
pixbuf = gtk_clipboard_wait_for_image (clipboard);
if (!GDK_IS_PIXBUF (pixbuf))
goto chainup;
@@ -2145,7 +2057,7 @@ msg_composer_class_init (EMsgComposerClass *class)
signals[SEND] = g_signal_new (
"send",
- E_TYPE_MSG_COMPOSER,
+ G_OBJECT_CLASS_TYPE (class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
@@ -2153,11 +2065,20 @@ msg_composer_class_init (EMsgComposerClass *class)
signals[SAVE_DRAFT] = g_signal_new (
"save-draft",
- E_TYPE_MSG_COMPOSER,
+ G_OBJECT_CLASS_TYPE (class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+
+ signals[PRINT] = g_signal_new (
+ "print",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_PRINT_OPERATION_ACTION);
}
static void
@@ -2172,6 +2093,7 @@ msg_composer_init (EMsgComposer *composer)
GtkUIManager *ui_manager;
GtkhtmlEditor *editor;
GtkHTML *html;
+ const gchar *id;
gint n_targets;
composer->lite = composer_lite;
@@ -2209,9 +2131,9 @@ msg_composer_init (EMsgComposer *composer)
/* Configure Headers */
e_composer_header_table_set_account_list (
- table, mail_config_get_accounts ());
+ table, e_get_account_list ());
e_composer_header_table_set_signature_list (
- table, mail_config_get_signatures ());
+ table, e_get_signature_list ());
g_signal_connect_swapped (
table, "notify::account",
@@ -2261,8 +2183,9 @@ msg_composer_init (EMsgComposer *composer)
/* Initialization may have tripped the "changed" state. */
gtkhtml_editor_set_changed (editor, FALSE);
- e_plugin_ui_register_manager (
- "org.gnome.evolution.composer", ui_manager, composer);
+ id = "org.gnome.evolution.composer";
+ e_plugin_ui_register_manager (ui_manager, id, composer);
+ e_plugin_ui_enable_manager (ui_manager, id);
}
GType
@@ -2505,7 +2428,7 @@ handle_multipart_signed (EMsgComposer *composer,
gchar *html;
gssize length;
- html = em_utils_part_to_html (mime_part, &length, NULL);
+ html = emcu_part_to_html (mime_part, &length, NULL);
e_msg_composer_set_pending_body (composer, html, length);
} else {
e_msg_composer_attach (composer, mime_part);
@@ -2521,6 +2444,7 @@ handle_multipart_encrypted (EMsgComposer *composer,
CamelCipherContext *cipher;
CamelDataWrapper *content;
CamelMimePart *mime_part;
+ CamelSession *session;
CamelException ex;
CamelCipherValidity *valid;
GtkToggleAction *action;
@@ -2530,7 +2454,8 @@ handle_multipart_encrypted (EMsgComposer *composer,
gtk_toggle_action_set_active (action, TRUE);
camel_exception_init (&ex);
- cipher = mail_crypto_get_pgp_cipher_context (NULL);
+ session = e_msg_composer_get_session (composer);
+ cipher = camel_gpg_context_new (session);
mime_part = camel_mime_part_new ();
valid = camel_cipher_decrypt (cipher, multipart, mime_part, &ex);
camel_object_unref (cipher);
@@ -2568,7 +2493,7 @@ handle_multipart_encrypted (EMsgComposer *composer,
gchar *html;
gssize length;
- html = em_utils_part_to_html (mime_part, &length, NULL);
+ html = emcu_part_to_html (mime_part, &length, NULL);
e_msg_composer_set_pending_body (composer, html, length);
} else {
e_msg_composer_attach (composer, mime_part);
@@ -2634,7 +2559,7 @@ handle_multipart_alternative (EMsgComposer *composer,
gchar *html;
gssize length;
- html = em_utils_part_to_html (text_part, &length, NULL);
+ html = emcu_part_to_html (text_part, &length, NULL);
e_msg_composer_set_pending_body (composer, html, length);
}
}
@@ -2684,7 +2609,7 @@ handle_multipart (EMsgComposer *composer,
/* Since the first part is not multipart/alternative,
* this must be the body. */
- html = em_utils_part_to_html (mime_part, &length, NULL);
+ html = emcu_part_to_html (mime_part, &length, NULL);
e_msg_composer_set_pending_body (composer, html, length);
} else if (camel_mime_part_get_content_id (mime_part) ||
camel_mime_part_get_content_location (mime_part)) {
@@ -2715,11 +2640,11 @@ set_signature_gui (EMsgComposer *composer)
data = gtkhtml_editor_get_paragraph_data (editor, "signature_name");
if (g_str_has_prefix (data, "uid:")) {
decoded = decode_signature_name (data + 4);
- signature = mail_config_get_signature_by_uid (decoded);
+ signature = e_get_signature_by_uid (decoded);
g_free (decoded);
} else if (g_str_has_prefix (data, "name:")) {
decoded = decode_signature_name (data + 5);
- signature = mail_config_get_signature_by_name (decoded);
+ signature = e_get_signature_by_name (decoded);
g_free (decoded);
}
@@ -2776,10 +2701,12 @@ e_msg_composer_new_with_message (CamelMimeMessage *message)
account_name = g_strdup (account_name);
g_strstrip (account_name);
- if ((account = mail_config_get_account_by_uid (account_name)) == NULL)
- /* 'old' setting */
- account = mail_config_get_account_by_name (account_name);
- if (account) {
+ account = e_get_account_by_uid (account_name);
+ if (account == NULL)
+ /* XXX Backwards compatibility */
+ account = e_get_account_by_name (account_name);
+
+ if (account != NULL) {
g_free (account_name);
account_name = g_strdup (account->name);
}
@@ -2944,7 +2871,7 @@ e_msg_composer_new_with_message (CamelMimeMessage *message)
}
/* Remove any other X-Evolution-* headers that may have been set */
- xev = mail_tool_remove_xevolution_headers (message);
+ xev = emcu_remove_xevolution_headers (message);
camel_header_raw_clear (&xev);
/* Check for receipt request */
@@ -3000,7 +2927,7 @@ e_msg_composer_new_with_message (CamelMimeMessage *message)
gchar *html;
gssize length;
- html = em_utils_part_to_html ((CamelMimePart *)message, &length, NULL);
+ html = emcu_part_to_html ((CamelMimePart *)message, &length, NULL);
e_msg_composer_set_pending_body (composer, html, length);
}
@@ -3073,6 +3000,35 @@ e_msg_composer_new_redirect (CamelMimeMessage *message,
}
/**
+ * e_msg_composer_get_session:
+ * @composer: an #EMsgComposer
+ *
+ * Returns the mail module's global #CamelSession instance. Calling
+ * this function will load the mail module if it isn't already loaded.
+ *
+ * Returns: the mail module's #CamelSession
+ **/
+CamelSession *
+e_msg_composer_get_session (EMsgComposer *composer)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ CamelSession *session;
+
+ /* FIXME EMsgComposer should own a reference to EShell. */
+
+ g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
+
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ session = e_shell_settings_get_pointer (shell_settings, "mail-session");
+ g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL);
+
+ return session;
+}
+
+/**
* e_msg_composer_send:
* @composer: an #EMsgComposer
*
@@ -3108,6 +3064,22 @@ e_msg_composer_save_draft (EMsgComposer *composer)
e_composer_autosave_set_saved (composer, FALSE);
}
+/**
+ * e_msg_composer_print:
+ * @composer: an #EMsgComposer
+ * @action: the print action to start
+ *
+ * Print the message in @composer.
+ **/
+void
+e_msg_composer_print (EMsgComposer *composer,
+ GtkPrintOperationAction action)
+{
+ g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+ g_signal_emit (composer, signals[PRINT], 0, action);
+}
+
static GList *
add_recipients (GList *list, const gchar *recips)
{
@@ -3594,7 +3566,7 @@ e_msg_composer_get_message (EMsgComposer *composer,
store = e_attachment_view_get_store (view);
if (e_attachment_store_get_num_loading (store) > 0) {
- if (!em_utils_prompt_user (GTK_WINDOW (composer), NULL,
+ if (!emcu_prompt_user (GTK_WINDOW (composer), NULL,
"mail-composer:ask-send-message-pending-download", NULL)) {
return NULL;
}
@@ -3771,7 +3743,6 @@ e_msg_composer_show_sig_file (EMsgComposer *composer)
GtkhtmlEditor *editor;
GtkHTML *html;
gchar *html_text;
- gboolean top_signature;
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
@@ -3798,8 +3769,6 @@ e_msg_composer_show_sig_file (EMsgComposer *composer)
}
gtkhtml_editor_run_command (editor, "unblock-selection");
- top_signature = is_top_signature ();
-
html_text = get_signature_html (composer);
if (html_text) {
gtkhtml_editor_run_command (editor, "insert-paragraph");
@@ -3813,10 +3782,6 @@ e_msg_composer_show_sig_file (EMsgComposer *composer)
gtkhtml_editor_run_command (editor, "style-normal");
gtkhtml_editor_insert_html (editor, html_text);
g_free (html_text);
- } else if (top_signature) {
- /* insert paragraph after the signature ClueFlow things */
- gtkhtml_editor_run_command (editor, "cursor-forward");
- gtkhtml_editor_run_command (editor, "insert-paragraph");
}
gtkhtml_editor_undo_end (editor);
@@ -3960,17 +3925,8 @@ e_msg_composer_load_from_file (const gchar *filename)
camel_object_unref (stream);
composer = e_msg_composer_new_with_message (msg);
- if (composer != NULL) {
- g_signal_connect (
- composer, "send",
- G_CALLBACK (em_utils_composer_send_cb), NULL);
-
- g_signal_connect (
- composer, "save-draft",
- G_CALLBACK (em_utils_composer_save_draft_cb), NULL);
-
+ if (composer != NULL)
gtk_widget_show (GTK_WIDGET (composer));
- }
return composer;
}
diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h
index 434f330e9a..1d5eb39d80 100644
--- a/composer/e-msg-composer.h
+++ b/composer/e-msg-composer.h
@@ -25,6 +25,7 @@
#include <camel/camel-internet-address.h>
#include <camel/camel-mime-message.h>
+#include <camel/camel-session.h>
#include <libedataserver/e-account.h>
#include <libebook/e-destination.h>
#include <gtkhtml-editor.h>
@@ -67,21 +68,21 @@ struct _EMsgComposerClass {
GtkhtmlEditorClass parent_class;
};
-struct _EAttachmentBar;
-
GType e_msg_composer_get_type (void);
EMsgComposer * e_msg_composer_new (void);
-EMsgComposer * e_msg_composer_lite_new (void);
-
+void e_msg_composer_set_lite (void);
+gboolean e_msg_composer_get_lite (void);
+EMsgComposer * e_msg_composer_lite_new (void);
EMsgComposer * e_msg_composer_new_with_message (CamelMimeMessage *msg);
EMsgComposer * e_msg_composer_new_from_url (const gchar *url);
EMsgComposer * e_msg_composer_new_redirect (CamelMimeMessage *message,
const gchar *resent_from);
-void e_msg_composer_set_lite (void);
-gboolean e_msg_composer_get_lite (void);
+CamelSession * e_msg_composer_get_session (EMsgComposer *composer);
void e_msg_composer_send (EMsgComposer *composer);
void e_msg_composer_save_draft (EMsgComposer *composer);
+void e_msg_composer_print (EMsgComposer *composer,
+ GtkPrintOperationAction action);
void e_msg_composer_set_alternative (EMsgComposer *composer,
gboolean alt);
@@ -129,9 +130,6 @@ void e_msg_composer_set_enable_autosave
(EMsgComposer *composer,
gboolean enabled);
-gchar * e_msg_composer_get_sig_file_content
- (const gchar *sigfile,
- gboolean in_html);
void e_msg_composer_add_message_attachments
(EMsgComposer *composer,
CamelMimeMessage *message,
diff --git a/configure.ac b/configure.ac
index 607ceb01ae..8f771064ef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,15 +28,18 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_SRCDIR(README)
+dnl User Documentation
+GNOME_DOC_INIT
+
+dnl Developer Documentation
+GTK_DOC_CHECK(1.9)
+
dnl This is for the autoconf tests only - it set's the language we use
AC_LANG(C)
dnl Automake 1.11 - Silent Build Rules
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-dnl Gnome Doc Initialization
-GNOME_DOC_INIT
-
dnl Some requirements have versioned package names
dnl XXX In the spirit of getting rid of versioned
dnl files, can we please drop these suffixes?
@@ -50,7 +53,6 @@ m4_define([eds_minimum_version], [evo_version])
m4_define([gnome_icon_theme_minimum_version], [2.19.91])
m4_define([gnome_desktop_minimum_version], [2.26.0])
m4_define([libbonobo_minimum_version], [2.20.3])
-m4_define([libbonoboui_minimum_version], [2.4.2])
m4_define([libgtkhtml_minimum_version], [3.27.90])
m4_define([gconf_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([libglade_minimum_version], [2.0.0]) dnl XXX Just a Guess
@@ -59,6 +61,7 @@ m4_define([libgnomeui_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([libxml_minimum_version], [2.7.3])
m4_define([shared_mime_info_minimum_version], [0.22])
m4_define([libpst_minimum_version], [0.6.41])
+m4_define([unique_minimum_version], [1.0.8])
dnl Optional Packages
m4_define([dbus_minimum_version], [0.74])
@@ -68,15 +71,15 @@ m4_define([libnotify_minimum_version], [0.3.0])
m4_define([gnome_pilot_minimum_version], [2.0.15])
m4_define([gweather_minimum_version], [2.25.3])
+dnl ******************************
dnl Compiler Warning Flags
-
+dnl ******************************
AS_COMPILER_FLAGS(WARNING_FLAGS,
"-DG_DISABLE_DEPRECATED
-DPANGO_DISABLE_DEPRECATED
-DGDK_PIXBUF_DISABLE_DEPRECATED
-DGDK_DISABLE_DEPRECATED
-DG_DISABLE_SINGLE_INCLUDES
- -DGTK_DISABLE_SINGLE_INCLUDES
-Wall -Wextra
-Wno-missing-field-initializers
-Wno-sign-compare
@@ -95,15 +98,24 @@ dnl -Wmissing-format-attribute
dnl -Wshadow
dnl -Wformat-nonliteral
+dnl Disabled until libunique fixes its headers. Think it's
+dnl already fixed in git, just waiting for a formal release.
+dnl -DGTK_DISABLE_SINGLE_INCLUDES
+
CFLAGS="$CFLAGS $WARNING_FLAGS"
+LDFLAGS="$LDFLAGS -Wl,--no-undefined"
AC_CANONICAL_HOST
AC_DEFINE_UNQUOTED(VERSION_COMMENT, "", [Define if you want a comment appended to the version number])
+dnl *************************************
dnl Put the ACLOCAL flags in the Makefile
+dnl *************************************
ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
+dnl ******************************
dnl Initialize maintainer mode
+dnl ******************************
AM_MAINTAINER_MODE
if test "$evo_version" != "$evo_stable_version"; then
@@ -136,7 +148,9 @@ case $YACC in
esac
AC_ARG_PROGRAM
+dnl ******************************
dnl Test whether jw is installed
+dnl ******************************
AC_PATH_PROG(JW,jw,no)
if test x$JW = xno; then
HAVE_JW="no"
@@ -146,7 +160,9 @@ fi
AM_CONDITIONAL(HAVE_JW, [test x$HAVE_JW = xyes])
AC_SUBST(HAVE_JW)
+dnl ******************************
dnl I18N stuff
+dnl ******************************
IT_PROG_INTLTOOL([0.35.5])
AM_GLIB_GNU_GETTEXT
@@ -158,10 +174,12 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Package name for gettex
localedir='$(prefix)/$(DATADIRNAME)/locale'
AC_SUBST(localedir)
-dnl Initialize libtool
+dnl ******************************
+dnl Initialize libtool \ DOLT
dnl if switch to libtool >= 2.2, replace existing with following:
dnl LT_PREREQ(2.2)
dnl LT_INIT(disable-static win32-dll)
+dnl ******************************
AM_DISABLE_STATIC
AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
@@ -169,7 +187,9 @@ DOLT
PKG_PROG_PKG_CONFIG
+dnl ******************************
dnl Win32
+dnl ******************************
AC_MSG_CHECKING([for Win32])
case "$host" in
*-mingw*)
@@ -198,6 +218,9 @@ AM_CONDITIONAL(OS_WIN32, [test $os_win32 = yes])
AC_SUBST(NO_UNDEFINED)
AC_SUBST(SOEXT)
+MATH_LIB="-lm"
+AC_SUBST(MATH_LIB)
+
if test "$os_win32" = "yes"; then
AC_CHECK_TOOL(WINDRES, windres, :)
else
@@ -208,35 +231,42 @@ AM_CONDITIONAL(HAVE_WINDRES, test "x$WINDRES" != "x:")
AC_SUBST(WINDRES)
+dnl **********************************
dnl Check for base dependencies early.
+dnl **********************************
PKG_CHECK_MODULES([GNOME_PLATFORM],
[glib-2.0 >= glib_minimum_version
- gtk+-2.0 >= gtk_minimum_version
- gconf-2.0 >= gconf_minimum_version
- libbonobo-2.0 >= libbonobo_minimum_version
- libbonoboui-2.0 >= libbonoboui_minimum_version
- libglade-2.0 >= libglade_minimum_version
- libgnomecanvas-2.0 >= libgnomecanvas_minimum_version
- libgnomeui-2.0 >= libgnomeui_minimum_version
- libxml-2.0 >= libxml_minimum_version
- shared-mime-info >= shared_mime_info_minimum_version
- gnome-desktop-2.0 >= gnome_desktop_minimum_version])
+ gtk+-2.0 >= gtk_minimum_version
+ gconf-2.0 >= gconf_minimum_version
+ libbonobo-2.0 >= libbonobo_minimum_version
+ libglade-2.0 >= libglade_minimum_version
+ libgnomecanvas-2.0 >= libgnomecanvas_minimum_version
+ libgnomeui-2.0 >= libgnomeui_minimum_version
+ libxml-2.0 >= libxml_minimum_version
+ shared-mime-info >= shared_mime_info_minimum_version
+ gnome-desktop-2.0 >= gnome_desktop_minimum_version])
AC_SUBST(GNOME_PLATFORM_CFLAGS)
AC_SUBST(GNOME_PLATFORM_LIBS)
PKG_CHECK_MODULES([EVOLUTION_DATA_SERVER],
[libebook-$EDS_PACKAGE >= eds_minimum_version
- libecal-$EDS_PACKAGE >= eds_minimum_version
- libedataserver-$EDS_PACKAGE >= eds_minimum_version
- libedataserverui-$EDS_PACKAGE >= eds_minimum_version
- libegroupwise-$EDS_PACKAGE >= eds_minimum_version
- libebackend-$EDS_PACKAGE >= eds_minimum_version
- libgdata-$EDS_PACKAGE >= eds_minimum_version
- libgdata-google-$EDS_PACKAGE >= eds_minimum_version])
+ libecal-$EDS_PACKAGE >= eds_minimum_version
+ libedataserver-$EDS_PACKAGE >= eds_minimum_version
+ libedataserverui-$EDS_PACKAGE >= eds_minimum_version
+ libegroupwise-$EDS_PACKAGE >= eds_minimum_version
+ libebackend-$EDS_PACKAGE >= eds_minimum_version
+ libgdata-$EDS_PACKAGE >= eds_minimum_version
+ libgdata-google-$EDS_PACKAGE >= eds_minimum_version])
+dnl ******************************
+dnl Canberra / Canberra-GTK Sound
+dnl ******************************
+PKG_CHECK_MODULES([CANBERRA],[libcanberra-gtk])
+AC_SUBST(CANBERRA_CFLAGS)
+AC_SUBST(CANBERRA_LIBS)
dnl ******************
-dnl User documentation
+dnl User Documentation
dnl ******************
AC_MSG_CHECKING([whether to build user documentation])
AC_ARG_WITH([help],
@@ -319,6 +349,7 @@ if test "$have_iconv" = no; then
fi
AC_SUBST(ICONV_LIBS)
+save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -I$srcdir"
AC_MSG_CHECKING([preferred charset name formats for system iconv])
@@ -356,15 +387,19 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
+dnl ***********
dnl alloca()
+dnl ***********
AC_FUNC_ALLOCA
+dnl **************
dnl waitpid() etc
+dnl **************
AC_HEADER_SYS_WAIT
-dnl
+dnl ***************
dnl Purify support
-dnl
+dnl ***************
EVO_PURIFY_SUPPORT
dnl **************
@@ -519,19 +554,19 @@ AC_CHECK_HEADER([sys/mount.h],
AC_CHECK_FUNCS(statfs)
dnl **************************************************
-dnl * Gnome Icon Theme
+dnl Gnome Icon Theme
dnl **************************************************
PKG_CHECK_MODULES([GIT], [gnome-icon-theme >= gnome_icon_theme_minimum_version])
dnl **************************************************
-dnl * Accessibility support
+dnl Accessibility support
dnl **************************************************
PKG_CHECK_MODULES([A11Y], [atk])
AC_SUBST(A11Y_CFLAGS)
AC_SUBST(A11Y_LIBS)
dnl **************************************************
-dnl * XF86 multimedia keys support
+dnl XF86 multimedia keys support
dnl **************************************************
have_xfree=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
@@ -548,40 +583,40 @@ dnl **************************************************
dnl LDAP support.
dnl **************************************************
if test "$os_win32" != yes; then
-EVO_LDAP_CHECK(no)
-case $with_openldap in
-no)
- msg_ldap=no
- ;;
-*)
- case $with_static_ldap in
- yes)
- msg_ldap="yes (static)"
+ EVO_LDAP_CHECK(no)
+ case $with_openldap in
+ no)
+ msg_ldap=no
;;
*)
- msg_ldap="yes (dynamic)"
+ case $with_static_ldap in
+ yes)
+ msg_ldap="yes (static)"
;;
+ *)
+ msg_ldap="yes (dynamic)"
+ ;;
+ esac
esac
-esac
-SAVE_CFLAGS="$CFLAGS"
-SAVE_LIBS="$LIBS"
-LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_DEPRECATED"
-CFLAGS="$CFLAGS $LDAP_CFLAGS"
-LIBS="$LIBS $LDAP_LIBS"
-AC_CHECK_FUNCS(ldap_ntlm_bind)
-CFLAGS="$SAVE_CFLAGS"
-LIBS="$SAVE_LIBS"
-
-else dnl Win32
-LDAP_CFLAGS="-DLDAP_DEPRECATED"
-LDAP_LIBS="-lwldap32"
-AC_SUBST(LDAP_CFLAGS)
-AC_SUBST(LDAP_LIBS)
-AC_DEFINE(HAVE_LDAP,1,[Define if you have LDAP support])
-AM_CONDITIONAL(ENABLE_LDAP, true)
-msg_ldap="yes"
-fi dnl Win32
+ SAVE_CFLAGS="$CFLAGS"
+ SAVE_LIBS="$LIBS"
+ LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_DEPRECATED"
+ CFLAGS="$CFLAGS $LDAP_CFLAGS"
+ LIBS="$LIBS $LDAP_LIBS"
+ AC_CHECK_FUNCS(ldap_ntlm_bind)
+ CFLAGS="$SAVE_CFLAGS"
+ LIBS="$SAVE_LIBS"
+dnl Win32 support
+else
+ LDAP_CFLAGS="-DLDAP_DEPRECATED"
+ LDAP_LIBS="-lwldap32"
+ AC_SUBST(LDAP_CFLAGS)
+ AC_SUBST(LDAP_LIBS)
+ AC_DEFINE(HAVE_LDAP,1,[Define if you have LDAP support])
+ AM_CONDITIONAL(ENABLE_LDAP, true)
+ msg_ldap="yes"
+fi
dnl **************************************************
dnl SunLDAP support, but if OpenLDAP support, skip check SunLDAP.
@@ -625,7 +660,7 @@ AM_CONDITIONAL(ENABLE_NNTP, [test x$enable_nntp = xyes])
AC_DEFINE(HANDLE_LIBICAL_MEMORY, 1, [Define it once memory returned by libical is free'ed properly])
dnl **************************************************
-dnl * Posix thread support
+dnl Posix thread support
dnl **************************************************
dnl GLIB_CONFIG=${GLIB_CONFIG-glib-config}
@@ -650,17 +685,19 @@ AC_SUBST(THREADS_CFLAGS)
AC_DEFINE(ENABLE_THREADS,1,[Required])
-dnl *********
-dnl Libraries
-dnl *********
-
+dnl ************
+dnl regex check
+dnl ************
AC_CHECK_FUNCS(regexec,,[AC_CHECK_LIB(regex,regexec,
[REGEX_LIBS=-lregex
AC_DEFINE(HAVE_REGEXEC,1,[Define to 1 if you have the regexec function.])],
[AC_MSG_ERROR([No regex library found])])])
AC_SUBST(REGEX_LIBS)
+dnl *************************
+dnl GTKHTML check
dnl XXX Drop the version from the package name?
+dnl *************************
PKG_CHECK_MODULES([GTKHTML], [libgtkhtml-3.14 >= libgtkhtml_minimum_version])
AC_SUBST(GTKHTML_CFLAGS)
AC_SUBST(GTKHTML_LIBS)
@@ -759,29 +796,32 @@ AC_ARG_WITH([krb4-includes],
[Location of Kerberos 4 headers]),
[with_krb4_includes=$withval],[with_krb4_includes=""])
+dnl ************
+dnl Kerberos 5
+dnl ************
msg_krb5="no"
if test "x${with_krb5}" != "xno"; then
- LDFLAGS_save="$LDFLAGS"
+ LIBS_save="$LIBS"
mitlibs="-lkrb5 -lk5crypto -lcom_err -lgssapi_krb5"
heimlibs="-lkrb5 -lcrypto -lasn1 -lcom_err -lroken -lgssapi"
sunlibs="-lkrb5 -lgss"
AC_CACHE_CHECK([for Kerberos 5], [ac_cv_lib_kerberos5],
[
- LDFLAGS="$LDFLAGS -L$with_krb5_libs $mitlibs"
- AC_LINK_IFELSE([AC_LANG_CALL([], [krb5_init_context,])],
+ LIBS="$LIBS -L$with_krb5_libs $mitlibs"
+ AC_LINK_IFELSE([AC_LANG_CALL([], [krb5_init_context])],
[ac_cv_lib_kerberos5="$mitlibs"],
[
- LDFLAGS="$LDFLAGS_save -L$with_krb5_libs $heimlibs"
+ LIBS="$LIBS_save -L$with_krb5_libs $heimlibs"
AC_LINK_IFELSE([AC_LANG_CALL([], [krb5_init_context])],
[ac_cv_lib_kerberos5="$heimlibs"],
[
- LDFLAGS="$LDFLAGS_save -L$with_krb5_libs $sunlibs"
+ LIBS="$LIBS_save -L$with_krb5_libs $sunlibs"
AC_LINK_IFELSE([AC_LANG_CALL([], [krb5_init_context])],
[ac_cv_lib_kerberos5="$sunlibs"], [ac_cv_lib_kerberos5="no"])
])
])
- LDFLAGS="$LDFLAGS_save"
+ LIBS="$LIBS_save"
])
if test "$ac_cv_lib_kerberos5" != "no"; then
AC_DEFINE(HAVE_KRB5,1,[Define if you have Krb5])
@@ -832,38 +872,40 @@ AC_CHECK_HEADER([com_err.h],
#endif
]])
+dnl ***********
+dnl Kerberos 4
+dnl ***********
msg_krb4="no"
if test "x${with_krb4}" != "xno"; then
- LDFLAGS_save="$LDFLAGS"
+ LIBS_save="$LIBS"
AC_CACHE_CHECK([for Kerberos 4], [ac_cv_lib_kerberos4],
[
ac_cv_lib_kerberos4="no"
-
mitcompatlibs="-lkrb4 -ldes425 -lkrb5 -lk5crypto -lcom_err"
dnl Look for MIT krb5 compat krb4
- LDFLAGS="$LDFLAGS -L$with_krb4_libs $mitcompatlibs"
+ LIBS="$LIBS_save -L$with_krb4_libs $mitcompatlibs"
AC_LINK_IFELSE([AC_LANG_CALL([], [krb_mk_req])],
[ac_cv_lib_kerberos4="$mitcompatlibs"])
if test "$ac_cv_lib_kerberos4" = "no"; then
dnl Look for KTH krb4
- LDFLAGS="$LDFLAGS_save -L$with_krb4_libs -lkrb -lcrypto -lcom_err -lroken"
+ LIBS="$LIBS_save -L$with_krb4_libs -lkrb -lcrypto -lcom_err -lroken"
AC_LINK_IFELSE([AC_LANG_CALL([], [krb_mk_req])],
[ac_cv_lib_kerberos4="-lkrb -lcrypto -lcom_err -lroken"])
fi
if test "$ac_cv_lib_kerberos4" = "no"; then
dnl Look for old MIT krb4
- LDFLAGS="$LDFLAGS_save -L$with_krb4_libs -lkrb"
+ LIBS="$LIBS_save -L$with_krb4_libs -lkrb"
AC_LINK_IFELSE([AC_LANG_CALL([], [krb_mk_req])],
[ac_cv_lib_kerberos4="-lkrb"],
[
- LDFLAGS="$LDFLAGS -ldes"
+ LIBS="$LIBS_save -ldes"
AC_LINK_IFELSE([AC_LANG_CALL([], [krb_mk_req])],
[ac_cv_lib_kerberos4="-lkrb -ldes"])
])
fi
])
- LDFLAGS="$LDFLAGS_save"
+ LIBS="$LIBS_save"
if test "$ac_cv_lib_kerberos4" != "no"; then
AC_DEFINE(HAVE_KRB4,1,[Define if you have Krb4])
msg_krb4="yes"
@@ -899,10 +941,10 @@ AC_SUBST(KRB5_LIBS)
AC_SUBST(KRB4_CFLAGS)
AC_SUBST(KRB4_LIBS)
+dnl ******************************
dnl Mono hooks
-dnl This should just define mono CFLAGS etc here, it is used later to
-dnl turn on the mono plugin or not.
-
+dnl This should just define mono CFLAGS etc here, it is used later to turn on the mono plugin or not.
+dnl ******************************
MONO_CFLAGS=
MONO_LIBS=
AC_ARG_ENABLE([mono],
@@ -912,15 +954,17 @@ AC_ARG_ENABLE([mono],
if test "x${enable_mono}" = "xyes"; then
PKG_CHECK_MODULES([MONO], ["mono"])
AC_DEFINE(ENABLE_MONO,1,[Define if Mono embedding should be enabled])
- MONO_PLUGIN="mono"
fi
AC_SUBST(MONO_CFLAGS)
AC_SUBST(MONO_LIBS)
+AM_CONDITIONAL(ENABLE_MONO, [test "x$enable_mono" = "xyes"])
+
+dnl ******************************
dnl Python hooks
-dnl This should just define python CFLAGS etc here, it is used later to
-dnl turn on the python plugin or not.
+dnl This should just define python CFLAGS etc here, it is used later to turn on the python plugin or not.
dnl (Thanks to Pidgin)
+dnl ******************************
AC_ARG_ENABLE([python],
AS_HELP_STRING([--enable-python],
@@ -939,23 +983,23 @@ if test "x${enable_python}" = "xyes"; then
changequote([, ])dnl
if test -f $PY_PREFIX/include/python$PY_VERSION/Python.h -a "$PY_MAJOR" = "2."; then
- PY_LIBS="-lpython$PY_VERSION -L$PY_EXEC_PREFIX/lib/python$PY_VERSION/config"
+ PY_LIBS="-lpython$PY_VERSION -L$PY_EXEC_PREFIX/lib/python$PY_VERSION/config"
PY_INCLUDES="-I$PY_PREFIX/include/python$PY_VERSION"
AC_MSG_RESULT([ok])
python_package="python-devel"
- PYTHON_PLUGIN="python"
else
AC_MSG_ERROR([Can't find Python.h])
PY_LIBS=""
PY_INCLUDES=""
python_package=""
- PYTHON_PLUGIN=""
fi
fi
AC_SUBST(PY_LIBS)
AC_SUBST(PY_INCLUDES)
fi
+AM_CONDITIONAL(ENABLE_PYTHON, [test "x$enable_python" = "xyes"])
+
dnl ********************************************************************************
dnl security extension support (SSL and S/MIME)
@@ -1091,22 +1135,22 @@ if test "x${enable_nss}" = "xyes" || test "x${enable_nss}" = "xstatic"; then
AC_CACHE_CHECK([for Mozilla nspr libraries], [ac_cv_moz_nspr_libs],
[
- LIBS_save="$LIBS"
+ LIBS_save="$LIBS"
CFLAGS="$CFLAGS $MANUAL_NSPR_CFLAGS"
if test "x${with_nspr_libs}" != "x"; then
- LIBS="$nsprlibs"
- LDFLAGS="$LDFLAGS -L$with_nspr_libs"
+ LIBS="$nsprlibs"
+ LDFLAGS="$LDFLAGS -L$with_nspr_libs"
else
- LIBS="$nsprlibs"
- LDFLAGS="$LDFLAGS"
+ LIBS="$nsprlibs"
+ LDFLAGS="$LDFLAGS"
fi
AC_LINK_IFELSE([AC_LANG_CALL([], [PR_Init])],
[ac_cv_moz_nspr_libs="yes"], [ac_cv_moz_nspr_libs="no"])
CFLAGS="$CFLAGS_save"
LDFLAGS="$LDFLAGS_save"
- LIBS="$LIBS_save"
+ LIBS="$LIBS_save"
])
if test "x$ac_cv_moz_nspr_libs" != "xno"; then
have_nspr_libs="yes"
@@ -1160,7 +1204,7 @@ if test "x${enable_nss}" = "xyes" || test "x${enable_nss}" = "xstatic"; then
LDFLAGS_save="$LDFLAGS"
if test "$enable_nss" = "static"; then
- if test -z "${with_nss_libs}"; then
+ if test -z "${with_nss_libs}"; then
AC_MSG_ERROR([Static linkage requested, but path to nss libraries not set.]
[Please specify the path to libnss3.a]
[Example: --with-nspr-libs=/usr/lib/mozilla])
@@ -1173,14 +1217,14 @@ if test "x${enable_nss}" = "xyes" || test "x${enable_nss}" = "xstatic"; then
esac
fi
else
- nsslibs="-lssl3 -lsmime3 -lnss3"
+ nsslibs="-lssl3 -lsmime3 -lnss3"
fi
AC_CACHE_CHECK([for Mozilla nss libraries], [ac_cv_moz_nss_libs],
[
- LIBS_save="$LIBS"
+ LIBS_save="$LIBS"
LDFLAGS="$LDFLAGS -L$with_nspr_libs $nsprlibs -L$with_nss_libs $nsslibs"
- LIBS="$nsslibs $nsprlibs"
+ LIBS="$nsslibs $nsprlibs"
AC_LINK_IFELSE([AC_LANG_CALL([], [NSS_Init])],
[ac_cv_moz_nss_libs="yes"], [ac_cv_moz_nss_libs="no"])
if test "$ac_cv_moz_nss_libs" = no; then
@@ -1190,7 +1234,7 @@ if test "x${enable_nss}" = "xyes" || test "x${enable_nss}" = "xstatic"; then
[ac_cv_moz_nss_libs="yes"], [ac_cv_moz_nss_libs="no"])
fi
LDFLAGS="$LDFLAGS_save"
- LIBS="$LIBS_save"
+ LIBS="$LIBS_save"
])
if test "$ac_cv_moz_nss_libs" != no; then
AC_DEFINE(HAVE_NSS)
@@ -1198,7 +1242,7 @@ if test "x${enable_nss}" = "xyes" || test "x${enable_nss}" = "xstatic"; then
AC_DEFINE_UNQUOTED(MOZILLA_NSS_LIB_DIR,"$with_nss_libs", [Define to the full path of mozilla nss library])
if test "$enable_nss" = "static"; then
msg_ssl="yes (Mozilla NSS:static)"
- else
+ else
msg_ssl="yes (Mozilla NSS)"
fi
dnl static_nss
@@ -1334,7 +1378,9 @@ AC_COMPILE_IFELSE([
CFLAGS="$evolution_save_cflags"
-
+dnl *************************
+dnl Orbit / Bonobo
+dnl *************************
AM_PATH_ORBIT2(2.9.8)
AC_MSG_CHECKING([for CORBA include paths])
@@ -1342,22 +1388,21 @@ IDL_INCLUDES="-I "`${PKG_CONFIG} --variable=idldir libbonobo-2.0`" -I "`${PKG_CO
AC_MSG_RESULT([$IDL_INCLUDES])
AC_SUBST(IDL_INCLUDES)
+dnl *****************************************************************
dnl Utility macro to set compiler flags for a specific lib.
dnl EVO_SET_COMPILE_FLAGS(VAR-PREFIX, DEPS, EXTRA-CFLAGS, EXTRA-LIBS)
+dnl *****************************************************************
AC_DEFUN([EVO_SET_COMPILE_FLAGS], [
PKG_CHECK_MODULES([$1], [$2])
- $1_CFLAGS="[$]$1_CFLAGS \$(WERROR) $3"
+ $1_CFLAGS="[$]$1_CFLAGS $3"
$1_LIBS="[$]$1_LIBS $4"
])
-dnl --- Required version numbers
-
-BONOBOUI_REQUIRED=libbonoboui_minimum_version
-AC_SUBST(BONOBOUI_REQUIRED)
+dnl ********************************
+dnl Flags to get all the GNOME stuff
+dnl ********************************
-dnl --- Flags to get all the GNOME stuff
-
-FULL_GNOME_DEPS="libbonoboui-2.0 gconf-2.0 gthread-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0"
+FULL_GNOME_DEPS="gconf-2.0 gthread-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0"
PKG_CHECK_MODULES([HAL], [hal >= hal_minimum_version], [HAVE_HAL="yes"], [HAVE_HAL="no"])
if test "x$HAVE_HAL" = "xyes"; then
@@ -1369,6 +1414,9 @@ else
IPOD_SYNC=""
fi
+dnl ******************************
+dnl TNEF implementation
+dnl ******************************
AC_MSG_CHECKING([for yTNEF])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
@@ -1401,7 +1449,9 @@ else
fi
AC_SUBST(TNEF_CFLAGS)
+dnl ******************************
dnl Check for dbus-glib-1 and dbus
+dnl ******************************
AC_ARG_ENABLE([dbus],
[AS_HELP_STRING([--enable-dbus],
[enable DBUS support (default=yes)])],
@@ -1427,7 +1477,9 @@ else
fi
AM_CONDITIONAL([DBUS_SUPPORT], [test "$DBUS_SUPPORT" = yes])
+dnl ******************************
dnl Check for NetworkManager
+dnl ******************************
AC_ARG_ENABLE([nm],
[AS_HELP_STRING([--enable-nm],
[enable NetworkManager support (default=yes)])],
@@ -1448,8 +1500,9 @@ fi
AM_CONDITIONAL([NM_SUPPORT], [test "$NM_SUPPORT" = yes])
-dnl --- Flags for the various libraries we build
-
+dnl ******************************
+dnl Camel Flags
+dnl ******************************
EVO_SET_COMPILE_FLAGS(CAMEL, camel-provider-$EDS_PACKAGE)
AC_SUBST(CAMEL_CFLAGS)
AC_SUBST(CAMEL_LIBS)
@@ -1467,16 +1520,16 @@ else
fi
fi
-EVO_SET_COMPILE_FLAGS(CERT_UI, libedataserverui-$EDS_PACKAGE libglade-2.0 gthread-2.0, $MANUAL_NSS_CFLAGS $MOZILLA_NSS_CFLAGS, $MOZILLA_L_DIR $MANUAL_NSS_LIBS $MOZILLA_NSS_LIBS)
+dnl ******************************
+dnl CERT_UI Flags
+dnl ******************************
+EVO_SET_COMPILE_FLAGS(CERT_UI, libedataserverui-$EDS_PACKAGE libglade-2.0 gthread-2.0, $MANUAL_NSS_CFLAGS $MOZILLA_NSS_CFLAGS, $MOZILLA_L_DIR $MANUAL_NSS_LIBS $MOZILLA_NSS_LIBS)
AC_SUBST(CERT_UI_CFLAGS)
AC_SUBST(CERT_UI_LIBS)
-EVO_SET_COMPILE_FLAGS(E_NAME, libgnomeui-2.0 libbonoboui-2.0)
-AC_SUBST(E_NAME_CFLAGS)
-AC_SUBST(E_NAME_LIBS)
-
-dnl If Gtk/Gdk is built against X11, e-util uses some
-dnl X11-specific code so link with X11.
+dnl ******************************
+dnl If Gtk/Gdk is built against X11, e-util uses some X11-specific code so link with X11.
+dnl ******************************
if test "x$GDK_BACKEND_X11" = "xyes"; then
E_UTIL_X11_CFLAGS="$X_CFLAGS"
E_UTIL_X11_LIBS="$X_LIBS"
@@ -1484,36 +1537,56 @@ else
E_UTIL_X11_CFLAGS=""
E_UTIL_X11_LIBS=""
fi
-EVO_SET_COMPILE_FLAGS(E_UTIL, libbonoboui-2.0 libglade-2.0 libgnomeui-2.0 gnome-desktop-2.0 libedataserver-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE $mozilla_nspr, $THREADS_CFLAGS $MANUAL_NSPR_CFLAGS $E_UTIL_X11_CFLAGS, $THREADS_LIBS $MANUAL_NSPR_LIBS $E_UTIL_X11_LIBS)
+
+dnl ************
+dnl E_UTIL Flags
+dnl ************
+EVO_SET_COMPILE_FLAGS(E_UTIL, libglade-2.0 libgnomeui-2.0 gnome-desktop-2.0 libedataserver-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE $mozilla_nspr, $THREADS_CFLAGS $MANUAL_NSPR_CFLAGS $E_UTIL_X11_CFLAGS, $THREADS_LIBS $MANUAL_NSPR_LIBS $E_UTIL_X11_LIBS)
AC_SUBST(E_UTIL_CFLAGS)
AC_SUBST(E_UTIL_LIBS)
+E_UTIL_LIBS="$E_UTIL_LIBS $MATH_LIB"
+
+dnl **************
+dnl TZDIALOG Flags
+dnl **************
EVO_SET_COMPILE_FLAGS(TZDIALOG, libecal-$EDS_PACKAGE, $GNOME_PLATFORM_CFLAGS, $GNOME_PLATFORM_LIBS)
AC_SUBST(TZDIALOG_CFLAGS)
AC_SUBST(TZDIALOG_LIBS)
-EVO_SET_COMPILE_FLAGS(E_WIDGETS, libbonoboui-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0 libedataserverui-$EDS_PACKAGE libedataserver-$EDS_PACKAGE)
+dnl ***************
+dnl E_WIDGETS Flags
+dnl ***************
+EVO_SET_COMPILE_FLAGS(E_WIDGETS, gio-2.0 gconf-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0 libedataserverui-$EDS_PACKAGE libedataserver-$EDS_PACKAGE gtkhtml-editor)
AC_SUBST(E_WIDGETS_CFLAGS)
AC_SUBST(E_WIDGETS_LIBS)
-EVO_SET_COMPILE_FLAGS(IMPORTERS, libedataserverui-$EDS_PACKAGE camel-provider-$EDS_PACKAGE camel-$EDS_PACKAGE libglade-2.0 libbonoboui-2.0 libgnomeui-2.0 libebook-$EDS_PACKAGE)
+dnl ***************
+dnl IMPORTERS Flags
+dnl ***************
+EVO_SET_COMPILE_FLAGS(IMPORTERS, libedataserverui-$EDS_PACKAGE camel-provider-$EDS_PACKAGE camel-$EDS_PACKAGE libglade-2.0 libgnomeui-2.0 libebook-$EDS_PACKAGE)
AC_SUBST(IMPORTERS_CFLAGS)
AC_SUBST(IMPORTERS_LIBS)
+dnl ***************
+dnl LIBFILTER Flags
+dnl ***************
EVO_SET_COMPILE_FLAGS(LIBFILTER, libgnomeui-2.0 libglade-2.0 libedataserver-$EDS_PACKAGE)
AC_SUBST(LIBFILTER_CFLAGS)
AC_SUBST(LIBFILTER_LIBS)
-dnl --- evolution (shell) flags
-EVO_SET_COMPILE_FLAGS(SHELL, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE)
+dnl ***********
+dnl Shell Flags
+dnl ***********
+EVO_SET_COMPILE_FLAGS(SHELL, libgnomeui-2.0 gnome-desktop-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE unique-1.0 libedataserverui-$EDS_PACKAGE)
AC_SUBST(SHELL_CFLAGS)
AC_SUBST(SHELL_LIBS)
-dnl --- evolution-addressbook flags
-
-EVOLUTION_ADDRESSBOOK_DEPS="libbonoboui-2.0 libglade-2.0 libgnomeui-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE gtkhtml-editor"
-
+dnl *****************
+dnl Addressbook Flags
+dnl *****************
+EVOLUTION_ADDRESSBOOK_DEPS="libglade-2.0 libgnomeui-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE gtkhtml-editor unique-1.0"
EVO_SET_COMPILE_FLAGS(EVOLUTION_ADDRESSBOOK, $EVOLUTION_ADDRESSBOOK_DEPS)
AC_SUBST(EVOLUTION_ADDRESSBOOK_CFLAGS)
AC_SUBST(EVOLUTION_ADDRESSBOOK_LIBS)
@@ -1524,6 +1597,9 @@ AC_SUBST(EVOLUTION_ADDRESSBOOK_CONDUIT_CFLAGS)
AC_SUBST(EVOLUTION_ADDRESSBOOK_CONDUIT_LIBS)
fi
+dnl ***************
+dnl Libnotify Flags
+dnl ***************
LIBNOTIFY_CFLAGS=
LIBNOTIFY_LIBS=
PKG_CHECK_MODULES([LIBNOTIFY], [libnotify >= libnotify_minimum_version], [HAVE_LIBNOTIFY="yes"], [HAVE_LIBNOTIFY="no"])
@@ -1536,12 +1612,14 @@ fi
AC_SUBST(LIBNOTIFY_CFLAGS)
AC_SUBST(LIBNOTIFY_LIBS)
-dnl --- evolution-calendar flags
+dnl **************
+dnl Calendar Flags
+dnl **************
EVO_SET_COMPILE_FLAGS(LIBSOUP, libsoup-2.4 >= 2.3.0)
AC_SUBST(LIBSOUP_CFLAGS)
AC_SUBST(LIBSOUP_LIBS)
-EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libecal-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE libebackend-$EDS_PACKAGE $HAL_REQUIREMENT $libnotify gtkhtml-editor libgdata-$EDS_PACKAGE libgdata-google-$EDS_PACKAGE)
+EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, libgnomeui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libecal-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE libebackend-$EDS_PACKAGE $HAL_REQUIREMENT $libnotify gtkhtml-editor libgdata-$EDS_PACKAGE libgdata-google-$EDS_PACKAGE unique-1.0)
AC_SUBST(EVOLUTION_CALENDAR_CFLAGS)
AC_SUBST(EVOLUTION_CALENDAR_LIBS)
@@ -1551,14 +1629,16 @@ AC_SUBST(EVOLUTION_CALENDAR_CONDUIT_CFLAGS)
AC_SUBST(EVOLUTION_CALENDAR_CONDUIT_LIBS)
fi
-dnl --- evolution-mail flags
-
-EVO_SET_COMPILE_FLAGS(EVOLUTION_MAIL, camel-provider-$EDS_PACKAGE libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE gtkhtml-editor bonobo-activation-2.0 $mozilla_nss libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE)
+dnl **********
+dnl Mail Flags
+dnl **********
+EVO_SET_COMPILE_FLAGS(EVOLUTION_MAIL, camel-provider-$EDS_PACKAGE libgnomeui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE gtkhtml-editor bonobo-activation-2.0 $mozilla_nss libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE unique-1.0)
AC_SUBST(EVOLUTION_MAIL_CFLAGS)
AC_SUBST(EVOLUTION_MAIL_LIBS)
-dnl -- evolution-data-server IDL and version
-
+dnl ***************************
+dnl Evolution-Data-Server Flags
+dnl ***************************
AC_DEFINE(DATASERVER_API_VERSION, "1.2", evolution-data-server API version)
AC_DEFINE_UNQUOTED(DATASERVER_VERSION, "`${PKG_CONFIG} --modversion evolution-data-server-1.2`", evolution-data-server version)
@@ -1574,19 +1654,26 @@ else
AC_MSG_ERROR([no])
fi
-dnl --- evolution-test flags
-
-EVO_SET_COMPILE_FLAGS(EVOLUTION_TEST, libgnomeui-2.0 libbonoboui-2.0)
+dnl **********
+dnl Test Flags
+dnl **********
+EVO_SET_COMPILE_FLAGS(EVOLUTION_TEST, gtk+-2.0 gconf-2.0 libxml-2.0 unique-1.0)
AC_SUBST(EVOLUTION_TEST_CFLAGS)
AC_SUBST(EVOLUTION_TEST_LIBS)
+dnl *****************
+dnl EggSMClient Flags
+dnl *****************
+EVO_SET_COMPILE_FLAGS(EGG_SMCLIENT, gtk+-2.0)
+AC_SUBST(EGG_SMCLIENT_CFLAGS)
+AC_SUBST(EGG_SMCLIENT_LIBS)
+
dnl *******************
dnl Special directories
dnl *******************
-dnl --- If you add something here, consider whether or not you also
-dnl --- need to add it to one or more .pc.in files (for Connector,
-dnl --- etc)
+dnl If you add something here, consider whether or not you also need to add it to one or more .pc.in
+dnl files (for Connector, etc)
privlibdir='${libdir}'/evolution/$BASE_VERSION
AC_SUBST(privlibdir)
@@ -1603,6 +1690,9 @@ AC_SUBST(privincludedir)
componentdir="$privlibdir/components"
AC_SUBST(componentdir)
+moduledir="$privlibdir/modules"
+AC_SUBST(moduledir)
+
idldir='${datadir}'/idl/evolution-$BASE_VERSION
AC_SUBST(idldir)
@@ -1702,20 +1792,32 @@ AC_ARG_ENABLE([plugins],
[enable_plugins="$enableval"],[enable_plugins=all])
dnl Add any new plugins here
-plugins_base_always="calendar-file calendar-http $CALENDAR_WEATHER itip-formatter plugin-manager default-source addressbook-file startup-wizard mark-all-read groupwise-features groupwise-account-setup mail-account-disable publish-calendar caldav imap-features google-account-setup webdav-account-setup"
+plugins_base_always="calendar-file calendar-http $CALENDAR_WEATHER itip-formatter plugin-manager default-source addressbook-file startup-wizard mark-all-read groupwise-features groupwise-account-setup publish-calendar caldav imap-features google-account-setup webdav-account-setup"
-plugins_base="$plugins_base_always $SA_JUNK_PLUGIN $BF_JUNK_PLUGIN $EXCHANGE_PLUGIN $MONO_PLUGIN "
-all_plugins_base="$plugins_base_always sa-junk-plugin bogo-junk-plugin exchange-operations mono"
+plugins_base="$plugins_base_always $SA_JUNK_PLUGIN $BF_JUNK_PLUGIN $EXCHANGE_PLUGIN"
+all_plugins_base="$plugins_base_always sa-junk-plugin bogo-junk-plugin exchange-operations"
-plugins_standard_always="bbdb subject-thread save-calendar select-one-source copy-tool mail-to-task audio-inline mailing-list-actions default-mailer prefer-plain mail-notification attachment-reminder backup-restore email-custom-header templates pst-import vcard-inline"
+plugins_standard_always="bbdb subject-thread save-calendar mail-to-task audio-inline mailing-list-actions default-mailer prefer-plain mail-notification attachment-reminder backup-restore email-custom-header templates pst-import vcard-inline"
plugins_standard="$plugins_standard_always"
all_plugins_standard="$plugins_standard"
-plugins_experimental_always="face folder-unsubscribe external-editor hula-account-setup"
-plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS $PYTHON_PLUGIN"
+plugins_experimental_always="face external-editor hula-account-setup"
+plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS"
all_plugins_experimental="$plugins_experimental_always ipod-sync tnef-attachments"
+dnl Temporary KILL-BONOBO hack
+enable_plugins="attachment-reminder addressbook-file audio-inline backup-restore bbdb bogo-junk-plugin caldav calendar-file calendar-http calendar-weather default-mailer default-source email-custom-header external-editor face google-account-setup hula-account-setup imap-features itip-formatter mail-notification mail-to-task mark-all-read plugin-manager prefer-plain profiler pst-import sa-junk-plugin startup-wizard subject-thread templates $TNEF_ATTACHMENTS vcard-inline webdav-account-setup"
+
+dnl PLUGINS NOT BUILDING YET
+dnl ------------------------
+dnl exchange-operations
+dnl groupwise-features
+dnl ipod-sync
+dnl mailing-list-actions
+dnl publish-calendar
+dnl save-calendar
+
case x"$enable_plugins" in
xno)
plugins_enabled=""
@@ -1739,6 +1841,9 @@ xexperimental)
;;
esac
+dnl ******************************
+dnl Profiling support
+dnl ******************************
AC_ARG_ENABLE([profiling],
AS_HELP_STRING([--enable-profiling],
[Enable profiling plugin.]),
@@ -1752,17 +1857,6 @@ x | xyes)
;;
esac
-if test "x${enable_mono}" = "xyes"; then
- plugins_enabled="$plugins_enabled mono"
- msg_plugins="$msg_plugins (and mono)"
-fi
-
-
-if test "x${enable_python}" = "xyes"; then
- plugins_enabled="$plugins_enabled python"
- msg_plugins="$msg_plugins (and python)"
-fi
-
AC_SUBST(plugins_enabled)
AC_SUBST(all_plugins_base)
AC_SUBST(all_plugins_standard)
@@ -1791,7 +1885,7 @@ if echo ${plugins_enabled} | grep "exchange-operations" > /dev/null ; then
dnl **************************************************
dnl * Exchange Operations plugin
dnl **************************************************
- EVO_SET_COMPILE_FLAGS(CAMEL_EXCHANGE, libbonoboui-2.0 libglade-2.0 gconf-2.0 camel-provider-$EDS_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE libexchange-storage-$EDS_PACKAGE libecal-$EDS_PACKAGE)
+ EVO_SET_COMPILE_FLAGS(CAMEL_EXCHANGE, libglade-2.0 gconf-2.0 camel-provider-$EDS_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE libexchange-storage-$EDS_PACKAGE libecal-$EDS_PACKAGE)
AC_SUBST(CAMEL_EXCHANGE_CFLAGS)
AC_SUBST(CAMEL_EXCHANGE_LIBS)
else
@@ -1874,15 +1968,9 @@ AC_CONFIG_FILES([ po/Makefile.in
Makefile
win32/Makefile
a11y/Makefile
-a11y/addressbook/Makefile
-a11y/calendar/Makefile
-a11y/widgets/Makefile
-a11y/e-table/Makefile
-a11y/e-text/Makefile
addressbook/Makefile
addressbook/conduit/Makefile
addressbook/gui/Makefile
-addressbook/gui/component/Makefile
addressbook/gui/contact-editor/Makefile
addressbook/gui/contact-list-editor/Makefile
addressbook/gui/merging/Makefile
@@ -1895,7 +1983,11 @@ addressbook/util/Makefile
art/Makefile
data/Makefile
data/icons/Makefile
+doc/Makefile
+doc/reference/Makefile
+doc/reference/shell/Makefile
e-util/Makefile
+em-format/Makefile
filter/Makefile
help/Makefile
help/quickref/Makefile
@@ -1941,6 +2033,7 @@ calendar/gui/Makefile
calendar/gui/alarm-notify/Makefile
calendar/gui/dialogs/Makefile
composer/Makefile
+m4/Makefile
mail/Makefile
mail/default/Makefile
mail/default/C/Makefile
@@ -1964,6 +2057,13 @@ mail/default/sr@latin/Makefile
mail/default/sv/Makefile
mail/default/hu/Makefile
mail/importers/Makefile
+modules/Makefile
+modules/addressbook/Makefile
+modules/calendar/Makefile
+modules/mail/Makefile
+modules/plugin-lib/Makefile
+modules/plugin-mono/Makefile
+modules/plugin-python/Makefile
plugins/Makefile
plugins/addressbook-file/Makefile
plugins/attachment-reminder/Makefile
@@ -1975,14 +2075,12 @@ plugins/caldav/Makefile
plugins/calendar-file/Makefile
plugins/calendar-http/Makefile
plugins/calendar-weather/Makefile
-plugins/copy-tool/Makefile
plugins/default-mailer/Makefile
plugins/default-source/Makefile
plugins/email-custom-header/Makefile
plugins/exchange-operations/Makefile
plugins/external-editor/Makefile
plugins/face/Makefile
-plugins/folder-unsubscribe/Makefile
plugins/google-account-setup/Makefile
plugins/groupwise-account-setup/Makefile
plugins/groupwise-features/Makefile
@@ -1990,27 +2088,24 @@ plugins/hula-account-setup/Makefile
plugins/imap-features/Makefile
plugins/ipod-sync/Makefile
plugins/itip-formatter/Makefile
-plugins/mail-account-disable/Makefile
plugins/mail-notification/Makefile
plugins/mail-to-task/Makefile
plugins/mailing-list-actions/Makefile
plugins/mark-all-read/Makefile
-plugins/mono/Makefile
plugins/plugin-manager/Makefile
plugins/prefer-plain/Makefile
plugins/profiler/Makefile
plugins/pst-import/Makefile
plugins/publish-calendar/Makefile
-plugins/python/Makefile
plugins/sa-junk-plugin/Makefile
plugins/save-calendar/Makefile
-plugins/select-one-source/Makefile
plugins/startup-wizard/Makefile
plugins/subject-thread/Makefile
plugins/templates/Makefile
plugins/tnef-attachments/Makefile
plugins/vcard-inline/Makefile
plugins/webdav-account-setup/Makefile
+smclient/Makefile
smime/Makefile
smime/lib/Makefile
smime/gui/Makefile
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 486263dbd4..d2ac0cf244 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,3 +1,5 @@
+SUBDIRS = reference
+
EXTRA_DIST = ChangeLog.pre-1-4
-include $(top_srcdir)/git.mk
diff --git a/doc/devel/Makefile.am b/doc/devel/Makefile.am
index 2406f0af02..cd7881e23b 100644
--- a/doc/devel/Makefile.am
+++ b/doc/devel/Makefile.am
@@ -54,9 +54,6 @@ local_entities = \
# executive-summary/sgml/executive-summary-component-factory-client.sgml \
# executive-summary/sgml/executive-summary-html-view.sgml
-# importer/sgml/evolution-importer.sgml \
-# importer/sgml/evolution-importer-client.sgml
-
installed_content_files = \
fdl.sgml \
preface.sgml \
diff --git a/doc/devel/importer/Makefile.am b/doc/devel/importer/Makefile.am
deleted file mode 100644
index a186bc770f..0000000000
--- a/doc/devel/importer/Makefile.am
+++ /dev/null
@@ -1,197 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-# The name of the module, e.g. 'glib'.
-DOC_MODULE=evolution-shell-importer
-
-# The top-level SGML file. Change it if you want.
-DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
-
-# The directory containing the source code. Relative to $(srcdir).
-# gtk-doc will search all .c & .h files beneath here for inline comments
-# documenting functions and macros.
-DOC_SOURCE_DIR=$(EVOLUTION_DIR)/shell/importer
-
-# Extra options to supply to gtkdoc-scan.
-SCAN_OPTIONS=
-
-# Extra options to supply to gtkdoc-mkdb.
-MKDB_OPTIONS=
-
-# Extra options to supply to gtkdoc-fixref.
-FIXXREF_OPTIONS=
-
-# Used for dependencies.
-HFILE_GLOB= \
- $(top_srcdir)/shell/importer/evolution-importer.h \
- $(top_srcdir)/shell/importer/evolution-importer-client.h
-
-CFILE_GLOB= \
- $(top_srcdir)/shell/importer/evolution-importer.c \
- $(top_srcdir)/shell/importer/evolution-importer-client.c
-
-# Header files to ignore when scanning.
-IGNORE_HFILES= \
- GNOME_Evolution_Importer.h \
- importer.h
-
-# Images to copy into HTML directory.
-HTML_IMAGES =
-
-# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
-content_files =
-
-# Other files to distribute.
-extra_files =
-
-# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib
-# contains GtkObjects/GObjects and you want to document signals and properties.
-GTKDOC_CFLAGS = \
- -I$(top_srcdir)/shell/importer \
- -I$(top_srcdir)/shell \
- -I$(top_srcdir) \
- -I$(top_builddir) \
- $(BONOBO_VFS_GNOME_CFLAGS)
-
-GTKDOC_LIBS = \
- $(BONOBO_VFS_GNOME_LIBS) \
- $(top_builddir)/shell/importer/.libs/libevolution-importer.so
-
-GTKDOC_CC=$(LIBTOOL) --mode=compile $(CC)
-GTKDOC_LD=$(LIBTOOL) --mode=link $(CC)
-
-# If you need to override some of the declarations, place them in this file
-# and uncomment this line.
-#DOC_OVERRIDES = $(DOC_MODULE)-overrides.txt
-DOC_OVERRIDES =
-
-###########################################################################
-# Everything below here is generic and you shouldn't need to change it.
-###########################################################################
-
-TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
-
-EXTRA_DIST = \
- $(content_files) \
- $(extra_files) \
- $(HTML_IMAGES) \
- $(DOC_MAIN_SGML_FILE) \
- $(DOC_MODULE).types \
- $(DOC_MODULE)-sections.txt \
- $(DOC_OVERRIDES)
-
-DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \
- $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp $(srcdir)/html.stamp
-
-SCANOBJ_FILES = \
- $(DOC_MODULE).args \
- $(DOC_MODULE).hierarchy \
- $(DOC_MODULE).signals
-
-if ENABLE_GTK_DOC
-#all-local: html-build.stamp
-all-local: sgml-build.stamp
-
-#### scan ####
-
-scan-build.stamp: $(HFILE_GLOB)
- @echo '*** Scanning header files ***'
- if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null ; then \
- CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" gtkdoc-scanobj --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \
- else \
- cd $(srcdir) ; \
- for i in $(SCANOBJ_FILES) ; do \
- test -f $$i || touch $$i ; \
- done \
- fi
- cd $(srcdir) && \
- gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES)
- touch scan-build.stamp
-
-$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp
- @true
-
-#### templates ####
-
-tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_OVERRIDES)
- @echo '*** Rebuilding template files ***'
- cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE)
- touch tmpl-build.stamp
-
-tmpl.stamp: tmpl-build.stamp
- @true
-
-#### sgml ####
-
-sgml-build.stamp: tmpl.stamp $(CFILE_GLOB) $(srcdir)/tmpl/*.sgml
- @echo '*** Building SGML ***'
- cd $(srcdir) && \
- gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS)
- touch sgml-build.stamp
-
-sgml.stamp: sgml-build.stamp
- @true
-
-#### html ####
-
-html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
- @echo '*** Building HTML ***'
- test -d $(srcdir)/html || mkdir $(srcdir)/html
- cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
- test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html )
- @echo '-- Fixing Crossreferences'
- cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
- touch html-build.stamp
-endif
-
-##############
-
-clean-local:
- rm -f *~ *.bak $(SCANOBJ_FILES) *-unused.txt $(DOC_STAMPS)
-
-maintainer-clean-local: clean
- cd $(srcdir) && rm -rf sgml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
-
-install-data-local:
- $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)
- (installfiles=`echo $(srcdir)/html/*.html`; \
- if test "$$installfiles" = '$(srcdir)/html/*.html'; \
- then echo '-- Nothing to install' ; \
- else \
- for i in $$installfiles; do \
- echo '-- Installing '$$i ; \
- $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \
- done; \
- echo '-- Installing $(srcdir)/html/index.sgml' ; \
- $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \
- fi)
-
-#
-# Require gtk-doc when making dist
-#
-if ENABLE_GTK_DOC
-dist-check-gtkdoc:
-else
-dist-check-gtkdoc:
- @echo "*** gtk-doc must be installed and enabled in order to make dist"
- @false
-endif
-
-dist-hook: dist-check-gtkdoc dist-hook-local
- mkdir $(distdir)/tmpl
- mkdir $(distdir)/sgml
- mkdir $(distdir)/html
- -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl
- -cp $(srcdir)/sgml/*.sgml $(distdir)/sgml
- -cp $(srcdir)/html/index.sgml $(distdir)/html
- -cp $(srcdir)/html/*.html $(srcdir)/html/*.css $(distdir)/html
-
- images=$(HTML_IMAGES) ; \
- for i in $$images ; do \
- cp $(srcdir)/$$i $(distdir)/html ; \
- done
-
-.PHONY : dist-hook-local
-
-
-
--include $(top_srcdir)/git.mk
diff --git a/doc/devel/importer/evolution-shell-importer-sections.txt b/doc/devel/importer/evolution-shell-importer-sections.txt
deleted file mode 100644
index e2474f6375..0000000000
--- a/doc/devel/importer/evolution-shell-importer-sections.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-<INCLUDE>evolution-importer.h</INCLUDE>
-
-<SECTION>
-<FILE>evolution-importer</FILE>
-EVOLUTION_IMPORTER
-<TITLE>EvolutionImporter</TITLE>
-
-EvolutionImporterSupportFormatFn
-EvolutionImporterLoadFileFn
-EvolutionImporterProcessItemFn
-EvolutionImporterGetErrorFn
-
-EvolutionImporterResult
-
-evolution_importer_new
-
-<SUBSECTION Standard>
-EVOLUTION_TYPE_IMPORTER
-EVOLUTION_IMPORTER
-EVOLUTION_IS_IMPORTER
-EVOLUTION_IMPORTER_CLASS
-EVOLUTION_IS_IMPORTER_CLASS
-evolution_importer_get_type
-
-<SUBSECTION Private>
-EvolutionImporter
-EvolutionImporterPrivate
-
-</SECTION>
-
-<INCLUDE>evolution-importer-listener.h</INCLUDE>
-<SECTION>
-<FILE>evolution-importer-listener</FILE>
-EVOLUTION_IMPORTER_LISTENER
-<TITLE>EvolutionImporterListener</TITLE>
-
-EvolutionImporterListenerCallback
-
-evolution_importer_listener_new
-
-<SUBSECTION Standard>
-EVOLUTION_TYPE_IMPORTER_LISTENER
-EVOLUTION_IMPORTER_LISTENER
-EVOLUTION_IMPORTER_LISTENER_CLASS
-EVOLUTION_IS_IMPORTER_LISTENER
-EVOLUTION_IS_IMPORTER_LISTENER_CLASS
-evolution_importer_listener_get_type
-
-<SUBSECTION Private>
-EvolutionImporterListener
-EvolutionImporterListenerPrivate
-
-</SECTION>
-
-<INCLUDE>evolution-importer-client.h</INCLUDE>
-<SECTION>
-<FILE>evolution-importer-client</FILE>
-EVOLUTION_IMPORTER_CLIENT
-<TITLE>EvolutionImporterClient</TITLE>
-
-evolution_importer_client_new
-evolution_importer_client_new_from_id
-evolution_importer_client_support_format
-evolution_importer_client_load_file
-evolution_importer_client_process_item
-evolution_importer_client_get_error
-
-<SUBSECTION Standard>
-EVOLUTION_TYPE_IMPORTER_CLIENT
-EVOLUTION_IMPORTER_CLIENT
-EVOLUTION_IMPORTER_CLIENT_CLASS
-EVOLUTION_IS_IMPORTER_CLIENT
-EVOLUTION_IS_IMPORTER_CLIENT_CLASS
-evolution_importer_client_get_type
-
-<SUBSECTION Private>
-EvolutionImporterClient
-
-</SECTION>
diff --git a/doc/devel/importer/evolution-shell-importer.hierarchy b/doc/devel/importer/evolution-shell-importer.hierarchy
deleted file mode 100644
index c46ebdf782..0000000000
--- a/doc/devel/importer/evolution-shell-importer.hierarchy
+++ /dev/null
@@ -1,7 +0,0 @@
-GtkObject
- BonoboObject
- BonoboXObject
- EvolutionImporter
- EvolutionImporterListener
- Handle to remote Bonobo::Unknown
- EvolutionImporterClient
diff --git a/doc/devel/importer/evolution-shell-importer.types b/doc/devel/importer/evolution-shell-importer.types
deleted file mode 100644
index e787818599..0000000000
--- a/doc/devel/importer/evolution-shell-importer.types
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <gnome.h>
-#include <bonobo.h>
-#include <shell/importer/evolution-importer.h>
-#include <shell/importer/evolution-importer-client.h>
-#include <shell/importer/evolution-importer-listener.h>
-
-evolution_importer_get_type
-evolution_importer_client_get_type
-evolution_importer_listener_get_type
diff --git a/doc/devel/importer/private-reference.sgml b/doc/devel/importer/private-reference.sgml
deleted file mode 100644
index d28c7b8591..0000000000
--- a/doc/devel/importer/private-reference.sgml
+++ /dev/null
@@ -1,21 +0,0 @@
- <reference id="importer-private-reference">
- <title>Importer Private API Reference</title>
-
- <partintro>
- <para>
- This part presents the class and function reference for the
- private APIs of the different components of the &Evolution;
- Import Framework.
- </para>
- </partintro>
-
- &EvolutionImporterListener;
- &EvolutionImporterClient;
- </reference>
-
-<!--
-Local variables:
-mode: sgml
-sml-parent-document: ("../evolution-devel-guide.sgml" "book" "part" "")
-End:
--->
diff --git a/doc/devel/importer/public-reference.sgml b/doc/devel/importer/public-reference.sgml
deleted file mode 100644
index ba99c9b309..0000000000
--- a/doc/devel/importer/public-reference.sgml
+++ /dev/null
@@ -1,20 +0,0 @@
- <reference id="importer-public-reference">
- <title>Importer Public API Reference</title>
-
- <partintro>
- <para>
- This part presents the class and function reference for the
- public APIs of the different components of the &Evolution;
- Import Framework.
- </para>
- </partintro>
-
- &EvolutionImporter;
- </reference>
-
-<!--
-Local variables:
-mode: sgml
-sml-parent-document: ("../evolution-devel-guide.sgml" "book" "part" "")
-End:
--->
diff --git a/doc/devel/importer/tmpl/evolution-importer.sgml b/doc/devel/importer/tmpl/evolution-importer.sgml
deleted file mode 100644
index 1c7736a37f..0000000000
--- a/doc/devel/importer/tmpl/evolution-importer.sgml
+++ /dev/null
@@ -1,96 +0,0 @@
-<!-- ##### SECTION Title ##### -->
-EvolutionImporter
-
-<!-- ##### SECTION Short_Description ##### -->
-A #BonoboObject that implements the GNOME/Evolution/Importer interface.
-
-<!-- ##### SECTION Long_Description ##### -->
-<para>
-A #BonoboObject wrapper around the GNOME/Evolution/Importer interface, providing error checking and reference counting, hiding the CORBA internals from the user and providing a simple way to create a GNOME_Evolution_Importer object.
-</para>
-
-<!-- ##### SECTION See_Also ##### -->
-<para>
-
-</para>
-
-<!-- ##### MACRO EVOLUTION_IMPORTER ##### -->
-<para>
-Casts a #GtkObject into an #EvolutionImporter.
-</para>
-
-@obj: A #GtkObject.
-
-
-<!-- ##### USER_FUNCTION EvolutionImporterSupportFormatFn ##### -->
-<para>
-The type of function that is called when the importer wishes to find out if the importing component can support the file given in @filename.
-</para>
-
-@importer: The #EvolutionImporter.
-@filename: The filename of the file to check.
-@closure: The data passed into evolution_importer_new ().
-@Returns: A #gboolean. TRUE if the importing component can import the file, FALSE otherwise.
-
-
-<!-- ##### USER_FUNCTION EvolutionImporterLoadFileFn ##### -->
-<para>
-The type of function that is called when the importer wishes the importing component to load the file given in @filename, and initialise itself.
-</para>
-
-@importer: The #EvolutionImporter.
-@filename: The filename of the file to load.
-@folderpath:
-@closure: The data passed into evolution_importer_new ().
-@Returns: A #gboolean. TRUE if the load and initialisation was successful, FALSE otherwise.
-
-
-<!-- ##### USER_FUNCTION EvolutionImporterProcessItemFn ##### -->
-<para>
-The type of function that is called when the importer wants the importing component to process the next item (or items) in a file.
-</para>
-
-@importer: The #EvolutionImporter
-@listener: A GNOME_Evolution_Importer_Listener CORBA object.
-@closure: The data passed into evolution_importer_new ().
-@ev: A #CORBA_Environment for returning any CORBA exceptions.
-
-
-<!-- ##### USER_FUNCTION EvolutionImporterGetErrorFn ##### -->
-<para>
-The type of function that is called when the importer wants to get a string version of an error. Not all importing components support this function.
-</para>
-
-@importer: The #EvolutionImporter.
-@closure: The data passed to evolution_importer_new ().
-@Returns: A string representation of the error, or NULL if there was no error, or the importing component does not support the getError method.
-
-
-<!-- ##### ENUM EvolutionImporterResult ##### -->
-<para>
-
-</para>
-
-@EVOLUTION_IMPORTER_OK:
-@EVOLUTION_IMPORTER_UNSUPPORTED_OPERATION:
-@EVOLUTION_IMPORTER_INTERRUPTED:
-@EVOLUTION_IMPORTER_BUSY:
-@EVOLUTION_IMPORTER_NOT_READY:
-@EVOLUTION_IMPORTER_UNKNOWN_DATA:
-@EVOLUTION_IMPORTER_BAD_DATA:
-@EVOLUTION_IMPORTER_BAD_FILE:
-@EVOLUTION_IMPORTER_UNKNOWN_ERROR:
-
-<!-- ##### FUNCTION evolution_importer_new ##### -->
-<para>
-
-</para>
-
-@support_format_fn:
-@load_file_fn:
-@process_item_fn:
-@get_error_fn:
-@closure:
-@Returns:
-
-
diff --git a/doc/devel/importer/tmpl/evolution-shell-importer-unused.sgml b/doc/devel/importer/tmpl/evolution-shell-importer-unused.sgml
deleted file mode 100644
index 7a9a98034b..0000000000
--- a/doc/devel/importer/tmpl/evolution-shell-importer-unused.sgml
+++ /dev/null
@@ -1,10 +0,0 @@
-<!-- ##### USER_FUNCTION EvolutionImporterClientCallback ##### -->
-<para>
-
-</para>
-
-@client:
-@result:
-@more_items:
-@data:
-
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
new file mode 100644
index 0000000000..48d38adb0a
--- /dev/null
+++ b/doc/reference/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = shell
+
+-include $(top_srcdir)/git.mk
diff --git a/doc/reference/shell/Makefile.am b/doc/reference/shell/Makefile.am
new file mode 100644
index 0000000000..370fd53b99
--- /dev/null
+++ b/doc/reference/shell/Makefile.am
@@ -0,0 +1,158 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=eshell
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=../../../shell
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/shell/*.h
+CFILE_GLOB=$(top_srcdir)/shell/*.c
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=e-shell-window-private.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files=
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+AM_CPPFLAGS= \
+ -I$(top_srcdir) \
+ -I$(SHELL_CFLAGS)
+GTKDOC_LIBS= \
+ $(top_builddir)/shell/.libs/e-shell.o \
+ $(top_builddir)/shell/.libs/e-shell-backend.o \
+ $(top_builddir)/shell/.libs/e-shell-content.o \
+ $(top_builddir)/shell/.libs/e-shell-importer.o \
+ $(top_builddir)/shell/.libs/e-shell-migrate.o \
+ $(top_builddir)/shell/.libs/e-shell-settings.o \
+ $(top_builddir)/shell/.libs/e-shell-sidebar.o \
+ $(top_builddir)/shell/.libs/e-shell-switcher.o \
+ $(top_builddir)/shell/.libs/e-shell-taskbar.o \
+ $(top_builddir)/shell/.libs/e-shell-view.o \
+ $(top_builddir)/shell/.libs/e-shell-window-actions.o \
+ $(top_builddir)/shell/.libs/e-shell-window-private.o \
+ $(top_builddir)/shell/.libs/e-shell-window.o \
+ $(top_builddir)/shell/.libs/es-event.o \
+ $(top_builddir)/e-util/.libs/e-bconf-map.o \
+ $(top_builddir)/e-util/.libs/e-binding.o \
+ $(top_builddir)/e-util/.libs/e-dialog-utils.o \
+ $(top_builddir)/e-util/.libs/e-error.o \
+ $(top_builddir)/e-util/.libs/e-event.o \
+ $(top_builddir)/e-util/.libs/e-fsutils.o \
+ $(top_builddir)/e-util/.libs/e-icon-factory.o \
+ $(top_builddir)/e-util/.libs/e-import.o \
+ $(top_builddir)/e-util/.libs/e-logger.o \
+ $(top_builddir)/e-util/.libs/e-marshal.o \
+ $(top_builddir)/e-util/.libs/e-mktemp.o \
+ $(top_builddir)/e-util/.libs/e-module.o \
+ $(top_builddir)/e-util/.libs/e-plugin.o \
+ $(top_builddir)/e-util/.libs/e-plugin-ui.o \
+ $(top_builddir)/e-util/.libs/e-print.o \
+ $(top_builddir)/e-util/.libs/e-unicode.o \
+ $(top_builddir)/e-util/.libs/e-util.o \
+ $(top_builddir)/e-util/.libs/e-xml-utils.o \
+ $(top_builddir)/e-util/.libs/gconf-bridge.o \
+ $(top_builddir)/filter/.libs/filter-code.o \
+ $(top_builddir)/filter/.libs/filter-colour.o \
+ $(top_builddir)/filter/.libs/filter-datespec.o \
+ $(top_builddir)/filter/.libs/filter-element.o \
+ $(top_builddir)/filter/.libs/filter-file.o \
+ $(top_builddir)/filter/.libs/filter-input.o \
+ $(top_builddir)/filter/.libs/filter-int.o \
+ $(top_builddir)/filter/.libs/filter-option.o \
+ $(top_builddir)/filter/.libs/filter-part.o \
+ $(top_builddir)/filter/.libs/filter-rule.o \
+ $(top_builddir)/filter/.libs/rule-context.o \
+ $(top_builddir)/filter/.libs/rule-editor.o \
+ $(top_builddir)/smclient/.libs/eggdesktopfile.o \
+ $(top_builddir)/smclient/.libs/eggsmclient.o \
+ $(top_builddir)/smclient/.libs/eggsmclient-xsmp.o \
+ $(top_builddir)/widgets/menus/.libs/gal-define-views-dialog.o \
+ $(top_builddir)/widgets/menus/.libs/gal-view-collection.o \
+ $(top_builddir)/widgets/menus/.libs/gal-view-factory.o \
+ $(top_builddir)/widgets/menus/.libs/gal-view-instance.o \
+ $(top_builddir)/widgets/menus/.libs/gal-view-instance-save-as-dialog.o \
+ $(top_builddir)/widgets/menus/.libs/gal-view-new-dialog.o \
+ $(top_builddir)/widgets/menus/.libs/gal-view.o \
+ $(top_builddir)/widgets/misc/.libs/e-action-combo-box.o \
+ $(top_builddir)/widgets/misc/.libs/e-activity.o \
+ $(top_builddir)/widgets/misc/.libs/e-activity-proxy.o \
+ $(top_builddir)/widgets/misc/.libs/e-gui-utils.o \
+ $(top_builddir)/widgets/misc/.libs/e-hinted-entry.o \
+ $(top_builddir)/widgets/misc/.libs/e-menu-tool-button.o \
+ $(top_builddir)/widgets/misc/.libs/e-online-button.o \
+ $(top_builddir)/widgets/misc/.libs/e-popup-menu.o \
+ $(top_builddir)/widgets/misc/.libs/e-preferences-window.o \
+ $(top_builddir)/widgets/misc/.libs/e-spinner.o \
+ -ledataserver-1.2 \
+ -ledataserverui-1.2 \
+ $(SHELL_LIBS)
+
+if NM_SUPPORT
+GTKDOC_LIBS += \
+ $(top_builddir)/shell/.libs/e-shell-nm.o
+endif
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST +=
+
+# Files not to distribute
+# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
+# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
+#DISTCLEANFILES +=
+
+# Comment this out if you want your docs-status tested during 'make check'
+#TESTS = $(GTKDOC_CHECK)
+
+-include $(top_srcdir)/git.mk
diff --git a/doc/reference/shell/eshell-docs.sgml b/doc/reference/shell/eshell-docs.sgml
new file mode 100644
index 0000000000..3d7bdcd36e
--- /dev/null
+++ b/doc/reference/shell/eshell-docs.sgml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>Evolution Shell Reference Manual</title>
+ <releaseinfo>
+ The latest version of this documentation can be found on-line at
+ <ulink role="online-location"
+url="http://mbarnes.fedorapeople.org/docs/eshell/">http://mbarnes.fedorapeople.org/docs/eshell/</ulink>.
+ </releaseinfo>
+ </bookinfo>
+
+ <chapter>
+ <title>The Shell</title>
+ <xi:include href="xml/e-shell.xml"/>
+ <xi:include href="xml/e-shell-backend.xml"/>
+ <xi:include href="xml/e-shell-window.xml"/>
+ <xi:include href="xml/e-shell-view.xml"/>
+ <xi:include href="xml/e-shell-content.xml"/>
+ <xi:include href="xml/e-shell-sidebar.xml"/>
+ <xi:include href="xml/e-shell-taskbar.xml"/>
+ <xi:include href="xml/e-shell-settings.xml"/>
+ <xi:include href="xml/e-shell-switcher.xml"/>
+ <xi:include href="xml/e-shell-importer.xml"/>
+ </chapter>
+
+ <chapter>
+ <title>Actions</title>
+ <xi:include href="xml/shell-actions.xml"/>
+ <xi:include href="xml/action-groups.xml"/>
+ </chapter>
+
+ <chapter>
+ <title>Object Hierarchy</title>
+ <xi:include href="xml/tree_index.sgml"/>
+ </chapter>
+
+ <index>
+ <title>Index</title>
+ </index>
+
+</book>
diff --git a/doc/devel/importer/evolution-shell-importer.args b/doc/reference/shell/eshell-overrides.txt
index e69de29bb2..e69de29bb2 100644
--- a/doc/devel/importer/evolution-shell-importer.args
+++ b/doc/reference/shell/eshell-overrides.txt
diff --git a/doc/reference/shell/eshell-sections.txt b/doc/reference/shell/eshell-sections.txt
new file mode 100644
index 0000000000..8bfb57b5f3
--- /dev/null
+++ b/doc/reference/shell/eshell-sections.txt
@@ -0,0 +1,346 @@
+<SECTION>
+<FILE>e-shell</FILE>
+<TITLE>EShell</TITLE>
+EShell
+e_shell_get_default
+e_shell_get_shell_backends
+e_shell_get_canonical_name
+e_shell_get_backend_by_name
+e_shell_get_backend_by_scheme
+e_shell_get_shell_settings
+e_shell_get_gconf_client
+e_shell_create_shell_window
+e_shell_handle_uris
+e_shell_watch_window
+e_shell_get_watched_windows
+e_shell_send_receive
+e_shell_get_network_available
+e_shell_set_network_available
+e_shell_get_online
+e_shell_set_online
+e_shell_get_preferences_window
+e_shell_event
+e_shell_quit
+e_shell_cancel_quit
+E_SHELL_MIGRATE_ERROR
+e_shell_migrate_attempt
+<SUBSECTION Standard>
+E_SHELL
+E_IS_SHELL
+E_TYPE_SHELL
+E_SHELL_CLASS
+E_IS_SHELL_CLASS
+E_SHELL_GET_CLASS
+EShellClass
+e_shell_get_type
+<SUBSECTION Private>
+EShellPrivate
+e_shell_migrate_error_quark
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-backend</FILE>
+<TITLE>EShellBackend</TITLE>
+EShellBackend
+e_shell_backend_compare
+e_shell_backend_get_config_dir
+e_shell_backend_get_data_dir
+e_shell_backend_get_filename
+e_shell_backend_get_shell
+e_shell_backend_add_activity
+e_shell_backend_start
+e_shell_backend_migrate
+<SUBSECTION Standard>
+E_SHELL_BACKEND
+E_IS_SHELL_BACKEND
+E_TYPE_SHELL_BACKEND
+E_SHELL_BACKEND_CLASS
+E_IS_SHELL_BACKEND_CLASS
+E_SHELL_BACKEND_GET_CLASS
+EShellBackendClass
+e_shell_backend_get_type
+<SUBSECTION Private>
+EShellBackendPrivate
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-content</FILE>
+<TITLE>EShellContent</TITLE>
+EShellContent
+e_shell_content_new
+e_shell_content_check_state
+e_shell_content_get_shell_view
+e_shell_content_get_filter_action
+e_shell_content_set_filter_action
+e_shell_content_get_filter_value
+e_shell_content_set_filter_value
+e_shell_content_get_filter_visible
+e_shell_content_set_filter_visible
+e_shell_content_add_filter_separator_before
+e_shell_content_add_filter_separator_after
+e_shell_content_get_search_context
+e_shell_content_get_search_hint
+e_shell_content_set_search_hint
+e_shell_content_get_search_rule
+e_shell_content_set_search_rule
+e_shell_content_get_search_text
+e_shell_content_set_search_text
+e_shell_content_get_search_visible
+e_shell_content_set_search_visible
+e_shell_content_get_scope_action
+e_shell_content_set_scope_action
+e_shell_content_get_scope_value
+e_shell_content_set_scope_value
+e_shell_content_get_scope_visible
+e_shell_content_set_scope_visible
+e_shell_content_get_view_id
+e_shell_content_set_view_id
+e_shell_content_run_advanced_search_dialog
+e_shell_content_run_edit_searches_dialog
+e_shell_content_run_save_search_dialog
+e_shell_content_restore_state
+<SUBSECTION Standard>
+E_SHELL_CONTENT
+E_IS_SHELL_CONTENT
+E_TYPE_SHELL_CONTENT
+E_SHELL_CONTENT_CLASS
+E_IS_SHELL_CONTENT_CLASS
+E_SHELL_CONTENT_GET_CLASS
+EShellContentClass
+e_shell_content_get_type
+<SUBSECTION Private>
+EShellContentPrivate
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-settings</FILE>
+<TITLE>EShellSettings</TITLE>
+EShellSettings
+e_shell_settings_install_property
+e_shell_settings_install_property_for_key
+e_shell_settings_enable_debug
+e_shell_settings_get_boolean
+e_shell_settings_set_boolean
+e_shell_settings_get_int
+e_shell_settings_set_int
+e_shell_settings_get_string
+e_shell_settings_set_string
+e_shell_settings_get_object
+e_shell_settings_set_object
+e_shell_settings_get_pointer
+e_shell_settings_set_pointer
+<SUBSECTION Standard>
+E_SHELL_SETTINGS
+E_IS_SHELL_SETTINGS
+E_TYPE_SHELL_SETTINGS
+E_SHELL_SETTINGS_CLASS
+E_IS_SHELL_SETTINGS_CLASS
+E_SHELL_SETTINGS_GET_CLASS
+EShellSettingsClass
+e_shell_settings_get_type
+<SUBSECTION Private>
+EShellSettingsPrivate
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-sidebar</FILE>
+<TITLE>EShellSidebar</TITLE>
+EShellSidebar
+e_shell_sidebar_new
+e_shell_sidebar_check_state
+e_shell_sidebar_get_shell_view
+e_shell_sidebar_get_icon_name
+e_shell_sidebar_set_icon_name
+e_shell_sidebar_get_primary_text
+e_shell_sidebar_set_primary_text
+e_shell_sidebar_get_secondary_text
+e_shell_sidebar_set_secondary_text
+<SUBSECTION Standard>
+E_SHELL_SIDEBAR
+E_IS_SHELL_SIDEBAR
+E_TYPE_SHELL_SIDEBAR
+E_SHELL_SIDEBAR_CLASS
+E_IS_SHELL_SIDEBAR_CLASS
+E_SHELL_SIDEBAR_GET_CLASS
+EShellSidebarClass
+e_shell_sidebar_get_type
+<SUBSECTION Private>
+EShellSidebarPrivate
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-switcher</FILE>
+<TITLE>EShellSwitcher</TITLE>
+EShellSwitcher
+e_shell_switcher_new
+e_shell_switcher_add_action
+e_shell_switcher_get_style
+e_shell_switcher_set_style
+e_shell_switcher_unset_style
+e_shell_switcher_get_visible
+e_shell_switcher_set_visible
+<SUBSECTION Standard>
+E_SHELL_SWITCHER
+E_IS_SHELL_SWITCHER
+E_TYPE_SHELL_SWITCHER
+E_SHELL_SWITCHER_CLASS
+E_IS_SHELL_SWITCHER_CLASS
+E_SHELL_SWITCHER_GET_CLASS
+EShellSwitcherClass
+e_shell_switcher_get_type
+<SUBSECTION Private>
+EShellSwitcherPrivate
+E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-taskbar</FILE>
+<TITLE>EShellTaskbar</TITLE>
+EShellTaskbar
+e_shell_taskbar_new
+e_shell_taskbar_get_shell_view
+e_shell_taskbar_get_message
+e_shell_taskbar_set_message
+e_shell_taskbar_unset_message
+<SUBSECTION Standard>
+E_SHELL_TASKBAR
+E_IS_SHELL_TASKBAR
+E_TYPE_SHELL_TASKBAR
+E_SHELL_TASKBAR_CLASS
+E_IS_SHELL_TASKBAR_CLASS
+E_SHELL_TASKBAR_GET_CLASS
+EShellTaskbarClass
+e_shell_taskbar_get_type
+<SUBSECTION Private>
+EShellTaskbarPrivate
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-view</FILE>
+<TITLE>EShellView</TITLE>
+EShellView
+EShellViewClass
+e_shell_view_get_name
+e_shell_view_get_action
+e_shell_view_get_title
+e_shell_view_set_title
+e_shell_view_get_view_id
+e_shell_view_set_view_id
+e_shell_view_is_active
+e_shell_view_get_page_num
+e_shell_view_set_page_num
+e_shell_view_get_size_group
+e_shell_view_get_shell_backend
+e_shell_view_get_shell_content
+e_shell_view_get_shell_sidebar
+e_shell_view_get_shell_taskbar
+e_shell_view_get_shell_window
+e_shell_view_get_state_key_file
+e_shell_view_set_state_dirty
+e_shell_view_update_actions
+e_shell_view_show_popup_menu
+e_shell_view_new_view_instance
+<SUBSECTION Standard>
+E_SHELL_VIEW
+E_IS_SHELL_VIEW
+E_TYPE_SHELL_VIEW
+E_SHELL_VIEW_CLASS
+E_IS_SHELL_VIEW_CLASS
+E_SHELL_VIEW_GET_CLASS
+e_shell_view_get_type
+<SUBSECTION Private>
+EShellViewPrivate
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-window</FILE>
+<TITLE>EShellWindow</TITLE>
+EShellWindow
+e_shell_window_new
+e_shell_window_get_shell
+e_shell_window_get_shell_view
+e_shell_window_get_shell_view_action
+e_shell_window_get_ui_manager
+e_shell_window_get_action
+e_shell_window_get_action_group
+e_shell_window_get_managed_widget
+e_shell_window_get_active_view
+e_shell_window_set_active_view
+e_shell_window_get_safe_mode
+e_shell_window_set_safe_mode
+e_shell_window_add_action_group
+e_shell_window_register_new_item_actions
+e_shell_window_register_new_source_actions
+<SUBSECTION Standard>
+E_SHELL_WINDOW
+E_IS_SHELL_WINDOW
+E_TYPE_SHELL_WINDOW
+E_SHELL_WINDOW_CLASS
+E_IS_SHELL_WINDOW_CLASS
+E_SHELL_WINDOW_GET_CLASS
+EShellWindowClass
+e_shell_window_get_type
+<SUBSECTION Private>
+EShellWindowPrivate
+E_SHELL_WINDOW_ACTION
+E_SHELL_WINDOW_ACTION_GROUP
+</SECTION>
+
+<SECTION>
+<FILE>e-shell-importer</FILE>
+e_shell_importer_start_import
+</SECTION>
+
+<SECTION>
+<FILE>shell-actions</FILE>
+<TITLE>Shell Actions</TITLE>
+E_SHELL_WINDOW_ACTION_ABOUT
+E_SHELL_WINDOW_ACTION_CLOSE
+E_SHELL_WINDOW_ACTION_CONTENTS
+E_SHELL_WINDOW_ACTION_FAQ
+E_SHELL_WINDOW_ACTION_FORGET_PASSWORDS
+E_SHELL_WINDOW_ACTION_GAL_CUSTOM_VIEW
+E_SHELL_WINDOW_ACTION_GAL_DEFINE_VIEWS
+E_SHELL_WINDOW_ACTION_GAL_SAVE_CUSTOM_VIEW
+E_SHELL_WINDOW_ACTION_IMPORT
+E_SHELL_WINDOW_ACTION_NEW_WINDOW
+E_SHELL_WINDOW_ACTION_PAGE_SETUP
+E_SHELL_WINDOW_ACTION_PREFERENCES
+E_SHELL_WINDOW_ACTION_QUICK_REFERENCE
+E_SHELL_WINDOW_ACTION_QUIT
+E_SHELL_WINDOW_ACTION_SEARCH_ADVANCED
+E_SHELL_WINDOW_ACTION_SEARCH_CLEAR
+E_SHELL_WINDOW_ACTION_SEARCH_EDIT
+E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE
+E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS
+E_SHELL_WINDOW_ACTION_SEARCH_SAVE
+E_SHELL_WINDOW_ACTION_SEND_RECEIVE
+E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR
+E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR
+E_SHELL_WINDOW_ACTION_SHOW_SWITCHER
+E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR
+E_SHELL_WINDOW_ACTION_SUBMIT_BUG
+E_SHELL_WINDOW_ACTION_SWITCHER_INITIAL
+E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_BOTH
+E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS
+E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_TEXT
+E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_USER
+E_SHELL_WINDOW_ACTION_SYNC_OPTIONS
+E_SHELL_WINDOW_ACTION_WORK_OFFLINE
+E_SHELL_WINDOW_ACTION_WORK_ONLINE
+</SECTION>
+
+<SECTION>
+<FILE>action-groups</FILE>
+<TITLE>Action Groups</TITLE>
+E_SHELL_WINDOW_ACTION_GROUP_SHELL
+E_SHELL_WINDOW_ACTION_GROUP_SWITCHER
+E_SHELL_WINDOW_ACTION_GROUP_NEW_ITEM
+E_SHELL_WINDOW_ACTION_GROUP_NEW_SOURCE
+E_SHELL_WINDOW_ACTION_GROUP_CUSTOM_RULES
+E_SHELL_WINDOW_ACTION_GROUP_GAL_VIEW
+E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_APPLICATION_HANDLERS
+E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_PRINTING
+E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_PRINT_SETUP
+E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_SAVE_TO_DISK
+</SECTION>
diff --git a/doc/reference/shell/eshell.types b/doc/reference/shell/eshell.types
new file mode 100644
index 0000000000..7ad399f7c9
--- /dev/null
+++ b/doc/reference/shell/eshell.types
@@ -0,0 +1,8 @@
+e_shell_get_type
+e_shell_backend_get_type
+e_shell_content_get_type
+e_shell_sidebar_get_type
+e_shell_switcher_get_type
+e_shell_taskbar_get_type
+e_shell_view_get_type
+e_shell_window_get_type
diff --git a/doc/reference/shell/tmpl/Evolution-DataServer.sgml b/doc/reference/shell/tmpl/Evolution-DataServer.sgml
new file mode 100644
index 0000000000..181b45f301
--- /dev/null
+++ b/doc/reference/shell/tmpl/Evolution-DataServer.sgml
@@ -0,0 +1,1139 @@
+<!-- ##### SECTION Title ##### -->
+Evolution-DataServer
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO ORBIT_IDL_SERIAL ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO ORBIT_DECL_GNOME_Evolution_DataServer_Config ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Config__freekids ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### TYPEDEF GNOME_Evolution_DataServer_Config ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### VARIABLE GNOME_Evolution_DataServer_Config__classid ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_0 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_11 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_12 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_13 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_14 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_15 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_16 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_17 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_18 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_19 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_Config ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO ORBIT_DECL_GNOME_Evolution_DataServer_InterfaceCheck ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck__freekids ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### TYPEDEF GNOME_Evolution_DataServer_InterfaceCheck ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### VARIABLE GNOME_Evolution_DataServer_InterfaceCheck__classid ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_0 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_11 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_12 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_13 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_14 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_15 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_16 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_17 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_18 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_19 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_InterfaceCheck ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO ORBIT_DECL_GNOME_Evolution_DataServer_Logging ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging__freekids ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### TYPEDEF GNOME_Evolution_DataServer_Logging ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### VARIABLE GNOME_Evolution_DataServer_Logging__classid ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_0 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_11 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_12 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_13 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_14 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_15 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_16 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_17 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_18 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_19 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_Logging ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### ENUM GNOME_Evolution_DataServer_Logging_Level ##### -->
+<para>
+
+</para>
+
+@GNOME_Evolution_DataServer_Logging_Error:
+@GNOME_Evolution_DataServer_Logging_Critical:
+@GNOME_Evolution_DataServer_Logging_Warning:
+@GNOME_Evolution_DataServer_Logging_Message:
+@GNOME_Evolution_DataServer_Logging_Info:
+@GNOME_Evolution_DataServer_Logging_Debug:
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_0 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_11 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_12 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_13 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_14 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_15 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_16 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_17 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_18 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_19 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_Logging_Level ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### TYPEDEF GNOME_Evolution_DataServer_Logging_LogEvent ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_0 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_1 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_3 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_4 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_5 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_6 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_7 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_8 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_9 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_10 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_11 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_12 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_13 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_14 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_15 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_16 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_17 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_18 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_19 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_Logging_LogEvent ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_LogEvent__alloc ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_LogEvent__freekids ##### -->
+<para>
+
+</para>
+
+@m:
+@d:
+
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Config__epv ##### -->
+<para>
+
+</para>
+
+@_private:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Config__vepv ##### -->
+<para>
+
+</para>
+
+@_base_epv:
+@GNOME_Evolution_DataServer_Config_epv:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Config ##### -->
+<para>
+
+</para>
+
+@_private:
+@vepv:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_Config__init ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_Config__fini ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_InterfaceCheck__epv ##### -->
+<para>
+
+</para>
+
+@_private:
+@_get_interfaceVersion:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_InterfaceCheck__vepv ##### -->
+<para>
+
+</para>
+
+@_base_epv:
+@Bonobo_Unknown_epv:
+@GNOME_Evolution_DataServer_InterfaceCheck_epv:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_InterfaceCheck ##### -->
+<para>
+
+</para>
+
+@_private:
+@vepv:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_InterfaceCheck__init ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_InterfaceCheck__fini ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Logging__epv ##### -->
+<para>
+
+</para>
+
+@_private:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Logging__vepv ##### -->
+<para>
+
+</para>
+
+@_base_epv:
+@Bonobo_Unknown_epv:
+@Bonobo_EventSource_epv:
+@GNOME_Evolution_DataServer_Logging_epv:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Logging ##### -->
+<para>
+
+</para>
+
+@_private:
+@vepv:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_Logging__init ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_Logging__fini ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck_ref ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck_unref ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck_queryInterface ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION GNOME_Evolution_DataServer_InterfaceCheck__get_interfaceVersion ##### -->
+<para>
+
+</para>
+
+@_obj:
+@ev:
+@Returns:
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_ref ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_unref ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_queryInterface ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_addListener ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_addListenerWithMask ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_removeListener ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_unImplemented ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_unImplemented2 ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Config_IMETHODS_LEN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Config__imethods ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck_IMETHODS_LEN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_IMETHODS_LEN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging__imethods ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### ENUM GNOME_Evolution_DataServer_InterfaceCheck__imethods_index ##### -->
+<para>
+
+</para>
+
+@GNOME_Evolution_DataServer_InterfaceCheck__get_interfaceVersion__imethods_index:
+
+<!-- ##### MACRO ORBIT_IMETHODS_INDEX ##### -->
+<para>
+
+</para>
+
+@m:
+
+
diff --git a/doc/reference/shell/tmpl/action-groups.sgml b/doc/reference/shell/tmpl/action-groups.sgml
new file mode 100644
index 0000000000..5fe62d7ebb
--- /dev/null
+++ b/doc/reference/shell/tmpl/action-groups.sgml
@@ -0,0 +1,99 @@
+<!-- ##### SECTION Title ##### -->
+Action Groups
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_SHELL ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_SWITCHER ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_NEW_ITEM ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_NEW_SOURCE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_CUSTOM_RULES ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_GAL_VIEW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_APPLICATION_HANDLERS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_PRINTING ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_PRINT_SETUP ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_SAVE_TO_DISK ##### -->
+<para>
+
+</para>
+
+@window:
+
+
diff --git a/doc/reference/shell/tmpl/e-activity-handler.sgml b/doc/reference/shell/tmpl/e-activity-handler.sgml
new file mode 100644
index 0000000000..09d417213d
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-activity-handler.sgml
@@ -0,0 +1,19 @@
+<!-- ##### SECTION Title ##### -->
+EActivityHandler
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
diff --git a/doc/reference/shell/tmpl/e-config-upgrade.sgml b/doc/reference/shell/tmpl/e-config-upgrade.sgml
new file mode 100644
index 0000000000..0ef774b3dd
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-config-upgrade.sgml
@@ -0,0 +1,32 @@
+<!-- ##### SECTION Title ##### -->
+e-config-upgrade
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### FUNCTION e_config_upgrade ##### -->
+<para>
+
+</para>
+
+@major:
+@minor:
+@revision:
+@Returns:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-backend.sgml b/doc/reference/shell/tmpl/e-shell-backend.sgml
new file mode 100644
index 0000000000..10e2845d59
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-backend.sgml
@@ -0,0 +1,114 @@
+<!-- ##### SECTION Title ##### -->
+EShellBackend
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellBackend ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL EShellBackend::activity-added ##### -->
+<para>
+
+</para>
+
+@eshellbackend: the object which received the signal.
+@arg1:
+
+<!-- ##### ARG EShellBackend:shell ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION e_shell_backend_compare ##### -->
+<para>
+
+</para>
+
+@shell_backend_a:
+@shell_backend_b:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_backend_get_config_dir ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_backend_get_data_dir ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_backend_get_filename ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_backend_get_shell ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_backend_add_activity ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+@activity:
+
+
+<!-- ##### FUNCTION e_shell_backend_start ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+
+
+<!-- ##### FUNCTION e_shell_backend_migrate ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+@major:
+@minor:
+@micro:
+@error:
+@Returns:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-common.sgml b/doc/reference/shell/tmpl/e-shell-common.sgml
new file mode 100644
index 0000000000..1932480643
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-common.sgml
@@ -0,0 +1,21 @@
+<!-- ##### SECTION Title ##### -->
+e-shell-common
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-constants.sgml b/doc/reference/shell/tmpl/e-shell-constants.sgml
new file mode 100644
index 0000000000..74b95024a8
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-constants.sgml
@@ -0,0 +1,140 @@
+<!-- ##### SECTION Title ##### -->
+e-shell-constants
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO E_SHELL_URI_PREFIX ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SHELL_URI_PREFIX_LEN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SHELL_DEFAULTURI_PREFIX ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SHELL_DEFAULTURI_PREFIX_LEN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SHELL_MINI_ICON_SUFFIX ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SHELL_MINI_ICON_SUFFIX_LEN ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SHELL_ICON_SIZE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SHELL_MINI_ICON_SIZE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_PATH_SEPARATOR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_PATH_SEPARATOR_S ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_LOCAL_STORAGE_NAME ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SUMMARY_STORAGE_NAME ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_SUMMARY_URI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_LOCAL_INBOX_URI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_LOCAL_CONTACTS_URI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_LOCAL_CALENDAR_URI ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_LOCAL_TASKS_URI ##### -->
+<para>
+
+</para>
+
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-content.sgml b/doc/reference/shell/tmpl/e-shell-content.sgml
new file mode 100644
index 0000000000..2ffe528e98
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-content.sgml
@@ -0,0 +1,370 @@
+<!-- ##### SECTION Title ##### -->
+EShellContent
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellContent ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG EShellContent:filter-action ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:filter-value ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:filter-visible ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:scope-action ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:scope-value ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:scope-visible ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:search-context ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:search-hint ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:search-rule ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:search-text ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:search-visible ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellContent:shell-view ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION e_shell_content_new ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_check_state ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_get_shell_view ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_get_filter_action ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_filter_action ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@filter_action:
+
+
+<!-- ##### FUNCTION e_shell_content_get_filter_value ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_filter_value ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@filter_value:
+
+
+<!-- ##### FUNCTION e_shell_content_get_filter_visible ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_filter_visible ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@filter_visible:
+
+
+<!-- ##### FUNCTION e_shell_content_add_filter_separator_before ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@action_value:
+
+
+<!-- ##### FUNCTION e_shell_content_add_filter_separator_after ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@action_value:
+
+
+<!-- ##### FUNCTION e_shell_content_get_search_context ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_get_search_hint ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_search_hint ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@search_hint:
+
+
+<!-- ##### FUNCTION e_shell_content_get_search_rule ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_search_rule ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@search_rule:
+
+
+<!-- ##### FUNCTION e_shell_content_get_search_text ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_search_text ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@search_text:
+
+
+<!-- ##### FUNCTION e_shell_content_get_search_visible ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_search_visible ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@search_visible:
+
+
+<!-- ##### FUNCTION e_shell_content_get_scope_action ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_scope_action ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@scope_action:
+
+
+<!-- ##### FUNCTION e_shell_content_get_scope_value ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_scope_value ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@scope_value:
+
+
+<!-- ##### FUNCTION e_shell_content_get_scope_visible ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_scope_visible ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@scope_visible:
+
+
+<!-- ##### FUNCTION e_shell_content_get_view_id ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_content_set_view_id ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@view_id:
+
+
+<!-- ##### FUNCTION e_shell_content_run_advanced_search_dialog ##### -->
+<para>
+
+</para>
+
+@shell_content:
+
+
+<!-- ##### FUNCTION e_shell_content_run_edit_searches_dialog ##### -->
+<para>
+
+</para>
+
+@shell_content:
+
+
+<!-- ##### FUNCTION e_shell_content_run_save_search_dialog ##### -->
+<para>
+
+</para>
+
+@shell_content:
+
+
+<!-- ##### FUNCTION e_shell_content_restore_state ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@group_name:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-importer.sgml b/doc/reference/shell/tmpl/e-shell-importer.sgml
new file mode 100644
index 0000000000..0b3aa44506
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-importer.sgml
@@ -0,0 +1,27 @@
+<!-- ##### SECTION Title ##### -->
+e-shell-importer
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### FUNCTION e_shell_importer_start_import ##### -->
+<para>
+
+</para>
+
+@shell_window:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-marshal.sgml b/doc/reference/shell/tmpl/e-shell-marshal.sgml
new file mode 100644
index 0000000000..27f0c92196
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-marshal.sgml
@@ -0,0 +1,41 @@
+<!-- ##### SECTION Title ##### -->
+e-shell-marshal
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### FUNCTION e_shell_marshal_BOOLEAN__STRING ##### -->
+<para>
+
+</para>
+
+@closure:
+@return_value:
+@n_param_values:
+@param_values:
+@invocation_hint:
+@marshal_data:
+
+
+<!-- ##### MACRO e_shell_marshal_BOOL__STRING ##### -->
+<para>
+
+</para>
+
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-module.sgml b/doc/reference/shell/tmpl/e-shell-module.sgml
new file mode 100644
index 0000000000..f74773c9da
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-module.sgml
@@ -0,0 +1,180 @@
+<!-- ##### SECTION Title ##### -->
+EShellModule
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellModule ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL EShellModule::activity-added ##### -->
+<para>
+
+</para>
+
+@eshellmodule: the object which received the signal.
+@arg1:
+
+<!-- ##### ARG EShellModule:filename ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellModule:shell ##### -->
+<para>
+
+</para>
+
+<!-- ##### STRUCT EShellModuleInfo ##### -->
+<para>
+
+</para>
+
+@name:
+@aliases:
+@schemes:
+@sort_order:
+@start:
+@is_busy:
+@shutdown:
+@migrate:
+
+<!-- ##### FUNCTION e_shell_module_new ##### -->
+<para>
+
+</para>
+
+@shell:
+@filename:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_compare ##### -->
+<para>
+
+</para>
+
+@shell_module_a:
+@shell_module_b:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_get_config_dir ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_get_data_dir ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_get_filename ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_get_shell ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_get_shell_view_type ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_add_activity ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@activity:
+
+
+<!-- ##### FUNCTION e_shell_module_start ##### -->
+<para>
+
+</para>
+
+@shell_module:
+
+
+<!-- ##### FUNCTION e_shell_module_is_busy ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_shutdown ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_migrate ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@major:
+@minor:
+@micro:
+@error:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_module_set_info ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@info:
+@shell_view_type:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-settings.sgml b/doc/reference/shell/tmpl/e-shell-settings.sgml
new file mode 100644
index 0000000000..40ab7076b9
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-settings.sgml
@@ -0,0 +1,150 @@
+<!-- ##### SECTION Title ##### -->
+EShellSettings
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellSettings ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION e_shell_settings_install_property ##### -->
+<para>
+
+</para>
+
+@pspec:
+
+
+<!-- ##### FUNCTION e_shell_settings_install_property_for_key ##### -->
+<para>
+
+</para>
+
+@property_name:
+@gconf_key:
+
+
+<!-- ##### FUNCTION e_shell_settings_enable_debug ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+
+
+<!-- ##### FUNCTION e_shell_settings_get_boolean ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_settings_set_boolean ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@v_boolean:
+
+
+<!-- ##### FUNCTION e_shell_settings_get_int ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_settings_set_int ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@v_int:
+
+
+<!-- ##### FUNCTION e_shell_settings_get_string ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_settings_set_string ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@v_string:
+
+
+<!-- ##### FUNCTION e_shell_settings_get_object ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_settings_set_object ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@v_object:
+
+
+<!-- ##### FUNCTION e_shell_settings_get_pointer ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_settings_set_pointer ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@v_pointer:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-sidebar.sgml b/doc/reference/shell/tmpl/e-shell-sidebar.sgml
new file mode 100644
index 0000000000..45a55b127b
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-sidebar.sgml
@@ -0,0 +1,126 @@
+<!-- ##### SECTION Title ##### -->
+EShellSidebar
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellSidebar ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG EShellSidebar:icon-name ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellSidebar:primary-text ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellSidebar:secondary-text ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellSidebar:shell-view ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION e_shell_sidebar_new ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_sidebar_check_state ##### -->
+<para>
+
+</para>
+
+@shell_sidebar:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_sidebar_get_shell_view ##### -->
+<para>
+
+</para>
+
+@shell_sidebar:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_sidebar_get_icon_name ##### -->
+<para>
+
+</para>
+
+@shell_sidebar:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_sidebar_set_icon_name ##### -->
+<para>
+
+</para>
+
+@shell_sidebar:
+@icon_name:
+
+
+<!-- ##### FUNCTION e_shell_sidebar_get_primary_text ##### -->
+<para>
+
+</para>
+
+@shell_sidebar:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_sidebar_set_primary_text ##### -->
+<para>
+
+</para>
+
+@shell_sidebar:
+@primary_text:
+
+
+<!-- ##### FUNCTION e_shell_sidebar_get_secondary_text ##### -->
+<para>
+
+</para>
+
+@shell_sidebar:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_sidebar_set_secondary_text ##### -->
+<para>
+
+</para>
+
+@shell_sidebar:
+@secondary_text:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-switcher.sgml b/doc/reference/shell/tmpl/e-shell-switcher.sgml
new file mode 100644
index 0000000000..f656b65988
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-switcher.sgml
@@ -0,0 +1,104 @@
+<!-- ##### SECTION Title ##### -->
+EShellSwitcher
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellSwitcher ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL EShellSwitcher::style-changed ##### -->
+<para>
+
+</para>
+
+@eshellswitcher: the object which received the signal.
+@arg1:
+
+<!-- ##### ARG EShellSwitcher:toolbar-style ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellSwitcher:toolbar-visible ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION e_shell_switcher_new ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_switcher_add_action ##### -->
+<para>
+
+</para>
+
+@switcher:
+@action:
+
+
+<!-- ##### FUNCTION e_shell_switcher_get_style ##### -->
+<para>
+
+</para>
+
+@switcher:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_switcher_set_style ##### -->
+<para>
+
+</para>
+
+@switcher:
+@style:
+
+
+<!-- ##### FUNCTION e_shell_switcher_unset_style ##### -->
+<para>
+
+</para>
+
+@switcher:
+
+
+<!-- ##### FUNCTION e_shell_switcher_get_visible ##### -->
+<para>
+
+</para>
+
+@switcher:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_switcher_set_visible ##### -->
+<para>
+
+</para>
+
+@switcher:
+@visible:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-taskbar.sgml b/doc/reference/shell/tmpl/e-shell-taskbar.sgml
new file mode 100644
index 0000000000..6aa90f1c72
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-taskbar.sgml
@@ -0,0 +1,79 @@
+<!-- ##### SECTION Title ##### -->
+EShellTaskbar
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellTaskbar ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG EShellTaskbar:message ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellTaskbar:shell-view ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION e_shell_taskbar_new ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_taskbar_get_shell_view ##### -->
+<para>
+
+</para>
+
+@shell_taskbar:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_taskbar_get_message ##### -->
+<para>
+
+</para>
+
+@shell_taskbar:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_taskbar_set_message ##### -->
+<para>
+
+</para>
+
+@shell_taskbar:
+@message:
+
+
+<!-- ##### FUNCTION e_shell_taskbar_unset_message ##### -->
+<para>
+
+</para>
+
+@shell_taskbar:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-view.sgml b/doc/reference/shell/tmpl/e-shell-view.sgml
new file mode 100644
index 0000000000..408e869528
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-view.sgml
@@ -0,0 +1,284 @@
+<!-- ##### SECTION Title ##### -->
+EShellView
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellView ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL EShellView::toggled ##### -->
+<para>
+
+</para>
+
+@eshellview: the object which received the signal.
+
+<!-- ##### SIGNAL EShellView::update-actions ##### -->
+<para>
+
+</para>
+
+@eshellview: the object which received the signal.
+
+<!-- ##### ARG EShellView:action ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellView:page-num ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellView:shell-backend ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellView:shell-content ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellView:shell-sidebar ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellView:shell-taskbar ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellView:shell-window ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellView:title ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellView:view-id ##### -->
+<para>
+
+</para>
+
+<!-- ##### STRUCT EShellViewClass ##### -->
+<para>
+
+</para>
+
+@parent_class:
+@label:
+@icon_name:
+@ui_definition:
+@ui_manager_id:
+@search_options:
+@search_rules:
+@view_collection:
+@shell_backend:
+@new_shell_content:
+@new_shell_sidebar:
+@new_shell_taskbar:
+@toggled:
+@update_actions:
+
+<!-- ##### FUNCTION e_shell_view_get_name ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_action ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_title ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_set_title ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@title:
+
+
+<!-- ##### FUNCTION e_shell_view_get_view_id ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_set_view_id ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@view_id:
+
+
+<!-- ##### FUNCTION e_shell_view_is_active ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_page_num ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_set_page_num ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@page_num:
+
+
+<!-- ##### FUNCTION e_shell_view_get_size_group ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_shell_backend ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_shell_content ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_shell_sidebar ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_shell_taskbar ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_shell_window ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_get_state_key_file ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_view_set_state_dirty ##### -->
+<para>
+
+</para>
+
+@shell_view:
+
+
+<!-- ##### FUNCTION e_shell_view_update_actions ##### -->
+<para>
+
+</para>
+
+@shell_view:
+
+
+<!-- ##### FUNCTION e_shell_view_show_popup_menu ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@widget_path:
+@event:
+
+
+<!-- ##### FUNCTION e_shell_view_new_view_instance ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@instance_id:
+@Returns:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-window-actions.sgml b/doc/reference/shell/tmpl/e-shell-window-actions.sgml
new file mode 100644
index 0000000000..48e6f44203
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-window-actions.sgml
@@ -0,0 +1,309 @@
+<!-- ##### SECTION Title ##### -->
+Global Actions
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION ##### -->
+<para>
+
+</para>
+
+@window:
+@name:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP ##### -->
+<para>
+
+</para>
+
+@window:
+@name:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_ABOUT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_CLOSE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_FAQ ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_FORGET_PASSWORDS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GAL_CUSTOM_VIEW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GAL_DEFINE_VIEWS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GAL_SAVE_CUSTOM_VIEW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GAL_VIEW_MENU ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_IMPORT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_NEW_WINDOW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_PAGE_SETUP ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_PREFERENCES ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_QUICK_REFERENCE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_QUIT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_ADVANCED ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_CLEAR ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_EDIT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_SAVE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEND_RECEIVE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_SWITCHER ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SUBMIT_BUG ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SYNC_OPTIONS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_WORK_OFFLINE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_WORK_ONLINE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_GAL_VIEW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_NEW_ITEM ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_NEW_SOURCE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_SHELL ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_SHELL_VIEW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-window-private.sgml b/doc/reference/shell/tmpl/e-shell-window-private.sgml
new file mode 100644
index 0000000000..6c1c6d0e72
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-window-private.sgml
@@ -0,0 +1,25 @@
+<!-- ##### SECTION Title ##### -->
+e-shell-window-private
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellWindowPrivate ##### -->
+<para>
+
+</para>
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-window.sgml b/doc/reference/shell/tmpl/e-shell-window.sgml
new file mode 100644
index 0000000000..9571632bae
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell-window.sgml
@@ -0,0 +1,190 @@
+<!-- ##### SECTION Title ##### -->
+EShellWindow
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShellWindow ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG EShellWindow:active-view ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellWindow:safe-mode ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellWindow:shell ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellWindow:ui-manager ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION e_shell_window_new ##### -->
+<para>
+
+</para>
+
+@shell:
+@safe_mode:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_get_shell ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_get_shell_view ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@view_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_get_shell_view_action ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@view_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_get_ui_manager ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_get_action ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@action_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_get_action_group ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@group_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_get_managed_widget ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@widget_path:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_get_active_view ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_set_active_view ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@view_name:
+
+
+<!-- ##### FUNCTION e_shell_window_get_safe_mode ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_window_set_safe_mode ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@safe_mode:
+
+
+<!-- ##### FUNCTION e_shell_window_add_action_group ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@group_name:
+
+
+<!-- ##### FUNCTION e_shell_window_register_new_item_actions ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@backend_name:
+@entries:
+@n_entries:
+
+
+<!-- ##### FUNCTION e_shell_window_register_new_source_actions ##### -->
+<para>
+
+</para>
+
+@shell_window:
+@backend_name:
+@entries:
+@n_entries:
+
+
diff --git a/doc/reference/shell/tmpl/e-shell.sgml b/doc/reference/shell/tmpl/e-shell.sgml
new file mode 100644
index 0000000000..a34a083b7c
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-shell.sgml
@@ -0,0 +1,310 @@
+<!-- ##### SECTION Title ##### -->
+EShell
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EShell ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL EShell::event ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@Param2:
+
+<!-- ##### SIGNAL EShell::handle-uri ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@arg1:
+@Returns:
+
+<!-- ##### SIGNAL EShell::prepare-for-offline ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL EShell::prepare-for-online ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL EShell::prepare-for-quit ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL EShell::quit-requested ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+
+<!-- ##### SIGNAL EShell::send-receive ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL EShell::window-created ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL EShell::window-destroyed ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+
+<!-- ##### ARG EShell:network-available ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShell:online ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShell:shell-settings ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION e_shell_get_default ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_get_shell_backends ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_get_canonical_name ##### -->
+<para>
+
+</para>
+
+@shell:
+@name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_get_backend_by_name ##### -->
+<para>
+
+</para>
+
+@shell:
+@name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_get_backend_by_scheme ##### -->
+<para>
+
+</para>
+
+@shell:
+@scheme:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_get_shell_settings ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_get_gconf_client ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_create_shell_window ##### -->
+<para>
+
+</para>
+
+@shell:
+@view_name:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_handle_uris ##### -->
+<para>
+
+</para>
+
+@shell:
+@uris:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_watch_window ##### -->
+<para>
+
+</para>
+
+@shell:
+@window:
+
+
+<!-- ##### FUNCTION e_shell_get_watched_windows ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_send_receive ##### -->
+<para>
+
+</para>
+
+@shell:
+@parent:
+
+
+<!-- ##### FUNCTION e_shell_get_network_available ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_set_network_available ##### -->
+<para>
+
+</para>
+
+@shell:
+@network_available:
+
+
+<!-- ##### FUNCTION e_shell_get_online ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_set_online ##### -->
+<para>
+
+</para>
+
+@shell:
+@online:
+
+
+<!-- ##### FUNCTION e_shell_get_preferences_window ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+
+<!-- ##### FUNCTION e_shell_event ##### -->
+<para>
+
+</para>
+
+@shell:
+@event_name:
+@event_data:
+
+
+<!-- ##### FUNCTION e_shell_quit ##### -->
+<para>
+
+</para>
+
+@shell:
+
+
+<!-- ##### FUNCTION e_shell_cancel_quit ##### -->
+<para>
+
+</para>
+
+@shell:
+
+
+<!-- ##### MACRO E_SHELL_MIGRATE_ERROR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### FUNCTION e_shell_migrate_attempt ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+
diff --git a/doc/reference/shell/tmpl/e-test-shell-view.sgml b/doc/reference/shell/tmpl/e-test-shell-view.sgml
new file mode 100644
index 0000000000..2c9c912c20
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-test-shell-view.sgml
@@ -0,0 +1,41 @@
+<!-- ##### SECTION Title ##### -->
+ETestShellView
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### VARIABLE e_test_shell_view_type ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ETestShellViewPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ETestShellView ##### -->
+<para>
+
+</para>
+
+@parent:
+@priv:
+
diff --git a/doc/reference/shell/tmpl/es-event.sgml b/doc/reference/shell/tmpl/es-event.sgml
new file mode 100644
index 0000000000..8821e92ad5
--- /dev/null
+++ b/doc/reference/shell/tmpl/es-event.sgml
@@ -0,0 +1,147 @@
+<!-- ##### SECTION Title ##### -->
+ESEventHook
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### ENUM es_event_target_t ##### -->
+<para>
+
+</para>
+
+@ES_EVENT_TARGET_STATE:
+@ES_EVENT_TARGET_UPGRADE:
+@ES_EVENT_TARGET_SHELL:
+@ES_EVENT_TARGET_COMPONENT:
+
+<!-- ##### STRUCT ESEventTargetState ##### -->
+<para>
+
+</para>
+
+@target:
+@state:
+
+<!-- ##### STRUCT ESEventTargetUpgrade ##### -->
+<para>
+
+</para>
+
+@target:
+@major:
+@minor:
+@revision:
+
+<!-- ##### STRUCT ESEventTargetShell ##### -->
+<para>
+
+</para>
+
+@target:
+
+<!-- ##### STRUCT ESEventTargetComponent ##### -->
+<para>
+
+</para>
+
+@target:
+@id:
+
+<!-- ##### TYPEDEF ESEventItem ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ESEvent ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION es_event_get_type ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION es_event_peek ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION es_event_target_new ##### -->
+<para>
+
+</para>
+
+@eme:
+@Returns:
+
+
+<!-- ##### FUNCTION es_event_target_new_state ##### -->
+<para>
+
+</para>
+
+@emp:
+@state:
+@Returns:
+
+
+<!-- ##### FUNCTION es_event_target_new_upgrade ##### -->
+<para>
+
+</para>
+
+@emp:
+@major:
+@minor:
+@revision:
+@Returns:
+
+
+<!-- ##### FUNCTION es_event_target_new_component ##### -->
+<para>
+
+</para>
+
+@eme:
+@id:
+@Returns:
+
+
+<!-- ##### STRUCT ESEventHook ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION es_event_hook_get_type ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
diff --git a/doc/reference/shell/tmpl/eshell-unused.sgml b/doc/reference/shell/tmpl/eshell-unused.sgml
new file mode 100644
index 0000000000..827e2a95f5
--- /dev/null
+++ b/doc/reference/shell/tmpl/eshell-unused.sgml
@@ -0,0 +1,2384 @@
+<!-- ##### SECTION ./tmpl/Evolution-DataServer.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/Evolution-DataServer.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/Evolution-DataServer.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/Evolution-DataServer.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/Evolution-DataServer.sgml:Title ##### -->
+Evolution-DataServer
+
+
+<!-- ##### SECTION ./tmpl/e-activity-handler.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-activity-handler.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-activity-handler.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-activity-handler.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-activity-handler.sgml:Title ##### -->
+EActivityHandler
+
+
+<!-- ##### SECTION ./tmpl/e-config-upgrade.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-config-upgrade.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-config-upgrade.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-config-upgrade.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-config-upgrade.sgml:Title ##### -->
+e-config-upgrade
+
+
+<!-- ##### SECTION ./tmpl/e-shell-common.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-common.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-common.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-common.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-common.sgml:Title ##### -->
+e-shell-common
+
+
+<!-- ##### SECTION ./tmpl/e-shell-constants.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-constants.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-constants.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-constants.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-constants.sgml:Title ##### -->
+e-shell-constants
+
+
+<!-- ##### SECTION ./tmpl/e-shell-marshal.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-marshal.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-marshal.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-marshal.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-marshal.sgml:Title ##### -->
+e-shell-marshal
+
+
+<!-- ##### SECTION ./tmpl/e-shell-migrate.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-migrate.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-migrate.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-migrate.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-migrate.sgml:Title ##### -->
+Migration
+
+
+<!-- ##### SECTION ./tmpl/e-shell-module.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-module.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-module.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-module.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-module.sgml:Title ##### -->
+EShellModule
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-actions.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-actions.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-actions.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-actions.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-actions.sgml:Title ##### -->
+Global Actions
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-private.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-private.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-private.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-private.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-shell-window-private.sgml:Title ##### -->
+e-shell-window-private
+
+
+<!-- ##### SECTION ./tmpl/e-test-shell-view.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-test-shell-view.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-test-shell-view.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-test-shell-view.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-test-shell-view.sgml:Title ##### -->
+ETestShellView
+
+
+<!-- ##### SECTION ./tmpl/es-event.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/es-event.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/es-event.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/es-event.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/es-event.sgml:Title ##### -->
+ESEventHook
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-client.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-client.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-client.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-client.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-client.sgml:Title ##### -->
+EvolutionImporterClient
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-listener.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-listener.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-listener.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-listener.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer-listener.sgml:Title ##### -->
+EvolutionImporterListener
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/evolution-importer.sgml:Title ##### -->
+EvolutionImporter
+
+
+<!-- ##### SECTION ./tmpl/evolution-intelligent-importer.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/evolution-intelligent-importer.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/evolution-intelligent-importer.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/evolution-intelligent-importer.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/evolution-intelligent-importer.sgml:Title ##### -->
+EvolutionIntelligentImporter
+
+
+<!-- ##### SECTION ./tmpl/intelligent.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/intelligent.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/intelligent.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/intelligent.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/intelligent.sgml:Title ##### -->
+intelligent
+
+
+<!-- ##### STRUCT ESEvent ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ESEventHook ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### TYPEDEF ESEventItem ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ESEventTargetComponent ##### -->
+<para>
+
+</para>
+
+@target:
+@id:
+
+<!-- ##### STRUCT ESEventTargetShell ##### -->
+<para>
+
+</para>
+
+@target:
+
+<!-- ##### STRUCT ESEventTargetState ##### -->
+<para>
+
+</para>
+
+@target:
+@state:
+
+<!-- ##### STRUCT ESEventTargetUpgrade ##### -->
+<para>
+
+</para>
+
+@target:
+@major:
+@minor:
+@revision:
+
+<!-- ##### SIGNAL EShell::prepare-for-shutdown ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@arg1:
+
+<!-- ##### ARG EShell:online-mode ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG EShell:settings ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG EShellContent:search-value ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ENUM EShellLineStatus ##### -->
+<para>
+
+</para>
+
+@E_SHELL_LINE_STATUS_ONLINE:
+@E_SHELL_LINE_STATUS_GOING_OFFLINE:
+@E_SHELL_LINE_STATUS_OFFLINE:
+@E_SHELL_LINE_STATUS_FORCED_OFFLINE:
+
+<!-- ##### STRUCT EShellModule ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL EShellModule::activity-added ##### -->
+<para>
+
+</para>
+
+@eshellmodule: the object which received the signal.
+@arg1:
+
+<!-- ##### ARG EShellModule:filename ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG EShellModule:shell ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT EShellModuleInfo ##### -->
+<para>
+
+</para>
+
+@name:
+@aliases:
+@schemes:
+@sort_order:
+@start:
+@is_busy:
+@shutdown:
+@migrate:
+
+<!-- ##### SIGNAL EShellView::capture-state ##### -->
+<para>
+
+</para>
+
+@eshellview: the object which received the signal.
+@arg1:
+
+<!-- ##### SIGNAL EShellView::restore-state ##### -->
+<para>
+
+</para>
+
+@eshellview: the object which received the signal.
+@arg1:
+
+<!-- ##### ARG EShellView:shell-module ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT EShellWindowPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT ETestShellView ##### -->
+<para>
+
+</para>
+
+@parent:
+@priv:
+
+<!-- ##### STRUCT ETestShellViewPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_LOCAL_CALENDAR_URI ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_LOCAL_CONTACTS_URI ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_LOCAL_INBOX_URI ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_LOCAL_STORAGE_NAME ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_LOCAL_TASKS_URI ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_PATH_SEPARATOR ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_PATH_SEPARATOR_S ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_DEFAULTURI_PREFIX ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_DEFAULTURI_PREFIX_LEN ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_ICON_SIZE ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_MINI_ICON_SIZE ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_MINI_ICON_SUFFIX ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_MINI_ICON_SUFFIX_LEN ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_UPGRADE_ERROR ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_URI_PREFIX ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_URI_PREFIX_LEN ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION ##### -->
+<para>
+
+</para>
+
+@window:
+@name:
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GAL_VIEW_MENU ##### -->
+<para>
+
+</para>
+
+@window:
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP ##### -->
+<para>
+
+</para>
+
+@window:
+@name:
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GROUP_SHELL_VIEW ##### -->
+<para>
+
+</para>
+
+@window:
+
+<!-- ##### MACRO E_SUMMARY_STORAGE_NAME ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO E_SUMMARY_URI ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### STRUCT EvolutionImporter ##### -->
+<para>
+
+</para>
+
+@parent:
+@priv:
+
+<!-- ##### STRUCT EvolutionImporterClient ##### -->
+<para>
+
+</para>
+
+@parent_type:
+@objref:
+
+<!-- ##### USER_FUNCTION EvolutionImporterCreateControlFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@control:
+@closure:
+
+<!-- ##### USER_FUNCTION EvolutionImporterGetErrorFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@closure:
+@Returns:
+
+<!-- ##### STRUCT EvolutionImporterListener ##### -->
+<para>
+
+</para>
+
+@parent:
+@priv:
+
+<!-- ##### USER_FUNCTION EvolutionImporterListenerCallback ##### -->
+<para>
+
+</para>
+
+@listener:
+@result:
+@more_items:
+@closure:
+
+<!-- ##### STRUCT EvolutionImporterListenerPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### USER_FUNCTION EvolutionImporterLoadFileFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@filename:
+@closure:
+@Returns:
+
+<!-- ##### STRUCT EvolutionImporterPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### USER_FUNCTION EvolutionImporterProcessItemFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@listener:
+@closure:
+@ev:
+
+<!-- ##### ENUM EvolutionImporterResult ##### -->
+<para>
+
+</para>
+
+@EVOLUTION_IMPORTER_OK:
+@EVOLUTION_IMPORTER_UNSUPPORTED_OPERATION:
+@EVOLUTION_IMPORTER_INTERRUPTED:
+@EVOLUTION_IMPORTER_BUSY:
+@EVOLUTION_IMPORTER_NOT_READY:
+@EVOLUTION_IMPORTER_UNKNOWN_DATA:
+@EVOLUTION_IMPORTER_BAD_DATA:
+@EVOLUTION_IMPORTER_BAD_FILE:
+@EVOLUTION_IMPORTER_UNKNOWN_ERROR:
+
+<!-- ##### USER_FUNCTION EvolutionImporterSupportFormatFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@filename:
+@closure:
+@Returns:
+
+<!-- ##### STRUCT EvolutionIntelligentImporter ##### -->
+<para>
+
+</para>
+
+@parent:
+@priv:
+
+<!-- ##### USER_FUNCTION EvolutionIntelligentImporterCanImportFn ##### -->
+<para>
+
+</para>
+
+@ii:
+@closure:
+@Returns:
+
+<!-- ##### USER_FUNCTION EvolutionIntelligentImporterImportDataFn ##### -->
+<para>
+
+</para>
+
+@ii:
+@closure:
+
+<!-- ##### STRUCT EvolutionIntelligentImporterPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### TYPEDEF GNOME_Evolution_DataServer_Config ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Config_IMETHODS_LEN ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### VARIABLE GNOME_Evolution_DataServer_Config__classid ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Config__freekids ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Config__imethods ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### TYPEDEF GNOME_Evolution_DataServer_InterfaceCheck ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck_IMETHODS_LEN ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### VARIABLE GNOME_Evolution_DataServer_InterfaceCheck__classid ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck__freekids ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION GNOME_Evolution_DataServer_InterfaceCheck__get_interfaceVersion ##### -->
+<para>
+
+</para>
+
+@_obj:
+@ev:
+@Returns:
+
+<!-- ##### ENUM GNOME_Evolution_DataServer_InterfaceCheck__imethods_index ##### -->
+<para>
+
+</para>
+
+@GNOME_Evolution_DataServer_InterfaceCheck__get_interfaceVersion__imethods_index:
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck_queryInterface ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck_ref ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_InterfaceCheck_unref ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### TYPEDEF GNOME_Evolution_DataServer_Logging ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_IMETHODS_LEN ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ENUM GNOME_Evolution_DataServer_Logging_Level ##### -->
+<para>
+
+</para>
+
+@GNOME_Evolution_DataServer_Logging_Error:
+@GNOME_Evolution_DataServer_Logging_Critical:
+@GNOME_Evolution_DataServer_Logging_Warning:
+@GNOME_Evolution_DataServer_Logging_Message:
+@GNOME_Evolution_DataServer_Logging_Info:
+@GNOME_Evolution_DataServer_Logging_Debug:
+
+<!-- ##### TYPEDEF GNOME_Evolution_DataServer_Logging_LogEvent ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_LogEvent__alloc ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_LogEvent__freekids ##### -->
+<para>
+
+</para>
+
+@m:
+@d:
+
+<!-- ##### VARIABLE GNOME_Evolution_DataServer_Logging__classid ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging__freekids ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging__imethods ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_addListener ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_addListenerWithMask ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_queryInterface ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_ref ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_removeListener ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_unImplemented ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_unImplemented2 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO GNOME_Evolution_DataServer_Logging_unref ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO ORBIT_DECL_GNOME_Evolution_DataServer_Config ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO ORBIT_DECL_GNOME_Evolution_DataServer_InterfaceCheck ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO ORBIT_DECL_GNOME_Evolution_DataServer_Logging ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO ORBIT_IDL_SERIAL ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO ORBIT_IMETHODS_INDEX ##### -->
+<para>
+
+</para>
+
+@m:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Config ##### -->
+<para>
+
+</para>
+
+@_private:
+@vepv:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Config__epv ##### -->
+<para>
+
+</para>
+
+@_private:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_Config__fini ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_Config__init ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Config__vepv ##### -->
+<para>
+
+</para>
+
+@_base_epv:
+@GNOME_Evolution_DataServer_Config_epv:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_InterfaceCheck ##### -->
+<para>
+
+</para>
+
+@_private:
+@vepv:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_InterfaceCheck__epv ##### -->
+<para>
+
+</para>
+
+@_private:
+@_get_interfaceVersion:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_InterfaceCheck__fini ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_InterfaceCheck__init ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_InterfaceCheck__vepv ##### -->
+<para>
+
+</para>
+
+@_base_epv:
+@Bonobo_Unknown_epv:
+@GNOME_Evolution_DataServer_InterfaceCheck_epv:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Logging ##### -->
+<para>
+
+</para>
+
+@_private:
+@vepv:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Logging__epv ##### -->
+<para>
+
+</para>
+
+@_private:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_Logging__fini ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+<!-- ##### FUNCTION POA_GNOME_Evolution_DataServer_Logging__init ##### -->
+<para>
+
+</para>
+
+@servant:
+@ev:
+
+<!-- ##### STRUCT POA_GNOME_Evolution_DataServer_Logging__vepv ##### -->
+<para>
+
+</para>
+
+@_base_epv:
+@Bonobo_Unknown_epv:
+@Bonobo_EventSource_epv:
+@GNOME_Evolution_DataServer_Logging_epv:
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_Config ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_InterfaceCheck ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_Logging ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_Logging_Level ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_GNOME_Evolution_DataServer_Logging_LogEvent ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_0 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_1 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_10 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_11 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_12 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_13 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_14 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_15 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_16 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_17 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_18 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_19 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_2 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_3 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_4 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_5 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_6 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_7 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_8 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Config_9 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_0 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_1 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_10 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_11 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_12 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_13 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_14 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_15 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_16 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_17 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_18 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_19 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_2 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_3 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_4 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_5 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_6 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_7 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_8 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_InterfaceCheck_9 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_0 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_1 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_10 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_11 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_12 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_13 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_14 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_15 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_16 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_17 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_18 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_19 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_2 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_3 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_4 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_5 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_6 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_7 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_8 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_9 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_0 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_1 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_10 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_11 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_12 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_13 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_14 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_15 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_16 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_17 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_18 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_19 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_2 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_3 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_4 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_5 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_6 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_7 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_8 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_Level_9 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_0 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_1 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_10 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_11 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_12 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_13 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_14 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_15 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_16 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_17 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_18 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_19 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_2 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_3 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_4 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_5 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_6 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_7 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_8 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO TC_IMPL_TC_GNOME_Evolution_DataServer_Logging_LogEvent_9 ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION e_config_upgrade ##### -->
+<para>
+
+</para>
+
+@major:
+@minor:
+@revision:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_backend_is_busy ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_backend_shutdown ##### -->
+<para>
+
+</para>
+
+@shell_backend:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_content_get_context ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_content_get_search_value ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_content_set_context ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@context:
+
+<!-- ##### FUNCTION e_shell_content_set_search_value ##### -->
+<para>
+
+</para>
+
+@shell_content:
+@search_value:
+
+<!-- ##### FUNCTION e_shell_create_window ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_do_quit ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_get_focused_window ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_get_line_status ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_get_module_by_name ##### -->
+<para>
+
+</para>
+
+@shell:
+@name:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_get_module_by_scheme ##### -->
+<para>
+
+</para>
+
+@shell:
+@scheme:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_get_online_mode ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_get_settings ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_get_shell_modules ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_get_shell_windows ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_handle_uri ##### -->
+<para>
+
+</para>
+
+@shell:
+@uri:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_is_busy ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_list_modules ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_list_shell_modules ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_list_shell_windows ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_marshal_BOOLEAN__STRING ##### -->
+<para>
+
+</para>
+
+@closure:
+@return_value:
+@n_param_values:
+@param_values:
+@invocation_hint:
+@marshal_data:
+
+<!-- ##### MACRO e_shell_marshal_BOOL__STRING ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION e_shell_migrate_error_quark ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_add_activity ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@activity:
+
+<!-- ##### FUNCTION e_shell_module_compare ##### -->
+<para>
+
+</para>
+
+@shell_module_a:
+@shell_module_b:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_get_config_dir ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_get_data_dir ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_get_filename ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_get_shell ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_get_shell_view_type ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_is_busy ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_migrate ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@major:
+@minor:
+@micro:
+@error:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_new ##### -->
+<para>
+
+</para>
+
+@shell:
+@filename:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_set_info ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@info:
+@shell_view_type:
+
+<!-- ##### FUNCTION e_shell_module_shutdown ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_module_start ##### -->
+<para>
+
+</para>
+
+@shell_module:
+
+<!-- ##### FUNCTION e_shell_module_upgrade ##### -->
+<para>
+
+</para>
+
+@shell_module:
+@major:
+@minor:
+@micro:
+@error:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_new ##### -->
+<para>
+
+</para>
+
+@online:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_set_line_status ##### -->
+<para>
+
+</para>
+
+@shell:
+@status:
+
+<!-- ##### FUNCTION e_shell_set_online_mode ##### -->
+<para>
+
+</para>
+
+@shell:
+@online_mode:
+
+<!-- ##### FUNCTION e_shell_settings_bind_to_gconf ##### -->
+<para>
+
+</para>
+
+@shell_settings:
+@property_name:
+@gconf_key:
+
+<!-- ##### FUNCTION e_shell_upgrade_attempt ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
+<!-- ##### FUNCTION e_shell_view_get_shell_module ##### -->
+<para>
+
+</para>
+
+@shell_view:
+@Returns:
+
+<!-- ##### VARIABLE e_test_shell_view_type ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION es_event_get_type ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+<!-- ##### FUNCTION es_event_hook_get_type ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+<!-- ##### FUNCTION es_event_peek ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+<!-- ##### FUNCTION es_event_target_new ##### -->
+<para>
+
+</para>
+
+@eme:
+@Returns:
+
+<!-- ##### FUNCTION es_event_target_new_component ##### -->
+<para>
+
+</para>
+
+@eme:
+@id:
+@Returns:
+
+<!-- ##### FUNCTION es_event_target_new_state ##### -->
+<para>
+
+</para>
+
+@emp:
+@state:
+@Returns:
+
+<!-- ##### FUNCTION es_event_target_new_upgrade ##### -->
+<para>
+
+</para>
+
+@emp:
+@major:
+@minor:
+@revision:
+@Returns:
+
+<!-- ##### ENUM es_event_target_t ##### -->
+<para>
+
+</para>
+
+@ES_EVENT_TARGET_STATE:
+@ES_EVENT_TARGET_UPGRADE:
+@ES_EVENT_TARGET_SHELL:
+@ES_EVENT_TARGET_COMPONENT:
+
+<!-- ##### FUNCTION evolution_importer_client_create_control ##### -->
+<para>
+
+</para>
+
+@client:
+@Returns:
+
+<!-- ##### FUNCTION evolution_importer_client_get_error ##### -->
+<para>
+
+</para>
+
+@client:
+@Returns:
+
+<!-- ##### FUNCTION evolution_importer_client_load_file ##### -->
+<para>
+
+</para>
+
+@client:
+@filename:
+@Returns:
+
+<!-- ##### FUNCTION evolution_importer_client_new ##### -->
+<para>
+
+</para>
+
+@objref:
+@Returns:
+
+<!-- ##### FUNCTION evolution_importer_client_new_from_id ##### -->
+<para>
+
+</para>
+
+@id:
+@Returns:
+
+<!-- ##### FUNCTION evolution_importer_client_process_item ##### -->
+<para>
+
+</para>
+
+@client:
+@listener:
+
+<!-- ##### FUNCTION evolution_importer_client_support_format ##### -->
+<para>
+
+</para>
+
+@client:
+@filename:
+@Returns:
+
+<!-- ##### FUNCTION evolution_importer_listener_new ##### -->
+<para>
+
+</para>
+
+@callback:
+@closure:
+@Returns:
+
+<!-- ##### FUNCTION evolution_importer_new ##### -->
+<para>
+
+</para>
+
+@create_control_fn:
+@support_format_fn:
+@load_file_fn:
+@process_item_fn:
+@get_error_fn:
+@closure:
+@Returns:
+
+<!-- ##### FUNCTION evolution_intelligent_importer_new ##### -->
+<para>
+
+</para>
+
+@can_import_fn:
+@import_data_fn:
+@importername:
+@message:
+@closure:
+@Returns:
+
+<!-- ##### FUNCTION intelligent_importer_init ##### -->
+<para>
+
+</para>
+
+
diff --git a/doc/devel/importer/tmpl/evolution-importer-client.sgml b/doc/reference/shell/tmpl/evolution-importer-client.sgml
index 6cee37bef1..db2acb621a 100644
--- a/doc/devel/importer/tmpl/evolution-importer-client.sgml
+++ b/doc/reference/shell/tmpl/evolution-importer-client.sgml
@@ -2,25 +2,30 @@
EvolutionImporterClient
<!-- ##### SECTION Short_Description ##### -->
-A #GtkObject based client to simplify use of a GNOME_Evolution_Importer object.
+
<!-- ##### SECTION Long_Description ##### -->
<para>
-This #GtkObject provides a convience wrapper to the GNOME_Evolution_Importer object, providing error checking and hiding all the CORBA internals from the user.
+
</para>
+
<!-- ##### SECTION See_Also ##### -->
<para>
</para>
-<!-- ##### MACRO EVOLUTION_IMPORTER_CLIENT ##### -->
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EvolutionImporterClient ##### -->
<para>
-Casts a #GtkObject into an #EvolutionImporterClient
-</para>
-@obj: A #GtkObject
+</para>
+@parent_type:
+@objref:
<!-- ##### FUNCTION evolution_importer_client_new ##### -->
<para>
@@ -40,6 +45,15 @@ Casts a #GtkObject into an #EvolutionImporterClient
@Returns:
+<!-- ##### FUNCTION evolution_importer_client_create_control ##### -->
+<para>
+
+</para>
+
+@client:
+@Returns:
+
+
<!-- ##### FUNCTION evolution_importer_client_support_format ##### -->
<para>
@@ -57,7 +71,6 @@ Casts a #GtkObject into an #EvolutionImporterClient
@client:
@filename:
-@folderpath:
@Returns:
@@ -68,9 +81,6 @@ Casts a #GtkObject into an #EvolutionImporterClient
@client:
@listener:
-<!-- # Unused Parameters # -->
-@callback:
-@closure:
<!-- ##### FUNCTION evolution_importer_client_get_error ##### -->
diff --git a/doc/reference/shell/tmpl/evolution-importer-listener.sgml b/doc/reference/shell/tmpl/evolution-importer-listener.sgml
new file mode 100644
index 0000000000..7b0b3ab488
--- /dev/null
+++ b/doc/reference/shell/tmpl/evolution-importer-listener.sgml
@@ -0,0 +1,56 @@
+<!-- ##### SECTION Title ##### -->
+EvolutionImporterListener
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EvolutionImporterListenerPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### USER_FUNCTION EvolutionImporterListenerCallback ##### -->
+<para>
+
+</para>
+
+@listener:
+@result:
+@more_items:
+@closure:
+
+
+<!-- ##### STRUCT EvolutionImporterListener ##### -->
+<para>
+
+</para>
+
+@parent:
+@priv:
+
+<!-- ##### FUNCTION evolution_importer_listener_new ##### -->
+<para>
+
+</para>
+
+@callback:
+@closure:
+@Returns:
+
+
diff --git a/doc/reference/shell/tmpl/evolution-importer.sgml b/doc/reference/shell/tmpl/evolution-importer.sgml
new file mode 100644
index 0000000000..c092138c60
--- /dev/null
+++ b/doc/reference/shell/tmpl/evolution-importer.sgml
@@ -0,0 +1,117 @@
+<!-- ##### SECTION Title ##### -->
+EvolutionImporter
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EvolutionImporterPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### USER_FUNCTION EvolutionImporterCreateControlFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@control:
+@closure:
+
+
+<!-- ##### USER_FUNCTION EvolutionImporterSupportFormatFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@filename:
+@closure:
+@Returns:
+
+
+<!-- ##### USER_FUNCTION EvolutionImporterLoadFileFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@filename:
+@closure:
+@Returns:
+
+
+<!-- ##### USER_FUNCTION EvolutionImporterProcessItemFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@listener:
+@closure:
+@ev:
+
+
+<!-- ##### USER_FUNCTION EvolutionImporterGetErrorFn ##### -->
+<para>
+
+</para>
+
+@importer:
+@closure:
+@Returns:
+
+
+<!-- ##### ENUM EvolutionImporterResult ##### -->
+<para>
+
+</para>
+
+@EVOLUTION_IMPORTER_OK:
+@EVOLUTION_IMPORTER_UNSUPPORTED_OPERATION:
+@EVOLUTION_IMPORTER_INTERRUPTED:
+@EVOLUTION_IMPORTER_BUSY:
+@EVOLUTION_IMPORTER_NOT_READY:
+@EVOLUTION_IMPORTER_UNKNOWN_DATA:
+@EVOLUTION_IMPORTER_BAD_DATA:
+@EVOLUTION_IMPORTER_BAD_FILE:
+@EVOLUTION_IMPORTER_UNKNOWN_ERROR:
+
+<!-- ##### STRUCT EvolutionImporter ##### -->
+<para>
+
+</para>
+
+@parent:
+@priv:
+
+<!-- ##### FUNCTION evolution_importer_new ##### -->
+<para>
+
+</para>
+
+@create_control_fn:
+@support_format_fn:
+@load_file_fn:
+@process_item_fn:
+@get_error_fn:
+@closure:
+@Returns:
+
+
diff --git a/doc/reference/shell/tmpl/evolution-intelligent-importer.sgml b/doc/reference/shell/tmpl/evolution-intelligent-importer.sgml
new file mode 100644
index 0000000000..4dfdb70203
--- /dev/null
+++ b/doc/reference/shell/tmpl/evolution-intelligent-importer.sgml
@@ -0,0 +1,67 @@
+<!-- ##### SECTION Title ##### -->
+EvolutionIntelligentImporter
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT EvolutionIntelligentImporterPrivate ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### USER_FUNCTION EvolutionIntelligentImporterCanImportFn ##### -->
+<para>
+
+</para>
+
+@ii:
+@closure:
+@Returns:
+
+
+<!-- ##### USER_FUNCTION EvolutionIntelligentImporterImportDataFn ##### -->
+<para>
+
+</para>
+
+@ii:
+@closure:
+
+
+<!-- ##### STRUCT EvolutionIntelligentImporter ##### -->
+<para>
+
+</para>
+
+@parent:
+@priv:
+
+<!-- ##### FUNCTION evolution_intelligent_importer_new ##### -->
+<para>
+
+</para>
+
+@can_import_fn:
+@import_data_fn:
+@importername:
+@message:
+@closure:
+@Returns:
+
+
diff --git a/doc/reference/shell/tmpl/intelligent.sgml b/doc/reference/shell/tmpl/intelligent.sgml
new file mode 100644
index 0000000000..1c50af5c7b
--- /dev/null
+++ b/doc/reference/shell/tmpl/intelligent.sgml
@@ -0,0 +1,26 @@
+<!-- ##### SECTION Title ##### -->
+intelligent
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### FUNCTION intelligent_importer_init ##### -->
+<para>
+
+</para>
+
+
+
diff --git a/doc/reference/shell/tmpl/shell-actions.sgml b/doc/reference/shell/tmpl/shell-actions.sgml
new file mode 100644
index 0000000000..60001d61bb
--- /dev/null
+++ b/doc/reference/shell/tmpl/shell-actions.sgml
@@ -0,0 +1,291 @@
+<!-- ##### SECTION Title ##### -->
+Shell Actions
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_ABOUT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_CLOSE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_CONTENTS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_FAQ ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_FORGET_PASSWORDS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GAL_CUSTOM_VIEW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GAL_DEFINE_VIEWS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_GAL_SAVE_CUSTOM_VIEW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_IMPORT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_NEW_WINDOW ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_PAGE_SETUP ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_PREFERENCES ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_QUICK_REFERENCE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_QUIT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_ADVANCED ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_CLEAR ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_EDIT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEARCH_SAVE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SEND_RECEIVE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_SWITCHER ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SUBMIT_BUG ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SWITCHER_INITIAL ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_BOTH ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_TEXT ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_USER ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SYNC_OPTIONS ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_WORK_OFFLINE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_WORK_ONLINE ##### -->
+<para>
+
+</para>
+
+@window:
+
+
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index 35d254b4eb..e5c0886735 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -4,7 +4,6 @@ ecpsdir = $(privdatadir)/ecps
ruledir = $(privdatadir)
if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libemiscwidgets.la
PLATFORM_SOURCES = e-win32-reloc.c
endif
@@ -39,11 +38,12 @@ AM_CPPFLAGS = \
privsolib_LTLIBRARIES = libeutil.la libeconduit.la
eutilinclude_HEADERS = \
+ e-account-utils.h \
e-bconf-map.h \
e-binding.h \
e-categories-config.h \
+ e-charset.h \
e-config.h \
- e-corba-utils.h \
e-cursor.h \
e-datetime-format.h \
e-dialog-utils.h \
@@ -56,18 +56,18 @@ eutilinclude_HEADERS = \
e-icon-factory.h \
e-import.h \
e-logger.h \
- e-non-intrusive-error-dialog.h \
e-marshal.h \
- e-menu.h \
e-mktemp.h \
+ e-module.h \
+ e-non-intrusive-error-dialog.h \
e-print.h \
e-plugin.h \
e-plugin-ui.h \
- e-popup.h \
e-profile-event.h \
e-request.h \
e-signature.h \
e-signature-list.h \
+ e-signature-utils.h \
e-bit-array.h \
e-sorter.h \
e-sorter-array.h \
@@ -75,16 +75,17 @@ eutilinclude_HEADERS = \
e-text-event-processor-types.h \
e-text-event-processor.h \
e-util.h \
- e-util-labels.h \
+ e-unicode.h \
e-xml-utils.h
libeutil_la_SOURCES = \
$(eutilinclude_HEADERS) \
+ e-account-utils.c \
e-bconf-map.c \
e-binding.c \
e-categories-config.c \
+ e-charset.c \
e-config.c \
- e-corba-utils.c \
e-cursor.c \
e-datetime-format.c \
e-dialog-utils.c \
@@ -97,25 +98,25 @@ libeutil_la_SOURCES = \
e-icon-factory.c \
e-import.c \
e-logger.c \
- e-non-intrusive-error-dialog.c \
e-marshal.c \
- e-menu.c \
e-mktemp.c \
- e-plugin.c \
+ e-module.c \
+ e-non-intrusive-error-dialog.c \
e-plugin-ui.c \
- e-popup.c \
+ e-plugin.c \
e-print.c \
e-profile-event.c \
e-request.c \
e-signature.c \
e-signature-list.c \
+ e-signature-utils.c \
e-bit-array.c \
e-sorter.c \
e-sorter-array.c \
e-text-event-processor-emacs-like.c \
e-text-event-processor.c \
e-util.c \
- e-util-labels.c \
+ e-unicode.c \
e-util-private.h \
e-xml-utils.c \
gconf-bridge.c \
@@ -128,7 +129,6 @@ MARSHAL_GENERATED = e-marshal.c e-marshal.h
libeutil_la_LDFLAGS = $(NO_UNDEFINED)
libeutil_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
$(ICONV_LIBS) \
$(E_UTIL_LIBS) \
$(GNOME_PILOT_LIBS) \
diff --git a/e-util/e-account-utils.c b/e-util/e-account-utils.c
new file mode 100644
index 0000000000..5fdffd8be2
--- /dev/null
+++ b/e-util/e-account-utils.c
@@ -0,0 +1,96 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#include "e-account-utils.h"
+
+#include <gconf/gconf-client.h>
+
+static EAccountList *global_account_list;
+
+EAccountList *
+e_get_account_list (void)
+{
+ if (G_UNLIKELY (global_account_list == NULL)) {
+ GConfClient *client;
+
+ client = gconf_client_get_default ();
+ global_account_list = e_account_list_new (client);
+ g_object_unref (client);
+ }
+
+ g_return_val_if_fail (global_account_list != NULL, NULL);
+
+ return global_account_list;
+}
+
+EAccount *
+e_get_default_account (void)
+{
+ EAccountList *account_list;
+ const EAccount *account;
+
+ account_list = e_get_account_list ();
+ account = e_account_list_get_default (account_list);
+
+ /* XXX EAccountList misuses const. */
+ return (EAccount *) account;
+}
+
+void
+e_set_default_account (EAccount *account)
+{
+ EAccountList *account_list;
+
+ g_return_if_fail (E_IS_ACCOUNT (account));
+
+ account_list = e_get_account_list ();
+ e_account_list_set_default (account_list, account);
+}
+
+EAccount *
+e_get_account_by_name (const gchar *name)
+{
+ EAccountList *account_list;
+ const EAccount *account;
+ e_account_find_t find;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ find = E_ACCOUNT_FIND_NAME;
+ account_list = e_get_account_list ();
+ account = e_account_list_find (account_list, find, name);
+
+ /* XXX EAccountList misuses const. */
+ return (EAccount *) account;
+}
+
+EAccount *
+e_get_account_by_uid (const gchar *uid)
+{
+ EAccountList *account_list;
+ const EAccount *account;
+ e_account_find_t find;
+
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ find = E_ACCOUNT_FIND_UID;
+ account_list = e_get_account_list ();
+ account = e_account_list_find (account_list, find, uid);
+
+ /* XXX EAccountList misuses const. */
+ return (EAccount *) account;
+}
diff --git a/e-util/e-account-utils.h b/e-util/e-account-utils.h
new file mode 100644
index 0000000000..f2ae8fc5dc
--- /dev/null
+++ b/e-util/e-account-utils.h
@@ -0,0 +1,35 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#ifndef E_ACCOUNT_UTILS_H
+#define E_ACCOUNT_UTILS_H
+
+#include <glib.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
+
+G_BEGIN_DECLS
+
+EAccountList * e_get_account_list (void);
+EAccount * e_get_default_account (void);
+void e_set_default_account (EAccount *account);
+EAccount * e_get_account_by_name (const gchar *name);
+EAccount * e_get_account_by_uid (const gchar *uid);
+
+G_END_DECLS
+
+#endif /* E_ACCOUNT_UTILS_H */
diff --git a/e-util/e-charset.c b/e-util/e-charset.c
new file mode 100644
index 0000000000..329f513ec7
--- /dev/null
+++ b/e-util/e-charset.c
@@ -0,0 +1,255 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-charset.h"
+
+#include <string.h>
+#include <iconv.h>
+
+#include <glib/gi18n-lib.h>
+
+typedef enum {
+ E_CHARSET_UNKNOWN,
+ E_CHARSET_ARABIC,
+ E_CHARSET_BALTIC,
+ E_CHARSET_CENTRAL_EUROPEAN,
+ E_CHARSET_CHINESE,
+ E_CHARSET_CYRILLIC,
+ E_CHARSET_GREEK,
+ E_CHARSET_HEBREW,
+ E_CHARSET_JAPANESE,
+ E_CHARSET_KOREAN,
+ E_CHARSET_THAI,
+ E_CHARSET_TURKISH,
+ E_CHARSET_UNICODE,
+ E_CHARSET_WESTERN_EUROPEAN,
+ E_CHARSET_WESTERN_EUROPEAN_NEW
+} ECharsetClass;
+
+static const gchar *classnames[] = {
+ N_("Unknown"),
+ N_("Arabic"),
+ N_("Baltic"),
+ N_("Central European"),
+ N_("Chinese"),
+ N_("Cyrillic"),
+ N_("Greek"),
+ N_("Hebrew"),
+ N_("Japanese"),
+ N_("Korean"),
+ N_("Thai"),
+ N_("Turkish"),
+ N_("Unicode"),
+ N_("Western European"),
+ N_("Western European, New"),
+};
+
+typedef struct {
+ const gchar *name;
+ ECharsetClass class;
+ const gchar *subclass;
+} ECharset;
+
+/* This list is based on what other mailers/browsers support. There's
+ * not a lot of point in using, say, ISO-8859-3, if anything that can
+ * read that can read UTF8 too.
+ */
+/* To Translators: Character set "Logical Hebrew" */
+static ECharset charsets[] = {
+ { "ISO-8859-6", E_CHARSET_ARABIC, NULL },
+ { "ISO-8859-13", E_CHARSET_BALTIC, NULL },
+ { "ISO-8859-4", E_CHARSET_BALTIC, NULL },
+ { "ISO-8859-2", E_CHARSET_CENTRAL_EUROPEAN, NULL },
+ { "Big5", E_CHARSET_CHINESE, N_("Traditional") },
+ { "BIG5HKSCS", E_CHARSET_CHINESE, N_("Traditional") },
+ { "EUC-TW", E_CHARSET_CHINESE, N_("Traditional") },
+ { "GB18030", E_CHARSET_CHINESE, N_("Simplified") },
+ { "GB2312", E_CHARSET_CHINESE, N_("Simplified") },
+ { "HZ", E_CHARSET_CHINESE, N_("Simplified") },
+ { "ISO-2022-CN", E_CHARSET_CHINESE, N_("Simplified") },
+ { "KOI8-R", E_CHARSET_CYRILLIC, NULL },
+ { "Windows-1251", E_CHARSET_CYRILLIC, NULL },
+ { "KOI8-U", E_CHARSET_CYRILLIC, N_("Ukrainian") },
+ { "ISO-8859-5", E_CHARSET_CYRILLIC, NULL },
+ { "ISO-8859-7", E_CHARSET_GREEK, NULL },
+ { "ISO-8859-8", E_CHARSET_HEBREW, N_("Visual") },
+ { "ISO-2022-JP", E_CHARSET_JAPANESE, NULL },
+ { "EUC-JP", E_CHARSET_JAPANESE, NULL },
+ { "Shift_JIS", E_CHARSET_JAPANESE, NULL },
+ { "EUC-KR", E_CHARSET_KOREAN, NULL },
+ { "TIS-620", E_CHARSET_THAI, NULL },
+ { "ISO-8859-9", E_CHARSET_TURKISH, NULL },
+ { "UTF-8", E_CHARSET_UNICODE, NULL },
+ { "UTF-7", E_CHARSET_UNICODE, NULL },
+ { "ISO-8859-1", E_CHARSET_WESTERN_EUROPEAN, NULL },
+ { "ISO-8859-15", E_CHARSET_WESTERN_EUROPEAN_NEW, NULL },
+};
+
+/**
+ * e_charset_add_radio_actions:
+ * @action_group: a #GtkActionGroup
+ * @action_prefix: a prefix for action names, or %NULL
+ * @default_charset: the default character set, or %NULL to use the
+ * locale character set
+ * @callback: a callback function for actions in the group, or %NULL
+ * @user_data: user data to be passed to @callback, or %NULL
+ *
+ * Adds a set of #GtkRadioActions for available character sets to
+ * @action_group. The @default_charset (or locale character set if
+ * @default_charset is %NULL) will be added first, and selected by
+ * default (except that ISO-8859-1 will always be used instead of
+ * US-ASCII). Any other character sets of the same language class as
+ * the default will be added next, followed by the remaining character
+ * sets.
+ **/
+GSList *
+e_charset_add_radio_actions (GtkActionGroup *action_group,
+ const gchar *action_prefix,
+ const gchar *default_charset,
+ GCallback callback,
+ gpointer user_data)
+{
+ GtkRadioAction *action = NULL;
+ GSList *group = NULL;
+ const gchar *locale_charset;
+ gint def, ii;
+
+ g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
+
+ if (action_prefix == NULL)
+ action_prefix = "";
+
+ g_get_charset (&locale_charset);
+ if (!g_ascii_strcasecmp (locale_charset, "US-ASCII"))
+ locale_charset = "ISO-8859-1";
+
+ if (default_charset == NULL)
+ default_charset = locale_charset;
+ for (def = 0; def < G_N_ELEMENTS (charsets); def++)
+ if (!g_ascii_strcasecmp (charsets[def].name, default_charset))
+ break;
+
+ for (ii = 0; ii < G_N_ELEMENTS (charsets); ii++) {
+ const gchar *charset_name;
+ gchar *action_name;
+ gchar *escaped_name;
+ gchar *charset_label;
+ gchar **str_array;
+
+ charset_name = charsets[ii].name;
+ action_name = g_strconcat (action_prefix, charset_name, NULL);
+
+ /* Escape underlines in the character set name so
+ * they're not treated as GtkLabel mnemonics. */
+ str_array = g_strsplit (charset_name, "_", -1);
+ escaped_name = g_strjoinv ("__", str_array);
+ g_strfreev (str_array);
+
+ if (charsets[ii].subclass != NULL)
+ charset_label = g_strdup_printf (
+ "%s, %s (%s)",
+ gettext (classnames[charsets[ii].class]),
+ gettext (charsets[ii].subclass),
+ escaped_name);
+ else if (charsets[ii].class != E_CHARSET_UNKNOWN)
+ charset_label = g_strdup_printf (
+ "%s (%s)",
+ gettext (classnames[charsets[ii].class]),
+ escaped_name);
+ else
+ charset_label = g_strdup (escaped_name);
+
+ /* XXX Add a tooltip! */
+ action = gtk_radio_action_new (
+ action_name, charset_label, NULL, NULL, ii);
+
+ /* Character set name is static so no need to free it. */
+ g_object_set_data (
+ G_OBJECT (action), "charset",
+ (gpointer) charset_name);
+
+ gtk_radio_action_set_group (action, group);
+ group = gtk_radio_action_get_group (action);
+
+ if (callback != NULL)
+ g_signal_connect (
+ action, "changed", callback, user_data);
+
+ gtk_action_group_add_action (
+ action_group, GTK_ACTION (action));
+
+ g_object_unref (action);
+
+ g_free (action_name);
+ g_free (escaped_name);
+ g_free (charset_label);
+ }
+
+ if (def == G_N_ELEMENTS (charsets)) {
+ const gchar *charset_name;
+ gchar *action_name;
+ gchar *charset_label;
+ gchar **str_array;
+
+ charset_name = default_charset;
+ action_name = g_strconcat (action_prefix, charset_name, NULL);
+
+ /* Escape underlines in the character set name so
+ * they're not treated as GtkLabel mnemonics. */
+ str_array = g_strsplit (charset_name, "_", -1);
+ charset_label = g_strjoinv ("__", str_array);
+ g_strfreev (str_array);
+
+ /* XXX Add a tooltip! */
+ action = gtk_radio_action_new (
+ action_name, charset_label, NULL, NULL, def);
+
+ /* Character set name is static so no need to free it. */
+ g_object_set_data (
+ G_OBJECT (action), "charset",
+ (gpointer) charset_name);
+
+ gtk_radio_action_set_group (action, group);
+ group = gtk_radio_action_get_group (action);
+
+ if (callback != NULL)
+ g_signal_connect (
+ action, "changed", callback, user_data);
+
+ gtk_action_group_add_action (
+ action_group, GTK_ACTION (action));
+
+ g_object_unref (action);
+
+ g_free (action_name);
+ g_free (charset_label);
+ }
+
+ /* Any of the actions in the action group will do. */
+ if (action != NULL)
+ gtk_radio_action_set_current_value (action, def);
+
+ return group;
+}
diff --git a/mail/em-migrate.h b/e-util/e-charset.h
index 89896d4aec..57b6976a1f 100644
--- a/mail/em-migrate.h
+++ b/e-util/e-charset.h
@@ -1,4 +1,5 @@
/*
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,22 +14,23 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef __EM_MIGRATE_H__
-#define __EM_MIGRATE_H__
+#ifndef E_CHARSET_H
+#define E_CHARSET_H
-#include <camel/camel-exception.h>
+#include <gtk/gtk.h>
G_BEGIN_DECLS
-gint em_migrate (const gchar *evolution_dir, gint major, gint minor, gint revision, CamelException *ex);
+GSList * e_charset_add_radio_actions (GtkActionGroup *action_group,
+ const gchar *action_prefix,
+ const gchar *default_charset,
+ GCallback callback,
+ gpointer user_data);
G_END_DECLS
-#endif /* __EM_MIGRATE_H__ */
+#endif /* E_CHARSET_H */
diff --git a/e-util/e-config.c b/e-util/e-config.c
index 412c00b649..9974da72cb 100644
--- a/e-util/e-config.c
+++ b/e-util/e-config.c
@@ -30,10 +30,6 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include <libgnomeui/gnome-druid.h>
-#include <libgnomeui/gnome-druid-page-standard.h>
-#include <libgnomeui/gnome-druid-page-edge.h>
-
#include "e-config.h"
#include <glib/gi18n.h>
@@ -79,12 +75,19 @@ struct _check_node {
gpointer data;
};
+struct _finish_page_node {
+ struct _finish_page_node *next, *prev;
+
+ gchar *pageid;
+ gboolean is_finish;
+ gint orig_type;
+};
+
struct _EConfigPrivate {
EDList menus;
EDList widgets;
EDList checks;
-
- struct _widget_node *druid_page; /* current druid page if using the druid */
+ EDList finish_pages;
};
static GObjectClass *ep_parent;
@@ -100,6 +103,7 @@ ep_init(GObject *o)
e_dlist_init(&p->menus);
e_dlist_init(&p->widgets);
e_dlist_init(&p->checks);
+ e_dlist_init(&p->finish_pages);
}
static void
@@ -110,6 +114,7 @@ ep_finalise(GObject *o)
struct _menu_node *mnode;
struct _widget_node *wn;
struct _check_node *cn;
+ struct _finish_page_node *fp;
d(printf("finalising EConfig %p\n", o));
@@ -135,6 +140,11 @@ ep_finalise(GObject *o)
g_free(cn);
}
+ while ( (fp = (struct _finish_page_node *) e_dlist_remhead (&p->finish_pages)) ) {
+ g_free (fp->pageid);
+ g_free (fp);
+ }
+
g_free(p);
((GObjectClass *)ep_parent)->finalize(o);
@@ -204,7 +214,7 @@ e_config_get_type(void)
* e_config_construct:
* @ep: The instance to initialise.
* @type: The type of configuration manager, @E_CONFIG_BOOK or
- * @E_CONFIG_DRUID.
+ * @E_CONFIG_ASSISTANT.
* @id: The name of the configuration window this manager drives.
*
* Used by implementing classes to initialise base parameters.
@@ -213,7 +223,7 @@ e_config_get_type(void)
**/
EConfig *e_config_construct(EConfig *ep, gint type, const gchar *id)
{
- g_return_val_if_fail (type == E_CONFIG_BOOK || type == E_CONFIG_DRUID, NULL);
+ g_return_val_if_fail (type == E_CONFIG_BOOK || type == E_CONFIG_ASSISTANT, NULL);
ep->type = type;
ep->id = g_strdup(id);
@@ -269,7 +279,7 @@ e_config_add_items(EConfig *ec, GSList *items, EConfigItemsFunc commitfunc, ECon
* is being checked.
*
* The page check function is used to validate input before allowing
- * the druid to continue or the notebook to close.
+ * the assistant to continue or the notebook to close.
**/
void
e_config_add_page_check(EConfig *ec, const gchar *pageid, EConfigCheckFunc check, gpointer data)
@@ -284,6 +294,48 @@ e_config_add_page_check(EConfig *ec, const gchar *pageid, EConfigCheckFunc check
e_dlist_addtail(&ec->priv->checks, (EDListNode *)cn);
}
+static struct _finish_page_node *
+find_page_finish (EConfig *ec, const gchar *pageid)
+{
+ struct _finish_page_node *fp;
+
+ for (fp = (struct _finish_page_node *) ec->priv->finish_pages.head; fp->next; fp = fp->next) {
+ if (g_str_equal (fp->pageid, pageid))
+ return fp;
+ }
+
+ return NULL;
+}
+
+/**
+ * e_config_set_page_is_finish:
+ * @ec: Initialised implementing instance of EConfig.
+ * @pageid: pageid to change the value on.
+ * @can_finish: whether the pageid can finish immediately or not.
+ *
+ * With is_finish set on the pageid the page is treated as the last page in an assistant.
+ **/
+void
+e_config_set_page_is_finish (EConfig *ec, const gchar *pageid, gboolean is_finish)
+{
+ struct _finish_page_node *fp;
+
+ fp = find_page_finish (ec, pageid);
+
+ if (is_finish) {
+ if (!fp) {
+ fp = g_malloc0 (sizeof (*fp));
+ fp->pageid = g_strdup (pageid);
+ e_dlist_addtail (&ec->priv->finish_pages, (EDListNode *)fp);
+ }
+
+ fp->is_finish = TRUE;
+ } else {
+ if (fp)
+ fp->is_finish = FALSE;
+ }
+}
+
static void
ec_add_static_items(EConfig *ec)
{
@@ -309,83 +361,131 @@ ep_cmp(gconstpointer ap, gconstpointer bp)
return strcmp(a->item->path, b->item->path);
}
+static struct _widget_node *
+ec_assistant_find_page (EConfig *ec, GtkWidget *page, gint *page_index)
+{
+ struct _widget_node *wn;
+
+ g_return_val_if_fail (ec != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_ASSISTANT (ec->widget), NULL);
+ g_return_val_if_fail (page != NULL, NULL);
+
+ for (wn = (struct _widget_node *)ec->priv->widgets.head; wn->next; wn = wn->next) {
+ if (wn->frame == page
+ && (wn->item->type == E_CONFIG_PAGE
+ || wn->item->type == E_CONFIG_PAGE_START
+ || wn->item->type == E_CONFIG_PAGE_FINISH))
+ break;
+ }
+
+ if (wn->frame != page)
+ wn = NULL;
+
+ if (page_index) {
+ if (wn) {
+ GtkAssistant *assistant = GTK_ASSISTANT (ec->widget);
+ gint index, count = gtk_assistant_get_n_pages (assistant);
+
+ for (index = 0; index < count; index++) {
+ if (gtk_assistant_get_nth_page (assistant, index) == page)
+ break;
+ }
+
+ if (index == count)
+ index = -1;
+ *page_index = index;
+ } else {
+ *page_index = -1;
+ }
+ }
+
+ return wn;
+}
+
static void
-ec_druid_check_current(EConfig *ec)
+ec_assistant_check_current (EConfig *ec)
{
- g_return_if_fail(ec->priv->druid_page != NULL);
+ struct _widget_node *wn;
+ struct _finish_page_node *fp;
+ GtkAssistant *assistant;
+ GtkWidget *page;
+ gint page_no;
- if (e_config_page_check(ec, ec->priv->druid_page->item->path)) {
- gtk_widget_set_sensitive(((GnomeDruid *)ec->widget)->next, TRUE);
- } else {
- gtk_widget_set_sensitive(((GnomeDruid *)ec->widget)->next, FALSE);
+ g_return_if_fail (GTK_IS_ASSISTANT (ec->widget));
+
+ assistant = GTK_ASSISTANT (ec->widget);
+ page_no = gtk_assistant_get_current_page (assistant);
+
+ /* no page selected yet */
+ if (page_no == -1)
+ return;
+
+ page = gtk_assistant_get_nth_page (assistant, page_no);
+ g_return_if_fail (page != NULL);
+
+ wn = ec_assistant_find_page (ec, page, NULL);
+ g_return_if_fail (wn != NULL);
+
+ /* this should come first, as the check function can change the finish state of the page */
+ gtk_assistant_set_page_complete (assistant, page, e_config_page_check (ec, wn->item->path));
+
+ fp = find_page_finish (ec, wn->item->path);
+ if (fp) {
+ GtkAssistantPageType pt = gtk_assistant_get_page_type (assistant, page);
+
+ if (fp->is_finish && pt != GTK_ASSISTANT_PAGE_CONFIRM) {
+ if (fp->orig_type == GTK_ASSISTANT_PAGE_CONTENT)
+ fp->orig_type = pt;
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
+ } else if (!fp->is_finish && pt != fp->orig_type) {
+ gtk_assistant_set_page_type (assistant, page, fp->orig_type);
+ }
}
+
+ gtk_assistant_update_buttons_state (assistant);
}
static void
-ec_druid_cancel(GnomeDruid *druid, struct _widget_node *wn)
+ec_assistant_cancel (GtkAssistant *assistant, EConfig *config)
{
- d(printf("finishing druid, calling abort\n"));
- e_config_abort(wn->config);
+ d(printf("finishing assistant, calling abort\n"));
+ e_config_abort (config);
- if (wn->config->window)
- gtk_widget_destroy(wn->config->window);
+ if (config->window)
+ gtk_widget_destroy (config->window);
}
static void
-ec_druid_finish(GnomeDruidPage *page, GnomeDruid *druid, struct _widget_node *wn)
+ec_assistant_apply (GtkAssistant *assistant, EConfig *config)
{
- d(printf("finishing druid, calling commit\n"));
- e_config_commit(wn->config);
+ d(printf("finishing assistant, calling commit\n"));
+ e_config_commit (config);
/* TODO: allow the commit to fail? Do we care? */
- if (wn->config->window)
- gtk_widget_destroy(wn->config->window);
+ if (config->window)
+ gtk_widget_destroy (config->window);
}
static void
-ec_druid_prepare(GnomeDruidPage *page, GnomeDruid *druid, struct _widget_node *wn)
+ec_assistant_prepare (GtkAssistant *assistant, GtkWidget *page, EConfig *config)
{
- d(printf("prepare page '%s'\n", wn->item->path));
- wn->config->priv->druid_page = wn;
- ec_druid_check_current(wn->config);
+ d(printf("prepare page '%p'\n", page));
+ ec_assistant_check_current (config);
}
-static gboolean
-ec_druid_prev(GnomeDruidPage *page, GnomeDruid *druid, struct _widget_node *wn)
+static gint
+ec_assistant_forward (gint current_page, gpointer user_data)
{
- EConfig *ec = wn->config;
-
- d(printf("prev page from '%s'\n", wn->item->path));
- if (wn->prev) {
- for (wn = wn->prev;wn->prev;wn=wn->prev) {
- if (!wn->empty && wn->frame != NULL
- && (wn->item->type == E_CONFIG_PAGE
- || wn->item->type == E_CONFIG_PAGE_START
- || wn->item->type == E_CONFIG_PAGE_FINISH))
- break;
- }
- }
+ EConfig *ec = user_data;
+ struct _widget_node *wn;
+ gint next_page = current_page;
- if (wn->prev) {
- d(printf(" is %s\n",wn->item->path));
- gnome_druid_set_page((GnomeDruid *)ec->widget, (GnomeDruidPage *)wn->frame);
- ec->priv->druid_page = wn;
- } else {
- /* do we need to indicate first? */
- ec->priv->druid_page = NULL;
- }
+ d(printf("next page from '%d'\n", current_page));
- return wn->prev != NULL;
-}
+ wn = ec_assistant_find_page (ec, gtk_assistant_get_nth_page (GTK_ASSISTANT (ec->widget), current_page), NULL);
-static gboolean
-ec_druid_next(GnomeDruidPage *page, GnomeDruid *druid, struct _widget_node *wn)
-{
- EConfig *ec = wn->config;
-
- d(printf("next page from '%s'\n", wn->item->path));
- if (wn->next) {
- for (wn = wn->next;wn->next;wn=wn->next) {
+ if (wn && wn->next) {
+ for (wn = wn->next; wn->next; wn = wn->next) {
if (!wn->empty && wn->frame != NULL
&& (wn->item->type == E_CONFIG_PAGE
|| wn->item->type == E_CONFIG_PAGE_START
@@ -394,25 +494,23 @@ ec_druid_next(GnomeDruidPage *page, GnomeDruid *druid, struct _widget_node *wn)
}
}
- if (wn->next) {
+ if (wn && wn->next) {
d(printf(" is %s\n",wn->item->path));
- gnome_druid_set_page((GnomeDruid *)ec->widget, (GnomeDruidPage *)wn->frame);
- ec->priv->druid_page = wn;
- } else {
- /* do we need to indicate last? */
- ec->priv->druid_page = NULL;
+ ec_assistant_find_page (ec, wn->frame, &next_page);
}
- return wn->next != NULL;
+ return next_page;
}
static void
-ec_rebuild(EConfig *emp)
+ec_rebuild (EConfig *emp)
{
struct _EConfigPrivate *p = emp->priv;
struct _widget_node *wn, *sectionnode = NULL, *pagenode = NULL;
- GtkWidget *book = NULL, *page = NULL, *section = NULL, *root = NULL, *druid = NULL;
+ GtkWidget *book = NULL, *page = NULL, *section = NULL, *root = NULL, *assistant = NULL;
gint pageno = 0, sectionno = 0, itemno = 0;
+ struct _widget_node *last_active_page = NULL;
+ gboolean is_assistant;
d(printf("target changed, rebuilding:\n"));
@@ -421,6 +519,15 @@ ec_rebuild(EConfig *emp)
* into the two base types, but there would be a lot of code
* duplication */
+ /* because rebuild destroys pages, and destroying active page causes crashes */
+ is_assistant = emp->widget && GTK_IS_ASSISTANT (emp->widget);
+ if (is_assistant) {
+ gint page_index = gtk_assistant_get_current_page (GTK_ASSISTANT (emp->widget));
+ if (page_index != -1)
+ last_active_page = ec_assistant_find_page (emp, gtk_assistant_get_nth_page (GTK_ASSISTANT (emp->widget), page_index), NULL);
+ gtk_assistant_set_current_page (GTK_ASSISTANT (emp->widget), 0);
+ }
+
for (wn = (struct _widget_node *)p->widgets.head;wn->next;wn=wn->next) {
struct _EConfigItem *item = wn->item;
const gchar *translated_label = NULL;
@@ -464,35 +571,39 @@ ec_rebuild(EConfig *emp)
/* Now process the item */
switch (item->type) {
case E_CONFIG_BOOK:
- case E_CONFIG_DRUID:
- /* Only one of BOOK or DRUID may be define, it
+ case E_CONFIG_ASSISTANT:
+ /* Only one of BOOK or ASSISTANT may be define, it
is used by the defining code to mark the
type of the config window. It is
cross-checked with the code's defined
type. */
if (root != NULL) {
- g_warning("EConfig book/druid redefined at: %s", item->path);
+ g_warning("EConfig book/assistant redefined at: %s", item->path);
break;
}
if (wn->widget == NULL) {
if (item->type != emp->type) {
- g_warning("EConfig book/druid type mismatch");
+ g_warning("EConfig book/assistant type mismatch");
break;
}
if (item->factory) {
root = item->factory(emp, item, NULL, wn->widget, wn->context->data);
} else if (item->type == E_CONFIG_BOOK) {
- root = book = gtk_notebook_new();
- gtk_widget_show(book);
- } else if (item->type == E_CONFIG_DRUID) {
- root = druid = gnome_druid_new();
- gtk_widget_show(druid);
+ root = gtk_notebook_new();
+ gtk_widget_show (root);
+ } else if (item->type == E_CONFIG_ASSISTANT) {
+ root = gtk_assistant_new ();
} else
abort();
- if (item->type == E_CONFIG_DRUID)
- g_signal_connect(root, "cancel", G_CALLBACK(ec_druid_cancel), wn);
+ if (item->type == E_CONFIG_ASSISTANT) {
+ g_signal_connect (root, "cancel", G_CALLBACK (ec_assistant_cancel), emp);
+ g_signal_connect (root, "close", G_CALLBACK (ec_assistant_cancel), emp);
+ g_signal_connect (root, "apply", G_CALLBACK (ec_assistant_apply), emp);
+ g_signal_connect (root, "prepare", G_CALLBACK (ec_assistant_prepare), emp);
+ gtk_assistant_set_forward_page_func (GTK_ASSISTANT (root), ec_assistant_forward, emp, NULL);
+ }
emp->widget = root;
wn->widget = root;
@@ -503,7 +614,7 @@ ec_rebuild(EConfig *emp)
if (item->type == E_CONFIG_BOOK)
book = root;
else
- druid = root;
+ assistant = root;
page = NULL;
pagenode = NULL;
@@ -518,8 +629,8 @@ ec_rebuild(EConfig *emp)
g_warning("EConfig page defined before container widget: %s", item->path);
break;
}
- if (emp->type != E_CONFIG_DRUID) {
- g_warning("EConfig druid start/finish pages can't be used on E_CONFIG_BOOKs");
+ if (emp->type != E_CONFIG_ASSISTANT) {
+ g_warning("EConfig assistant start/finish pages can't be used on E_CONFIG_BOOKs");
break;
}
@@ -527,21 +638,41 @@ ec_rebuild(EConfig *emp)
if (item->factory) {
page = item->factory(emp, item, root, wn->frame, wn->context->data);
} else {
- page = gnome_druid_page_edge_new(item->type == E_CONFIG_PAGE_START?GNOME_EDGE_START:GNOME_EDGE_FINISH);
- gtk_widget_show(page);
- gnome_druid_page_edge_set_title((GnomeDruidPageEdge *)page, translated_label);
- gnome_druid_insert_page((GnomeDruid *)druid, pagenode?(GnomeDruidPage *)pagenode->frame:NULL, (GnomeDruidPage *)page);
- }
- if (page) {
- if (item->type == E_CONFIG_PAGE_FINISH) {
- g_signal_connect(page, "back", G_CALLBACK(ec_druid_prev), wn);
- g_signal_connect(page, "finish", G_CALLBACK(ec_druid_finish), wn);
- } else
- g_signal_connect(page, "next", G_CALLBACK(ec_druid_next), wn);
+ page = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (page), 12);
+ if (pagenode) {
+ /* put after */
+ gint index = -1;
+ ec_assistant_find_page (emp, pagenode->frame, &index);
+ gtk_assistant_insert_page (GTK_ASSISTANT (assistant), page, index + 1);
+ } else {
+ gtk_assistant_prepend_page (GTK_ASSISTANT (assistant), page);
+ }
+
+ gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, item->type == E_CONFIG_PAGE_START ? GTK_ASSISTANT_PAGE_INTRO : GTK_ASSISTANT_PAGE_CONFIRM);
+ gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, translated_label);
+ gtk_widget_show_all (page);
}
+
wn->frame = page;
wn->widget = page;
+
+ if (page) {
+ const gchar *empty_xpm_img[] = {
+ "48 1 2 1",
+ " c None",
+ ". c #FFFFFF",
+ " "};
+
+ /* left side place with a blue background on a start and finish page */
+ GdkPixbuf *spacer = gdk_pixbuf_new_from_xpm_data (empty_xpm_img);
+
+ gtk_assistant_set_page_side_image (GTK_ASSISTANT (assistant), page, spacer);
+
+ g_object_unref (spacer);
+ }
}
+
pageno++;
page = NULL;
pagenode = wn; /* need this for previous page linking */
@@ -550,15 +681,12 @@ ec_rebuild(EConfig *emp)
sectionno = 1; /* never want to hide these */
break;
case E_CONFIG_PAGE: {
- gint connect = 0; /* connect druid signals */
-
/* CONFIG_PAGEs depend on the config type.
E_CONFIG_BOOK:
The page is a VBox, stored in the notebook.
- E_CONFIG_DRUID
- The page is a GnomeDruidPageStandard,
- any sections automatically added are added to
- the vbox inside it. */
+ E_CONFIG_ASSISTANT
+ The page is a VBox, stored in the GtkAssistant,
+ any sections automatically added inside it. */
sectionno = 0;
if (root == NULL) {
g_warning("EConfig page defined before container widget: %s", item->path);
@@ -567,15 +695,8 @@ ec_rebuild(EConfig *emp)
if (item->factory) {
page = item->factory(emp, item, root, wn->frame, wn->context->data);
- if (emp->type == E_CONFIG_DRUID) {
- if (page) {
- if (GNOME_IS_DRUID_PAGE_STANDARD(page)) {
- connect = wn->frame != page;
- wn->frame = page;
- page = ((GnomeDruidPageStandard *)page)->vbox;
- }
- } else
- wn->frame = page;
+ if (emp->type == E_CONFIG_ASSISTANT) {
+ wn->frame = page;
} else {
wn->frame = page;
if (page)
@@ -584,14 +705,22 @@ ec_rebuild(EConfig *emp)
if (page)
sectionno = 1;
} else if (wn->widget == NULL) {
- if (emp->type == E_CONFIG_DRUID) {
- w = gnome_druid_page_standard_new();
- gtk_widget_show(w);
- gnome_druid_page_standard_set_title((GnomeDruidPageStandard *)w, translated_label);
- gnome_druid_insert_page((GnomeDruid *)druid, pagenode?(GnomeDruidPage *)pagenode->frame:NULL, (GnomeDruidPage *)w);
- wn->frame = w;
- page = ((GnomeDruidPageStandard *)w)->vbox;
- connect = TRUE;
+ if (emp->type == E_CONFIG_ASSISTANT) {
+ page = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (page), 12);
+ if (pagenode) {
+ /* put after */
+ gint index = -1;
+ ec_assistant_find_page (emp, pagenode->frame, &index);
+ gtk_assistant_insert_page (GTK_ASSISTANT (assistant), page, index + 1);
+ } else {
+ gtk_assistant_prepend_page (GTK_ASSISTANT (assistant), page);
+ }
+ gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONTENT);
+ gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, translated_label);
+ gtk_widget_show_all (page);
+
+ wn->frame = page;
} else {
w = gtk_label_new_with_mnemonic (translated_label);
gtk_widget_show(w);
@@ -607,15 +736,8 @@ ec_rebuild(EConfig *emp)
d(printf("page %d:%s widget %p\n", pageno, item->path, page));
if (wn->widget && wn->widget != page) {
- d(printf("destroy old widget for page '%s'\n", item->path));
- gtk_widget_destroy(wn->widget);
- }
-
- if (connect) {
- g_signal_connect(wn->frame, "next", G_CALLBACK(ec_druid_next), wn);
- g_signal_connect(wn->frame, "back", G_CALLBACK(ec_druid_prev), wn);
- /* GnomeDruid bug, need to connect_after */
- g_signal_connect_after(wn->frame, "prepare", G_CALLBACK(ec_druid_prepare), wn);
+ d(printf("destroy old widget for page '%s' (%p)\n", item->path, wn->widget));
+ gtk_widget_destroy (wn->widget);
}
pageno++;
@@ -629,8 +751,7 @@ ec_rebuild(EConfig *emp)
case E_CONFIG_SECTION:
case E_CONFIG_SECTION_TABLE:
/* The section factory is always called with
- the parent vbox object. Even for druid
- pages. */
+ the parent vbox object. Even for assistant pages. */
if (page == NULL) {
/*g_warning("EConfig section '%s' has no parent page", item->path);*/
section = NULL;
@@ -768,6 +889,13 @@ ec_rebuild(EConfig *emp)
gtk_notebook_set_show_border((GtkNotebook *)book, FALSE);
}
}
+
+ if (is_assistant && last_active_page) {
+ gint page_index = -1;
+
+ ec_assistant_find_page (emp, last_active_page->frame, &page_index);
+ gtk_assistant_set_current_page (GTK_ASSISTANT (emp->widget), page_index);
+ }
}
/**
@@ -805,7 +933,7 @@ ec_widget_destroy(GtkWidget *w, EConfig *ec)
*
* Create the widget described by @emp. Only the core widget
* appropriate for the given type is created, i.e. a GtkNotebook for
- * the E_CONFIG_BOOK type and a GnomeDruid for the E_CONFIG_DRUID
+ * the E_CONFIG_BOOK type and a GtkAssistant for the E_CONFIG_ASSISTANT
* type.
*
* This object will be self-driving, but will not close itself once
@@ -859,6 +987,11 @@ e_config_create_widget(EConfig *emp)
/* FIXME: for some reason ec_rebuild puts the widget on page 1, this is just to override that */
if (emp->type == E_CONFIG_BOOK)
gtk_notebook_set_current_page((GtkNotebook *)emp->widget, 0);
+ else {
+ gtk_assistant_set_current_page (GTK_ASSISTANT (emp->widget), 0);
+ gtk_window_set_position (GTK_WINDOW (emp->widget), GTK_WIN_POS_CENTER);
+ gtk_widget_show (emp->widget);
+ }
return emp->widget;
}
@@ -882,9 +1015,9 @@ ec_dialog_response(GtkWidget *d, gint id, EConfig *ec)
*
* Create a managed GtkWindow object from @emp. This window will be
* fully driven by the EConfig @emp. If @emp.type is
- * @E_CONFIG_DRUID, then this will be a toplevel GtkWindow containing
- * a GnomeDruid. If it is @E_CONFIG_BOOK then it will be a GtkDialog
- * containing a Nnotebook.
+ * @E_CONFIG_ASSISTANT, then this will be a toplevel GtkWindow containing
+ * a GtkAssistant. If it is @E_CONFIG_BOOK then it will be a GtkDialog
+ * containing a Notebook.
*
* Unless reffed otherwise, the management object @emp will be
* finalised when the widget is.
@@ -913,11 +1046,9 @@ e_config_create_window(EConfig *emp, GtkWindow *parent, const gchar *title)
gtk_box_pack_start((GtkBox *)gtk_dialog_get_content_area (((GtkDialog *)w)), emp->widget, TRUE, TRUE, 0);
} else {
- /* response is handled directly by the druid stuff */
- w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ /* response is handled directly by the assistant stuff */
+ w = emp->widget;
gtk_window_set_title ((GtkWindow *)w, title);
- gtk_container_add((GtkContainer *)w, emp->widget);
- gtk_window_set_type_hint((GtkWindow *)w, GDK_WINDOW_TYPE_HINT_DIALOG);
}
emp->window = w;
@@ -926,17 +1057,11 @@ e_config_create_window(EConfig *emp, GtkWindow *parent, const gchar *title)
return w;
}
-static gboolean
-ec_idle_handler_for_rebuild (gpointer data)
+static void
+ec_call_page_check (EConfig *emp)
{
- EConfig *emp = (EConfig*) data;
-
- ec_rebuild (emp);
- if (emp->type == E_CONFIG_DRUID) {
- if (emp->priv->druid_page) {
- gnome_druid_set_page((GnomeDruid *)emp->widget, (GnomeDruidPage *)emp->priv->druid_page->frame);
- ec_druid_check_current(emp);
- }
+ if (emp->type == E_CONFIG_ASSISTANT) {
+ ec_assistant_check_current (emp);
} else {
if (emp->window) {
if (e_config_page_check(emp, NULL)) {
@@ -946,6 +1071,16 @@ ec_idle_handler_for_rebuild (gpointer data)
}
}
}
+}
+
+static gboolean
+ec_idle_handler_for_rebuild (gpointer data)
+{
+ EConfig *emp = (EConfig*) data;
+
+ ec_rebuild (emp);
+ ec_call_page_check (emp);
+
return FALSE;
}
@@ -959,29 +1094,15 @@ ec_idle_handler_for_rebuild (gpointer data)
* %E_CONFIG_TARGET_CHANGED_REBUILD, then the entire configuration
* widget may be recreated based on the changed target.
*
- * This is used to sensitise Druid next/back buttons and the Apply
+ * This is used to sensitise Assistant next/back buttons and the Apply
* button for the Notebook mode.
**/
void e_config_target_changed(EConfig *emp, e_config_target_change_t how)
{
if (how == E_CONFIG_TARGET_CHANGED_REBUILD) {
g_idle_add (ec_idle_handler_for_rebuild, emp);
- return;
- }
-
- if (emp->type == E_CONFIG_DRUID) {
- if (emp->priv->druid_page) {
- gnome_druid_set_page((GnomeDruid *)emp->widget, (GnomeDruidPage *)emp->priv->druid_page->frame);
- ec_druid_check_current(emp);
- }
} else {
- if (emp->window) {
- if (e_config_page_check(emp, NULL)) {
- gtk_dialog_set_response_sensitive((GtkDialog *)emp->window, GTK_RESPONSE_OK, TRUE);
- } else {
- gtk_dialog_set_response_sensitive((GtkDialog *)emp->window, GTK_RESPONSE_OK, FALSE);
- }
- }
+ ec_call_page_check (emp);
}
/* virtual method/signal? */
@@ -992,7 +1113,7 @@ void e_config_target_changed(EConfig *emp, e_config_target_change_t how)
* @ec:
*
* Signify that the stateful configuration changes must be discarded
- * to all listeners. This is used by self-driven druid or notebook, or
+ * to all listeners. This is used by self-driven assistant or notebook, or
* may be used by code using the widget directly.
**/
void e_config_abort(EConfig *ec)
@@ -1012,7 +1133,7 @@ void e_config_abort(EConfig *ec)
* @ec:
*
* Signify that the stateful configuration changes should be saved.
- * This is used by the self-driven druid or notebook, or may be used
+ * This is used by the self-driven assistant or notebook, or may be used
* by code driving the widget directly.
**/
void e_config_commit(EConfig *ec)
@@ -1046,8 +1167,9 @@ gboolean e_config_page_check(EConfig *ec, const gchar *pageid)
if ((pageid == NULL
|| mnode->pageid == NULL
|| strcmp(mnode->pageid, pageid) == 0)
- && !mnode->check(ec, pageid, mnode->data))
+ && !mnode->check(ec, pageid, mnode->data)) {
return FALSE;
+ }
return TRUE;
}
@@ -1060,7 +1182,7 @@ gboolean e_config_page_check(EConfig *ec, const gchar *pageid)
* Retrieve the page widget corresponding to @pageid.
*
* Return value: The page widget. It will be the root GtkNotebook
- * container or the GnomeDruidPage object.
+ * container or the GtkVBox object inside the assistant.
**/
GtkWidget *e_config_page_get(EConfig *ec, const gchar *pageid)
{
@@ -1258,7 +1380,7 @@ static gpointer emph_parent_class;
static const EPluginHookTargetKey ech_item_types[] = {
{ "book", E_CONFIG_BOOK },
- { "druid", E_CONFIG_DRUID },
+ { "assistant", E_CONFIG_ASSISTANT },
{ "page", E_CONFIG_PAGE },
{ "page_start", E_CONFIG_PAGE_START },
diff --git a/e-util/e-config.h b/e-util/e-config.h
index e6ff495520..1550f8895c 100644
--- a/e-util/e-config.h
+++ b/e-util/e-config.h
@@ -76,18 +76,18 @@ enum _e_config_target_change_t {
* enum _e_config_t - configuration item type.
*
* @E_CONFIG_BOOK: A notebook item. Only one of this or
- * @E_CONFIG_DRUID may be included in the item list for the entire
+ * @E_CONFIG_ASSISTANT may be included in the item list for the entire
* configuration description.
- * @E_CONFIG_DRUID: A druid item. Only one of this or @E_CONFIG_BOOK
+ * @E_CONFIG_ASSISTANT: An assistant item. Only one of this or @E_CONFIG_BOOK
* may be included in the item list for the entire configutation
* description.
* @E_CONFIG_PAGE: A configuration page. The item @label will be
- * either the notebook tab label or the druid page title if no factory
+ * either the notebook tab label or the assistant page title if no factory
* is supplied.
- * @E_CONFIG_PAGE_START: A druid start page. Only one of these may be
- * supplied for a druid and it should be the first page in the druid.
- * @E_CONFIG_PAGE_FINISH: A druid finish page. Only one of these may
- * be supplied for a druid and it should be the last page of the druid.
+ * @E_CONFIG_PAGE_START: An assistant start page. Only one of these may be
+ * supplied for a assistant and it should be the first page in the assistant.
+ * @E_CONFIG_PAGE_FINISH: An assistant finish page. Only one of these may
+ * be supplied for an assistant and it should be the last page of the assistant.
* @E_CONFIG_SECTION: A section in the configuration page. A page for
* this section must have already been defined. The item @label if
* supplied will be setup as a borderless hig-compliant frame title.
@@ -109,11 +109,11 @@ enum _e_config_target_change_t {
enum _e_config_t {
/* use one and only one of these for any given config-window id */
E_CONFIG_BOOK,
- E_CONFIG_DRUID,
+ E_CONFIG_ASSISTANT,
E_CONFIG_PAGE,
- E_CONFIG_PAGE_START, /* only allowed in druid types */
- E_CONFIG_PAGE_FINISH, /* only allowed in druid types */
+ E_CONFIG_PAGE_START, /* only allowed in assistant types */
+ E_CONFIG_PAGE_FINISH, /* only allowed in assistant types */
E_CONFIG_SECTION,
E_CONFIG_SECTION_TABLE,
E_CONFIG_ITEM,
@@ -175,7 +175,7 @@ struct _EConfigTarget {
* @id: The globally unique identifider for this configuration window,
* used for hooking into it.
* @target: The current target.
- * @widget: The GtkNoteBook or GnomeDruid created after
+ * @widget: The GtkNoteBook or GtkAssistant created after
* :create_widget() is called that represents the merged and combined
* configuration window.
* @window: If :create_window() is called, then the containing
@@ -188,7 +188,7 @@ struct _EConfig {
struct _EConfigPrivate *priv;
- gint type; /* E_CONFIG_BOOK or E_CONFIG_DRUID */
+ gint type; /* E_CONFIG_BOOK or E_CONFIG_ASSISTANT */
gchar *id;
@@ -231,6 +231,7 @@ EConfig *e_config_construct(EConfig *, gint type, const gchar *id);
void e_config_add_items(EConfig *, GSList *items, EConfigItemsFunc commitfunc, EConfigItemsFunc abortfunc, EConfigItemsFunc freefunc, gpointer data);
void e_config_add_page_check(EConfig *, const gchar *pageid, EConfigCheckFunc, gpointer data);
+void e_config_set_page_is_finish (EConfig *ec, const gchar *pageid, gboolean is_finish);
void e_config_set_target(EConfig *emp, EConfigTarget *target);
GtkWidget *e_config_create_widget(EConfig *);
diff --git a/e-util/e-corba-utils.h b/e-util/e-corba-utils.h
deleted file mode 100644
index c7527ebe26..0000000000
--- a/e-util/e-corba-utils.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_CORBA_UTILS_H
-#define E_CORBA_UTILS_H
-
-#include <orbit/orbit.h>
-
-const CORBA_char *e_safe_corba_string (const gchar *s);
-CORBA_char *e_safe_corba_string_dup (const gchar *s);
-
-#endif
diff --git a/e-util/e-dialog-utils.c b/e-util/e-dialog-utils.c
index 5bc1bbc685..d02a42572b 100644
--- a/e-util/e-dialog-utils.c
+++ b/e-util/e-dialog-utils.c
@@ -343,29 +343,29 @@ e_file_dialog_save_folder (const gchar *title)
* no signals connected and is not shown.
**/
GtkWidget *
-e_file_get_save_filesel (GtkWidget *parent, const gchar *title, const gchar *name, GtkFileChooserAction action)
+e_file_get_save_filesel (GtkWindow *parent, const gchar *title, const gchar *name, GtkFileChooserAction action)
{
GtkWidget *filesel;
gchar *uri;
- filesel = gtk_file_chooser_dialog_new (title,
- NULL,
- action,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- (action == GTK_FILE_CHOOSER_ACTION_OPEN) ? GTK_STOCK_OPEN:GTK_STOCK_SAVE, GTK_RESPONSE_OK,
- NULL);
+ g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
+
+ filesel = gtk_file_chooser_dialog_new (
+ title, parent, action,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ (action == GTK_FILE_CHOOSER_ACTION_OPEN) ?
+ GTK_STOCK_OPEN : GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
gtk_dialog_set_default_response (GTK_DIALOG (filesel), GTK_RESPONSE_OK);
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (filesel), FALSE);
- if (parent)
- e_dialog_set_transient_for ((GtkWindow *)filesel, parent);
-
- uri = e_file_get_save_path();
+ uri = e_file_get_save_path ();
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (filesel), uri);
+ gtk_file_chooser_set_current_folder_uri (
+ GTK_FILE_CHOOSER (filesel), uri);
if (name && name[0])
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filesel), name);
+ gtk_file_chooser_set_current_name (
+ GTK_FILE_CHOOSER (filesel), name);
g_free (uri);
diff --git a/e-util/e-dialog-utils.h b/e-util/e-dialog-utils.h
index 71c801cbc0..98d85e151d 100644
--- a/e-util/e-dialog-utils.h
+++ b/e-util/e-dialog-utils.h
@@ -43,7 +43,7 @@ gchar *e_file_dialog_save (const gchar *title, const gchar *fna
gchar *e_file_dialog_save_folder (const gchar *title);
-GtkWidget * e_file_get_save_filesel (GtkWidget *parent, const gchar *title, const gchar *name, GtkFileChooserAction action);
+GtkWidget * e_file_get_save_filesel (GtkWindow *parent, const gchar *title, const gchar *name, GtkFileChooserAction action);
gboolean e_file_can_save(GtkWindow *parent, const gchar *uri);
gboolean e_file_check_local(const gchar *name);
diff --git a/e-util/e-dialog-widgets.c b/e-util/e-dialog-widgets.c
index afa680d11b..cdcd52dd26 100644
--- a/e-util/e-dialog-widgets.c
+++ b/e-util/e-dialog-widgets.c
@@ -320,9 +320,11 @@ e_dialog_radio_get (GtkWidget *widget, const gint *value_map)
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
for (i = 0, l = group; l; l = l->next, i++) {
- widget = GTK_WIDGET (l->data);
+ GtkToggleButton *toggle_button;
- if (GTK_TOGGLE_BUTTON (widget)->active)
+ toggle_button = GTK_TOGGLE_BUTTON (l->data);
+
+ if (gtk_toggle_button_get_active (toggle_button))
break;
}
@@ -373,10 +375,9 @@ e_dialog_toggle_set (GtkWidget *widget, gboolean value)
gboolean
e_dialog_toggle_get (GtkWidget *widget)
{
- g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (widget), FALSE);
- return GTK_TOGGLE_BUTTON (widget)->active;
+ return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
}
/**
@@ -396,7 +397,7 @@ e_dialog_spin_set (GtkWidget *widget, double value)
adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget));
- adj->value = value;
+ gtk_adjustment_set_value (adj, value);
g_signal_emit_by_name (adj, "value_changed", 0);
}
@@ -417,7 +418,8 @@ e_dialog_spin_get_double (GtkWidget *widget)
g_return_val_if_fail (GTK_IS_SPIN_BUTTON (widget), 0.0);
adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget));
- return adj->value;
+
+ return gtk_adjustment_get_value (adj);
}
/**
diff --git a/e-util/e-error.c b/e-util/e-error.c
index dd5dddf64e..b672e1d17e 100644
--- a/e-util/e-error.c
+++ b/e-util/e-error.c
@@ -412,6 +412,8 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
struct _e_error *e;
struct _e_error_button *b;
GtkWidget *hbox, *w, *scroll=NULL;
+ GtkWidget *action_area;
+ GtkWidget *content_area;
gchar *tmp, *domain, *id;
GString *out, *oerr;
GPtrArray *args;
@@ -422,11 +424,14 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
ee_load_tables();
dialog = (GtkDialog *)gtk_dialog_new();
+ action_area = gtk_dialog_get_action_area (dialog);
+ content_area = gtk_dialog_get_content_area (dialog);
+
gtk_dialog_set_has_separator(dialog, FALSE);
gtk_widget_ensure_style ((GtkWidget *)dialog);
- gtk_container_set_border_width ((GtkContainer *)(dialog->vbox), 0);
- gtk_container_set_border_width ((GtkContainer *)(dialog->action_area), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
if (parent == NULL && ee_parent_list)
parent = (GtkWindow *)ee_parent_list->data;
@@ -454,7 +459,7 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
gtk_label_set_markup((GtkLabel *)w, tmp);
GTK_WIDGET_UNSET_FLAGS (w, GTK_CAN_FOCUS);
gtk_widget_show(w);
- gtk_box_pack_start((GtkBox *)dialog->vbox, w, TRUE, TRUE, 12);
+ gtk_box_pack_start (GTK_BOX (content_area), w, TRUE, TRUE, 12);
return (GtkWidget *)dialog;
}
@@ -557,7 +562,7 @@ e_error_newv(GtkWindow *parent, const gchar *tag, const gchar *arg0, va_list ap)
gtk_widget_show_all(hbox);
- gtk_box_pack_start((GtkBox *)dialog->vbox, hbox, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
g_object_set_data_full ((GObject *) dialog, "primary", perr, g_free);
g_object_set_data_full ((GObject *) dialog, "secondary", serr, g_free);
@@ -645,14 +650,14 @@ e_error_run(GtkWindow *parent, const gchar *tag, const gchar *arg0, ...)
guint
e_error_count_buttons (GtkDialog *dialog)
{
- GtkContainer *action_area;
+ GtkWidget *container;
GList *children, *iter;
guint n_buttons = 0;
g_return_val_if_fail (GTK_DIALOG (dialog), 0);
- action_area = GTK_CONTAINER (dialog->action_area);
- children = gtk_container_get_children (action_area);
+ container = gtk_dialog_get_action_area (dialog);
+ children = gtk_container_get_children (GTK_CONTAINER (container));
/* Iterate over the children looking for buttons. */
for (iter = children; iter != NULL; iter = iter->next)
diff --git a/e-util/e-import.c b/e-util/e-import.c
index 6f4c5947b4..0c10715ce3 100644
--- a/e-util/e-import.c
+++ b/e-util/e-import.c
@@ -29,10 +29,6 @@
#include <gtk/gtk.h>
-#include <libgnomeui/gnome-druid.h>
-#include <libgnomeui/gnome-druid-page-standard.h>
-#include <libgnomeui/gnome-druid-page-edge.h>
-
#include "e-import.h"
#include <glib/gi18n.h>
diff --git a/e-util/e-import.h b/e-util/e-import.h
index 5a3165e117..9e409a30fb 100644
--- a/e-util/e-import.h
+++ b/e-util/e-import.h
@@ -60,7 +60,7 @@ enum _e_import_target_t {
* @type: target type
* @priority: Priority of importer. Higher values will be processed first.
* @supported: Callback to see if this target is supported by the importer.
- * @get_widget: A widget factory for this importer, if it needs any extra information in the druid. It will update the target.
+ * @get_widget: A widget factory for this importer, if it needs any extra information in the assistant. It will update the target.
* @import: Run the import.
* @user_data: User data for the callbacks;
*
diff --git a/e-util/e-logger.c b/e-util/e-logger.c
index eac1a8fb06..07571d229a 100644
--- a/e-util/e-logger.c
+++ b/e-util/e-logger.c
@@ -43,7 +43,7 @@
((obj), E_TYPE_LOGGER, ELoggerPrivate))
struct _ELoggerPrivate {
- gchar *component;
+ gchar *name;
gchar *logfile;
FILE *fp;
@@ -52,13 +52,13 @@ struct _ELoggerPrivate {
enum {
PROP_0,
- PROP_COMPONENT
+ PROP_NAME
};
static gpointer parent_class;
static gboolean
-flush_logfile (ELogger *logger)
+logger_flush (ELogger *logger)
{
if (logger->priv->fp)
fflush (logger->priv->fp);
@@ -68,16 +68,26 @@ flush_logfile (ELogger *logger)
}
static void
-logger_set_component (ELogger *logger,
- const gchar *component)
+logger_set_dirty (ELogger *logger)
+{
+ if (logger->priv->timer)
+ return;
+
+ logger->priv->timer = g_timeout_add (
+ TIMEOUT_INTERVAL, (GSourceFunc) logger_flush, logger);
+}
+
+static void
+logger_set_name (ELogger *logger,
+ const gchar *name)
{
gchar *temp;
- g_return_if_fail (logger->priv->component == NULL);
+ g_return_if_fail (logger->priv->name == NULL);
- temp = g_strdup_printf ("%s.log.XXXXXX", component);
+ temp = g_strdup_printf ("%s.log.XXXXXX", name);
- logger->priv->component = g_strdup (component);
+ logger->priv->name = g_strdup (name);
logger->priv->logfile = e_mktemp (temp);
logger->priv->fp = g_fopen (logger->priv->logfile, "w");
logger->priv->timer = 0;
@@ -95,8 +105,8 @@ logger_set_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_COMPONENT:
- logger_set_component (
+ case PROP_NAME:
+ logger_set_name (
E_LOGGER (object),
g_value_get_string (value));
return;
@@ -112,9 +122,9 @@ logger_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_COMPONENT:
+ case PROP_NAME:
g_value_set_string (
- value, e_logger_get_component (
+ value, e_logger_get_name (
E_LOGGER (object)));
return;
}
@@ -129,11 +139,11 @@ logger_finalize (GObject *object)
if (logger->priv->timer)
g_source_remove (logger->priv->timer);
- flush_logfile (logger);
+ logger_flush (logger);
if (logger->priv->fp)
fclose (logger->priv->fp);
- g_free (logger->priv->component);
+ g_free (logger->priv->name);
g_free (logger->priv->logfile);
/* Chain up to parent's finalize() method. */
@@ -155,11 +165,11 @@ logger_class_init (ELoggerClass *class)
g_object_class_install_property (
object_class,
- PROP_COMPONENT,
+ PROP_NAME,
g_param_spec_string (
- "component",
- _("Component"),
- _("Name of the component being logged"),
+ "name",
+ _("Name"),
+ _("Name of the logger"),
"anonymous",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
@@ -198,34 +208,24 @@ e_logger_get_type (void)
}
ELogger *
-e_logger_create (const gchar *component)
+e_logger_new (const gchar *name)
{
- g_return_val_if_fail (component != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
- return g_object_new (E_TYPE_LOGGER, "component", component, NULL);
+ return g_object_new (E_TYPE_LOGGER, "name", name, NULL);
}
const gchar *
-e_logger_get_component (ELogger *logger)
+e_logger_get_name (ELogger *logger)
{
g_return_val_if_fail (E_IS_LOGGER (logger), NULL);
- return logger->priv->component;
-}
-
-static void
-set_dirty (ELogger *logger)
-{
- if (logger->priv->timer)
- return;
-
- logger->priv->timer = g_timeout_add_seconds (
- TIMEOUT_INTERVAL, (GSourceFunc) flush_logfile, logger);
+ return logger->priv->name;
}
void
e_logger_log (ELogger *logger,
- gint level,
+ ELogLevel level,
gchar *primary,
gchar *secondary)
{
@@ -240,13 +240,13 @@ e_logger_log (ELogger *logger,
fprintf (logger->priv->fp, "%d:%ld:%s\n", level, t, primary);
fprintf (logger->priv->fp, "%d:%ld:%s\n", level, t, secondary);
- set_dirty (logger);
+ logger_set_dirty (logger);
}
void
e_logger_get_logs (ELogger *logger,
ELogFunction func,
- gpointer data)
+ gpointer user_data)
{
FILE *fp;
gchar buf[250];
@@ -288,11 +288,11 @@ e_logger_get_logs (ELogger *logger,
g_string_append (str, tmp);
}
- func (str->str, data);
+ func (str->str, user_data);
g_string_free (str, TRUE);
} else
- func (tmp, data);
+ func (tmp, user_data);
}
fclose (fp);
diff --git a/e-util/e-logger.h b/e-util/e-logger.h
index b3bd4f8919..efb5cd47f1 100644
--- a/e-util/e-logger.h
+++ b/e-util/e-logger.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef __E_LOGGER_H__
-#define __E_LOGGER_H__
+#ifndef E_LOGGER_H
+#define E_LOGGER_H
#include <glib-object.h>
@@ -52,34 +52,32 @@ typedef struct _ELoggerPrivate ELoggerPrivate;
typedef void (*ELogFunction) (gchar *line, gpointer data);
-enum e_log_level_t {
+typedef enum {
E_LOG_ERROR,
- E_LOG_WARNINGS,
+ E_LOG_WARNING,
E_LOG_DEBUG
-};
+} ELogLevel;
-/* The object */
struct _ELogger {
GObject parent;
-
- struct _ELoggerPrivate *priv;
+ ELoggerPrivate *priv;
};
struct _ELoggerClass {
- GObjectClass popup_class;
+ GObjectClass parent_class;
};
GType e_logger_get_type (void);
-ELogger * e_logger_create (const gchar *component);
-const gchar * e_logger_get_component (ELogger *logger);
+ELogger * e_logger_new (const gchar *name);
+const gchar * e_logger_get_name (ELogger *logger);
void e_logger_log (ELogger *logger,
- gint level,
+ ELogLevel level,
gchar *primary,
gchar *secondary);
void e_logger_get_logs (ELogger *logger,
ELogFunction func,
- gpointer data);
+ gpointer user_data);
G_END_DECLS
-#endif /* __E_LOGGER_H__ */
+#endif /* E_LOGGER_H */
diff --git a/e-util/e-marshal.list b/e-util/e-marshal.list
index 366602491b..d6a3f0cb55 100644
--- a/e-util/e-marshal.list
+++ b/e-util/e-marshal.list
@@ -66,3 +66,5 @@ NONE:STRING,STRING,STRING
NONE:STRING,STRING,UINT
OBJECT:OBJECT,DOUBLE,DOUBLE,BOOLEAN
POINTER:NONE
+STRING:NONE
+
diff --git a/e-util/e-menu.c b/e-util/e-menu.c
deleted file mode 100644
index 76c41b62f5..0000000000
--- a/e-util/e-menu.c
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-ui-util.h>
-
-#include <libedataserver/e-data-server-util.h>
-
-#include "e-menu.h"
-#include "e-icon-factory.h"
-
-#define d(x)
-
-struct _EMenuFactory {
- struct _EMenuFactory *next, *prev;
-
- gchar *menuid;
- EMenuFactoryFunc factory;
- gpointer factory_data;
-};
-
-struct _item_node {
- struct _item_node *next;
-
- EMenuItem *item;
- struct _menu_node *menu;
-};
-
-struct _menu_node {
- struct _menu_node *next, *prev;
-
- EMenu *parent;
-
- GSList *items;
- GSList *uis;
- GSList *pixmaps;
-
- EMenuItemsFunc freefunc;
- gpointer data;
-
- /* a copy of items wrapped in an item_node, for bonobo
- * callback mapping */
- struct _item_node *menu;
-};
-
-struct _EMenuPrivate {
- EDList menus;
-};
-
-static GObjectClass *em_parent;
-
-static void
-em_init(GObject *o)
-{
- EMenu *emp = (EMenu *)o;
- struct _EMenuPrivate *p;
-
- p = emp->priv = g_malloc0(sizeof(struct _EMenuPrivate));
-
- e_dlist_init(&p->menus);
-}
-
-static void
-em_finalise(GObject *o)
-{
- EMenu *em = (EMenu *)o;
- struct _EMenuPrivate *p = em->priv;
- struct _menu_node *mnode;
-
- if (em->target)
- e_menu_target_free(em, em->target);
- g_free(em->menuid);
-
- while ((mnode = (struct _menu_node *)e_dlist_remhead(&p->menus))) {
- struct _item_node *inode;
-
- if (mnode->freefunc)
- mnode->freefunc(em, mnode->items, mnode->uis, mnode->pixmaps, mnode->data);
-
- inode = mnode->menu;
- while (inode) {
- struct _item_node *nnode = inode->next;
-
- g_free(inode);
- inode = nnode;
- }
-
- g_free(mnode);
- }
-
- g_free(p);
-
- ((GObjectClass *)em_parent)->finalize(o);
-}
-
-static void
-em_target_free(EMenu *ep, EMenuTarget *t)
-{
- g_free(t);
- /* look funny but t has a reference to us */
- g_object_unref(ep);
-}
-
-static void
-em_class_init(GObjectClass *klass)
-{
- d(printf("EMenu class init %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type)));
-
- klass->finalize = em_finalise;
- ((EMenuClass *)klass)->target_free = em_target_free;
-}
-
-static void
-em_base_init(GObjectClass *klass)
-{
- /* each class instance must have its own list, it isn't inherited */
- d(printf("%p: list init\n", klass));
- e_dlist_init(&((EMenuClass *)klass)->factories);
-}
-
-/**
- * e_menu_get_type:
- *
- * Standard GObject type function. Used to subclass this type only.
- *
- * Return value: The EMenu object type.
- **/
-GType
-e_menu_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMenuClass),
- (GBaseInitFunc)em_base_init, NULL,
- (GClassInitFunc)em_class_init,
- NULL, NULL,
- sizeof(EMenu), 0,
- (GInstanceInitFunc)em_init
- };
- em_parent = g_type_class_ref(G_TYPE_OBJECT);
- type = g_type_register_static(G_TYPE_OBJECT, "EMenu", &info, 0);
- }
-
- return type;
-}
-
-/**
- * e_menu_construct:
- * @em: An instantiated but uninitislied EPopup.
- * @menuid: The unique identifier for this menu.
- *
- * Construct the base menu instance based on the parameters.
- *
- * Return value: Returns @em.
- **/
-EMenu *e_menu_construct(EMenu *em, const gchar *menuid)
-{
- struct _EMenuFactory *f;
- EMenuClass *klass;
-
- d(printf("constructing menu '%s'\n", menuid));
-
- klass = (EMenuClass *)G_OBJECT_GET_CLASS(em);
-
- d(printf(" class is %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type)));
-
- em->menuid = g_strdup(menuid);
-
- /* setup the menu itself based on factories */
- f = (struct _EMenuFactory *)klass->factories.head;
- if (f->next == NULL) {
- d(printf("%p no factories registered on menu\n", klass));
- }
-
- while (f->next) {
- if (f->menuid == NULL
- || !strcmp(f->menuid, em->menuid)) {
- d(printf(" calling factory\n"));
- f->factory(em, f->factory_data);
- }
- f = f->next;
- }
-
- return em;
-}
-
-/**
- * e_menu_add_items:
- * @emp: An initialised EMenu.
- * @items: A list of EMenuItems or derived structures defining a group
- * of menu items for this menu.
- * @uifiles: A list of EMenuUIFile objects describing all ui files
- * associated with the items.
- * @pixmaps: A list of EMenuPixmap objects describing all pixmaps
- * associated with the menus.
- * @freefunc: If supplied, called when the menu items are no longer needed.
- * @data: user-data passed to @freefunc and activate callbacks.
- *
- * Add new EMenuItems to the menu's. This may be called any number of
- * times before the menu is first activated to hook onto any of the
- * menu items defined for that view.
- *
- * Return value: A handle that can be passed to remove_items as required.
- **/
-gpointer
-e_menu_add_items(EMenu *emp, GSList *items, GSList *uifiles, GSList *pixmaps, EMenuItemsFunc freefunc, gpointer data)
-{
- struct _menu_node *node;
- GSList *l;
-
- node = g_malloc0(sizeof(*node));
- node->parent = emp;
- node->items = items;
- node->uis = uifiles;
- node->pixmaps = pixmaps;
- node->freefunc = freefunc;
- node->data = data;
-
- for (l=items;l;l=g_slist_next(l)) {
- struct _item_node *inode = g_malloc0(sizeof(*inode));
- EMenuItem *item = l->data;
-
- inode->item = item;
- inode->menu = node;
- inode->next = node->menu;
- node->menu = inode;
- }
-
- for (l=pixmaps;l;l=g_slist_next(l)) {
- EMenuPixmap *pixmap = l->data;
-
- if (pixmap->pixmap == NULL) {
- GdkPixbuf *pixbuf;
-
- pixbuf = e_icon_factory_get_icon(pixmap->name, pixmap->size);
- if (pixbuf == NULL) {
- g_warning("Unable to load icon '%s'", pixmap->name);
- } else {
- pixmap->pixmap = bonobo_ui_util_pixbuf_to_xml(pixbuf);
- g_object_unref(pixbuf);
- }
- }
- }
-
- e_dlist_addtail(&emp->priv->menus, (EDListNode *)node);
-
- /* FIXME: add the menu's to a running menu if it is there? */
-
- return (gpointer)node;
-}
-
-/**
- * e_menu_remove_items:
- * @emp:
- * @handle:
- *
- * Remove menu items previously added.
- **/
-void
-e_menu_remove_items(EMenu *emp, gpointer handle)
-{
- struct _menu_node *node = handle;
- struct _item_node *inode;
- GSList *l;
-
- e_dlist_remove((EDListNode *)node);
-
- if (emp->uic) {
- for (l = node->items;l;l=g_slist_next(l)) {
- EMenuItem *item = l->data;
-
- bonobo_ui_component_remove_verb(emp->uic, item->verb);
- }
- }
-
- if (node->freefunc)
- node->freefunc(emp, node->items, node->uis, node->pixmaps, node->data);
-
- inode = node->menu;
- while (inode) {
- struct _item_node *nnode = inode->next;
-
- g_free(inode);
- inode = nnode;
- }
-
- g_free(node);
-}
-
-static void
-em_activate_toggle(BonoboUIComponent *component, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- struct _item_node *inode = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- ((EMenuToggleActivateFunc)inode->item->activate)(inode->menu->parent, inode->item, state[0] != '0', inode->menu->data);
-}
-
-static void
-em_activate(BonoboUIComponent *uic, gpointer data, const gchar *cname)
-{
- struct _item_node *inode = data;
-
- ((EMenuActivateFunc)inode->item->activate)(inode->menu->parent, inode->item, inode->menu->data);
-}
-
-/**
- * e_menu_activate:
- * @em: An initialised EMenu.
- * @uic: The BonoboUI component for this views menu's.
- * @act: If %TRUE, then the control is being activated.
- *
- * This is called by the owner of the component, control, or view to
- * pass on the activate or deactivate control signals. If the view is
- * being activated then the callbacks and menu items are setup,
- * otherwise they are removed.
- *
- * This should always be called in the strict sequence of activate, then
- * deactivate, repeated any number of times.
- **/
-void e_menu_activate(EMenu *em, struct _BonoboUIComponent *uic, gint act)
-{
- struct _EMenuPrivate *p = em->priv;
- struct _menu_node *mw;
- GSList *l;
-
- if (act) {
- GArray *verbs;
- gint i;
-
- em->uic = uic;
-
- verbs = g_array_new(TRUE, FALSE, sizeof(BonoboUIVerb));
- for (mw = (struct _menu_node *)p->menus.head;mw->next;mw=mw->next) {
- struct _item_node *inode;
-
- for (l = mw->uis; l; l = g_slist_next(l)) {
- EMenuUIFile *ui = l->data;
-
- bonobo_ui_util_set_ui(uic, ui->appdir, ui->filename, ui->appname, NULL);
- }
-
- for (l = mw->pixmaps; l; l = g_slist_next(l)) {
- EMenuPixmap *pm = l->data;
-
- if (pm->pixmap)
- bonobo_ui_component_set_prop(uic, pm->command, "pixmap", pm->pixmap, NULL);
- }
-
- for (inode = mw->menu; inode; inode=inode->next) {
- EMenuItem *item = inode->item;
- BonoboUIVerb *verb;
-
- d(printf("adding menu verb '%s'\n", item->verb));
-
- switch (item->type & E_MENU_TYPE_MASK) {
- case E_MENU_ITEM:
- i = verbs->len;
- verbs = g_array_set_size(verbs, i+1);
- verb = &((BonoboUIVerb *)verbs->data)[i];
-
- verb->cname = item->verb;
- verb->cb = em_activate;
- verb->user_data = inode;
- break;
- case E_MENU_TOGGLE:
- bonobo_ui_component_set_prop(uic, item->path, "state", item->type & E_MENU_ACTIVE?"1":"0", NULL);
- bonobo_ui_component_add_listener(uic, item->verb, em_activate_toggle, inode);
- break;
- }
- }
- }
-
- if (verbs->len)
- bonobo_ui_component_add_verb_list(uic, (BonoboUIVerb *)verbs->data);
-
- g_array_free(verbs, TRUE);
- } else {
- for (mw = (struct _menu_node *)p->menus.head;mw->next;mw=mw->next) {
- for (l = mw->items;l;l=g_slist_next(l)) {
- EMenuItem *item = l->data;
-
- bonobo_ui_component_remove_verb(uic, item->verb);
- }
- }
-
- em->uic = NULL;
- }
-}
-
-/**
- * e_menu_update_target:
- * @em: An initialised EMenu.
- * @tp: Target, after this call the menu owns the target.
- *
- * Change the target for the menu. Once the target is changed, the
- * sensitivity state of the menu items managed by @em is re-evaluated
- * and the physical menu's updated to reflect it.
- *
- * This is used by the owner of the menu and view to update the menu
- * system based on user input or changed system state.
- **/
-void e_menu_update_target(EMenu *em, gpointer tp)
-{
- struct _EMenuPrivate *p = em->priv;
- EMenuTarget *t = tp;
- guint32 mask = ~0;
- struct _menu_node *mw;
- GSList *l;
-
- if (em->target && em->target != t)
- e_menu_target_free(em, em->target);
-
- /* if we unset the target, should we disable/hide all the menu items? */
- em->target = t;
- if (t == NULL)
- return;
-
- mask = t->mask;
-
- /* canna do any more capt'n */
- if (em->uic == NULL)
- return;
-
- for (mw = (struct _menu_node *)p->menus.head;mw->next;mw=mw->next) {
- for (l = mw->items;l;l=g_slist_next(l)) {
- EMenuItem *item = l->data;
- gint state;
-
- d(printf("checking item '%s' mask %08x against target %08x\n", item->verb, item->enable, mask));
-
- state = (item->enable & mask) == 0;
- bonobo_ui_component_set_prop(em->uic, item->path, "sensitive", state?"1":"0", NULL);
- /* visible? */
- }
- }
-}
-
-/* ********************************************************************** */
-
-/**
- * e_menu_class_add_factory:
- * @klass: An EMenuClass type to which this factory applies.
- * @menuid: The identifier of the menu for this factory, or NULL to be
- * called on all menus.
- * @func: An EMenuFactoryFunc callback.
- * @data: Callback data for @func.
- *
- * Add a menu factory which will be called when the menu @menuid is
- * created. The factory is free to add new items as it wishes to the
- * menu provided in the callback.
- *
- * TODO: Make the menuid a pattern?
- *
- * Return value: A handle to the factory.
- **/
-EMenuFactory *
-e_menu_class_add_factory(EMenuClass *klass, const gchar *menuid, EMenuFactoryFunc func, gpointer data)
-{
- struct _EMenuFactory *f = g_malloc0(sizeof(*f));
-
- d(printf("%p adding factory '%s' to class '%s'\n", klass, menuid?menuid:"<all menus>", g_type_name(((GObjectClass *)klass)->g_type_class.g_type)));
-
- f->menuid = g_strdup(menuid);
- f->factory = func;
- f->factory_data = data;
- e_dlist_addtail(&klass->factories, (EDListNode *)f);
-
- /* setup the menu itself based on factories */
- {
- struct _EMenuFactory *j;
-
- j = (struct _EMenuFactory *)klass->factories.head;
- if (j->next == NULL) {
- d(printf("%p no factories registered on menu???\n", klass));
- }
- }
-
- return f;
-}
-
-/**
- * e_menu_class_remove_factory:
- * @klass: Class on which the factory was originally added.
- * @f: Factory handle.
- *
- * Remove a popup factory. This must only be called once, and must
- * only be called using a valid factory handle @f. After this call,
- * @f is undefined.
- **/
-void
-e_menu_class_remove_factory(EMenuClass *klass, EMenuFactory *f)
-{
- e_dlist_remove((EDListNode *)f);
- g_free(f->menuid);
- g_free(f);
-}
-
-/**
- * e_menu_target_new:
- * @ep: An EMenu to which this target applies.
- * @type: Target type, up to implementation.
- * @size: Size of memory to allocate. Must be >= sizeof(EMenuTarget).
- *
- * Allocate a new menu target suitable for this class. @size is used
- * to specify the actual target size, which may vary depending on the
- * implementing class.
- **/
-gpointer e_menu_target_new(EMenu *ep, gint type, gsize size)
-{
- EMenuTarget *t;
-
- if (size < sizeof(EMenuTarget)) {
- g_warning ("size less than size of EMenuTarget\n");
- size = sizeof (EMenuTarget);
- }
-
- t = g_malloc0(size);
- t->menu = ep;
- g_object_ref(ep);
- t->type = type;
-
- return t;
-}
-
-/**
- * e_menu_target_free:
- * @ep: EMenu on which the target was allocated.
- * @o: Tareget to free.
- *
- * Free a target.
- **/
-void
-e_menu_target_free(EMenu *ep, gpointer o)
-{
- EMenuTarget *t = o;
-
- ((EMenuClass *)G_OBJECT_GET_CLASS(ep))->target_free(ep, t);
-}
-
-/* ********************************************************************** */
-
-/* Main menu plugin handler */
-
-/* NB: This has significant overlap with EPopupHook */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.item:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="Main menu plugin">
- <hook class="org.gnome.evolution.bonobomenu:1.0">
- <menu id="any" target="select" view="org.gnome.mail">
- <ui file="ui file1"/>
- <ui file="ui file2"/>
- <pixmap command="command" pixmap="stockname" size="menu|button|small_toolbar|large_toolbar|dnd|dialog"/>
- <item
- type="item|toggle"
- verb="verb"
- enable="select_one"
- visible="select_one"
- activate="doactivate"/>
- </menu>
- </hook>
- </extension>
-
-*/
-
-static gpointer emph_parent_class;
-#define emph ((EMenuHook *)eph)
-
-/* must have 1:1 correspondence with e-menu types in order */
-static const EPluginHookTargetKey emph_item_types[] = {
- { "item", E_MENU_ITEM },
- { "toggle", E_MENU_TOGGLE },
- { "radio", E_MENU_RADIO },
- { NULL }
-};
-
-/* 1:1 with e-icon-factory sizes */
-static const EPluginHookTargetKey emph_pixmap_sizes[] = {
- { "menu", 0 },
- { "button", 1},
- { "small_toolbar", 2},
- { "large_toolbar", 3},
- { "dnd", 4},
- { "dialog", 5},
- { NULL }
-};
-
-static void
-emph_menu_activate(EMenu *em, EMenuItem *item, gpointer data)
-{
- EMenuHook *hook = data;
-
- d(printf("invoking plugin hook '%s' %p\n", (gchar *)item->user_data, em->target));
-
- e_plugin_invoke(hook->hook.plugin, item->user_data, em->target);
-}
-
-static void
-emph_menu_toggle_activate(EMenu *em, EMenuItem *item, gint state, gpointer data)
-{
- EMenuHook *hook = data;
-
- /* FIXME: where does the toggle state go? */
- d(printf("invoking plugin hook '%s' %p\n", (gchar *)item->user_data, em->target));
-
- e_plugin_invoke(hook->hook.plugin, item->user_data, em->target);
-}
-
-static void
-emph_menu_factory(EMenu *emp, gpointer data)
-{
- struct _EMenuHookMenu *menu = data;
-
- d(printf("menu factory, adding %d items\n", g_slist_length(menu->items)));
-
- if (menu->items)
- e_menu_add_items(emp, menu->items, menu->uis, menu->pixmaps, NULL, menu->hook);
-}
-
-static void
-emph_free_item(struct _EMenuItem *item)
-{
- g_free(item->path);
- g_free(item->verb);
- g_free(item->user_data);
- g_free(item);
-}
-
-static void
-emph_free_ui(struct _EMenuUIFile *ui)
-{
- g_free(ui->appdir);
- g_free(ui->appname);
- g_free(ui->filename);
-}
-
-static void
-emph_free_pixmap(struct _EMenuPixmap *pixmap)
-{
- g_free(pixmap->command);
- g_free(pixmap->name);
- g_free(pixmap->pixmap);
- g_free(pixmap);
-}
-
-static void
-emph_free_menu(struct _EMenuHookMenu *menu)
-{
- g_slist_foreach(menu->items, (GFunc)emph_free_item, NULL);
- g_slist_free(menu->items);
- g_slist_foreach(menu->uis, (GFunc)emph_free_ui, NULL);
- g_slist_free(menu->uis);
- g_slist_foreach(menu->pixmaps, (GFunc)emph_free_pixmap, NULL);
- g_slist_free(menu->pixmaps);
-
- g_free(menu->id);
- g_free(menu);
-}
-
-static struct _EMenuItem *
-emph_construct_item(EPluginHook *eph, EMenuHookMenu *menu, xmlNodePtr root, EMenuHookTargetMap *map)
-{
- struct _EMenuItem *item;
-
- d(printf(" loading menu item\n"));
- item = g_malloc0(sizeof(*item));
- item->type = e_plugin_hook_id(root, emph_item_types, "type");
- item->path = e_plugin_xml_prop(root, "path");
- item->verb = e_plugin_xml_prop(root, "verb");
- item->visible = e_plugin_hook_mask(root, map->mask_bits, "visible");
- item->enable = e_plugin_hook_mask(root, map->mask_bits, "enable");
- item->user_data = e_plugin_xml_prop(root, "activate");
- if ((item->type & E_MENU_TYPE_MASK) == E_MENU_TOGGLE)
- item->activate = G_CALLBACK(emph_menu_toggle_activate);
- else
- item->activate = G_CALLBACK(emph_menu_activate);
-
- if (item->type == -1 || item->user_data == NULL)
- goto error;
-
- d(printf(" path=%s\n", item->path));
- d(printf(" verb=%s\n", item->verb));
-
- return item;
-error:
- d(printf("error!\n"));
- emph_free_item(item);
- return NULL;
-}
-
-static struct _EMenuPixmap *
-emph_construct_pixmap(EPluginHook *eph, EMenuHookMenu *menu, xmlNodePtr root)
-{
- struct _EMenuPixmap *pixmap;
-
- d(printf(" loading menu pixmap\n"));
- pixmap = g_malloc0(sizeof(*pixmap));
- pixmap->command = e_plugin_xml_prop(root, "command");
- pixmap->name = e_plugin_xml_prop(root, "pixmap");
- pixmap->size = e_plugin_hook_id(root, emph_pixmap_sizes, "size");
-
- if (pixmap->command == NULL || pixmap->name == NULL || pixmap->size == -1)
- goto error;
-
- return pixmap;
-error:
- d(printf("error!\n"));
- emph_free_pixmap(pixmap);
- return NULL;
-}
-
-static struct _EMenuHookMenu *
-emph_construct_menu(EPluginHook *eph, xmlNodePtr root)
-{
- struct _EMenuHookMenu *menu;
- xmlNodePtr node;
- EMenuHookTargetMap *map;
- EMenuHookClass *klass = (EMenuHookClass *)G_OBJECT_GET_CLASS(eph);
- gchar *tmp;
-
- d(printf(" loading menu\n"));
- menu = g_malloc0(sizeof(*menu));
- menu->hook = (EMenuHook *)eph;
-
- tmp = (gchar *)xmlGetProp(root, (const guchar *)"target");
- if (tmp == NULL)
- goto error;
- map = g_hash_table_lookup(klass->target_map, tmp);
- xmlFree(tmp);
- if (map == NULL)
- goto error;
-
- menu->target_type = map->id;
- menu->id = e_plugin_xml_prop(root, "id");
- if (menu->id == NULL) {
- g_warning("Plugin '%s' missing 'id' field in menu for '%s'\n", eph->plugin->name,
- ((EPluginHookClass *)G_OBJECT_GET_CLASS(eph))->id);
- goto error;
- }
- node = root->children;
- while (node) {
- if (0 == strcmp((gchar *)node->name, "item")) {
- struct _EMenuItem *item;
-
- item = emph_construct_item(eph, menu, node, map);
- if (item)
- menu->items = g_slist_append(menu->items, item);
- } else if (0 == strcmp((gchar *)node->name, "ui")) {
- tmp = (gchar *)xmlGetProp(node, (const guchar *)"file");
- if (tmp) {
- EMenuUIFile *ui = g_malloc0(sizeof(*ui));
-
- ui->filename = g_strdup(tmp);
- xmlFree(tmp);
-#ifdef G_OS_WIN32
- {
- gchar *mapped_location =
- e_util_replace_prefix (EVOLUTION_PREFIX,
- e_util_get_prefix (),
- ui->filename);
- g_free (ui->filename);
- ui->filename = mapped_location;
- }
-#endif
- ui->appdir = g_strdup(g_get_tmp_dir());
- ui->appname = g_strdup("Evolution");
- menu->uis = g_slist_append(menu->uis, ui);
- }
- } else if (0 == strcmp((gchar *)node->name, "pixmap")) {
- struct _EMenuPixmap *pixmap;
-
- pixmap = emph_construct_pixmap(eph, menu, node);
- if (pixmap)
- menu->pixmaps = g_slist_append(menu->pixmaps, pixmap);
- }
- node = node->next;
- }
-
- return menu;
-error:
- d(printf("error loading menu hook\n"));
- emph_free_menu(menu);
- return NULL;
-}
-
-static gint
-emph_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root)
-{
- xmlNodePtr node;
- EMenuClass *klass;
-
- d(printf("loading menu hook\n"));
-
- if (!ep->enabled)
- return 0;
-
- if (((EPluginHookClass *)emph_parent_class)->construct(eph, ep, root) == -1)
- return -1;
-
- klass = ((EMenuHookClass *)G_OBJECT_GET_CLASS(eph))->menu_class;
-
- node = root->children;
- while (node) {
- if (strcmp((gchar *)node->name, "menu") == 0) {
- struct _EMenuHookMenu *menu;
-
- menu = emph_construct_menu(eph, node);
- if (menu) {
- d(printf(" plugin adding factory %p\n", klass));
- e_menu_class_add_factory(klass, menu->id, emph_menu_factory, menu);
- emph->menus = g_slist_append(emph->menus, menu);
- }
- }
-
- node = node->next;
- }
-
- eph->plugin = ep;
-
- return 0;
-}
-
-static void
-emph_finalise(GObject *o)
-{
- EPluginHook *eph = (EPluginHook *)o;
-
- g_slist_foreach(emph->menus, (GFunc)emph_free_menu, NULL);
- g_slist_free(emph->menus);
-
- ((GObjectClass *)emph_parent_class)->finalize(o);
-}
-
-static void
-emph_class_init(EPluginHookClass *klass)
-{
- d(printf("EMenuHook class init %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type)));
-
- ((GObjectClass *)klass)->finalize = emph_finalise;
- klass->construct = emph_construct;
-
- /* this is actually an abstract implementation but list it anyway */
- klass->id = "org.gnome.evolution.bonobomenu:1.0";
-
- ((EMenuHookClass *)klass)->target_map = g_hash_table_new(g_str_hash, g_str_equal);
- ((EMenuHookClass *)klass)->menu_class = g_type_class_ref(e_menu_get_type());
-}
-
-/**
- * e_menu_hook_get_type:
- *
- * Standard GObject function to get the object type. Used to subclass
- * EMenuHook.
- *
- * Return value: The type of the menu hook class.
- **/
-GType
-e_menu_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EMenuHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL,
- sizeof(EMenuHook), 0, (GInstanceInitFunc) NULL,
- };
-
- emph_parent_class = g_type_class_ref(e_plugin_hook_get_type());
- type = g_type_register_static(e_plugin_hook_get_type(), "EMenuHook", &info, 0);
- }
-
- return type;
-}
-
-/**
- * e_menu_hook_class_add_target_map:
- * @klass: The derived EMenuHook class.
- * @map: A map used to describe a single EMenuTarget for this class.
- *
- * Adds a target map to a concrete derived class of EMenu. The target
- * map enumerates a single target type, and the enable mask bit names,
- * so that the type can be loaded automatically by the EMenu class.
- **/
-void e_menu_hook_class_add_target_map(EMenuHookClass *klass, const EMenuHookTargetMap *map)
-{
- g_hash_table_insert(klass->target_map, (gpointer)map->type, (gpointer)map);
-}
diff --git a/e-util/e-menu.h b/e-util/e-menu.h
deleted file mode 100644
index 3b2416e46a..0000000000
--- a/e-util/e-menu.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michel Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __E_MENU_H__
-#define __E_MENU_H__
-
-#include <gtk/gtk.h>
-#include <libedataserver/e-msgport.h>
-
-G_BEGIN_DECLS
-
-/* This is an abstract popup menu management/merging class.
-
- To implement your own popup menu system, just create your own
- target types and implement the target free method. */
-
-typedef struct _EMenu EMenu;
-typedef struct _EMenuClass EMenuClass;
-
-typedef struct _EMenuItem EMenuItem;
-typedef struct _EMenuUIFile EMenuUIFile;
-typedef struct _EMenuPixmap EMenuPixmap;
-
-typedef struct _EMenuFactory EMenuFactory; /* anonymous type */
-typedef struct _EMenuTarget EMenuTarget;
-
-typedef void (*EMenuFactoryFunc)(EMenu *emp, gpointer data);
-typedef void (*EMenuActivateFunc)(EMenu *, EMenuItem *, gpointer data);
-typedef void (*EMenuToggleActivateFunc)(EMenu *, EMenuItem *, gint state, gpointer data);
-typedef void (*EMenuItemsFunc)(EMenu *, GSList *items, GSList *uifiles, GSList *pixmaps, gpointer data);
-
-/**
- * enum _e_menu_t - Menu item type.
- *
- * @E_MENU_ITEM: Normal menu item.
- * @E_MENU_TOGGLE: Toggle menu item.
- * @E_MENU_RADIO: unimplemented.
- * @E_MENU_TYPE_MASK: Mask used to separate item type from option bits.
- * @E_MENU_ACTIVE: Whether a toggle item is active.
- *
- * The type of menu items which are supported by the menu system.
- **/
-enum _e_menu_t {
- E_MENU_ITEM = 0,
- E_MENU_TOGGLE,
- E_MENU_RADIO,
- E_MENU_TYPE_MASK = 0xffff,
- E_MENU_ACTIVE = 0x10000
-};
-
-/**
- * struct _EMenuItem - A BonoboUI menu item.
- *
- * @type: Menu item type. %E_MENU_ITEM or %E_MENU_TOGGLE.
- * @path: BonoboUI Path to the menu item.
- * @verb: BonoboUI verb for the menu item.
- * @activate: Callback when the menu item is selected. This will be a
- * EMenuToggleActivateFunc for toggle items or EMenuActivateFunc for
- * normal items.
- * @user_data: User data for item.
- * @visible: Visibility mask, unimplemented.
- * @enable: Sensitivity mask, combined with the target mask.
- *
- * An EMenuItem defines a single menu item. This menu item is used to
- * hook onto callbacks from the bonobo menus, but not to build or
- * merge the menu itself.
- **/
-struct _EMenuItem {
- enum _e_menu_t type;
- gchar *path; /* full path? can we just create it from verb? */
- gchar *verb; /* command verb */
- GCallback activate; /* depends on type, the bonobo activate callback */
- gpointer user_data; /* up to caller to use */
- guint32 visible; /* is visible mask */
- guint32 enable; /* is enable mask */
-};
-
-/**
- * struct _EMenuPixmap - A menu icon holder.
- *
- * @command: The path to the command or verb to which this pixmap belongs.
- * @name: The name of the icon. Either an icon-theme name or the full
- * pathname of the icon.
- * @size: The e-icon-factory icon size.
- * @pixmap: The pixmap converted to XML format. If not set, then EMenu will
- * create it as required. This must be freed if set in the free function.
- *
- * Used to track all pixmap items used in menus. These need to be
- * supplied separately from the menu definition.
- **/
-struct _EMenuPixmap {
- gchar *command;
- gchar *name;
- gint size;
- gchar *pixmap;
-};
-
-/**
- * struct _EMenuUIFile - A meu UI file holder.
- *
- * @appdir: TODO; should this be handled internally.
- * @appname: TODO; should this be handled internally.
- * @filename: The filename of the BonoboUI XML menu definition.
- *
- * These values are passed directly to bonobo_ui_util_set_ui() when
- * the menu is activated.
- **/
-struct _EMenuUIFile {
- gchar *appdir;
- gchar *appname;
- gchar *filename;
-};
-
-/**
- * struct _EMenuTarget - A BonoboUI menu target definition.
- *
- * @menu: The parent menu object, used for virtual methods on the target.
- * @widget: The parent widget where available. In some cases the type
- * of this object is part of the published api for the target, in
- * others it is merely a GtkWidget from which you can find the
- * toplevel widget.
- * @type: Target type. This will be defined by the implementation.
- * @mask: Target mask. This is used to sensitise show items based on
- * their definition in EMenuItem.
- *
- * An EMenuTarget defines the context for a specific view instance.
- * It is used to enable and show menu items, and to provide contextual
- * data to menu invocations.
- **/
-struct _EMenuTarget {
- struct _EMenu *menu; /* used for virtual methods */
-
- GtkWidget *widget; /* used if you need a parent toplevel, if available */
- guint32 type; /* for implementors */
-
- guint32 mask; /* enable/visible mask */
-
- /* implementation fields follow */
-};
-
-/**
- * struct _EMenu - A BonoboUI menu manager object.
- *
- * @object: Superclass.
- * @priv: Private data.
- * @menuid: The id of this menu instance.
- * @uic: The current BonoboUIComponent which stores the actual menu
- * items this object manages.
- * @target: The current target for the view.
- *
- * The EMenu manager object manages the mappings between EMenuItems
- * and the BonoboUI menus loaded from UI files.
- **/
-struct _EMenu {
- GObject object;
- struct _EMenuPrivate *priv;
-
- gchar *menuid;
- struct _BonoboUIComponent *uic;
- EMenuTarget *target;
-};
-
-/**
- * struct _EMenuClass -
- *
- * @object_class: Superclass type.
- * @factories: A list of factories for this particular class of main menu.
- * @target_free: Virtual method to free the menu target. The base
- * class free method frees the allocation and unrefs the EMenu parent
- * pointer.
- *
- * The EMenu class definition. This should be sub-classed for each
- * component that wants to provide hookable main menus. The subclass
- * only needs to know how to allocate and free the various target
- * types it supports.
- **/
-struct _EMenuClass {
- GObjectClass object_class;
-
- EDList factories;
-
- void (*target_free)(EMenu *ep, EMenuTarget *t);
-};
-
-GType e_menu_get_type(void);
-
-/* Static class methods */
-EMenuFactory *e_menu_class_add_factory(EMenuClass *klass, const gchar *menuid, EMenuFactoryFunc func, gpointer data);
-void e_menu_class_remove_factory(EMenuClass *klass, EMenuFactory *f);
-
-EMenu *e_menu_construct(EMenu *menu, const gchar *menuid);
-
-void e_menu_add_ui(EMenu *, const gchar *appdir, const gchar *appname, const gchar *filename);
-void e_menu_add_pixmap(EMenu *, const gchar *cmd, const gchar *name, gint size);
-
-gpointer e_menu_add_items(EMenu *emp, GSList *items, GSList *uifiles, GSList *pixmaps, EMenuItemsFunc freefunc, gpointer data);
-void e_menu_remove_items(EMenu *emp, gpointer handle);
-
-void e_menu_activate(EMenu *, struct _BonoboUIComponent *uic, gint act);
-void e_menu_update_target(EMenu *, gpointer );
-
-gpointer e_menu_target_new(EMenu *, gint type, gsize size);
-void e_menu_target_free(EMenu *, gpointer );
-
-/* ********************************************************************** */
-
-/* menu plugin, they are closely integrated */
-
-/* To implement a basic menu plugin, you just need to subclass
- this and initialise the class target type tables */
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EMenuHookPixmap EMenuHookPixmap;
-typedef struct _EMenuHookMenu EMenuHookMenu;
-typedef struct _EMenuHook EMenuHook;
-typedef struct _EMenuHookClass EMenuHookClass;
-
-typedef struct _EPluginHookTargetMap EMenuHookTargetMap;
-typedef struct _EPluginHookTargetKey EMenuHookTargetMask;
-
-typedef void (*EMenuHookFunc)(struct _EPlugin *plugin, EMenuTarget *target);
-
-/**
- * struct _EMenuHookMenu - A group of items targetting a specific menu.
- *
- * @hook: Parent pointer.
- * @id: The identifier of the menu or view to which these items belong.
- * @target_type: The target number of the type of target these menu
- * items expect. This will be defined by menu itself.
- * @items: A list of EMenuItems.
- * @uis: A list of filenames of the BonoboUI files that need to be
- * loaded for an active view.
- * @pixmaps: A list of EMenuHookPixmap structures for the menus.
- *
- * This structure is used to keep track of all of the items that a
- * plugin wishes to add to specific menu. This is used internally by
- * a factory method defined by the EMenuHook to add the right menu
- * items to a given view.
- **/
-struct _EMenuHookMenu {
- struct _EMenuHook *hook; /* parent pointer */
- gchar *id; /* target menu id for these menu items */
- gint target_type; /* target type, not used */
- GSList *items; /* items to add to menu */
- GSList *uis; /* ui files */
- GSList *pixmaps; /* pixmap descriptors */
-};
-
-/**
- * struct _EMenuHook - A BonoboUI menu hook.
- *
- * @hook: Superclass.
- * @menus: A list of EMenuHookMenus for all menus registered on this
- * hook type.
- *
- * The EMenuHook class loads and manages the meta-data to required to
- * map plugin definitions to physical menus.
- **/
-struct _EMenuHook {
- EPluginHook hook;
-
- GSList *menus;
-};
-
-/**
- * struct _EMenuHookClass - Menu hook type.
- *
- * @hook_class: Superclass type.
- * @target_map: Table of EluginHookTargetMaps which enumerate the
- * target types and enable bits of the implementing class.
- * @menu_class: The EMenuClass of the corresponding popup manager for
- * implementing the class.
- *
- * The EMenuHookClass is an empty concrete class. It must be
- * subclassed and initialised appropriately to perform useful work.
- *
- * The EPluginHookClass.id must be set to the name and version of the
- * hook handler the implementation defines. The @target_map must be
- * initialised with the data required to enumerate the target types
- * and enable flags supported by the implementing class.
- **/
-struct _EMenuHookClass {
- EPluginHookClass hook_class;
-
- /* EMenuHookTargetMap by .type */
- GHashTable *target_map;
- /* the menu class these menus belong to */
- EMenuClass *menu_class;
-};
-
-GType e_menu_hook_get_type(void);
-
-/* for implementors */
-void e_menu_hook_class_add_target_map(EMenuHookClass *klass, const EMenuHookTargetMap *);
-
-G_END_DECLS
-
-#endif /* __E_MENU_H__ */
diff --git a/e-util/e-module.c b/e-util/e-module.c
new file mode 100644
index 0000000000..3919841910
--- /dev/null
+++ b/e-util/e-module.c
@@ -0,0 +1,318 @@
+/*
+ * e-module.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-module.h"
+
+#include <glib/gi18n.h>
+
+/* This is the symbol we call when loading a module. */
+#define LOAD_SYMBOL "e_module_load"
+
+/* This is the symbol we call when unloading a module. */
+#define UNLOAD_SYMBOL "e_module_unload"
+
+#define E_MODULE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MODULE, EModulePrivate))
+
+struct _EModulePrivate {
+ GModule *module;
+ gchar *filename;
+
+ void (*load) (GTypeModule *type_module);
+ void (*unload) (GTypeModule *type_module);
+};
+
+enum {
+ PROP_0,
+ PROP_FILENAME
+};
+
+static gpointer parent_class;
+
+static void
+module_set_filename (EModule *module,
+ const gchar *filename)
+{
+ g_return_if_fail (module->priv->filename == NULL);
+
+ module->priv->filename = g_strdup (filename);
+}
+
+static void
+module_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FILENAME:
+ module_set_filename (
+ E_MODULE (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+module_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FILENAME:
+ g_value_set_string (
+ value, e_module_get_filename (
+ E_MODULE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+module_finalize (GObject *object)
+{
+ EModulePrivate *priv;
+
+ priv = E_MODULE_GET_PRIVATE (object);
+
+ g_free (priv->filename);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+module_load (GTypeModule *type_module)
+{
+ EModulePrivate *priv;
+ gpointer symbol;
+
+ priv = E_MODULE_GET_PRIVATE (type_module);
+
+ g_return_val_if_fail (priv->filename != NULL, FALSE);
+ priv->module = g_module_open (priv->filename, 0);
+
+ if (priv->module == NULL)
+ goto fail;
+
+ if (!g_module_symbol (priv->module, LOAD_SYMBOL, &symbol))
+ goto fail;
+
+ priv->load = symbol;
+
+ if (!g_module_symbol (priv->module, UNLOAD_SYMBOL, &symbol))
+ goto fail;
+
+ priv->unload = symbol;
+
+ priv->load (type_module);
+
+ return TRUE;
+
+fail:
+ g_warning ("%s", g_module_error ());
+
+ if (priv->module != NULL)
+ g_module_close (priv->module);
+
+ return FALSE;
+}
+
+static void
+module_unload (GTypeModule *type_module)
+{
+ EModulePrivate *priv;
+
+ priv = E_MODULE_GET_PRIVATE (type_module);
+
+ priv->unload (type_module);
+
+ g_module_close (priv->module);
+ priv->module = NULL;
+
+ priv->load = NULL;
+ priv->unload = NULL;
+}
+
+static void
+module_class_init (EModuleClass *class)
+{
+ GObjectClass *object_class;
+ GTypeModuleClass *type_module_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EModulePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = module_set_property;
+ object_class->get_property = module_get_property;
+ object_class->finalize = module_finalize;
+
+ type_module_class = G_TYPE_MODULE_CLASS (class);
+ type_module_class->load = module_load;
+ type_module_class->unload = module_unload;
+
+ /**
+ * EModule:filename
+ *
+ * The filename of the module.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_FILENAME,
+ g_param_spec_string (
+ "filename",
+ _("Filename"),
+ _("The filename of the module"),
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+module_init (EModule *module)
+{
+ module->priv = E_MODULE_GET_PRIVATE (module);
+}
+
+GType
+e_module_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EModuleClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) module_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EModule),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) module_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_TYPE_MODULE, "EModule", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_module_new:
+ * @filename: filename of the shared library module
+ *
+ * Creates a new #EModule that will load the specific shared library
+ * when in use.
+ *
+ * Returns: a new #EModule for @filename
+ **/
+EModule *
+e_module_new (const gchar *filename)
+{
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ return g_object_new (E_TYPE_MODULE, "filename", filename, NULL);
+}
+
+/**
+ * e_module_get_filename:
+ * @module: an #EModule
+ *
+ * Returns the filename of the shared library for @module. The
+ * string is owned by @module and should not be modified or freed.
+ *
+ * Returns: the filename for @module
+ **/
+const gchar *
+e_module_get_filename (EModule *module)
+{
+ g_return_val_if_fail (E_IS_MODULE (module), NULL);
+
+ return module->priv->filename;
+}
+
+/**
+ * e_module_load_all_in_directory:
+ * @dirname: pathname for a directory containing modules to load
+ *
+ * Loads all the modules in the specified directory into memory. If
+ * you want to unload them (enabling on-demand loading) you must call
+ * g_type_module_unuse() on all the modules. Free the returned list
+ * with g_list_free().
+ *
+ * Returns: a list of #EModules loaded from @dirname
+ **/
+GList *
+e_module_load_all_in_directory (const gchar *dirname)
+{
+ GDir *dir;
+ const gchar *basename;
+ GList *loaded_modules = NULL;
+ GError *error = NULL;
+
+ g_return_val_if_fail (dirname != NULL, NULL);
+
+ if (!g_module_supported ())
+ return NULL;
+
+ dir = g_dir_open (dirname, 0, &error);
+ if (dir == NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ while ((basename = g_dir_read_name (dir)) != NULL) {
+ EModule *module;
+ gchar *filename;
+
+ if (!g_str_has_suffix (basename, "." G_MODULE_SUFFIX))
+ continue;
+
+ filename = g_build_filename (dirname, basename, NULL);
+
+ module = e_module_new (filename);
+
+ if (!g_type_module_use (G_TYPE_MODULE (module))) {
+ g_printerr ("Failed to load module: %s\n", filename);
+ g_object_unref (module);
+ g_free (filename);
+ continue;
+ }
+
+ g_free (filename);
+
+ loaded_modules = g_list_prepend (loaded_modules, module);
+ }
+
+ g_dir_close (dir);
+
+ return loaded_modules;
+}
diff --git a/e-util/e-module.h b/e-util/e-module.h
new file mode 100644
index 0000000000..a8120563d3
--- /dev/null
+++ b/e-util/e-module.h
@@ -0,0 +1,81 @@
+/*
+ * e-module.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-module
+ * @short_description: generic module loader
+ * @include: e-util/e-module.h
+ **/
+
+#ifndef E_MODULE_H
+#define E_MODULE_H
+
+#include <gmodule.h>
+#include <glib-object.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MODULE \
+ (e_module_get_type ())
+#define E_MODULE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MODULE, EModule))
+#define E_MODULE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MODULE, EModuleClass))
+#define E_IS_MODULE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MODULE))
+#define E_IS_MODULE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MODULE))
+#define E_MODULE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MODULE, EModuleClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EModule EModule;
+typedef struct _EModuleClass EModuleClass;
+typedef struct _EModulePrivate EModulePrivate;
+
+/**
+ * EModule:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EModule {
+ GTypeModule parent;
+ EModulePrivate *priv;
+};
+
+struct _EModuleClass {
+ GTypeModuleClass parent_class;
+};
+
+GType e_module_get_type (void);
+EModule * e_module_new (const gchar *filename);
+const gchar * e_module_get_filename (EModule *module);
+GList * e_module_load_all_in_directory (const gchar *dirname);
+
+G_END_DECLS
+
+#endif /* E_MODULE_H */
diff --git a/e-util/e-non-intrusive-error-dialog.c b/e-util/e-non-intrusive-error-dialog.c
index 7831c59f58..e36190fc9a 100644
--- a/e-util/e-non-intrusive-error-dialog.c
+++ b/e-util/e-non-intrusive-error-dialog.c
@@ -306,4 +306,3 @@ eni_show_logger(ELogger *logger, GtkWidget *top,const gchar *error_timeout_path,
gtk_widget_show_all (window);
}
-
diff --git a/e-util/e-non-intrusive-error-dialog.h b/e-util/e-non-intrusive-error-dialog.h
index 0adbd0c789..4c38808ea2 100644
--- a/e-util/e-non-intrusive-error-dialog.h
+++ b/e-util/e-non-intrusive-error-dialog.h
@@ -37,7 +37,7 @@ struct _log_data {
GdkPixbuf *pbuf;
} ldata [] = {
{ E_LOG_ERROR, N_("Error"), N_("Errors"), GTK_STOCK_DIALOG_ERROR },
- { E_LOG_WARNINGS, N_("Warning"), N_("Warnings and Errors"), GTK_STOCK_DIALOG_WARNING },
+ { E_LOG_WARNING, N_("Warning"), N_("Warnings and Errors"), GTK_STOCK_DIALOG_WARNING },
{ E_LOG_DEBUG, N_("Debug"), N_("Error, Warnings and Debug messages"), GTK_STOCK_DIALOG_INFO }
};
diff --git a/e-util/e-plugin-ui.c b/e-util/e-plugin-ui.c
index 6af3290bb6..4f948fbb2f 100644
--- a/e-util/e-plugin-ui.c
+++ b/e-util/e-plugin-ui.c
@@ -25,7 +25,6 @@
#define E_PLUGIN_UI_INIT_FUNC "e_plugin_ui_init"
#define E_PLUGIN_UI_HOOK_CLASS_ID "org.gnome.evolution.ui:1.0"
-#define E_PLUGIN_UI_MANAGER_ID_KEY "e-plugin-ui-manager-id"
struct _EPluginUIHookPrivate {
@@ -33,9 +32,11 @@ struct _EPluginUIHookPrivate {
*
* For example:
*
- * <ui-manager id="org.gnome.evolution.sample">
- * ... UI definition ...
- * </ui-manager>
+ * <hook class="org.gnome.evolution.ui:1.0">
+ * <ui-manager id="org.gnome.evolution.sample">
+ * ... UI definition ...
+ * </ui-manager>
+ * </hook>
*
* Results in:
*
@@ -49,197 +50,310 @@ struct _EPluginUIHookPrivate {
* optional.
*/
GHashTable *ui_definitions;
+
+ /* The registry is the heart of EPluginUI. It tracks GtkUIManager
+ * instances, GtkUIManager IDs, and UI merge IDs as a hash table of
+ * hash tables:
+ *
+ * GtkUIManager instance -> GtkUIManager ID -> UI Merge ID
+ *
+ * A GtkUIManager instance and ID form a unique key for looking up
+ * UI merge IDs. The reason both are needed is because the same
+ * GtkUIManager instance and be registered under multiple IDs.
+ *
+ * This is done primarily to support shell views, which share a
+ * common GtkUIManager instance for a particular shell window.
+ * Each shell view registers the same GtkUIManager instance under
+ * a unique ID:
+ *
+ * "org.gnome.evolution.mail" }
+ * "org.gnome.evolution.contacts" } aliases for a common
+ * "org.gnome.evolution.calendar" } GtkUIManager instance
+ * "org.gnome.evolution.memos" }
+ * "org.gnome.evolution.tasks" }
+ *
+ * Note: The shell window also registers the same GtkUIManager
+ * instance as "org.gnome.evolution.shell".
+ *
+ * This way, plugins that extend a shell view's UI will follow the
+ * merging and unmerging of the shell view automatically.
+ *
+ * The presence or absence of GtkUIManager IDs in the registry is
+ * significant. Presence of a (instance, ID) pair indicates that
+ * UI manager is active, absence indicates inactive. Furthermore,
+ * a non-zero merge ID for an active UI manager indicates the
+ * plugin is enabled. Zero indicates disabled.
+ *
+ * Here's a quick scenario to illustrate:
+ *
+ * Suppose we have a plugin that extends the mail shell view UI.
+ * Its EPlugin definition file has this section:
+ *
+ * <hook class="org.gnome.evolution.ui:1.0">
+ * <ui-manager id="org.gnome.evolution.mail">
+ * ... UI definition ...
+ * </ui-manager>
+ * </hook>
+ *
+ * The plugin is enabled and the active shell view is "mail".
+ * Let "ManagerA" denote the common GtkUIManager instance for
+ * this shell window. Here's what happens to the registry as
+ * the user performs various actions;
+ *
+ * - Initial State Merge ID
+ * V
+ * { "ManagerA", { "org.gnome.evolution.mail", 3 } }
+ *
+ * - User Disables the Plugin
+ *
+ * { "ManagerA", { "org.gnome.evolution.mail", 0 } }
+ *
+ * - User Enables the Plugin
+ *
+ * { "ManagerA", { "org.gnome.evolution.mail", 4 } }
+ *
+ * - User Switches to Calendar View
+ *
+ * { "ManagerA", { } }
+ *
+ * - User Disables the Plugin
+ *
+ * { "ManagerA", { } }
+ *
+ * - User Switches to Mail View
+ *
+ * { "ManagerA", { "org.gnome.evolution.mail", 0 } }
+ *
+ * - User Enables the Plugin
+ *
+ * { "ManagerA", { "org.gnome.evolution.mail", 5 } }
+ */
+ GHashTable *registry;
};
-/* The registry is a hash table of hash tables. It maps
- *
- * EPluginUIHook instance --> GtkUIManager instance --> UI merge id
- *
- * GtkUIManager instances are automatically removed when finalized.
- */
-static GHashTable *registry;
static gpointer parent_class;
static void
-plugin_ui_registry_remove (EPluginUIHook *hook,
- GtkUIManager *ui_manager)
+plugin_ui_hook_unregister_manager (EPluginUIHook *hook,
+ GtkUIManager *ui_manager)
{
- GHashTable *hash_table;
+ GHashTable *registry;
/* Note: Manager may already be finalized. */
-
- hash_table = g_hash_table_lookup (registry, hook);
- g_return_if_fail (hash_table != NULL);
-
- g_hash_table_remove (hash_table, ui_manager);
- if (g_hash_table_size (hash_table) == 0)
- g_hash_table_remove (registry, hook);
+ registry = hook->priv->registry;
+ g_hash_table_remove (registry, ui_manager);
}
static void
-plugin_ui_registry_insert (EPluginUIHook *hook,
- GtkUIManager *ui_manager,
- guint merge_id)
+plugin_ui_hook_register_manager (EPluginUIHook *hook,
+ GtkUIManager *ui_manager,
+ gpointer user_data)
{
+ EPlugin *plugin;
+ EPluginUIInitFunc func;
+ GHashTable *registry;
GHashTable *hash_table;
- hash_table = g_hash_table_lookup (registry, hook);
- if (hash_table == NULL) {
- hash_table = g_hash_table_new (g_direct_hash, g_direct_equal);
- g_hash_table_insert (registry, hook, hash_table);
- }
+ plugin = ((EPluginHook *) hook)->plugin;
+ func = e_plugin_get_symbol (plugin, E_PLUGIN_UI_INIT_FUNC);
+
+ /* Pass the manager and user_data to the plugin's e_plugin_ui_init()
+ * function (if it defined one). The plugin should install whatever
+ * GtkActions and GtkActionGroups are neccessary to implement the
+ * action names in its UI definition. */
+ if (func != NULL && !func (ui_manager, user_data))
+ return;
g_object_weak_ref (
G_OBJECT (ui_manager), (GWeakNotify)
- plugin_ui_registry_remove, hook);
+ plugin_ui_hook_unregister_manager, hook);
- g_hash_table_insert (
- hash_table, ui_manager, GUINT_TO_POINTER (merge_id));
+ registry = hook->priv->registry;
+ hash_table = g_hash_table_lookup (registry, ui_manager);
+
+ if (hash_table == NULL) {
+ hash_table = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+ g_hash_table_insert (registry, ui_manager, hash_table);
+ }
}
-/* Helper for plugin_ui_hook_merge_ui() */
-static void
-plugin_ui_hook_merge_foreach (GtkUIManager *ui_manager,
- const gchar *ui_definition,
- GHashTable *hash_table)
+static guint
+plugin_ui_hook_merge_ui (EPluginUIHook *hook,
+ GtkUIManager *ui_manager,
+ const gchar *id)
{
+ GHashTable *hash_table;
+ const gchar *ui_definition;
guint merge_id;
GError *error = NULL;
- /* Merge the UI definition into the manager. */
+ hash_table = hook->priv->ui_definitions;
+ ui_definition = g_hash_table_lookup (hash_table, id);
+ g_return_val_if_fail (ui_definition != NULL, 0);
+
merge_id = gtk_ui_manager_add_ui_from_string (
ui_manager, ui_definition, -1, &error);
- gtk_ui_manager_ensure_update (ui_manager);
+
if (error != NULL) {
g_warning ("%s", error->message);
g_error_free (error);
}
- /* Merge ID will be 0 on error, which is what we want. */
- g_hash_table_insert (
- hash_table, ui_manager, GUINT_TO_POINTER (merge_id));
+ return merge_id;
}
static void
-plugin_ui_hook_merge_ui (EPluginUIHook *hook)
+plugin_ui_enable_manager (EPluginUIHook *hook,
+ GtkUIManager *ui_manager,
+ const gchar *id)
{
- GHashTable *old_merge_ids;
- GHashTable *new_merge_ids;
- GHashTable *intermediate;
+ GHashTable *hash_table;
+ GHashTable *ui_definitions;
GList *keys;
- old_merge_ids = g_hash_table_lookup (registry, hook);
- if (old_merge_ids == NULL)
- return;
+ hash_table = hook->priv->registry;
+ hash_table = g_hash_table_lookup (hash_table, ui_manager);
- /* The GtkUIManager instances and UI definitions live in separate
- * tables, so we need to build an intermediate table that we can
- * easily iterate over. */
- keys = g_hash_table_get_keys (old_merge_ids);
- intermediate = g_hash_table_new (g_direct_hash, g_direct_equal);
+ if (hash_table == NULL)
+ return;
- while (keys != NULL) {
- GtkUIManager *ui_manager = keys->data;
- gchar *ui_definition;
+ if (id != NULL)
+ keys = g_list_prepend (NULL, (gpointer) id);
+ else
+ keys = g_hash_table_get_keys (hash_table);
- ui_definition = g_hash_table_lookup (
- hook->priv->ui_definitions,
- e_plugin_ui_get_manager_id (ui_manager));
+ ui_definitions = hook->priv->ui_definitions;
- g_hash_table_insert (intermediate, ui_manager, ui_definition);
+ while (keys != NULL) {
+ guint merge_id;
+ gpointer data;
+ id = keys->data;
keys = g_list_delete_link (keys, keys);
- }
- new_merge_ids = g_hash_table_new (g_direct_hash, g_direct_equal);
+ if (g_hash_table_lookup (ui_definitions, id) == NULL)
+ continue;
+
+ data = g_hash_table_lookup (hash_table, id);
+ merge_id = GPOINTER_TO_UINT (data);
- g_hash_table_foreach (
- intermediate, (GHFunc)
- plugin_ui_hook_merge_foreach, new_merge_ids);
+ if (merge_id > 0)
+ continue;
- g_hash_table_insert (registry, hook, new_merge_ids);
+ if (((EPluginHook *) hook)->plugin->enabled)
+ merge_id = plugin_ui_hook_merge_ui (
+ hook, ui_manager, id);
- g_hash_table_destroy (intermediate);
+ /* Merge ID will be 0 on error, which is what we want. */
+ data = GUINT_TO_POINTER (merge_id);
+ g_hash_table_insert (hash_table, g_strdup (id), data);
+ }
}
-/* Helper for plugin_ui_hook_unmerge_ui() */
static void
-plugin_ui_hook_unmerge_foreach (GtkUIManager *ui_manager,
- gpointer value,
- GHashTable *hash_table)
+plugin_ui_disable_manager (EPluginUIHook *hook,
+ GtkUIManager *ui_manager,
+ const gchar *id,
+ gboolean remove)
{
- guint merge_id;
+ GHashTable *hash_table;
+ GHashTable *ui_definitions;
+ GList *keys;
+
+ hash_table = hook->priv->registry;
+ hash_table = g_hash_table_lookup (hash_table, ui_manager);
+
+ if (hash_table == NULL)
+ return;
+
+ if (id != NULL)
+ keys = g_list_prepend (NULL, (gpointer) id);
+ else
+ keys = g_hash_table_get_keys (hash_table);
+
+ ui_definitions = hook->priv->ui_definitions;
+
+ while (keys != NULL) {
+ guint merge_id;
+ gpointer data;
- merge_id = GPOINTER_TO_UINT (value);
- gtk_ui_manager_remove_ui (ui_manager, merge_id);
+ id = keys->data;
+ keys = g_list_delete_link (keys, keys);
+
+ if (g_hash_table_lookup (ui_definitions, id) == NULL)
+ continue;
- g_hash_table_insert (hash_table, ui_manager, GUINT_TO_POINTER (0));
+ data = g_hash_table_lookup (hash_table, id);
+ merge_id = GPOINTER_TO_UINT (data);
+
+ /* Merge ID could be 0 if the plugin is disabled. */
+ if (merge_id > 0)
+ gtk_ui_manager_remove_ui (ui_manager, merge_id);
+
+ if (remove)
+ g_hash_table_remove (hash_table, id);
+ else
+ g_hash_table_insert (hash_table, g_strdup (id), NULL);
+ }
}
static void
-plugin_ui_hook_unmerge_ui (EPluginUIHook *hook)
+plugin_ui_enable_hook (EPluginUIHook *hook)
{
- GHashTable *old_merge_ids;
- GHashTable *new_merge_ids;
-
- old_merge_ids = g_hash_table_lookup (registry, hook);
- if (old_merge_ids == NULL)
- return;
+ GHashTable *hash_table;
+ GHashTableIter iter;
+ gpointer key;
- new_merge_ids = g_hash_table_new (g_direct_hash, g_direct_equal);
+ /* Enable all GtkUIManagers for this hook. */
- g_hash_table_foreach (
- old_merge_ids, (GHFunc)
- plugin_ui_hook_unmerge_foreach, new_merge_ids);
+ hash_table = hook->priv->registry;
+ g_hash_table_iter_init (&iter, hash_table);
- g_hash_table_insert (registry, hook, new_merge_ids);
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ GtkUIManager *ui_manager = key;
+ plugin_ui_enable_manager (hook, ui_manager, NULL);
+ }
}
static void
-plugin_ui_hook_register_manager (EPluginUIHook *hook,
- GtkUIManager *ui_manager,
- const gchar *ui_definition,
- gpointer user_data)
+plugin_ui_disable_hook (EPluginUIHook *hook)
{
- EPlugin *plugin;
- EPluginUIInitFunc func;
- guint merge_id = 0;
+ GHashTable *hash_table;
+ GHashTableIter iter;
+ gpointer key;
- plugin = ((EPluginHook *) hook)->plugin;
- func = e_plugin_get_symbol (plugin, E_PLUGIN_UI_INIT_FUNC);
+ /* Disable all GtkUIManagers for this hook. */
- /* Pass the manager and user_data to the plugin's e_plugin_ui_init()
- * function (if it defined one). The plugin should install whatever
- * GtkActions and GtkActionGroups are neccessary to implement the
- * action names in its UI definition. */
- if (func != NULL && !func (ui_manager, user_data))
- return;
+ hash_table = hook->priv->registry;
+ g_hash_table_iter_init (&iter, hash_table);
- if (plugin->enabled) {
- GError *error = NULL;
-
- /* Merge the UI definition into the manager. */
- merge_id = gtk_ui_manager_add_ui_from_string (
- ui_manager, ui_definition, -1, &error);
- gtk_ui_manager_ensure_update (ui_manager);
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ GtkUIManager *ui_manager = key;
+ plugin_ui_disable_manager (hook, ui_manager, NULL, FALSE);
}
-
- /* Save merge ID's for later use. */
- plugin_ui_registry_insert (hook, ui_manager, merge_id);
}
static void
plugin_ui_hook_finalize (GObject *object)
{
EPluginUIHookPrivate *priv;
+ GHashTableIter iter;
+ gpointer ui_manager;
priv = E_PLUGIN_UI_HOOK_GET_PRIVATE (object);
+ /* Remove weak reference callbacks to GtkUIManagers. */
+ g_hash_table_iter_init (&iter, priv->registry);
+ while (g_hash_table_iter_next (&iter, &ui_manager, NULL))
+ g_object_weak_unref (
+ G_OBJECT (ui_manager), (GWeakNotify)
+ plugin_ui_hook_unregister_manager, object);
+
g_hash_table_destroy (priv->ui_definitions);
+ g_hash_table_destroy (priv->registry);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -306,9 +420,9 @@ plugin_ui_hook_enable (EPluginHook *hook,
gint state)
{
if (state)
- plugin_ui_hook_merge_ui (E_PLUGIN_UI_HOOK (hook));
+ plugin_ui_enable_hook (E_PLUGIN_UI_HOOK (hook));
else
- plugin_ui_hook_unmerge_ui (E_PLUGIN_UI_HOOK (hook));
+ plugin_ui_disable_hook (E_PLUGIN_UI_HOOK (hook));
}
static void
@@ -327,25 +441,24 @@ plugin_ui_hook_class_init (EPluginUIHookClass *class)
plugin_hook_class->id = E_PLUGIN_UI_HOOK_CLASS_ID;
plugin_hook_class->construct = plugin_ui_hook_construct;
plugin_hook_class->enable = plugin_ui_hook_enable;
-
- registry = g_hash_table_new_full (
- g_direct_hash, g_direct_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) g_hash_table_destroy);
}
static void
plugin_ui_hook_init (EPluginUIHook *hook)
{
GHashTable *ui_definitions;
+ GHashTable *registry;
ui_definitions = g_hash_table_new_full (
g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) g_free);
+ registry = g_hash_table_new (g_direct_hash, g_direct_equal);
+
hook->priv = E_PLUGIN_UI_HOOK_GET_PRIVATE (hook);
hook->priv->ui_definitions = ui_definitions;
+ hook->priv->registry = registry;
}
GType
@@ -375,17 +488,14 @@ e_plugin_ui_hook_get_type (void)
}
void
-e_plugin_ui_register_manager (const gchar *id,
- GtkUIManager *ui_manager,
+e_plugin_ui_register_manager (GtkUIManager *ui_manager,
+ const gchar *id,
gpointer user_data)
{
- const gchar *key = E_PLUGIN_UI_MANAGER_ID_KEY;
GSList *plugin_list;
- g_return_if_fail (id != NULL);
g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
-
- g_object_set_data (G_OBJECT (ui_manager), key, (gpointer) id);
+ g_return_if_fail (id != NULL);
/* Loop over all installed plugins. */
plugin_list = e_plugin_list_plugins ();
@@ -393,36 +503,84 @@ e_plugin_ui_register_manager (const gchar *id,
EPlugin *plugin = plugin_list->data;
GSList *iter;
+ plugin_list = g_slist_next (plugin_list);
+
/* Look for hooks of type EPluginUIHook. */
for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
EPluginUIHook *hook = iter->data;
- const gchar *ui_definition;
+ GHashTable *hash_table;
if (!E_IS_PLUGIN_UI_HOOK (hook))
continue;
+ hash_table = hook->priv->ui_definitions;
+
/* Check if the hook has a UI definition
* for the GtkUIManager being registered. */
- ui_definition = g_hash_table_lookup (
- hook->priv->ui_definitions, id);
- if (ui_definition == NULL)
+ if (g_hash_table_lookup (hash_table, id) == NULL)
continue;
/* Register the manager with the hook. */
plugin_ui_hook_register_manager (
- hook, ui_manager, ui_definition, user_data);
+ hook, ui_manager, user_data);
}
+ }
+}
+
+void
+e_plugin_ui_enable_manager (GtkUIManager *ui_manager,
+ const gchar *id)
+{
+ GSList *plugin_list;
+
+ g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
+ g_return_if_fail (id != NULL);
+
+ /* Loop over all installed plugins. */
+ plugin_list = e_plugin_list_plugins ();
+ while (plugin_list != NULL) {
+ EPlugin *plugin = plugin_list->data;
+ GSList *iter;
plugin_list = g_slist_next (plugin_list);
+
+ /* Look for hooks of type EPluginUIHook. */
+ for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
+ EPluginUIHook *hook = iter->data;
+
+ if (!E_IS_PLUGIN_UI_HOOK (hook))
+ continue;
+
+ plugin_ui_enable_manager (hook, ui_manager, id);
+ }
}
}
-const gchar *
-e_plugin_ui_get_manager_id (GtkUIManager *ui_manager)
+void
+e_plugin_ui_disable_manager (GtkUIManager *ui_manager,
+ const gchar *id)
{
- const gchar *key = E_PLUGIN_UI_MANAGER_ID_KEY;
+ GSList *plugin_list;
+
+ g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
+ g_return_if_fail (id != NULL);
+
+ /* Loop over all installed plugins. */
+ plugin_list = e_plugin_list_plugins ();
+ while (plugin_list != NULL) {
+ EPlugin *plugin = plugin_list->data;
+ GSList *iter;
- g_return_val_if_fail (GTK_IS_UI_MANAGER (ui_manager), NULL);
+ plugin_list = g_slist_next (plugin_list);
+
+ /* Look for hooks of type EPluginUIHook. */
+ for (iter = plugin->hooks; iter != NULL; iter = iter->next) {
+ EPluginUIHook *hook = iter->data;
- return g_object_get_data (G_OBJECT (ui_manager), key);
+ if (!E_IS_PLUGIN_UI_HOOK (hook))
+ continue;
+
+ plugin_ui_disable_manager (hook, ui_manager, id, TRUE);
+ }
+ }
}
diff --git a/e-util/e-plugin-ui.h b/e-util/e-plugin-ui.h
index cdefda5617..c9bddafb64 100644
--- a/e-util/e-plugin-ui.h
+++ b/e-util/e-plugin-ui.h
@@ -62,10 +62,13 @@ typedef gboolean (*EPluginUIInitFunc) (GtkUIManager *ui_manager,
GType e_plugin_ui_hook_get_type (void);
-void e_plugin_ui_register_manager (const gchar *id,
- GtkUIManager *ui_manager,
+void e_plugin_ui_register_manager (GtkUIManager *ui_manager,
+ const gchar *id,
gpointer user_data);
-const gchar * e_plugin_ui_get_manager_id (GtkUIManager *ui_manager);
+void e_plugin_ui_enable_manager (GtkUIManager *ui_manager,
+ const gchar *id);
+void e_plugin_ui_disable_manager (GtkUIManager *ui_manager,
+ const gchar *id);
G_END_DECLS
diff --git a/e-util/e-plugin.c b/e-util/e-plugin.c
index 3b3d5d215d..5c5e55b147 100644
--- a/e-util/e-plugin.c
+++ b/e-util/e-plugin.c
@@ -72,12 +72,6 @@ static GHashTable *ep_types;
static GSList *ep_path;
/* global table of plugins by plugin.id */
static GHashTable *ep_plugins;
-/* a table of GSLists of plugins by hook class for hooks not loadable yet */
-static GHashTable *ep_plugins_pending_hooks;
-/* list of all cached xml docs:struct _plugin_doc's */
-static EDList ep_plugin_docs = E_DLIST_INITIALISER(ep_plugin_docs);
-/* gconf client */
-static GConfClient *ep_gconf;
/* the list of disabled plugins from gconf */
static GSList *ep_disabled;
@@ -110,6 +104,8 @@ ep_check_enabled (const gchar *id)
static void
ep_set_enabled (const gchar *id, gint state)
{
+ GConfClient *client;
+
/* Bail out if no change to state, when expressed as a boolean: */
if ((state == 0) == (ep_check_enabled(id) == 0))
return;
@@ -126,9 +122,11 @@ ep_set_enabled (const gchar *id, gint state)
} else
ep_disabled = g_slist_prepend (ep_disabled, g_strdup (id));
- gconf_client_set_list(
- ep_gconf, "/apps/evolution/eplugin/disabled",
+ client = gconf_client_get_default ();
+ gconf_client_set_list (
+ client, "/apps/evolution/eplugin/disabled",
GCONF_VALUE_STRING, ep_disabled, NULL);
+ g_object_unref (client);
}
static gint
@@ -182,21 +180,6 @@ ep_construct (EPlugin *ep, xmlNodePtr root)
} else {
ep->hooks = g_slist_append(ep->hooks, hook);
}
- } else {
- gpointer l, oldclass;
-
- if (ep_plugins_pending_hooks == NULL)
- ep_plugins_pending_hooks = g_hash_table_new(g_str_hash, g_str_equal);
- if (!g_hash_table_lookup_extended (ep_plugins_pending_hooks, class, &oldclass, &l)) {
- oldclass = class;
- l = NULL;
- }
- else {
- g_free(class);
- }
- l = g_slist_prepend (l, ep);
- g_hash_table_insert (ep_plugins_pending_hooks, oldclass, l);
- ep->hooks_pending = g_slist_prepend (ep->hooks_pending, node);
}
} else if (strcmp((gchar *)node->name, "description") == 0) {
ep->description = e_plugin_xml_content_domain(node, ep->domain);
@@ -276,7 +259,6 @@ ep_finalize (GObject *object)
g_free (ep->description);
g_free (ep->name);
g_free (ep->domain);
- g_slist_free (ep->hooks_pending);
g_slist_foreach (ep->hooks, (GFunc) g_object_unref, NULL);
g_slist_free (ep->hooks);
@@ -425,9 +407,7 @@ ep_load(const gchar *filename, gint load_level)
{
xmlDocPtr doc;
xmlNodePtr root;
- gint res = -1;
EPlugin *ep = NULL;
- gint cache = FALSE;
struct _plugin_doc *pdoc;
doc = e_xml_parse_file (filename);
@@ -478,80 +458,12 @@ ep_load(const gchar *filename, gint load_level)
g_free (is_system_plugin);
pdoc->plugin_hooks = g_slist_prepend(pdoc->plugin_hooks, ep);
- cache |= (ep->hooks_pending != NULL);
ep = NULL;
}
- cache |= pdoc->plugins != NULL;
- }
- }
-
- res = 0;
-
- if (cache) {
- pd(printf("Caching plugin description '%s' for unknown future hooks\n", filename));
- e_dlist_addtail(&ep_plugin_docs, (EDListNode *)pdoc);
- } else {
- pd(printf("freeing plugin description '%s', nothing uses it\n", filename));
- xmlFreeDoc(pdoc->doc);
- g_free(pdoc->filename);
- g_free(pdoc);
- }
-
- return res;
-}
-
-/* This loads a hook that was pending on a given plugin but the type wasn't registered yet */
-/* This works in conjunction with ep_construct and e_plugin_hook_register_type to make sure
- everything works nicely together. Apparently. */
-static gint
-ep_load_pending(EPlugin *ep, EPluginHookClass *type)
-{
- gint res = 0;
- GSList *l, *p;
-
- phd(printf("New hook type registered '%s', loading pending hooks on plugin '%s'\n", type->id, ep->id));
-
- l = ep->hooks_pending;
- p = NULL;
- while (l) {
- GSList *n = l->next;
- xmlNodePtr node = l->data;
- gchar *class = (gchar *)xmlGetProp(node, (const guchar *)"class");
- EPluginHook *hook;
-
- phd(printf(" checking pending hook '%s'\n", class?class:"<unknown>"));
-
- if (class) {
- if (strcmp(class, type->id) == 0) {
- hook = g_object_new(G_OBJECT_CLASS_TYPE(type), NULL);
-
- /* Don't bother loading hooks for plugins that are not anyway enabled */
- if (ep->enabled) {
- res = type->construct(hook, ep, node);
- if (res == -1) {
- g_warning("Plugin '%s' failed to load hook '%s'", ep->name, type->id);
- g_object_unref(hook);
- } else {
- ep->hooks = g_slist_append(ep->hooks, hook);
- }
- }
-
- if (p)
- p->next = n;
- else
- ep->hooks_pending = n;
- g_slist_free_1(l);
- l = p;
- }
-
- xmlFree(class);
}
-
- p = l;
- l = n;
}
- return res;
+ return 0;
}
/**
@@ -574,6 +486,69 @@ e_plugin_add_load_path(const gchar *path)
ep_path = g_slist_append(ep_path, g_strdup(path));
}
+static void
+plugin_load_subclasses (void)
+{
+ GType *children;
+ guint n_children, ii;
+
+ ep_types = g_hash_table_new (g_str_hash, g_str_equal);
+ eph_types = g_hash_table_new (g_str_hash, g_str_equal);
+ ep_plugins = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* Load EPlugin subclasses. */
+
+ children = g_type_children (E_TYPE_PLUGIN, &n_children);
+
+ for (ii = 0; ii < n_children; ii++) {
+ EPluginClass *class;
+
+ class = g_type_class_ref (children[ii]);
+ g_hash_table_insert (ep_types, (gpointer) class->type, class);
+ }
+
+ g_free (children);
+
+ /* Load EPluginHook subclasses. */
+
+ children = g_type_children (E_TYPE_PLUGIN_HOOK, &n_children);
+
+ for (ii = 0; ii < n_children; ii++) {
+ EPluginHookClass *hook_class;
+ EPluginHookClass *dupe_class;
+
+ hook_class = g_type_class_ref (children[ii]);
+
+ /* Sanity check the hook class. */
+ if (hook_class->id == NULL || *hook_class->id == '\0') {
+ g_warning (
+ "%s has no hook ID, so skipping",
+ G_OBJECT_CLASS_NAME (hook_class));
+ g_type_class_unref (hook_class);
+ continue;
+ }
+
+ /* Check for class ID collisions. */
+ dupe_class = g_hash_table_lookup (eph_types, hook_class->id);
+ if (dupe_class != NULL) {
+ g_warning (
+ "%s and %s have the same hook "
+ "ID ('%s'), so skipping %s",
+ G_OBJECT_CLASS_NAME (dupe_class),
+ G_OBJECT_CLASS_NAME (hook_class),
+ hook_class->id,
+ G_OBJECT_CLASS_NAME (hook_class));
+ g_type_class_unref (hook_class);
+ continue;
+ }
+
+ g_hash_table_insert (
+ eph_types, (gpointer) hook_class->id, hook_class);
+ }
+
+ g_free (children);
+}
+
/**
* e_plugin_load_plugins:
*
@@ -585,13 +560,23 @@ e_plugin_add_load_path(const gchar *path)
gint
e_plugin_load_plugins(void)
{
+ GConfClient *client;
GSList *l;
gint i;
- if (ep_types == NULL) {
- g_warning("no plugin types defined");
+ if (eph_types != NULL)
return 0;
- }
+
+ /* We require that all GTypes for EPlugin and EPluginHook
+ * subclasses be registered prior to loading any plugins.
+ * It greatly simplifies the loading process. */
+ plugin_load_subclasses ();
+
+ client = gconf_client_get_default ();
+ ep_disabled = gconf_client_get_list (
+ client, "/apps/evolution/eplugin/disabled",
+ GCONF_VALUE_STRING, NULL);
+ g_object_unref (client);
for (i=0; i < 3; i++) {
for (l = ep_path;l;l = g_slist_next(l)) {
@@ -623,70 +608,6 @@ e_plugin_load_plugins(void)
return 0;
}
-/**
- * e_plugin_register_type:
- * @type: The GObject type of the plugin loader.
- *
- * Register a new plugin type with the plugin system. Each type must
- * subclass EPlugin and must override the type member of the
- * EPluginClass with a unique name.
- **/
-void
-e_plugin_register_type(GType type)
-{
- EPluginClass *class;
- struct _plugin_doc *pdoc, *ndoc;
-
- if (ep_types == NULL) {
- ep_types = g_hash_table_new(g_str_hash, g_str_equal);
- ep_plugins = g_hash_table_new(g_str_hash, g_str_equal);
- /* TODO: notify listening */
- ep_gconf = gconf_client_get_default();
- ep_disabled = gconf_client_get_list(ep_gconf, "/apps/evolution/eplugin/disabled", GCONF_VALUE_STRING, NULL);
- }
-
- class = g_type_class_ref(type);
-
- pd(printf("register plugin type '%s'\n", class->type));
-
- g_hash_table_insert(ep_types, (gpointer)class->type, class);
-
- /* check for pending plugins */
- pdoc = (struct _plugin_doc *)ep_plugin_docs.head;
- ndoc = pdoc->next;
- while (ndoc) {
- if (pdoc->plugins) {
- GSList *l, *add = NULL;
-
- for (l=pdoc->plugins;l;l=g_slist_next(l)) {
- xmlNodePtr root = l->data;
- gchar *prop_type;
-
- prop_type = (gchar *)xmlGetProp(root, (const guchar *)"type");
- if (!strcmp(prop_type, class->type))
- add = g_slist_append(add, l->data);
- xmlFree(prop_type);
- }
-
- for (l=add;l;l=g_slist_next(l)) {
- xmlNodePtr root = l->data;
- EPlugin *ep;
-
- pdoc->plugins = g_slist_remove(pdoc->plugins, root);
- ep = ep_load_plugin(root, pdoc);
- if (ep)
- pdoc->plugin_hooks = g_slist_prepend(pdoc->plugin_hooks, ep);
- /* TODO: garbage collect plugin doc? */
- }
-
- g_slist_free(add);
- }
-
- pdoc = ndoc;
- ndoc = ndoc->next;
- }
-}
-
static void
ep_list_plugin(gpointer key, gpointer val, gpointer dat)
{
@@ -973,265 +894,6 @@ e_plugin_xml_content_domain(xmlNodePtr node, const gchar *domain)
/* ********************************************************************** */
-static gpointer epl_parent_class;
-
-/* TODO:
- We need some way to manage lifecycle.
- We need some way to manage state.
-
- Maybe just the g module init method will do, or we could add
- another which returns context.
-
- There is also the question of per-instance context, e.g. for config
- pages.
-*/
-
-static GList *missing_symbols = NULL;
-
-static gint
-epl_loadmodule(EPlugin *ep, gboolean fatal)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- EPluginLibEnableFunc enable;
-
- if (epl->module != NULL)
- return 0;
-
- if ((epl->module = g_module_open(epl->location, 0)) == NULL) {
- if (fatal)
- g_warning("can't load plugin '%s': %s", epl->location, g_module_error());
- else
- missing_symbols = g_list_prepend (missing_symbols, g_object_ref (ep));
- return -1;
- }
-
- if (g_module_symbol(epl->module, "e_plugin_lib_enable", (gpointer)&enable)) {
- if (enable(epl, TRUE) != 0) {
- ep->enabled = FALSE;
- g_module_close(epl->module);
- epl->module = NULL;
- return -1;
- }
- }
-
- return 0;
-}
-
-void
-e_plugin_load_plugins_with_missing_symbols (void)
-{
- GList *list = missing_symbols;
-
- while (list) {
- EPlugin *ep = list->data;
- epl_loadmodule (ep, TRUE);
- g_object_unref (ep);
- list = g_list_next (list);
- }
-
- g_list_free (missing_symbols);
- missing_symbols = NULL;
-}
-
-static gpointer
-epl_invoke(EPlugin *ep, const gchar *name, gpointer data)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- EPluginLibFunc cb;
-
- if (!ep->enabled) {
- g_warning("trying to invoke '%s' on disabled plugin '%s'", name, ep->id);
- return NULL;
- }
-
- if (epl_loadmodule(ep, FALSE) != 0)
- return NULL;
-
- if (!g_module_symbol(epl->module, name, (gpointer)&cb)) {
- g_warning("Cannot resolve symbol '%s' in plugin '%s' (not exported?)", name, epl->location);
- return NULL;
- }
-
- return cb(epl, data);
-}
-
-static gpointer
-epl_get_symbol(EPlugin *ep, const gchar *name)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- gpointer symbol;
-
- if (epl_loadmodule (ep, FALSE) != 0)
- return NULL;
-
- if (!g_module_symbol (epl->module, name, &symbol))
- return NULL;
-
- return symbol;
-}
-
-static gint
-epl_construct(EPlugin *ep, xmlNodePtr root)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
-
- if (E_PLUGIN_CLASS (epl_parent_class)->construct (ep, root) == -1)
- return -1;
-
- epl->location = e_plugin_xml_prop(root, "location");
-
- if (epl->location == NULL) {
- g_warning("Library plugin '%s' has no location", ep->id);
- return -1;
- }
-#ifdef G_OS_WIN32
- {
- gchar *mapped_location =
- e_util_replace_prefix (EVOLUTION_PREFIX,
- e_util_get_prefix (),
- epl->location);
- g_free (epl->location);
- epl->location = mapped_location;
- }
-#endif
- /* If we're enabled, check for the load-on-startup property */
- if (ep->enabled) {
- xmlChar *tmp;
-
- tmp = xmlGetProp(root, (const guchar *)"load-on-startup");
- if (tmp) {
- if (strcmp ((const gchar *)tmp, "after-ui") == 0) {
- missing_symbols = g_list_prepend (missing_symbols, g_object_ref (ep));
- } else {
- if (epl_loadmodule(ep, FALSE) != 0) {
- xmlFree(tmp);
- return -1;
- }
- }
- xmlFree(tmp);
- }
- }
-
- return 0;
-}
-
-static GtkWidget *
-epl_get_configure_widget (EPlugin *ep)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- EPluginLibGetConfigureWidgetFunc get_configure_widget;
-
- pd (printf ("\n epl_get_configure_widget \n"));
-
- if (epl_loadmodule (ep, FALSE) != 0) {
- pd (printf ("\n epl_loadmodule \n"));
- return NULL;
- }
-
- if (g_module_symbol (epl->module, "e_plugin_lib_get_configure_widget", (gpointer)&get_configure_widget)) {
- pd (printf ("\n g_module_symbol is loaded\n"));
- return (GtkWidget*) get_configure_widget (epl);
- }
- return NULL;
-}
-
-static void
-epl_enable(EPlugin *ep, gint state)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- EPluginLibEnableFunc enable;
-
- E_PLUGIN_CLASS (epl_parent_class)->enable (ep, state);
-
- /* if we're disabling and it isn't loaded, nothing to do */
- if (!state && epl->module == NULL)
- return;
-
- /* this will noop if we're disabling since we tested it above */
- if (epl_loadmodule(ep, FALSE) != 0)
- return;
-
- if (g_module_symbol(epl->module, "e_plugin_lib_enable", (gpointer)&enable)) {
- if (enable(epl, state) != 0)
- return;
- }
-#if 0
- if (!state) {
- g_module_close(epl->module);
- epl->module = NULL;
- }
-#endif
-}
-
-static void
-epl_finalize (GObject *object)
-{
- EPluginLib *epl = E_PLUGIN_LIB (object);
-
- g_free (epl->location);
-
- if (epl->module)
- g_module_close (epl->module);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (epl_parent_class)->finalize (object);
-}
-
-static void
-epl_class_init (EPluginClass *class)
-{
- GObjectClass *object_class;
-
- epl_parent_class = g_type_class_peek_parent (class);
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = epl_finalize;
-
- class->construct = epl_construct;
- class->invoke = epl_invoke;
- class->get_symbol = epl_get_symbol;
- class->enable = epl_enable;
- class->get_configure_widget = epl_get_configure_widget;
- class->type = "shlib";
-}
-
-/**
- * e_plugin_lib_get_type:
- *
- * Standard GObject function to retrieve the EPluginLib type. Use to
- * register the type with the plugin system if you want to use shared
- * library plugins.
- *
- * Return value: The EPluginLib type.
- **/
-GType
-e_plugin_lib_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EPluginLibClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) epl_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EPluginLib),
- 0, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- e_plugin_get_type (), "EPluginLib", &type_info, 0);
- }
-
- return type;
-}
-
-/* ********************************************************************** */
-
static gpointer eph_parent_class;
static gint
@@ -1315,83 +977,6 @@ e_plugin_hook_enable (EPluginHook *eph, gint state)
}
/**
- * e_plugin_hook_register_type:
- * @type:
- *
- * Register a new plugin hook type with the plugin system. Each type
- * must subclass EPluginHook and must override the id member of the
- * EPluginHookClass with a unique identification string.
- **/
-void
-e_plugin_hook_register_type(GType type)
-{
- EPluginHookClass *klass, *oldklass;
- GSList *l;
-
- gpointer plugins; /* GSList */
- gpointer class;
-
- if (eph_types == NULL)
- eph_types = g_hash_table_new(g_str_hash, g_str_equal);
-
- klass = g_type_class_ref(type);
-
- oldklass = g_hash_table_lookup(eph_types, (gpointer)klass->id);
- if (oldklass == klass) {
- g_type_class_unref(klass);
- return;
- } else if (oldklass != NULL) {
- g_warning("Trying to re-register hook type '%s'", klass->id);
- return;
- }
-
- phd(printf("register plugin hook type '%s'\n", klass->id));
- g_hash_table_insert(eph_types, (gpointer)klass->id, klass);
-
- /* if we've already loaded a plugin that needed this hook but it didn't exist, re-load it now */
-
- if (ep_plugins_pending_hooks
- && g_hash_table_lookup_extended (ep_plugins_pending_hooks, klass->id, &class, &plugins)) {
- struct _plugin_doc *pdoc, *ndoc;
-
- g_hash_table_remove (ep_plugins_pending_hooks, class);
- g_free (class);
- for (l = plugins; l; l = g_slist_next(l)) {
- EPlugin *ep = l->data;
-
- ep_load_pending (ep, klass);
- }
- g_slist_free (plugins);
-
- /* See if we can now garbage collect the xml definition since its been fully loaded */
-
- /* This is all because libxml doesn't refcount! */
-
- pdoc = (struct _plugin_doc *)ep_plugin_docs.head;
- ndoc = pdoc->next;
- while (ndoc) {
- if (pdoc->doc) {
- gint cache = pdoc->plugins != NULL;
-
- for (l=pdoc->plugin_hooks;!cache && l;l=g_slist_next(l))
- cache |= (((EPlugin *)l->data)->hooks_pending != NULL);
-
- if (!cache) {
- pd(printf("Gargabe collecting plugin description '%s'\n", pdoc->filename));
- e_dlist_remove((EDListNode *)pdoc);
- xmlFreeDoc(pdoc->doc);
- g_free(pdoc->filename);
- g_free(pdoc);
- }
- }
-
- pdoc = ndoc;
- ndoc = ndoc->next;
- }
- }
-}
-
-/**
* e_plugin_hook_mask:
* @root: An XML node.
* @map: A zero-fill terminated array of EPluginHookTargeKeys used to
@@ -1478,118 +1063,3 @@ e_plugin_hook_id(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const
return ~0;
}
-
-/* ********************************************************************** */
-/* Plugin plugin */
-
-static gpointer epth_parent_class;
-
-static gint
-epth_load_plugin(gpointer d)
-{
- EPluginHook *eph = d;
- EPluginTypeHook *epth = d;
- GType type;
-
- epth->idle = 0;
-
- type = GPOINTER_TO_UINT(e_plugin_invoke(eph->plugin, epth->get_type, eph->plugin));
- if (type != 0)
- e_plugin_register_type(type);
-
- return FALSE;
-}
-
-static gint
-epth_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root)
-{
- EPluginTypeHook *epth = E_PLUGIN_TYPE_HOOK (eph);
- xmlNodePtr node;
-
- phd(printf("loading plugin hook\n"));
-
- if (((EPluginHookClass *)epth_parent_class)->construct(eph, ep, root) == -1)
- return -1;
-
- node = root->children;
- while (node) {
- if (strcmp((gchar *)node->name, "plugin-type") == 0) {
- epth->get_type = e_plugin_xml_prop(node, "get-type");
- /* We need to run this in an idle handler,
- * since at this point the parent EPlugin wont
- * be fully initialised ... darn */
- if (epth->get_type)
- epth->idle = g_idle_add(epth_load_plugin, epth);
- else
- g_warning("Plugin type plugin missing get-type callback");
- }
- node = node->next;
- }
-
- eph->plugin = ep;
-
- return 0;
-}
-
-static void
-epth_finalize (GObject *object)
-{
- EPluginTypeHook *epth = E_PLUGIN_TYPE_HOOK (object);
-
- if (epth->idle != 0)
- g_source_remove (epth->idle);
-
- g_free (epth->get_type);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (epth_parent_class)->finalize (object);
-}
-
-static void
-epth_class_init (EPluginTypeHookClass *class)
-{
- GObjectClass *object_class;
- EPluginHookClass *hook_class;
-
- epth_parent_class = g_type_class_peek_parent (class);
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = epth_finalize;
-
- hook_class = E_PLUGIN_HOOK_CLASS (class);
- hook_class->construct = epth_construct;
- hook_class->id = "org.gnome.evolution.plugin.type:1.0";
-}
-
-/**
- * e_plugin_type_hook_get_type:
- *
- * Get the type for the plugin plugin hook.
- *
- * Return value: The type of the plugin type hook.
- **/
-GType
-e_plugin_type_hook_get_type(void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EPluginTypeHookClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) epth_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EPluginTypeHook),
- 0, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- E_TYPE_PLUGIN_HOOK, "EPluginTypeHook", &type_info, 0);
- }
-
- return type;
-}
diff --git a/e-util/e-plugin.h b/e-util/e-plugin.h
index 18949bf893..8e24436605 100644
--- a/e-util/e-plugin.h
+++ b/e-util/e-plugin.h
@@ -64,8 +64,6 @@ struct _EPluginAuthor {
* @object: Superclass.
* @id: Unique identifier for plugin instance.
* @path: Filename where the xml definition resides.
- * @hooks_pending: A list hooks which can't yet be loaded. This is
- * the xmlNodePtr to the root node of the hook definition.
* @description: A description of the plugin's purpose.
* @name: The name of the plugin.
* @domain: The translation domain for this plugin.
@@ -82,7 +80,6 @@ struct _EPlugin {
gchar *id;
gchar *path;
- GSList *hooks_pending;
gchar *description;
gchar *name;
@@ -134,11 +131,8 @@ GType e_plugin_get_type(void);
gint e_plugin_construct(EPlugin *ep, xmlNodePtr root);
void e_plugin_add_load_path(const gchar *);
gint e_plugin_load_plugins(void);
-void e_plugin_load_plugins_with_missing_symbols(void);
GSList * e_plugin_list_plugins(void);
-void e_plugin_register_type(GType type);
-
gpointer e_plugin_get_symbol(EPlugin *ep, const gchar *name);
gpointer e_plugin_invoke(EPlugin *ep, const gchar *name, gpointer data);
void e_plugin_enable(EPlugin *eph, gint state);
@@ -154,73 +148,6 @@ gchar *e_plugin_xml_content(xmlNodePtr node);
gchar *e_plugin_xml_content_domain(xmlNodePtr node, const gchar *domain);
/* ********************************************************************** */
-#include <gmodule.h>
-
-/* Standard GObject macros */
-#define E_TYPE_PLUGIN_LIB \
- (e_plugin_lib_get_type ())
-#define E_PLUGIN_LIB(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_PLUGIN_LIB, EPluginLib))
-#define E_PLUGIN_LIB_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_PLUGIN_LIB, EPluginLibClass))
-#define E_IS_PLUGIN_LIB(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_PLUGIN_LIB))
-#define E_IS_PLUGIN_LIB_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_PLUGIN_LIB))
-#define E_PLUGIN_LIB_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_PLUGIN_LIB, EPluginLibClass))
-
-typedef struct _EPluginLib EPluginLib;
-typedef struct _EPluginLibClass EPluginLibClass;
-
-/* The callback signature used for epluginlib methods */
-typedef gpointer (*EPluginLibFunc)(EPluginLib *ep, gpointer data);
-/* The setup method, this will be called when the plugin is
- * initialised. In the future it may also be called when the plugin
- * is disabled. */
-typedef gint (*EPluginLibEnableFunc)(EPluginLib *ep, gint enable);
-typedef gpointer (*EPluginLibGetConfigureWidgetFunc)(EPluginLib *ep);
-
-/**
- * struct _EPluginLib -
- *
- * @plugin: Superclass.
- * @location: The filename of the shared object.
- * @module: The GModule once it is loaded.
- *
- * This is a concrete EPlugin class. It loads and invokes dynamically
- * loaded libraries using GModule. The shared object isn't loaded
- * until the first callback is invoked.
- *
- * When the plugin is loaded, and if it exists, "e_plugin_lib_enable"
- * will be invoked to initialise the
- **/
-struct _EPluginLib {
- EPlugin plugin;
-
- gchar *location;
- GModule *module;
-};
-
-/**
- * struct _EPluginLibClass -
- *
- * @plugin_class: Superclass.
- *
- * The plugin library needs no additional class data.
- **/
-struct _EPluginLibClass {
- EPluginClass plugin_class;
-};
-
-GType e_plugin_lib_get_type(void);
-
-/* ********************************************************************** */
/* Standard GObject macros */
#define E_TYPE_PLUGIN_HOOK \
@@ -323,8 +250,6 @@ struct _EPluginHookClass {
GType e_plugin_hook_get_type(void);
-void e_plugin_hook_register_type(GType type);
-
EPluginHook * e_plugin_hook_new(EPlugin *ep, xmlNodePtr root);
void e_plugin_hook_enable(EPluginHook *eph, gint state);
@@ -332,49 +257,6 @@ void e_plugin_hook_enable(EPluginHook *eph, gint state);
guint32 e_plugin_hook_mask(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const gchar *prop);
guint32 e_plugin_hook_id(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const gchar *prop);
-/* ********************************************************************** */
-
-/* EPluginTypeHook lets a plugin register a new plugin type.
- <hook class="org.gnome.evolution.plugin.type:1.0">
- <plugin-type get-type="e_plugin_mono_get_type/>
- </hook>
-*/
-
-/* Standard GObject macros */
-#define E_TYPE_PLUGIN_TYPE_HOOK \
- (e_plugin_type_hook_get_type ())
-#define E_PLUGIN_TYPE_HOOK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_PLUGIN_TYPE_HOOK, EPluginTypeHook))
-#define E_PLUGIN_TYPE_HOOK_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_PLUGIN_TYPE_HOOK, EPluginTypeHookClass))
-#define E_IS_PLUGIN_TYPE_HOOK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_PLUGIN_TYPE_HOOK))
-#define E_IS_PLUGIN_TYPE_HOOK_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_PLUGIN_TYPE_HOOK))
-#define E_PLUGIN_TYPE_HOOK_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_PLUGIN_TYPE_HOOK, EPluginTypeHookClass))
-
-typedef struct _EPluginTypeHook EPluginTypeHook;
-typedef struct _EPluginTypeHookClass EPluginTypeHookClass;
-
-struct _EPluginTypeHook {
- EPluginHook hook;
-
- gchar *get_type;
- guint idle;
-};
-
-struct _EPluginTypeHookClass {
- EPluginHookClass hook_class;
-};
-
-GType e_plugin_type_hook_get_type(void);
-
/* README: Currently there is only one flag.
But we may need more in the future and hence makes
sense to keep as an enum */
diff --git a/e-util/e-popup.c b/e-util/e-popup.c
deleted file mode 100644
index 4cbe221ea8..0000000000
--- a/e-util/e-popup.c
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <gtk/gtk.h>
-
-#include "e-popup.h"
-
-#include <glib/gi18n.h>
-
-#define d(x)
-
-struct _EPopupFactory {
- struct _EPopupFactory *next, *prev;
-
- gchar *menuid;
- EPopupFactoryFunc factory;
- gpointer factory_data;
-};
-
-/* Used for the "activate" signal callback data to re-map to the api */
-struct _item_node {
- struct _item_node *next; /* tree pointers */
- struct _item_node *prev;
- struct _item_node *parent;
- EDList children;
-
- struct _item_node *link; /* for freeing */
-
- EPopupItem *item;
- struct _menu_node *menu;
-};
-
-/* Stores all the items added */
-struct _menu_node {
- struct _menu_node *next, *prev;
-
- EPopup *popup;
-
- GSList *menu;
- gchar *domain;
- EPopupItemsFunc freefunc;
- gpointer data;
-
- struct _item_node *items;
-};
-
-struct _EPopupPrivate {
- EDList menus;
-};
-
-static GObjectClass *ep_parent;
-
-static void
-ep_init(GObject *o)
-{
- EPopup *emp = (EPopup *)o;
- struct _EPopupPrivate *p;
-
- p = emp->priv = g_malloc0(sizeof(struct _EPopupPrivate));
-
- e_dlist_init(&p->menus);
-}
-
-static void
-ep_finalise(GObject *o)
-{
- EPopup *emp = (EPopup *)o;
- struct _EPopupPrivate *p = emp->priv;
- struct _menu_node *mnode, *nnode;
-
- mnode = (struct _menu_node *)p->menus.head;
- nnode = mnode->next;
- while (nnode) {
- struct _item_node *inode;
-
- if (mnode->freefunc)
- mnode->freefunc(emp, mnode->menu, mnode->data);
-
- g_free(mnode->domain);
-
- /* free item activate callback data */
- inode = mnode->items;
- while (inode) {
- /* This was declared as _menu_node above already */
- struct _item_node *nnode = inode->link;
-
- g_free(inode);
- inode = nnode;
- }
-
- g_free(mnode);
- mnode = nnode;
- nnode = nnode->next;
- }
-
- if (emp->target)
- e_popup_target_free(emp, emp->target);
-
- g_free(emp->menuid);
-
- g_free(p);
-
- ((GObjectClass *)ep_parent)->finalize(o);
-}
-
-static void
-ep_target_free(EPopup *ep, EPopupTarget *t)
-{
- g_free(t);
- g_object_unref(ep);
-}
-
-static void
-ep_class_init(GObjectClass *klass)
-{
- d(printf("EPopup class init %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type)));
-
- klass->finalize = ep_finalise;
- ((EPopupClass *)klass)->target_free = ep_target_free;
-}
-
-static void
-ep_base_init(GObjectClass *klass)
-{
- e_dlist_init(&((EPopupClass *)klass)->factories);
-}
-
-/**
- * e_popup_get_type:
- *
- * Standard GObject type function.
- *
- * Return value: The EPopup object type.
- **/
-GType
-e_popup_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EPopupClass),
- (GBaseInitFunc)ep_base_init, NULL,
- (GClassInitFunc)ep_class_init, NULL, NULL,
- sizeof(EPopup), 0,
- (GInstanceInitFunc)ep_init
- };
- ep_parent = g_type_class_ref(G_TYPE_OBJECT);
- type = g_type_register_static(G_TYPE_OBJECT, "EPopup", &info, 0);
- }
-
- return type;
-}
-
-/**
- * e_popup_new - Create an targetless popup menu manager.
- * @menuid: Unique ID for this menu.
- *
- * Create a targetless popup menu object. This can be used as a
- * helper for creating popup menu's with no target. Such popup menu's
- * wont be very pluggable.
- *
- * Return value: A new EPopup.
- **/
-EPopup *e_popup_new(const gchar *menuid)
-{
- EPopup *ep = g_object_new(e_popup_get_type(), NULL);
-
- e_popup_construct(ep, menuid);
-
- return ep;
-}
-
-/**
- * e_popup_construct:
- * @ep: An instantiated but uninitialised EPopup.
- * @menuid: The menu identifier.
- *
- * Construct the base popup instance with standard parameters.
- *
- * Return value: Returns @ep.
- **/
-EPopup *e_popup_construct(EPopup *ep, const gchar *menuid)
-{
- ep->menuid = g_strdup(menuid);
-
- return ep;
-}
-
-/**
- * e_popup_add_items:
- * @emp: An EPopup derived object.
- * @items: A list of EPopupItem's to add to the current popup menu.
- * @domain: Translation domain for translating labels.
- * @freefunc: A function which will be called when the items are no
- * longer needed.
- * @data: user-data passed to @freefunc, and passed to all activate
- * methods.
- *
- * Add new EPopupItems to the menus. Any with the same path
- * will override previously defined menu items, at menu building
- * time. This may be called any number of times before the menu is
- * built to create a complex heirarchy of menus.
- **/
-void
-e_popup_add_items(EPopup *emp, GSList *items, const gchar *domain, EPopupItemsFunc freefunc, gpointer data)
-{
- struct _menu_node *node;
-
- node = g_malloc0(sizeof(*node));
- node->menu = items;
- node->domain = g_strdup(domain);
- node->freefunc = freefunc;
- node->data = data;
- node->popup = emp;
-
- e_dlist_addtail(&emp->priv->menus, (EDListNode *)node);
-}
-
-static void
-ep_add_static_items(EPopup *emp)
-{
- struct _EPopupFactory *f;
- EPopupClass *klass = (EPopupClass *)G_OBJECT_GET_CLASS(emp);
-
- if (emp->menuid == NULL || emp->target == NULL)
- return;
-
- /* setup the menu itself */
- f = (struct _EPopupFactory *)klass->factories.head;
- while (f->next) {
- if (f->menuid == NULL
- || !strcmp(f->menuid, emp->menuid)) {
- f->factory(emp, f->factory_data);
- }
- f = f->next;
- }
-}
-
-static gint
-ep_cmp(gconstpointer ap, gconstpointer bp)
-{
- struct _item_node *a = *((gpointer *)ap);
- struct _item_node *b = *((gpointer *)bp);
-
- return strcmp(a->item->path, b->item->path);
-}
-
-static void
-ep_activate(GtkWidget *w, struct _item_node *inode)
-{
- EPopupItem *item = inode->item;
- guint32 type = item->type & E_POPUP_TYPE_MASK;
-
- /* this is a bit hackish, use the item->type to transmit the
- active state, presumes we can write to this memory ... The
- alternative is the EMenu idea of different callbacks, but
- thats painful for breaking type-safety on callbacks */
-
- if (type == E_POPUP_TOGGLE || type == E_POPUP_RADIO) {
- if (gtk_check_menu_item_get_active((GtkCheckMenuItem *)w))
- item->type |= E_POPUP_ACTIVE;
- else
- item->type &= ~E_POPUP_ACTIVE;
- }
-
- item->activate(inode->menu->popup, item, inode->menu->data);
-}
-
-static void
-ep_prune_tree(EDList *head)
-{
- struct _item_node *inode, *nnode;
-
- /* need to do two scans, first to find out if the subtree's
- * are empty, then to remove any unecessary bars which may
- * become unecessary after the first scan */
-
- inode = (struct _item_node *)head->head;
- nnode = inode->next;
- while (nnode) {
- struct _EPopupItem *item = inode->item;
-
- ep_prune_tree(&inode->children);
-
- if ((item->type & E_POPUP_TYPE_MASK) == E_POPUP_SUBMENU) {
- if (e_dlist_empty(&inode->children))
- e_dlist_remove((EDListNode *)inode);
- }
-
- inode = nnode;
- nnode = nnode->next;
- }
-
- inode = (struct _item_node *)head->head;
- nnode = inode->next;
- while (nnode) {
- struct _EPopupItem *item = inode->item;
-
- if ((item->type & E_POPUP_TYPE_MASK) == E_POPUP_BAR) {
- if (inode->prev->prev == NULL
- || nnode->next == NULL
- || (nnode->item->type & E_POPUP_TYPE_MASK) == E_POPUP_BAR)
- e_dlist_remove((EDListNode *)inode);
- }
-
- inode = nnode;
- nnode = nnode->next;
- }
-}
-
-static GtkMenu *
-ep_build_tree(struct _item_node *inode, guint32 mask)
-{
- struct _item_node *nnode;
- GtkMenu *topmenu;
- GHashTable *group_hash = g_hash_table_new(g_str_hash, g_str_equal);
-
- topmenu = (GtkMenu *)gtk_menu_new();
-
- nnode = inode->next;
- while (nnode) {
- GtkWidget *label;
- struct _EPopupItem *item = inode->item;
- GtkMenuItem *menuitem;
-
- switch (item->type & E_POPUP_TYPE_MASK) {
- case E_POPUP_ITEM:
- if (item->image) {
- GtkWidget *image;
-
- image = gtk_image_new_from_icon_name (
- (gchar *) item->image, GTK_ICON_SIZE_MENU);
- gtk_widget_show(image);
- menuitem = (GtkMenuItem *)gtk_image_menu_item_new();
- gtk_image_menu_item_set_image((GtkImageMenuItem *)menuitem, image);
- } else {
- menuitem = (GtkMenuItem *)gtk_menu_item_new();
- }
- break;
- case E_POPUP_TOGGLE:
- menuitem = (GtkMenuItem *)gtk_check_menu_item_new();
- if (item->type & E_POPUP_INCONSISTENT)
- gtk_check_menu_item_set_inconsistent (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
- else
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), item->type & E_POPUP_ACTIVE);
-
- if (item->image)
- gtk_widget_show (item->image);
- break;
- case E_POPUP_RADIO: {
- gchar *ppath = inode->parent?inode->parent->item->path:NULL;
-
- menuitem = (GtkMenuItem *)gtk_radio_menu_item_new(g_hash_table_lookup(group_hash, ppath));
- g_hash_table_insert(group_hash, ppath, gtk_radio_menu_item_get_group((GtkRadioMenuItem *)menuitem));
- gtk_check_menu_item_set_active((GtkCheckMenuItem *)menuitem, item->type & E_POPUP_ACTIVE);
- break; }
- case E_POPUP_IMAGE:
- menuitem = (GtkMenuItem *)gtk_image_menu_item_new();
- gtk_image_menu_item_set_image((GtkImageMenuItem *)menuitem, item->image);
- break;
- case E_POPUP_SUBMENU: {
- GtkMenu *submenu = ep_build_tree((struct _item_node *)inode->children.head, mask);
-
- menuitem = (GtkMenuItem *)gtk_menu_item_new();
- gtk_menu_item_set_submenu(menuitem, (GtkWidget *)submenu);
- break; }
- case E_POPUP_BAR:
- menuitem = (GtkMenuItem *)gtk_separator_menu_item_new();
- break;
- default:
- continue;
- }
-
- if (item->label) {
- label = gtk_label_new_with_mnemonic(dgettext(inode->menu->domain, item->label));
- gtk_misc_set_alignment((GtkMisc *)label, 0.0, 0.5);
- gtk_widget_show(label);
- if (item->image && (item->type & E_POPUP_TYPE_MASK) == E_POPUP_TOGGLE) {
- GtkWidget *hbox = gtk_hbox_new (FALSE, 4);
-
- gtk_box_pack_start (GTK_BOX (hbox), item->image, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
- gtk_widget_show (hbox);
- gtk_container_add (GTK_CONTAINER (menuitem), hbox);
- } else
- gtk_container_add((GtkContainer *)menuitem, label);
- } else if (item->image && (item->type & E_POPUP_TYPE_MASK) == E_POPUP_TOGGLE) {
- gtk_container_add (GTK_CONTAINER (menuitem), item->image);
- }
-
- if (item->activate)
- g_signal_connect(menuitem, "activate", G_CALLBACK(ep_activate), inode);
-
- gtk_menu_shell_append((GtkMenuShell *)topmenu, (GtkWidget *)menuitem);
-
- if (item->enable & mask)
- gtk_widget_set_sensitive((GtkWidget *)menuitem, FALSE);
-
- gtk_widget_show((GtkWidget *)menuitem);
-
- inode = nnode;
- nnode = nnode->next;
- }
-
- g_hash_table_destroy(group_hash);
-
- return topmenu;
-}
-
-/**
- * e_popup_create:
- * @emp: An EPopup derived object.
- * @target: popup target, if set, then factories will be invoked.
- * This is then owned by the menu.
- * @mask: If supplied, overrides the target specified mask or provides
- * a mask if no target is supplied. Used to enable or show menu
- * items.
- *
- * All of the menu items registered on @emp are sorted by path, and
- * then converted into a menu heirarchy.
- *
- *
- * Return value: A GtkMenu which can be popped up when ready.
- **/
-GtkMenu *
-e_popup_create_menu(EPopup *emp, EPopupTarget *target, guint32 mask)
-{
- struct _EPopupPrivate *p = emp->priv;
- struct _menu_node *mnode, *nnode;
- GPtrArray *items = g_ptr_array_new();
- GSList *l;
- GString *ppath = g_string_new("");
- GHashTable *tree_hash = g_hash_table_new(g_str_hash, g_str_equal);
- EDList head = E_DLIST_INITIALISER(head);
- gint i;
-
- emp->target = target;
- ep_add_static_items(emp);
-
- if (target && mask == 0)
- mask = target->mask;
-
- /* Note: This code vastly simplifies memory management by
- * keeping a linked list of all temporary tree nodes on the
- * menu's tree until the epopup is destroyed */
-
- /* FIXME: need to override old ones with new names */
- mnode = (struct _menu_node *)p->menus.head;
- nnode = mnode->next;
- while (nnode) {
- for (l=mnode->menu; l; l = l->next) {
- struct _item_node *inode;
- struct _EPopupItem *item = l->data;
-
- /* we calculate bar/submenu visibility based on calculated set */
- if (item->visible) {
- if ((item->type & E_POPUP_TYPE_MASK) != E_POPUP_BAR
- && (item->type & E_POPUP_TYPE_MASK) != E_POPUP_SUBMENU
- && item->visible & mask) {
- d(printf("%s not visible\n", item->path));
- continue;
- }
- }
-
- inode = g_malloc0(sizeof(*inode));
- inode->item = l->data;
- inode->menu = mnode;
- e_dlist_init(&inode->children);
- inode->link = mnode->items;
- mnode->items = inode;
-
- g_ptr_array_add(items, inode);
- }
- mnode = nnode;
- nnode = nnode->next;
- }
-
- /* this makes building the tree in the right order easier */
- qsort(items->pdata, items->len, sizeof(items->pdata[0]), ep_cmp);
-
- /* create tree structure */
- for (i=0;i<items->len;i++) {
- struct _item_node *inode = items->pdata[i], *pnode;
- struct _item_node *nextnode = (i + 1 < items->len) ? items->pdata[i+1] : NULL;
- struct _EPopupItem *item = inode->item;
- const gchar *tmp;
-
- if (nextnode && !strcmp (nextnode->item->path, item->path)) {
- d(printf ("skipping item %s\n", item->path));
- continue;
- }
-
- g_string_truncate(ppath, 0);
- tmp = strrchr(item->path, '/');
- if (tmp) {
- g_string_append_len(ppath, item->path, tmp-item->path);
- pnode = g_hash_table_lookup(tree_hash, ppath->str);
- if (pnode == NULL) {
- g_warning("No parent defined for node '%s'", item->path);
- e_dlist_addtail(&head, (EDListNode *)inode);
- } else {
- e_dlist_addtail(&pnode->children, (EDListNode *)inode);
- inode->parent = pnode;
- }
- } else {
- e_dlist_addtail(&head, (EDListNode *)inode);
- }
-
- if ((item->type & E_POPUP_TYPE_MASK) == E_POPUP_SUBMENU)
- g_hash_table_insert(tree_hash, item->path, inode);
- }
-
- g_string_free(ppath, TRUE);
- g_ptr_array_free(items, TRUE);
- g_hash_table_destroy(tree_hash);
-
- /* prune unnecessary items */
- ep_prune_tree(&head);
-
- /* & build it */
- return ep_build_tree((struct _item_node *)head.head, mask);
-}
-
-static void
-ep_popup_done(GtkWidget *w, EPopup *emp)
-{
- gtk_widget_destroy(w);
- if (emp->target) {
- e_popup_target_free(emp, emp->target);
- emp->target = NULL;
- }
- g_object_unref(emp);
-}
-
-/**
- * e_popup_create_menu_once:
- * @emp: EPopup, once the menu is shown, this cannot be
- * considered a valid pointer.
- * @target: If set, the target of the selection. Static menu
- * items will be added. The target will be freed once complete.
- * @mask: Enable/disable and visibility mask.
- *
- * Like popup_create_menu, but automatically sets up the menu
- * so that it is destroyed once a selection takes place, and
- * the EPopup is unreffed. This is the normal entry point as it
- * automates most memory management for popup menus.
- *
- * Return value: A menu, to popup.
- **/
-GtkMenu *
-e_popup_create_menu_once(EPopup *emp, EPopupTarget *target, guint32 mask)
-{
- GtkMenu *menu;
-
- menu = e_popup_create_menu(emp, target, mask);
-
- g_signal_connect(menu, "selection_done", G_CALLBACK(ep_popup_done), emp);
-
- return menu;
-}
-
-/* ********************************************************************** */
-
-/**
- * e_popup_class_add_factory:
- * @klass: The EPopup derived class which you're interested in.
- * @menuid: The identifier of the menu you're interested in, or NULL
- * to be called for all menus on this class.
- * @func: The factory called when the menu @menuid is being created.
- * @data: User-data for the factory callback.
- *
- * This is a class-static method used to register factory callbacks
- * against specific menu's.
- *
- * The factory method will be invoked before the menu is created.
- * This way, the factory may add any additional menu items it wishes
- * based on the context supplied in the @target.
- *
- * Return value: A handle to the factory which can be used to remove
- * it later.
- **/
-EPopupFactory *
-e_popup_class_add_factory(EPopupClass *klass, const gchar *menuid, EPopupFactoryFunc func, gpointer data)
-{
- struct _EPopupFactory *f = g_malloc0(sizeof(*f));
-
- f->menuid = g_strdup(menuid);
- f->factory = func;
- f->factory_data = data;
- e_dlist_addtail(&klass->factories, (EDListNode *)f);
-
- return f;
-}
-
-/**
- * e_popup_class_remove_factory:
- * @klass: The EPopup derived class.
- * @f: The factory handle returned by e_popup_class_add_factory().
- *
- * Remove a popup menu factory. If it has not been added, or it has
- * already been removed, then the result is undefined (i.e. it will
- * crash).
- *
- * Generally factories are static for the life of the application, and
- * so do not need to be removed.
- **/
-void
-e_popup_class_remove_factory(EPopupClass *klass, EPopupFactory *f)
-{
- e_dlist_remove((EDListNode *)f);
- g_free(f->menuid);
- g_free(f);
-}
-
-/**
- * e_popup_target_new:
- * @ep: An EPopup derived object.
- * @type: type, defined by the implementing class.
- * @size: The size of memory to allocate for the target. It must be
- * equal or greater than the size of EPopupTarget.
- *
- * Allocate a new popup target suitable for this popup type.
- **/
-gpointer e_popup_target_new(EPopup *ep, gint type, gsize size)
-{
- EPopupTarget *t;
-
- if (size < sizeof(EPopupTarget)) {
- g_warning ("Size is less than the size of EPopupTarget\n");
- size = sizeof(EPopupTarget);
- }
-
- t = g_malloc0(size);
- t->popup = ep;
- g_object_ref(ep);
- t->type = type;
-
- return t;
-}
-
-/**
- * e_popup_target_free:
- * @ep: An EPopup derived object.
- * @o: The target, previously allocated by e_popup_target_new().
- *
- * Free the target against @ep. Note that targets are automatically
- * freed if they are passed to the menu creation functions, so this is
- * only required if you are using the target for other purposes.
- **/
-void
-e_popup_target_free(EPopup *ep, gpointer o)
-{
- EPopupTarget *t = o;
-
- ((EPopupClass *)G_OBJECT_GET_CLASS(ep))->target_free(ep, t);
-}
-
-/* ********************************************************************** */
-
-/* Popup menu plugin handler */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.item:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="IMAP4 and IMAP4v1 mail store">
- <hook class="org.gnome.mail.popupMenu:1.0"
- handler="HandlePopup">
- <menu id="any" target="select" factory="funcspec"?>
- <item
- type="item|toggle|radio|image|submenu|bar"
- active
- path="foo/bar"
- label="label"
- icon="foo"
- visible="select_one"
- activate="ep_view_emacs"/> *
- </menu>
- </extension>
-
-*/
-
-static gpointer emph_parent_class;
-#define emph ((EPopupHook *)eph)
-
-/* must have 1:1 correspondence with e-popup types in order */
-static const EPluginHookTargetKey emph_item_types[] = {
- { "item", E_POPUP_ITEM },
- { "toggle", E_POPUP_TOGGLE },
- { "radio", E_POPUP_RADIO },
- { "image", E_POPUP_IMAGE },
- { "submenu", E_POPUP_SUBMENU },
- { "bar", E_POPUP_BAR },
- { NULL }
-};
-
-static void
-emph_popup_activate(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupHook *hook = data;
-
- e_plugin_invoke(hook->hook.plugin, (gchar *)item->user_data, ep->target);
-}
-
-static void
-emph_popup_factory(EPopup *emp, gpointer data)
-{
- struct _EPopupHookMenu *menu = data;
-
- d(printf("popup factory called %s mask %08x\n", menu->id?menu->id:"all menus", emp->target->mask));
-
- /* If we're disabled, then don't add the menu's. */
- if (emp->target->type != menu->target_type
- || !menu->hook->hook.plugin->enabled)
- return;
-
- if (menu->items)
- e_popup_add_items(emp, menu->items, menu->hook->hook.plugin->domain, NULL, menu->hook);
-
- if (menu->factory)
- e_plugin_invoke(menu->hook->hook.plugin, menu->factory, emp->target);
-}
-
-static void
-emph_free_item(struct _EPopupItem *item)
-{
- g_free(item->path);
- g_free(item->label);
- g_free(item->image);
- g_free(item->user_data);
- g_free(item);
-}
-
-static void
-emph_free_menu(struct _EPopupHookMenu *menu)
-{
- g_slist_foreach(menu->items, (GFunc)emph_free_item, NULL);
- g_slist_free(menu->items);
-
- g_free(menu->factory);
- g_free(menu->id);
- g_free(menu);
-}
-
-static struct _EPopupItem *
-emph_construct_item(EPluginHook *eph, EPopupHookMenu *menu, xmlNodePtr root, EPopupHookTargetMap *map)
-{
- struct _EPopupItem *item;
-
- d(printf(" loading menu item\n"));
- item = g_malloc0(sizeof(*item));
- if ((item->type = e_plugin_hook_id(root, emph_item_types, "type")) == -1
- || item->type == E_POPUP_IMAGE)
- goto error;
- item->path = e_plugin_xml_prop(root, "path");
- item->label = e_plugin_xml_prop_domain(root, "label", eph->plugin->domain);
- item->image = e_plugin_xml_prop(root, "icon");
- item->visible = e_plugin_hook_mask(root, map->mask_bits, "visible");
- item->enable = e_plugin_hook_mask(root, map->mask_bits, "enable");
- item->user_data = e_plugin_xml_prop(root, "activate");
-
- item->activate = emph_popup_activate;
-
- if (item->user_data == NULL)
- goto error;
-
- d(printf(" path=%s\n", item->path));
- d(printf(" label=%s\n", item->label));
-
- return item;
-error:
- d(printf("error!\n"));
- emph_free_item(item);
- return NULL;
-}
-
-static struct _EPopupHookMenu *
-emph_construct_menu(EPluginHook *eph, xmlNodePtr root)
-{
- struct _EPopupHookMenu *menu;
- xmlNodePtr node;
- EPopupHookTargetMap *map;
- EPopupHookClass *klass = (EPopupHookClass *)G_OBJECT_GET_CLASS(eph);
- gchar *tmp;
-
- d(printf(" loading menu\n"));
- menu = g_malloc0(sizeof(*menu));
- menu->hook = (EPopupHook *)eph;
-
- tmp = (gchar *)xmlGetProp(root, (const guchar *)"target");
- if (tmp == NULL)
- goto error;
- map = g_hash_table_lookup(klass->target_map, tmp);
- xmlFree(tmp);
- if (map == NULL)
- goto error;
-
- menu->target_type = map->id;
- menu->id = e_plugin_xml_prop(root, "id");
- if (menu->id == NULL) {
- g_warning("Plugin '%s' missing 'id' field in popup for '%s'\n", eph->plugin->name,
- ((EPluginHookClass *)G_OBJECT_GET_CLASS(eph))->id);
- goto error;
- }
-
- menu->factory = e_plugin_xml_prop(root, "factory");
-
- node = root->children;
- while (node) {
- if (0 == strcmp((gchar *)node->name, "item")) {
- struct _EPopupItem *item;
-
- item = emph_construct_item(eph, menu, node, map);
- if (item)
- menu->items = g_slist_append(menu->items, item);
- }
- node = node->next;
- }
-
- return menu;
-error:
- emph_free_menu(menu);
- return NULL;
-}
-
-static gint
-emph_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root)
-{
- xmlNodePtr node;
- EPopupClass *klass;
-
- d(printf("loading popup hook\n"));
-
- if (((EPluginHookClass *)emph_parent_class)->construct(eph, ep, root) == -1)
- return -1;
-
- klass = ((EPopupHookClass *)G_OBJECT_GET_CLASS(eph))->popup_class;
-
- node = root->children;
- while (node) {
- if (strcmp((gchar *)node->name, "menu") == 0) {
- struct _EPopupHookMenu *menu;
-
- menu = emph_construct_menu(eph, node);
- if (menu) {
- e_popup_class_add_factory(klass, menu->id, emph_popup_factory, menu);
- emph->menus = g_slist_append(emph->menus, menu);
- }
- }
- node = node->next;
- }
-
- eph->plugin = ep;
-
- return 0;
-}
-
-static void
-emph_finalise(GObject *o)
-{
- EPluginHook *eph = (EPluginHook *)o;
-
- g_slist_foreach(emph->menus, (GFunc)emph_free_menu, NULL);
- g_slist_free(emph->menus);
-
- ((GObjectClass *)emph_parent_class)->finalize(o);
-}
-
-static void
-emph_class_init(EPluginHookClass *klass)
-{
- ((GObjectClass *)klass)->finalize = emph_finalise;
- klass->construct = emph_construct;
-
- /* this is actually an abstract implementation but list it anyway */
- klass->id = "org.gnome.evolution.popup:1.0";
-
- d(printf("EPopupHook: init class %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type)));
-
- ((EPopupHookClass *)klass)->target_map = g_hash_table_new(g_str_hash, g_str_equal);
- ((EPopupHookClass *)klass)->popup_class = g_type_class_ref(e_popup_get_type());
-}
-
-/**
- * e_popup_hook_get_type:
- *
- * Standard GObject function to get the object type. Used to subclass
- * EPopupHook.
- *
- * Return value: The type of the popup hook class.
- **/
-GType
-e_popup_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EPopupHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL,
- sizeof(EPopupHook), 0, (GInstanceInitFunc) NULL,
- };
-
- emph_parent_class = g_type_class_ref(e_plugin_hook_get_type());
- type = g_type_register_static(e_plugin_hook_get_type(), "EPopupHook", &info, 0);
- }
-
- return type;
-}
-
-/**
- * e_popup_hook_class_add_target_map:
- * @klass: The derived EPopupHook class.
- * @map: A map used to describe a single EPopupTarget type for this
- * class.
- *
- * Add a target map to a concrete derived class of EPopup. The target
- * map enumerates a single target type and the enable mask bit names,
- * so that the type can be loaded automatically by the EPopup class.
- **/
-void e_popup_hook_class_add_target_map(EPopupHookClass *klass, const EPopupHookTargetMap *map)
-{
- g_hash_table_insert(klass->target_map, (gpointer)map->type, (gpointer)map);
-}
diff --git a/e-util/e-popup.h b/e-util/e-popup.h
deleted file mode 100644
index 257234dc81..0000000000
--- a/e-util/e-popup.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michel Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __E_POPUP_H__
-#define __E_POPUP_H__
-
-#include <gtk/gtk.h>
-#include <libedataserver/e-msgport.h>
-
-G_BEGIN_DECLS
-
-/* This is an abstract popup menu management/merging class.
-
- To implement your own popup menu system, just create your own
- target types and implement the target free method. */
-
-typedef struct _EPopup EPopup;
-typedef struct _EPopupClass EPopupClass;
-
-typedef struct _EPopupItem EPopupItem;
-typedef struct _EPopupFactory EPopupFactory; /* anonymous type */
-typedef struct _EPopupTarget EPopupTarget;
-
-typedef void (*EPopupActivateFunc)(EPopup *ep, EPopupItem *item, gpointer data);
-typedef void (*EPopupFactoryFunc)(EPopup *emp, gpointer data);
-typedef void (*EPopupItemsFunc)(EPopup *ep, GSList *items, gpointer data);
-
-/**
- * enum _e_popup_t - Popup item type enumeration.
- * @E_POPUP_ITEM: A simple menu item.
- * @E_POPUP_TOGGLE: A toggle menu item. If struct _EPopupItem::image is
- * not NULL, then it points to GtkImage directly and there is a toggle
- * with an image and caption shown in the popup menu.
- * @E_POPUP_RADIO: A radio menu item. Note that the radio group is
- * global for the entire (sub) menu. i.e. submenu's must be used to
- * separate radio button menu items.
- * @E_POPUP_IMAGE: A &GtkImage menu item. In this case the @image
- * field of &struct _EPopupItem points to the &GtkImage directly.
- * @E_POPUP_SUBMENU: A sub-menu header. It is up to the application
- * to define the @path properly so that the submenu comes before the
- * submenu items.
- * @E_POPUP_BAR: A menu separator bar.
- * @E_POPUP_TYPE_MASK: Mask used to separate item type from option bits.
- * @E_POPUP_ACTIVE: An option bit to signify that the radio button or
- * toggle button is active.
- * @E_POPUP_INCONSISTENT: An option to toggle only, if set, the toggle
- * is shown in inconsistent state. This is used before E_POPUP_ACTIVE.
- */
-enum _e_popup_t {
- E_POPUP_ITEM = 0,
- E_POPUP_TOGGLE,
- E_POPUP_RADIO,
- E_POPUP_IMAGE,
- E_POPUP_SUBMENU,
- E_POPUP_BAR,
- E_POPUP_TYPE_MASK = 0xffff,
- E_POPUP_ACTIVE = 0x10000,
- E_POPUP_INCONSISTENT = 0x20000
-};
-
-/* FIXME: activate passes back no context data apart from that provided.
- FIXME: It should pass the target at the least. The menu widget is
- useless */
-
-/**
- * struct _EPopupItem - A popup menu item definition.
- * @type: The type of the popup. See the &enum _epopup_t definition
- * for possible values.
- * @path: An absolute path, which when sorted using a simple ASCII
- * sort, will put the menu item in the right place in the menu
- * heirarchy. '/' is used to separate menus from submenu items.
- * @label: The text of the menyu item.
- * @activate: A function conforming to &EPopupActivateFunc which will
- * be called when the menu item is activated.
- * @user_data: Extra per-item user-data available to the
- * application. This is not passed to the @data field of @activate.
- * @image: For most types, the name of the icon in the icon theme to
- * display next to the menu item, if required. For the %E_POPUP_IMAGE
- * type, it is a pointer to the &GtkWidget instead.
- * @visible: Visibility mask. Used together with the &EPopupTarget mask
- * to determine if the item should be part of the menu or not.
- * @enable: Sensitivity mask. Similar to the visibility mask, but
- * currently unimplemented.
- * @popup: Used by e-popup to reference the parent object from
- * callbacks.
- *
- * The EPopupItem defines a single popup menu item, or submenu item,
- * or menu separator based on the @type. Any number of these are
- * merged at popup display type to form the popup menu.
- *
- * The application may extend this structure using simple C structure
- * containers to add any additional fields it may require.
- */
-struct _EPopupItem {
- enum _e_popup_t type;
- gchar *path; /* absolute path! must sort ascii-lexographically into the right spot */
- gchar *label;
- EPopupActivateFunc activate;
- gpointer user_data; /* user data, not passed directly to @activate */
- gpointer image; /* gchar * for item type, GtkWidget * for image type */
- guint32 visible; /* visibility mask */
- guint32 enable; /* sensitivity mask */
-};
-
-/**
- * struct EPopupTarget - A popup menu target definition.
- *
- * @popup: The parent popup object, used for virtual methods on the target.
- * @widget: The parent widget, where available. In some cases the
- * type of this object is part of the published api for the target.
- * @type: The target type. This will be defined by the
- * implementation.
- * @mask: Target mask. This is used to sensitise and show items
- * based on their definition in EPopupItem.
- *
- * An EPopupTarget defines the context for a specific popup menu
- * instance. The root target object is abstract, and it is up to
- * sub-classes of &EPopup to define the additional fields required to
- * make it usable.
- */
-struct _EPopupTarget {
- struct _EPopup *popup; /* used for virtual methods */
-
- GtkWidget *widget; /* used if you need a parent toplevel, if available */
- guint32 type; /* targe type, for implementors */
-
- guint32 mask; /* depends on type, visibility mask */
-
- /* implementation fields follow */
-};
-
-/**
- * struct _EPopup - A Popup menu manager.
- *
- * @object: Superclass, GObject.
- * @priv: Private data.
- * @menuid: The id of this menu instance.
- * @target: The current target during the display of the popup menu.
- *
- * The EPopup manager object. Each popup menu is built using this
- * one-off object which is created each time the popup is invoked.
- */
-struct _EPopup {
- GObject object;
-
- struct _EPopupPrivate *priv;
-
- gchar *menuid;
-
- EPopupTarget *target;
-};
-
-/**
- * struct _EPopupClass -
- *
- * @object_class: Superclass type.
- * @factories: A list of factories for this particular class of popup
- * menu.
- * @target_free: Virtual method to free the popup target. The base
- * class frees the allocation and unrefs the popup pointer
- * structure.
- *
- * The EPopup class definition. This should be sub-classed for each
- * component that wants to provide hookable popup menus. The
- * sub-class only needs to know how to allocate and free the various target
- * types it supports.
- */
-struct _EPopupClass {
- GObjectClass object_class;
-
- EDList factories;
-
- void (*target_free)(EPopup *ep, EPopupTarget *t);
-};
-
-GType e_popup_get_type(void);
-
-EPopup *e_popup_new(const gchar *menuid);
-
-/* Static class methods */
-EPopupFactory *e_popup_class_add_factory(EPopupClass *klass, const gchar *menuid, EPopupFactoryFunc func, gpointer data);
-void e_popup_class_remove_factory(EPopupClass *klass, EPopupFactory *f);
-
-EPopup *e_popup_construct(EPopup *, const gchar *menuid);
-
-void e_popup_add_items(EPopup *, GSList *items, const gchar *domain, EPopupItemsFunc freefunc, gpointer data);
-
-void e_popup_add_static_items(EPopup *emp, EPopupTarget *target);
-/* do not call e_popup_create_menu, it can leak structures if not used right */
-GtkMenu *e_popup_create_menu(EPopup *, EPopupTarget *, guint32 mask);
-GtkMenu *e_popup_create_menu_once(EPopup *emp, EPopupTarget *, guint32 mask);
-
-gpointer e_popup_target_new(EPopup *, gint type, gsize size);
-void e_popup_target_free(EPopup *, gpointer );
-
-/* ********************************************************************** */
-
-/* popup plugin target, they are closely integrated */
-
-/* To implement a basic popup menu plugin, you just need to subclass
- this and initialise the class target type tables */
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPopupHookMenu EPopupHookMenu;
-typedef struct _EPopupHook EPopupHook;
-typedef struct _EPopupHookClass EPopupHookClass;
-
-typedef struct _EPluginHookTargetMap EPopupHookTargetMap;
-typedef struct _EPluginHookTargetKey EPopupHookTargetMask;
-
-typedef void (*EPopupHookFunc)(struct _EPlugin *plugin, EPopupTarget *target);
-
-/**
- * struct _EPopupHookMenu -
- *
- * @hook: Parent pointer.
- * @id: The identifier of the menu to which these items belong.
- * @target_type: The target number of the type of target these menu
- * items expect. It will generally also be defined by the menu id.
- * @items: A list of EPopupItems.
- * @factory: If supplied, a function to call
- *
- * The structure used to keep track of all of the items that a plugin
- * wishes to add to a given menu. This is used internally by a factory
- * method set on EPlugin to add the right menu items to a given menu.
- */
-struct _EPopupHookMenu {
- struct _EPopupHook *hook; /* parent pointer */
- gchar *id; /* target menu id for these menu items */
- gint target_type; /* target type of this menu */
- GSList *items; /* items to add to menu */
- gchar *factory; /* optional factory to call for adding menu items */
-};
-
-/**
- * struct _EPopupHook - A popup menu hook.
- *
- * @hook: Superclass.
- * @menus: A list of EPopupHookMenus, for all menus registered on
- * this hook type.
- *
- * The EPopupHook class loads and manages the meta-data required to
- * map plugin definitions to physical menus.
- */
-struct _EPopupHook {
- EPluginHook hook;
-
- GSList *menus;
-};
-
-/**
- * struct _EPopupHookClass -
- *
- * @hook_class: Superclass.
- * @target_map: Table of EPluginHookTargetMaps which enumerate the
- * target types and enable bits of the implementing class.
- * @popup_class: The EPopupClass of the corresponding popup manager
- * for the implementing class.
- *
- * The EPopupHookClass is a concrete class, however it is empty on its
- * own. It needs to be sub-classed and initialised appropriately.
- *
- * The EPluginHookClass.id must be set to the name and version of the
- * hook handler itself. The @target_map must be initialised with the
- * data required to enumerate the target types and enable flags
- * supported by the implementing class.
- */
-struct _EPopupHookClass {
- EPluginHookClass hook_class;
-
- /* EPopupHookTargetMap by .type */
- GHashTable *target_map;
- /* the popup class these popups belong to */
- EPopupClass *popup_class;
-};
-
-GType e_popup_hook_get_type(void);
-
-/* for implementors */
-void e_popup_hook_class_add_target_map(EPopupHookClass *klass, const EPopupHookTargetMap *);
-
-G_END_DECLS
-
-#endif /* __E_POPUP_H__ */
diff --git a/e-util/e-request.c b/e-util/e-request.c
index 3cd23968b2..58784ee1ae 100644
--- a/e-util/e-request.c
+++ b/e-util/e-request.c
@@ -64,7 +64,7 @@ e_request_string (GtkWindow *parent,
gtk_window_set_default_size (GTK_WINDOW (dialog), 275, -1);
gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
- vbox = GTK_DIALOG (dialog)->vbox;
+ vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
prompt_label = gtk_label_new (prompt);
gtk_box_pack_start (GTK_BOX (vbox), prompt_label, TRUE, TRUE, 6);
diff --git a/e-util/e-signature-utils.c b/e-util/e-signature-utils.c
new file mode 100644
index 0000000000..4ae5ac2c8f
--- /dev/null
+++ b/e-util/e-signature-utils.c
@@ -0,0 +1,351 @@
+/*
+ * e-signature-utils.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#include "e-signature-utils.h"
+
+#include <errno.h>
+#include <glib/gstdio.h>
+#include <gconf/gconf-client.h>
+#include <camel/camel-stream.h>
+#include <camel/camel-stream-fs.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-mime-filter-charset.h>
+#include <camel/camel-mime-filter-tohtml.h>
+
+#ifndef G_OS_WIN32
+#include <sys/wait.h>
+#endif
+
+#include "e-util/e-util.h"
+
+static ESignatureList *global_signature_list;
+
+ESignatureList *
+e_get_signature_list (void)
+{
+ if (G_UNLIKELY (global_signature_list == NULL)) {
+ GConfClient *client;
+
+ client = gconf_client_get_default ();
+ global_signature_list = e_signature_list_new (client);
+ g_object_unref (client);
+ }
+
+ g_return_val_if_fail (global_signature_list != NULL, NULL);
+
+ return global_signature_list;
+}
+
+ESignature *
+e_get_signature_by_name (const gchar *name)
+{
+ ESignatureList *signature_list;
+ const ESignature *signature;
+ e_signature_find_t find;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ find = E_SIGNATURE_FIND_NAME;
+ signature_list = e_get_signature_list ();
+ signature = e_signature_list_find (signature_list, find, name);
+
+ /* XXX ESignatureList misuses const. */
+ return (ESignature *) signature;
+}
+
+ESignature *
+e_get_signature_by_uid (const gchar *uid)
+{
+ ESignatureList *signature_list;
+ const ESignature *signature;
+ e_signature_find_t find;
+
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ find = E_SIGNATURE_FIND_UID;
+ signature_list = e_get_signature_list ();
+ signature = e_signature_list_find (signature_list, find, uid);
+
+ /* XXX ESignatureList misuses const. */
+ return (ESignature *) signature;
+}
+
+gchar *
+e_create_signature_file (GError **error)
+{
+ const gchar *data_dir;
+ gchar basename[32];
+ gchar *filename;
+ gchar *pathname;
+ gint32 ii;
+
+ data_dir = e_get_user_data_dir ();
+ pathname = g_build_filename (data_dir, "signatures", NULL);
+ filename = NULL;
+
+ if (g_mkdir_with_parents (pathname, 0700) < 0) {
+ g_set_error (
+ error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s: %s", pathname, g_strerror (errno));
+ g_free (pathname);
+ return NULL;
+ }
+
+ for (ii = 0; ii < G_MAXINT32; ii++) {
+
+ g_snprintf (
+ basename, sizeof (basename),
+ "signature-%" G_GINT32_FORMAT, ii);
+
+ g_free (filename);
+ filename = g_build_filename (pathname, basename, NULL);
+
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ gint fd;
+
+ fd = g_creat (filename, 0600);
+ if (fd >= 0) {
+ close (fd);
+ break;
+ }
+
+ /* If we failed once we're probably going
+ * to continue failing, so just give up. */
+ g_set_error (
+ error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s: %s", filename, g_strerror (errno));
+ g_free (filename);
+ filename = NULL;
+ break;
+ }
+ }
+
+ /* If there are actually G_MAXINT32 signature files, the
+ * most recent signature file we be overwritten. Sorry. */
+
+ return filename;
+}
+
+gchar *
+e_read_signature_file (ESignature *signature,
+ gboolean convert_to_html,
+ GError **error)
+{
+ CamelStream *input_stream;
+ CamelStream *output_stream;
+ GByteArray *buffer;
+ const gchar *filename;
+ gboolean is_html;
+ gchar *content;
+ gsize length;
+ gint fd;
+
+ g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
+
+ filename = e_signature_get_filename (signature);
+ is_html = e_signature_get_is_html (signature);
+
+ fd = g_open (filename, O_RDONLY, 0);
+ if (fd < 0) {
+ g_set_error (
+ error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s: %s", filename, g_strerror (errno));
+ return NULL;
+ }
+
+ input_stream = camel_stream_fs_new_with_fd (fd);
+
+ if (!is_html && convert_to_html) {
+ CamelStreamFilter *filtered_stream;
+ CamelMimeFilter *filter;
+ gint32 flags;
+
+ filtered_stream =
+ camel_stream_filter_new_with_stream (input_stream);
+ camel_object_unref (input_stream);
+
+ flags =
+ CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES;
+ filter = camel_mime_filter_tohtml_new (flags, 0);
+ camel_stream_filter_add (filtered_stream, filter);
+ camel_object_unref (filter);
+
+ input_stream = (CamelStream *) filtered_stream;
+ }
+
+ buffer = g_byte_array_new ();
+ output_stream = camel_stream_mem_new ();
+ camel_stream_mem_set_byte_array (
+ CAMEL_STREAM_MEM (output_stream), buffer);
+ camel_stream_write_to_stream (input_stream, output_stream);
+ camel_object_unref (output_stream);
+ camel_object_unref (input_stream);
+
+ /* Make sure the buffer is nul-terminated. */
+ length = (gsize) buffer->len;
+ g_byte_array_append (buffer, (guint8 *) "", 1);
+ content = (gchar *) g_byte_array_free (buffer, FALSE);
+
+ /* Signatures are saved as UTF-8, but we still need to check that
+ * the signature is valid UTF-8 because the user may be opening
+ * a signature file that is in his/her locale character set. If
+ * it's not in UTF-8 then try converting from the current locale. */
+ if (!g_utf8_validate (content, length, NULL)) {
+ gchar *utf8;
+
+ utf8 = g_locale_to_utf8 (content, length, NULL, NULL, error);
+ g_free (content);
+ content = utf8;
+ }
+
+ return content;
+}
+
+gchar *
+e_run_signature_script (const gchar *filename)
+{
+ /* FIXME Make this cross-platform, prefer GLib functions over
+ * POSIX, and report errors via GError instead of dumping
+ * messages to the terminal where users won't see them. */
+
+#ifndef G_OS_WIN32
+ gint in_fds[2];
+ pid_t pid;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ if (pipe (in_fds) == -1) {
+ g_warning (
+ "Failed to create pipe to '%s': %s",
+ filename, g_strerror (errno));
+ return NULL;
+ }
+
+ pid = fork ();
+
+ /* Child Process */
+ if (pid == 0) {
+ gint maxfd, ii;
+
+ close (in_fds[0]);
+ if (dup2 (in_fds[1], STDOUT_FILENO) < 0)
+ _exit (255);
+ close (in_fds[1]);
+
+ setsid ();
+
+ maxfd = sysconf (_SC_OPEN_MAX);
+ for (ii = 3; ii < maxfd; ii++) {
+ if (ii == STDIN_FILENO)
+ continue;
+ if (ii == STDOUT_FILENO)
+ continue;
+ if (ii == STDERR_FILENO)
+ continue;
+ fcntl (ii, F_SETFD, FD_CLOEXEC);
+ }
+
+ execlp ("/bin/sh", "/bin/sh", "-c", filename, NULL);
+
+ g_warning (
+ "Could not execute '%s': %s",
+ filename, g_strerror (errno));
+
+ _exit (255);
+
+ /* Parent Process */
+ } else if (pid > 0) {
+ CamelStream *output_stream;
+ CamelStream *input_stream;
+ GByteArray *buffer;
+ gchar *content;
+ gsize length;
+ gint result;
+ gint status;
+
+ close (in_fds[1]);
+
+ buffer = g_byte_array_new ();
+ output_stream = camel_stream_mem_new ();
+ camel_stream_mem_set_byte_array (
+ CAMEL_STREAM_MEM (output_stream), buffer);
+
+ input_stream = camel_stream_fs_new_with_fd (in_fds[0]);
+ camel_stream_write_to_stream (input_stream, output_stream);
+ camel_object_unref (input_stream);
+
+ camel_object_unref (output_stream);
+
+ /* Make sure the buffer is nul-terminated. */
+ length = (gsize) buffer->len;
+ g_byte_array_append (buffer, (guchar *) "", 1);
+ content = (gchar *) g_byte_array_free (buffer, FALSE);
+
+ /* Signature scripts are supposed to generate UTF-8 content,
+ * but because users are known to never read the manual, we
+ * try to do our best if the content isn't valid UTF-8 by
+ * assuming that the content is in the user's locale
+ * character set. */
+ if (!g_utf8_validate (content, length, NULL)) {
+ gchar *utf8;
+
+ /* XXX Should pass a GError here. */
+ utf8 = g_locale_to_utf8 (
+ content, length, NULL, NULL, NULL);
+ g_free (content);
+ content = utf8;
+ }
+
+ /* Wait for the script process to terminate. */
+ result = waitpid (pid, &status, 0);
+
+ if (result == -1 && errno == EINTR) {
+ /* Child process is hanging... */
+ kill (pid, SIGTERM);
+ sleep (1);
+ result = waitpid (pid, &status, WNOHANG);
+ if (result == 0) {
+ /* ...still hanging, set phasers to KILL. */
+ kill (pid, SIGKILL);
+ sleep (1);
+ result = waitpid (pid, &status, WNOHANG);
+ }
+ }
+
+ return content;
+
+ /* Forking Failed */
+ } else {
+ g_warning (
+ "Failed to create child process '%s': %s",
+ filename, g_strerror (errno));
+ close (in_fds[0]);
+ close (in_fds[1]);
+ }
+#endif
+
+ return NULL;
+}
diff --git a/mail/mail-config-factory.h b/e-util/e-signature-utils.h
index e32d730089..56f8564131 100644
--- a/mail/mail-config-factory.h
+++ b/e-util/e-signature-utils.h
@@ -1,4 +1,6 @@
/*
+ * e-signature-utils.h
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -12,28 +14,27 @@
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- *
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
*/
-#ifndef __MAIL_CONFIG_FACTORY_H__
-#define __MAIL_CONFIG_FACTORY_H__
+#ifndef E_SIGNATURE_UTILS_H
+#define E_SIGNATURE_UTILS_H
-G_BEGIN_DECLS
-
-#include <bonobo/bonobo-generic-factory.h>
-#include "evolution-config-control.h"
+#include <gtk/gtk.h>
+#include <e-util/e-signature.h>
+#include <e-util/e-signature-list.h>
-#include <shell/Evolution.h>
-
-gboolean mail_config_register_factory (GNOME_Evolution_Shell shell);
+G_BEGIN_DECLS
-BonoboObject *mail_config_control_factory_cb (BonoboGenericFactory *factory, const gchar *component_id, gpointer user_data);
+ESignatureList *e_get_signature_list (void);
+ESignature * e_get_signature_by_name (const gchar *name);
+ESignature * e_get_signature_by_uid (const gchar *uid);
+gchar * e_create_signature_file (GError **error);
+gchar * e_read_signature_file (ESignature *signature,
+ gboolean convert_to_html,
+ GError **error);
+gchar * e_run_signature_script (const gchar *filename);
G_END_DECLS
-#endif /* __MAIL_CONFIG_FACTORY_H__ */
+#endif /* E_SIGNATURE_UTILS_H */
diff --git a/widgets/misc/e-unicode.c b/e-util/e-unicode.c
index fb815ff94f..fb815ff94f 100644
--- a/widgets/misc/e-unicode.c
+++ b/e-util/e-unicode.c
diff --git a/widgets/misc/e-unicode.h b/e-util/e-unicode.h
index 737c5088eb..737c5088eb 100644
--- a/widgets/misc/e-unicode.h
+++ b/e-util/e-unicode.h
diff --git a/e-util/e-util-labels.c b/e-util/e-util-labels.c
deleted file mode 100644
index eeab09fe59..0000000000
--- a/e-util/e-util-labels.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include <gconf/gconf-client.h>
-
-#include <camel/camel-utf8.h>
-
-#include "e-util.h"
-#include "e-util-labels.h"
-#include "e-dialog-utils.h"
-#include "filter/filter-option.h"
-
-typedef struct {
- const gchar *tag;
- const gchar *name;
- const gchar *colour;
-} DefaultLabel;
-
-/* Note, the first element of each DefaultLabel must NOT be translated */
-DefaultLabel label_defaults[] = {
- { "$Labelimportant", N_("I_mportant"), "#EF2929" }, /* red */
- { "$Labelwork", N_("_Work"), "#F57900" }, /* orange */
- { "$Labelpersonal", N_("_Personal"), "#4E9A06" }, /* green */
- { "$Labeltodo", N_("_To Do"), "#3465A4" }, /* blue */
- { "$Labellater", N_("_Later"), "#75507B" } /* purple */
-};
-
-/**
- * e_util_labels_parse
- * Reads the setup from client and parses it to list of EUtilLabel objects.
- *
- * @param client The config client to be used for reading setup.
- * Can be NULL, in that case it will use the default client.
- * @return Newly allocated list of labels, should be freed with @ref e_util_labels_free.
- **/
-GSList *
-e_util_labels_parse (GConfClient *client)
-{
- GSList *labels, *list, *head;
- EUtilLabel *label;
- gchar *buf;
- gint num = 0;
- gboolean unref_client = client == NULL;
-
- labels = NULL;
-
- if (!client)
- client = gconf_client_get_default ();
-
- head = gconf_client_get_list (client, E_UTIL_LABELS_GCONF_KEY, GCONF_VALUE_STRING, NULL);
-
- for (list = head; list; list = list->next) {
- gchar *color, *name, *tag;
- name = buf = list->data;
- color = strrchr (buf, ':');
- if (color == NULL) {
- g_free (buf);
- continue;
- }
-
- *color++ = '\0';
- tag = strchr (color, '|');
- if (tag)
- *tag++ = '\0';
-
- label = g_new (EUtilLabel, 1);
-
- /* Needed for Backward Compatibility */
- if (num < G_N_ELEMENTS (label_defaults)) {
- label->name = g_strdup ((buf && *buf) ? buf : _(label_defaults[num].name));
- label->tag = g_strdup (label_defaults[num].tag);
- num++;
- } else if (!tag) {
- g_free (buf);
- g_free (label);
- continue;
- } else {
- label->name = g_strdup (name);
- label->tag = g_strdup (tag);
- }
-
- label->colour = g_strdup (color);
- labels = g_slist_prepend (labels, label);
-
- g_free (buf);
- }
-
- if (head)
- g_slist_free (head);
-
- while (num < G_N_ELEMENTS (label_defaults)) {
- /* complete the list with defaults */
- label = g_new (EUtilLabel, 1);
- label->tag = g_strdup (label_defaults[num].tag);
- label->name = g_strdup (_(label_defaults[num].name));
- label->colour = g_strdup (label_defaults[num].colour);
-
- labels = g_slist_prepend (labels, label);
-
- num++;
- }
-
- if (unref_client)
- g_object_unref (client);
-
- return g_slist_reverse (labels);
-}
-
-static void
-free_label_struct (EUtilLabel *label)
-{
- if (!label)
- return;
-
- g_free (label->tag);
- g_free (label->name);
- g_free (label->colour);
- g_free (label);
-}
-
-/**
- * e_util_labels_free
- * Frees memory previously allocated by @ref e_util_labels_parse
- *
- * @param labels Labels list, previously allocated by @ref e_util_labels_parse
- * It is safe to call with NULL.
- **/
-void
-e_util_labels_free (GSList *labels)
-{
- if (!labels)
- return;
-
- g_slist_foreach (labels, (GFunc)free_label_struct, NULL);
- g_slist_free (labels);
-}
-
-/* stores the actual cache to gconf */
-static gboolean
-flush_labels_cache (GSList *labels, gboolean free_labels)
-{
- GSList *l, *text_labels;
- GConfClient *client;
-
- if (!labels)
- return FALSE;
-
- text_labels = NULL;
-
- for (l = labels; l; l = l->next) {
- EUtilLabel *label = l->data;
-
- if (label && label->tag && label->name && label->colour)
- text_labels = g_slist_prepend (text_labels, g_strdup_printf ("%s:%s|%s", label->name, label->colour, label->tag));
- }
-
- if (!text_labels) {
- if (free_labels)
- e_util_labels_free (labels);
-
- return FALSE;
- }
-
- text_labels = g_slist_reverse (text_labels);
-
- client = gconf_client_get_default ();
- gconf_client_set_list (client, E_UTIL_LABELS_GCONF_KEY, GCONF_VALUE_STRING, text_labels, NULL);
- g_object_unref (client);
-
- g_slist_foreach (text_labels, (GFunc)g_free, NULL);
- g_slist_free (text_labels);
-
- if (free_labels)
- e_util_labels_free (labels);
-
- /* not true if gconf failed to write; who cares */
- return TRUE;
-}
-
-/**
- * find_label
- *
- * Looks for label in labels cache by tag and returns actual pointer to cache.
- * @param labels The cache of labels; comes from @ref e_util_labels_parse
- * @param tag Tag of label you are looking for.
- * @return Pointer to cache data if label with such tag exists or NULL. Do not free it!
- **/
-static EUtilLabel *
-find_label (GSList *labels, const gchar *tag)
-{
- GSList *l;
-
- g_return_val_if_fail (tag != NULL, NULL);
-
- for (l = labels; l; l = l->next) {
- EUtilLabel *label = l->data;
-
- if (label && label->tag && !strcmp (tag, label->tag))
- return label;
- }
-
- return NULL;
-}
-
-static gchar *
-tag_from_name (const gchar *name)
-{
- /* this does thunderbird, just do not ask */
- gchar *s1, *s2, *p;
- const gchar *bads = " ()/{%*<>\\\"";
-
- if (!name || !*name)
- return NULL;
-
- s1 = g_strdup (name);
- for (p = s1; p && *p; p++) {
- if (strchr (bads, *p))
- *p = '_';
- }
-
- s2 = camel_utf8_utf7 (s1);
- g_free (s1);
-
- s1 = g_ascii_strdown (s2, -1);
- g_free (s2);
-
- return s1;
-}
-
-/**
- * e_util_labels_add
- * Creates new label at the end of actual list of labels.
- *
- * @param name User readable name of this label. Should not be NULL.
- * @param color Color assigned to this label. Should not be NULL.
- * @return If succeeded then new label tag, NULL otherwise.
- * Returned pointer should be freed with g_free.
- * It will return NULL when the tag will be same as already existed.
- * Tag name is generated in similar way as in Thunderbird.
- **/
-gchar *
-e_util_labels_add (const gchar *name, const GdkColor *color)
-{
- EUtilLabel *label;
- GSList *labels;
- gchar *tag;
-
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (color != NULL, NULL);
-
- labels = e_util_labels_parse (NULL);
- tag = tag_from_name (name);
-
- if (!tag || find_label (labels, tag) != NULL) {
- g_free (tag);
- e_util_labels_free (labels);
- return NULL;
- }
-
- label = g_new0 (EUtilLabel, 1);
- label->tag = g_strdup (tag);
- label->name = g_strdup (name);
- label->colour = gdk_color_to_string (color);
-
- labels = g_slist_append (labels, label);
-
- flush_labels_cache (labels, TRUE);
-
- return tag;
-}
-
-/**
- * e_util_labels_add_with_dlg
- * This will open a dialog to add or edit label.
- *
- * @param parent Parent widget for the dialog.
- * @param tag A tag for existing label to edit or NULL to add new label.
- * @return Tag for newly added label or NULL, if something failed.
- * Returned value should be freed with g_free.
- **/
-gchar *
-e_util_labels_add_with_dlg (GtkWindow *parent, const gchar *tag)
-{
- GtkWidget *table, *dialog, *l, *e, *c;
- const gchar *name;
- GdkColor color;
- gboolean is_edit = FALSE;
- gchar *new_tag = NULL;
- GSList *labels;
-
- table = gtk_table_new (2, 2, FALSE);
-
- labels = e_util_labels_parse (NULL);
- name = tag ? e_util_labels_get_name (labels, tag) : NULL;
-
- l = gtk_label_new_with_mnemonic (_("Label _Name:"));
- e = gtk_entry_new ();
- c = gtk_color_button_new ();
-
- if (!tag || !e_util_labels_get_color (labels, tag, &color))
- memset (&color, 0xCD, sizeof (GdkColor));
- else
- is_edit = TRUE;
-
- if (name)
- gtk_entry_set_text (GTK_ENTRY (e), name);
-
- gtk_entry_set_activates_default (GTK_ENTRY (e), TRUE);
- gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
- gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.0);
- gtk_color_button_set_color (GTK_COLOR_BUTTON (c), &color);
-
- gtk_table_attach (GTK_TABLE (table), l, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- gtk_table_attach (GTK_TABLE (table), e, 0, 1, 1, 2, 0, 0, 0, 0);
- gtk_table_attach (GTK_TABLE (table), c, 1, 2, 1, 2, 0, 0, 0, 0);
- gtk_container_set_border_width (GTK_CONTAINER (table), 10);
- gtk_widget_show_all (table);
-
- dialog = gtk_dialog_new_with_buttons (is_edit ? _("Edit Label") : _("Add Label"),
- parent,
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0);
-
- while (!new_tag) {
- const gchar *error = NULL;
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
- name = gtk_entry_get_text (GTK_ENTRY (e));
- gtk_color_button_get_color (GTK_COLOR_BUTTON (c), &color);
-
- if (!name || !*name)
- error = _("Label name cannot be empty.");
- else if (is_edit) {
- e_util_labels_set_data (tag, name, &color);
- break;
- } else if (!(new_tag = e_util_labels_add (name, &color)))
- error = _("A label having the same tag already exists on the server. Please rename your label.");
- else
- break;
- } else
- break;
-
- if (error)
- e_notice (parent, GTK_MESSAGE_ERROR, error);
- }
-
- gtk_widget_destroy (dialog);
- e_util_labels_free (labels);
-
- return new_tag;
-}
-
-/**
- * e_util_labels_remove
- *
- * @param tag Tag of the label to remove.
- * @return Whether was removed.
- **/
-gboolean
-e_util_labels_remove (const gchar *tag)
-{
- EUtilLabel *label;
- GSList *labels;
-
- g_return_val_if_fail (tag != NULL, FALSE);
-
- labels = e_util_labels_parse (NULL);
- label = find_label (labels, tag);
-
- if (!label) {
- e_util_labels_free (labels);
- return FALSE;
- }
-
- labels = g_slist_remove (labels, label);
-
- free_label_struct (label);
-
- return flush_labels_cache (labels, TRUE);
-}
-
-/**
- * e_util_labels_set_data
- *
- * @param tag Tag of the label of our interest.
- * @param name New name for the label.
- * @param color New color for the label.
- * @return Whether successfully saved.
- **/
-gboolean
-e_util_labels_set_data (const gchar *tag, const gchar *name, const GdkColor *color)
-{
- EUtilLabel *label;
- GSList *labels;
-
- g_return_val_if_fail (tag != NULL, FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
- g_return_val_if_fail (color != NULL, FALSE);
-
- labels = e_util_labels_parse (NULL);
- label = find_label (labels, tag);
-
- if (!label) {
- e_util_labels_free (labels);
- return FALSE;
- }
-
- g_free (label->name);
- label->name = g_strdup (name);
-
- g_free (label->colour);
- label->colour = gdk_color_to_string (color);
-
- return flush_labels_cache (labels, TRUE);
-}
-
-/**
- * e_util_labels_is_system
- *
- * @return Whether the tag is one of default/system labels or not.
- **/
-gboolean
-e_util_labels_is_system (const gchar *tag)
-{
- gint i;
-
- if (!tag)
- return FALSE;
-
- for (i = 0; i < G_N_ELEMENTS (label_defaults); i++) {
- if (strcmp (tag, label_defaults[i].tag) == 0)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * e_util_labels_get_new_tag
- *
- * @param old_tag Tag of the label from old version of Evolution.
- * @return New tag name equivalent with the old tag, or NULL if no such name existed before.
- **/
-const gchar *
-e_util_labels_get_new_tag (const gchar *old_tag)
-{
- gint i;
-
- if (!old_tag)
- return NULL;
-
- for (i = 0; i < G_N_ELEMENTS (label_defaults); i++) {
- /* default labels have same name as those old, only with prefix "$Label" */
- if (!strcmp (old_tag, label_defaults[i].tag + 6))
- return label_defaults[i].tag;
- }
-
- return NULL;
-}
-
-/**
- * e_util_labels_get_name
- *
- * @param labels Cache of labels from call of @ref e_util_labels_parse.
- * The returned pointer will be taken from this list, so it's alive as long as the list.
- * @param tag Tag of the label of our interest.
- * @return Name of the label with that tag or NULL, if no such label exists.
- **/
-const gchar *
-e_util_labels_get_name (GSList *labels, const gchar *tag)
-{
- EUtilLabel *label;
-
- g_return_val_if_fail (tag != NULL, NULL);
-
- label = find_label (labels, tag);
- if (!label)
- return NULL;
-
- return label->name;
-}
-
-/**
- * e_util_labels_get_color
- *
- * @param labels Cache of labels from call of @ref e_util_labels_parse.
- * @param tag Tag of the label of our interest.
- * @param color [out] Actual color of the label with that tag, or unchanged if failed.
- * @return Whether found such label and color has been set.
- **/
-gboolean
-e_util_labels_get_color (GSList *labels, const gchar *tag, GdkColor *color)
-{
- EUtilLabel *label;
-
- g_return_val_if_fail (tag != NULL, FALSE);
- g_return_val_if_fail (color != NULL, FALSE);
-
- label = find_label (labels, tag);
- if (!label)
- return FALSE;
-
- return gdk_color_parse (label->colour, color);
-}
-
-/**
- * e_util_labels_get_color_str
- *
- * @param labels Cache of labels from call of @ref e_util_labels_parse.
- * The returned pointer will be taken from this list, so it's alive as long as the list.
- * @param tag Tag of the label of our interest.
- * @return String representation of that label, or NULL, if no such label exists.
- **/
-const gchar *
-e_util_labels_get_color_str (GSList *labels, const gchar *tag)
-{
- EUtilLabel *label;
-
- g_return_val_if_fail (tag != NULL, NULL);
-
- label = find_label (labels, tag);
- if (!label)
- return NULL;
-
- return label->colour;
-}
-
-/**
- * e_util_labels_get_filter_options:
- * Returns list of newly allocated struct _filter_option-s, to be used in filters.
- **/
-GSList *
-e_util_labels_get_filter_options (void)
-{
- GSList *known = e_util_labels_parse (NULL), *l;
- GSList *res = NULL;
-
- for (l = known; l; l = l->next) {
- EUtilLabel *label = l->data;
- const gchar *tag;
- struct _filter_option *fo;
-
- if (!label)
- continue;
-
- tag = label->tag;
-
- if (tag && strncmp (tag, "$Label", 6) == 0)
- tag += 6;
-
- fo = g_new0 (struct _filter_option, 1);
- fo->title = e_str_without_underscores (label->name);
- fo->value = g_strdup (tag);
-
- res = g_slist_prepend (res, fo);
- }
-
- e_util_labels_free (known);
-
- return g_slist_reverse (res);
-}
diff --git a/e-util/e-util-labels.h b/e-util/e-util-labels.h
deleted file mode 100644
index f0f3ae3bfe..0000000000
--- a/e-util/e-util-labels.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_UTIL_LABELS_H
-#define _E_UTIL_LABELS_H
-
-#include <gtk/gtk.h>
-#include <gconf/gconf-client.h>
-
-typedef struct {
- gchar *tag;
- gchar *name;
- gchar *colour;
-} EUtilLabel;
-
-#define E_UTIL_LABELS_GCONF_KEY "/apps/evolution/mail/labels"
-
-GSList * e_util_labels_parse (struct _GConfClient *client);
-void e_util_labels_free (GSList *labels);
-
-gchar * e_util_labels_add (const gchar *name, const GdkColor *color);
-gchar * e_util_labels_add_with_dlg (GtkWindow *parent, const gchar *tag);
-gboolean e_util_labels_remove (const gchar *tag);
-gboolean e_util_labels_set_data (const gchar *tag, const gchar *name, const GdkColor *color);
-
-gboolean e_util_labels_is_system (const gchar *tag);
-const gchar *e_util_labels_get_new_tag (const gchar *old_tag);
-
-const gchar *e_util_labels_get_name (GSList *labels, const gchar *tag);
-gboolean e_util_labels_get_color (GSList *labels, const gchar *tag, GdkColor *color);
-const gchar *e_util_labels_get_color_str (GSList *labels, const gchar *tag);
-
-GSList * e_util_labels_get_filter_options (void);
-
-#endif /* _E_UTIL_LABELS_H */
diff --git a/e-util/e-util.c b/e-util/e-util.c
index ebd4251b00..57ec251c55 100644
--- a/e-util/e-util.c
+++ b/e-util/e-util.c
@@ -372,6 +372,41 @@ e_action_group_remove_all_actions (GtkActionGroup *action_group)
}
/**
+ * e_radio_action_get_current_action:
+ * @radio_action: a #GtkRadioAction
+ *
+ * Returns the currently active member of the group to which @radio_action
+ * belongs.
+ *
+ * Returns: the currently active group member
+ **/
+GtkRadioAction *
+e_radio_action_get_current_action (GtkRadioAction *radio_action)
+{
+ GSList *group;
+ gint current_value;
+
+ g_return_val_if_fail (GTK_IS_RADIO_ACTION (radio_action), NULL);
+
+ group = gtk_radio_action_get_group (radio_action);
+ current_value = gtk_radio_action_get_current_value (radio_action);
+
+ while (group != NULL) {
+ gint value;
+
+ radio_action = GTK_RADIO_ACTION (group->data);
+ g_object_get (radio_action, "value", &value, NULL);
+
+ if (value == current_value)
+ return radio_action;
+
+ group = g_slist_next (group);
+ }
+
+ return NULL;
+}
+
+/**
* e_str_without_underscores:
* @s: the string to strip underscores from.
*
@@ -521,6 +556,30 @@ e_write_file_uri (const gchar *filename, const gchar *data)
return res;
}
+/**
+ * e_color_to_value:
+ * color: a #GdkColor
+ *
+ * Converts a #GdkColor to a 24-bit RGB color value.
+ *
+ * Returns: a 24-bit color value
+ **/
+guint32
+e_color_to_value (GdkColor *color)
+{
+ guint16 red;
+ guint16 green;
+ guint16 blue;
+
+ g_return_val_if_fail (color != NULL, 0);
+
+ red = color->red >> 8;
+ green = color->green >> 8;
+ blue = color->blue >> 8;
+
+ return (guint32) (((red << 16) | (green << 8) | blue) & 0xffffff);
+}
+
static gint
epow10 (gint number)
{
diff --git a/e-util/e-util.h b/e-util/e-util.h
index ecb389b8b3..33bc940df7 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -57,6 +57,8 @@ gint e_action_compare_by_label (GtkAction *action1,
GtkAction *action2);
void e_action_group_remove_all_actions
(GtkActionGroup *action_group);
+GtkRadioAction *e_radio_action_get_current_action
+ (GtkRadioAction *radio_action);
gchar * e_str_without_underscores (const gchar *s);
gint e_str_compare (gconstpointer x,
@@ -69,6 +71,7 @@ gint e_int_compare (gconstpointer x,
gconstpointer y);
gboolean e_write_file_uri (const gchar *filename,
const gchar *data);
+guint32 e_color_to_value (GdkColor *color);
/* This only makes a filename safe for usage as a filename.
* It still may have shell meta-characters in it. */
@@ -129,7 +132,8 @@ gboolean e_file_lock_create (void);
void e_file_lock_destroy (void);
gboolean e_file_lock_exists (void);
-gchar * e_util_guess_mime_type (const gchar *filename, gboolean localfile);
+gchar * e_util_guess_mime_type (const gchar *filename,
+ gboolean localfile);
gchar * e_util_filename_to_uri (const gchar *filename);
gchar * e_util_uri_to_filename (const gchar *uri);
@@ -138,8 +142,8 @@ gboolean e_util_read_file (const gchar *filename,
gchar **buffer,
gsize *read,
GError **error);
-
-GSList *e_util_get_category_filter_options (void);
+GSList * e_util_get_category_filter_options
+ (void);
/* Camel uses its own object system, so we have to box
* CamelObjects to safely use them as GObject properties. */
diff --git a/e-util/gconf-bridge.c b/e-util/gconf-bridge.c
index 259ad14adc..be2a0cabd7 100644
--- a/e-util/gconf-bridge.c
+++ b/e-util/gconf-bridge.c
@@ -1083,17 +1083,17 @@ gconf_bridge_bind_string_list_store (GConfBridge *bridge,
(list_store_binding_store_changed_cb),
binding);
binding->row_changed_id =
- g_signal_connect_swapped (list_store, "row-inserted",
+ g_signal_connect_swapped (list_store, "row-changed",
G_CALLBACK
(list_store_binding_store_changed_cb),
binding);
binding->row_deleted_id =
- g_signal_connect_swapped (list_store, "row-inserted",
+ g_signal_connect_swapped (list_store, "row-deleted",
G_CALLBACK
(list_store_binding_store_changed_cb),
binding);
binding->rows_reordered_id =
- g_signal_connect_swapped (list_store, "row-inserted",
+ g_signal_connect_swapped (list_store, "rows-reordered",
G_CALLBACK
(list_store_binding_store_changed_cb),
binding);
diff --git a/em-format/Makefile.am b/em-format/Makefile.am
new file mode 100644
index 0000000000..953364482f
--- /dev/null
+++ b/em-format/Makefile.am
@@ -0,0 +1,28 @@
+emformatincludedir = $(privincludedir)/em-format
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ $(EVOLUTION_MAIL_CFLAGS)
+
+privsolib_LTLIBRARIES = libemformat.la
+
+emformatinclude_HEADERS = \
+ em-format.h \
+ em-format-quote.h \
+ em-stripsig-filter.h
+
+libemformat_la_SOURCES = \
+ $(emformatinclude_HEADERS) \
+ em-format.c \
+ em-format-quote.c \
+ em-stripsig-filter.c
+
+libemformat_la_LDFLAGS = $(NO_UNDEFINED)
+
+libemformat_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/shell/libeshell.la \
+ $(EVOLUTION_MAIL_LIBS)
+
+-include $(top_srcdir)/git.mk
diff --git a/mail/em-format-quote.c b/em-format/em-format-quote.c
index af8616a981..88b11c3ac2 100644
--- a/mail/em-format-quote.c
+++ b/em-format/em-format-quote.c
@@ -28,7 +28,6 @@
#include <string.h>
#include <camel/camel-iconv.h>
-#include <camel/camel-stream.h>
#include <camel/camel-stream-filter.h>
#include <camel/camel-mime-filter-tohtml.h>
#include <camel/camel-mime-filter-enriched.h>
@@ -41,7 +40,6 @@
#include "em-stripsig-filter.h"
#include "em-format-quote.h"
-#include "mail-config.h"
struct _EMFormatQuotePrivate {
gint dummy;
@@ -55,82 +53,94 @@ static void emfq_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, c
static void emfq_builtin_init(EMFormatQuoteClass *efhc);
-static EMFormatClass *emfq_parent;
+static gpointer parent_class;
static void
emfq_init(GObject *o)
{
EMFormatQuote *emfq =(EMFormatQuote *) o;
- emfq->priv = g_malloc0(sizeof(*emfq->priv));
-
/* we want to convert url's etc */
emfq->text_html_flags = CAMEL_MIME_FILTER_TOHTML_PRE | CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS
| CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
}
static void
-emfq_finalise(GObject *o)
+emfq_finalize (GObject *object)
{
- EMFormatQuote *emfq =(EMFormatQuote *) o;
+ EMFormatQuote *emfq =(EMFormatQuote *) object;
if (emfq->stream)
camel_object_unref(emfq->stream);
g_free(emfq->credits);
- g_free(emfq->priv);
- ((GObjectClass *) emfq_parent)->finalize(o);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-emfq_base_init(EMFormatQuoteClass *emfqklass)
+emfq_base_init(EMFormatQuoteClass *emfqclass)
{
- emfq_builtin_init(emfqklass);
+ emfq_builtin_init(emfqclass);
}
static void
-emfq_class_init(GObjectClass *klass)
+emfq_class_init (EMFormatQuoteClass *class)
{
- ((EMFormatClass *) klass)->format_clone = emfq_format_clone;
- ((EMFormatClass *) klass)->format_error = emfq_format_error;
- ((EMFormatClass *) klass)->format_source = emfq_format_source;
- ((EMFormatClass *) klass)->format_attachment = emfq_format_attachment;
+ GObjectClass *object_class;
+ EMFormatClass *format_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFormatQuotePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = emfq_finalize;
- klass->finalize = emfq_finalise;
+ format_class = EM_FORMAT_CLASS (class);
+ format_class->format_clone = emfq_format_clone;
+ format_class->format_error = emfq_format_error;
+ format_class->format_source = emfq_format_source;
+ format_class->format_attachment = emfq_format_attachment;
}
GType
-em_format_quote_get_type(void)
+em_format_quote_get_type (void)
{
static GType type = 0;
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFormatQuoteClass),
- (GBaseInitFunc)emfq_base_init, NULL,
- (GClassInitFunc)emfq_class_init,
- NULL, NULL,
- sizeof(EMFormatQuote), 0,
- (GInstanceInitFunc) emfq_init
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFormatQuoteClass),
+ (GBaseInitFunc) emfq_base_init,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) emfq_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFormatQuote),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) emfq_init,
+ NULL /* value_table */
};
- emfq_parent = g_type_class_ref(em_format_get_type());
- type = g_type_register_static(em_format_get_type(), "EMFormatQuote", &info, 0);
+ type = g_type_register_static (
+ EM_TYPE_FORMAT, "EMFormatQuote", &type_info, 0);
}
return type;
}
EMFormatQuote *
-em_format_quote_new(const gchar *credits, CamelStream *stream, guint32 flags)
+em_format_quote_new (const gchar *credits,
+ CamelStream *stream,
+ guint32 flags)
{
EMFormatQuote *emfq;
- emfq = (EMFormatQuote *)g_object_new(em_format_quote_get_type(), NULL);
+ emfq = g_object_new (EM_TYPE_FORMAT_QUOTE, NULL);
- emfq->credits = g_strdup(credits);
+ emfq->credits = g_strdup (credits);
emfq->stream = stream;
- camel_object_ref(stream);
+ camel_object_ref (stream);
emfq->flags = flags;
return emfq;
@@ -147,12 +157,16 @@ emfq_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMim
{
EMFormatQuote *emfq = (EMFormatQuote *) emf;
const EMFormatHandler *handle;
+ GConfClient *gconf;
- ((EMFormatClass *)emfq_parent)->format_clone(emf, folder, uid, msg, src);
+ /* Chain up to parent's format_clone() method. */
+ EM_FORMAT_CLASS (parent_class)->format_clone (emf, folder, uid, msg, src);
+ gconf = gconf_client_get_default ();
camel_stream_reset(emfq->stream);
- if (gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/composer/top_signature", NULL))
+ if (gconf_client_get_bool(gconf, "/apps/evolution/mail/composer/top_signature", NULL))
emfq_format_empty_line(emf, emfq->stream, (CamelMimePart *)msg, NULL);
+ g_object_unref (gconf);
handle = em_format_find_handler(emf, "x-evolution/message/prefix");
if (handle)
handle->handler(emf, emfq->stream, (CamelMimePart *)msg, handle);
diff --git a/mail/em-format-quote.h b/em-format/em-format-quote.h
index be88be5956..5b010e1da5 100644
--- a/mail/em-format-quote.h
+++ b/em-format/em-format-quote.h
@@ -24,7 +24,7 @@
#define EM_FORMAT_QUOTE_H
#include <camel/camel-stream.h>
-#include "mail/em-format.h"
+#include "em-format.h"
/* Standard GObject macros */
#define EM_TYPE_FORMAT_QUOTE \
diff --git a/mail/em-format.c b/em-format/em-format.c
index 1cc6468e55..71cd977b0a 100644
--- a/mail/em-format.c
+++ b/em-format/em-format.c
@@ -32,7 +32,6 @@
#include <gio/gio.h>
#include <libedataserver/e-msgport.h>
-#include <camel/camel-url.h>
#include <camel/camel-stream.h>
#include <camel/camel-stream-mem.h>
#include <camel/camel-multipart.h>
@@ -51,8 +50,9 @@
#include <camel/camel-mime-filter-pgp.h>
#include "em-format.h"
-#include "em-utils.h"
-#include "mail-config.h"
+#include "e-util/e-util.h"
+#include "shell/e-shell.h"
+#include "shell/e-shell-settings.h"
#define d(x)
@@ -85,10 +85,8 @@ enum {
EMF_LAST_SIGNAL
};
-extern CamelSession *session;
-
-static guint emf_signals[EMF_LAST_SIGNAL];
-static GObjectClass *emf_parent;
+static gpointer parent_class;
+static guint signals[EMF_LAST_SIGNAL];
static void
emf_free_cache(struct _EMFormatCache *efc)
@@ -113,32 +111,14 @@ emf_insert_cache(EMFormat *emf, const gchar *partid)
}
static void
-emf_init(GObject *o)
-{
- EMFormat *emf = (EMFormat *)o;
-
- emf->inline_table = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) emf_free_cache);
- emf->composer = FALSE;
- emf->print = FALSE;
- emf->show_photo = TRUE;
- emf->photo_local = TRUE;
- e_dlist_init(&emf->header_list);
- em_format_default_headers(emf);
- emf->part_id = g_string_new("");
-}
-
-static void
-emf_finalise(GObject *o)
+emf_finalize (GObject *object)
{
- EMFormat *emf = (EMFormat *)o;
+ EMFormat *emf = EM_FORMAT (object);
if (emf->session)
- camel_object_unref(emf->session);
+ camel_object_unref (emf->session);
- g_hash_table_destroy(emf->inline_table);
+ g_hash_table_destroy (emf->inline_table);
em_format_clear_headers(emf);
camel_cipher_validity_free(emf->valid);
@@ -148,54 +128,91 @@ emf_finalise(GObject *o)
/* FIXME: check pending jobs */
- ((GObjectClass *)emf_parent)->finalize(o);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+emf_base_init (EMFormatClass *class)
+{
+ class->type_handlers = g_hash_table_new (g_str_hash, g_str_equal);
+ emf_builtin_init (class);
}
static void
-emf_base_init(EMFormatClass *emfklass)
+emf_class_init (EMFormatClass *class)
{
- emfklass->type_handlers = g_hash_table_new(g_str_hash, g_str_equal);
- emf_builtin_init(emfklass);
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = emf_finalize;
+
+ class->find_handler = emf_find_handler;
+ class->format_clone = emf_format_clone;
+ class->format_secure = emf_format_secure;
+ class->busy = emf_busy;
+
+ signals[EMF_COMPLETE] = g_signal_new (
+ "complete",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMFormatClass, complete),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ class->type_handlers = g_hash_table_new (g_str_hash, g_str_equal);
+ emf_builtin_init (class);
}
static void
-emf_class_init(GObjectClass *klass)
+emf_init (EMFormat *emf)
{
- ((EMFormatClass *)klass)->type_handlers = g_hash_table_new(g_str_hash, g_str_equal);
- emf_builtin_init((EMFormatClass *)klass);
-
- klass->finalize = emf_finalise;
- ((EMFormatClass *)klass)->find_handler = emf_find_handler;
- ((EMFormatClass *)klass)->format_clone = emf_format_clone;
- ((EMFormatClass *)klass)->format_secure = emf_format_secure;
- ((EMFormatClass *)klass)->busy = emf_busy;
-
- emf_signals[EMF_COMPLETE] =
- g_signal_new("complete",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFormatClass, complete),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ EShell *shell;
+ EShellSettings *shell_settings;
+
+ emf->inline_table = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) emf_free_cache);
+ emf->composer = FALSE;
+ emf->print = FALSE;
+ e_dlist_init(&emf->header_list);
+ em_format_default_headers(emf);
+ emf->part_id = g_string_new("");
+
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ emf->session = e_shell_settings_get_pointer (shell_settings, "mail-session");
+ g_return_if_fail (emf->session != NULL);
+
+ camel_object_ref (emf->session);
}
GType
-em_format_get_type(void)
+em_format_get_type (void)
{
static GType type = 0;
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFormatClass),
- (GBaseInitFunc)emf_base_init, NULL,
- (GClassInitFunc)emf_class_init,
- NULL, NULL,
- sizeof(EMFormat), 0,
- (GInstanceInitFunc)emf_init
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFormatClass),
+ (GBaseInitFunc) emf_base_init,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) emf_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFormat),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) emf_init,
+ NULL /* value_table */
};
- emf_parent = g_type_class_ref(G_TYPE_OBJECT);
- type = g_type_register_static(G_TYPE_OBJECT, "EMFormat", &info, 0);
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EMFormat", &type_info, 0);
}
return type;
@@ -257,6 +274,7 @@ em_format_merge_handler(EMFormat *new, EMFormat *old)
g_hash_table_foreach (oldc->type_handlers, merge_missing, &fclasses);
}
+
/**
* em_format_class_remove_handler:
* @emfc:
@@ -287,6 +305,20 @@ em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info)
}
}
+const EMFormatHandler *
+em_format_find_handler (EMFormat *emf,
+ const gchar *mime_type)
+{
+ EMFormatClass *class;
+
+ g_return_val_if_fail (EM_IS_FORMAT (emf), NULL);
+ g_return_val_if_fail (mime_type != NULL, NULL);
+
+ class = EM_FORMAT_GET_CLASS (emf);
+ g_return_val_if_fail (class->find_handler != NULL, NULL);
+ return class->find_handler (emf, mime_type);
+}
+
/**
* em_format_find_handler:
* @emf:
@@ -613,7 +645,7 @@ em_format_part_as(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const
if (mime_type != NULL) {
if (g_ascii_strcasecmp(mime_type, "application/octet-stream") == 0) {
- emf->snoop_mime_type = mime_type = em_utils_snoop_type(part);
+ emf->snoop_mime_type = mime_type = em_format_snoop_type(part);
if (mime_type == NULL)
mime_type = "application/octet-stream";
}
@@ -760,10 +792,10 @@ emf_busy(EMFormat *emf)
/**
* em_format_format_clone:
- * @emf: Mail formatter.
- * @folder: Camel Folder.
- * @uid: Uid of message.
- * @msg: Camel Message.
+ * @emf: an #EMFormat
+ * @folder: a #CamelFolder or %NULL
+ * @uid: Message UID or %NULL
+ * @msg: a #CamelMimeMessage or %NULL
* @emfsource: Used as a basis for user-altered layout, e.g. inline viewed
* attachments.
*
@@ -813,25 +845,6 @@ em_format_redraw (EMFormat *emf)
}
/**
- * em_format_set_session:
- * @emf:
- * @s:
- *
- * Set the CamelSession to be used for signature verification and decryption
- * purposes. If this is not set, then signatures cannot be verified or
- * encrypted messages viewed.
- **/
-void
-em_format_set_session(EMFormat *emf, CamelSession *s)
-{
- if (s)
- camel_object_ref(s);
- if (emf->session)
- camel_object_unref(emf->session);
- emf->session = s;
-}
-
-/**
* em_format_set_mode:
* @emf:
* @type:
@@ -1071,28 +1084,101 @@ void em_format_set_inline(EMFormat *emf, const gchar *partid, gint state)
em_format_redraw(emf);
}
-void em_format_format_error(EMFormat *emf, CamelStream *stream, const gchar *fmt, ...)
+void
+em_format_format_attachment (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *mime_part,
+ const gchar *mime_type,
+ const struct _EMFormatHandler *info)
{
+ EMFormatClass *class;
+
+ g_return_if_fail (EM_IS_FORMAT (emf));
+ g_return_if_fail (CAMEL_IS_STREAM (stream));
+ g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
+ g_return_if_fail (mime_type != NULL);
+ g_return_if_fail (info != NULL);
+
+ class = EM_FORMAT_GET_CLASS (emf);
+ g_return_if_fail (class->format_attachment != NULL);
+ class->format_attachment (emf, stream, mime_part, mime_type, info);
+}
+
+void
+em_format_format_error (EMFormat *emf,
+ CamelStream *stream,
+ const gchar *format,
+ ...)
+{
+ EMFormatClass *class;
+ gchar *errmsg;
va_list ap;
- gchar *txt;
- va_start(ap, fmt);
- txt = g_strdup_vprintf(fmt, ap);
- ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_error((emf), (stream), (txt));
- g_free(txt);
+ g_return_if_fail (EM_IS_FORMAT (emf));
+ g_return_if_fail (CAMEL_IS_STREAM (stream));
+ g_return_if_fail (format != NULL);
+
+ class = EM_FORMAT_GET_CLASS (emf);
+ g_return_if_fail (class->format_error != NULL);
+
+ va_start (ap, format);
+ errmsg = g_strdup_vprintf (format, ap);
+ class->format_error (emf, stream, errmsg);
+ g_free (errmsg);
+ va_end (ap);
}
void
-em_format_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
+em_format_format_secure (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *mime_part,
+ CamelCipherValidity *valid)
{
- ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_secure(emf, stream, part, valid);
+ EMFormatClass *class;
+
+ g_return_if_fail (EM_IS_FORMAT (emf));
+ g_return_if_fail (CAMEL_IS_STREAM (stream));
+ g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
+ g_return_if_fail (valid != NULL);
+
+ class = EM_FORMAT_GET_CLASS (emf);
+ g_return_if_fail (class->format_secure != NULL);
+ class->format_secure (emf, stream, mime_part, valid);
if (emf->valid_parent == NULL && emf->valid != NULL) {
- camel_cipher_validity_free(emf->valid);
+ camel_cipher_validity_free (emf->valid);
emf->valid = NULL;
}
}
+void
+em_format_format_source (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *mime_part)
+{
+ EMFormatClass *class;
+
+ g_return_if_fail (EM_IS_FORMAT (emf));
+ g_return_if_fail (CAMEL_IS_STREAM (stream));
+ g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
+
+ class = EM_FORMAT_GET_CLASS (emf);
+ g_return_if_fail (class->format_source != NULL);
+ class->format_source (emf, stream, mime_part);
+}
+
+gboolean
+em_format_busy (EMFormat *emf)
+{
+ EMFormatClass *class;
+
+ g_return_val_if_fail (EM_IS_FORMAT (emf), FALSE);
+
+ class = EM_FORMAT_GET_CLASS (emf);
+ g_return_val_if_fail (class->busy != NULL, FALSE);
+ return class->busy (emf);
+}
+
/* should this be virtual? */
void
em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part)
@@ -1123,6 +1209,7 @@ em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *dw)
CamelStream *mem_stream = NULL;
gsize size;
gsize max;
+ GConfClient *gconf;
if (emf->charset) {
charset = emf->charset;
@@ -1160,7 +1247,16 @@ em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *dw)
camel_object_unref(filter);
}
- max = mail_config_get_message_limit();
+ max = -1;
+
+ gconf = gconf_client_get_default ();
+ if (gconf_client_get_bool (gconf, "/apps/evolution/mail/display/force_message_limit", NULL)) {
+ max = gconf_client_get_int (gconf, "/apps/evolution/mail/display/message_text_part_limit", NULL);
+ if (max == 0)
+ max = -1;
+ }
+ g_object_unref (gconf);
+
size = camel_data_wrapper_decode_to_stream(emf->mode == EM_FORMAT_SOURCE ? (CamelDataWrapper *)dw: camel_medium_get_content_object((CamelMedium *)dw), (CamelStream *)filter_stream);
camel_stream_flush((CamelStream *)filter_stream);
camel_object_unref(filter_stream);
@@ -1231,7 +1327,7 @@ emf_application_xpkcs7mime(EMFormat *emf, CamelStream *stream, CamelMimePart *pa
ex = camel_exception_new();
- context = camel_smime_context_new(session);
+ context = camel_smime_context_new(emf->session);
opart = camel_mime_part_new();
valid = camel_cipher_decrypt(context, part, opart, ex);
@@ -1405,7 +1501,7 @@ emf_multipart_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
em_format_format_secure(emf, stream, opart, valid);
}
- /* TODO: Make sure when we finalise this part, it is zero'd out */
+ /* TODO: Make sure when we finalize this part, it is zero'd out */
camel_object_unref(opart);
camel_object_unref(context);
camel_exception_free(ex);
@@ -1785,7 +1881,7 @@ emf_inlinepgp_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart
/* this ensures to show the 'opart' as inlined, if possible */
if (mime_type && g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0) {
- const gchar *snoop = em_utils_snoop_type (opart);
+ const gchar *snoop = em_format_snoop_type (opart);
if (snoop)
camel_data_wrapper_set_mime_type (dw, snoop);
@@ -1830,10 +1926,91 @@ static EMFormatHandler type_builtin_table[] = {
};
static void
-emf_builtin_init(EMFormatClass *klass)
+emf_builtin_init(EMFormatClass *class)
{
gint i;
for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++)
- g_hash_table_insert(klass->type_handlers, (gpointer) type_builtin_table[i].mime_type, &type_builtin_table[i]);
+ g_hash_table_insert(class->type_handlers, type_builtin_table[i].mime_type, &type_builtin_table[i]);
+}
+
+/**
+ * em_format_snoop_type:
+ * @part:
+ *
+ * Tries to snoop the mime type of a part.
+ *
+ * Return value: NULL if unknown (more likely application/octet-stream).
+ **/
+const gchar *
+em_format_snoop_type (CamelMimePart *part)
+{
+ /* cache is here only to be able still return const gchar * */
+ static GHashTable *types_cache = NULL;
+
+ const gchar *filename;
+ gchar *name_type = NULL, *magic_type = NULL, *res, *tmp;
+ CamelDataWrapper *dw;
+
+ filename = camel_mime_part_get_filename (part);
+ if (filename != NULL)
+ name_type = e_util_guess_mime_type (filename, FALSE);
+
+ dw = camel_medium_get_content_object((CamelMedium *)part);
+ if (!camel_data_wrapper_is_offline(dw)) {
+ CamelStreamMem *mem = (CamelStreamMem *)camel_stream_mem_new();
+
+ if (camel_data_wrapper_decode_to_stream(dw, (CamelStream *)mem) > 0) {
+ gchar *ct = g_content_type_guess (filename, mem->buffer->data, mem->buffer->len, NULL);
+
+ if (ct)
+ magic_type = g_content_type_get_mime_type (ct);
+
+ g_free (ct);
+ }
+ camel_object_unref(mem);
+ }
+
+ d(printf("snooped part, magic_type '%s' name_type '%s'\n", magic_type, name_type));
+
+ /* If gvfs doesn't recognize the data by magic, but it
+ * contains English words, it will call it text/plain. If the
+ * filename-based check came up with something different, use
+ * that instead and if it returns "application/octet-stream"
+ * try to do better with the filename check.
+ */
+
+ if (magic_type) {
+ if (name_type
+ && (!strcmp(magic_type, "text/plain")
+ || !strcmp(magic_type, "application/octet-stream")))
+ res = name_type;
+ else
+ res = magic_type;
+ } else
+ res = name_type;
+
+ if (res != name_type)
+ g_free (name_type);
+
+ if (res != magic_type)
+ g_free (magic_type);
+
+ if (!types_cache)
+ types_cache = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) NULL);
+
+ if (res) {
+ tmp = g_hash_table_lookup (types_cache, res);
+ if (tmp) {
+ g_free (res);
+ res = tmp;
+ } else {
+ g_hash_table_insert (types_cache, res, res);
+ }
+ }
+
+ return res;
+
+ /* We used to load parts to check their type, we dont anymore,
+ see bug #11778 for some discussion */
}
diff --git a/mail/em-format.h b/em-format/em-format.h
index b3af1e8c3c..7e59ecf462 100644
--- a/mail/em-format.h
+++ b/em-format/em-format.h
@@ -248,8 +248,6 @@ struct _EMFormat {
gchar *default_charset; /* charset fallback */
gboolean composer; /* Formatting from composer ?*/
gboolean print;
- gboolean show_photo; /* Want to show the photo of the sender ?*/
- gboolean photo_local; /* Photos only from local addressbooks */
};
struct _EMFormatClass {
@@ -285,63 +283,119 @@ struct _EMFormatClass {
void (*complete)(EMFormat *);
};
-/* helper entry point */
-void em_format_set_session(EMFormat *emf, CamelSession *s);
+void em_format_set_mode (EMFormat *emf,
+ em_format_mode_t type);
+void em_format_set_charset (EMFormat *emf,
+ const gchar *charset);
+void em_format_set_default_charset (EMFormat *emf,
+ const gchar *charset);
-void em_format_set_mode(EMFormat *emf, em_format_mode_t type);
-void em_format_set_charset(EMFormat *emf, const gchar *charset);
-void em_format_set_default_charset(EMFormat *emf, const gchar *charset);
+/* also indicates to show all headers */
+void em_format_clear_headers (EMFormat *emf);
-void em_format_clear_headers(EMFormat *emf); /* also indicates to show all headers */
-void em_format_default_headers(EMFormat *emf);
-void em_format_add_header(EMFormat *emf, const gchar *name, guint32 flags);
+void em_format_default_headers (EMFormat *emf);
+void em_format_add_header (EMFormat *emf,
+ const gchar *name,
+ guint32 flags);
/* FIXME: Need a 'clone' api to copy details about the current view (inlines etc)
Or maybe it should live with sub-classes? */
-gint em_format_is_attachment(EMFormat *emf, CamelMimePart *part);
+gint em_format_is_attachment (EMFormat *emf,
+ CamelMimePart *part);
-gint em_format_is_inline(EMFormat *emf, const gchar *partid, CamelMimePart *part, const EMFormatHandler *handle);
-void em_format_set_inline(EMFormat *emf, const gchar *partid, gint state);
+gint em_format_is_inline (EMFormat *emf,
+ const gchar *partid,
+ CamelMimePart *part,
+ const EMFormatHandler *handle);
+void em_format_set_inline (EMFormat *emf,
+ const gchar *partid,
+ gint state);
-gchar *em_format_describe_part(CamelMimePart *part, const gchar *mimetype);
+gchar * em_format_describe_part (CamelMimePart *part,
+ const gchar *mime_type);
/* for implementers */
-GType em_format_get_type(void);
-
-void em_format_class_add_handler(EMFormatClass *emfc, EMFormatHandler *info);
-void em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info);
-#define em_format_find_handler(emf, type) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->find_handler((emf), (type))
-const EMFormatHandler *em_format_fallback_handler(EMFormat *emf, const gchar *mime_type);
+GType em_format_get_type (void);
+
+void em_format_class_add_handler (EMFormatClass *emfc,
+ EMFormatHandler *info);
+void em_format_class_remove_handler (EMFormatClass *emfc,
+ EMFormatHandler *info);
+const EMFormatHandler *
+ em_format_find_handler (EMFormat *emf,
+ const gchar *mime_type);
+const EMFormatHandler *
+ em_format_fallback_handler (EMFormat *emf,
+ const gchar *mime_type);
/* puri is short for pending uri ... really */
-EMFormatPURI *em_format_add_puri(EMFormat *emf, gsize size, const gchar *uri, CamelMimePart *part, EMFormatPURIFunc func);
-EMFormatPURI *em_format_find_visible_puri(EMFormat *emf, const gchar *uri);
-EMFormatPURI *em_format_find_puri(EMFormat *emf, const gchar *uri);
-void em_format_clear_puri_tree(EMFormat *emf);
-void em_format_push_level(EMFormat *emf);
-void em_format_pull_level(EMFormat *emf);
+EMFormatPURI * em_format_add_puri (EMFormat *emf,
+ gsize size,
+ const gchar *uri,
+ CamelMimePart *part,
+ EMFormatPURIFunc func);
+EMFormatPURI * em_format_find_visible_puri (EMFormat *emf,
+ const gchar *uri);
+EMFormatPURI * em_format_find_puri (EMFormat *emf,
+ const gchar *uri);
+void em_format_clear_puri_tree (EMFormat *emf);
+void em_format_push_level (EMFormat *emf);
+void em_format_pull_level (EMFormat *emf);
/* clones inline state/view and format, or use to redraw */
-void em_format_format_clone (EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *message, EMFormat *source);
-/* formats a new message */
-void em_format_format(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *message);
-void em_format_redraw(EMFormat *emf);
-void em_format_format_error(EMFormat *emf, CamelStream *stream, const gchar *fmt, ...);
-#define em_format_format_attachment(emf, stream, msg, type, info) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_attachment((emf), (stream), (msg), (type), (info))
-#define em_format_format_source(emf, stream, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_source((emf), (stream), (msg))
-void em_format_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
+void em_format_format_clone (EMFormat *emf,
+ CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *message,
+ EMFormat *source);
-#define em_format_busy(emf) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->busy((emf))
+/* formats a new message */
+void em_format_format (EMFormat *emf,
+ CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *message);
+void em_format_redraw (EMFormat *emf);
+void em_format_format_attachment (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *mime_part,
+ const gchar *mime_type,
+ const struct _EMFormatHandler *info);
+void em_format_format_error (EMFormat *emf,
+ CamelStream *stream,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (3, 4);
+void em_format_format_secure (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *mime_part,
+ CamelCipherValidity *valid);
+void em_format_format_source (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *mime_part);
+
+gboolean em_format_busy (EMFormat *emf);
/* raw content only */
-void em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part);
-/* raw content text parts - should this just be checked/done by above? */
-void em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *part);
+void em_format_format_content (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part);
-void em_format_part_as(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type);
-void em_format_part(EMFormat *emf, CamelStream *stream, CamelMimePart *part);
-void em_format_merge_handler(EMFormat *new, EMFormat *old);
+/* raw content text parts - should this just be checked/done by above? */
+void em_format_format_text (EMFormat *emf,
+ CamelStream *stream,
+ CamelDataWrapper *part);
+
+void em_format_part_as (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part,
+ const gchar *mime_type);
+void em_format_part (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part);
+void em_format_merge_handler (EMFormat *new,
+ EMFormat *old);
+
+const gchar * em_format_snoop_type (CamelMimePart *part);
G_END_DECLS
diff --git a/mail/em-stripsig-filter.c b/em-format/em-stripsig-filter.c
index 42d824778b..42d824778b 100644
--- a/mail/em-stripsig-filter.c
+++ b/em-format/em-stripsig-filter.c
diff --git a/mail/em-stripsig-filter.h b/em-format/em-stripsig-filter.h
index 39493e5e88..39493e5e88 100644
--- a/mail/em-stripsig-filter.h
+++ b/em-format/em-stripsig-filter.h
diff --git a/evolution-plugin.pc.in b/evolution-plugin.pc.in
index a1bb7728ed..ac2d40f78d 100644
--- a/evolution-plugin.pc.in
+++ b/evolution-plugin.pc.in
@@ -15,6 +15,6 @@ errordir=@privdatadir@/errors
Name: evolution-plugin
Description: libraries needed for Evolution plugin development
Version: @VERSION@
-Requires: libgnome-2.0 libgnomeui-2.0 libbonoboui-2.0 >= @BONOBOUI_REQUIRED@ camel-provider-1.2 libxml-2.0
+Requires: libgnome-2.0 libgnomeui-2.0 camel-provider-1.2 libxml-2.0
Libs: -L${privlibdir} -leutil -Wl,-R${privlibdir}
Cflags: -I${privincludedir}
diff --git a/evolution-shell.pc.in b/evolution-shell.pc.in
index fb72dfebab..b94dd8512f 100644
--- a/evolution-shell.pc.in
+++ b/evolution-shell.pc.in
@@ -11,6 +11,7 @@ privlibexecdir=@privlibexecdir@
privincludedir=@privincludedir@
idldir=@idldir@
componentdir=@componentdir@
+moduledir=@moduledir@
evolutionuidir=@evolutionuidir@
imagesdir=@imagesdir@
@@ -21,6 +22,6 @@ IDL_INCLUDES=-I ${idldir} @IDL_INCLUDES@
Name: evolution-shell
Description: libraries needed for Evolution shell components
Version: @VERSION@
-Requires: libgnome-2.0 libgnomeui-2.0 libbonoboui-2.0 >= @BONOBOUI_REQUIRED@
+Requires: libgnome-2.0 libgnomeui-2.0 unique-1.0
Libs: -L${privlibdir} -leshell -Wl,-R${privlibdir}
Cflags: -I${privincludedir}
diff --git a/filter/Makefile.am b/filter/Makefile.am
index ea996c839f..0a94811d46 100644
--- a/filter/Makefile.am
+++ b/filter/Makefile.am
@@ -4,7 +4,6 @@ glade_DATA = filter.glade
AM_CPPFLAGS = \
-I $(top_srcdir) \
-I $(top_srcdir)/e-util \
- -I $(top_srcdir)/widgets/misc \
-DEVOLUTION_GLADEDIR=\"$(gladedir)\" \
-DG_LOG_DOMAIN=\"filter\" \
$(LIBFILTER_CFLAGS)
diff --git a/filter/filter-datespec.c b/filter/filter-datespec.c
index 4989fc59b8..fcfc877dc0 100644
--- a/filter/filter-datespec.c
+++ b/filter/filter-datespec.c
@@ -69,33 +69,27 @@ typedef struct _timespan {
gfloat max;
} timespan;
-#if 0
-ngettext("1 second ago", "%d seconds ago")
-ngettext("1 second in the future", "%d seconds in the future")
-ngettext("1 minute ago", "%d minutes ago")
-ngettext("1 minute in the future", "%d minutes in the future")
-ngettext("1 hour ago", "%d hours ago")
-ngettext("1 hour in the future", "%d hours in the future")
-ngettext("1 day ago", "%d days ago")
-ngettext("1 day in the future", "%d days in the future")
-ngettext("1 week ago", "%d weeks ago")
-ngettext("1 week in the future", "%d weeks in the future")
-ngettext("1 month ago", "%d months ago")
-ngettext("1 month in the future", "%d months in the future")
-ngettext("1 year ago", "%d years ago")
-ngettext("1 year in the future", "%d years in the future")
+#ifdef ngettext
+#undef ngettext
#endif
+/* This is a nasty hack trying to keep both ngettext function and xgettext tool happy */
+/* It *will* cause problems if ngettext is a macro */
+#define ngettext(a, b) a, b
+
static const timespan timespans[] = {
- { 1, "1 second ago", "%d seconds ago", "1 second in the future", "%d seconds in the future", 59.0 },
- { 60, "1 minute ago", "%d minutes ago", "1 minute in the future", "%d minutes in the future", 59.0 },
- { 3600, "1 hour ago", "%d hours ago", "1 hour in the future", "%d hours in the future", 23.0 },
- { 86400, "1 day ago", "%d days ago", "1 day in the future", "%d days in the future", 31.0 },
- { 604800, "1 week ago", "%d weeks ago", "1 week in the future", "%d weeks in the future", 52.0 },
- { 2419200, "1 month ago", "%d months ago", "1 month in the future", "%d months in the future", 12.0 },
- { 31557600, "1 year ago", "%d years ago", "1 year in the future", "%d years in the future", 1000.0 },
+ { 1, ngettext("1 second ago", "%d seconds ago"), ngettext("1 second in the future", "%d seconds in the future"), 59.0 },
+ { 60, ngettext("1 minute ago", "%d minutes ago"), ngettext("1 minute in the future", "%d minutes in the future"), 59.0 },
+ { 3600, ngettext("1 hour ago", "%d hours ago"), ngettext("1 hour in the future", "%d hours in the future"), 23.0 },
+ { 86400, ngettext("1 day ago", "%d days ago"), ngettext("1 day in the future", "%d days in the future"), 31.0 },
+ { 604800, ngettext("1 week ago", "%d weeks ago"), ngettext("1 week in the future", "%d weeks in the future"), 52.0 },
+ { 2419200, ngettext("1 month ago", "%d months ago"), ngettext("1 month in the future", "%d months in the future"), 12.0 },
+ { 31557600, ngettext("1 year ago", "%d years ago"), ngettext("1 year in the future", "%d years in the future"), 1000.0 },
};
+/* now we let the compiler see the real function call */
+#undef ngettext
+
#define DAY_INDEX 3
#define N_TIMESPANS (sizeof (timespans) / sizeof (timespans[0]))
@@ -432,6 +426,7 @@ static void
button_clicked (GtkButton *button, FilterDatespec *fds)
{
struct _FilterDatespecPrivate *p = PRIV(fds);
+ GtkWidget *content_area;
GtkWidget *toplevel;
GtkDialog *dialog;
GladeXML *gui;
@@ -464,7 +459,8 @@ button_clicked (GtkButton *button, FilterDatespec *fds)
g_signal_connect (p->combobox_relative, "changed", G_CALLBACK (set_combobox_relative), fds);
g_signal_connect (p->combobox_past_future, "changed", G_CALLBACK (set_combobox_past_future), fds);
- gtk_box_pack_start ((GtkBox *) dialog->vbox, toplevel, TRUE, TRUE, 3);
+ content_area = gtk_dialog_get_content_area (dialog);
+ gtk_box_pack_start (GTK_BOX (content_area), toplevel, TRUE, TRUE, 3);
if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK) {
get_values (fds);
diff --git a/filter/filter-rule.c b/filter/filter-rule.c
index 354d276fe8..7d28881fb4 100644
--- a/filter/filter-rule.c
+++ b/filter/filter-rule.c
@@ -807,8 +807,12 @@ more_parts (GtkWidget *button, struct _rule_data *data)
GtkAdjustment *adjustment;
adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (w));
- if (adjustment)
- gtk_adjustment_set_value (adjustment, adjustment->upper);
+ if (adjustment) {
+ gdouble upper;
+
+ upper = gtk_adjustment_get_upper (adjustment);
+ gtk_adjustment_set_value (adjustment, upper);
+ }
}
}
diff --git a/filter/rule-context.c b/filter/rule-context.c
index 84cf2e4e92..b6e7df47de 100644
--- a/filter/rule-context.c
+++ b/filter/rule-context.c
@@ -711,6 +711,7 @@ rule_context_add_rule_gui(RuleContext *rc, FilterRule *rule, const gchar *title,
{
GtkDialog *dialog;
GtkWidget *widget;
+ GtkWidget *content_area;
d(printf("add rule gui '%s'\n", rule->name));
@@ -731,7 +732,8 @@ rule_context_add_rule_gui(RuleContext *rc, FilterRule *rule, const gchar *title,
gtk_window_set_default_size((GtkWindow *) dialog, 600, 400);
gtk_window_set_resizable((GtkWindow *) dialog, TRUE);
- gtk_box_pack_start((GtkBox *) dialog->vbox, widget, TRUE, TRUE, 0);
+ content_area = gtk_dialog_get_content_area (dialog);
+ gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0);
g_object_set_data_full((GObject *) dialog, "rule", rule, g_object_unref);
if (path)
diff --git a/filter/rule-editor.c b/filter/rule-editor.c
index 59006f7597..7a9335990f 100644
--- a/filter/rule-editor.c
+++ b/filter/rule-editor.c
@@ -363,6 +363,7 @@ static void
rule_add (GtkWidget *widget, RuleEditor *re)
{
GtkWidget *rules;
+ GtkWidget *content_area;
if (re->edit != NULL)
return;
@@ -384,7 +385,8 @@ rule_add (GtkWidget *widget, RuleEditor *re)
gtk_window_set_transient_for ((GtkWindow *) re->dialog, (GtkWindow *) re);
gtk_container_set_border_width ((GtkContainer *) re->dialog, 6);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (re->dialog)->vbox), rules, TRUE, TRUE, 3);
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (re->dialog));
+ gtk_box_pack_start (GTK_BOX (content_area), rules, TRUE, TRUE, 3);
g_signal_connect (re->dialog, "response", G_CALLBACK (add_editor_response), re);
g_object_weak_ref ((GObject *) re->dialog, (GWeakNotify) editor_destroy, re);
@@ -442,6 +444,7 @@ static void
rule_edit (GtkWidget *widget, RuleEditor *re)
{
GtkWidget *rules;
+ GtkWidget *content_area;
update_selected_rule(re);
@@ -465,7 +468,8 @@ rule_edit (GtkWidget *widget, RuleEditor *re)
gtk_widget_set_parent_window (GTK_WIDGET (re->dialog), GTK_WIDGET (re)->window);
gtk_container_set_border_width ((GtkContainer *) re->dialog, 6);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (re->dialog)->vbox), rules, TRUE, TRUE, 3);
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (re->dialog));
+ gtk_box_pack_start (GTK_BOX (content_area), rules, TRUE, TRUE, 3);
g_signal_connect (re->dialog, "response", G_CALLBACK (edit_editor_response), re);
g_object_weak_ref ((GObject *) re->dialog, (GWeakNotify) editor_destroy, re);
@@ -828,19 +832,24 @@ void
rule_editor_construct (RuleEditor *re, RuleContext *context, GladeXML *gui, const gchar *source, const gchar *label)
{
GtkWidget *w;
+ GtkWidget *action_area;
+ GtkWidget *content_area;
gint i;
gchar *tmp;
re->context = context;
g_object_ref (context);
+ action_area = gtk_dialog_get_action_area (GTK_DIALOG (re));
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (re));
+
gtk_window_set_resizable ((GtkWindow *) re, TRUE);
gtk_window_set_default_size ((GtkWindow *) re, 350, 400);
gtk_widget_realize ((GtkWidget *) re);
- gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *) re)->action_area, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
w = glade_xml_get_widget(gui, "rule_editor");
- gtk_box_pack_start((GtkBox *)((GtkDialog *)re)->vbox, w, TRUE, TRUE, 3);
+ gtk_box_pack_start (GTK_BOX (content_area), w, TRUE, TRUE, 3);
for (i = 0; i < BUTTON_LAST; i++) {
re->priv->buttons[i] = (GtkButton *) (w = glade_xml_get_widget (gui, edit_buttons[i].name));
diff --git a/m4/Makefile.am b/m4/Makefile.am
new file mode 100644
index 0000000000..ae44c94bff
--- /dev/null
+++ b/m4/Makefile.am
@@ -0,0 +1 @@
+-include $(top_srcdir)/git.mk
diff --git a/mail/Makefile.am b/mail/Makefile.am
index f8277aa9e0..043ffeebed 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = default importers
+SUBDIRS = . default importers
mailincludedir = $(privincludedir)/mail
@@ -6,6 +6,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/widgets \
-I$(top_srcdir)/widgets/misc \
-I$(top_srcdir) \
+ -I$(top_srcdir)/em-format \
-I$(top_srcdir)/mail \
-I$(top_srcdir)/composer \
-I$(top_builddir)/composer \
@@ -16,6 +17,7 @@ AM_CPPFLAGS = \
$(EVOLUTION_MAIL_CFLAGS) \
$(CERT_UI_CFLAGS) \
$(THREADS_CFLAGS) \
+ $(CANBERRA_CFLAGS) \
-DEVOLUTION_DATADIR=\""$(datadir)"\" \
-DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
@@ -30,257 +32,146 @@ AM_CPPFLAGS = \
-DPREFIX=\""$(prefix)"\" \
-DG_LOG_DOMAIN=\"evolution-mail\"
-privsolib_LTLIBRARIES = libevolution-mail-shared.la
-component_LTLIBRARIES = libevolution-mail.la
-
-# Mail.idl
-MAIL_IDL = Evolution-Mail.idl
-MAIL_IDL_GENERATED_H = \
- Evolution-Mail.h
-MAIL_IDL_GENERATED_C = \
- Evolution-Mail-common.c \
- Evolution-Mail-skels.c \
- Evolution-Mail-stubs.c
-MAIL_IDL_GENERATED = $(MAIL_IDL_GENERATED_C) $(MAIL_IDL_GENERATED_H)
-
-$(MAIL_IDL_GENERATED_H): $(MAIL_IDL)
- $(ORBIT_IDL) -I $(top_srcdir) -I $(datadir)/idl $(IDL_INCLUDES) $^
-$(MAIL_IDL_GENERATED_C): $(MAIL_IDL_GENERATED_H)
-
-# IDL install
-
-idl_DATA = $(MAIL_IDL)
-
-# plugin mail api
-mailinclude_HEADERS = \
- $(MAIL_IDL_GENERATED_H) \
- e-mail-attachment-bar.h \
- e-searching-tokenizer.h \
- em-account-editor.h \
- e-mail-search-bar.h \
- em-composer-utils.h \
- em-config.h \
- em-event.h \
- em-filter-context.h \
- em-filter-editor.h \
- em-filter-folder-element.h \
- em-filter-rule.h \
- em-filter-source-element.h \
- em-folder-browser.h \
- em-folder-tree-model.h \
- em-folder-tree.h \
- em-folder-utils.h \
- em-folder-view.h \
- em-format-hook.h \
- em-format-html-display.h \
- em-format-html-print.h \
- em-format-html.h \
- em-format-quote.h \
- em-format.h \
- em-html-stream.h \
- em-icon-stream.h \
- em-inline-filter.h \
- em-junk-hook.h \
- em-menu.h \
- em-message-browser.h \
- em-popup.h \
- em-search-context.h \
- em-stripsig-filter.h \
- em-sync-stream.h \
- em-utils.h \
- mail-autofilter.h \
- mail-component.h \
- mail-config.h \
- mail-folder-cache.h \
- mail-mt.h \
- mail-ops.h \
- mail-send-recv.h \
- mail-session.h \
- mail-tools.h \
- message-list.h \
- mail-vfolder.h
+privsolib_LTLIBRARIES = libevolution-mail.la
+
+mailinclude_HEADERS = \
+ e-mail-attachment-bar.h \
+ e-mail-browser.h \
+ e-mail-display.h \
+ e-mail-label-dialog.h \
+ e-mail-label-list-store.h \
+ e-mail-label-manager.h \
+ e-mail-label-tree-view.h \
+ e-mail-local.h \
+ e-mail-reader.h \
+ e-mail-reader-utils.h \
+ e-mail-search-bar.h \
+ e-mail-store.h \
+ e-searching-tokenizer.h \
+ em-account-editor.h \
+ em-composer-utils.h \
+ em-config.h \
+ em-event.h \
+ em-filter-context.h \
+ em-filter-editor.h \
+ em-filter-folder-element.h \
+ em-filter-rule.h \
+ em-filter-source-element.h \
+ em-folder-properties.h \
+ em-folder-selection.h \
+ em-folder-selector.h \
+ em-folder-selection-button.h \
+ em-folder-tree.h \
+ em-folder-tree-model.h \
+ em-folder-utils.h \
+ em-format-hook.h \
+ em-format-html.h \
+ em-format-html-display.h \
+ em-format-html-print.h \
+ em-html-stream.h \
+ em-icon-stream.h \
+ em-inline-filter.h \
+ em-junk.h \
+ em-search-context.h \
+ em-subscribe-editor.h \
+ em-sync-stream.h \
+ em-utils.h \
+ em-vfolder-context.h \
+ em-vfolder-editor.h \
+ em-vfolder-rule.h \
+ mail-autofilter.h \
+ mail-config.h \
+ mail-folder-cache.h \
+ mail-mt.h \
+ mail-ops.h \
+ mail-send-recv.h \
+ mail-session.h \
+ mail-tools.h \
+ mail-vfolder.h \
+ message-list.h \
+ message-tag-editor.h \
+ message-tag-followup.h
-# libevolution-mail
+libevolution_mail_la_SOURCES = \
+ e-mail-attachment-bar.c \
+ e-mail-browser.c \
+ e-mail-display.c \
+ e-mail-label-dialog.c \
+ e-mail-label-list-store.c \
+ e-mail-label-manager.c \
+ e-mail-label-tree-view.c \
+ e-mail-local.c \
+ e-mail-reader.c \
+ e-mail-reader-utils.c \
+ e-mail-search-bar.c \
+ e-mail-store.c \
+ e-searching-tokenizer.c \
+ em-account-editor.c \
+ em-composer-utils.c \
+ em-config.c \
+ em-event.c \
+ em-filter-context.c \
+ em-filter-editor.c \
+ em-filter-folder-element.c \
+ em-filter-rule.c \
+ em-filter-source-element.c \
+ em-folder-properties.c \
+ em-folder-selection.c \
+ em-folder-selector.c \
+ em-folder-selection-button.c \
+ em-folder-tree.c \
+ em-folder-tree-model.c \
+ em-folder-utils.c \
+ em-format-hook.c \
+ em-format-html.c \
+ em-format-html-display.c \
+ em-format-html-print.c \
+ em-html-stream.c \
+ em-icon-stream.c \
+ em-inline-filter.c \
+ em-junk.c \
+ em-search-context.c \
+ em-subscribe-editor.c \
+ em-sync-stream.c \
+ em-utils.c \
+ em-vfolder-context.c \
+ em-vfolder-editor.c \
+ em-vfolder-rule.c \
+ mail-autofilter.c \
+ mail-config.c \
+ mail-folder-cache.c \
+ mail-mt.c \
+ mail-ops.c \
+ mail-send-recv.c \
+ mail-session.c \
+ mail-tools.c \
+ mail-vfolder.c \
+ message-list.c \
+ message-tag-editor.c \
+ message-tag-followup.c
-libevolution_mail_la_SOURCES = \
- $(MAIL_IDL_GENERATED) \
- $(mailinclude_HEADERS) \
- e-searching-tokenizer.c \
- em-account-prefs.c \
- em-account-prefs.h \
- em-composer-prefs.c \
- em-composer-prefs.h \
- em-folder-browser.c \
- em-folder-view.c \
- em-format-hook.c \
- em-format-html-display.c \
- em-format-html-print.c \
- em-format-html.c \
- em-html-stream.c \
- em-junk-hook.c \
- em-mailer-prefs.c \
- em-mailer-prefs.h \
- em-menu.c \
- em-message-browser.c \
- em-migrate.c \
- em-migrate.h \
- em-network-prefs.c \
- em-network-prefs.h \
- em-subscribe-editor.c \
- em-subscribe-editor.h \
- mail-component-factory.c \
- mail-component.c \
- mail-config-factory.c \
- mail-config-factory.h \
- mail-signature-editor.c \
- mail-signature-editor.h \
- mail-types.h \
- message-list.c
if ENABLE_SMIME
-SMIME_LIBS = \
+SMIME_LIBS = \
$(top_builddir)/smime/lib/libessmime.la \
$(top_builddir)/smime/gui/libevolution-smime.la
endif
-libevolution_mail_la_LIBADD = \
- $(top_builddir)/mail/libevolution-mail-shared.la \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/shell/libeshell.la \
- $(top_builddir)/widgets/table/libetable.la \
- $(top_builddir)/widgets/text/libetext.la \
- $(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/widgets/misc/libefilterbar.la \
- $(top_builddir)/filter/libfilter.la \
- $(top_builddir)/widgets/menus/libmenus.la \
- $(top_builddir)/addressbook/util/libeabutil.la \
+libevolution_mail_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/shell/libeshell.la \
+ $(top_builddir)/composer/libcomposer.la \
+ $(top_builddir)/widgets/table/libetable.la \
+ $(top_builddir)/widgets/text/libetext.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
$(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
$(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
- $(top_builddir)/mail/importers/libevolution-mail-importers.la \
- $(SMIME_LIBS) \
- $(EVOLUTION_MAIL_LIBS) \
- $(GTKHTML_LIBS) \
- $(REGEX_LIBS) \
- $(THREADS_LIBS)
-
-libevolution_mail_la_LDFLAGS = \
- -avoid-version -module $(NO_UNDEFINED)
-
-libevolution_mail_la_DEPENDENCIES = \
- em-filter-i18n.h \
- libevolution-mail-shared.la
-
-libevolution_mail_shared_la_SOURCES = \
- e-attachment-handler-mail.c \
- e-attachment-handler-mail.h \
- e-mail-attachment-bar.c \
- e-mail-search-bar.c \
- em-account-editor.c \
- em-account-editor.h \
- em-event.c \
- em-config.c \
- em-composer-utils.c \
- em-composer-utils.h \
- em-filter-context.c \
- em-filter-context.h \
- em-filter-editor.c \
- em-filter-editor.h \
- em-filter-folder-element.c \
- em-filter-folder-element.h \
- em-filter-rule.c \
- em-filter-rule.h \
- em-filter-source-element.c \
- em-filter-source-element.h \
- em-folder-tree-model.c \
- em-folder-tree.c \
- em-folder-properties.c \
- em-folder-properties.h \
- em-folder-selection-button.c \
- em-folder-selection-button.h \
- em-folder-selection.c \
- em-folder-selection.h \
- em-folder-selector.c \
- em-folder-selector.h \
- em-folder-utils.c \
- em-format-quote.c \
- em-format.c \
- em-icon-stream.c \
- em-inline-filter.c \
- em-popup.c \
- em-search-context.c \
- em-search-context.h \
- em-stripsig-filter.c \
- em-sync-stream.c \
- em-utils.c \
- em-vfolder-context.c \
- em-vfolder-context.h \
- em-vfolder-editor.c \
- em-vfolder-editor.h \
- em-vfolder-rule.c \
- em-vfolder-rule.h \
- mail-autofilter.c \
- mail-config.c \
- mail-crypto.c \
- mail-crypto.h \
- mail-folder-cache.c \
- mail-folder-cache.h \
- mail-ops.c \
- mail-mt.c \
- mail-send-recv.c \
- mail-send-recv.h \
- mail-session.c \
- mail-tools.c \
- mail-vfolder.c \
- message-tag-editor.c \
- message-tag-editor.h \
- message-tag-followup.c \
- message-tag-followup.h
-
-if OS_WIN32
-LIBEVOMAIL=$(top_builddir)/win32/libevolution-mail.la
-endif
-
-libevolution_mail_shared_la_LIBADD = \
- $(LIBEVOMAIL) \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/composer/libcomposer.la \
- $(top_builddir)/filter/libfilter.la \
- $(top_builddir)/widgets/menus/libmenus.la \
- $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
- $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
- $(SMIME_LIBS) \
- $(EVOLUTION_MAIL_LIBS) \
- $(THREADS_LIBS)
-
-libevolution_mail_shared_la_LDFLAGS = $(NO_UNDEFINED)
-
-# --- BIG NASTY AUTOMAKE HACK ---
-#
-# Automake apparently sorts Makefile.am rules alphabetically. And
-# since component_LTLIBRARIES < privsolib_LTLIBRARIES, it tries to
-# install libevolution-mail.la before libevolution-mail-shared.la,
-# which fails when libtool tries to relink libevolution-mail.la
-# against the not-yet-installed libevolution-mail-shared.la.
-install-data-am: \
- install-privsolibLTLIBRARIES \
- install-componentLTLIBRARIES \
- install-data-local \
- install-errorDATA \
- install-etspecDATA \
- install-filterDATA \
- install-gladeDATA \
- install-idlDATA \
- install-mailincludeHEADERS \
- install-schemaDATA \
- install-serverDATA
-
-# .server files
+ $(CANBERRA_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(SMIME_LIBS)
-server_in_files = GNOME_Evolution_Mail.server.in.in
-server_DATA = $(server_in_files:.server.in.in=.server)
+libevolution_mail_la_LDFLAGS = $(NO_UNDEFINED)
-@EVO_SERVER_RULE@
-@INTLTOOL_SERVER_RULE@
+libevolution_mail_la_DEPENDENCIES = em-filter-i18n.h
# Misc data to install
filterdir = $(privdatadir)
@@ -304,7 +195,6 @@ etspec_DATA = message-list.etspec
EXTRA_DIST = \
ChangeLog.pre-1-4 \
README.async \
- $(MAIL_IDL) \
mail.error.xml \
$(glade_DATA) \
$(schema_in_files) \
@@ -360,7 +250,7 @@ endif
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
-BUILT_SOURCES = $(MAIL_IDL_GENERATED) $(server_DATA) $(error_DATA)
+BUILT_SOURCES = $(error_DATA)
CLEANFILES = $(BUILT_SOURCES)
diff --git a/mail/e-attachment-handler-mail.h b/mail/e-attachment-handler-mail.h
deleted file mode 100644
index c62ea99cab..0000000000
--- a/mail/e-attachment-handler-mail.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * e-attachment-handler-mail.h
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_ATTACHMENT_HANDLER_MAIL_H
-#define E_ATTACHMENT_HANDLER_MAIL_H
-
-#include <widgets/misc/e-attachment-handler.h>
-
-/* Standard GObject macros */
-#define E_TYPE_ATTACHMENT_HANDLER_MAIL \
- (e_attachment_handler_mail_get_type ())
-#define E_ATTACHMENT_HANDLER_MAIL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMail))
-#define E_ATTACHMENT_HANDLER_MAIL_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailClass))
-#define E_IS_ATTACHMENT_HANDLER_MAIL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL))
-#define E_IS_ATTACHMENT_HANDLER_MAIL_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_ATTACHMENT_HANDLER_MAIL))
-#define E_ATTACHMENT_HANDLER_MAIL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EAttachmentHandlerMail EAttachmentHandlerMail;
-typedef struct _EAttachmentHandlerMailClass EAttachmentHandlerMailClass;
-typedef struct _EAttachmentHandlerMailPrivate EAttachmentHandlerMailPrivate;
-
-struct _EAttachmentHandlerMail {
- EAttachmentHandler parent;
- EAttachmentHandlerMailPrivate *priv;
-};
-
-struct _EAttachmentHandlerMailClass {
- EAttachmentHandlerClass parent_class;
-};
-
-GType e_attachment_handler_mail_get_type (void);
-
-G_END_DECLS
-
-#endif /* E_ATTACHMENT_HANDLER_MAIL_H */
diff --git a/mail/e-mail-attachment-bar.c b/mail/e-mail-attachment-bar.c
index e3656e1223..fd53292610 100644
--- a/mail/e-mail-attachment-bar.c
+++ b/mail/e-mail-attachment-bar.c
@@ -98,6 +98,7 @@ mail_attachment_bar_update_status (EMailAttachmentBar *bar)
{
EAttachmentView *view;
EAttachmentStore *store;
+ GtkActivatable *activatable;
GtkExpander *expander;
GtkAction *action;
GtkLabel *label;
@@ -106,8 +107,6 @@ mail_attachment_bar_update_status (EMailAttachmentBar *bar)
gchar *display_size;
gchar *markup;
- GtkActivatable *activatable;
-
view = E_ATTACHMENT_VIEW (bar);
store = e_attachment_view_get_store (view);
expander = GTK_EXPANDER (bar->priv->expander);
diff --git a/mail/e-mail-browser.c b/mail/e-mail-browser.c
new file mode 100644
index 0000000000..fb79932653
--- /dev/null
+++ b/mail/e-mail-browser.c
@@ -0,0 +1,745 @@
+/*
+ * e-mail-browser.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-browser.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <camel/camel-folder.h>
+
+#include "e-util/e-util.h"
+#include "e-util/gconf-bridge.h"
+#include "shell/e-shell.h"
+
+#include "mail/e-mail-reader.h"
+#include "mail/e-mail-reader-utils.h"
+#include "mail/e-mail-search-bar.h"
+#include "mail/em-folder-tree-model.h"
+#include "mail/em-format-html-display.h"
+#include "mail/message-list.h"
+
+#define E_MAIL_BROWSER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_BROWSER, EMailBrowserPrivate))
+
+#define MAIL_BROWSER_GCONF_PREFIX "/apps/evolution/mail/mail_browser"
+
+struct _EMailBrowserPrivate {
+ GtkUIManager *ui_manager;
+ EShellBackend *shell_backend;
+ GtkActionGroup *action_group;
+ EMFormatHTMLDisplay *html_display;
+
+ GtkWidget *main_menu;
+ GtkWidget *main_toolbar;
+ GtkWidget *message_list;
+ GtkWidget *search_bar;
+ GtkWidget *statusbar;
+
+ guint show_deleted : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_SHELL_BACKEND,
+ PROP_SHOW_DELETED,
+ PROP_UI_MANAGER
+};
+
+static gpointer parent_class;
+
+/* This is too trivial to put in a file.
+ * It gets merged with the EMailReader UI. */
+static const gchar *ui =
+"<ui>"
+" <menubar name='main-menu'>"
+" <menu action='file-menu'>"
+" <placeholder name='file-actions'/>"
+" <placeholder name='print-actions'/>"
+" <separator/>"
+" <menuitem action='close'/>"
+" </menu>"
+" </menubar>"
+"</ui>";
+
+static void
+action_close_cb (GtkAction *action,
+ EMailBrowser *browser)
+{
+ e_mail_browser_close (browser);
+}
+
+static GtkActionEntry mail_browser_entries[] = {
+
+ { "close",
+ GTK_STOCK_CLOSE,
+ NULL,
+ NULL,
+ N_("Close this window"),
+ G_CALLBACK (action_close_cb) },
+
+ /*** Menus ***/
+
+ { "file-menu",
+ NULL,
+ N_("_File"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "edit-menu",
+ NULL,
+ N_("_Edit"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "view-menu",
+ NULL,
+ N_("_View"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static void
+mail_browser_menu_item_select_cb (EMailBrowser *browser,
+ GtkWidget *menu_item)
+{
+ GtkAction *action;
+ GtkStatusbar *statusbar;
+ gchar *tooltip = NULL;
+ guint context_id;
+ gpointer data;
+
+ action = g_object_get_data (G_OBJECT (menu_item), "action");
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ data = g_object_get_data (G_OBJECT (menu_item), "context-id");
+ context_id = GPOINTER_TO_UINT (data);
+
+ g_object_get (action, "tooltip", &tooltip, NULL);
+
+ if (tooltip == NULL)
+ return;
+
+ statusbar = GTK_STATUSBAR (browser->priv->statusbar);
+ gtk_statusbar_push (statusbar, context_id, tooltip);
+}
+
+static void
+mail_browser_menu_item_deselect_cb (EMailBrowser *browser,
+ GtkWidget *menu_item)
+{
+ GtkStatusbar *statusbar;
+ guint context_id;
+ gpointer data;
+
+ data = g_object_get_data (G_OBJECT (menu_item), "context-id");
+ context_id = GPOINTER_TO_UINT (data);
+
+ statusbar = GTK_STATUSBAR (browser->priv->statusbar);
+ gtk_statusbar_pop (statusbar, context_id);
+}
+
+static void
+mail_browser_connect_proxy_cb (EMailBrowser *browser,
+ GtkAction *action,
+ GtkWidget *proxy)
+{
+ GtkStatusbar *statusbar;
+ guint context_id;
+
+ if (!GTK_IS_MENU_ITEM (proxy))
+ return;
+
+ statusbar = GTK_STATUSBAR (browser->priv->statusbar);
+ context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
+
+ g_object_set_data_full (
+ G_OBJECT (proxy),
+ "action", g_object_ref (action),
+ (GDestroyNotify) g_object_unref);
+
+ g_object_set_data (
+ G_OBJECT (proxy), "context-id",
+ GUINT_TO_POINTER (context_id));
+
+ g_signal_connect_swapped (
+ proxy, "select",
+ G_CALLBACK (mail_browser_menu_item_select_cb), browser);
+
+ g_signal_connect_swapped (
+ proxy, "deselect",
+ G_CALLBACK (mail_browser_menu_item_deselect_cb), browser);
+}
+
+static void
+mail_browser_message_selected_cb (EMailBrowser *browser,
+ const gchar *uid)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelMessageInfo *info;
+ EMailReader *reader;
+
+ if (uid == NULL)
+ return;
+
+ reader = E_MAIL_READER (browser);
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+ info = camel_folder_get_message_info (message_list->folder, uid);
+
+ if (info == NULL)
+ return;
+
+ gtk_window_set_title (
+ GTK_WINDOW (browser),
+ camel_message_info_subject (info));
+ gtk_widget_grab_focus (
+ GTK_WIDGET (((EMFormatHTML *) html_display)->html));
+
+ camel_folder_free_message_info (message_list->folder, info);
+}
+
+static void
+mail_browser_status_message_cb (EMailBrowser *browser,
+ const gchar *status_message)
+{
+ GtkStatusbar *statusbar;
+ guint context_id;
+
+ statusbar = GTK_STATUSBAR (browser->priv->statusbar);
+ context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
+
+ /* Always pop first. This prevents messages from piling up. */
+ gtk_statusbar_pop (statusbar, context_id);
+
+ if (status_message != NULL && *status_message != '\0')
+ gtk_statusbar_push (statusbar, context_id, status_message);
+}
+
+static void
+mail_browser_set_shell_backend (EMailBrowser *browser,
+ EShellBackend *shell_backend)
+{
+ g_return_if_fail (browser->priv->shell_backend == NULL);
+
+ browser->priv->shell_backend = g_object_ref (shell_backend);
+}
+
+static void
+mail_browser_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ mail_browser_set_shell_backend (
+ E_MAIL_BROWSER (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SHOW_DELETED:
+ e_mail_browser_set_show_deleted (
+ E_MAIL_BROWSER (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_browser_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ g_value_set_object (
+ value, e_mail_reader_get_shell_backend (
+ E_MAIL_READER (object)));
+ return;
+
+ case PROP_SHOW_DELETED:
+ g_value_set_boolean (
+ value, e_mail_browser_get_show_deleted (
+ E_MAIL_BROWSER (object)));
+ return;
+
+ case PROP_UI_MANAGER:
+ g_value_set_object (
+ value, e_mail_browser_get_ui_manager (
+ E_MAIL_BROWSER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_browser_dispose (GObject *object)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (object);
+
+ if (priv->ui_manager != NULL) {
+ g_object_unref (priv->ui_manager);
+ priv->ui_manager = NULL;
+ }
+
+ if (priv->shell_backend != NULL) {
+ g_object_unref (priv->shell_backend);
+ priv->shell_backend = NULL;
+ }
+
+ if (priv->action_group != NULL) {
+ g_object_unref (priv->action_group);
+ priv->action_group = NULL;
+ }
+
+ if (priv->html_display != NULL) {
+ g_object_unref (priv->html_display);
+ priv->html_display = NULL;
+ }
+
+ if (priv->main_menu != NULL) {
+ g_object_unref (priv->main_menu);
+ priv->main_menu = NULL;
+ }
+
+ if (priv->main_toolbar != NULL) {
+ g_object_unref (priv->main_toolbar);
+ priv->main_toolbar = NULL;
+ }
+
+ if (priv->message_list != NULL) {
+ g_object_unref (priv->message_list);
+ priv->message_list = NULL;
+ }
+
+ if (priv->search_bar != NULL) {
+ g_object_unref (priv->search_bar);
+ priv->search_bar = NULL;
+ }
+
+ if (priv->statusbar != NULL) {
+ g_object_unref (priv->statusbar);
+ priv->statusbar = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_browser_constructed (GObject *object)
+{
+ EMFormatHTMLDisplay *html_display;
+ EMailBrowserPrivate *priv;
+ EMailReader *reader;
+ EShellBackend *shell_backend;
+ EShell *shell;
+ GConfBridge *bridge;
+ GtkAccelGroup *accel_group;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GtkHTML *html;
+ const gchar *domain;
+ const gchar *key;
+ guint merge_id;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (object);
+
+ reader = E_MAIL_READER (object);
+ ui_manager = priv->ui_manager;
+ domain = GETTEXT_PACKAGE;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ e_shell_watch_window (shell, GTK_WINDOW (object));
+
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ /* The message list is a widget, but it is not shown in the browser.
+ * Unfortunately, the widget is inseparable from its model, and the
+ * model is all we need. */
+ priv->message_list = message_list_new (shell_backend);
+ g_object_ref_sink (priv->message_list);
+
+ g_signal_connect_swapped (
+ priv->message_list, "message-selected",
+ G_CALLBACK (mail_browser_message_selected_cb), object);
+
+ g_signal_connect_swapped (
+ html, "status-message",
+ G_CALLBACK (mail_browser_status_message_cb), object);
+
+ e_mail_reader_init (reader);
+
+ action_group = priv->action_group;
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_action_group_add_actions (
+ action_group, mail_browser_entries,
+ G_N_ELEMENTS (mail_browser_entries), object);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+
+ e_load_ui_definition (ui_manager, E_MAIL_READER_UI_DEFINITION);
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);
+
+ merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+ e_mail_reader_create_charset_menu (reader, ui_manager, merge_id);
+
+ accel_group = gtk_ui_manager_get_accel_group (ui_manager);
+ gtk_window_add_accel_group (GTK_WINDOW (object), accel_group);
+
+ g_signal_connect_swapped (
+ ui_manager, "connect-proxy",
+ G_CALLBACK (mail_browser_connect_proxy_cb), object);
+
+ /* Construct window widgets. */
+
+ widget = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (object), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ /* Create the status bar before connecting proxy widgets. */
+ widget = gtk_statusbar_new ();
+ gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->statusbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = e_mail_search_bar_new (EM_FORMAT_HTML (html_display)->html);
+ gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->search_bar = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (em_format_redraw), html_display);
+
+ widget = gtk_ui_manager_get_widget (ui_manager, "/main-menu");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->main_menu = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_ui_manager_get_widget (ui_manager, "/main-toolbar");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->main_toolbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = GTK_WIDGET (EM_FORMAT_HTML (html_display)->html);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (reader);
+ key = "/apps/evolution/mail/display/show_deleted";
+ gconf_bridge_bind_property (bridge, key, object, "show-deleted");
+}
+
+static gboolean
+mail_browser_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_Escape) {
+ e_mail_browser_close (E_MAIL_BROWSER (widget));
+ return TRUE;
+ }
+
+ /* Chain up to parent's key_press_event() method. */
+ return GTK_WIDGET_CLASS (parent_class)->
+ key_press_event (widget, event);
+}
+
+static GtkActionGroup *
+mail_browser_get_action_group (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ return priv->action_group;
+}
+
+static gboolean
+mail_browser_get_hide_deleted (EMailReader *reader)
+{
+ EMailBrowser *browser;
+
+ browser = E_MAIL_BROWSER (reader);
+
+ return !e_mail_browser_get_show_deleted (browser);
+}
+
+static EMFormatHTMLDisplay *
+mail_browser_get_html_display (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ return priv->html_display;
+}
+
+static MessageList *
+mail_browser_get_message_list (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ return MESSAGE_LIST (priv->message_list);
+}
+
+static EShellBackend *
+mail_browser_get_shell_backend (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ return priv->shell_backend;
+}
+
+static GtkWindow *
+mail_browser_get_window (EMailReader *reader)
+{
+ return GTK_WINDOW (reader);
+}
+
+static void
+mail_browser_set_message (EMailReader *reader,
+ const gchar *uid)
+{
+ EMailReaderIface *iface;
+ MessageList *message_list;
+ CamelMessageInfo *info;
+ CamelFolder *folder;
+
+ /* Chain up to parent's set_message() method. */
+ iface = g_type_default_interface_peek (E_TYPE_MAIL_READER);
+ iface->set_message (reader, uid);
+
+ if (uid == NULL) {
+ e_mail_browser_close (E_MAIL_BROWSER (reader));
+ return;
+ }
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ info = camel_folder_get_message_info (folder, uid);
+
+ if (info != NULL) {
+ gtk_window_set_title (
+ GTK_WINDOW (reader),
+ camel_message_info_subject (info));
+ camel_folder_free_message_info (folder, info);
+ }
+}
+
+static void
+mail_browser_show_search_bar (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ gtk_widget_show (priv->search_bar);
+}
+
+static void
+mail_browser_class_init (EMailBrowserClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailBrowserPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_browser_set_property;
+ object_class->get_property = mail_browser_get_property;
+ object_class->dispose = mail_browser_dispose;
+ object_class->constructed = mail_browser_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->key_press_event = mail_browser_key_press_event;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_BACKEND,
+ g_param_spec_object (
+ "shell-backend",
+ _("Shell Module"),
+ _("The mail shell backend"),
+ E_TYPE_SHELL_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_DELETED,
+ g_param_spec_boolean (
+ "show-deleted",
+ _("Show Deleted"),
+ _("Show deleted messages"),
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+static void
+mail_browser_iface_init (EMailReaderIface *iface)
+{
+ iface->get_action_group = mail_browser_get_action_group;
+ iface->get_hide_deleted = mail_browser_get_hide_deleted;
+ iface->get_html_display = mail_browser_get_html_display;
+ iface->get_message_list = mail_browser_get_message_list;
+ iface->get_shell_backend = mail_browser_get_shell_backend;
+ iface->get_window = mail_browser_get_window;
+ iface->set_message = mail_browser_set_message;
+ iface->show_search_bar = mail_browser_show_search_bar;
+}
+
+static void
+mail_browser_init (EMailBrowser *browser)
+{
+ GConfBridge *bridge;
+ const gchar *prefix;
+
+ browser->priv = E_MAIL_BROWSER_GET_PRIVATE (browser);
+
+ browser->priv->ui_manager = gtk_ui_manager_new ();
+ browser->priv->action_group = gtk_action_group_new ("mail-browser");
+ browser->priv->html_display = em_format_html_display_new ();
+
+ bridge = gconf_bridge_get ();
+ prefix = "/apps/evolution/mail/mail_browser";
+ gconf_bridge_bind_window_size (bridge, prefix, GTK_WINDOW (browser));
+
+ gtk_window_set_title (GTK_WINDOW (browser), _("Evolution"));
+}
+
+GType
+e_mail_browser_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailBrowserClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_browser_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailBrowser),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_browser_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo iface_info = {
+ (GInterfaceInitFunc) mail_browser_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_WINDOW, "EMailBrowser", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_MAIL_READER, &iface_info);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_mail_browser_new (EShellBackend *shell_backend)
+{
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_BROWSER,
+ "shell-backend", shell_backend, NULL);
+}
+
+void
+e_mail_browser_close (EMailBrowser *browser)
+{
+ g_return_if_fail (E_IS_MAIL_BROWSER (browser));
+
+ gtk_widget_destroy (GTK_WIDGET (browser));
+}
+
+gboolean
+e_mail_browser_get_show_deleted (EMailBrowser *browser)
+{
+ g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), FALSE);
+
+ return browser->priv->show_deleted;
+}
+
+void
+e_mail_browser_set_show_deleted (EMailBrowser *browser,
+ gboolean show_deleted)
+{
+ g_return_if_fail (E_IS_MAIL_BROWSER (browser));
+
+ browser->priv->show_deleted = show_deleted;
+
+ g_object_notify (G_OBJECT (browser), "show-deleted");
+}
+
+GtkUIManager *
+e_mail_browser_get_ui_manager (EMailBrowser *browser)
+{
+ g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), NULL);
+
+ return browser->priv->ui_manager;
+}
diff --git a/mail/e-mail-browser.h b/mail/e-mail-browser.h
new file mode 100644
index 0000000000..f2fd4d9131
--- /dev/null
+++ b/mail/e-mail-browser.h
@@ -0,0 +1,72 @@
+/*
+ * e-mail-browser.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_BROWSER_H
+#define E_MAIL_BROWSER_H
+
+#include <gtk/gtk.h>
+#include <shell/e-shell-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_BROWSER \
+ (e_mail_browser_get_type ())
+#define E_MAIL_BROWSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_BROWSER, EMailBrowser))
+#define E_MAIL_BROWSER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_BROWSER, EMailBrowserClass))
+#define E_IS_MAIL_BROWSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_BROWSER))
+#define E_IS_MAIL_BROWSER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_BROWSER))
+#define E_MAIL_BROWSER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_BROWSER, EMailBrowserClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailBrowser EMailBrowser;
+typedef struct _EMailBrowserClass EMailBrowserClass;
+typedef struct _EMailBrowserPrivate EMailBrowserPrivate;
+
+struct _EMailBrowser {
+ GtkWindow parent;
+ EMailBrowserPrivate *priv;
+};
+
+struct _EMailBrowserClass {
+ GtkWindowClass parent_class;
+};
+
+GType e_mail_browser_get_type (void);
+GtkWidget * e_mail_browser_new (EShellBackend *shell_backend);
+void e_mail_browser_close (EMailBrowser *browser);
+gboolean e_mail_browser_get_show_deleted (EMailBrowser *browser);
+void e_mail_browser_set_show_deleted (EMailBrowser *browser,
+ gboolean show_deleted);
+GtkUIManager * e_mail_browser_get_ui_manager (EMailBrowser *browser);
+
+G_END_DECLS
+
+#endif /* E_MAIL_BROWSER_H */
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
new file mode 100644
index 0000000000..c29328b36b
--- /dev/null
+++ b/mail/e-mail-display.c
@@ -0,0 +1,1072 @@
+/*
+ * e-mail-display.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-display.h"
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+#include "e-util/e-plugin-ui.h"
+#include "mail/em-composer-utils.h"
+#include "mail/em-utils.h"
+
+#define E_MAIL_DISPLAY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_DISPLAY, EMailDisplayPrivate))
+
+struct _EMailDisplayPrivate {
+ EMFormatHTML *formatter;
+ GtkUIManager *ui_manager;
+ gchar *selected_uri;
+};
+
+enum {
+ PROP_0,
+ PROP_ANIMATE,
+ PROP_CARET_MODE,
+ PROP_FORMATTER,
+ PROP_SELECTED_URI
+};
+
+enum {
+ POPUP_EVENT,
+ STATUS_MESSAGE,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static const gchar *ui =
+"<ui>"
+" <popup name='context'>"
+" <menuitem action='http-open'/>"
+" <menuitem action='send-message'/>"
+" <menuitem action='uri-copy'/>"
+" <menuitem action='add-to-address-book'/>"
+" <menuitem action='mailto-copy'/>"
+" <menu action='search-folder-menu'>"
+" <menuitem action='search-folder-sender'/>"
+" <menuitem action='search-folder-recipient'/>"
+" </menu>"
+" </popup>"
+"</ui>";
+
+static void
+action_add_to_address_book_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ CamelURL *curl;
+ const gchar *uri;
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (display));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ /* This should work because we checked it in update_actions(). */
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ if (curl->path != NULL && *curl->path != '\0')
+ em_utils_add_address (parent, curl->path);
+
+ camel_url_free (curl);
+}
+
+static void
+action_http_open_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ const gchar *uri;
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (display));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ e_show_uri (parent, uri);
+}
+
+static void
+action_mailto_copy_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ CamelURL *curl;
+ CamelInternetAddress *inet_addr;
+ GtkClipboard *clipboard;
+ const gchar *uri;
+ gchar *text;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ /* This should work because we checked it in update_actions(). */
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ inet_addr = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
+ text = camel_address_encode (CAMEL_ADDRESS (inet_addr));
+ if (text == NULL || *text == '\0')
+ text = g_strdup (uri + strlen ("mailto:"));
+
+ camel_object_unref (inet_addr);
+ camel_url_free (curl);
+
+ gtk_clipboard_set_text (clipboard, text, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_free (text);
+}
+
+static void
+action_send_message_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ const gchar *uri;
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ em_utils_compose_new_message_with_mailto (uri, NULL);
+}
+
+static void
+action_uri_copy_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ GtkClipboard *clipboard;
+ const gchar *uri;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ gtk_clipboard_set_text (clipboard, uri, -1);
+ gtk_clipboard_store (clipboard);
+}
+
+static GtkActionEntry uri_entries[] = {
+
+ { "uri-copy",
+ GTK_STOCK_COPY,
+ N_("_Copy Link Location"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_uri_copy_cb) },
+};
+
+static GtkActionEntry http_entries[] = {
+
+ { "http-open",
+ "emblem-web",
+ N_("_Open Link in Browser"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_http_open_cb) },
+};
+
+static GtkActionEntry mailto_entries[] = {
+
+ { "add-to-address-book",
+ "contact-new",
+ N_("_Add to Address Book..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_add_to_address_book_cb) },
+
+ { "mailto-copy",
+ GTK_STOCK_COPY,
+ N_("_Copy Email Address"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_mailto_copy_cb) },
+
+ { "search-folder-recipient",
+ NULL,
+ N_("_To This Address"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ NULL /* Handled by EMailReader */ },
+
+ { "search-folder-sender",
+ NULL,
+ N_("_From This Address"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ NULL /* Handled by EMailReader */ },
+
+ { "send-message",
+ "mail-message-new",
+ N_("_Send New Message To..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_send_message_cb) },
+
+ /*** Menus ***/
+
+ { "search-folder-menu",
+ "folder-saved-search",
+ N_("Create Search _Folder"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static gboolean
+mail_display_emit_popup_event (EMailDisplay *display,
+ GdkEventButton *event,
+ const gchar *uri,
+ EMFormatPURI *puri)
+{
+ CamelMimePart *mime_part;
+ gboolean stop_handlers = FALSE;
+
+ mime_part = (puri != NULL) ? puri->part : NULL;
+
+ g_signal_emit (
+ display, signals[POPUP_EVENT], 0,
+ event, uri, mime_part, &stop_handlers);
+
+ return stop_handlers;
+}
+
+static void
+mail_display_emit_status_message (EMailDisplay *display,
+ const gchar *status_message)
+{
+ g_signal_emit (display, signals[STATUS_MESSAGE], 0, status_message);
+}
+
+static void
+mail_display_get_uri_puri (EMailDisplay *display,
+ GdkEventButton *event,
+ GtkHTML *html,
+ gchar **uri,
+ EMFormatPURI **puri)
+{
+ EMFormat *formatter;
+ gchar *text_uri;
+ gchar *image_uri;
+ gboolean is_cid;
+
+ formatter = EM_FORMAT (display->priv->formatter);
+
+ if (event != NULL) {
+ text_uri = gtk_html_get_url_at (html, event->x, event->y);
+ image_uri = gtk_html_get_image_src_at (html, event->x, event->y);
+ } else {
+ text_uri = gtk_html_get_cursor_url (html);
+ image_uri = gtk_html_get_cursor_image_src (html);
+ }
+
+ is_cid = (image_uri != NULL) &&
+ (g_ascii_strncasecmp (image_uri, "cid:", 4) == 0);
+
+ if (image_uri != NULL) {
+ if (strstr (image_uri, "://") == NULL && !is_cid) {
+ gchar *temp;
+
+ temp = g_strconcat ("file://", image_uri, NULL);
+ g_free (image_uri);
+ image_uri = temp;
+ }
+ }
+
+ if (puri != NULL) {
+ if (text_uri != NULL)
+ *puri = em_format_find_puri (formatter, text_uri);
+
+ if (*puri == NULL && image_uri != NULL)
+ *puri = em_format_find_puri (formatter, image_uri);
+ }
+
+ if (uri != NULL) {
+ *uri = NULL;
+ if (is_cid) {
+ if (text_uri != NULL)
+ *uri = g_strdup_printf (
+ "%s\n%s", text_uri, image_uri);
+ else {
+ *uri = image_uri;
+ image_uri = NULL;
+ }
+ } else {
+ *uri = text_uri;
+ text_uri = NULL;
+ }
+ }
+
+ g_free (text_uri);
+ g_free (image_uri);
+}
+
+static gboolean
+mail_display_button_press_event_cb (EMailDisplay *display,
+ GdkEventButton *event,
+ GtkHTML *html)
+{
+ EMFormatPURI *puri = NULL;
+ gboolean finished = TRUE;
+ gchar *uri = NULL;
+
+ /* The GtkHTML object may be the EMailDisplay itself
+ * or an inner iframe. */
+
+ if (event->button != 3)
+ return FALSE;
+
+ mail_display_get_uri_puri (display, event, html, &uri, &puri);
+
+ if (uri == NULL || g_str_has_prefix (uri, "##")) {
+ g_free (uri);
+ return FALSE;
+ }
+
+ finished = mail_display_emit_popup_event (display, event, uri, puri);
+
+ g_free (uri);
+
+ return finished;
+}
+
+static void
+mail_display_update_formatter_colors (EMailDisplay *display)
+{
+ EMFormatHTMLColorType type;
+ EMFormatHTML *formatter;
+ GdkColor *color;
+ GtkStyle *style;
+ gint state;
+
+ state = GTK_WIDGET_STATE (display);
+ formatter = display->priv->formatter;
+
+ style = gtk_widget_get_style (GTK_WIDGET (display));
+ if (style == NULL)
+ return;
+
+ g_object_freeze_notify (G_OBJECT (formatter));
+
+ color = &style->bg[state];
+ type = EM_FORMAT_HTML_COLOR_BODY;
+ em_format_html_set_color (formatter, type, color);
+
+ color = &style->base[GTK_STATE_NORMAL];
+ type = EM_FORMAT_HTML_COLOR_CONTENT;
+ em_format_html_set_color (formatter, type, color);
+
+ color = &style->dark[state];
+ type = EM_FORMAT_HTML_COLOR_FRAME;
+ em_format_html_set_color (formatter, type, color);
+
+ color = &style->fg[state];
+ type = EM_FORMAT_HTML_COLOR_HEADER;
+ em_format_html_set_color (formatter, type, color);
+
+ color = &style->text[state];
+ type = EM_FORMAT_HTML_COLOR_TEXT;
+ em_format_html_set_color (formatter, type, color);
+
+ g_object_thaw_notify (G_OBJECT (formatter));
+}
+
+static void
+mail_display_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ANIMATE:
+ e_mail_display_set_animate (
+ E_MAIL_DISPLAY (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_CARET_MODE:
+ e_mail_display_set_caret_mode (
+ E_MAIL_DISPLAY (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_FORMATTER:
+ e_mail_display_set_formatter (
+ E_MAIL_DISPLAY (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SELECTED_URI:
+ e_mail_display_set_selected_uri (
+ E_MAIL_DISPLAY (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_display_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ANIMATE:
+ g_value_set_boolean (
+ value, e_mail_display_get_animate (
+ E_MAIL_DISPLAY (object)));
+ return;
+
+ case PROP_CARET_MODE:
+ g_value_set_boolean (
+ value, e_mail_display_get_caret_mode (
+ E_MAIL_DISPLAY (object)));
+ return;
+
+ case PROP_FORMATTER:
+ g_value_set_object (
+ value, e_mail_display_get_formatter (
+ E_MAIL_DISPLAY (object)));
+ return;
+
+ case PROP_SELECTED_URI:
+ g_value_set_string (
+ value, e_mail_display_get_selected_uri (
+ E_MAIL_DISPLAY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_display_dispose (GObject *object)
+{
+ EMailDisplayPrivate *priv;
+
+ priv = E_MAIL_DISPLAY_GET_PRIVATE (object);
+
+ if (priv->formatter) {
+ g_object_unref (priv->formatter);
+ priv->formatter = NULL;
+ }
+
+ if (priv->ui_manager) {
+ g_object_unref (priv->ui_manager);
+ priv->ui_manager = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_display_realize (GtkWidget *widget)
+{
+ /* Chain up to parent's realize() method. */
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
+
+ mail_display_update_formatter_colors (E_MAIL_DISPLAY (widget));
+}
+
+static void
+mail_display_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ EMailDisplayPrivate *priv;
+
+ priv = E_MAIL_DISPLAY_GET_PRIVATE (widget);
+
+ /* Chain up to parent's style_set() method. */
+ GTK_WIDGET_CLASS (parent_class)->style_set (widget, previous_style);
+
+ mail_display_update_formatter_colors (E_MAIL_DISPLAY (widget));
+ em_format_redraw (EM_FORMAT (priv->formatter));
+}
+
+static gboolean
+mail_display_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ EMailDisplay *display = E_MAIL_DISPLAY (widget);
+ GtkHTML *html = GTK_HTML (widget);
+
+ if (mail_display_button_press_event_cb (display, event, html))
+ return TRUE;
+
+ /* Chain up to parent's button_press_event() method. */
+ return GTK_WIDGET_CLASS (parent_class)->
+ button_press_event (widget, event);
+}
+
+static gboolean
+mail_display_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event)
+{
+ if (event->state & GDK_CONTROL_MASK) {
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ gtk_html_zoom_in (GTK_HTML (widget));
+ return TRUE;
+ case GDK_SCROLL_DOWN:
+ gtk_html_zoom_out (GTK_HTML (widget));
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+mail_display_link_clicked (GtkHTML *html,
+ const gchar *uri)
+{
+ EMailDisplayPrivate *priv;
+
+ priv = E_MAIL_DISPLAY_GET_PRIVATE (html);
+ g_return_if_fail (priv->formatter != NULL);
+
+ if (g_str_has_prefix (uri, "##")) {
+ guint32 flags;
+
+ flags = priv->formatter->header_wrap_flags;
+
+ if (strcmp (uri, "##TO##") == 0) {
+ if (!(flags & EM_FORMAT_HTML_HEADER_TO))
+ flags |= EM_FORMAT_HTML_HEADER_TO;
+ else
+ flags &= ~EM_FORMAT_HTML_HEADER_TO;
+ } else if (strcmp (uri, "##CC##") == 0) {
+ if (!(flags & EM_FORMAT_HTML_HEADER_CC))
+ flags |= EM_FORMAT_HTML_HEADER_CC;
+ else
+ flags |= EM_FORMAT_HTML_HEADER_CC;
+ } else if (strcmp (uri, "##BCC##") == 0) {
+ if (!(flags & EM_FORMAT_HTML_HEADER_BCC))
+ flags |= EM_FORMAT_HTML_HEADER_BCC;
+ else
+ flags |= EM_FORMAT_HTML_HEADER_BCC;
+ }
+
+ priv->formatter->header_wrap_flags = flags;
+ em_format_redraw (EM_FORMAT (priv->formatter));
+
+ } else if (*uri == '#')
+ gtk_html_jump_to_anchor (html, uri + 1);
+
+ else if (g_ascii_strncasecmp (uri, "thismessage:", 12) == 0)
+ /* ignore */ ;
+
+ else if (g_ascii_strncasecmp (uri, "cid:", 4) == 0)
+ /* ignore */ ;
+
+ else {
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (html));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ e_show_uri (parent, uri);
+ }
+}
+
+static void
+mail_display_on_url (GtkHTML *html,
+ const gchar *uri)
+{
+ EMailDisplay *display;
+ CamelInternetAddress *address;
+ CamelURL *curl;
+ const gchar *format = NULL;
+ gchar *message = NULL;
+ gchar *who;
+
+ display = E_MAIL_DISPLAY (html);
+
+ if (uri == NULL || *uri == '\0')
+ goto exit;
+
+ if (g_str_has_prefix (uri, "mailto:"))
+ format = _("Click to mail %s");
+ else if (g_str_has_prefix (uri, "callto:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "h323:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "sip:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "##"))
+ message = g_strdup (_("Click to hide/unhide addresses"));
+ else
+ message = g_strdup_printf (_("Click to open %s"), uri);
+
+ if (format == NULL)
+ goto exit;
+
+ curl = camel_url_new (uri, NULL);
+ address = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (address), curl->path);
+ who = camel_address_format (CAMEL_ADDRESS (address));
+ camel_object_unref (address);
+ camel_url_free (curl);
+
+ if (who == NULL)
+ who = g_strdup (strchr (uri, ':') + 1);
+
+ message = g_strdup_printf (format, who);
+
+ g_free (who);
+
+exit:
+ mail_display_emit_status_message (display, message);
+
+ g_free (message);
+}
+
+static void
+mail_display_iframe_created (GtkHTML *html,
+ GtkHTML *iframe)
+{
+ g_signal_connect_swapped (
+ iframe, "button-press-event",
+ G_CALLBACK (mail_display_button_press_event_cb), html);
+}
+
+static gboolean
+mail_display_popup_event (EMailDisplay *display,
+ GdkEventButton *event,
+ const gchar *uri,
+ EMFormatPURI *puri)
+{
+ e_mail_display_set_selected_uri (display, uri);
+ e_mail_display_show_popup_menu (display, event, NULL, NULL);
+
+ return TRUE;
+}
+
+static void
+mail_display_class_init (EMailDisplayClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkHTMLClass *html_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailDisplayPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_display_set_property;
+ object_class->get_property = mail_display_get_property;
+ object_class->dispose = mail_display_dispose;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = mail_display_realize;
+ widget_class->style_set = mail_display_style_set;
+ widget_class->button_press_event = mail_display_button_press_event;
+ widget_class->scroll_event = mail_display_scroll_event;
+
+ html_class = GTK_HTML_CLASS (class);
+ html_class->link_clicked = mail_display_link_clicked;
+ html_class->on_url = mail_display_on_url;
+ html_class->iframe_created = mail_display_iframe_created;
+
+ class->popup_event = mail_display_popup_event;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ANIMATE,
+ g_param_spec_boolean (
+ "animate",
+ "Animate Images",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CARET_MODE,
+ g_param_spec_boolean (
+ "caret-mode",
+ "Caret Mode",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FORMATTER,
+ g_param_spec_object (
+ "formatter",
+ "HTML Formatter",
+ NULL,
+ EM_TYPE_FORMAT_HTML,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTED_URI,
+ g_param_spec_string (
+ "selected-uri",
+ "Selected URI",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailDisplayClass, popup_event),
+ g_signal_accumulator_true_handled, NULL,
+ e_marshal_BOOLEAN__BOXED_POINTER_POINTER,
+ G_TYPE_BOOLEAN, 3,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status-message",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMailDisplayClass, status_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+}
+
+static void
+mail_display_init (EMailDisplay *display)
+{
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ const gchar *id;
+ GError *error = NULL;
+
+ display->priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
+
+ ui_manager = gtk_ui_manager_new ();
+ display->priv->ui_manager = ui_manager;
+
+ action_group = e_mail_display_add_action_group (display, "uri");
+
+ gtk_action_group_add_actions (
+ action_group, uri_entries,
+ G_N_ELEMENTS (uri_entries), display);
+
+ action_group = e_mail_display_add_action_group (display, "http");
+
+ gtk_action_group_add_actions (
+ action_group, http_entries,
+ G_N_ELEMENTS (http_entries), display);
+
+ action_group = e_mail_display_add_action_group (display, "mailto");
+
+ gtk_action_group_add_actions (
+ action_group, mailto_entries,
+ G_N_ELEMENTS (mailto_entries), display);
+
+ /* Because we are loading from a hard-coded string, there is
+ * no chance of I/O errors. Failure here implies a malformed
+ * UI definition. Full stop. */
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
+ if (error != NULL)
+ g_error ("%s", error->message);
+
+ id = "org.gnome.evolution.mail.display";
+ e_plugin_ui_register_manager (ui_manager, id, display);
+ e_plugin_ui_enable_manager (ui_manager, id);
+}
+
+GType
+e_mail_display_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailDisplayClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_display_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailDisplay),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_display_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HTML, "EMailDisplay", &type_info, 0);
+ }
+
+ return type;
+}
+
+gboolean
+e_mail_display_get_animate (EMailDisplay *display)
+{
+ /* XXX This is just here to maintain symmetry
+ * with e_mail_display_set_animate(). */
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
+
+ return gtk_html_get_animate (GTK_HTML (display));
+}
+
+void
+e_mail_display_set_animate (EMailDisplay *display,
+ gboolean animate)
+{
+ /* XXX GtkHTML does not utilize GObject properties as well
+ * as it could. This just wraps gtk_html_set_animate()
+ * so we can get a "notify::animate" signal. */
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ gtk_html_set_animate (GTK_HTML (display), animate);
+
+ g_object_notify (G_OBJECT (display), "animate");
+}
+
+gboolean
+e_mail_display_get_caret_mode (EMailDisplay *display)
+{
+ /* XXX This is just here to maintain symmetry
+ * with e_mail_display_set_caret_mode(). */
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
+
+ return gtk_html_get_caret_mode (GTK_HTML (display));
+}
+
+void
+e_mail_display_set_caret_mode (EMailDisplay *display,
+ gboolean caret_mode)
+{
+ /* XXX GtkHTML does not utilize GObject properties as well
+ * as it could. This just wraps gtk_html_set_caret_mode()
+ * so we can get a "notify::caret-mode" signal. */
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ gtk_html_set_caret_mode (GTK_HTML (display), caret_mode);
+
+ g_object_notify (G_OBJECT (display), "caret-mode");
+}
+
+EMFormatHTML *
+e_mail_display_get_formatter (EMailDisplay *display)
+{
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ return display->priv->formatter;
+}
+
+void
+e_mail_display_set_formatter (EMailDisplay *display,
+ EMFormatHTML *formatter)
+{
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+ g_return_if_fail (EM_IS_FORMAT_HTML (formatter));
+
+ if (display->priv->formatter != NULL)
+ g_object_unref (display->priv->formatter);
+
+ display->priv->formatter = g_object_ref (formatter);
+
+ g_object_notify (G_OBJECT (display), "formatter");
+}
+
+const gchar *
+e_mail_display_get_selected_uri (EMailDisplay *display)
+{
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ return display->priv->selected_uri;
+}
+
+void
+e_mail_display_set_selected_uri (EMailDisplay *display,
+ const gchar *selected_uri)
+{
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ g_free (display->priv->selected_uri);
+ display->priv->selected_uri = g_strdup (selected_uri);
+
+ g_object_notify (G_OBJECT (display), "selected-uri");
+}
+
+GtkAction *
+e_mail_display_get_action (EMailDisplay *display,
+ const gchar *action_name)
+{
+ GtkUIManager *ui_manager;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
+
+ ui_manager = e_mail_display_get_ui_manager (display);
+
+ return e_lookup_action (ui_manager, action_name);
+}
+
+GtkActionGroup *
+e_mail_display_add_action_group (EMailDisplay *display,
+ const gchar *group_name)
+{
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ const gchar *domain;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ ui_manager = e_mail_display_get_ui_manager (display);
+ domain = GETTEXT_PACKAGE;
+
+ action_group = gtk_action_group_new (group_name);
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ return action_group;
+}
+
+GtkActionGroup *
+e_mail_display_get_action_group (EMailDisplay *display,
+ const gchar *group_name)
+{
+ GtkUIManager *ui_manager;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ ui_manager = e_mail_display_get_ui_manager (display);
+
+ return e_lookup_action_group (ui_manager, group_name);
+}
+
+GtkWidget *
+e_mail_display_get_popup_menu (EMailDisplay *display)
+{
+ GtkUIManager *ui_manager;
+ GtkWidget *menu;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ ui_manager = e_mail_display_get_ui_manager (display);
+ menu = gtk_ui_manager_get_widget (ui_manager, "/context");
+ g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
+
+ return menu;
+}
+
+GtkUIManager *
+e_mail_display_get_ui_manager (EMailDisplay *display)
+{
+ EMailDisplayPrivate *priv;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
+
+ return priv->ui_manager;
+}
+
+void
+e_mail_display_show_popup_menu (EMailDisplay *display,
+ GdkEventButton *event,
+ GtkMenuPositionFunc func,
+ gpointer user_data)
+{
+ GtkWidget *menu;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ e_mail_display_update_actions (display);
+
+ menu = e_mail_display_get_popup_menu (display);
+
+ if (event != NULL)
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, func,
+ user_data, event->button, event->time);
+ else
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, func,
+ user_data, 0, gtk_get_current_event_time ());
+}
+
+void
+e_mail_display_update_actions (EMailDisplay *display)
+{
+ CamelURL *curl;
+ GtkActionGroup *action_group;
+ gboolean scheme_is_http;
+ gboolean scheme_is_mailto;
+ gboolean uri_is_valid;
+ gboolean visible;
+ const gchar *uri;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ /* Parse the URI early so we know if the actions will work. */
+ curl = camel_url_new (uri, NULL);
+ uri_is_valid = (curl != NULL);
+ camel_url_free (curl);
+
+ scheme_is_http =
+ (g_ascii_strncasecmp (uri, "http:", 5) == 0) ||
+ (g_ascii_strncasecmp (uri, "https:", 6) == 0);
+
+ scheme_is_mailto =
+ (g_ascii_strncasecmp (uri, "mailto:", 7) == 0);
+
+ /* Allow copying the URI even if it's malformed. */
+ visible = !scheme_is_mailto;
+ action_group = e_mail_display_get_action_group (display, "uri");
+ gtk_action_group_set_visible (action_group, visible);
+
+ visible = uri_is_valid && scheme_is_http;
+ action_group = e_mail_display_get_action_group (display, "http");
+ gtk_action_group_set_visible (action_group, visible);
+
+ visible = uri_is_valid && scheme_is_mailto;
+ action_group = e_mail_display_get_action_group (display, "mailto");
+ gtk_action_group_set_visible (action_group, visible);
+}
diff --git a/mail/e-mail-display.h b/mail/e-mail-display.h
new file mode 100644
index 0000000000..9f273fb26f
--- /dev/null
+++ b/mail/e-mail-display.h
@@ -0,0 +1,99 @@
+/*
+ * e-mail-display.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_DISPLAY_H
+#define E_MAIL_DISPLAY_H
+
+#include <gtkhtml/gtkhtml.h>
+#include <mail/em-format-html.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_DISPLAY \
+ (e_mail_display_get_type ())
+#define E_MAIL_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_DISPLAY, EMailDisplay))
+#define E_MAIL_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_DISPLAY, EMailDisplayClass))
+#define E_IS_MAIL_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_DISPLAY))
+#define E_IS_MAIL_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_DISPLAY))
+#define E_MAIL_DISPLAY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_DISPLAY, EMailDisplayClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailDisplay EMailDisplay;
+typedef struct _EMailDisplayClass EMailDisplayClass;
+typedef struct _EMailDisplayPrivate EMailDisplayPrivate;
+
+struct _EMailDisplay {
+ GtkHTML parent;
+ EMailDisplayPrivate *priv;
+};
+
+struct _EMailDisplayClass {
+ GtkHTMLClass parent_class;
+
+ /* Signals */
+ gboolean (*popup_event) (EMailDisplay *display,
+ GdkEventButton *event,
+ const gchar *uri,
+ EMFormatPURI *puri);
+ void (*status_message) (EMailDisplay *display,
+ const gchar *status_message);
+};
+
+GType e_mail_display_get_type (void);
+gboolean e_mail_display_get_animate (EMailDisplay *display);
+void e_mail_display_set_animate (EMailDisplay *display,
+ gboolean animate);
+gboolean e_mail_display_get_caret_mode (EMailDisplay *display);
+void e_mail_display_set_caret_mode (EMailDisplay *display,
+ gboolean caret_mode);
+EMFormatHTML * e_mail_display_get_formatter (EMailDisplay *display);
+void e_mail_display_set_formatter (EMailDisplay *display,
+ EMFormatHTML *formatter);
+const gchar * e_mail_display_get_selected_uri (EMailDisplay *display);
+void e_mail_display_set_selected_uri (EMailDisplay *display,
+ const gchar *uri);
+GtkAction * e_mail_display_get_action (EMailDisplay *display,
+ const gchar *action_name);
+GtkActionGroup *e_mail_display_add_action_group (EMailDisplay *display,
+ const gchar *group_name);
+GtkActionGroup *e_mail_display_get_action_group (EMailDisplay *display,
+ const gchar *group_name);
+GtkWidget * e_mail_display_get_popup_menu (EMailDisplay *display);
+GtkUIManager * e_mail_display_get_ui_manager (EMailDisplay *display);
+void e_mail_display_show_popup_menu (EMailDisplay *display,
+ GdkEventButton *event,
+ GtkMenuPositionFunc func,
+ gpointer user_data);
+void e_mail_display_update_actions (EMailDisplay *display);
+
+G_END_DECLS
+
+#endif /* E_MAIL_DISPLAY_H */
diff --git a/mail/e-mail-label-dialog.c b/mail/e-mail-label-dialog.c
new file mode 100644
index 0000000000..bebe0e69fb
--- /dev/null
+++ b/mail/e-mail-label-dialog.c
@@ -0,0 +1,323 @@
+/*
+ * e-mail-label-dialog.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-label-dialog.h"
+
+#include <glib/gi18n.h>
+
+#define E_MAIL_LABEL_DIALOG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_LABEL_DIALOG, EMailLabelDialogPrivate))
+
+struct _EMailLabelDialogPrivate {
+ GtkWidget *entry;
+ GtkWidget *colorsel;
+};
+
+enum {
+ PROP_0,
+ PROP_LABEL_COLOR,
+ PROP_LABEL_NAME
+};
+
+static gpointer parent_class;
+
+static void
+mail_label_dialog_entry_changed_cb (EMailLabelDialog *dialog)
+{
+ const gchar *text;
+ gboolean sensitive;
+
+ text = gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry));
+ sensitive = (text != NULL && *text != '\0');
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
+}
+
+static void
+mail_label_dialog_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_LABEL_COLOR:
+ e_mail_label_dialog_set_label_color (
+ E_MAIL_LABEL_DIALOG (object),
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_LABEL_NAME:
+ e_mail_label_dialog_set_label_name (
+ E_MAIL_LABEL_DIALOG (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_label_dialog_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdkColor color;
+
+ switch (property_id) {
+ case PROP_LABEL_COLOR:
+ e_mail_label_dialog_get_label_color (
+ E_MAIL_LABEL_DIALOG (object), &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_LABEL_NAME:
+ g_value_set_string (
+ value, e_mail_label_dialog_get_label_name (
+ E_MAIL_LABEL_DIALOG (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_label_dialog_dispose (GObject *object)
+{
+ EMailLabelDialogPrivate *priv;
+
+ priv = E_MAIL_LABEL_DIALOG_GET_PRIVATE (object);
+
+ if (priv->entry != NULL) {
+ g_object_unref (priv->entry);
+ priv->entry = NULL;
+ }
+
+ if (priv->colorsel != NULL) {
+ g_object_unref (priv->colorsel);
+ priv->colorsel = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_label_dialog_constructed (GObject *object)
+{
+ GtkWidget *action_area;
+ GtkWidget *content_area;
+
+ /* XXX Override GTK's style property defaults for GtkDialog.
+ * Hopefully GTK+ 3.0 will fix the broken defaults. */
+
+ action_area = gtk_dialog_get_action_area (GTK_DIALOG (object));
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (object));
+
+ gtk_box_set_spacing (GTK_BOX (content_area), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (object), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (action_area), 0);
+ gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
+}
+
+static void
+mail_label_dialog_class_init (EMailLabelDialogClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailLabelDialogPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_label_dialog_set_property;
+ object_class->get_property = mail_label_dialog_get_property;
+ object_class->dispose = mail_label_dialog_dispose;
+ object_class->constructed = mail_label_dialog_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_LABEL_COLOR,
+ g_param_spec_boxed (
+ "label-color",
+ "Label Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_LABEL_NAME,
+ g_param_spec_string (
+ "label-name",
+ "Label Name",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+}
+
+static void
+mail_label_dialog_init (EMailLabelDialog *dialog)
+{
+ GtkWidget *content_area;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ dialog->priv = E_MAIL_LABEL_DIALOG_GET_PRIVATE (dialog);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ gtk_dialog_add_button (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+ gtk_dialog_add_button (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_OK, GTK_RESPONSE_OK);
+
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ container = content_area;
+
+ widget = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
+ gtk_box_pack_end (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ dialog->priv->entry = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (mail_label_dialog_entry_changed_cb), dialog);
+
+ mail_label_dialog_entry_changed_cb (dialog);
+
+ widget = gtk_label_new_with_mnemonic (_("_Label name:"));
+ gtk_label_set_mnemonic_widget (
+ GTK_LABEL (widget), dialog->priv->entry);
+ gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = content_area;
+
+ widget = gtk_color_selection_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ dialog->priv->colorsel = g_object_ref (widget);
+ gtk_widget_show (widget);
+}
+
+GType
+e_mail_label_dialog_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailLabelDialogClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_label_dialog_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailLabelDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_label_dialog_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_DIALOG, "EMailLabelDialog", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_mail_label_dialog_new (GtkWindow *parent)
+{
+ return g_object_new (
+ E_TYPE_MAIL_LABEL_DIALOG,
+ "transient-for", parent, NULL);
+}
+
+const gchar *
+e_mail_label_dialog_get_label_name (EMailLabelDialog *dialog)
+{
+ GtkEntry *entry;
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_DIALOG (dialog), NULL);
+
+ entry = GTK_ENTRY (dialog->priv->entry);
+
+ return gtk_entry_get_text (entry);
+}
+
+void
+e_mail_label_dialog_set_label_name (EMailLabelDialog *dialog,
+ const gchar *label_name)
+{
+ GtkEntry *entry;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_DIALOG (dialog));
+
+ entry = GTK_ENTRY (dialog->priv->entry);
+
+ gtk_entry_set_text (entry, label_name);
+
+ g_object_notify (G_OBJECT (dialog), "label-name");
+}
+
+void
+e_mail_label_dialog_get_label_color (EMailLabelDialog *dialog,
+ GdkColor *label_color)
+{
+ GtkColorSelection *colorsel;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_DIALOG (dialog));
+ g_return_if_fail (label_color != NULL);
+
+ colorsel = GTK_COLOR_SELECTION (dialog->priv->colorsel);
+
+ gtk_color_selection_get_current_color (colorsel, label_color);
+}
+
+void
+e_mail_label_dialog_set_label_color (EMailLabelDialog *dialog,
+ const GdkColor *label_color)
+{
+ GtkColorSelection *colorsel;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_DIALOG (dialog));
+ g_return_if_fail (label_color != NULL);
+
+ colorsel = GTK_COLOR_SELECTION (dialog->priv->colorsel);
+
+ gtk_color_selection_set_current_color (colorsel, label_color);
+
+ g_object_notify (G_OBJECT (dialog), "label-color");
+}
diff --git a/mail/e-mail-label-dialog.h b/mail/e-mail-label-dialog.h
new file mode 100644
index 0000000000..17430c3607
--- /dev/null
+++ b/mail/e-mail-label-dialog.h
@@ -0,0 +1,77 @@
+/*
+ * e-mail-label-dialog.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_LABEL_DIALOG_H
+#define E_MAIL_LABEL_DIALOG_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_LABEL_DIALOG \
+ (e_mail_label_dialog_get_type ())
+#define E_MAIL_LABEL_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_LABEL_DIALOG, EMailLabelDialog))
+#define E_MAIL_LABEL_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_LABEL_DIALOG, EMailLabelDialogClass))
+#define E_IS_MAIL_LABEL_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_LABEL_DIALOG))
+#define E_IS_MAIL_LABEL_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_LABEL_DIALOG))
+#define E_MAIL_LABEL_DIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_LABEL_DIALOG, EMailLabelDialogClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailLabelDialog EMailLabelDialog;
+typedef struct _EMailLabelDialogClass EMailLabelDialogClass;
+typedef struct _EMailLabelDialogPrivate EMailLabelDialogPrivate;
+
+struct _EMailLabelDialog {
+ GtkDialog parent;
+ EMailLabelDialogPrivate *priv;
+};
+
+struct _EMailLabelDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType e_mail_label_dialog_get_type (void);
+GtkWidget * e_mail_label_dialog_new (GtkWindow *parent);
+const gchar * e_mail_label_dialog_get_label_name
+ (EMailLabelDialog *dialog);
+void e_mail_label_dialog_set_label_name
+ (EMailLabelDialog *dialog,
+ const gchar *label_name);
+void e_mail_label_dialog_get_label_color
+ (EMailLabelDialog *dialog,
+ GdkColor *label_color);
+void e_mail_label_dialog_set_label_color
+ (EMailLabelDialog *dialog,
+ const GdkColor *label_color);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LABEL_DIALOG_H */
diff --git a/mail/e-mail-label-list-store.c b/mail/e-mail-label-list-store.c
new file mode 100644
index 0000000000..1cbe927cb6
--- /dev/null
+++ b/mail/e-mail-label-list-store.c
@@ -0,0 +1,513 @@
+/*
+ * e-mail-label-list-store.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-label-list-store.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-utf8.h>
+#include "e-util/gconf-bridge.h"
+
+#define E_MAIL_LABEL_LIST_STORE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_LABEL_LIST_STORE, EMailLabelListStorePrivate))
+
+struct _EMailLabelListStorePrivate {
+ GHashTable *tag_index;
+};
+
+static struct {
+ const gchar *label_name;
+ const gchar *label_color;
+ const gchar *label_tag;
+} label_defaults[] = {
+ { N_("I_mportant"), "#EF2929", "$Labelimportant" }, /* red */
+ { N_("_Work"), "#F57900", "$Labelwork" }, /* orange */
+ { N_("_Personal"), "#4E9A06", "$Labelpersonal" }, /* green */
+ { N_("_To Do"), "#3465A4", "$Labeltodo" }, /* blue */
+ { N_("_Later"), "#75507B", "$Labellater" } /* purple */
+};
+
+static gpointer parent_class;
+
+static gchar *
+mail_label_list_store_tag_from_name (const gchar *label_name)
+{
+ gchar *label_tag;
+ gchar *temp;
+
+ /* Thunderbird compatible */
+ temp = g_ascii_strdown (label_name, -1);
+ g_strdelimit (temp, " ()/{%*<>\\\"", '_');
+ label_tag = camel_utf8_utf7 (temp);
+ g_free (temp);
+
+ return label_tag;
+}
+
+static gchar *
+mail_label_list_store_encode_label (const gchar *label_name,
+ const gchar *label_color,
+ const gchar *label_tag)
+{
+ GString *string;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ string = g_string_new (label_name);
+ g_string_append_printf (string, ":%s", label_color);
+
+ if (label_tag != NULL)
+ g_string_append_printf (string, "|%s", label_tag);
+
+ return g_string_free (string, FALSE);
+}
+
+static void
+mail_label_list_store_ensure_defaults (EMailLabelListStore *store)
+{
+ gint ii;
+
+ for (ii = 0; ii < G_N_ELEMENTS (label_defaults); ii++) {
+ GtkTreeIter iter;
+ const gchar *label_name;
+ const gchar *label_color;
+ const gchar *label_tag;
+ gchar *encoded;
+
+ label_name = gettext (label_defaults[ii].label_name);
+ label_color = label_defaults[ii].label_color;
+ label_tag = label_defaults[ii].label_tag;
+
+ encoded = mail_label_list_store_encode_label (
+ label_name, label_color, label_tag);
+
+ if (e_mail_label_list_store_lookup (store, label_tag, &iter))
+ gtk_list_store_set (
+ GTK_LIST_STORE (store),
+ &iter, 0, encoded, -1);
+ else
+ gtk_list_store_insert_with_values (
+ GTK_LIST_STORE (store),
+ NULL, -1, 0, encoded, -1);
+
+ g_free (encoded);
+ }
+}
+
+static gchar *
+mail_label_list_store_get_stock_id (EMailLabelListStore *store,
+ const gchar *color_spec)
+{
+ EMailLabelListStoreClass *class;
+ GtkIconFactory *icon_factory;
+ GdkColor color;
+ gchar *stock_id;
+
+ class = E_MAIL_LABEL_LIST_STORE_GET_CLASS (store);
+ icon_factory = class->icon_factory;
+
+ if (!gdk_color_parse (color_spec, &color))
+ return NULL;
+
+ stock_id = g_strdup_printf ("evolution-label-%s", color_spec);
+
+ /* Themes need not be taken into account here.
+ * It's just a solid block of a user-chosen color. */
+ if (gtk_icon_factory_lookup (icon_factory, stock_id) == NULL) {
+ GtkIconSet *icon_set;
+ GdkPixbuf *pixbuf;
+ guint32 pixel;
+
+ pixel = ((color.red & 0xFF00) << 16) +
+ ((color.green & 0xFF00) << 8) +
+ (color.blue & 0xFF00);
+
+ pixbuf = gdk_pixbuf_new (
+ GDK_COLORSPACE_RGB, FALSE, 8, 16, 16);
+ gdk_pixbuf_fill (pixbuf, pixel);
+
+ icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
+ gtk_icon_factory_add (icon_factory, stock_id, icon_set);
+ gtk_icon_set_unref (icon_set);
+
+ g_object_unref (pixbuf);
+ }
+
+ return stock_id;
+}
+
+static void
+mail_label_list_store_finalize (GObject *object)
+{
+ EMailLabelListStorePrivate *priv;
+
+ priv = E_MAIL_LABEL_LIST_STORE_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->tag_index);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+mail_label_list_store_constructed (GObject *object)
+{
+ EMailLabelListStore *store;
+ GtkTreeModel *model;
+ GConfBridge *bridge;
+ const gchar *key;
+
+ model = GTK_TREE_MODEL (object);
+ store = E_MAIL_LABEL_LIST_STORE (object);
+
+ bridge = gconf_bridge_get ();
+ key = "/apps/evolution/mail/labels";
+ gconf_bridge_bind_string_list_store (
+ bridge, key, GTK_LIST_STORE (store));
+
+ mail_label_list_store_ensure_defaults (store);
+}
+
+static void
+mail_label_list_store_row_inserted (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter)
+{
+ EMailLabelListStore *store;
+ GtkTreeRowReference *reference;
+ GHashTable *tag_index;
+ gchar *tag;
+
+ store = E_MAIL_LABEL_LIST_STORE (model);
+
+ /* Hash table takes ownership of both tag and reference. */
+ tag_index = store->priv->tag_index;
+ tag = e_mail_label_list_store_get_tag (store, iter);
+ reference = gtk_tree_row_reference_new (model, path);
+ g_hash_table_insert (tag_index, tag, reference);
+
+ /* We don't need to do anything special for row deletion.
+ * The reference will automatically become invalid (that's
+ * why we're storing references and not iterators or paths),
+ * so garbage collection is not important. We'll do it
+ * lazily. */
+}
+
+static void
+mail_label_list_store_class_init (EMailLabelListStoreClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailLabelListStorePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = mail_label_list_store_finalize;
+ object_class->constructed = mail_label_list_store_constructed;
+
+ class->icon_factory = gtk_icon_factory_new ();
+ gtk_icon_factory_add_default (class->icon_factory);
+}
+
+static void
+mail_label_list_store_init (EMailLabelListStore *store)
+{
+ GHashTable *tag_index;
+ GType type = G_TYPE_STRING;
+
+ tag_index = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) gtk_tree_row_reference_free);
+
+ store->priv = E_MAIL_LABEL_LIST_STORE_GET_PRIVATE (store);
+ store->priv->tag_index = tag_index;
+
+ /* XXX While it may seem awkward to cram the label name and color
+ * into a single string column, we do it for the benefit of
+ * letting GConfBridge keep the model in sync with GConf.
+ *
+ * XXX There's a valid argument to be made that this information
+ * doesn't belong in GConf in the first place. A key file
+ * under $(user_data_dir)/mail would work better. */
+ gtk_list_store_set_column_types (GTK_LIST_STORE (store), 1, &type);
+}
+
+static void
+mail_label_list_store_iface_init (GtkTreeModelIface *iface)
+{
+ iface->row_inserted = mail_label_list_store_row_inserted;
+}
+
+GType
+e_mail_label_list_store_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailLabelListStoreClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_label_list_store_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailLabelListStore),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_label_list_store_init,
+ NULL /* vaule_table */
+ };
+
+ static const GInterfaceInfo iface_info = {
+ (GInterfaceInitFunc) mail_label_list_store_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_LIST_STORE, "EMailLabelListStore",
+ &type_info, 0);
+
+ g_type_add_interface_static (
+ type, GTK_TYPE_TREE_MODEL, &iface_info);
+ }
+
+ return type;
+}
+
+EMailLabelListStore *
+e_mail_label_list_store_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_LABEL_LIST_STORE, NULL);
+}
+
+gchar *
+e_mail_label_list_store_get_name (EMailLabelListStore *store,
+ GtkTreeIter *iter)
+{
+ gchar *encoded;
+ gchar *result;
+ gchar **strv;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &encoded, -1);
+
+ strv = g_strsplit_set (encoded, ":|", 3);
+
+ if (g_strv_length (strv) >= 2)
+ result = g_strdup (gettext (strv[0]));
+ else
+ result = NULL;
+
+ g_strfreev (strv);
+
+ return result;
+}
+
+gboolean
+e_mail_label_list_store_get_color (EMailLabelListStore *store,
+ GtkTreeIter *iter,
+ GdkColor *color)
+{
+ gchar *encoded;
+ gchar **strv;
+ gboolean valid;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+ g_return_val_if_fail (color != NULL, FALSE);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &encoded, -1);
+
+ strv = g_strsplit_set (encoded, ":|", 3);
+
+ if (g_strv_length (strv) >= 2)
+ valid = gdk_color_parse (strv[1], color);
+ else
+ valid = FALSE;
+
+ g_strfreev (strv);
+
+ return valid;
+}
+
+gchar *
+e_mail_label_list_store_get_stock_id (EMailLabelListStore *store,
+ GtkTreeIter *iter)
+{
+ gchar *encoded;
+ gchar *result;
+ gchar **strv;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &encoded, -1);
+
+ strv = g_strsplit_set (encoded, ":|", 3);
+
+ if (g_strv_length (strv) >= 2)
+ result = mail_label_list_store_get_stock_id (store, strv[1]);
+ else
+ result = NULL;
+
+ g_strfreev (strv);
+
+ return result;
+}
+
+gchar *
+e_mail_label_list_store_get_tag (EMailLabelListStore *store,
+ GtkTreeIter *iter)
+{
+ gchar *encoded;
+ gchar *result;
+ gchar **strv;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &encoded, -1);
+
+ strv = g_strsplit_set (encoded, ":|", 3);
+
+ /* XXX I guess for historical reasons the default label tags have
+ * a "$Label" prefix, but the default list in GConf doesn't
+ * include tags. That's why the <tag> part is optional.
+ * So if we're missing the <tag> part, look it up in the
+ * hard-coded default list above.
+ *
+ * Not sure I got my facts straight here. Double check. */
+ if (g_strv_length (strv) >= 3)
+ result = g_strdup (strv[2]);
+ else {
+ gint ii;
+
+ result = NULL;
+
+ for (ii = 0; ii < G_N_ELEMENTS (label_defaults); ii++) {
+ const gchar *label_name;
+ const gchar *label_tag;
+
+ label_name = label_defaults[ii].label_name;
+ label_tag = label_defaults[ii].label_tag;
+
+ if (strcmp (strv[0], label_name) == 0) {
+ result = g_strdup (label_tag);
+ break;
+ }
+ }
+ }
+
+ g_strfreev (strv);
+
+ return result;
+}
+
+void
+e_mail_label_list_store_set (EMailLabelListStore *store,
+ GtkTreeIter *iter,
+ const gchar *name,
+ const GdkColor *color)
+{
+ gchar *encoded;
+ gchar *label_color;
+ gchar *label_tag = NULL;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (color != NULL);
+
+ label_color = gdk_color_to_string (color);
+
+ if (iter != NULL)
+ label_tag = e_mail_label_list_store_get_tag (store, iter);
+ if (label_tag == NULL)
+ label_tag = mail_label_list_store_tag_from_name (name);
+
+ encoded = mail_label_list_store_encode_label (
+ name, label_color, label_tag);
+
+ /* We use gtk_list_store_insert_with_values() so the data is
+ * in place when the 'row-inserted' signal is emitted and our
+ * row_inserted() method executes. */
+ if (iter != NULL)
+ gtk_list_store_set (
+ GTK_LIST_STORE (store), iter, 0, encoded, -1);
+ else
+ gtk_list_store_insert_with_values (
+ GTK_LIST_STORE (store), NULL, -1, 0, encoded, -1);
+
+ g_free (label_color);
+ g_free (label_tag);
+ g_free (encoded);
+}
+
+gboolean
+e_mail_label_list_store_lookup (EMailLabelListStore *store,
+ const gchar *tag,
+ GtkTreeIter *iter)
+{
+ GtkTreeRowReference *reference;
+ GHashTable *tag_index;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), FALSE);
+ g_return_val_if_fail (tag != NULL, FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ tag_index = store->priv->tag_index;
+ reference = g_hash_table_lookup (tag_index, tag);
+
+ if (reference == NULL)
+ return FALSE;
+
+ if (!gtk_tree_row_reference_valid (reference)) {
+ /* Garbage collect the dead reference. */
+ g_hash_table_remove (tag_index, tag);
+ return FALSE;
+ }
+
+ model = gtk_tree_row_reference_get_model (reference);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (model, iter, path);
+ gtk_tree_path_free (path);
+
+ return TRUE;
+}
+
+gboolean
+e_mail_label_tag_is_default (const gchar *tag)
+{
+ g_return_val_if_fail (tag != NULL, FALSE);
+
+ return g_str_has_prefix (tag, "$Label");
+}
diff --git a/mail/e-mail-label-list-store.h b/mail/e-mail-label-list-store.h
new file mode 100644
index 0000000000..a9093eaa08
--- /dev/null
+++ b/mail/e-mail-label-list-store.h
@@ -0,0 +1,85 @@
+/*
+ * e-mail-label-list-store.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_LABEL_LIST_STORE_H
+#define E_MAIL_LABEL_LIST_STORE_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_LABEL_LIST_STORE \
+ (e_mail_label_list_store_get_type ())
+#define E_MAIL_LABEL_LIST_STORE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_LABEL_LIST_STORE, EMailLabelListStore))
+#define E_MAIL_LABEL_LIST_STORE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_LABEL_LIST_STORE, EMailLabelListStoreClass))
+#define E_IS_MAIL_LABEL_LIST_STORE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_LABEL_LIST_STORE))
+#define E_IS_MAIL_LABEL_LIST_STORE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_LABEL_LIST_STORE))
+#define E_MAIL_LABEL_LIST_STORE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_LABEL_LIST_STORE, EMailLabelListStoreClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailLabelListStore EMailLabelListStore;
+typedef struct _EMailLabelListStoreClass EMailLabelListStoreClass;
+typedef struct _EMailLabelListStorePrivate EMailLabelListStorePrivate;
+
+struct _EMailLabelListStore {
+ GtkListStore parent;
+ EMailLabelListStorePrivate *priv;
+};
+
+struct _EMailLabelListStoreClass {
+ GtkListStoreClass parent_class;
+ GtkIconFactory *icon_factory;
+};
+
+GType e_mail_label_list_store_get_type (void);
+EMailLabelListStore *
+ e_mail_label_list_store_new (void);
+gchar * e_mail_label_list_store_get_name (EMailLabelListStore *store,
+ GtkTreeIter *iter);
+gboolean e_mail_label_list_store_get_color (EMailLabelListStore *store,
+ GtkTreeIter *iter,
+ GdkColor *color);
+gchar * e_mail_label_list_store_get_stock_id (EMailLabelListStore *store,
+ GtkTreeIter *iter);
+gchar * e_mail_label_list_store_get_tag (EMailLabelListStore *store,
+ GtkTreeIter *iter);
+void e_mail_label_list_store_set (EMailLabelListStore *store,
+ GtkTreeIter *iter,
+ const gchar *name,
+ const GdkColor *color);
+gboolean e_mail_label_list_store_lookup (EMailLabelListStore *store,
+ const gchar *tag,
+ GtkTreeIter *iter);
+gboolean e_mail_label_tag_is_default (const gchar *tag);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LABEL_LIST_STORE_H */
diff --git a/mail/e-mail-label-manager.c b/mail/e-mail-label-manager.c
new file mode 100644
index 0000000000..212a0507ad
--- /dev/null
+++ b/mail/e-mail-label-manager.c
@@ -0,0 +1,479 @@
+/*
+ * e-mail-label-manager.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-label-manager.h"
+
+#include <glib/gi18n.h>
+#include "e-mail-label-dialog.h"
+#include "e-mail-label-tree-view.h"
+
+#define E_MAIL_LABEL_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManagerPrivate))
+
+struct _EMailLabelManagerPrivate {
+ GtkWidget *tree_view;
+ GtkWidget *add_button;
+ GtkWidget *edit_button;
+ GtkWidget *remove_button;
+};
+
+enum {
+ PROP_0,
+ PROP_LIST_STORE
+};
+
+enum {
+ ADD_LABEL,
+ EDIT_LABEL,
+ REMOVE_LABEL,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+mail_label_manager_selection_changed_cb (EMailLabelManager *manager,
+ GtkTreeSelection *selection)
+{
+ GtkWidget *edit_button;
+ GtkWidget *remove_button;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ edit_button = manager->priv->edit_button;
+ remove_button = manager->priv->remove_button;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ EMailLabelListStore *store;
+ gboolean sensitive;
+ gchar *label_tag;
+
+ store = E_MAIL_LABEL_LIST_STORE (model);
+ label_tag = e_mail_label_list_store_get_tag (store, &iter);
+ sensitive = !e_mail_label_tag_is_default (label_tag);
+ g_free (label_tag);
+
+ /* Disallow removing default labels. */
+ gtk_widget_set_sensitive (edit_button, TRUE);
+ gtk_widget_set_sensitive (remove_button, sensitive);
+ } else {
+ gtk_widget_set_sensitive (edit_button, FALSE);
+ gtk_widget_set_sensitive (remove_button, FALSE);
+ }
+}
+
+static void
+mail_label_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_LIST_STORE:
+ e_mail_label_manager_set_list_store (
+ E_MAIL_LABEL_MANAGER (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_label_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_LIST_STORE:
+ g_value_set_object (
+ value, e_mail_label_manager_get_list_store (
+ E_MAIL_LABEL_MANAGER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_label_manager_dispose (GObject *object)
+{
+ EMailLabelManagerPrivate *priv;
+
+ priv = E_MAIL_LABEL_MANAGER_GET_PRIVATE (object);
+
+ if (priv->tree_view != NULL) {
+ g_object_unref (priv->tree_view);
+ priv->tree_view = NULL;
+ }
+
+ if (priv->add_button != NULL) {
+ g_object_unref (priv->add_button);
+ priv->add_button = NULL;
+ }
+
+ if (priv->edit_button != NULL) {
+ g_object_unref (priv->edit_button);
+ priv->edit_button = NULL;
+ }
+
+ if (priv->remove_button != NULL) {
+ g_object_unref (priv->remove_button);
+ priv->remove_button = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_label_manager_add_label (EMailLabelManager *manager)
+{
+ EMailLabelDialog *label_dialog;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkWidget *dialog;
+ gpointer parent;
+ GdkColor label_color;
+ const gchar *label_name;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+ dialog = e_mail_label_dialog_new (parent);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Add Label"));
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ label_dialog = E_MAIL_LABEL_DIALOG (dialog);
+ label_name = e_mail_label_dialog_get_label_name (label_dialog);
+ e_mail_label_dialog_get_label_color (label_dialog, &label_color);
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ model = gtk_tree_view_get_model (tree_view);
+
+ e_mail_label_list_store_set (
+ E_MAIL_LABEL_LIST_STORE (model),
+ NULL, label_name, &label_color);
+
+exit:
+ gtk_widget_destroy (dialog);
+}
+
+static void
+mail_label_manager_edit_label (EMailLabelManager *manager)
+{
+ EMailLabelDialog *label_dialog;
+ EMailLabelListStore *label_store;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *dialog;
+ GtkWidget *parent;
+ GdkColor label_color;
+ const gchar *new_name;
+ gchar *label_name;
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ label_store = E_MAIL_LABEL_LIST_STORE (model);
+ label_name = e_mail_label_list_store_get_name (label_store, &iter);
+ e_mail_label_list_store_get_color (label_store, &iter, &label_color);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ dialog = e_mail_label_dialog_new (GTK_WINDOW (parent));
+ label_dialog = E_MAIL_LABEL_DIALOG (dialog);
+
+ e_mail_label_dialog_set_label_name (label_dialog, label_name);
+ e_mail_label_dialog_set_label_color (label_dialog, &label_color);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Label"));
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ new_name = e_mail_label_dialog_get_label_name (label_dialog);
+ e_mail_label_dialog_get_label_color (label_dialog, &label_color);
+
+ e_mail_label_list_store_set (
+ label_store, &iter, new_name, &label_color);
+
+exit:
+ gtk_widget_destroy (dialog);
+
+ g_free (label_name);
+}
+
+static void
+mail_label_manager_remove_label (EMailLabelManager *manager)
+{
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+}
+
+static void
+mail_label_manager_class_init (EMailLabelManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailLabelManagerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_label_manager_set_property;
+ object_class->get_property = mail_label_manager_get_property;
+ object_class->dispose = mail_label_manager_dispose;
+
+ class->add_label = mail_label_manager_add_label;
+ class->edit_label = mail_label_manager_edit_label;
+ class->remove_label = mail_label_manager_remove_label;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_LIST_STORE,
+ g_param_spec_object (
+ "list-store",
+ "List Store",
+ NULL,
+ E_TYPE_MAIL_LABEL_LIST_STORE,
+ G_PARAM_READWRITE));
+
+ signals[ADD_LABEL] = g_signal_new (
+ "add-label",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailLabelManagerClass, add_label),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[EDIT_LABEL] = g_signal_new (
+ "edit-label",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailLabelManagerClass, edit_label),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[REMOVE_LABEL] = g_signal_new (
+ "remove-label",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailLabelManagerClass, remove_label),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+mail_label_manager_init (EMailLabelManager *manager)
+{
+ GtkTreeSelection *selection;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ manager->priv = E_MAIL_LABEL_MANAGER_GET_PRIVATE (manager);
+
+ gtk_table_resize (GTK_TABLE (manager), 2, 2);
+ gtk_table_set_col_spacings (GTK_TABLE (manager), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (manager), 12);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_table_attach (
+ GTK_TABLE (container), widget, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_mail_label_tree_view_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ manager->priv->tree_view = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (mail_label_manager_selection_changed_cb),
+ manager);
+
+ container = GTK_WIDGET (manager);
+
+ /* FIXME Clarify this. What menu? */
+ widget = gtk_label_new (
+ _("Note: Underscore in the label name is used\n"
+ "as mnemonic identifier in menu."));
+ gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_CENTER);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 0, 1, 1, 2, 0, 0, 0, 0);
+ gtk_widget_show (widget);
+
+ widget = gtk_vbutton_box_new ();
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (widget), 6);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 0, 2, 0, GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->add_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_label_manager_add_label), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->edit_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_label_manager_edit_label), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->remove_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_label_manager_remove_label), manager);
+}
+
+GType
+e_mail_label_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailLabelManagerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_label_manager_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailLabelManager),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_label_manager_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "EMailLabelManager", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_mail_label_manager_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_LABEL_MANAGER, NULL);
+}
+
+void
+e_mail_label_manager_add_label (EMailLabelManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
+
+ g_signal_emit (manager, signals[ADD_LABEL], 0);
+}
+
+void
+e_mail_label_manager_edit_label (EMailLabelManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
+
+ g_signal_emit (manager, signals[EDIT_LABEL], 0);
+}
+
+void
+e_mail_label_manager_remove_label (EMailLabelManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
+
+ g_signal_emit (manager, signals[REMOVE_LABEL], 0);
+}
+
+EMailLabelListStore *
+e_mail_label_manager_get_list_store (EMailLabelManager *manager)
+{
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_MANAGER (manager), NULL);
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ model = gtk_tree_view_get_model (tree_view);
+
+ return E_MAIL_LABEL_LIST_STORE (model);
+}
+
+void
+e_mail_label_manager_set_list_store (EMailLabelManager *manager,
+ EMailLabelListStore *list_store)
+{
+ GtkTreeView *tree_view;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
+ g_return_if_fail (E_IS_MAIL_LABEL_LIST_STORE (list_store));
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
+
+ g_object_notify (G_OBJECT (manager), "list-store");
+}
diff --git a/mail/e-mail-label-manager.h b/mail/e-mail-label-manager.h
new file mode 100644
index 0000000000..20d375efc0
--- /dev/null
+++ b/mail/e-mail-label-manager.h
@@ -0,0 +1,81 @@
+/*
+ * e-mail-label-manager.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_LABEL_MANAGER_H
+#define E_MAIL_LABEL_MANAGER_H
+
+#include <gtk/gtk.h>
+#include <mail/e-mail-label-list-store.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_LABEL_MANAGER \
+ (e_mail_label_manager_get_type ())
+#define E_MAIL_LABEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManager))
+#define E_MAIL_LABEL_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManagerClass))
+#define E_IS_MAIL_LABEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_LABEL_MANAGER))
+#define E_IS_MAIL_LABEL_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_LABEL_MANAGER))
+#define E_MAIL_LABEL_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManagerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailLabelManager EMailLabelManager;
+typedef struct _EMailLabelManagerClass EMailLabelManagerClass;
+typedef struct _EMailLabelManagerPrivate EMailLabelManagerPrivate;
+
+struct _EMailLabelManager {
+ GtkTable parent;
+ EMailLabelManagerPrivate *priv;
+};
+
+struct _EMailLabelManagerClass {
+ GtkTableClass parent_class;
+
+ void (*add_label) (EMailLabelManager *manager);
+ void (*edit_label) (EMailLabelManager *manager);
+ void (*remove_label) (EMailLabelManager *manager);
+};
+
+GType e_mail_label_manager_get_type (void);
+GtkWidget * e_mail_label_manager_new (void);
+void e_mail_label_manager_add_label (EMailLabelManager *manager);
+void e_mail_label_manager_edit_label (EMailLabelManager *manager);
+void e_mail_label_manager_remove_label
+ (EMailLabelManager *manager);
+EMailLabelListStore *
+ e_mail_label_manager_get_list_store
+ (EMailLabelManager *manager);
+void e_mail_label_manager_set_list_store
+ (EMailLabelManager *manager,
+ EMailLabelListStore *list_store);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LABEL_MANAGER_H */
diff --git a/mail/e-mail-label-tree-view.c b/mail/e-mail-label-tree-view.c
new file mode 100644
index 0000000000..808d8d060a
--- /dev/null
+++ b/mail/e-mail-label-tree-view.c
@@ -0,0 +1,136 @@
+/*
+ * e-mail-label-tree-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-label-tree-view.h"
+
+#include <glib/gi18n.h>
+#include "e-mail-label-list-store.h"
+
+#define E_MAIL_LABEL_TREE_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_LABEL_TREE_VIEW, EMailLabelTreeViewPrivate))
+
+struct _EMailLabelTreeViewPrivate {
+ gint placeholder;
+};
+
+static gpointer parent_class;
+
+static void
+mail_label_tree_view_render_pixbuf (GtkTreeViewColumn *column,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ EMailLabelTreeView *tree_view)
+{
+ EMailLabelListStore *store;
+ gchar *stock_id;
+
+ store = E_MAIL_LABEL_LIST_STORE (model);
+ stock_id = e_mail_label_list_store_get_stock_id (store, iter);
+ g_object_set (renderer, "stock-id", stock_id, NULL);
+ g_free (stock_id);
+}
+
+static void
+mail_label_tree_view_render_text (GtkTreeViewColumn *column,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ EMailLabelTreeView *tree_view)
+{
+ EMailLabelListStore *store;
+ gchar *name;
+
+ store = E_MAIL_LABEL_LIST_STORE (model);
+ name = e_mail_label_list_store_get_name (store, iter);
+ g_object_set (renderer, "text", name, NULL);
+ g_free (name);
+}
+
+static void
+mail_label_tree_view_class_init (EMailLabelTreeViewClass *class)
+{
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailLabelTreeViewPrivate));
+}
+
+static void
+mail_label_tree_view_init (EMailLabelTreeView *tree_view)
+{
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ tree_view->priv = E_MAIL_LABEL_TREE_VIEW_GET_PRIVATE (tree_view);
+
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_set_title (column, _("Color"));
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+
+ gtk_tree_view_column_set_cell_data_func (
+ column, renderer, (GtkTreeCellDataFunc)
+ mail_label_tree_view_render_pixbuf, tree_view, NULL);
+
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_set_title (column, _("Name"));
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+
+ gtk_tree_view_column_set_cell_data_func (
+ column, renderer, (GtkTreeCellDataFunc)
+ mail_label_tree_view_render_text, tree_view, NULL);
+}
+
+GType
+e_mail_label_tree_view_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailLabelTreeViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_label_tree_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailLabelTreeView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_label_tree_view_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TREE_VIEW, "EMailLabelTreeView",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_mail_label_tree_view_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_LABEL_TREE_VIEW, NULL);
+}
diff --git a/mail/e-mail-label-tree-view.h b/mail/e-mail-label-tree-view.h
new file mode 100644
index 0000000000..0dd58f2152
--- /dev/null
+++ b/mail/e-mail-label-tree-view.h
@@ -0,0 +1,66 @@
+/*
+ * e-mail-label-tree-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_LABEL_TREE_VIEW_H
+#define E_MAIL_LABEL_TREE_VIEW_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_LABEL_TREE_VIEW \
+ (e_mail_label_tree_view_get_type ())
+#define E_MAIL_LABEL_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_LABEL_TREE_VIEW, EMailLabelTreeView))
+#define E_MAIL_LABEL_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_LABEL_TREE_VIEW, EMailLabelTreeViewClass))
+#define E_IS_MAIL_LABEL_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_LABEL_TREE_VIEW))
+#define E_IS_MAIL_LABEL_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_LABEL_TREE_VIEW))
+#define E_MAIL_LABEL_TREE_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_LABEL_TREE_VIEW, EMailLabelTreeViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailLabelTreeView EMailLabelTreeView;
+typedef struct _EMailLabelTreeViewClass EMailLabelTreeViewClass;
+typedef struct _EMailLabelTreeViewPrivate EMailLabelTreeViewPrivate;
+
+struct _EMailLabelTreeView {
+ GtkTreeView parent;
+ EMailLabelTreeViewPrivate *priv;
+};
+
+struct _EMailLabelTreeViewClass {
+ GtkTreeViewClass parent_class;
+};
+
+GType e_mail_label_tree_view_get_type (void);
+GtkWidget * e_mail_label_tree_view_new (void);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LABEL_TREE_VIEW_H */
diff --git a/mail/e-mail-local.c b/mail/e-mail-local.c
new file mode 100644
index 0000000000..0944c7da95
--- /dev/null
+++ b/mail/e-mail-local.c
@@ -0,0 +1,130 @@
+/*
+ * e-mail-local.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-local.h"
+
+#include <glib/gi18n.h>
+
+#include "mail/mail-session.h"
+
+#define CHECK_LOCAL_FOLDER_TYPE(type) \
+ ((type) < G_N_ELEMENTS (default_local_folders))
+
+/* The array elements correspond to EMailLocalFolder. */
+static struct {
+ const gchar *display_name;
+ CamelFolder *folder;
+ gchar *folder_uri;
+} default_local_folders[] = {
+ { N_("Inbox") },
+ { N_("Drafts") },
+ { N_("Outbox") },
+ { N_("Sent") },
+ { N_("Templates") },
+ { "Inbox" } /* "always local" inbox */
+};
+
+static CamelStore *local_store;
+
+void
+e_mail_local_init (const gchar *data_dir)
+{
+ static gboolean initialized = FALSE;
+ CamelException ex;
+ CamelService *service;
+ CamelURL *url;
+ gchar *temp;
+ gint ii;
+
+ g_return_if_fail (!initialized);
+ g_return_if_fail (data_dir != NULL);
+
+ camel_exception_init (&ex);
+
+ url = camel_url_new ("mbox:", NULL);
+ temp = g_build_filename (data_dir, "local", NULL);
+ camel_url_set_path (url, temp);
+ g_free (temp);
+
+ temp = camel_url_to_string (url, 0);
+ service = camel_session_get_service (
+ session, temp, CAMEL_PROVIDER_STORE, &ex);
+ g_free (temp);
+
+ if (camel_exception_is_set (&ex))
+ goto fail;
+
+ /* Populate the rest of the default_local_folders array. */
+ for (ii = 0; ii < G_N_ELEMENTS (default_local_folders); ii++) {
+ const gchar *display_name;
+ gchar *folder_uri;
+
+ display_name = default_local_folders[ii].display_name;
+
+ /* XXX Should this URI be account relative? */
+ camel_url_set_fragment (url, display_name);
+ folder_uri = camel_url_to_string (url, 0);
+
+ default_local_folders[ii].folder_uri = folder_uri;
+ default_local_folders[ii].folder = camel_store_get_folder (
+ CAMEL_STORE (service), display_name,
+ CAMEL_STORE_FOLDER_CREATE, &ex);
+
+ camel_exception_clear (&ex);
+ }
+
+ camel_url_free (url);
+
+ camel_object_ref (service);
+ local_store = CAMEL_STORE (service);
+
+ return;
+
+fail:
+ g_warning ("Could not initialize local store/folder: %s", ex.desc);
+
+ camel_exception_clear (&ex);
+ camel_url_free (url);
+}
+
+CamelFolder *
+e_mail_local_get_folder (EMailLocalFolder type)
+{
+ g_return_val_if_fail (CHECK_LOCAL_FOLDER_TYPE (type), NULL);
+
+ return default_local_folders[type].folder;
+}
+
+const gchar *
+e_mail_local_get_folder_uri (EMailLocalFolder type)
+{
+ g_return_val_if_fail (CHECK_LOCAL_FOLDER_TYPE (type), NULL);
+
+ return default_local_folders[type].folder_uri;
+}
+
+CamelStore *
+e_mail_local_get_store (void)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (local_store), NULL);
+
+ return local_store;
+}
diff --git a/mail/e-mail-local.h b/mail/e-mail-local.h
new file mode 100644
index 0000000000..b8dda29857
--- /dev/null
+++ b/mail/e-mail-local.h
@@ -0,0 +1,51 @@
+/*
+ * e-mail-local.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_LOCAL_H
+#define E_MAIL_LOCAL_H
+
+#include <glib.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-store.h>
+
+G_BEGIN_DECLS
+
+/* XXX E_MAIL_FOLDER_TEMPLATES is a prime example of why templates
+ * should be a core feature: the mailer now has to know about
+ * this specific plugin, which defeats the purpose of plugins. */
+typedef enum {
+ E_MAIL_FOLDER_INBOX,
+ E_MAIL_FOLDER_DRAFTS,
+ E_MAIL_FOLDER_OUTBOX,
+ E_MAIL_FOLDER_SENT,
+ E_MAIL_FOLDER_TEMPLATES,
+ E_MAIL_FOLDER_LOCAL_INBOX,
+ E_MAIL_NUM_LOCAL_FOLDERS
+} EMailLocalFolder;
+
+void e_mail_local_init (const gchar *data_dir);
+CamelFolder * e_mail_local_get_folder (EMailLocalFolder type);
+const gchar * e_mail_local_get_folder_uri (EMailLocalFolder type);
+CamelStore * e_mail_local_get_store (void);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LOCAL_H */
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
new file mode 100644
index 0000000000..ddede8c2ce
--- /dev/null
+++ b/mail/e-mail-reader-utils.c
@@ -0,0 +1,587 @@
+/*
+ * e-mail-reader-utils.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* Miscellaneous utility functions used by EMailReader actions. */
+
+#include "e-mail-reader-utils.h"
+
+#include <glib/gi18n.h>
+#include <gtkhtml/gtkhtml.h>
+#include <camel/camel-mime-message.h>
+#include <camel/camel-vee-folder.h>
+#include <camel/camel-vee-store.h>
+
+#include "e-util/e-error.h"
+#include "filter/filter-rule.h"
+
+#include "mail/e-mail-browser.h"
+#include "mail/em-composer-utils.h"
+#include "mail/em-format-html-print.h"
+#include "mail/em-utils.h"
+#include "mail/mail-autofilter.h"
+#include "mail/mail-ops.h"
+#include "mail/mail-tools.h"
+#include "mail/mail-vfolder.h"
+
+void
+e_mail_reader_activate (EMailReader *reader,
+ const gchar *action_name)
+{
+ GtkActionGroup *action_group;
+ GtkAction *action;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+ g_return_if_fail (action_name != NULL);
+
+ action_group = e_mail_reader_get_action_group (reader);
+ action = gtk_action_group_get_action (action_group, action_name);
+ g_return_if_fail (action != NULL);
+
+ gtk_action_activate (action);
+}
+
+gboolean
+e_mail_reader_confirm_delete (EMailReader *reader)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWidget *check_button;
+ GtkWidget *content_area;
+ GtkWidget *dialog;
+ GtkWindow *window;
+ const gchar *label;
+ gboolean prompt_delete_in_vfolder;
+ gint response;
+
+ /* Remind users what deleting from a search folder does. */
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ folder = message_list->folder;
+
+ prompt_delete_in_vfolder = e_shell_settings_get_boolean (
+ shell_settings, "mail-prompt-delete-in-vfolder");
+
+ if (!CAMEL_IS_VEE_STORE (folder->parent_store))
+ return TRUE;
+
+ if (!prompt_delete_in_vfolder)
+ return TRUE;
+
+ dialog = e_error_new (
+ window, "mail:ask-delete-vfolder-msg",
+ folder->full_name, NULL);
+
+ /* XXX e-error should provide a widget layout and API suitable
+ * for packing additional widgets to the right of the alert
+ * icon. But for now, screw it. */
+
+ label = _("Do not ask me again");
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ check_button = gtk_check_button_new_with_label (label);
+ gtk_box_pack_start (
+ GTK_BOX (content_area), check_button, TRUE, TRUE, 6);
+ gtk_widget_show (check_button);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_OK)
+ e_shell_settings_set_boolean (
+ shell_settings,
+ "mail-prompt-delete-in-vfolder",
+ gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (check_button)));
+
+ gtk_widget_destroy (dialog);
+
+ return (response == GTK_RESPONSE_OK);
+}
+
+void
+e_mail_reader_mark_as_read (EMailReader *reader,
+ const gchar *uid)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelFolder *folder;
+ guint32 mask, set;
+ guint32 flags;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+ g_return_if_fail (uid != NULL);
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ flags = camel_folder_get_message_flags (folder, uid);
+
+ if (!(flags & CAMEL_MESSAGE_SEEN)) {
+ CamelMimeMessage *message;
+
+ message = ((EMFormat *) html_display)->message;
+ em_utils_handle_receipt (folder, uid, message);
+ }
+
+ mask = CAMEL_MESSAGE_SEEN;
+ set = CAMEL_MESSAGE_SEEN;
+ camel_folder_set_message_flags (folder, uid, mask, set);
+}
+
+guint
+e_mail_reader_mark_selected (EMailReader *reader,
+ guint32 mask,
+ guint32 set)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+ guint ii;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ if (folder == NULL)
+ return 0;
+
+ camel_folder_freeze (folder);
+ uids = message_list_get_selected (message_list);
+
+ for (ii = 0; ii < uids->len; ii++)
+ camel_folder_set_message_flags (
+ folder, uids->pdata[ii], mask, set);
+
+ message_list_free_uids (message_list, uids);
+ camel_folder_thaw (folder);
+
+ return ii;
+}
+
+guint
+e_mail_reader_open_selected (EMailReader *reader)
+{
+ EShellBackend *shell_backend;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *views;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+ guint ii;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
+
+ message_list = e_mail_reader_get_message_list (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len >= 10) {
+ gchar *len_str;
+ gboolean proceed;
+
+ len_str = g_strdup_printf ("%d", uids->len);
+
+ proceed = em_utils_prompt_user (
+ window, "/apps/evolution/mail/prompts/open_many",
+ "mail:ask-open-many", len_str, NULL);
+
+ g_free (len_str);
+
+ if (!proceed) {
+ message_list_free_uids (message_list, uids);
+ return 0;
+ }
+ }
+
+ if (em_utils_folder_is_drafts (folder, folder_uri) ||
+ em_utils_folder_is_outbox (folder, folder_uri) ||
+ em_utils_folder_is_templates (folder, folder_uri)) {
+ em_utils_edit_messages (folder, uids, TRUE);
+ return uids->len;
+ }
+
+ views = g_ptr_array_new ();
+
+ /* For vfolders we need to edit the original, not the vfolder copy. */
+ for (ii = 0; ii < uids->len; ii++) {
+ const gchar *uid = uids->pdata[ii];
+ CamelFolder *real_folder;
+ CamelMessageInfo *info;
+ gchar *real_folder_uri;
+ gchar *real_uid;
+
+ if (!CAMEL_IS_VEE_FOLDER (folder)) {
+ g_ptr_array_add (views, g_strdup (uid));
+ continue;
+ }
+
+ info = camel_folder_get_message_info (folder, uid);
+ if (info == NULL)
+ continue;
+
+ real_folder = camel_vee_folder_get_location (
+ CAMEL_VEE_FOLDER (folder),
+ (CamelVeeMessageInfo *) info, &real_uid);
+ real_folder_uri = mail_tools_folder_to_url (real_folder);
+
+ if (em_utils_folder_is_drafts (real_folder, real_folder_uri) ||
+ em_utils_folder_is_outbox (real_folder, real_folder_uri)) {
+ GPtrArray *edits;
+
+ edits = g_ptr_array_new ();
+ g_ptr_array_add (edits, real_uid);
+ em_utils_edit_messages (real_folder, edits, TRUE);
+ } else {
+ g_free (real_uid);
+ g_ptr_array_add (views, g_strdup (uid));
+ }
+
+ g_free (real_folder_uri);
+ }
+
+ for (ii = 0; ii < views->len; ii++) {
+ const gchar *uid = views->pdata[ii];
+ GtkWidget *browser;
+
+ browser = e_mail_browser_new (shell_backend);
+ e_mail_reader_set_folder (
+ E_MAIL_READER (browser), folder, folder_uri);
+ e_mail_reader_set_message (E_MAIL_READER (browser), uid);
+ gtk_widget_show (browser);
+ }
+
+ g_ptr_array_free (views, TRUE);
+
+ message_list_free_uids (message_list, uids);
+
+ return ii;
+}
+
+void
+e_mail_reader_print (EMailReader *reader,
+ GtkPrintOperationAction action)
+{
+ MessageList *message_list;
+ EMFormatHTMLDisplay *html_display;
+ EMFormatHTMLPrint *html_print;
+ CamelFolder *folder;
+ GPtrArray *uids;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ g_return_if_fail (folder != NULL);
+
+ /* XXX Learn to handle len > 1. */
+ uids = message_list_get_selected (message_list);
+ if (uids->len != 1)
+ goto exit;
+
+ html_print = em_format_html_print_new (
+ (EMFormatHTML *) html_display, action);
+ em_format_merge_handler (
+ (EMFormat *) html_print,
+ (EMFormat *) html_display);
+ em_format_html_print_message (html_print, folder, uids->pdata[0]);
+ g_object_unref (html_print);
+
+exit:
+ message_list_free_uids (message_list, uids);
+}
+
+/* Helper for e_mail_reader_reply_to_message()
+ * XXX This function belongs in e-html-utils.c */
+static gboolean
+html_contains_nonwhitespace (const gchar *html,
+ gint len)
+{
+ const gchar *cp;
+ gunichar uc = 0;
+
+ if (html == NULL || len <= 0)
+ return FALSE;
+
+ cp = html;
+
+ while (cp != NULL && cp - html < len) {
+ uc = g_utf8_get_char (cp);
+ if (uc == 0)
+ break;
+
+ if (uc == '<') {
+ /* skip until next '>' */
+ uc = g_utf8_get_char (cp);
+ while (uc != 0 && uc != '>' && cp - html < len) {
+ cp = g_utf8_next_char (cp);
+ uc = g_utf8_get_char (cp);
+ }
+ if (uc == 0)
+ break;
+ } else if (uc == '&') {
+ /* sequence '&nbsp;' is a space */
+ if (g_ascii_strncasecmp (cp, "&nbsp;", 6) == 0)
+ cp = cp + 5;
+ else
+ break;
+ } else if (!g_unichar_isspace (uc))
+ break;
+
+ cp = g_utf8_next_char (cp);
+ }
+
+ return cp - html < len - 1 && uc != 0;
+}
+
+void
+e_mail_reader_reply_to_message (EMailReader *reader,
+ gint reply_mode)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelMimeMessage *new_message;
+ CamelMimeMessage *src_message;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GtkHTML *html;
+ struct _camel_header_raw *header;
+ const gchar *uid;
+ gchar *selection = NULL;
+ gint length;
+
+ /* This handles quoting only selected text in the reply. If
+ * nothing is selected or only whitespace is selected, fall
+ * back to the normal em_utils_reply_to_message(). */
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = ((EMFormatHTML *) html_display)->html;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uid = message_list->cursor_uid;
+ g_return_if_fail (uid != NULL);
+
+ if (!gtk_html_command (html, "is-selection-active"))
+ goto whole_message;
+
+ selection = gtk_html_get_selection_html (html, &length);
+ if (selection == NULL || *selection == '\0')
+ goto whole_message;
+
+ if (!html_contains_nonwhitespace (selection, length))
+ goto whole_message;
+
+ src_message =
+ CAMEL_MIME_MESSAGE (((EMFormat *) html_display)->message);
+ new_message = camel_mime_message_new ();
+
+ /* Filter out "content-*" headers. */
+ header = CAMEL_MIME_PART (src_message)->headers;
+ while (header != NULL) {
+ if (g_ascii_strncasecmp (header->name, "content-", 8) != 0)
+ camel_medium_add_header (
+ CAMEL_MEDIUM (new_message),
+ header->name, header->value);
+ }
+
+ camel_mime_part_set_encoding (
+ CAMEL_MIME_PART (new_message),
+ CAMEL_TRANSFER_ENCODING_8BIT);
+
+ camel_mime_part_set_content (
+ CAMEL_MIME_PART (new_message),
+ selection, length, "text/html");
+
+ em_utils_reply_to_message (
+ folder, uid, new_message, reply_mode, NULL);
+
+ g_free (selection);
+
+ return;
+
+whole_message:
+ em_utils_reply_to_message (
+ folder, uid, NULL, reply_mode, (EMFormat *) html_display);
+}
+
+void
+e_mail_reader_select_next_message (EMailReader *reader,
+ gboolean or_else_previous)
+{
+ MessageList *message_list;
+ gboolean hide_deleted;
+ gboolean success;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ hide_deleted = e_mail_reader_get_hide_deleted (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ success = message_list_select (
+ message_list, MESSAGE_LIST_SELECT_NEXT, 0, 0);
+
+ if (!success && (hide_deleted || or_else_previous))
+ message_list_select (
+ message_list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
+}
+
+/* Helper for e_mail_reader_create_filter_from_selected() */
+static void
+mail_reader_create_filter_cb (CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *message,
+ gpointer user_data)
+{
+ struct {
+ const gchar *source;
+ gint type;
+ } *filter_data = user_data;
+
+ if (message != NULL)
+ filter_gui_add_from_message (
+ message, filter_data->source, filter_data->type);
+
+ g_free (filter_data);
+}
+
+void
+e_mail_reader_create_filter_from_selected (EMailReader *reader,
+ gint filter_type)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ const gchar *filter_source;
+ const gchar *folder_uri;
+ GPtrArray *uids;
+
+ struct {
+ const gchar *source;
+ gint type;
+ } *filter_data;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+
+ if (em_utils_folder_is_sent (folder, folder_uri))
+ filter_source = FILTER_SOURCE_OUTGOING;
+ else if (em_utils_folder_is_outbox (folder, folder_uri))
+ filter_source = FILTER_SOURCE_OUTGOING;
+ else
+ filter_source = FILTER_SOURCE_INCOMING;
+
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len == 1) {
+ filter_data = g_malloc (sizeof (*filter_data));
+ filter_data->source = filter_source;
+ filter_data->type = filter_type;
+
+ mail_get_message (
+ folder, uids->pdata[0],
+ mail_reader_create_filter_cb,
+ filter_data, mail_msg_unordered_push);
+ }
+
+ em_utils_uids_free (uids);
+}
+
+/* Helper for e_mail_reader_create_vfolder_from_selected() */
+static void
+mail_reader_create_vfolder_cb (CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *message,
+ gpointer user_data)
+{
+ struct {
+ gchar *uri;
+ gint type;
+ } *vfolder_data = user_data;
+
+ if (message != NULL)
+ vfolder_gui_add_from_message (
+ message, vfolder_data->type, vfolder_data->uri);
+
+ g_free (vfolder_data->uri);
+ g_free (vfolder_data);
+}
+
+void
+e_mail_reader_create_vfolder_from_selected (EMailReader *reader,
+ gint vfolder_type)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ const gchar *folder_uri;
+ GPtrArray *uids;
+
+ struct {
+ gchar *uri;
+ gint type;
+ } *vfolder_data;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len == 1) {
+ vfolder_data = g_malloc (sizeof (*vfolder_data));
+ vfolder_data->uri = g_strdup (folder_uri);
+ vfolder_data->type = vfolder_type;
+
+ mail_get_message (
+ folder, uids->pdata[0],
+ mail_reader_create_vfolder_cb,
+ vfolder_data, mail_msg_unordered_push);
+ }
+
+ em_utils_uids_free (uids);
+}
diff --git a/mail/e-mail-reader-utils.h b/mail/e-mail-reader-utils.h
new file mode 100644
index 0000000000..46c3ea7345
--- /dev/null
+++ b/mail/e-mail-reader-utils.h
@@ -0,0 +1,56 @@
+/*
+ * e-mail-reader-utils.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* Miscellaneous utility functions used by EMailReader actions. */
+
+#ifndef E_MAIL_READER_UTILS_H
+#define E_MAIL_READER_UTILS_H
+
+#include <mail/e-mail-reader.h>
+
+G_BEGIN_DECLS
+
+void e_mail_reader_activate (EMailReader *reader,
+ const gchar *action_name);
+gboolean e_mail_reader_confirm_delete (EMailReader *reader);
+void e_mail_reader_mark_as_read (EMailReader *reader,
+ const gchar *uid);
+guint e_mail_reader_mark_selected (EMailReader *reader,
+ guint32 mask,
+ guint32 set);
+guint e_mail_reader_open_selected (EMailReader *reader);
+void e_mail_reader_print (EMailReader *reader,
+ GtkPrintOperationAction action);
+void e_mail_reader_reply_to_message (EMailReader *reader,
+ gint reply_mode);
+void e_mail_reader_select_next_message
+ (EMailReader *reader,
+ gboolean or_else_previous);
+void e_mail_reader_create_filter_from_selected
+ (EMailReader *reader,
+ gint filter_type);
+void e_mail_reader_create_vfolder_from_selected
+ (EMailReader *reader,
+ gint filter_type);
+
+G_END_DECLS
+
+#endif /* E_MAIL_READER_UTILS_H */
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
new file mode 100644
index 0000000000..7497cf8029
--- /dev/null
+++ b/mail/e-mail-reader.c
@@ -0,0 +1,2752 @@
+/*
+ * e-mail-reader.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-reader.h"
+
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
+
+#ifdef HAVE_XFREE
+#include <X11/XF86keysym.h>
+#endif
+
+#include "e-util/e-binding.h"
+#include "e-util/e-charset.h"
+#include "e-util/e-util.h"
+#include "e-util/gconf-bridge.h"
+#include "shell/e-shell.h"
+#include "widgets/misc/e-popup-action.h"
+
+#include "mail/e-mail-browser.h"
+#include "mail/e-mail-display.h"
+#include "mail/e-mail-reader-utils.h"
+#include "mail/em-composer-utils.h"
+#include "mail/em-event.h"
+#include "mail/em-folder-selector.h"
+#include "mail/em-folder-tree.h"
+#include "mail/em-utils.h"
+#include "mail/mail-autofilter.h"
+#include "mail/mail-config.h"
+#include "mail/mail-ops.h"
+#include "mail/mail-vfolder.h"
+
+enum {
+ CHANGED,
+ FOLDER_LOADED,
+ SHOW_SEARCH_BAR,
+ LAST_SIGNAL
+};
+
+/* Remembers the previously selected folder when transferring messages. */
+static gchar *default_xfer_messages_uri;
+
+static guint signals[LAST_SIGNAL];
+
+static void
+action_mail_add_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelMessageInfo *info;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *address;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len != 1)
+ goto exit;
+
+ info = camel_folder_get_message_info (folder, uids->pdata[0]);
+ if (info == NULL)
+ goto exit;
+
+ address = camel_message_info_from (info);
+ if (address == NULL || *address == '\0')
+ goto exit;
+
+ em_utils_add_address (window, address);
+
+exit:
+ em_utils_uids_free (uids);
+}
+
+static void
+action_mail_charset_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ const gchar *charset;
+
+ if (action != current)
+ return;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ charset = g_object_get_data (G_OBJECT (action), "charset");
+
+ /* Charset for "Default" action will be NULL. */
+ em_format_set_charset (EM_FORMAT (html_display), charset);
+}
+
+static void
+action_mail_check_for_junk_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ mail_filter_junk (folder, uids);
+}
+
+static void
+action_mail_clipboard_copy_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_copy (html);
+}
+
+static void
+action_mail_copy_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWidget *folder_tree;
+ GtkWidget *dialog;
+ GPtrArray *selected;
+ const gchar *uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder_tree = em_folder_tree_new ();
+ selected = message_list_get_selected (message_list);
+
+ folder = message_list->folder;
+
+ em_folder_tree_set_excluded (
+ EM_FOLDER_TREE (folder_tree),
+ EMFT_EXCLUDE_NOSELECT | EMFT_EXCLUDE_VIRTUAL |
+ EMFT_EXCLUDE_VTRASH);
+
+ dialog = em_folder_selector_new (
+ EM_FOLDER_TREE (folder_tree),
+ EM_FOLDER_SELECTOR_CAN_CREATE,
+ _("Select Folder"), NULL, _("C_opy"));
+
+ if (default_xfer_messages_uri != NULL)
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog),
+ default_xfer_messages_uri);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ uri = em_folder_selector_get_selected_uri (
+ EM_FOLDER_SELECTOR (dialog));
+
+ g_free (default_xfer_messages_uri);
+ default_xfer_messages_uri = g_strdup (uri);
+
+ if (uri != NULL) {
+ mail_transfer_messages (
+ folder, selected, FALSE, uri, 0, NULL, NULL);
+ selected = NULL;
+ }
+
+exit:
+ if (selected != NULL)
+ em_utils_uids_free (selected);
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_mail_delete_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
+ guint32 set = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
+
+ if (!e_mail_reader_confirm_delete (reader))
+ return;
+
+ /* FIXME Verify all selected messages are deletable.
+ * But handle it by disabling this action. */
+
+ if (e_mail_reader_mark_selected (reader, mask, set) == 1)
+ e_mail_reader_select_next_message (reader, FALSE);
+}
+
+static void
+action_mail_filter_on_mailing_list_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_filter_from_selected (reader, AUTO_MLIST);
+}
+
+static void
+action_mail_filter_on_recipients_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_filter_from_selected (reader, AUTO_TO);
+}
+
+static void
+action_mail_filter_on_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_filter_from_selected (reader, AUTO_FROM);
+}
+
+static void
+action_mail_filter_on_subject_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_filter_from_selected (reader, AUTO_SUBJECT);
+}
+
+static void
+action_mail_filters_apply_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ mail_filter_on_demand (folder, uids);
+}
+
+static void
+action_mail_find_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_show_search_bar (reader);
+}
+
+static void
+action_mail_flag_clear_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_flag_for_followup_clear (window, folder, uids);
+
+ em_format_redraw (EM_FORMAT (html_display));
+}
+
+static void
+action_mail_flag_completed_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_flag_for_followup_completed (window, folder, uids);
+
+ em_format_redraw (EM_FORMAT (html_display));
+}
+
+static void
+action_mail_flag_for_followup_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_flag_for_followup (reader, folder, uids);
+}
+
+static void
+action_mail_forward_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_forward_messages (folder, uids, folder_uri);
+}
+
+static void
+action_mail_forward_attached_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_forward_attached (folder, uids, folder_uri);
+}
+
+static void
+action_mail_forward_inline_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_forward_inline (folder, uids, folder_uri);
+}
+
+static void
+action_mail_forward_quoted_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_forward_quoted (folder, uids, folder_uri);
+}
+
+static void
+action_mail_load_images_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+
+ html_display = e_mail_reader_get_html_display (reader);
+
+ em_format_html_load_images (EM_FORMAT_HTML (html_display));
+}
+
+static void
+action_mail_mark_important_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_DELETED;
+ guint32 set = CAMEL_MESSAGE_FLAGGED;
+
+ e_mail_reader_mark_selected (reader, mask, set);
+}
+
+static void
+action_mail_mark_junk_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_JUNK |
+ CAMEL_MESSAGE_NOTJUNK | CAMEL_MESSAGE_JUNK_LEARN;
+ guint32 set = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_JUNK |
+ CAMEL_MESSAGE_JUNK_LEARN;
+
+ if (e_mail_reader_mark_selected (reader, mask, set) == 1)
+ e_mail_reader_select_next_message (reader, TRUE);
+}
+
+static void
+action_mail_mark_notjunk_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK |
+ CAMEL_MESSAGE_JUNK_LEARN;
+ guint32 set = CAMEL_MESSAGE_NOTJUNK | CAMEL_MESSAGE_JUNK_LEARN;
+
+ if (e_mail_reader_mark_selected (reader, mask, set) == 1)
+ e_mail_reader_select_next_message (reader, TRUE);
+}
+
+static void
+action_mail_mark_read_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_SEEN;
+ guint32 set = CAMEL_MESSAGE_SEEN;
+
+ e_mail_reader_mark_selected (reader, mask, set);
+}
+
+static void
+action_mail_mark_unimportant_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_FLAGGED;
+ guint32 set = 0;
+
+ e_mail_reader_mark_selected (reader, mask, set);
+}
+
+static void
+action_mail_mark_unread_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
+ guint32 set = 0;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ e_mail_reader_mark_selected (reader, mask, set);
+
+ if (message_list->seen_id != 0) {
+ g_source_remove (message_list->seen_id);
+ message_list->seen_id = 0;
+ }
+}
+
+static void
+action_mail_message_edit_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ window = e_mail_reader_get_window (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_edit_messages (folder, uids, FALSE);
+}
+
+static void
+action_mail_message_new_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ GtkWindow *window;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ em_utils_compose_new_message (message_list->folder_uri);
+}
+
+static void
+action_mail_message_open_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_open_selected (reader);
+}
+
+static void
+action_mail_move_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWidget *folder_tree;
+ GtkWidget *dialog;
+ GPtrArray *selected;
+ const gchar *uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder_tree = em_folder_tree_new ();
+ selected = message_list_get_selected (message_list);
+
+ folder = message_list->folder;
+
+ em_folder_tree_set_excluded (
+ EM_FOLDER_TREE (folder_tree),
+ EMFT_EXCLUDE_NOSELECT | EMFT_EXCLUDE_VIRTUAL |
+ EMFT_EXCLUDE_VTRASH);
+
+ dialog = em_folder_selector_new (
+ EM_FOLDER_TREE (folder_tree),
+ EM_FOLDER_SELECTOR_CAN_CREATE,
+ _("Select Folder"), NULL, _("_Move"));
+
+ if (default_xfer_messages_uri != NULL)
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog),
+ default_xfer_messages_uri);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ uri = em_folder_selector_get_selected_uri (
+ EM_FOLDER_SELECTOR (dialog));
+
+ g_free (default_xfer_messages_uri);
+ default_xfer_messages_uri = g_strdup (uri);
+
+ if (uri != NULL) {
+ mail_transfer_messages (
+ folder, selected, TRUE, uri, 0, NULL, NULL);
+ selected = NULL;
+ }
+
+exit:
+ if (selected != NULL)
+ em_utils_uids_free (selected);
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_mail_next_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_NEXT;
+ flags = 0;
+ mask = 0;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_next_important_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
+ flags = CAMEL_MESSAGE_FLAGGED;
+ mask = CAMEL_MESSAGE_FLAGGED;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_next_thread_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select_next_thread (message_list);
+}
+
+static void
+action_mail_next_unread_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
+ flags = 0;
+ mask = CAMEL_MESSAGE_SEEN;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_previous_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_PREVIOUS;
+ flags = 0;
+ mask = 0;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_previous_important_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
+ flags = CAMEL_MESSAGE_FLAGGED;
+ mask = CAMEL_MESSAGE_FLAGGED;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_previous_unread_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
+ flags = 0;
+ mask = CAMEL_MESSAGE_SEEN;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_print_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ GtkPrintOperationAction print_action;
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ e_mail_reader_print (reader, print_action);
+}
+
+static void
+action_mail_print_preview_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ GtkPrintOperationAction print_action;
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
+ e_mail_reader_print (reader, print_action);
+}
+
+static void
+action_mail_redirect_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ const gchar *uid;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uid = message_list->cursor_uid;
+ g_return_if_fail (uid != NULL);
+
+ em_utils_redirect_message_by_uid (folder, uid);
+}
+
+static void
+action_mail_reply_all_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_reply_to_message (reader, REPLY_MODE_ALL);
+}
+
+static void
+action_mail_reply_list_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_reply_to_message (reader, REPLY_MODE_LIST);
+}
+
+static void
+action_mail_reply_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_reply_to_message (reader, REPLY_MODE_SENDER);
+}
+
+static void
+action_mail_save_as_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_save_messages (window, folder, uids);
+}
+
+static void
+action_mail_search_folder_from_mailing_list_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_vfolder_from_selected (reader, AUTO_MLIST);
+}
+
+static void
+action_mail_search_folder_from_recipients_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_vfolder_from_selected (reader, AUTO_TO);
+}
+
+static void
+action_mail_search_folder_from_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_vfolder_from_selected (reader, AUTO_FROM);
+}
+
+static void
+action_mail_search_folder_from_subject_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_vfolder_from_selected (reader, AUTO_SUBJECT);
+}
+
+static void
+action_mail_select_all_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+ const gchar *action_name;
+ gboolean selection_active;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_select_all (html);
+
+ action_name = "mail-clipboard-copy";
+ action = e_mail_reader_get_action (reader, action_name);
+ selection_active = gtk_html_command (html, "is-selection-active");
+ gtk_action_set_sensitive (action, selection_active);
+}
+
+static void
+action_mail_show_all_headers_cb (GtkToggleAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ em_format_mode_t mode;
+
+ html_display = e_mail_reader_get_html_display (reader);
+
+ if (gtk_toggle_action_get_active (action))
+ mode = EM_FORMAT_ALLHEADERS;
+ else
+ mode = EM_FORMAT_NORMAL;
+
+ em_format_set_mode (EM_FORMAT (html_display), mode);
+}
+
+static void
+action_mail_show_source_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ EShellBackend *shell_backend;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWidget *browser;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+ g_return_if_fail (uids->len > 0);
+
+ browser = e_mail_browser_new (shell_backend);
+ reader = E_MAIL_READER (browser);
+ html_display = e_mail_reader_get_html_display (reader);
+ em_format_set_mode (EM_FORMAT (html_display), EM_FORMAT_SOURCE);
+ e_mail_reader_set_folder (reader, folder, folder_uri);
+ e_mail_reader_set_message (reader, uids->pdata[0]);
+ gtk_widget_show (browser);
+
+ message_list_free_uids (message_list, uids);
+}
+
+static void
+action_mail_toggle_important_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+ guint ii;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ camel_folder_freeze (folder);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ guint32 flags;
+
+ flags = camel_folder_get_message_flags (
+ folder, uids->pdata[ii]);
+ flags ^= CAMEL_MESSAGE_FLAGGED;
+ if (flags & CAMEL_MESSAGE_FLAGGED)
+ flags &= ~CAMEL_MESSAGE_DELETED;
+ camel_folder_set_message_flags (
+ folder, uids->pdata[ii], CAMEL_MESSAGE_FLAGGED |
+ CAMEL_MESSAGE_DELETED, flags);
+ }
+
+ camel_folder_thaw (folder);
+
+ message_list_free_uids (message_list, uids);
+}
+
+static void
+action_mail_undelete_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_DELETED;
+ guint32 set = 0;
+
+ e_mail_reader_mark_selected (reader, mask, set);
+}
+
+static void
+action_mail_zoom_100_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_zoom_reset (html);
+}
+
+static void
+action_mail_zoom_in_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_zoom_out (html);
+}
+
+static void
+action_mail_zoom_out_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_zoom_out (html);
+}
+
+static void
+action_search_folder_recipient_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ EMailDisplay *display;
+ CamelURL *curl;
+ const gchar *uri;
+
+ /* This action is defined in EMailDisplay. */
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ if (curl->path != NULL && *curl->path != '\0') {
+ CamelInternetAddress *inet_addr;
+ const gchar *folder_uri;
+
+ /* Ensure vfolder is running. */
+ vfolder_load_storage ();
+
+ folder_uri = message_list->folder_uri;
+
+ inet_addr = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
+ vfolder_gui_add_from_address (inet_addr, AUTO_TO, folder_uri);
+ camel_object_unref (inet_addr);
+ }
+
+ camel_url_free (curl);
+}
+
+static void
+action_search_folder_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ EMailDisplay *display;
+ CamelURL *curl;
+ const gchar *uri;
+
+ /* This action is defined in EMailDisplay. */
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ if (curl->path != NULL && *curl->path != '\0') {
+ CamelInternetAddress *inet_addr;
+ const gchar *folder_uri;
+
+ /* Ensure vfolder is running. */
+ vfolder_load_storage ();
+
+ folder_uri = message_list->folder_uri;
+
+ inet_addr = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
+ vfolder_gui_add_from_address (inet_addr, AUTO_FROM, folder_uri);
+ camel_object_unref (inet_addr);
+ }
+
+ camel_url_free (curl);
+}
+
+static GtkActionEntry mail_reader_entries[] = {
+
+ { "mail-add-sender",
+ NULL,
+ N_("A_dd Sender to Address Book"),
+ NULL,
+ N_("Add sender to address book"),
+ G_CALLBACK (action_mail_add_sender_cb) },
+
+ { "mail-check-for-junk",
+ "mail-mark-junk",
+ N_("Check for _Junk"),
+ NULL,
+ N_("Filter the selected messages for junk status"),
+ G_CALLBACK (action_mail_check_for_junk_cb) },
+
+ { "mail-clipboard-copy",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy selected messages to the clipboard"),
+ G_CALLBACK (action_mail_clipboard_copy_cb) },
+
+ { "mail-copy",
+ "mail-copy",
+ N_("_Copy to Folder..."),
+ "<Shift><Control>y",
+ N_("Copy selected messages to another folder"),
+ G_CALLBACK (action_mail_copy_cb) },
+
+ { "mail-delete",
+ "user-trash",
+ N_("_Delete Message"),
+ "<Control>d",
+ N_("Mark the selected messages for deletion"),
+ G_CALLBACK (action_mail_delete_cb) },
+
+ { "mail-filter-on-mailing-list",
+ NULL,
+ N_("Filter on Mailing _List..."),
+ NULL,
+ N_("Create a rule to filter messages to this mailing list"),
+ G_CALLBACK (action_mail_filter_on_mailing_list_cb) },
+
+ { "mail-filter-on-recipients",
+ NULL,
+ N_("Filter on _Recipients..."),
+ NULL,
+ N_("Create a rule to filter messages to these recipients"),
+ G_CALLBACK (action_mail_filter_on_recipients_cb) },
+
+ { "mail-filter-on-sender",
+ NULL,
+ N_("Filter on Se_nder..."),
+ NULL,
+ N_("Create a rule to filter messages from this sender"),
+ G_CALLBACK (action_mail_filter_on_sender_cb) },
+
+ { "mail-filter-on-subject",
+ NULL,
+ N_("Filter on _Subject..."),
+ NULL,
+ N_("Create a rule to filter messages with this subject"),
+ G_CALLBACK (action_mail_filter_on_subject_cb) },
+
+ { "mail-filters-apply",
+ "stock_mail-filters-apply",
+ N_("A_pply Filters"),
+ "<Control>y",
+ N_("Apply filter rules to the selected messages"),
+ G_CALLBACK (action_mail_filters_apply_cb) },
+
+ { "mail-find",
+ GTK_STOCK_FIND,
+ N_("_Find in Message..."),
+ "<Shift><Control>f",
+ N_("Search for text in the body of the displayed message"),
+ G_CALLBACK (action_mail_find_cb) },
+
+ { "mail-flag-clear",
+ NULL,
+ N_("_Clear Flag"),
+ NULL,
+ N_("Remove the follow-up flag from the selected messages"),
+ G_CALLBACK (action_mail_flag_clear_cb) },
+
+ { "mail-flag-completed",
+ NULL,
+ N_("_Flag Completed"),
+ NULL,
+ N_("Set the follow-up flag to completed on the selected messages"),
+ G_CALLBACK (action_mail_flag_completed_cb) },
+
+ { "mail-flag-for-followup",
+ "stock_mail-flag-for-followup",
+ N_("Follow _Up..."),
+ "<Shift><Control>g",
+ N_("Flag the selected messages for follow-up"),
+ G_CALLBACK (action_mail_flag_for_followup_cb) },
+
+ { "mail-forward",
+ "mail-forward",
+ N_("_Forward"),
+ "<Control>f",
+ N_("Forward the selected message to someone"),
+ G_CALLBACK (action_mail_forward_cb) },
+
+ { "mail-forward-attached",
+ NULL,
+ N_("_Attached"),
+ NULL,
+ N_("Forward the selected message to someone as an attachment"),
+ G_CALLBACK (action_mail_forward_attached_cb) },
+
+ { "mail-forward-inline",
+ NULL,
+ N_("_Inline"),
+ NULL,
+ N_("Forward the selected message in the body of a new message"),
+ G_CALLBACK (action_mail_forward_inline_cb) },
+
+ { "mail-forward-quoted",
+ NULL,
+ N_("_Quoted"),
+ NULL,
+ N_("Forward the selected message quoted like a reply"),
+ G_CALLBACK (action_mail_forward_quoted_cb) },
+
+ { "mail-load-images",
+ "image-x-generic",
+ N_("_Load Images"),
+ "<Control>i",
+ N_("Force images in HTML mail to be loaded"),
+ G_CALLBACK (action_mail_load_images_cb) },
+
+ { "mail-mark-important",
+ "mail-mark-important",
+ N_("_Important"),
+ NULL,
+ N_("Mark the selected messages as important"),
+ G_CALLBACK (action_mail_mark_important_cb) },
+
+ { "mail-mark-junk",
+ "mail-mark-junk",
+ N_("_Junk"),
+ "<Control>j",
+ N_("Mark the selected messages as junk"),
+ G_CALLBACK (action_mail_mark_junk_cb) },
+
+ { "mail-mark-notjunk",
+ "mail-mark-notjunk",
+ N_("_Not Junk"),
+ "<Shift><Control>j",
+ N_("Mark the selected messasges as not being junk"),
+ G_CALLBACK (action_mail_mark_notjunk_cb) },
+
+ { "mail-mark-read",
+ "mail-mark-read",
+ N_("_Read"),
+ "<Control>k",
+ N_("Mark the selected messages as having been read"),
+ G_CALLBACK (action_mail_mark_read_cb) },
+
+ { "mail-mark-unimportant",
+ NULL,
+ N_("Uni_mportant"),
+ NULL,
+ N_("Mark the selected messages as unimportant"),
+ G_CALLBACK (action_mail_mark_unimportant_cb) },
+
+ { "mail-mark-unread",
+ "mail-mark-unread",
+ N_("_Unread"),
+ "<Shift><Control>k",
+ N_("Mark the selected messages as not having been read"),
+ G_CALLBACK (action_mail_mark_unread_cb) },
+
+ { "mail-message-edit",
+ NULL,
+ N_("_Edit as New Message..."),
+ NULL,
+ N_("Open the selected messages in the composer for editing"),
+ G_CALLBACK (action_mail_message_edit_cb) },
+
+ { "mail-message-new",
+ "mail-message-new",
+ N_("Compose _New Message"),
+ "<Shift><Control>m",
+ N_("Open a window for composing a mail message"),
+ G_CALLBACK (action_mail_message_new_cb) },
+
+ { "mail-message-open",
+ NULL,
+ N_("_Open in New Window"),
+ "<Control>o",
+ N_("Open the selected messages in a new window"),
+ G_CALLBACK (action_mail_message_open_cb) },
+
+ { "mail-move",
+ "mail-move",
+ N_("_Move to Folder..."),
+ "<Shift><Control>v",
+ N_("Move selected messages to another folder"),
+ G_CALLBACK (action_mail_move_cb) },
+
+ { "mail-next",
+ GTK_STOCK_GO_FORWARD,
+ N_("_Next Message"),
+ "<Control>Page_Down",
+ N_("Display the next message"),
+ G_CALLBACK (action_mail_next_cb) },
+
+ { "mail-next-important",
+ NULL,
+ N_("Next _Important Message"),
+ NULL,
+ N_("Display the next important message"),
+ G_CALLBACK (action_mail_next_important_cb) },
+
+ { "mail-next-thread",
+ NULL,
+ N_("Next _Thread"),
+ NULL,
+ N_("Display the next thread"),
+ G_CALLBACK (action_mail_next_thread_cb) },
+
+ { "mail-next-unread",
+ NULL,
+ N_("Next _Unread Message"),
+ "<Control>bracketright",
+ N_("Display the next unread message"),
+ G_CALLBACK (action_mail_next_unread_cb) },
+
+ { "mail-previous",
+ GTK_STOCK_GO_BACK,
+ N_("_Previous Message"),
+ "<Control>Page_Up",
+ N_("Display the previous message"),
+ G_CALLBACK (action_mail_previous_cb) },
+
+ { "mail-previous-important",
+ NULL,
+ N_("Pr_evious Important Message"),
+ NULL,
+ N_("Display the previous important message"),
+ G_CALLBACK (action_mail_previous_important_cb) },
+
+ { "mail-previous-unread",
+ NULL,
+ N_("P_revious Unread Message"),
+ "<Control>bracketleft",
+ N_("Display the previous unread message"),
+ G_CALLBACK (action_mail_previous_unread_cb) },
+
+ { "mail-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ "<Control>p",
+ N_("Print this message"),
+ G_CALLBACK (action_mail_print_cb) },
+
+ { "mail-print-preview",
+ GTK_STOCK_PRINT_PREVIEW,
+ NULL,
+ NULL,
+ N_("Preview the message to be printed"),
+ G_CALLBACK (action_mail_print_preview_cb) },
+
+ { "mail-redirect",
+ NULL,
+ N_("Re_direct"),
+ NULL,
+ N_("Redirect (bounce) the selected message to someone"),
+ G_CALLBACK (action_mail_redirect_cb) },
+
+ { "mail-reply-all",
+ "mail-reply-all",
+ N_("Reply to _All"),
+ "<Shift><Control>r",
+ N_("Compose a reply to all the recipients of the selected message"),
+ G_CALLBACK (action_mail_reply_all_cb) },
+
+ { "mail-reply-list",
+ NULL,
+ N_("Reply to _List"),
+ "<Control>l",
+ N_("Compose a reply to the mailing list of the selected message"),
+ G_CALLBACK (action_mail_reply_list_cb) },
+
+ { "mail-reply-sender",
+ "mail-reply-sender",
+ N_("_Reply to Sender"),
+ "<Control>r",
+ N_("Compose a reply to the sender of the selected message"),
+ G_CALLBACK (action_mail_reply_sender_cb) },
+
+ { "mail-save-as",
+ GTK_STOCK_SAVE_AS,
+ N_("_Save as mbox..."),
+ NULL,
+ N_("Save selected messages as an mbox file"),
+ G_CALLBACK (action_mail_save_as_cb) },
+
+ { "mail-search-folder-from-mailing-list",
+ NULL,
+ N_("Search Folder from Mailing _List..."),
+ NULL,
+ N_("Create a search folder for this mailing list"),
+ G_CALLBACK (action_mail_search_folder_from_mailing_list_cb) },
+
+ { "mail-search-folder-from-recipients",
+ NULL,
+ N_("Search Folder from Recipien_ts..."),
+ NULL,
+ N_("Create a search folder for these recipients"),
+ G_CALLBACK (action_mail_search_folder_from_recipients_cb) },
+
+ { "mail-search-folder-from-sender",
+ NULL,
+ N_("Search Folder from Sen_der..."),
+ NULL,
+ N_("Create a search folder for this sender"),
+ G_CALLBACK (action_mail_search_folder_from_sender_cb) },
+
+ { "mail-search-folder-from-subject",
+ NULL,
+ N_("Search Folder from S_ubject..."),
+ NULL,
+ N_("Create a search folder for this subject"),
+ G_CALLBACK (action_mail_search_folder_from_subject_cb) },
+
+ { "mail-select-all",
+ NULL,
+ N_("Select _All Text"),
+ "<Shift><Control>x",
+ N_("Select all the text in a message"),
+ G_CALLBACK (action_mail_select_all_cb) },
+
+ { "mail-show-source",
+ NULL,
+ N_("_Message Source"),
+ "<Control>u",
+ N_("Show the raw email source of the message"),
+ G_CALLBACK (action_mail_show_source_cb) },
+
+ { "mail-toggle-important",
+ NULL,
+ NULL, /* No menu item; key press only */
+ NULL,
+ NULL,
+ G_CALLBACK (action_mail_toggle_important_cb) },
+
+ { "mail-undelete",
+ NULL,
+ N_("_Undelete Message"),
+ "<Shift><Control>d",
+ N_("Undelete the selected messages"),
+ G_CALLBACK (action_mail_undelete_cb) },
+
+ { "mail-zoom-100",
+ GTK_STOCK_ZOOM_100,
+ N_("_Normal Size"),
+ "<Control>0",
+ N_("Reset the text to its original size"),
+ G_CALLBACK (action_mail_zoom_100_cb) },
+
+ { "mail-zoom-in",
+ GTK_STOCK_ZOOM_IN,
+ N_("_Zoom In"),
+ "<Control>plus",
+ N_("Increase the text size"),
+ G_CALLBACK (action_mail_zoom_in_cb) },
+
+ { "mail-zoom-out",
+ GTK_STOCK_ZOOM_OUT,
+ N_("Zoom _Out"),
+ "<Control>minus",
+ N_("Decrease the text size"),
+ G_CALLBACK (action_mail_zoom_out_cb) },
+
+ /*** Menus ***/
+
+ { "mail-create-rule-menu",
+ NULL,
+ N_("Create R_ule"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-encoding-menu",
+ NULL,
+ N_("Ch_aracter Encoding"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-forward-as-menu",
+ NULL,
+ N_("F_orward As"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-goto-menu",
+ GTK_STOCK_JUMP_TO,
+ N_("_Go To"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-mark-as-menu",
+ NULL,
+ N_("Mar_k As"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-message-menu",
+ NULL,
+ N_("_Message"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-zoom-menu",
+ NULL,
+ N_("_Zoom"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static EPopupActionEntry mail_reader_popup_entries[] = {
+
+ { "mail-popup-copy",
+ NULL,
+ "mail-copy" },
+
+ { "mail-popup-delete",
+ NULL,
+ "mail-delete" },
+
+ { "mail-popup-flag-for-followup",
+ N_("Mark for Follo_w Up..."),
+ "mail-flag-for-followup" },
+
+ { "mail-popup-forward",
+ NULL,
+ "mail-forward" },
+
+ { "mail-popup-mark-important",
+ N_("Mark as _Important"),
+ "mail-mark-important" },
+
+ { "mail-popup-mark-junk",
+ N_("Mark as _Junk"),
+ "mail-mark-junk" },
+
+ { "mail-popup-mark-notjunk",
+ N_("Mark as _Not Junk"),
+ "mail-mark-notjunk" },
+
+ { "mail-popup-mark-read",
+ N_("Mar_k as Read"),
+ "mail-mark-read" },
+
+ { "mail-popup-mark-unimportant",
+ N_("Mark as Uni_mportant"),
+ "mail-mark-unimportant" },
+
+ { "mail-popup-mark-unread",
+ N_("Mark as _Unread"),
+ "mail-mark-unread" },
+
+ { "mail-popup-message-edit",
+ NULL,
+ "mail-message-edit" },
+
+ { "mail-popup-move",
+ NULL,
+ "mail-move" },
+
+ { "mail-popup-print",
+ NULL,
+ "mail-print" },
+
+ { "mail-popup-reply-all",
+ NULL,
+ "mail-reply-all" },
+
+ { "mail-popup-reply-sender",
+ NULL,
+ "mail-reply-sender" },
+
+ { "mail-popup-save-as",
+ NULL,
+ "mail-save-as" },
+
+ { "mail-popup-undelete",
+ NULL,
+ "mail-undelete" }
+};
+
+static GtkToggleActionEntry mail_reader_toggle_entries[] = {
+
+ { "mail-caret-mode",
+ NULL,
+ N_("_Caret Mode"),
+ "F7",
+ N_("Show a blinking cursor in the body of displayed messages"),
+ NULL, /* No callback required */
+ FALSE },
+
+ { "mail-show-all-headers",
+ NULL,
+ N_("All Message _Headers"),
+ NULL,
+ N_("Show messages with all email headers"),
+ G_CALLBACK (action_mail_show_all_headers_cb),
+ FALSE }
+};
+
+static gboolean
+mail_reader_button_release_event_cb (EMailReader *reader,
+ GdkEventButton *button,
+ GtkHTML *html)
+{
+ GtkAction *action;
+ const gchar *action_name;
+ gboolean selection_active;
+
+ action_name = "mail-clipboard-copy";
+ action = e_mail_reader_get_action (reader, action_name);
+ selection_active = gtk_html_command (html, "is-selection-active");
+ gtk_action_set_sensitive (action, selection_active);
+
+ return FALSE;
+}
+
+static void
+mail_reader_double_click_cb (EMailReader *reader,
+ gint row,
+ ETreePath path,
+ gint col,
+ GdkEvent *event)
+{
+ /* Ignore double clicks on columns that handle their own state. */
+ if (MESSAGE_LIST_COLUMN_IS_ACTIVE (col))
+ return;
+
+ e_mail_reader_activate (reader, "mail-message-open");
+}
+
+static gboolean
+mail_reader_key_press_event_cb (EMailReader *reader,
+ GdkEventKey *event)
+{
+ const gchar *action_name;
+
+ if ((event->state & GDK_CONTROL_MASK) != 0)
+ goto ctrl;
+
+ /* <keyval> alone */
+ switch (event->keyval) {
+ case GDK_Delete:
+ case GDK_KP_Delete:
+ action_name = "mail-delete";
+ break;
+
+ case GDK_Return:
+ case GDK_KP_Enter:
+ case GDK_ISO_Enter:
+ action_name = "mail-message-open";
+ break;
+
+ case GDK_period:
+ case GDK_bracketleft:
+ action_name = "mail-next-unread";
+ break;
+
+ case GDK_comma:
+ case GDK_bracketright:
+ action_name = "mail-previous-unread";
+ break;
+
+#ifdef HAVE_XFREE
+ case XF86XK_Reply:
+ action_name = "mail-reply-all";
+ break;
+
+ case XF86XK_MailForward:
+ action_name = "mail-forward";
+ break;
+#endif
+
+ case GDK_exclam:
+ action_name = "mail-toggle-important";
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ goto exit;
+
+ctrl:
+
+ /* Ctrl + <keyval> */
+ switch (event->keyval) {
+ case GDK_period:
+ action_name = "mail-next-unread";
+ break;
+
+ case GDK_comma:
+ action_name = "mail-previous-unread";
+ break;
+
+ default:
+ return FALSE;
+ }
+
+exit:
+ e_mail_reader_activate (reader, action_name);
+
+ return TRUE;
+}
+
+static gint
+mail_reader_key_press_cb (EMailReader *reader,
+ gint row,
+ ETreePath path,
+ gint col,
+ GdkEvent *event)
+{
+ return mail_reader_key_press_event_cb (reader, &event->key);
+}
+
+static gboolean
+mail_reader_message_read_cb (EMailReader *reader)
+{
+ MessageList *message_list;
+ const gchar *uid;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ uid = g_object_get_data (G_OBJECT (reader), "mark-read-uid");
+ g_return_val_if_fail (uid != NULL, FALSE);
+
+ if (g_strcmp0 (message_list->cursor_uid, uid) == 0)
+ e_mail_reader_mark_as_read (reader, uid);
+
+ return FALSE;
+}
+
+static void
+mail_reader_message_loaded_cb (CamelFolder *folder,
+ const gchar *message_uid,
+ CamelMimeMessage *message,
+ gpointer user_data,
+ CamelException *ex)
+{
+ EMailReader *reader = user_data;
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EShell *shell;
+ EMEvent *event;
+ EMEventTargetMessage *target;
+ gboolean mark_read;
+ gint timeout_interval;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ /* If the user picked a different message in the time it took
+ * to fetch this message, then don't bother rendering it. */
+ if (g_strcmp0 (message_list->cursor_uid, message_uid) != 0)
+ return;
+
+ /** @Event: message.reading
+ * @Title: Viewing a message
+ * @Target: EMEventTargetMessage
+ *
+ * message.reading is emitted whenever a user views a message.
+ */
+ event = em_event_peek ();
+ target = em_event_target_new_message (
+ event, folder, message, message_uid, 0, NULL);
+ e_event_emit (
+ (EEvent *) event, "message.reading",
+ (EEventTarget *) target);
+
+ em_format_format (
+ EM_FORMAT (html_display), folder, message_uid, message);
+
+ /* Reset the shell view icon. */
+ e_shell_event (shell, "mail-icon", (gpointer) "evolution-mail");
+
+ /* Determine whether to mark the message as read. */
+ mark_read = e_shell_settings_get_boolean (
+ shell_settings, "mail-mark-seen");
+ timeout_interval = e_shell_settings_get_int (
+ shell_settings, "mail-mark-seen-timeout");
+
+ g_object_set_data_full (
+ G_OBJECT (reader), "mark-read-uid",
+ g_strdup (message_uid), (GDestroyNotify) g_free);
+
+ if (message_list->seen_id > 0)
+ g_source_remove (message_list->seen_id);
+
+ if (mark_read) {
+ message_list->seen_id = g_timeout_add (
+ timeout_interval, (GSourceFunc)
+ mail_reader_message_read_cb, reader);
+
+ } else if (camel_exception_is_set (ex)) {
+ GtkHTMLStream *stream;
+
+ /* Display the error inline and clear the exception. */
+ stream = gtk_html_begin (
+ EM_FORMAT_HTML (html_display)->html);
+ gtk_html_stream_printf (
+ stream, "<h2>%s</h2><p>%s</p>",
+ _("Unable to retrieve message"),
+ ex->desc);
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
+ camel_exception_clear (ex);
+ }
+
+ e_mail_reader_update_actions (reader);
+
+ /* We referenced this in the call to mail_get_messagex(). */
+ g_object_unref (reader);
+}
+
+static gboolean
+mail_reader_message_selected_timeout_cb (EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ const gchar *cursor_uid;
+ const gchar *format_uid;
+ const gchar *key;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ cursor_uid = message_list->cursor_uid;
+ format_uid = EM_FORMAT (html_display)->uid;
+
+ if (message_list->last_sel_single) {
+ GtkWidget *widget;
+ gboolean html_display_visible;
+ gboolean selected_uid_changed;
+
+ /* Decide whether to download the full message now. */
+
+ widget = GTK_WIDGET (EM_FORMAT_HTML (html_display)->html);
+
+ html_display_visible = GTK_WIDGET_MAPPED (widget);
+ selected_uid_changed = g_strcmp0 (cursor_uid, format_uid);
+
+ if (html_display_visible && selected_uid_changed)
+ mail_get_messagex (
+ message_list->folder, cursor_uid,
+ mail_reader_message_loaded_cb,
+ g_object_ref (reader),
+ mail_msg_fast_ordered_push);
+ } else
+ em_format_format (EM_FORMAT (html_display), NULL, NULL, NULL);
+
+ key = "message-selected-timeout";
+ g_object_set_data (G_OBJECT (reader), key, NULL);
+
+ return FALSE;
+}
+
+static void
+mail_reader_message_selected_cb (EMailReader *reader,
+ const gchar *uid)
+{
+ const gchar *key;
+ guint source_id;
+ gpointer data;
+
+ /* XXX This is kludgy, but we have no other place to store timeout
+ * state information. Addendum: See EAttachmentView for an example
+ * of storing private data in an interface. Clunky but works. */
+
+ key = "message-selected-timeout";
+ data = g_object_get_data (G_OBJECT (reader), key);
+ source_id = GPOINTER_TO_UINT (data);
+
+ if (source_id > 0)
+ g_source_remove (source_id);
+
+ source_id = g_timeout_add (
+ 100, (GSourceFunc)
+ mail_reader_message_selected_timeout_cb, reader);
+
+ data = GUINT_TO_POINTER (source_id);
+ g_object_set_data (G_OBJECT (reader), key, data);
+
+ e_mail_reader_changed (reader);
+}
+
+static void
+mail_reader_emit_folder_loaded (EMailReader *reader)
+{
+ g_signal_emit (reader, signals[FOLDER_LOADED], 0);
+}
+
+static void
+mail_reader_set_folder (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ gboolean outgoing;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ outgoing = folder != NULL && folder_uri != NULL && (
+ em_utils_folder_is_drafts (folder, folder_uri) ||
+ em_utils_folder_is_outbox (folder, folder_uri) ||
+ em_utils_folder_is_sent (folder, folder_uri));
+
+ if (message_list->folder != NULL)
+ mail_sync_folder (message_list->folder, NULL, NULL);
+
+ em_format_format (EM_FORMAT (html_display), NULL, NULL, NULL);
+ message_list_set_folder (message_list, folder, folder_uri, outgoing);
+
+ mail_reader_emit_folder_loaded (reader);
+}
+
+static void
+mail_reader_set_message (EMailReader *reader,
+ const gchar *uid)
+{
+ MessageList *message_list;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select_uid (message_list, uid);
+}
+
+static void
+mail_reader_init_charset_actions (EMailReader *reader)
+{
+ GtkActionGroup *action_group;
+ GtkRadioAction *default_action;
+ GSList *radio_group;
+
+ action_group = e_mail_reader_get_action_group (reader);
+
+ radio_group = e_charset_add_radio_actions (
+ action_group, "mail-charset-", NULL,
+ G_CALLBACK (action_mail_charset_cb), reader);
+
+ /* XXX Add a tooltip! */
+ default_action = gtk_radio_action_new (
+ "mail-charset-default", _("Default"), NULL, NULL, -1);
+
+ gtk_radio_action_set_group (default_action, radio_group);
+
+ g_signal_connect (
+ default_action, "changed",
+ G_CALLBACK (action_mail_charset_cb), reader);
+
+ gtk_action_group_add_action (
+ action_group, GTK_ACTION (default_action));
+
+ gtk_radio_action_set_current_value (default_action, -1);
+}
+
+static void
+mail_reader_class_init (EMailReaderIface *iface)
+{
+ iface->set_folder = mail_reader_set_folder;
+ iface->set_message = mail_reader_set_message;
+
+ signals[CHANGED] = g_signal_new (
+ "changed",
+ G_OBJECT_CLASS_TYPE (iface),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[FOLDER_LOADED] = g_signal_new (
+ "folder-loaded",
+ G_OBJECT_CLASS_TYPE (iface),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SHOW_SEARCH_BAR] = g_signal_new (
+ "show-search-bar",
+ G_OBJECT_CLASS_TYPE (iface),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailReaderIface, show_search_bar),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+GType
+e_mail_reader_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailReaderIface),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_reader_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ 0, /* instance_size */
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_INTERFACE, "EMailReader", &type_info, 0);
+
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ }
+
+ return type;
+}
+
+void
+e_mail_reader_init (EMailReader *reader)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EMFormatHTMLDisplay *html_display;
+ EMailDisplay *display;
+ GtkActionGroup *action_group;
+ MessageList *message_list;
+ GConfBridge *bridge;
+ GtkAction *action;
+ const gchar *action_name;
+ const gchar *key;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ action_group = e_mail_reader_get_action_group (reader);
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+
+ gtk_action_group_add_actions (
+ action_group, mail_reader_entries,
+ G_N_ELEMENTS (mail_reader_entries), reader);
+ e_action_group_add_popup_actions (
+ action_group, mail_reader_popup_entries,
+ G_N_ELEMENTS (mail_reader_popup_entries));
+ gtk_action_group_add_toggle_actions (
+ action_group, mail_reader_toggle_entries,
+ G_N_ELEMENTS (mail_reader_toggle_entries), reader);
+
+ mail_reader_init_charset_actions (reader);
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ action_name = "mail-caret-mode";
+ key = "/apps/evolution/mail/display/caret_mode";
+ action = e_mail_reader_get_action (reader, action_name);
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+
+ action_name = "mail-show-all-headers";
+ key = "/apps/evolution/mail/display/show_all_headers";
+ action = e_mail_reader_get_action (reader, action_name);
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+
+ /* Fine tuning. */
+
+ action_name = "mail-clipboard-copy";
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, FALSE);
+
+ action_name = "mail-delete";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_object_set (action, "short-label", _("Delete"), NULL);
+
+ action_name = "mail-next";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_object_set (action, "short-label", _("Next"), NULL);
+
+ action_name = "mail-previous";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_object_set (action, "short-label", _("Previous"), NULL);
+
+ action_name = "mail-reply-sender";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_object_set (action, "short-label", _("Reply"), NULL);
+
+ action_name = "search-folder-recipient";
+ action = e_mail_display_get_action (display, action_name);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_search_folder_recipient_cb), reader);
+
+ action_name = "search-folder-sender";
+ action = e_mail_display_get_action (display, action_name);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_search_folder_sender_cb), reader);
+
+ /* Bind properties. */
+
+ e_binding_new_full (
+ G_OBJECT (shell_settings), "mail-citation-color",
+ G_OBJECT (html_display), "citation-color",
+ e_binding_transform_string_to_color,
+ NULL, NULL);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-image-loading-policy",
+ G_OBJECT (html_display), "image-loading-policy");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-only-local-photos",
+ G_OBJECT (html_display), "only-local-photos");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-show-animated-images",
+ G_OBJECT (display), "animate");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-show-sender-photo",
+ G_OBJECT (html_display), "show-sender-photo");
+
+ action_name = "mail-caret-mode";
+ action = e_mail_reader_get_action (reader, action_name);
+
+ e_mutual_binding_new (
+ G_OBJECT (action), "active",
+ G_OBJECT (display), "caret-mode");
+
+ /* Connect signals. */
+
+ g_signal_connect_swapped (
+ display, "button-release-event",
+ G_CALLBACK (mail_reader_button_release_event_cb), reader);
+
+ g_signal_connect_swapped (
+ display, "key-press-event",
+ G_CALLBACK (mail_reader_key_press_event_cb), reader);
+
+ g_signal_connect_swapped (
+ message_list, "message-selected",
+ G_CALLBACK (mail_reader_message_selected_cb), reader);
+
+ g_signal_connect_swapped (
+ message_list, "message-list-built",
+ G_CALLBACK (mail_reader_emit_folder_loaded), reader);
+
+ g_signal_connect_swapped (
+ message_list->tree, "double-click",
+ G_CALLBACK (mail_reader_double_click_cb), reader);
+
+ g_signal_connect_swapped (
+ message_list->tree, "key-press",
+ G_CALLBACK (mail_reader_key_press_cb), reader);
+
+ g_signal_connect_swapped (
+ message_list->tree, "selection-change",
+ G_CALLBACK (e_mail_reader_changed), reader);
+}
+
+void
+e_mail_reader_changed (EMailReader *reader)
+{
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ g_signal_emit (reader, signals[CHANGED], 0);
+}
+
+guint32
+e_mail_reader_check_state (EMailReader *reader)
+{
+ MessageList *message_list;
+ GPtrArray *uids;
+ CamelFolder *folder;
+ CamelStore *store = NULL;
+ const gchar *folder_uri;
+ const gchar *tag;
+ gboolean can_clear_flags = FALSE;
+ gboolean can_flag_completed = FALSE;
+ gboolean can_flag_for_followup = FALSE;
+ gboolean has_deleted = FALSE;
+ gboolean has_important = FALSE;
+ gboolean has_junk = FALSE;
+ gboolean has_not_junk = FALSE;
+ gboolean has_read = FALSE;
+ gboolean has_undeleted = FALSE;
+ gboolean has_unimportant = FALSE;
+ gboolean has_unread = FALSE;
+ gboolean drafts_or_outbox;
+ gboolean store_supports_vjunk = FALSE;
+ gboolean is_mailing_list;
+ guint32 state = 0;
+ guint ii;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
+
+ message_list = e_mail_reader_get_message_list (reader);
+ uids = message_list_get_selected (message_list);
+ folder_uri = message_list->folder_uri;
+ folder = message_list->folder;
+
+ if (folder != NULL) {
+ store = CAMEL_STORE (folder->parent_store);
+ store_supports_vjunk = (store->flags & CAMEL_STORE_VJUNK);
+ }
+
+ drafts_or_outbox =
+ em_utils_folder_is_drafts (folder, folder_uri) ||
+ em_utils_folder_is_outbox (folder, folder_uri);
+
+ /* Initialize this flag based on whether there are any
+ * messages selected. We will update it in the loop. */
+ is_mailing_list = (uids->len > 0);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ CamelMessageInfo *info;
+ const gchar *string;
+ guint32 flags;
+
+ info = camel_folder_get_message_info (
+ folder, uids->pdata[ii]);
+ if (info == NULL)
+ continue;
+
+ flags = camel_message_info_flags (info);
+
+ if (flags & CAMEL_MESSAGE_SEEN)
+ has_read = TRUE;
+ else
+ has_unread = TRUE;
+
+ if (drafts_or_outbox) {
+ has_junk = FALSE;
+ has_not_junk = FALSE;
+ } else if (store_supports_vjunk) {
+ guint32 bitmask;
+
+ /* XXX Strictly speaking, this logic is correct.
+ * Problem is there's nothing in the message
+ * list that indicates whether a message is
+ * already marked "Not Junk". So the user may
+ * think the "Not Junk" button is enabling and
+ * disabling itself randomly as he reads mail. */
+
+ if (flags & CAMEL_MESSAGE_JUNK)
+ has_junk = TRUE;
+ if (flags & CAMEL_MESSAGE_NOTJUNK)
+ has_not_junk = TRUE;
+
+ bitmask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK;
+
+ /* If neither junk flag is set, the
+ * message can be marked either way. */
+ if ((flags & bitmask) == 0) {
+ has_junk = TRUE;
+ has_not_junk = TRUE;
+ }
+
+ } else {
+ has_junk = TRUE;
+ has_not_junk = TRUE;
+ }
+
+ if (flags & CAMEL_MESSAGE_DELETED)
+ has_deleted = TRUE;
+ else
+ has_undeleted = TRUE;
+
+ if (flags & CAMEL_MESSAGE_FLAGGED)
+ has_important = TRUE;
+ else
+ has_unimportant = TRUE;
+
+ tag = camel_message_info_user_tag (info, "follow-up");
+ if (tag != NULL && *tag != '\0') {
+ can_clear_flags = TRUE;
+ tag = camel_message_info_user_tag (
+ info, "completed-on");
+ if (tag != NULL && *tag != '\0')
+ can_flag_completed = TRUE;
+ } else
+ can_flag_for_followup = TRUE;
+
+ string = camel_message_info_mlist (info);
+ is_mailing_list &= (string != NULL && *string != '\0');
+ }
+
+ if (em_utils_check_user_can_send_mail ())
+ state |= E_MAIL_READER_HAVE_ACCOUNT;
+ if (uids->len == 1)
+ state |= E_MAIL_READER_SELECTION_SINGLE;
+ if (uids->len > 1)
+ state |= E_MAIL_READER_SELECTION_MULTIPLE;
+ if (!drafts_or_outbox && uids->len == 1)
+ state |= E_MAIL_READER_SELECTION_CAN_ADD_SENDER;
+ if (can_clear_flags)
+ state |= E_MAIL_READER_SELECTION_FLAG_CLEAR;
+ if (can_flag_completed)
+ state |= E_MAIL_READER_SELECTION_FLAG_COMPLETED;
+ if (can_flag_for_followup)
+ state |= E_MAIL_READER_SELECTION_FLAG_FOLLOWUP;
+ if (has_deleted)
+ state |= E_MAIL_READER_SELECTION_HAS_DELETED;
+ if (has_important)
+ state |= E_MAIL_READER_SELECTION_HAS_IMPORTANT;
+ if (has_junk)
+ state |= E_MAIL_READER_SELECTION_HAS_JUNK;
+ if (has_not_junk)
+ state |= E_MAIL_READER_SELECTION_HAS_NOT_JUNK;
+ if (has_read)
+ state |= E_MAIL_READER_SELECTION_HAS_READ;
+ if (has_undeleted)
+ state |= E_MAIL_READER_SELECTION_HAS_UNDELETED;
+ if (has_unimportant)
+ state |= E_MAIL_READER_SELECTION_HAS_UNIMPORTANT;
+ if (has_unread)
+ state |= E_MAIL_READER_SELECTION_HAS_UNREAD;
+ if (is_mailing_list)
+ state |= E_MAIL_READER_SELECTION_IS_MAILING_LIST;
+
+ em_utils_uids_free (uids);
+
+ return state;
+
+}
+
+void
+e_mail_reader_update_actions (EMailReader *reader)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ GtkAction *action;
+ GtkActionGroup *action_group;
+ const gchar *action_name;
+ gboolean sensitive;
+ guint32 state;
+
+ /* Be descriptive. */
+ gboolean any_messages_selected;
+ gboolean disable_printing;
+ gboolean enable_flag_clear;
+ gboolean enable_flag_completed;
+ gboolean enable_flag_for_followup;
+ gboolean have_an_account;
+ gboolean multiple_messages_selected;
+ gboolean selection_has_deleted_messages;
+ gboolean selection_has_important_messages;
+ gboolean selection_has_junk_messages;
+ gboolean selection_has_not_junk_messages;
+ gboolean selection_has_read_messages;
+ gboolean selection_has_undeleted_messages;
+ gboolean selection_has_unimportant_messages;
+ gboolean selection_has_unread_messages;
+ gboolean selection_is_mailing_list;
+ gboolean single_message_selected;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ action_group = e_mail_reader_get_action_group (reader);
+ state = e_mail_reader_check_state (reader);
+
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ disable_printing = e_shell_settings_get_boolean (
+ shell_settings, "disable-printing");
+
+ have_an_account =
+ (state & E_MAIL_READER_HAVE_ACCOUNT);
+ single_message_selected =
+ (state & E_MAIL_READER_SELECTION_SINGLE);
+ multiple_messages_selected =
+ (state & E_MAIL_READER_SELECTION_MULTIPLE);
+ /* FIXME Missing CAN_ADD_SENDER */
+ enable_flag_clear =
+ (state & E_MAIL_READER_SELECTION_FLAG_CLEAR);
+ enable_flag_completed =
+ (state & E_MAIL_READER_SELECTION_FLAG_COMPLETED);
+ enable_flag_for_followup =
+ (state & E_MAIL_READER_SELECTION_FLAG_FOLLOWUP);
+ selection_has_deleted_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_DELETED);
+ selection_has_important_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_IMPORTANT);
+ selection_has_junk_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_JUNK);
+ selection_has_not_junk_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_NOT_JUNK);
+ selection_has_read_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_READ);
+ selection_has_undeleted_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_UNDELETED);
+ selection_has_unimportant_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_UNIMPORTANT);
+ selection_has_unread_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_UNREAD);
+ selection_is_mailing_list =
+ (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST);
+
+ any_messages_selected =
+ (single_message_selected || multiple_messages_selected);
+
+ action_name = "mail-check-for-junk";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-copy";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-delete";
+ sensitive = selection_has_undeleted_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-filters-apply";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-forward";
+ sensitive = have_an_account && any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-forward-attached";
+ sensitive = have_an_account && any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-forward-inline";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-forward-quoted";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-load-images";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-important";
+ sensitive = selection_has_unimportant_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-junk";
+ sensitive = selection_has_not_junk_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-notjunk";
+ sensitive = selection_has_junk_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-read";
+ sensitive = selection_has_unread_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-unimportant";
+ sensitive = selection_has_important_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-unread";
+ sensitive = selection_has_read_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-message-edit";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-message-new";
+ sensitive = have_an_account;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-message-open";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-move";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-next-important";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-next-thread";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-next-unread";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-previous-important";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-previous-unread";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-print";
+ sensitive = single_message_selected && !disable_printing;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-print-preview";
+ sensitive = single_message_selected && !disable_printing;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-redirect";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-reply-all";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-reply-list";
+ sensitive = have_an_account && single_message_selected &&
+ selection_is_mailing_list;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-reply-sender";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-save-as";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-select-all";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-show-source";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-undelete";
+ sensitive = selection_has_deleted_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-zoom-100";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-zoom-in";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-zoom-out";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+}
+
+GtkAction *
+e_mail_reader_get_action (EMailReader *reader,
+ const gchar *action_name)
+{
+ GtkActionGroup *action_group;
+ GtkAction *action;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
+
+ action_group = e_mail_reader_get_action_group (reader);
+ action = gtk_action_group_get_action (action_group, action_name);
+
+ if (action == NULL)
+ g_critical (
+ "%s: action `%s' not found", G_STRFUNC, action_name);
+
+ return action;
+}
+
+GtkActionGroup *
+e_mail_reader_get_action_group (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_action_group != NULL, NULL);
+
+ return iface->get_action_group (reader);
+}
+
+gboolean
+e_mail_reader_get_hide_deleted (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_hide_deleted != NULL, FALSE);
+
+ return iface->get_hide_deleted (reader);
+}
+
+EMFormatHTMLDisplay *
+e_mail_reader_get_html_display (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_html_display != NULL, NULL);
+
+ return iface->get_html_display (reader);
+}
+
+MessageList *
+e_mail_reader_get_message_list (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_message_list != NULL, NULL);
+
+ return iface->get_message_list (reader);
+}
+
+EShellBackend *
+e_mail_reader_get_shell_backend (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_shell_backend != NULL, NULL);
+
+ return iface->get_shell_backend (reader);
+}
+
+GtkWindow *
+e_mail_reader_get_window (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_window != NULL, NULL);
+
+ return iface->get_window (reader);
+}
+
+void
+e_mail_reader_set_folder (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri)
+{
+ EMailReaderIface *iface;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_if_fail (iface->set_folder != NULL);
+
+ iface->set_folder (reader, folder, folder_uri);
+}
+
+/* Helper for e_mail_reader_set_folder_uri() */
+static void
+mail_reader_got_folder_cb (gchar *folder_uri,
+ CamelFolder *folder,
+ gpointer user_data)
+{
+ EMailReader *reader = user_data;
+
+ e_mail_reader_set_folder (reader, folder, folder_uri);
+}
+
+void
+e_mail_reader_set_folder_uri (EMailReader *reader,
+ const gchar *folder_uri)
+{
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+ g_return_if_fail (folder_uri != NULL);
+
+ /* Fetch the CamelFolder asynchronously. */
+ mail_get_folder (
+ folder_uri, 0, mail_reader_got_folder_cb,
+ reader, mail_msg_fast_ordered_push);
+}
+
+void
+e_mail_reader_set_message (EMailReader *reader,
+ const gchar *uid)
+{
+ EMailReaderIface *iface;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_if_fail (iface->set_message != NULL);
+
+ iface->set_message (reader, uid);
+}
+
+void
+e_mail_reader_create_charset_menu (EMailReader *reader,
+ GtkUIManager *ui_manager,
+ guint merge_id)
+{
+ GtkAction *action;
+ const gchar *action_name;
+ const gchar *path;
+ GSList *list;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+ g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
+
+ action_name = "mail-charset-default";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_return_if_fail (action != NULL);
+
+ list = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
+ list = g_slist_copy (list);
+ list = g_slist_remove (list, action);
+ list = g_slist_sort (list, (GCompareFunc) e_action_compare_by_label);
+
+ path = "/main-menu/view-menu/mail-message-view-actions/mail-encoding-menu";
+
+ while (list != NULL) {
+ action = list->data;
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id, path,
+ gtk_action_get_name (action),
+ gtk_action_get_name (action),
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ list = g_slist_delete_link (list, list);
+ }
+
+ gtk_ui_manager_ensure_update (ui_manager);
+}
+
+void
+e_mail_reader_show_search_bar (EMailReader *reader)
+{
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ g_signal_emit (reader, signals[SHOW_SEARCH_BAR], 0);
+}
diff --git a/mail/e-mail-reader.h b/mail/e-mail-reader.h
new file mode 100644
index 0000000000..6830e4f84c
--- /dev/null
+++ b/mail/e-mail-reader.h
@@ -0,0 +1,129 @@
+/*
+ * e-mail-reader.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_READER_H
+#define E_MAIL_READER_H
+
+#include <gtk/gtk.h>
+#include <camel/camel-folder.h>
+#include <mail/em-format-html-display.h>
+#include <mail/message-list.h>
+#include <shell/e-shell-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_READER \
+ (e_mail_reader_get_type ())
+#define E_MAIL_READER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_READER, EMailReader))
+#define E_MAIL_READER_IFACE(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_READER, EMailReaderIface))
+#define E_IS_MAIL_READER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_READER))
+#define E_IS_MAIL_READER_IFACE(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_READER))
+#define E_MAIL_READER_GET_IFACE(obj) \
+ (G_TYPE_INSTANCE_GET_INTERFACE \
+ ((obj), E_TYPE_MAIL_READER, EMailReaderIface))
+
+/* Basename of the UI definition file. */
+#define E_MAIL_READER_UI_DEFINITION "evolution-mail-reader.ui"
+
+G_BEGIN_DECLS
+
+typedef struct _EMailReader EMailReader;
+typedef struct _EMailReaderIface EMailReaderIface;
+
+enum {
+ E_MAIL_READER_HAVE_ACCOUNT = 1 << 0,
+ E_MAIL_READER_SELECTION_SINGLE = 1 << 1,
+ E_MAIL_READER_SELECTION_MULTIPLE = 1 << 2,
+ E_MAIL_READER_SELECTION_CAN_ADD_SENDER = 1 << 3,
+ E_MAIL_READER_SELECTION_FLAG_CLEAR = 1 << 4,
+ E_MAIL_READER_SELECTION_FLAG_COMPLETED = 1 << 5,
+ E_MAIL_READER_SELECTION_FLAG_FOLLOWUP = 1 << 6,
+ E_MAIL_READER_SELECTION_HAS_DELETED = 1 << 7,
+ E_MAIL_READER_SELECTION_HAS_IMPORTANT = 1 << 8,
+ E_MAIL_READER_SELECTION_HAS_JUNK = 1 << 9,
+ E_MAIL_READER_SELECTION_HAS_NOT_JUNK = 1 << 10,
+ E_MAIL_READER_SELECTION_HAS_READ = 1 << 11,
+ E_MAIL_READER_SELECTION_HAS_UNDELETED = 1 << 12,
+ E_MAIL_READER_SELECTION_HAS_UNIMPORTANT = 1 << 13,
+ E_MAIL_READER_SELECTION_HAS_UNREAD = 1 << 14,
+ E_MAIL_READER_SELECTION_IS_MAILING_LIST = 1 << 15
+};
+
+struct _EMailReaderIface {
+ GTypeInterface parent_iface;
+
+ GtkActionGroup *
+ (*get_action_group) (EMailReader *reader);
+ gboolean (*get_hide_deleted) (EMailReader *reader);
+ EMFormatHTMLDisplay *
+ (*get_html_display) (EMailReader *reader);
+ MessageList * (*get_message_list) (EMailReader *reader);
+ EShellBackend * (*get_shell_backend) (EMailReader *reader);
+ GtkWindow * (*get_window) (EMailReader *reader);
+
+ void (*set_folder) (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri);
+ void (*set_message) (EMailReader *reader,
+ const gchar *uid);
+
+ /* Signals */
+ void (*show_search_bar) (EMailReader *reader);
+};
+
+GType e_mail_reader_get_type (void);
+void e_mail_reader_init (EMailReader *reader);
+void e_mail_reader_changed (EMailReader *reader);
+guint32 e_mail_reader_check_state (EMailReader *reader);
+void e_mail_reader_update_actions (EMailReader *reader);
+GtkAction * e_mail_reader_get_action (EMailReader *reader,
+ const gchar *action_name);
+GtkActionGroup *
+ e_mail_reader_get_action_group (EMailReader *reader);
+gboolean e_mail_reader_get_hide_deleted (EMailReader *reader);
+EMFormatHTMLDisplay *
+ e_mail_reader_get_html_display (EMailReader *reader);
+MessageList * e_mail_reader_get_message_list (EMailReader *reader);
+EShellBackend * e_mail_reader_get_shell_backend (EMailReader *reader);
+GtkWindow * e_mail_reader_get_window (EMailReader *reader);
+void e_mail_reader_set_folder (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri);
+void e_mail_reader_set_folder_uri (EMailReader *reader,
+ const gchar *folder_uri);
+void e_mail_reader_set_message (EMailReader *reader,
+ const gchar *uid);
+void e_mail_reader_create_charset_menu
+ (EMailReader *reader,
+ GtkUIManager *ui_manager,
+ guint merge_id);
+void e_mail_reader_show_search_bar (EMailReader *reader);
+
+G_END_DECLS
+
+#endif /* E_MAIL_READER_H */
diff --git a/mail/e-mail-store.c b/mail/e-mail-store.c
new file mode 100644
index 0000000000..1fc3eb5b25
--- /dev/null
+++ b/mail/e-mail-store.c
@@ -0,0 +1,423 @@
+/*
+ * e-mail-store.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-store.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-service.h>
+#include <camel/camel-session.h>
+#include <camel/camel-url.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
+
+#include "e-util/e-account-utils.h"
+
+#include "mail/e-mail-local.h"
+#include "mail/em-folder-tree-model.h"
+#include "mail/mail-folder-cache.h"
+#include "mail/mail-mt.h"
+#include "mail/mail-session.h"
+
+typedef struct _StoreInfo StoreInfo;
+
+typedef void (*AddStoreCallback) (CamelStore *store,
+ CamelFolderInfo *info,
+ StoreInfo *store_info);
+
+struct _StoreInfo {
+ gint ref_count;
+
+ CamelStore *store;
+ gchar *display_name;
+
+ /* Hold a reference to keep them alive. */
+ CamelFolder *vtrash;
+ CamelFolder *vjunk;
+
+ AddStoreCallback callback;
+
+ guint removed : 1;
+};
+
+CamelStore *vfolder_store; /* XXX write a get() function for this */
+static GHashTable *store_table;
+
+static MailAsyncEvent *async_event;
+
+static StoreInfo *
+store_info_new (CamelStore *store,
+ const gchar *display_name)
+{
+ CamelService *service;
+ StoreInfo *store_info;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ service = CAMEL_SERVICE (store);
+
+ store_info = g_slice_new0 (StoreInfo);
+ store_info->ref_count = 1;
+
+ camel_object_ref (store);
+ store_info->store = store;
+
+ if (display_name == NULL)
+ store_info->display_name =
+ camel_service_get_name (service, TRUE);
+ else
+ store_info->display_name = g_strdup (display_name);
+
+ /* If these are vfolders then they need to be opened now,
+ * otherwise they won't keep track of all folders. */
+ if (store->flags & CAMEL_STORE_VTRASH)
+ store_info->vtrash = camel_store_get_trash (store, NULL);
+ if (store->flags & CAMEL_STORE_VJUNK)
+ store_info->vjunk = camel_store_get_junk (store, NULL);
+
+ return store_info;
+}
+
+static StoreInfo *
+store_info_ref (StoreInfo *store_info)
+{
+ g_return_val_if_fail (store_info != NULL, store_info);
+ g_return_val_if_fail (store_info->ref_count > 0, store_info);
+
+ g_atomic_int_add (&store_info->ref_count, 1);
+
+ return store_info;
+}
+
+static void
+store_info_unref (StoreInfo *store_info)
+{
+ g_return_if_fail (store_info != NULL);
+ g_return_if_fail (store_info->ref_count > 0);
+
+ if (g_atomic_int_exchange_and_add (&store_info->ref_count, -1) > 1)
+ return;
+
+ camel_object_unref (store_info->store);
+ g_free (store_info->display_name);
+
+ if (store_info->vtrash != NULL)
+ camel_object_unref (store_info->vtrash);
+
+ if (store_info->vjunk != NULL)
+ camel_object_unref (store_info->vjunk);
+
+ g_slice_free (StoreInfo, store_info);
+}
+
+static void
+store_table_free (StoreInfo *store_info)
+{
+ store_info->removed = 1;
+ store_info_unref (store_info);
+}
+
+static gboolean
+mail_store_note_store_cb (CamelStore *store,
+ CamelFolderInfo *info,
+ gpointer user_data)
+{
+ StoreInfo *store_info = user_data;
+
+ if (store_info->callback != NULL)
+ store_info->callback (store, info, store_info);
+
+ if (!store_info->removed) {
+ /* This keeps message counters up-to-date. */
+ if (store_info->vtrash != NULL)
+ mail_note_folder (store_info->vtrash);
+ if (store_info->vjunk != NULL)
+ mail_note_folder (store_info->vjunk);
+ }
+
+ store_info_unref (store_info);
+
+ return TRUE;
+}
+
+static void
+mail_store_add (CamelStore *store,
+ const gchar *display_name,
+ AddStoreCallback callback)
+{
+ EMFolderTreeModel *default_model;
+ StoreInfo *store_info;
+
+ g_return_if_fail (store_table != NULL);
+
+ default_model = em_folder_tree_model_get_default ();
+
+ store_info = store_info_new (store, display_name);
+ store_info->callback = callback;
+
+ g_hash_table_insert (store_table, store, store_info);
+
+ em_folder_tree_model_add_store (
+ default_model, store, store_info->display_name);
+
+ mail_note_store (
+ store, NULL,
+ mail_store_note_store_cb,
+ store_info_ref (store_info));
+}
+
+static void
+mail_store_add_local_done_cb (CamelStore *store,
+ CamelFolderInfo *info,
+ StoreInfo *store_info)
+{
+ CamelFolder *folder;
+ gint ii;
+
+ for (ii = 0; ii < E_MAIL_NUM_LOCAL_FOLDERS; ii++) {
+ folder = e_mail_local_get_folder (ii);
+ if (folder != NULL)
+ mail_note_folder (folder);
+ }
+}
+
+static void
+mail_store_add_local_cb (CamelStore *local_store,
+ const gchar *display_name)
+{
+ mail_store_add (
+ local_store, display_name,
+ (AddStoreCallback) mail_store_add_local_done_cb);
+}
+
+static void
+mail_store_load_accounts (const gchar *data_dir)
+{
+ CamelStore *local_store;
+ EAccountList *account_list;
+ EIterator *iter;
+
+ /* Set up the local store. */
+
+ e_mail_local_init (data_dir);
+ local_store = e_mail_local_get_store ();
+
+ mail_async_event_emit (
+ async_event, MAIL_ASYNC_GUI,
+ (MailAsyncFunc) mail_store_add_local_cb,
+ local_store, _("On This Computer"), NULL);
+
+ /* Set up remote stores. */
+
+ account_list = e_get_account_list ();
+
+ for (iter = e_list_get_iterator ((EList *) account_list);
+ e_iterator_is_valid (iter); e_iterator_next (iter)) {
+
+ EAccountService *service;
+ EAccount *account;
+ const gchar *display_name;
+ const gchar *uri;
+
+ account = (EAccount *) e_iterator_get (iter);
+ display_name = account->name;
+ service = account->source;
+ uri = service->url;
+
+ if (!account->enabled)
+ continue;
+
+ if (uri == NULL || *uri == '\0')
+ continue;
+
+ /* HACK: mbox URI's are handled by the local store setup
+ * above. Any that come through as account sources
+ * are really movemail sources! */
+ if (g_str_has_prefix (uri, "mbox:"))
+ continue;
+
+ e_mail_store_add_by_uri (uri, display_name);
+ }
+
+ g_object_unref (iter);
+}
+
+void
+e_mail_store_init (const gchar *data_dir)
+{
+ static gboolean initialized = FALSE;
+
+ g_return_if_fail (!initialized);
+ g_return_if_fail (data_dir != NULL);
+
+ /* Initialize global variables. */
+
+ store_table = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) store_table_free);
+
+ async_event = mail_async_event_new ();
+
+ mail_store_load_accounts (data_dir);
+
+ initialized = TRUE;
+}
+
+void
+e_mail_store_add (CamelStore *store,
+ const gchar *display_name)
+{
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (display_name != NULL);
+
+ mail_store_add (store, display_name, NULL);
+}
+
+CamelStore *
+e_mail_store_add_by_uri (const gchar *uri,
+ const gchar *display_name)
+{
+ CamelService *service;
+ CamelProvider *provider;
+ CamelException ex;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+ g_return_val_if_fail (display_name != NULL, NULL);
+
+ camel_exception_init (&ex);
+
+ /* Load the service, but don't connect. Check its provider,
+ * and if this belongs in the folder tree model, add it. */
+
+ provider = camel_provider_get (uri, &ex);
+ if (provider == NULL)
+ goto fail;
+
+ if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+ return NULL;
+
+ service = camel_session_get_service (
+ session, uri, CAMEL_PROVIDER_STORE, &ex);
+ if (service == NULL)
+ goto fail;
+
+ e_mail_store_add (CAMEL_STORE (service), display_name);
+
+ camel_object_unref (service);
+
+ return CAMEL_STORE (service);
+
+fail:
+ /* FIXME: Show an error dialog. */
+ g_warning (
+ "Couldn't get service: %s: %s", uri,
+ camel_exception_get_description (&ex));
+ camel_exception_clear (&ex);
+
+ return NULL;
+}
+
+/* Helper for e_mail_store_remove() */
+static void
+mail_store_remove_cb (CamelStore *store)
+{
+ camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
+ camel_object_unref (store);
+}
+
+void
+e_mail_store_remove (CamelStore *store)
+{
+ EMFolderTreeModel *default_model;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (store_table != NULL);
+ g_return_if_fail (async_event != NULL);
+
+ /* Because the store table holds a reference to each store used
+ * as a key in it, none of them will ever be gc'ed, meaning any
+ * call to camel_session_get_{service,store} with the same URL
+ * will always return the same object. So this works. */
+
+ if (g_hash_table_lookup (store_table, store) == NULL)
+ return;
+
+ camel_object_ref (store);
+
+ g_hash_table_remove (store_table, store);
+ mail_note_store_remove (store);
+
+ default_model = em_folder_tree_model_get_default ();
+ em_folder_tree_model_remove_store (default_model, store);
+
+ mail_async_event_emit (
+ async_event, MAIL_ASYNC_THREAD,
+ (MailAsyncFunc) mail_store_remove_cb,
+ store, NULL, NULL);
+}
+
+void
+e_mail_store_remove_by_uri (const gchar *uri)
+{
+ CamelService *service;
+ CamelProvider *provider;
+
+ g_return_if_fail (uri != NULL);
+
+ provider = camel_provider_get (uri, NULL);
+ if (provider == NULL)
+ return;
+
+ if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+ return;
+
+ service = camel_session_get_service (
+ session, uri, CAMEL_PROVIDER_STORE, NULL);
+ if (service == NULL)
+ return;
+
+ e_mail_store_remove (CAMEL_STORE (service));
+
+ camel_object_unref (service);
+}
+
+void
+e_mail_store_foreach (GHFunc func,
+ gpointer user_data)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_if_fail (func != NULL);
+ g_return_if_fail (store_table != NULL);
+
+ g_hash_table_iter_init (&iter, store_table);
+
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ StoreInfo *store_info = value;
+
+ /* Just being paranoid. */
+ g_return_if_fail (CAMEL_IS_STORE (key));
+ g_return_if_fail (store_info != NULL);
+
+ func (key, store_info->display_name, user_data);
+ }
+}
diff --git a/widgets/table/e-table-tree.h b/mail/e-mail-store.h
index 178c2a3ba2..bfd1ab47c8 100644
--- a/widgets/table/e-table-tree.h
+++ b/mail/e-mail-store.h
@@ -1,4 +1,5 @@
/*
+ * e-mail-store.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,35 +15,28 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _E_TABLE_TREE_H_
-#define _E_TABLE_TREE_H_
+#ifndef E_MAIL_STORE_H
+#define E_MAIL_STORE_H
-#include <table/e-table-model.h>
+#include <glib.h>
+#include <camel/camel-store.h>
G_BEGIN_DECLS
-typedef struct {
- gchar *title;
-
- union {
- ETableModel *table;
- GList *children;
- } u;
-
- guint expanded :1;
- guint is_leaf :1;
-} ETableGroup;
-
-ETableGroup *e_table_group_new (const gchar *title, ETableModel *table);
-ETableGroup *e_table_group_new_leaf (const gchar *title);
+void e_mail_store_init (const gchar *data_dir);
+void e_mail_store_add (CamelStore *store,
+ const gchar *display_name);
+CamelStore * e_mail_store_add_by_uri (const gchar *uri,
+ const gchar *display_name);
+void e_mail_store_remove (CamelStore *store);
+void e_mail_store_remove_by_uri (const gchar *uri);
+void e_mail_store_foreach (GHFunc func,
+ gpointer user_data);
G_END_DECLS
-#endif /* _E_TABLE_TREE_H_ */
+#endif /* E_MAIL_STORE_H */
diff --git a/mail/e-searching-tokenizer.c b/mail/e-searching-tokenizer.c
index 32a2d6ccd3..b9a00cddf3 100644
--- a/mail/e-searching-tokenizer.c
+++ b/mail/e-searching-tokenizer.c
@@ -38,76 +38,17 @@
#define d(x)
+#define E_SEARCHING_TOKENIZER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerPrivate))
+
enum {
MATCH_SIGNAL,
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0, };
-
-static void e_searching_tokenizer_begin (HTMLTokenizer *, const gchar *);
-static void e_searching_tokenizer_end (HTMLTokenizer *);
-static gchar *e_searching_tokenizer_peek_token (HTMLTokenizer *);
-static gchar *e_searching_tokenizer_next_token (HTMLTokenizer *);
-static gboolean e_searching_tokenizer_has_more (HTMLTokenizer *);
-
-static HTMLTokenizer *e_searching_tokenizer_clone (HTMLTokenizer *);
-
-/*
- static const gchar *space_tags[] = { "br", NULL };*/
-
-static HTMLTokenizerClass *parent_class = NULL;
-
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-
-/* ???
-typedef struct _SharedState SharedState;
-struct _SharedState {
- gint refs;
- gchar *str_primary;
- gchar *str_secondary;
- gboolean case_sensitive_primary;
- gboolean case_sensitive_secondary;
-};
-*/
-
-/* ********************************************************************** */
-
-#if 0
-static SharedState *
-shared_state_new (void)
-{
- SharedState *shared = g_new0 (SharedState, 1);
- shared->refs = 1;
- return shared;
-}
-
-static void
-shared_state_ref (SharedState *shared)
-{
- g_return_if_fail (shared != NULL);
- g_return_if_fail (shared->refs > 0);
- ++shared->refs;
-}
-
-static void
-shared_state_unref (SharedState *shared)
-{
- if (shared) {
- g_return_if_fail (shared->refs > 0);
- --shared->refs;
- if (shared->refs == 0) {
- g_free (shared->str_primary);
- g_free (shared->str_secondary);
- g_free (shared);
- }
- }
-}
-#endif
-
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-
-/* ********************************************************************** */
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
/* Utility functions */
@@ -183,7 +124,7 @@ ignore_tag (const gchar *tag)
*out = 0;
for (i=0;i<sizeof(ignored_tags)/sizeof(ignored_tags[0]);i++) {
- if (strcmp(t, ignored_tags[i]) == 0)
+ if (strcmp (t, ignored_tags[i]) == 0)
return 1;
}
@@ -221,7 +162,7 @@ struct _trie {
/* will be enabled only if debug is enabled */
#if d(1) -1 != -1
static void
-dump_trie(struct _state *s, gint d)
+dump_trie (struct _state *s, gint d)
{
gchar *p = alloca(d*2+1);
struct _match *m;
@@ -234,7 +175,7 @@ dump_trie(struct _state *s, gint d)
while (m) {
printf(" %s'%c' -> %p\n", p, m->ch, m->match);
if (m->match)
- dump_trie(m->match, d+1);
+ dump_trie (m->match, d+1);
m = m->next;
}
}
@@ -246,7 +187,7 @@ dump_trie(struct _state *s, gint d)
for a neat demo */
static inline struct _match *
-g(struct _state *q, guint32 c)
+g (struct _state *q, guint32 c)
{
struct _match *m = q->matches;
@@ -257,7 +198,7 @@ g(struct _state *q, guint32 c)
}
static struct _trie *
-build_trie(gint nocase, gint len, guchar **words)
+build_trie (gint nocase, gint len, guchar **words)
{
struct _state *q, *qt, *r;
const guchar *word;
@@ -274,8 +215,8 @@ build_trie(gint nocase, gint len, guchar **words)
trie->root.fail = NULL;
trie->root.next = NULL;
- trie->state_chunks = e_memchunk_new(8, sizeof(struct _state));
- trie->match_chunks = e_memchunk_new(8, sizeof(struct _match));
+ trie->state_chunks = e_memchunk_new (8, sizeof(struct _state));
+ trie->match_chunks = e_memchunk_new (8, sizeof(struct _match));
/* This will correspond to the length of the longest pattern */
state_depth_size = 0;
@@ -293,8 +234,8 @@ build_trie(gint nocase, gint len, guchar **words)
depth = 0;
while ((c = camel_utf8_getc (&word))) {
if (nocase)
- c = g_unichar_tolower(c);
- m = g(q, c);
+ c = g_unichar_tolower (c);
+ m = g (q, c);
if (m == NULL) {
m = e_memchunk_alloc(trie->match_chunks);
m->ch = c;
@@ -323,7 +264,7 @@ build_trie(gint nocase, gint len, guchar **words)
}
d(printf("Dumping trie:\n"));
- d(dump_trie(&trie->root, 0));
+ d(dump_trie (&trie->root, 0));
/* Step 2: Build failure graph */
@@ -339,14 +280,14 @@ build_trie(gint nocase, gint len, guchar **words)
c = m->ch;
qt = m->match;
r = q->fail;
- while (r && (n = g(r, c)) == NULL)
+ while (r && (n = g (r, c)) == NULL)
r = r->fail;
if (r != NULL) {
qt->fail = n->match;
if (qt->fail->final > qt->final)
qt->final = qt->fail->final;
} else {
- if ((n = g(&trie->root, c)))
+ if ((n = g (&trie->root, c)))
qt->fail = n->match;
else
qt->fail = &trie->root;
@@ -357,10 +298,10 @@ build_trie(gint nocase, gint len, guchar **words)
}
}
- d(printf("After failure analysis\n"));
- d(dump_trie(&trie->root, 0));
+ d (printf("After failure analysis\n"));
+ d (dump_trie (&trie->root, 0));
- g_free(state_depth);
+ g_free (state_depth);
trie->max_depth = state_depth_size;
@@ -368,12 +309,12 @@ build_trie(gint nocase, gint len, guchar **words)
}
static void
-free_trie(struct _trie *t)
+free_trie (struct _trie *t)
{
e_memchunk_destroy(t->match_chunks);
e_memchunk_destroy(t->state_chunks);
- g_free(t);
+ g_free (t);
}
/* ********************************************************************** */
@@ -443,10 +384,10 @@ searcher_new (gint flags, gint argc, guchar **argv, const gchar *tags, const gch
s = g_malloc(sizeof(*s));
- s->t = build_trie((flags&SEARCH_CASE) == 0, argc, argv);
+ s->t = build_trie ((flags&SEARCH_CASE) == 0, argc, argv);
s->words = argc;
- s->tags = g_strdup(tags);
- s->tage = g_strdup(tage);
+ s->tags = g_strdup (tags);
+ s->tage = g_strdup (tage);
s->flags = flags;
s->state = &s->t->root;
s->matchcount = 0;
@@ -475,20 +416,20 @@ searcher_new (gint flags, gint argc, guchar **argv, const gchar *tags, const gch
}
static void
-searcher_free(struct _searcher *s)
+searcher_free (struct _searcher *s)
{
struct _token *t;
- while ((t = (struct _token *)e_dlist_remhead(&s->input)))
- g_free(t);
- while ((t = (struct _token *)e_dlist_remhead(&s->output)))
- g_free(t);
- g_free(s->tags);
- g_free(s->tage);
- g_free(s->last);
- g_free(s->submatches);
- free_trie(s->t);
- g_free(s);
+ while ((t = (struct _token *)e_dlist_remhead (&s->input)))
+ g_free (t);
+ while ((t = (struct _token *)e_dlist_remhead (&s->output)))
+ g_free (t);
+ g_free (s->tags);
+ g_free (s->tage);
+ g_free (s->last);
+ g_free (s->submatches);
+ free_trie (s->t);
+ g_free (s);
}
static struct _token *
append_token(EDList *list, const gchar *tok, gint len)
@@ -506,7 +447,7 @@ append_token(EDList *list, const gchar *tok, gint len)
return token;
}
-#define free_token(x) (g_free(x))
+#define free_token(x) (g_free (x))
static void
output_token(struct _searcher *s, struct _token *token)
@@ -516,10 +457,10 @@ output_token(struct _searcher *s, struct _token *token)
if (token->tok[0] == TAG_ESCAPE) {
if (token->offset >= s->offout) {
- d(printf("moving tag token '%s' from input to output\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("moving tag token '%s' from input to output\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
e_dlist_addtail(&s->output, (EDListNode *)token);
} else {
- d(printf("discarding tag token '%s' from input\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("discarding tag token '%s' from input\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
free_token(token);
}
} else {
@@ -528,12 +469,12 @@ output_token(struct _searcher *s, struct _token *token)
if (left > 0) {
pre = s->offout - token->offset;
if (pre>0)
- memmove(token->tok, token->tok+pre, left+1);
- d(printf("adding partial remaining/failed '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ memmove (token->tok, token->tok+pre, left+1);
+ d (printf("adding partial remaining/failed '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
s->offout = offend;
e_dlist_addtail(&s->output, (EDListNode *)token);
} else {
- d(printf("discarding whole token '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("discarding whole token '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
free_token(token);
}
}
@@ -562,30 +503,30 @@ output_match(struct _searcher *s, guint start, guint end)
struct _token *starttoken, *endtoken;
gchar b[8];
- d(printf("output match: %d-%d at %d\n", start, end, s->offout));
+ d (printf("output match: %d-%d at %d\n", start, end, s->offout));
starttoken = find_token(s, start);
endtoken = find_token(s, end);
if (starttoken == NULL || endtoken == NULL) {
- d(printf("Cannot find match history for match %d-%d\n", start, end));
+ d (printf("Cannot find match history for match %d-%d\n", start, end));
return;
}
- d(printf("start in token '%s'\n", starttoken->tok[0]==TAG_ESCAPE?starttoken->tok+1:starttoken->tok));
- d(printf("end in token '%s'\n", endtoken->tok[0]==TAG_ESCAPE?endtoken->tok+1:endtoken->tok));
+ d (printf("start in token '%s'\n", starttoken->tok[0]==TAG_ESCAPE?starttoken->tok+1:starttoken->tok));
+ d (printf("end in token '%s'\n", endtoken->tok[0]==TAG_ESCAPE?endtoken->tok+1:endtoken->tok));
/* output pending stuff that didn't match afterall */
while ((struct _token *)s->input.head != starttoken) {
- token = (struct _token *)e_dlist_remhead(&s->input);
- d(printf("appending failed match '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ token = (struct _token *)e_dlist_remhead (&s->input);
+ d (printf("appending failed match '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
output_token(s, token);
}
/* output any pre-match text */
if (s->offout < start) {
token = append_token(&s->output, starttoken->tok + (s->offout-starttoken->offset), start-s->offout);
- d(printf("adding pre-match text '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("adding pre-match text '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
s->offout = start;
}
@@ -597,11 +538,11 @@ output_match(struct _searcher *s, guint start, guint end)
if (s->tags)
append_token(&s->output, s->tags, -1);
- /* output match node(s) */
+ /* output match node (s) */
if (starttoken != endtoken) {
while ((struct _token *)s->input.head != endtoken) {
- token = (struct _token *)e_dlist_remhead(&s->input);
- d(printf("appending (partial) match node (head) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ token = (struct _token *)e_dlist_remhead (&s->input);
+ d (printf("appending (partial) match node (head) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
output_token(s, token);
}
}
@@ -609,7 +550,7 @@ output_match(struct _searcher *s, guint start, guint end)
/* any remaining partial content */
if (s->offout < end) {
token = append_token(&s->output, endtoken->tok+(s->offout-endtoken->offset), end-s->offout);
- d(printf("appending (partial) match node (tail) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("appending (partial) match node (tail) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
s->offout = end;
}
@@ -626,7 +567,7 @@ output_match(struct _searcher *s, guint start, guint end)
/* output any sub-pending blocks */
static void
-output_subpending(struct _searcher *s)
+output_subpending (struct _searcher *s)
{
gint i;
@@ -637,7 +578,7 @@ output_subpending(struct _searcher *s)
/* returns true if a merge took place */
static gint
-merge_subpending(struct _searcher *s, gint offstart, gint offend)
+merge_subpending (struct _searcher *s, gint offstart, gint offend)
{
gint i;
@@ -662,11 +603,11 @@ merge_subpending(struct _searcher *s, gint offstart, gint offend)
}
static void
-push_subpending(struct _searcher *s, gint offstart, gint offend)
+push_subpending (struct _searcher *s, gint offstart, gint offend)
{
/* This is really an assertion, we just ignore the last pending match instead of crashing though */
if (s->submatchp >= s->words) {
- d(printf("ERROR: submatch pending stack overflow\n"));
+ d (printf("ERROR: submatch pending stack overflow\n"));
s->submatchp = s->words-1;
}
@@ -677,11 +618,11 @@ push_subpending(struct _searcher *s, gint offstart, gint offend)
/* move any (partial) tokens from input to output if they are beyond the current output position */
static void
-output_pending(struct _searcher *s)
+output_pending (struct _searcher *s)
{
struct _token *token;
- while ( (token = (struct _token *)e_dlist_remhead(&s->input)) )
+ while ( (token = (struct _token *)e_dlist_remhead (&s->input)) )
output_token(s, token);
}
@@ -705,7 +646,7 @@ flush_extra(struct _searcher *s)
return;
while ((struct _token *)s->input.head != starttoken) {
- token = (struct _token *)e_dlist_remhead(&s->input);
+ token = (struct _token *)e_dlist_remhead (&s->input);
output_token(s, token);
}
}
@@ -725,8 +666,8 @@ searcher_next_token(struct _searcher *s)
/* get next token */
tok = (guchar *)s->next_token(s->next_data);
if (tok == NULL) {
- output_subpending(s);
- output_pending(s);
+ output_subpending (s);
+ output_pending (s);
break;
}
@@ -735,14 +676,14 @@ searcher_next_token(struct _searcher *s)
token->offset = s->offset;
tok = (guchar *)token->tok;
- d(printf("new token %d '%s'\n", token->offset, token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("new token %d '%s'\n", token->offset, token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
/* tag test, reset state on unknown tags */
if (tok[0] == TAG_ESCAPE) {
if (!ignore_tag ((gchar *)tok)) {
/* force reset */
- output_subpending(s);
- output_pending(s);
+ output_subpending (s);
+ output_pending (s);
q = &t->root;
}
@@ -753,12 +694,12 @@ searcher_next_token(struct _searcher *s)
pre_tok = stok = tok;
while ((c = camel_utf8_getc (&tok))) {
if ((s->flags & SEARCH_CASE) == 0)
- c = g_unichar_tolower(c);
- while (q && (m = g(q, c)) == NULL)
+ c = g_unichar_tolower (c);
+ while (q && (m = g (q, c)) == NULL)
q = q->fail;
if (q == NULL) {
/* mismatch ... reset state */
- output_subpending(s);
+ output_subpending (s);
q = &t->root;
} else if (m != NULL) {
/* keep track of previous offsets of utf8 chars, rotating buffer */
@@ -777,21 +718,21 @@ searcher_next_token(struct _searcher *s)
if (q->matches == NULL) {
if (s->submatchp == 0) {
/* nothing pending, always put something in so we can try merge */
- push_subpending(s, offstart, offend);
- } else if (!merge_subpending(s, offstart, offend)) {
+ push_subpending (s, offstart, offend);
+ } else if (!merge_subpending (s, offstart, offend)) {
/* can't merge, output what we have, and start againt */
- output_subpending(s);
- push_subpending(s, offstart, offend);
+ output_subpending (s);
+ push_subpending (s, offstart, offend);
/*output_match(s, offstart, offend);*/
} else if (e_dlist_length(&s->input) > 8) {
/* we're continuing to match and merge, but we have a lot of stuff
waiting, so flush it out now since this is a safe point to do it */
- output_subpending(s);
+ output_subpending (s);
}
} else {
/* merge/add subpending */
- if (!merge_subpending(s, offstart, offend))
- push_subpending(s, offstart, offend);
+ if (!merge_subpending (s, offstart, offend))
+ push_subpending (s, offstart, offend);
}
}
}
@@ -808,7 +749,7 @@ searcher_next_token(struct _searcher *s)
if (s->current)
free_token(s->current);
- s->current = token = (struct _token *)e_dlist_remhead(&s->output);
+ s->current = token = (struct _token *)e_dlist_remhead (&s->output);
return token ? g_strdup (token->tok) : NULL;
}
@@ -822,7 +763,7 @@ searcher_peek_token(struct _searcher *s)
tok = searcher_next_token(s);
if (tok) {
/* need to clear this so we dont free it while its still active */
- e_dlist_addhead(&s->output, (EDListNode *)s->current);
+ e_dlist_addhead (&s->output, (EDListNode *)s->current);
s->current = NULL;
}
@@ -830,7 +771,7 @@ searcher_peek_token(struct _searcher *s)
}
static gint
-searcher_pending(struct _searcher *s)
+searcher_pending (struct _searcher *s)
{
return !(e_dlist_empty(&s->input) && e_dlist_empty(&s->output));
}
@@ -839,7 +780,7 @@ searcher_pending(struct _searcher *s)
struct _search_info {
GPtrArray *strv;
- gchar *colour;
+ gchar *color;
guint size:8;
guint flags:8;
};
@@ -847,12 +788,12 @@ struct _search_info {
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
static struct _search_info *
-search_info_new(void)
+search_info_new (void)
{
struct _search_info *s;
s = g_malloc0(sizeof(struct _search_info));
- s->strv = g_ptr_array_new();
+ s->strv = g_ptr_array_new ();
return s;
}
@@ -864,14 +805,14 @@ search_info_set_flags(struct _search_info *si, guint flags, guint mask)
}
static void
-search_info_set_colour(struct _search_info *si, const gchar *colour)
+search_info_set_color (struct _search_info *si, const gchar *color)
{
- g_free(si->colour);
- si->colour = g_strdup(colour);
+ g_free (si->color);
+ si->color = g_strdup (color);
}
static void
-search_info_add_string(struct _search_info *si, const gchar *s)
+search_info_add_string (struct _search_info *si, const gchar *s)
{
const guchar *start;
guint32 c;
@@ -888,44 +829,44 @@ search_info_add_string(struct _search_info *si, const gchar *s)
}
/* should probably also strip trailing, but i'm lazy today */
if (start[0])
- g_ptr_array_add(si->strv, g_strdup ((gchar *)start));
+ g_ptr_array_add (si->strv, g_strdup ((gchar *)start));
}
}
static void
-search_info_clear(struct _search_info *si)
+search_info_clear (struct _search_info *si)
{
gint i;
for (i=0;i<si->strv->len;i++)
- g_free(si->strv->pdata[i]);
+ g_free (si->strv->pdata[i]);
- g_ptr_array_set_size(si->strv, 0);
+ g_ptr_array_set_size (si->strv, 0);
}
static void
-search_info_free(struct _search_info *si)
+search_info_free (struct _search_info *si)
{
gint i;
for (i=0;i<si->strv->len;i++)
- g_free(si->strv->pdata[i]);
+ g_free (si->strv->pdata[i]);
- g_ptr_array_free(si->strv, TRUE);
- g_free(si->colour);
- g_free(si);
+ g_ptr_array_free (si->strv, TRUE);
+ g_free (si->color);
+ g_free (si);
}
static struct _search_info *
-search_info_clone(struct _search_info *si)
+search_info_clone (struct _search_info *si)
{
struct _search_info *out;
gint i;
- out = search_info_new();
+ out = search_info_new ();
for (i=0;i<si->strv->len;i++)
- g_ptr_array_add(out->strv, g_strdup(si->strv->pdata[i]));
- out->colour = g_strdup(si->colour);
+ g_ptr_array_add (out->strv, g_strdup (si->strv->pdata[i]));
+ out->color = g_strdup (si->color);
out->flags = si->flags;
out->size = si->size;
@@ -933,7 +874,7 @@ search_info_clone(struct _search_info *si)
}
static struct _searcher *
-search_info_to_searcher(struct _search_info *si)
+search_info_to_searcher (struct _search_info *si)
{
gchar *tags, *tage;
const gchar *col;
@@ -941,10 +882,10 @@ search_info_to_searcher(struct _search_info *si)
if (si->strv->len == 0)
return NULL;
- if (si->colour == NULL)
+ if (si->color == NULL)
col = "red";
else
- col = si->colour;
+ col = si->color;
tags = alloca(20+strlen(col));
sprintf(tags, "%c<font color=\"%s\">", TAG_ESCAPE, col);
@@ -963,287 +904,289 @@ struct _ESearchingTokenizerPrivate {
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-static void
-e_searching_tokenizer_finalise (GObject *obj)
-{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (obj);
- struct _ESearchingTokenizerPrivate *p = st->priv;
-
- search_info_free (p->primary);
- search_info_free (p->secondary);
- if (p->engine)
- searcher_free(p->engine);
+/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
- /* again wtf?
- shared_state_unref (st->priv->shared);
- */
+/* blah blah the htmltokeniser doesn't like being asked
+ for a token if it doens't hvae any! */
+static gchar *
+get_token (HTMLTokenizer *tokenizer)
+{
+ HTMLTokenizerClass *class = HTML_TOKENIZER_CLASS (parent_class);
- g_free (p);
+ if (class->has_more (tokenizer))
+ return class->next_token (tokenizer);
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize(obj);
+ return NULL;
}
+/* proxy matched event, not sure what its for otherwise */
static void
-e_searching_tokenizer_class_init (ESearchingTokenizerClass *klass)
+matched (ESearchingTokenizer *tokenizer)
{
- GObjectClass *obj_class = (GObjectClass *) klass;
- HTMLTokenizerClass *tok_class = HTML_TOKENIZER_CLASS (klass);
-
- parent_class = g_type_class_ref (HTML_TYPE_TOKENIZER);
-
- signals[MATCH_SIGNAL] =
- g_signal_new ("match",
- E_TYPE_SEARCHING_TOKENIZER,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESearchingTokenizerClass, match),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- obj_class->finalize = e_searching_tokenizer_finalise;
-
- tok_class->begin = e_searching_tokenizer_begin;
- tok_class->end = e_searching_tokenizer_end;
-
- tok_class->peek_token = e_searching_tokenizer_peek_token;
- tok_class->next_token = e_searching_tokenizer_next_token;
- tok_class->has_more = e_searching_tokenizer_has_more;
- tok_class->clone = e_searching_tokenizer_clone;
+ /*++tokenizer->priv->match_count;*/
+ g_signal_emit (tokenizer, signals[MATCH_SIGNAL], 0);
}
-static void
-e_searching_tokenizer_init (ESearchingTokenizer *st)
-{
- struct _ESearchingTokenizerPrivate *p;
-
- p = st->priv = g_new0 (struct _ESearchingTokenizerPrivate, 1);
-
- p->primary = search_info_new();
- search_info_set_flags(p->primary, SEARCH_BOLD, SEARCH_CASE|SEARCH_BOLD);
- search_info_set_colour(p->primary, "red");
-
- p->secondary = search_info_new();
- search_info_set_flags(p->secondary, SEARCH_BOLD, SEARCH_CASE|SEARCH_BOLD);
- search_info_set_colour(p->secondary, "purple");
-}
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-GType
-e_searching_tokenizer_get_type (void)
+static void
+searching_tokenizer_finalize (GObject *object)
{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (ESearchingTokenizerClass),
- NULL, NULL,
- (GClassInitFunc) e_searching_tokenizer_class_init,
- NULL, NULL,
- sizeof (ESearchingTokenizer),
- 0,
- (GInstanceInitFunc) e_searching_tokenizer_init,
- };
-
- type = g_type_register_static (HTML_TYPE_TOKENIZER, "ESearchingTokenizer", &info, 0);
- }
-
- return type;
-}
+ ESearchingTokenizerPrivate *priv;
-ESearchingTokenizer *
-e_searching_tokenizer_new (void)
-{
- return g_object_new (E_TYPE_SEARCHING_TOKENIZER, NULL);
-}
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (object);
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
+ search_info_free (priv->primary);
+ search_info_free (priv->secondary);
-/* blah blah the htmltokeniser doesn't like being asked
- for a token if it doens't hvae any! */
-static gchar *get_token(HTMLTokenizer *t)
-{
- HTMLTokenizerClass *klass = HTML_TOKENIZER_CLASS (parent_class);
+ if (priv->engine != NULL)
+ searcher_free (priv->engine);
- return klass->has_more(t) ? klass->next_token(t) : NULL;
+ /* Chain up to parent's finalize () method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-e_searching_tokenizer_begin (HTMLTokenizer *t, const gchar *content_type)
+searching_tokenizer_begin (HTMLTokenizer *tokenizer,
+ const gchar *content_type)
{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t);
- struct _ESearchingTokenizerPrivate *p = st->priv;
+ ESearchingTokenizerPrivate *priv;
+
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
/* reset search */
- if (p->engine) {
- searcher_free(p->engine);
- p->engine = NULL;
+ if (priv->engine != NULL) {
+ searcher_free (priv->engine);
+ priv->engine = NULL;
}
- if ((p->engine = search_info_to_searcher(p->primary))
- || (p->engine = search_info_to_searcher(p->secondary))) {
- /*HTMLTokenizerClass *klass = HTML_TOKENIZER_CLASS (parent_class);*/
-
- /*searcher_set_tokenfunc(p->engine, klass->next_token, st);*/
- searcher_set_tokenfunc(p->engine, get_token, st);
+ if ((priv->engine = search_info_to_searcher (priv->primary))
+ || (priv->engine = search_info_to_searcher (priv->secondary))) {
+ searcher_set_tokenfunc(priv->engine, get_token, tokenizer);
}
/* else - no engine, no search active */
- HTML_TOKENIZER_CLASS (parent_class)->begin (t, content_type);
-}
-
-static void
-e_searching_tokenizer_end (HTMLTokenizer *t)
-{
- /* so end gets called before any get/next tokens.
- I dont get it. */
-#if 0
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t);
- struct _ESearchingTokenizerPrivate *p = st->priv;
-
- /* not sure if we should reset search every time ... *shrug* */
- if (p->engine) {
- searcher_free(p->engine);
- p->engine = NULL;
- }
-#endif
-
- HTML_TOKENIZER_CLASS (parent_class)->end (t);
+ /* Chain up to parent's begin() method. */
+ HTML_TOKENIZER_CLASS (parent_class)->begin (tokenizer, content_type);
}
static gchar *
-e_searching_tokenizer_peek_token (HTMLTokenizer *tok)
+searching_tokenizer_peek_token (HTMLTokenizer *tokenizer)
{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok);
+ ESearchingTokenizerPrivate *priv;
- /* If no search is active, just use the default method. */
- if (st->priv->engine == NULL)
- return HTML_TOKENIZER_CLASS (parent_class)->peek_token (tok);
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
- return searcher_peek_token(st->priv->engine);
+ if (priv->engine != NULL)
+ return searcher_peek_token (priv->engine);
+
+ /* Chain up to parent's peek_token() method. */
+ return HTML_TOKENIZER_CLASS (parent_class)->peek_token (tokenizer);
}
static gchar *
-e_searching_tokenizer_next_token (HTMLTokenizer *tok)
+searching_tokenizer_next_token (HTMLTokenizer *tokenizer)
{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok);
+ ESearchingTokenizerPrivate *priv;
gint oldmatched;
gchar *token;
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
+
/* If no search is active, just use the default method. */
- if (st->priv->engine == NULL)
- return HTML_TOKENIZER_CLASS (parent_class)->next_token (tok);
+ if (priv->engine == NULL)
+ return HTML_TOKENIZER_CLASS (parent_class)->next_token (tokenizer);
- oldmatched = st->priv->engine->matchcount;
+ oldmatched = priv->engine->matchcount;
- token = searcher_next_token(st->priv->engine);
+ token = searcher_next_token (priv->engine);
/* not sure if this has to be accurate or just say we had some matches */
- if (oldmatched != st->priv->engine->matchcount)
- g_signal_emit (st, signals[MATCH_SIGNAL], 0);
+ if (oldmatched != priv->engine->matchcount)
+ g_signal_emit (tokenizer, signals[MATCH_SIGNAL], 0);
return token;
}
static gboolean
-e_searching_tokenizer_has_more (HTMLTokenizer *tok)
+searching_tokenizer_has_more (HTMLTokenizer *tokenizer)
{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok);
+ ESearchingTokenizerPrivate *priv;
- return (st->priv->engine != NULL && searcher_pending(st->priv->engine))
- || HTML_TOKENIZER_CLASS (parent_class)->has_more (tok);
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
+
+ return (priv->engine != NULL && searcher_pending (priv->engine)) ||
+ HTML_TOKENIZER_CLASS (parent_class)->has_more (tokenizer);
}
-/* proxy matched event, not sure what its for otherwise */
+static HTMLTokenizer *
+searching_tokenizer_clone (HTMLTokenizer *tokenizer)
+{
+ ESearchingTokenizer *orig_st;
+ ESearchingTokenizer *new_st;
+
+ orig_st = E_SEARCHING_TOKENIZER (tokenizer);
+ new_st = e_searching_tokenizer_new ();
+
+ search_info_free (new_st->priv->primary);
+ search_info_free (new_st->priv->secondary);
+
+ new_st->priv->primary = search_info_clone (orig_st->priv->primary);
+ new_st->priv->secondary = search_info_clone (orig_st->priv->secondary);
+
+ g_signal_connect_swapped (
+ new_st, "match", G_CALLBACK (matched), orig_st);
+
+ return HTML_TOKENIZER (new_st);
+}
static void
-matched (ESearchingTokenizer *st)
+searching_tokenizer_class_init (ESearchingTokenizerClass *class)
{
- /*++st->priv->match_count;*/
- g_signal_emit (st, signals[MATCH_SIGNAL], 0);
+ GObjectClass *object_class;
+ HTMLTokenizerClass *tokenizer_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ESearchingTokenizerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = searching_tokenizer_finalize;
+
+ tokenizer_class = HTML_TOKENIZER_CLASS (class);
+ tokenizer_class->begin = searching_tokenizer_begin;
+ tokenizer_class->peek_token = searching_tokenizer_peek_token;
+ tokenizer_class->next_token = searching_tokenizer_next_token;
+ tokenizer_class->has_more = searching_tokenizer_has_more;
+ tokenizer_class->clone = searching_tokenizer_clone;
+
+ signals[MATCH_SIGNAL] = g_signal_new (
+ "match",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ESearchingTokenizerClass, match),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
-static HTMLTokenizer *
-e_searching_tokenizer_clone (HTMLTokenizer *tok)
+static void
+searching_tokenizer_init (ESearchingTokenizer *tokenizer)
{
- ESearchingTokenizer *orig_st = E_SEARCHING_TOKENIZER (tok);
- ESearchingTokenizer *new_st = E_SEARCHING_TOKENIZER (e_searching_tokenizer_new ());
+ tokenizer->priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
+
+ tokenizer->priv->primary = search_info_new ();
+ search_info_set_flags (
+ tokenizer->priv->primary,
+ SEARCH_BOLD, SEARCH_CASE | SEARCH_BOLD);
+ search_info_set_color (tokenizer->priv->primary, "red");
+
+ tokenizer->priv->secondary = search_info_new ();
+ search_info_set_flags(
+ tokenizer->priv->secondary,
+ SEARCH_BOLD, SEARCH_CASE | SEARCH_BOLD);
+ search_info_set_color (tokenizer->priv->secondary, "purple");
+}
- search_info_free(new_st->priv->primary);
- search_info_free(new_st->priv->secondary);
+GType
+e_searching_tokenizer_get_type (void)
+{
+ static GType type = 0;
- new_st->priv->primary = search_info_clone(orig_st->priv->primary);
- new_st->priv->secondary = search_info_clone(orig_st->priv->secondary);
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ESearchingTokenizerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) searching_tokenizer_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ESearchingTokenizer),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) searching_tokenizer_init,
+ NULL /* value_table */
+ };
-#if 0
- shared_state_ref (orig_st->priv->shared);
- shared_state_unref (new_st->priv->shared);
- new_st->priv->shared = orig_st->priv->shared;
-#endif
+ type = g_type_register_static (
+ HTML_TYPE_TOKENIZER, "ESearchingTokenizer",
+ &type_info, 0);
+ }
- g_signal_connect_swapped (new_st, "match", G_CALLBACK(matched), orig_st);
+ return type;
+}
- return HTML_TOKENIZER (new_st);
+ESearchingTokenizer *
+e_searching_tokenizer_new (void)
+{
+ return g_object_new (E_TYPE_SEARCHING_TOKENIZER, NULL);
}
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
void
-e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *tokenizer,
+ const gchar *primary_string)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_clear(st->priv->primary);
- search_info_add_string(st->priv->primary, search_str);
+ search_info_clear (tokenizer->priv->primary);
+ search_info_add_string (tokenizer->priv->primary, primary_string);
}
void
-e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *tokenizer,
+ const gchar *primary_string)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_add_string(st->priv->primary, search_str);
+ search_info_add_string (tokenizer->priv->primary, primary_string);
}
void
-e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *st, gboolean iscase)
+e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *tokenizer,
+ gboolean case_sensitive)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_set_flags(st->priv->primary, iscase?SEARCH_CASE:0, SEARCH_CASE);
+ search_info_set_flags (
+ tokenizer->priv->primary,
+ case_sensitive ? SEARCH_CASE : 0, SEARCH_CASE);
}
void
-e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *tokenizer,
+ const gchar *secondary_string)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_clear(st->priv->secondary);
- search_info_add_string(st->priv->secondary, search_str);
+ search_info_clear (tokenizer->priv->secondary);
+ search_info_add_string (tokenizer->priv->secondary, secondary_string);
}
void
-e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *tokenizer,
+ const gchar *secondary_string)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_add_string(st->priv->secondary, search_str);
+ search_info_add_string (tokenizer->priv->secondary, secondary_string);
}
void
-e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *st, gboolean iscase)
+e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *tokenizer,
+ gboolean case_sensitive)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_set_flags(st->priv->secondary, iscase?SEARCH_CASE:0, SEARCH_CASE);
+ search_info_set_flags (
+ tokenizer->priv->secondary,
+ case_sensitive ? SEARCH_CASE : 0, SEARCH_CASE);
}
/* Note: only returns the primary search string count */
gint
-e_searching_tokenizer_match_count (ESearchingTokenizer *st)
+e_searching_tokenizer_match_count (ESearchingTokenizer *tokenizer)
{
- g_return_val_if_fail (E_IS_SEARCHING_TOKENIZER (st), -1);
+ g_return_val_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer), -1);
- if (st->priv->engine && st->priv->primary->strv->len)
- return st->priv->engine->matchcount;
+ if (tokenizer->priv->engine && tokenizer->priv->primary->strv->len)
+ return tokenizer->priv->engine->matchcount;
return 0;
}
diff --git a/mail/e-searching-tokenizer.h b/mail/e-searching-tokenizer.h
index ddb47d7f05..7eb603a25d 100644
--- a/mail/e-searching-tokenizer.h
+++ b/mail/e-searching-tokenizer.h
@@ -21,49 +21,72 @@
*
*/
-#ifndef __E_SEARCHING_TOKENIZER_H__
-#define __E_SEARCHING_TOKENIZER_H__
+#ifndef E_SEARCHING_TOKENIZER_H
+#define E_SEARCHING_TOKENIZER_H
#include <glib.h>
#include <gtkhtml/htmltokenizer.h>
-#define E_TYPE_SEARCHING_TOKENIZER (e_searching_tokenizer_get_type ())
-#define E_SEARCHING_TOKENIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizer))
-#define E_SEARCHING_TOKENIZER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass))
-#define E_IS_SEARCHING_TOKENIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_SEARCHING_TOKENIZER))
-#define E_IS_SEARCHING_TOKENIZER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_SEARCHING_TOKENIZER))
+/* Standard GObject macros */
+#define E_TYPE_SEARCHING_TOKENIZER \
+ (e_searching_tokenizer_get_type ())
+#define E_SEARCHING_TOKENIZER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizer))
+#define E_SEARCHING_TOKENIZER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass))
+#define E_IS_SEARCHING_TOKENIZER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SEARCHING_TOKENIZER))
+#define E_IS_SEARCHING_TOKENIZER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SEARCHING_TOKENIZER))
+#define E_SEARCH_TOKENIZER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass))
+
+G_BEGIN_DECLS
typedef struct _ESearchingTokenizer ESearchingTokenizer;
typedef struct _ESearchingTokenizerClass ESearchingTokenizerClass;
-
-struct _ESearchingTokenizerPrivate;
+typedef struct _ESearchingTokenizerPrivate ESearchingTokenizerPrivate;
struct _ESearchingTokenizer {
HTMLTokenizer parent;
-
- struct _ESearchingTokenizerPrivate *priv;
+ ESearchingTokenizerPrivate *priv;
};
struct _ESearchingTokenizerClass {
HTMLTokenizerClass parent_class;
- void (*match) (ESearchingTokenizer *);
+ void (*match) (ESearchingTokenizer *tokenizer);
};
-GType e_searching_tokenizer_get_type (void);
-
-ESearchingTokenizer *e_searching_tokenizer_new (void);
-
-/* For now, just a simple API */
-
-void e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *, const gchar *);
-void e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *, const gchar *);
-void e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *, gboolean is_case_sensitive);
-
-void e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *, const gchar *);
-void e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str);
-void e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *, gboolean is_case_sensitive);
-
-gint e_searching_tokenizer_match_count (ESearchingTokenizer *);
-
-#endif /* __E_SEARCHING_TOKENIZER_H__ */
+GType e_searching_tokenizer_get_type (void);
+ESearchingTokenizer *
+ e_searching_tokenizer_new (void);
+void e_searching_tokenizer_set_primary_search_string
+ (ESearchingTokenizer *tokenizer,
+ const gchar *primary_string);
+void e_searching_tokenizer_add_primary_search_string
+ (ESearchingTokenizer *tokenizer,
+ const gchar *primary_string);
+void e_searching_tokenizer_set_primary_case_sensitivity
+ (ESearchingTokenizer *tokenizer,
+ gboolean case_sensitive);
+void e_searching_tokenizer_set_secondary_search_string
+ (ESearchingTokenizer *tokenizer,
+ const gchar *secondary_string);
+void e_searching_tokenizer_add_secondary_search_string
+ (ESearchingTokenizer *tokenizer,
+ const gchar *secondary_string);
+void e_searching_tokenizer_set_secondary_case_sensitivity
+ (ESearchingTokenizer *tokenizer,
+ gboolean case_sensitive);
+gint e_searching_tokenizer_match_count
+ (ESearchingTokenizer *tokenizer);
+
+G_END_DECLS
+
+#endif /* E_SEARCHING_TOKENIZER_H */
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
index 0c7e978a2f..af4be14a69 100644
--- a/mail/em-account-editor.c
+++ b/mail/em-account-editor.c
@@ -26,7 +26,7 @@
work before merge can occur:
verify behaviour.
- work out what to do with the startup druid.
+ work out what to do with the startup assistant.
also need to work out:
how to remove unecessary items from a service url once
@@ -48,24 +48,22 @@
#include <glade/glade.h>
-#include <libgnomeui/gnome-druid.h>
-#include <libgnomeui/gnome-druid-page-standard.h>
-
-#include <libedataserver/e-account-list.h>
-#include <e-util/e-signature-list.h>
-
+#include "shell/e-shell.h"
#include "e-util/e-error.h"
+#include "e-util/e-account-utils.h"
+#include "e-util/e-signature-list.h"
+#include "e-util/e-signature-utils.h"
#include "e-util/e-util-private.h"
+#include "widgets/misc/e-signature-editor.h"
+#include "e-mail-local.h"
+#include "e-mail-store.h"
#include "em-config.h"
#include "em-folder-selection-button.h"
#include "em-account-editor.h"
#include "mail-session.h"
#include "mail-send-recv.h"
-#include "mail-signature-editor.h"
-#include "mail-component.h"
#include "em-utils.h"
-#include "em-composer-prefs.h"
#include "mail-config.h"
#include "mail-ops.h"
#include "mail-mt.h"
@@ -74,6 +72,10 @@
#include "smime/gui/e-cert-selector.h"
#endif
+#define EM_ACCOUNT_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorPrivate))
+
#define d(x)
/* econfig item for the extra config hings */
@@ -128,6 +130,10 @@ typedef struct _EMAccountEditorService {
} EMAccountEditorService;
struct _EMAccountEditorPrivate {
+
+ EAccount *modified_account;
+ EAccount *original_account;
+
struct _EMConfig *config;
GList *providers;
@@ -181,60 +187,194 @@ struct _EMAccountEditorPrivate {
const gchar *widgets_name[5];
gint widgets_index;
- /* for druid page preparation */
+ /* for assistant page preparation */
guint identity_set:1;
guint receive_set:1;
guint send_set:1;
guint management_set:1;
};
+enum {
+ PROP_0,
+ PROP_MODIFIED_ACCOUNT,
+ PROP_ORIGINAL_ACCOUNT,
+ PROP_SHELL
+};
+
static void emae_refresh_authtype (EMAccountEditor *emae, EMAccountEditorService *service);
-static void em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_account_editor_t type, const gchar *id);
+static void em_account_editor_construct (EMAccountEditor *emae, EMAccountEditorType type, const gchar *id);
static void emae_account_folder_changed (EMFolderSelectionButton *folder, EMAccountEditor *emae);
-static GtkVBoxClass *emae_parent;
+
+static gpointer parent_class;
static void
-emae_init (GObject *o)
+emae_set_original_account (EMAccountEditor *emae,
+ EAccount *original_account)
{
- EMAccountEditor *emae = (EMAccountEditor *)o;
+ EAccount *modified_account;
- emae->priv = g_malloc0(sizeof (*emae->priv));
+ g_return_if_fail (emae->priv->original_account == NULL);
- emae->priv->source.emae = emae;
- emae->priv->transport.emae = emae;
+ /* Editing an existing account. */
+ if (original_account != NULL) {
+ gchar *xml;
+
+ xml = e_account_to_xml (original_account);
+ modified_account = e_account_new_from_xml (xml);
+ g_free (xml);
+
+ g_object_ref (original_account);
+ if (emae->type != EMAE_PAGES)
+ emae->do_signature = TRUE;
+
+ /* Creating a new account. */
+ } else {
+ modified_account = e_account_new ();
+ modified_account->enabled = TRUE;
+
+ e_account_set_string (
+ modified_account, E_ACCOUNT_DRAFTS_FOLDER_URI,
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS));
+
+ e_account_set_string (
+ modified_account, E_ACCOUNT_SENT_FOLDER_URI,
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_SENT));
+ }
+
+ emae->priv->original_account = original_account;
+ emae->priv->modified_account = modified_account;
}
static void
-emae_finalise (GObject *o)
+emae_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- EMAccountEditor *emae = (EMAccountEditor *)o;
- EMAccountEditorPrivate *p = emae->priv;
+ switch (property_id) {
+ case PROP_ORIGINAL_ACCOUNT:
+ emae_set_original_account (
+ EM_ACCOUNT_EDITOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+emae_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODIFIED_ACCOUNT:
+ g_value_set_object (
+ value,
+ em_account_editor_get_modified_account (
+ EM_ACCOUNT_EDITOR (object)));
+ return;
+
+ case PROP_ORIGINAL_ACCOUNT:
+ g_value_set_object (
+ value,
+ em_account_editor_get_original_account (
+ EM_ACCOUNT_EDITOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+emae_dispose (GObject *object)
+{
+ EMAccountEditorPrivate *priv;
+
+ priv = EM_ACCOUNT_EDITOR_GET_PRIVATE (object);
+
+ if (priv->modified_account != NULL) {
+ g_object_unref (priv->modified_account);
+ priv->modified_account = NULL;
+ }
+
+ if (priv->original_account != NULL) {
+ g_object_unref (priv->original_account);
+ priv->original_account = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
- if (p->sig_added_id) {
- ESignatureList *signatures = mail_config_get_signatures ();
+static void
+emae_finalize (GObject *object)
+{
+ EMAccountEditor *emae = EM_ACCOUNT_EDITOR (object);
+ EMAccountEditorPrivate *priv = emae->priv;
+
+ if (priv->sig_added_id) {
+ ESignatureList *signatures;
- g_signal_handler_disconnect (signatures, p->sig_added_id);
- g_signal_handler_disconnect (signatures, p->sig_removed_id);
- g_signal_handler_disconnect (signatures, p->sig_changed_id);
+ signatures = e_get_signature_list ();
+ g_signal_handler_disconnect (signatures, priv->sig_added_id);
+ g_signal_handler_disconnect (signatures, priv->sig_removed_id);
+ g_signal_handler_disconnect (signatures, priv->sig_changed_id);
}
- g_list_free (p->source.authtypes);
- g_list_free (p->transport.authtypes);
+ g_list_free (priv->source.authtypes);
+ g_list_free (priv->transport.authtypes);
- g_list_free (p->providers);
- g_free (p);
+ g_list_free (priv->providers);
- g_object_unref (emae->account);
- if (emae->original)
- g_object_unref (emae->original);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
- ((GObjectClass *)emae_parent)->finalize (o);
+static void
+emae_class_init (GObjectClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMAccountEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = emae_set_property;
+ object_class->get_property = emae_get_property;
+ object_class->dispose = emae_dispose;
+ object_class->finalize = emae_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODIFIED_ACCOUNT,
+ g_param_spec_object (
+ "modified-account",
+ "Modified Account",
+ NULL,
+ E_TYPE_ACCOUNT,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ORIGINAL_ACCOUNT,
+ g_param_spec_object (
+ "original-account",
+ "Original Account",
+ NULL,
+ E_TYPE_ACCOUNT,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
}
static void
-emae_class_init (GObjectClass *klass)
+emae_init (EMAccountEditor *emae)
{
- klass->finalize = emae_finalise;
+ emae->priv = EM_ACCOUNT_EDITOR_GET_PRIVATE (emae);
+
+ emae->priv->source.emae = emae;
+ emae->priv->transport.emae = emae;
}
GType
@@ -242,17 +382,22 @@ em_account_editor_get_type (void)
{
static GType type = 0;
- if (type == 0) {
- static const GTypeInfo info = {
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
sizeof (EMAccountEditorClass),
- NULL, NULL,
- (GClassInitFunc)emae_class_init,
- NULL, NULL,
- sizeof (EMAccountEditor), 0,
- (GInstanceInitFunc)emae_init
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) emae_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMAccountEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) emae_init,
+ NULL /* value_table */
};
- emae_parent = g_type_class_ref (G_TYPE_OBJECT);
- type = g_type_register_static (G_TYPE_OBJECT, "EMAccountEditor", &info, 0);
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EMAccountEditor", &type_info, 0);
}
return type;
@@ -269,11 +414,18 @@ em_account_editor_get_type (void)
*
* Return value:
**/
-EMAccountEditor *em_account_editor_new (EAccount *account, em_account_editor_t type, const gchar *id)
+EMAccountEditor *
+em_account_editor_new (EAccount *account,
+ EMAccountEditorType type,
+ const gchar *id)
{
- EMAccountEditor *emae = g_object_new (em_account_editor_get_type (), NULL);
+ EMAccountEditor *emae;
- em_account_editor_construct (emae, account, type, id);
+ emae = g_object_new (
+ EM_TYPE_ACCOUNT_EDITOR,
+ "original-account", account, NULL);
+
+ em_account_editor_construct (emae, type, id);
return emae;
}
@@ -289,15 +441,40 @@ EMAccountEditor *em_account_editor_new (EAccount *account, em_account_editor_t t
*
* Return value:
**/
-EMAccountEditor *em_account_editor_new_for_pages (EAccount *account, em_account_editor_t type, gchar *id, GtkWidget **pages)
+EMAccountEditor *
+em_account_editor_new_for_pages (EAccount *account,
+ EMAccountEditorType type,
+ const gchar *id,
+ GtkWidget **pages)
{
- EMAccountEditor *emae = g_object_new (em_account_editor_get_type (), NULL);
+ EMAccountEditor *emae;
+
+ emae = g_object_new (
+ EM_TYPE_ACCOUNT_EDITOR,
+ "original-account", account, NULL);
+
emae->pages = pages;
- em_account_editor_construct (emae, account, type, id);
+ em_account_editor_construct (emae, type, id);
return emae;
}
+EAccount *
+em_account_editor_get_modified_account (EMAccountEditor *emae)
+{
+ g_return_val_if_fail (EM_IS_ACCOUNT_EDITOR (emae), NULL);
+
+ return emae->priv->modified_account;
+}
+
+EAccount *
+em_account_editor_get_original_account (EMAccountEditor *emae)
+{
+ g_return_val_if_fail (EM_IS_ACCOUNT_EDITOR (emae), NULL);
+
+ return emae->priv->original_account;
+}
+
/* ********************************************************************** */
static struct {
@@ -337,10 +514,12 @@ is_email (const gchar *address)
static CamelURL *
emae_account_url (EMAccountEditor *emae, gint urlid)
{
+ EAccount *account;
CamelURL *url = NULL;
const gchar *uri;
- uri = e_account_get_string (emae->account, urlid);
+ account = em_account_editor_get_modified_account (emae);
+ uri = e_account_get_string (account, urlid);
if (uri && uri[0])
url = camel_url_new (uri, NULL);
@@ -469,11 +648,11 @@ default_folders_clicked (GtkButton *button, gpointer user_data)
EMAccountEditor *emae = user_data;
const gchar *uri;
- uri = mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_DRAFTS);
+ uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS);
em_folder_selection_button_set_selection ((EMFolderSelectionButton *)emae->priv->drafts_folder_button, uri);
emae_account_folder_changed ((EMFolderSelectionButton *)emae->priv->drafts_folder_button, emae);
- uri = mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_SENT);
+ uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_SENT);
em_folder_selection_button_set_selection ((EMFolderSelectionButton *)emae->priv->sent_folder_button, uri);
emae_account_folder_changed ((EMFolderSelectionButton *)emae->priv->sent_folder_button, emae);
}
@@ -484,7 +663,8 @@ GtkWidget *em_account_editor_folder_selector_button_new (gchar *widget_name, gch
GtkWidget *
em_account_editor_folder_selector_button_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2)
{
- return (GtkWidget *)em_folder_selection_button_new (string1 ? string1 : _("Select Folder"), NULL);
+ return (GtkWidget *)em_folder_selection_button_new (
+ string1 ? string1 : _("Select Folder"), NULL);
}
GtkWidget *em_account_editor_dropdown_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2);
@@ -492,7 +672,7 @@ GtkWidget *em_account_editor_dropdown_new (gchar *widget_name, gchar *string1, g
GtkWidget *
em_account_editor_dropdown_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2)
{
- return (GtkWidget *)gtk_combo_box_new ();
+ return gtk_combo_box_new ();
}
GtkWidget *em_account_editor_ssl_selector_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2);
@@ -670,34 +850,53 @@ emae_signature_changed (ESignatureList *signatures, ESignature *sig, EMAccountEd
static void
emae_signaturetype_changed (GtkComboBox *dropdown, EMAccountEditor *emae)
{
+ EAccount *account;
gint id = gtk_combo_box_get_active (dropdown);
GtkTreeModel *model;
GtkTreeIter iter;
gchar *uid = NULL;
+ account = em_account_editor_get_modified_account (emae);
+
if (id != -1) {
model = gtk_combo_box_get_model (dropdown);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, id))
gtk_tree_model_get (model, &iter, 1, &uid, -1);
}
- e_account_set_string (emae->account, E_ACCOUNT_ID_SIGNATURE, uid);
+ e_account_set_string (account, E_ACCOUNT_ID_SIGNATURE, uid);
g_free (uid);
}
static void
-emae_signature_new (GtkWidget *w, EMAccountEditor *emae)
+emae_signature_new (GtkWidget *widget, EMAccountEditor *emae)
{
- /* TODO: why is this in composer prefs? apart from it being somewhere to put it? */
- em_composer_prefs_new_signature ((GtkWindow *)gtk_widget_get_toplevel (w),
- gconf_client_get_bool (mail_config_get_gconf_client (),
- "/apps/evolution/mail/composer/send_html", NULL));
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GtkWidget *editor;
+ gboolean html_mode;
+ gpointer parent;
+
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ parent = gtk_widget_get_toplevel (widget);
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ html_mode = e_shell_settings_get_boolean (
+ shell_settings, "composer-format-html");
+
+ editor = e_signature_editor_new ();
+ gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (editor), html_mode);
+ gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
+ gtk_widget_show (editor);
}
static GtkWidget *
emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
{
EMAccountEditorPrivate *p = emae->priv;
+ EAccount *account;
GtkComboBox *dropdown = (GtkComboBox *)glade_xml_get_widget (xml, "signature_dropdown");
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
GtkListStore *store;
@@ -705,9 +904,12 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
GtkTreeIter iter;
ESignatureList *signatures;
EIterator *it;
- const gchar *current = e_account_get_string (emae->account, E_ACCOUNT_ID_SIGNATURE);
+ const gchar *current;
GtkWidget *button;
+ account = em_account_editor_get_modified_account (emae);
+ current = e_account_get_string (account, E_ACCOUNT_ID_SIGNATURE);
+
emae->priv->signatures_dropdown = dropdown;
gtk_widget_show ((GtkWidget *)dropdown);
@@ -716,7 +918,7 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, _("None"), 1, NULL, -1);
- signatures = mail_config_get_signatures ();
+ signatures = e_get_signature_list ();
if (p->sig_added_id == 0) {
p->sig_added_id = g_signal_connect (signatures, "signature-added", G_CALLBACK(emae_signature_added), emae);
@@ -753,7 +955,7 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
gtk_combo_box_set_active (dropdown, active);
g_signal_connect (dropdown, "changed", G_CALLBACK(emae_signaturetype_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)dropdown, e_account_writable (emae->account, E_ACCOUNT_ID_SIGNATURE));
+ gtk_widget_set_sensitive ((GtkWidget *)dropdown, e_account_writable (account, E_ACCOUNT_ID_SIGNATURE));
button = glade_xml_get_widget (xml, "sigAddNew");
g_signal_connect (button, "clicked", G_CALLBACK(emae_signature_new), emae);
@@ -767,29 +969,32 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
static void
emae_receipt_policy_changed (GtkComboBox *dropdown, EMAccountEditor *emae)
{
+ EAccount *account;
gint id = gtk_combo_box_get_active (dropdown);
GtkTreeModel *model;
GtkTreeIter iter;
EAccountReceiptPolicy policy;
+ account = em_account_editor_get_modified_account (emae);
+
if (id != -1) {
model = gtk_combo_box_get_model (dropdown);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, id)) {
gtk_tree_model_get (model, &iter, 1, &policy, -1);
- e_account_set_int (emae->account, E_ACCOUNT_RECEIPT_POLICY, policy);
+ e_account_set_int (account, E_ACCOUNT_RECEIPT_POLICY, policy);
}
}
-
}
static GtkWidget *
emae_setup_receipt_policy (EMAccountEditor *emae, GladeXML *xml)
{
+ EAccount *account;
GtkComboBox *dropdown = (GtkComboBox *)glade_xml_get_widget (xml, "receipt_policy_dropdown");
GtkListStore *store;
gint i = 0, active = 0;
GtkTreeIter iter;
- EAccountReceiptPolicy current = emae->account->receipt_policy;
+ EAccountReceiptPolicy current;
static struct {
EAccountReceiptPolicy policy;
const gchar *label;
@@ -799,6 +1004,9 @@ emae_setup_receipt_policy (EMAccountEditor *emae, GladeXML *xml)
{ E_ACCOUNT_RECEIPT_ASK, N_("Ask for each message") }
};
+ account = em_account_editor_get_modified_account (emae);
+ current = account->receipt_policy;
+
gtk_widget_show ((GtkWidget *)dropdown);
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
@@ -817,7 +1025,7 @@ emae_setup_receipt_policy (EMAccountEditor *emae, GladeXML *xml)
gtk_combo_box_set_active (dropdown, active);
g_signal_connect (dropdown, "changed", G_CALLBACK(emae_receipt_policy_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)dropdown, e_account_writable (emae->account, E_ACCOUNT_RECEIPT_POLICY));
+ gtk_widget_set_sensitive ((GtkWidget *)dropdown, e_account_writable (account, E_ACCOUNT_RECEIPT_POLICY));
return (GtkWidget *)dropdown;
}
@@ -825,24 +1033,32 @@ emae_setup_receipt_policy (EMAccountEditor *emae, GladeXML *xml)
static void
emae_account_entry_changed (GtkEntry *entry, EMAccountEditor *emae)
{
- gint item = GPOINTER_TO_INT(g_object_get_data ((GObject *)entry, "account-item"));
+ EAccount *account;
+ const gchar *text;
+ gpointer data;
- e_account_set_string (emae->account, item, gtk_entry_get_text (entry));
+ account = em_account_editor_get_modified_account (emae);
+ data = g_object_get_data (G_OBJECT (entry), "account-item");
+ text = gtk_entry_get_text (entry);
+
+ e_account_set_string (account, GPOINTER_TO_INT (data), text);
}
static GtkEntry *
emae_account_entry (EMAccountEditor *emae, const gchar *name, gint item, GladeXML *xml)
{
+ EAccount *account;
GtkEntry *entry;
const gchar *text;
+ account = em_account_editor_get_modified_account (emae);
entry = (GtkEntry *)glade_xml_get_widget (xml, name);
- text = e_account_get_string (emae->account, item);
+ text = e_account_get_string (account, item);
if (text)
gtk_entry_set_text (entry, text);
g_object_set_data ((GObject *)entry, "account-item", GINT_TO_POINTER(item));
g_signal_connect (entry, "changed", G_CALLBACK(emae_account_entry_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)entry, e_account_writable (emae->account, item));
+ gtk_widget_set_sensitive ((GtkWidget *)entry, e_account_writable (account, item));
return entry;
}
@@ -850,18 +1066,39 @@ emae_account_entry (EMAccountEditor *emae, const gchar *name, gint item, GladeXM
static void
emae_account_toggle_changed (GtkToggleButton *toggle, EMAccountEditor *emae)
{
- gint item = GPOINTER_TO_INT(g_object_get_data ((GObject *)toggle, "account-item"));
+ EAccount *account;
+ gboolean active;
+ gpointer data;
+
+ account = em_account_editor_get_modified_account (emae);
+ data = g_object_get_data (G_OBJECT (toggle), "account-item");
+ active = gtk_toggle_button_get_active (toggle);
- e_account_set_bool (emae->account, item, gtk_toggle_button_get_active (toggle));
+ e_account_set_bool (account, GPOINTER_TO_INT (data), active);
}
static void
emae_account_toggle_widget (EMAccountEditor *emae, GtkToggleButton *toggle, gint item)
{
- gtk_toggle_button_set_active (toggle, e_account_get_bool (emae->account, item));
- g_object_set_data ((GObject *)toggle, "account-item", GINT_TO_POINTER(item));
- g_signal_connect (toggle, "toggled", G_CALLBACK(emae_account_toggle_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)toggle, e_account_writable (emae->account, item));
+ EAccount *account;
+ gboolean active;
+ gboolean writable;
+
+ account = em_account_editor_get_modified_account (emae);
+
+ active = e_account_get_bool (account, item);
+ gtk_toggle_button_set_active (toggle, active);
+
+ writable = e_account_writable (account, item);
+ gtk_widget_set_sensitive (GTK_WIDGET (toggle), writable);
+
+ g_object_set_data (
+ G_OBJECT (toggle), "account-item",
+ GINT_TO_POINTER (item));
+
+ g_signal_connect (
+ toggle, "toggled",
+ G_CALLBACK (emae_account_toggle_changed), emae);
}
static GtkToggleButton *
@@ -878,18 +1115,39 @@ emae_account_toggle (EMAccountEditor *emae, const gchar *name, gint item, GladeX
static void
emae_account_spinint_changed (GtkSpinButton *spin, EMAccountEditor *emae)
{
- gint item = GPOINTER_TO_INT(g_object_get_data ((GObject *)spin, "account-item"));
+ EAccount *account;
+ gpointer data;
+ gint value;
+
+ account = em_account_editor_get_modified_account (emae);
+ data = g_object_get_data (G_OBJECT (spin), "account-item");
+ value = gtk_spin_button_get_value (spin);
- e_account_set_int (emae->account, item, gtk_spin_button_get_value (spin));
+ e_account_set_int (account, GPOINTER_TO_INT (data), value);
}
static void
emae_account_spinint_widget (EMAccountEditor *emae, GtkSpinButton *spin, gint item)
{
- gtk_spin_button_set_value (spin, e_account_get_int (emae->account, item));
- g_object_set_data ((GObject *)spin, "account-item", GINT_TO_POINTER(item));
- g_signal_connect (spin, "value_changed", G_CALLBACK(emae_account_spinint_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)spin, e_account_writable (emae->account, item));
+ EAccount *account;
+ gboolean writable;
+ gint v_int;
+
+ account = em_account_editor_get_modified_account (emae);
+
+ v_int = e_account_get_int (account, item);
+ gtk_spin_button_set_value (spin, v_int);
+
+ writable = e_account_writable (account, item);
+ gtk_widget_set_sensitive (GTK_WIDGET (spin), writable);
+
+ g_object_set_data (
+ G_OBJECT (spin), "account-item",
+ GINT_TO_POINTER (item));
+
+ g_signal_connect (
+ spin, "value-changed",
+ G_CALLBACK(emae_account_spinint_changed), emae);
}
#if 0
@@ -908,26 +1166,37 @@ emae_account_spinint (EMAccountEditor *emae, const gchar *name, gint item)
static void
emae_account_folder_changed (EMFolderSelectionButton *folder, EMAccountEditor *emae)
{
- gint item = GPOINTER_TO_INT(g_object_get_data ((GObject *)folder, "account-item"));
+ EAccount *account;
+ gpointer data;
+ const gchar *selection;
+
+ account = em_account_editor_get_modified_account (emae);
+ data = g_object_get_data (G_OBJECT (folder), "account-item");
+ selection = em_folder_selection_button_get_selection (folder);
- e_account_set_string (emae->account, item, em_folder_selection_button_get_selection (folder));
+ e_account_set_string (account, GPOINTER_TO_INT (data), selection);
}
static EMFolderSelectionButton *
emae_account_folder (EMAccountEditor *emae, const gchar *name, gint item, gint deffolder, GladeXML *xml)
{
+ EAccount *account;
EMFolderSelectionButton *folder;
const gchar *uri;
+ account = em_account_editor_get_modified_account (emae);
folder = (EMFolderSelectionButton *)glade_xml_get_widget (xml, name);
- uri = e_account_get_string (emae->account, item);
+ uri = e_account_get_string (account, item);
if (uri) {
gchar *tmp = em_uri_to_camel (uri);
em_folder_selection_button_set_selection (folder, tmp);
g_free (tmp);
} else {
- em_folder_selection_button_set_selection (folder, mail_component_get_folder_uri (NULL, deffolder));
+ const gchar *uri;
+
+ uri = e_mail_local_get_folder_uri (deffolder);
+ em_folder_selection_button_set_selection (folder, uri);
}
g_object_set_data ((GObject *)folder, "account-item", GINT_TO_POINTER(item));
@@ -935,7 +1204,7 @@ emae_account_folder (EMAccountEditor *emae, const gchar *name, gint item, gint d
g_signal_connect (folder, "selected", G_CALLBACK(emae_account_folder_changed), emae);
gtk_widget_show ((GtkWidget *)folder);
- gtk_widget_set_sensitive ((GtkWidget *)folder, e_account_writable (emae->account, item));
+ gtk_widget_set_sensitive ((GtkWidget *)folder, e_account_writable (account, item));
return folder;
}
@@ -1144,17 +1413,19 @@ static struct _service_info {
static void
emae_uri_changed (EMAccountEditorService *service, CamelURL *url)
{
+ EAccount *account;
gchar *uri;
+ account = em_account_editor_get_modified_account (service->emae);
uri = camel_url_to_string (url, 0);
- e_account_set_string (service->emae->account, emae_service_info[service->type].account_uri_key, uri);
+ e_account_set_string (account, emae_service_info[service->type].account_uri_key, uri);
/* small hack for providers which are store and transport - copy settings across */
if (service->type == CAMEL_PROVIDER_STORE
&& service->provider
&& CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT(service->provider))
- e_account_set_string (service->emae->account, E_ACCOUNT_TRANSPORT_URL, uri);
+ e_account_set_string (account, E_ACCOUNT_TRANSPORT_URL, uri);
g_free (uri);
}
@@ -1279,10 +1550,13 @@ emae_ssl_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
static void
emae_service_provider_changed (EMAccountEditorService *service)
{
+ EAccount *account;
gint i, j;
void (*show)(GtkWidget *);
CamelURL *url = emae_account_url (service->emae, emae_service_info[service->type].account_uri_key);
+ account = em_account_editor_get_modified_account (service->emae);
+
if (service->provider) {
gint enable;
GtkWidget *dwidget = NULL;
@@ -1294,14 +1568,14 @@ emae_service_provider_changed (EMAccountEditorService *service)
else
gtk_widget_show (service->frame);
- enable = e_account_writable_option (service->emae->account, service->provider->protocol, "auth");
+ enable = e_account_writable_option (account, service->provider->protocol, "auth");
gtk_widget_set_sensitive ((GtkWidget *)service->authtype, enable);
gtk_widget_set_sensitive ((GtkWidget *)service->check_supported, enable);
- enable = e_account_writable_option (service->emae->account, service->provider->protocol, "use_ssl");
+ enable = e_account_writable_option (account, service->provider->protocol, "use_ssl");
gtk_widget_set_sensitive ((GtkWidget *)service->use_ssl, enable);
- enable = e_account_writable (service->emae->account, emae_service_info[service->type].save_passwd_key);
+ enable = e_account_writable (account, emae_service_info[service->type].save_passwd_key);
gtk_widget_set_sensitive ((GtkWidget *)service->remember, enable);
for (i=0;emae_service_info[service->type].host_info[i].flag;i++) {
@@ -1411,7 +1685,7 @@ emae_provider_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
static void
emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service)
{
- EAccount *account = emae->account;
+ EAccount *account;
GtkListStore *store;
GtkTreeIter iter;
GList *l;
@@ -1419,11 +1693,14 @@ emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service)
GtkComboBox *dropdown;
gint active = 0, i;
struct _service_info *info = &emae_service_info[service->type];
- const gchar *uri = e_account_get_string (account, info->account_uri_key);
- const gchar *tmp;
+ const gchar *uri;
gchar *current = NULL;
+ const gchar *tmp;
CamelURL *url;
+ account = em_account_editor_get_modified_account (emae);
+ uri = e_account_get_string (account, info->account_uri_key);
+
dropdown = service->providers;
gtk_widget_show ((GtkWidget *)dropdown);
@@ -1438,7 +1715,7 @@ emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service)
current[len] = 0;
}
} else {
- current = (gchar *)"imap";
+ current = (gchar *) "imap";
}
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
@@ -1512,6 +1789,7 @@ emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service)
static void
emae_authtype_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
{
+ EAccount *account;
gint id = gtk_combo_box_get_active (dropdown);
GtkTreeModel *model;
GtkTreeIter iter;
@@ -1521,6 +1799,8 @@ emae_authtype_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
if (id == -1)
return;
+ account = em_account_editor_get_modified_account (service->emae);
+
url = emae_account_url (service->emae, emae_service_info[service->type].account_uri_key);
model = gtk_combo_box_get_model (dropdown);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, id)) {
@@ -1535,7 +1815,7 @@ emae_authtype_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
gtk_widget_set_sensitive ((GtkWidget *)service->remember,
authtype
- ?(authtype->need_password && e_account_writable (service->emae->account, emae_service_info[service->type].save_passwd_key))
+ ?(authtype->need_password && e_account_writable (account, emae_service_info[service->type].save_passwd_key))
:FALSE);
}
@@ -1562,17 +1842,20 @@ static void emae_check_authtype (GtkWidget *w, EMAccountEditorService *service);
static void
emae_refresh_authtype (EMAccountEditor *emae, EMAccountEditorService *service)
{
- EAccount *account = emae->account;
+ EAccount *account;
GtkListStore *store;
GtkTreeIter iter;
GtkComboBox *dropdown;
gint active = 0;
gint i;
struct _service_info *info = &emae_service_info[service->type];
- const gchar *uri = e_account_get_string (account, info->account_uri_key);
+ const gchar *uri;
GList *l, *ll;
CamelURL *url = NULL;
+ account = em_account_editor_get_modified_account (emae);
+ uri = e_account_get_string (account, info->account_uri_key);
+
dropdown = service->authtype;
gtk_widget_show ((GtkWidget *)dropdown);
@@ -1656,10 +1939,13 @@ static void emae_check_authtype_response (GtkWidget *d, gint button, EMAccountEd
static void emae_check_authtype (GtkWidget *w, EMAccountEditorService *service)
{
EMAccountEditor *emae = service->emae;
+ EAccount *account;
const gchar *uri;
+ account = em_account_editor_get_modified_account (emae);
+
/* TODO: do we need to remove the auth mechanism from the uri? */
- uri = e_account_get_string (emae->account, emae_service_info[service->type].account_uri_key);
+ uri = e_account_get_string (account, emae_service_info[service->type].account_uri_key);
g_object_ref (emae);
service->check_dialog = e_error_new (emae->editor ? (GtkWindow *)gtk_widget_get_toplevel (emae->editor) : NULL,
@@ -1674,12 +1960,16 @@ static void emae_check_authtype (GtkWidget *w, EMAccountEditorService *service)
static void
emae_setup_service (EMAccountEditor *emae, EMAccountEditorService *service, GladeXML *xml)
{
+ EAccount *account;
struct _service_info *info = &emae_service_info[service->type];
CamelURL *url = emae_account_url (emae, info->account_uri_key);
- const gchar *uri = e_account_get_string (emae->account, info->account_uri_key);
+ const gchar *uri;
const gchar *tmp;
gint i;
+ account = em_account_editor_get_modified_account (emae);
+ uri = e_account_get_string (account, info->account_uri_key);
+
service->provider = uri?camel_provider_get (uri, NULL):NULL;
service->frame = glade_xml_get_widget (xml, info->frame);
service->container = glade_xml_get_widget (xml, info->container);
@@ -1768,7 +2058,7 @@ emae_setup_service (EMAccountEditor *emae, EMAccountEditorService *service, Glad
service->needs_auth = NULL;
}
- if (!e_account_writable (emae->account, info->account_uri_key))
+ if (!e_account_writable (account, info->account_uri_key))
gtk_widget_set_sensitive (service->container, FALSE);
else
gtk_widget_set_sensitive (service->container, TRUE);
@@ -1778,6 +2068,60 @@ emae_setup_service (EMAccountEditor *emae, EMAccountEditorService *service, Glad
camel_url_free (url);
}
+static GtkWidget *
+emae_create_basic_assistant_page (GtkAssistant *assistant, const gchar *page_id)
+{
+ const gchar *title = NULL, *label = NULL;
+ GtkAssistantPageType page_type = GTK_ASSISTANT_PAGE_CONTENT;
+ GtkWidget *vbox, *lbl;
+ gboolean fill_space = FALSE;
+
+ g_return_val_if_fail (page_id != NULL, NULL);
+
+ if (g_ascii_strcasecmp (page_id, "start_page") == 0) {
+ page_type = GTK_ASSISTANT_PAGE_INTRO;
+ fill_space = TRUE;
+ title = _("Mail Configuration");
+ label = _("Welcome to the Evolution Mail Configuration Assistant.\n\nClick \"Forward\" to begin.");
+ } else if (g_ascii_strcasecmp (page_id, "identity_page") == 0) {
+ title = _("Identity");
+ label = _("Please enter your name and email address below. The \"optional\" fields below do not need to be filled in, unless you wish to include this information in email you send.");
+ } else if (g_ascii_strcasecmp (page_id, "source_page") == 0) {
+ title = _("Receiving Email");
+ label = _("Please configure the following account settings.");
+ } else if (g_ascii_strcasecmp (page_id, "transport_page") == 0) {
+ title = _("Sending Email");
+ label = _("Please enter information about the way you will send mail. If you are not sure, ask your system administrator or Internet Service Provider.");
+ } else if (g_ascii_strcasecmp (page_id, "management_page") == 0) {
+ title = _("Account Management");
+ label = _("Please enter a descriptive name for this account in the space below.\nThis name will be used for display purposes only.");
+ } else if (g_ascii_strcasecmp (page_id, "finish_page") == 0) {
+ page_type = GTK_ASSISTANT_PAGE_CONFIRM;
+ fill_space = TRUE;
+ title = _("Done");
+ label = _("Congratulations, your mail configuration is complete.\n\nYou are now ready to send and receive email using Evolution.\n\nClick \"Apply\" to save your settings.");
+ } else {
+ g_return_val_if_reached (NULL);
+ }
+
+ vbox = gtk_vbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+
+ lbl = gtk_label_new (label);
+ gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (lbl), TRUE);
+
+ gtk_box_pack_start (GTK_BOX (vbox), lbl, fill_space, fill_space, 0);
+
+ gtk_widget_show_all (vbox);
+
+ gtk_assistant_append_page (assistant, vbox);
+ gtk_assistant_set_page_title (assistant, vbox, title);
+ gtk_assistant_set_page_type (assistant, vbox, page_type);
+
+ return vbox;
+}
+
/* do not re-order these, the order is used by various code to look up emae->priv->identity_entries[] */
static struct {
const gchar *name;
@@ -1816,7 +2160,7 @@ emae_identity_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
{
EMAccountEditor *emae = data;
EMAccountEditorPrivate *gui = emae->priv;
- EAccount *account = emae->account;
+ EAccount *account;
gint i;
GtkWidget *w;
GladeXML *xml;
@@ -1825,22 +2169,24 @@ emae_identity_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
/*if (old)
return old;*/
+ account = em_account_editor_get_modified_account (emae);
+
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
"mail-config.glade",
NULL);
xml = glade_xml_new (gladefile, item->label, NULL);
g_free (gladefile);
- /* Management & Identity fields, in the druid the management frame is relocated to the last page later on */
+ /* Management & Identity fields, in the assistant the management frame is relocated to the last page later on */
for (i=0;i<sizeof (emae_identity_entries)/sizeof (emae_identity_entries[0]);i++)
gui->identity_entries[i] = emae_account_entry (emae, emae_identity_entries[i].name, emae_identity_entries[i].item, xml);
gui->management_frame = glade_xml_get_widget (xml, "management_frame");
gui->default_account = GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "management_default"));
- if (!mail_config_get_default_account ()
- || (account == mail_config_get_default_account ())
- || (GPOINTER_TO_INT(g_object_get_data (G_OBJECT (emae->account), "default_flagged"))) )
+ if (!e_get_default_account ()
+ || (account == e_get_default_account ())
+ || (GPOINTER_TO_INT(g_object_get_data (G_OBJECT (account), "default_flagged"))) )
gtk_toggle_button_set_active (gui->default_account, TRUE);
if (emae->do_signature) {
@@ -1857,22 +2203,12 @@ emae_identity_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
w = glade_xml_get_widget (xml, item->label);
if (emae->type == EMAE_PAGES) {
gtk_box_pack_start ((GtkBox *)emae->pages[0], w, TRUE, TRUE, 0);
- } else if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
- GladeXML *druidxml;
- GtkWidget *page;
+ } else if (((EConfig *)gui->config)->type == E_CONFIG_ASSISTANT) {
+ GtkWidget *page = emae_create_basic_assistant_page (GTK_ASSISTANT (parent), "identity_page");
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- druidxml = glade_xml_new (gladefile, "identity_page", NULL);
- g_free (gladefile);
+ gtk_box_pack_start (GTK_BOX (page), w, TRUE, TRUE, 0);
- page = glade_xml_get_widget (druidxml, "identity_page");
-
- gtk_box_pack_start ((GtkBox*)((GnomeDruidPageStandard *)page)->vbox, w, TRUE, TRUE, 0);
w = page;
- g_object_unref (druidxml);
- gnome_druid_append_page ((GnomeDruid *)parent, (GnomeDruidPage *)page);
} else {
gtk_notebook_append_page ((GtkNotebook *)parent, w, gtk_label_new (_("Identity")));
}
@@ -1908,22 +2244,12 @@ emae_receive_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
w = glade_xml_get_widget (xml, item->label);
if (emae->type == EMAE_PAGES) {
gtk_box_pack_start ((GtkBox *)emae->pages[1], w, TRUE, TRUE, 0);
- } else if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
- GladeXML *druidxml;
- GtkWidget *page;
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- druidxml = glade_xml_new (gladefile, "source_page", NULL);
- g_free (gladefile);
+ } else if (((EConfig *)gui->config)->type == E_CONFIG_ASSISTANT) {
+ GtkWidget *page = emae_create_basic_assistant_page (GTK_ASSISTANT (parent), "source_page");
- page = glade_xml_get_widget (druidxml, "source_page");
+ gtk_box_pack_start (GTK_BOX (page), w, TRUE, TRUE, 0);
- gtk_box_pack_start ((GtkBox*)((GnomeDruidPageStandard *)page)->vbox, w, TRUE, TRUE, 0);
w = page;
- g_object_unref (druidxml);
- gnome_druid_append_page ((GnomeDruid *)parent, (GnomeDruidPage *)page);
} else {
gtk_notebook_append_page ((GtkNotebook *)parent, w, gtk_label_new (_("Receiving Email")));
}
@@ -2378,22 +2704,12 @@ emae_send_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget *ol
w = glade_xml_get_widget (xml, item->label);
if (emae->type == EMAE_PAGES) {
gtk_box_pack_start ((GtkBox *)emae->pages[2], w, TRUE, TRUE, 0);
- } else if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
- GladeXML *druidxml;
- GtkWidget *page;
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- druidxml = glade_xml_new (gladefile, "transport_page", NULL);
- g_free (gladefile);
+ } else if (((EConfig *)gui->config)->type == E_CONFIG_ASSISTANT) {
+ GtkWidget *page = emae_create_basic_assistant_page (GTK_ASSISTANT (parent), "transport_page");
- page = glade_xml_get_widget (druidxml, "transport_page");
+ gtk_box_pack_start (GTK_BOX (page), w, TRUE, TRUE, 0);
- gtk_box_pack_start ((GtkBox*)((GnomeDruidPageStandard *)page)->vbox, w, TRUE, TRUE, 0);
w = page;
- g_object_unref (druidxml);
- gnome_druid_append_page ((GnomeDruid *)parent, (GnomeDruidPage *)page);
} else {
gtk_notebook_append_page ((GtkNotebook *)parent, w, gtk_label_new (_("Sending Email")));
}
@@ -2410,6 +2726,7 @@ emae_defaults_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
{
EMAccountEditor *emae = data;
EMAccountEditorPrivate *gui = emae->priv;
+ EAccount *account;
GtkWidget *w;
GladeXML *xml;
gchar *gladefile;
@@ -2417,6 +2734,8 @@ emae_defaults_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
/*if (old)
return old;*/
+ account = em_account_editor_get_modified_account (emae);
+
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
"mail-config.glade",
NULL);
@@ -2424,8 +2743,8 @@ emae_defaults_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
g_free (gladefile);
/* Special folders */
- gui->drafts_folder_button = (GtkButton *)emae_account_folder (emae, "drafts_button", E_ACCOUNT_DRAFTS_FOLDER_URI, MAIL_COMPONENT_FOLDER_DRAFTS, xml);
- gui->sent_folder_button = (GtkButton *)emae_account_folder (emae, "sent_button", E_ACCOUNT_SENT_FOLDER_URI, MAIL_COMPONENT_FOLDER_SENT, xml);
+ gui->drafts_folder_button = (GtkButton *)emae_account_folder (emae, "drafts_button", E_ACCOUNT_DRAFTS_FOLDER_URI, E_MAIL_FOLDER_DRAFTS, xml);
+ gui->sent_folder_button = (GtkButton *)emae_account_folder (emae, "sent_button", E_ACCOUNT_SENT_FOLDER_URI, E_MAIL_FOLDER_SENT, xml);
/* Special Folders "Reset Defaults" button */
gui->restore_folders_button = (GtkButton *)glade_xml_get_widget (xml, "default_folders_button");
@@ -2437,18 +2756,18 @@ emae_defaults_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
emae_account_toggle (emae, "always_bcc", E_ACCOUNT_BCC_ALWAYS, xml);
emae_account_entry (emae, "bcc_addrs", E_ACCOUNT_BCC_ADDRS, xml);
- gtk_widget_set_sensitive ((GtkWidget *)gui->drafts_folder_button, e_account_writable (emae->account, E_ACCOUNT_DRAFTS_FOLDER_URI));
+ gtk_widget_set_sensitive ((GtkWidget *)gui->drafts_folder_button, e_account_writable (account, E_ACCOUNT_DRAFTS_FOLDER_URI));
gtk_widget_set_sensitive ( (GtkWidget *)gui->sent_folder_button,
- e_account_writable (emae->account, E_ACCOUNT_SENT_FOLDER_URI)
+ e_account_writable (account, E_ACCOUNT_SENT_FOLDER_URI)
&&
(emae->priv->source.provider ? !(emae->priv->source.provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER): TRUE)
);
gtk_widget_set_sensitive ((GtkWidget *)gui->restore_folders_button,
- (e_account_writable (emae->account, E_ACCOUNT_SENT_FOLDER_URI)
+ (e_account_writable (account, E_ACCOUNT_SENT_FOLDER_URI)
&& ((emae->priv->source.provider && !( emae->priv->source.provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER))
- || e_account_writable (emae->account, E_ACCOUNT_DRAFTS_FOLDER_URI))));
+ || e_account_writable (account, E_ACCOUNT_DRAFTS_FOLDER_URI))));
/* Receipt policy */
emae_setup_receipt_policy (emae, xml);
@@ -2586,59 +2905,32 @@ emae_management_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidg
GtkWidget *w;
w = gui->management_frame;
- if (((EConfig *)gui->config)->type == E_CONFIG_DRUID) {
- GladeXML *druidxml;
- GtkWidget *page;
- gchar *gladefile;
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- druidxml = glade_xml_new (gladefile, "management_page", NULL);
- g_free (gladefile);
+ if (((EConfig *)gui->config)->type == E_CONFIG_ASSISTANT) {
+ GtkWidget *page = emae_create_basic_assistant_page (GTK_ASSISTANT (parent), "management_page");
- page = glade_xml_get_widget (druidxml, "management_page");
+ gtk_widget_reparent (w, page);
- gtk_widget_reparent (w, ((GnomeDruidPageStandard *)page)->vbox);
w = page;
- g_object_unref (druidxml);
- gnome_druid_append_page ((GnomeDruid *)parent, (GnomeDruidPage *)page);
}
return w;
}
static GtkWidget *
-emae_widget_druid_glade (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget *old, gpointer data)
+emae_widget_assistant_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget *old, gpointer data)
{
- GladeXML *druidxml;
- GtkWidget *w;
- gchar *gladefile;
EMAccountEditor *emae = (EMAccountEditor *)data;
if (emae->type == EMAE_PAGES)
return NULL;
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- druidxml = glade_xml_new (gladefile, item->label, NULL);
- g_free (gladefile);
-
- w = glade_xml_get_widget (druidxml, item->label);
- /* i think the glade file has issues, we need to show all on at least the end page */
- gtk_widget_show_all (w);
- g_object_unref (druidxml);
-
- gnome_druid_append_page ((GnomeDruid *)parent, (GnomeDruidPage *)w);
-
- return w;
+ return emae_create_basic_assistant_page (GTK_ASSISTANT (parent), item->label);
}
-/* plugin meta-data for "org.gnome.evolution.mail.config.accountDruid" */
-static EMConfigItem emae_druid_items[] = {
- { E_CONFIG_DRUID, (gchar *) "" },
- { E_CONFIG_PAGE_START, (gchar *) "0.start", (gchar *) "start_page", emae_widget_druid_glade },
+/* plugin meta-data for "org.gnome.evolution.mail.config.accountAssistant" */
+static EMConfigItem emae_assistant_items[] = {
+ { E_CONFIG_ASSISTANT, (gchar *) "" },
+ { E_CONFIG_PAGE_START, (gchar *) "0.start", (gchar *) "start_page", emae_widget_assistant_page },
{ E_CONFIG_PAGE, (gchar *) "00.identity", (gchar *) "vboxIdentityBorder", emae_identity_page },
{ E_CONFIG_SECTION, (gchar *) "00.identity/00.name", (gchar *) "account_vbox", emae_widget_glade },
@@ -2664,10 +2956,10 @@ static EMConfigItem emae_druid_items[] = {
{ E_CONFIG_PAGE, (gchar *) "40.management", (gchar *) "management_frame", emae_management_page },
- { E_CONFIG_PAGE_FINISH, (gchar *) "999.end", (gchar *) "finish_page", emae_widget_druid_glade },
+ { E_CONFIG_PAGE_FINISH, (gchar *) "999.end", (gchar *) "finish_page", emae_widget_assistant_page },
{ 0 },
};
-static gboolean emae_druid_items_translated = FALSE;
+static gboolean emae_assistant_items_translated = FALSE;
static void
emae_free (EConfig *ec, GSList *items, gpointer data)
@@ -2696,6 +2988,7 @@ emae_free_auto (EConfig *ec, GSList *items, gpointer data)
static gboolean
emae_service_complete (EMAccountEditor *emae, EMAccountEditorService *service)
{
+ EAccount *account;
CamelURL *url;
gint ok = TRUE;
const gchar *uri;
@@ -2703,7 +2996,9 @@ emae_service_complete (EMAccountEditor *emae, EMAccountEditorService *service)
if (service->provider == NULL)
return TRUE;
- uri = e_account_get_string (emae->account, emae_service_info[service->type].account_uri_key);
+ account = em_account_editor_get_modified_account (emae);
+
+ uri = e_account_get_string (account, emae_service_info[service->type].account_uri_key);
if (uri == NULL || (url = camel_url_new (uri, NULL)) == NULL)
return FALSE;
@@ -2765,16 +3060,22 @@ static gboolean
emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
{
EMAccountEditor *emae = data;
+ EAccount *account;
+ EAccount *original_account;
gint ok = TRUE;
const gchar *tmp;
EAccount *ea;
gboolean refresh = FALSE;
- gboolean edit = emae->original != NULL;
+ gboolean new_account;
+
+ account = em_account_editor_get_modified_account (emae);
+ original_account = em_account_editor_get_original_account (emae);
+ new_account = (original_account == NULL);
/* We use the page-check of various pages to 'prepare' or
- pre-load their values, only in the druid */
+ pre-load their values, only in the assistant */
if (pageid
- && ((EConfig *)emae->priv->config)->type == E_CONFIG_DRUID) {
+ && ((EConfig *)emae->priv->config)->type == E_CONFIG_ASSISTANT) {
if (!strcmp (pageid, "00.identity")) {
if (!emae->priv->identity_set) {
gchar *uname;
@@ -2794,12 +3095,12 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
if (!emae->priv->receive_set) {
gchar *user, *at;
gint index;
- gchar *uri = g_strdup (e_account_get_string (emae->account, E_ACCOUNT_SOURCE_URL));
+ gchar *uri = g_strdup (e_account_get_string (account, E_ACCOUNT_SOURCE_URL));
CamelURL *url;
emae->priv->receive_set = 1;
- tmp = (gchar *)e_account_get_string (emae->account, E_ACCOUNT_ID_ADDRESS);
- at = strrchr (tmp, '@');
+ tmp = (gchar *)e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
+ at = strchr (tmp, '@');
user = g_alloca (at-tmp+1);
memcpy (user, tmp, at-tmp);
user[at-tmp] = 0;
@@ -2808,7 +3109,7 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
index = check_servers (at);
gtk_entry_set_text (emae->priv->source.username, user);
gtk_entry_set_text (emae->priv->transport.username, user);
- if (!edit && uri && (url = camel_url_new (uri, NULL)) != NULL) {
+ if (new_account && uri && (url = camel_url_new (uri, NULL)) != NULL) {
refresh = TRUE;
camel_url_set_user (url, user);
if (index != -1) {
@@ -2817,20 +3118,16 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
camel_url_set_host (url, mail_servers[index].recv);
gtk_entry_set_text (emae->priv->source.hostname, mail_servers[index].recv);
gtk_entry_set_text (emae->priv->transport.hostname, mail_servers[index].send);
- camel_url_set_host (url, mail_servers[index].recv);
-
} else {
camel_url_set_host (url, "");
}
- camel_url_set_user (url, user);
g_free (uri);
uri = camel_url_to_string (url, 0);
- e_account_set_string (emae->account, E_ACCOUNT_SOURCE_URL, uri);
- g_free (uri);
+ e_account_set_string (account, E_ACCOUNT_SOURCE_URL, uri);
+
camel_url_free (url);
- } else {
- g_free (uri);
}
+ g_free (uri);
}
} else if (!strcmp (pageid, "30.send")) {
@@ -2838,29 +3135,30 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
CamelURL *url;
gchar *at, *user;
gint index;
- gchar *uri = (gchar *)e_account_get_string (emae->account, E_ACCOUNT_TRANSPORT_URL);
+ gchar *uri = (gchar *)e_account_get_string (account, E_ACCOUNT_TRANSPORT_URL);
+
emae->priv->send_set = 1;
- tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_ADDRESS);
- at = strrchr (tmp, '@');
+ tmp = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
+ at = strchr (tmp, '@');
user = g_alloca (at-tmp+1);
memcpy (user, tmp, at-tmp);
user[at-tmp] = 0;
at++;
index = check_servers (at);
- if (index != -1 && uri && (url = camel_url_new (uri, NULL)) != NULL) {
+ if (index != -1 && uri && (url = camel_url_new (uri, NULL)) != NULL) {
refresh = TRUE;
camel_url_set_protocol (url, "smtp");
camel_url_set_param (url, "use_ssl", mail_servers[index].ssl);
camel_url_set_host (url, mail_servers[index].send);
camel_url_set_user (url, user);
uri = camel_url_to_string (url, 0);
- e_account_set_string (emae->account, E_ACCOUNT_TRANSPORT_URL, uri);
+ e_account_set_string (account, E_ACCOUNT_TRANSPORT_URL, uri);
g_free (uri);
camel_url_free (url);
}
-
}
+
} else if (!strcmp (pageid, "20.receive_options")) {
if (emae->priv->source.provider
&& emae->priv->extra_provider != emae->priv->source.provider) {
@@ -2873,11 +3171,11 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
guint i = 0, len;
emae->priv->management_set = 1;
- tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_ADDRESS);
+ tmp = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
len = strlen (tmp);
template = alloca (len + 14);
strcpy (template, tmp);
- while (mail_config_get_account_by_name (template))
+ while (e_get_account_by_name (template))
sprintf (template + len, " (%d)", i++);
gtk_entry_set_text (emae->priv->identity_entries[0], template);
@@ -2891,15 +3189,15 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
editing multiple accounts at a time
*/
if (gtk_toggle_button_get_active (emae->priv->default_account))
- g_object_set_data (G_OBJECT (emae->account), "default_flagged", GINT_TO_POINTER(1));
+ g_object_set_data (G_OBJECT (account), "default_flagged", GINT_TO_POINTER(1));
if (pageid == NULL || !strcmp (pageid, "00.identity")) {
/* TODO: check the account name is set, and unique in the account list */
- ok = (tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_NAME))
+ ok = (tmp = e_account_get_string (account, E_ACCOUNT_ID_NAME))
&& tmp[0]
- && (tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_ADDRESS))
+ && (tmp = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS))
&& is_email (tmp)
- && ((tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_REPLY_TO)) == NULL
+ && ((tmp = e_account_get_string (account, E_ACCOUNT_ID_REPLY_TO)) == NULL
|| tmp[0] == 0
|| is_email (tmp));
if (!ok) {
@@ -2928,10 +3226,10 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
}
if (ok && (pageid == NULL || !strcmp (pageid, "40.management"))) {
- ok = (tmp = e_account_get_string (emae->account, E_ACCOUNT_NAME))
+ ok = (tmp = e_account_get_string (account, E_ACCOUNT_NAME))
&& tmp[0]
- && ((ea = mail_config_get_account_by_name (tmp)) == NULL
- || ea == emae->original);
+ && ((ea = e_get_account_by_name (tmp)) == NULL
+ || ea == original_account);
if (!ok) {
d (printf ("management page incomplete\n"));
}
@@ -2950,40 +3248,44 @@ em_account_editor_check (EMAccountEditor *emae, const gchar *page)
static void
add_new_store (gchar *uri, CamelStore *store, gpointer user_data)
{
- MailComponent *component = mail_component_peek ();
EAccount *account = user_data;
if (store == NULL)
return;
- mail_component_add_store (component, store, account->name);
+ e_mail_store_add (store, account->name);
}
static void
emae_commit (EConfig *ec, GSList *items, gpointer data)
{
EMAccountEditor *emae = data;
- EAccountList *accounts = mail_config_get_accounts ();
+ EAccountList *accounts = e_get_account_list ();
EAccount *account;
+ EAccount *modified_account;
+ EAccount *original_account;
/* the mail-config*acconts* api needs a lot of work */
- if (emae->original) {
- d (printf ("Committing account '%s'\n", e_account_get_string (emae->account, E_ACCOUNT_NAME)));
- e_account_import (emae->original, emae->account);
- account = emae->original;
+ modified_account = em_account_editor_get_modified_account (emae);
+ original_account = em_account_editor_get_original_account (emae);
+
+ if (original_account != NULL) {
+ d (printf ("Committing account '%s'\n", e_account_get_string (modified_account, E_ACCOUNT_NAME)));
+ e_account_import (original_account, modified_account);
+ account = original_account;
e_account_list_change (accounts, account);
} else {
- d (printf ("Adding new account '%s'\n", e_account_get_string (emae->account, E_ACCOUNT_NAME)));
- e_account_list_add (accounts, emae->account);
- account = emae->account;
+ d (printf ("Adding new account '%s'\n", e_account_get_string (account, E_ACCOUNT_NAME)));
+ e_account_list_add (accounts, modified_account);
+ account = modified_account;
/* HACK: this will add the account to the folder tree.
We should just be listening to the account list directly for changed events */
if (account->enabled
&& emae->priv->source.provider
&& (emae->priv->source.provider->flags & CAMEL_PROVIDER_IS_STORAGE))
- mail_get_store (e_account_get_string (emae->account, E_ACCOUNT_SOURCE_URL), NULL, add_new_store, account);
+ mail_get_store (e_account_get_string (modified_account, E_ACCOUNT_SOURCE_URL), NULL, add_new_store, account);
}
if (gtk_toggle_button_get_active (emae->priv->default_account))
@@ -3006,9 +3308,10 @@ emae_editor_destroyed (GtkWidget *dialog, EMAccountEditor *emae)
}
static void
-em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_account_editor_t type, const gchar *id)
+em_account_editor_construct (EMAccountEditor *emae, EMAccountEditorType type, const gchar *id)
{
EMAccountEditorPrivate *gui = emae->priv;
+ EAccount *account;
gint i, index;
GSList *l;
GList *prov;
@@ -3018,26 +3321,6 @@ em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_accoun
EConfigItem *items;
emae->type = type;
- emae->original = account;
- if (emae->original) {
- gchar *xml;
-
- g_object_ref (emae->original);
- xml = e_account_to_xml (emae->original);
- emae->account = e_account_new_from_xml (xml);
- g_free (xml);
-
- if (type != EMAE_PAGES)
- emae->do_signature = TRUE;
- } else {
- /* TODO: have a get_default_account thing?? */
- emae->account = e_account_new ();
- emae->account->enabled = TRUE;
- e_account_set_string (emae->account, E_ACCOUNT_DRAFTS_FOLDER_URI,
- mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_DRAFTS));
- e_account_set_string (emae->account, E_ACCOUNT_SENT_FOLDER_URI,
- mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_SENT));
- }
/* sort the providers, remote first */
gui->providers = g_list_sort (camel_provider_list (TRUE), (GCompareFunc)provider_compare);
@@ -3053,14 +3336,14 @@ em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_accoun
emae_editor_items_translated = TRUE;
}
} else {
- ec = em_config_new (E_CONFIG_DRUID, id);
- items = emae_druid_items;
- if (!emae_druid_items_translated) {
+ ec = em_config_new (E_CONFIG_ASSISTANT, id);
+ items = emae_assistant_items;
+ if (!emae_assistant_items_translated) {
for (i=0;items[i].path;i++) {
if (items[i].label)
items[i].label = _(items[i].label);
}
- emae_druid_items_translated = TRUE;
+ emae_assistant_items_translated = TRUE;
}
}
@@ -3116,7 +3399,8 @@ em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_accoun
e_config_add_page_check ((EConfig *)ec, NULL, emae_check_complete, emae);
- target = em_config_target_new_account (ec, emae->account);
+ account = em_account_editor_get_modified_account (emae);
+ target = em_config_target_new_account (ec, account);
e_config_set_target ((EConfig *)ec, (EConfigTarget *)target);
if (type != EMAE_PAGES) {
diff --git a/mail/em-account-editor.h b/mail/em-account-editor.h
index 12e7506a23..83e9cd4885 100644
--- a/mail/em-account-editor.h
+++ b/mail/em-account-editor.h
@@ -25,9 +25,27 @@
#define EM_ACCOUNT_EDITOR_H
#include <gtk/gtk.h>
-
#include <mail/em-config.h>
+/* Standard GObject macros */
+#define EM_TYPE_ACCOUNT_EDITOR \
+ (em_account_editor_get_type ())
+#define EM_ACCOUNT_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditor))
+#define EM_ACCOUNT_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorClass))
+#define EM_IS_ACCOUNT_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_ACCOUNT_EDITOR))
+#define EM_IS_ACCOUNT_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_ACCOUNT_EDITOR))
+#define EM_ACCOUNT_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorClass))
+
G_BEGIN_DECLS
typedef struct _EMAccountEditor EMAccountEditor;
@@ -36,50 +54,65 @@ typedef struct _EMAccountEditorPrivate EMAccountEditorPrivate;
typedef enum {
EMAE_NOTEBOOK,
- EMAE_DRUID,
+ EMAE_ASSISTANT,
EMAE_PAGES
-} em_account_editor_t;
+} EMAccountEditorType;
struct _EMAccountEditor {
- GObject gobject;
+ GObject parent;
EMAccountEditorPrivate *priv;
- em_account_editor_t type;
- GtkWidget *editor; /* gtknotebook or druid, depending on type */
+ EMAccountEditorType type;
+ GtkWidget *editor; /* gtknotebook or gtkassistant, depending on type */
EMConfig *config; /* driver object */
- EAccount *account; /* working account, must instant apply to this */
- EAccount *original; /* original account, not changed unless commit is invoked */
-
GtkWidget **pages; /* Pages for Anjal's page type editor */
guint do_signature:1; /* allow editing signature */
};
struct _EMAccountEditorClass {
- GObjectClass gobject_class;
+ GObjectClass parent_class;
};
-GType em_account_editor_get_type(void);
-
-EMAccountEditor *em_account_editor_new(EAccount *account, em_account_editor_t type, const gchar *id);
-EMAccountEditor *em_account_editor_new_for_pages(EAccount *account, em_account_editor_t type, gchar *id, GtkWidget **pages);
-void em_account_editor_commit (EMAccountEditor *emae);
-gboolean em_account_editor_check (EMAccountEditor *emae, const gchar *page);
-
-gboolean em_account_editor_save (EMAccountEditor *gui);
-void em_account_editor_destroy (EMAccountEditor *gui);
-
-gboolean em_account_editor_identity_complete (EMAccountEditor *gui, GtkWidget **incomplete);
-gboolean em_account_editor_source_complete (EMAccountEditor *gui, GtkWidget **incomplete);
-gboolean em_account_editor_transport_complete (EMAccountEditor *gui, GtkWidget **incomplete);
-gboolean em_account_editor_management_complete (EMAccountEditor *gui, GtkWidget **incomplete);
-
-void em_account_editor_build_extra_conf (EMAccountEditor *gui, const gchar *url);
-
-void em_account_editor_auto_detect_extra_conf (EMAccountEditor *gui);
+GType em_account_editor_get_type (void);
+EMAccountEditor *
+ em_account_editor_new (EAccount *account,
+ EMAccountEditorType type,
+ const gchar *id);
+EMAccountEditor *
+ em_account_editor_new_for_pages (EAccount *account,
+ EMAccountEditorType type,
+ const gchar *id,
+ GtkWidget **pages);
+EAccount * em_account_editor_get_modified_account
+ (EMAccountEditor *emae);
+EAccount * em_account_editor_get_original_account
+ (EMAccountEditor *emae);
+void em_account_editor_commit (EMAccountEditor *emae);
+gboolean em_account_editor_check (EMAccountEditor *emae,
+ const gchar *page);
+gboolean em_account_editor_save (EMAccountEditor *emae);
+void em_account_editor_destroy (EMAccountEditor *emae);
+gboolean em_account_editor_identity_complete
+ (EMAccountEditor *emae,
+ GtkWidget **incomplete);
+gboolean em_account_editor_source_complete
+ (EMAccountEditor *emae,
+ GtkWidget **incomplete);
+gboolean EMAccountEditorTyperansport_complete
+ (EMAccountEditor *emae,
+ GtkWidget **incomplete);
+gboolean em_account_editor_management_complete
+ (EMAccountEditor *emae,
+ GtkWidget **incomplete);
+void em_account_editor_build_extra_conf
+ (EMAccountEditor *emae,
+ const gchar *url);
+void em_account_editor_auto_detect_extra_conf
+ (EMAccountEditor *emae);
G_END_DECLS
diff --git a/mail/em-account-prefs.c b/mail/em-account-prefs.c
deleted file mode 100644
index cf93ced4d1..0000000000
--- a/mail/em-account-prefs.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <camel/camel-url.h>
-
-#include <glib/gi18n.h>
-
-#include "mail-component.h"
-#include "mail-config.h"
-#include "mail-ops.h"
-#include "mail-send-recv.h"
-
-#include "libedataserver/e-account-list.h"
-#include "e-util/e-error.h"
-#include "e-util/e-util-private.h"
-
-#include "em-account-prefs.h"
-
-#include "em-account-editor.h"
-
-static void em_account_prefs_class_init (EMAccountPrefsClass *class);
-static void em_account_prefs_init (EMAccountPrefs *prefs);
-static void em_account_prefs_finalise (GObject *obj);
-static void em_account_prefs_destroy (GtkObject *object);
-
-static void mail_accounts_load (EMAccountPrefs *prefs);
-
-static GtkVBoxClass *parent_class = NULL;
-
-#define PREFS_WINDOW(prefs) GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (prefs), GTK_TYPE_WINDOW))
-
-GType
-em_account_prefs_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- GTypeInfo type_info = {
- sizeof (EMAccountPrefsClass),
- NULL, NULL,
- (GClassInitFunc) em_account_prefs_class_init,
- NULL, NULL,
- sizeof (EMAccountPrefs),
- 0,
- (GInstanceInitFunc) em_account_prefs_init,
- };
-
- type = g_type_register_static (gtk_vbox_get_type (), "EMAccountPrefs", &type_info, 0);
- }
-
- return type;
-}
-
-static void
-em_account_prefs_class_init (EMAccountPrefsClass *klass)
-{
- GtkObjectClass *gtk_object_class = (GtkObjectClass *) klass;
- GObjectClass *object_class = (GObjectClass *) klass;
-
- parent_class = g_type_class_ref (gtk_vbox_get_type ());
-
- gtk_object_class->destroy = em_account_prefs_destroy;
-
- object_class->finalize = em_account_prefs_finalise;
-}
-
-static void
-em_account_prefs_init (EMAccountPrefs *prefs)
-{
- prefs->druid = NULL;
- prefs->editor = NULL;
-}
-
-static void
-em_account_prefs_destroy (GtkObject *obj)
-{
- EMAccountPrefs *prefs = (EMAccountPrefs *) obj;
-
- prefs->destroyed = TRUE;
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
-}
-
-static void
-em_account_prefs_finalise (GObject *obj)
-{
- EMAccountPrefs *prefs = (EMAccountPrefs *) obj;
-
- g_object_unref (prefs->gui);
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-account_add_finished (EMAccountPrefs *prefs, GObject *deadbeef)
-{
- /* Either Cancel or Finished was clicked in the druid so reload the accounts */
- prefs->druid = NULL;
-
- if (!prefs->destroyed)
- mail_accounts_load (prefs);
-
- g_object_unref (prefs);
-}
-
-#include "em-config.h"
-
-static void
-account_add_clicked (GtkButton *button, gpointer user_data)
-{
- EMAccountPrefs *prefs = (EMAccountPrefs *) user_data;
-
- if (prefs->druid == NULL) {
- EMAccountEditor *emae;
-
- /** @HookPoint-EMConfig: New Mail Account Druid
- * @Id: org.gnome.evolution.mail.config.accountDruid
- * @Type: E_CONFIG_DRUID
- * @Class: org.gnome.evolution.mail.config:1.0
- * @Target: EMConfigTargetAccount
- *
- * The new mail account druid.
- */
- emae = em_account_editor_new(NULL, EMAE_DRUID, "org.gnome.evolution.mail.config.accountDruid");
- prefs->druid = emae->editor;
-
- gtk_window_set_transient_for ((GtkWindow *)prefs->druid, (GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)prefs));
- g_object_ref(prefs);
- /* rather nasty hack to reload the accounts, it should just listen to the e-account-list */
- g_object_weak_ref((GObject *) prefs->druid, (GWeakNotify) account_add_finished, prefs);
- gtk_widget_show(emae->editor);
- } else {
- gdk_window_raise (prefs->druid->window);
- }
-}
-
-static void
-account_edit_finished (EMAccountPrefs *prefs, GObject *deadbeef)
-{
- prefs->editor = NULL;
-
- if (!prefs->destroyed)
- mail_accounts_load (prefs);
-
- g_object_unref (prefs);
-}
-
-static void
-account_edit_clicked (GtkButton *button, gpointer user_data)
-{
- EMAccountPrefs *prefs = (EMAccountPrefs *) user_data;
-
- if (prefs->editor == NULL) {
- GtkTreeSelection *selection;
- EAccount *account = NULL;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- selection = gtk_tree_view_get_selection (prefs->table);
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- gtk_tree_model_get (model, &iter, 3, &account, -1);
-
- if (account && !account->parent_uid) {
- EMAccountEditor *emae;
-
- /** @HookPoint-EMConfig: Mail Account Editor
- * @Id: org.gnome.evolution.mail.config.accountEditor
- * @Type: E_CONFIG_BOOK
- * @Class: org.gnome.evolution.mail.config:1.0
- * @Target: EMConfigTargetAccount
- *
- * The account editor window.
- */
- emae = em_account_editor_new(account, EMAE_NOTEBOOK, "org.gnome.evolution.mail.config.accountEditor");
- prefs->editor = emae->editor;
-
- gtk_window_set_transient_for ((GtkWindow *)prefs->editor, (GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)prefs));
- g_object_ref(prefs);
- /* rather nasty hack to reload the accounts, it should just listen to the e-account-list */
- g_object_weak_ref((GObject *)prefs->editor, (GWeakNotify) account_edit_finished, prefs);
- gtk_widget_show(emae->editor);
- }
- } else {
- gdk_window_raise (prefs->editor->window);
- }
-}
-
-static void
-account_delete_clicked (GtkButton *button, gpointer user_data)
-{
- EMAccountPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- EAccount *account = NULL;
- EAccountList *accounts;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gint ans;
- gboolean has_proxies = FALSE;
-
- selection = gtk_tree_view_get_selection (prefs->table);
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- gtk_tree_model_get (model, &iter, 3, &account, -1);
-
- /* make sure we have a valid account selected and that we aren't editing anything... */
- if (account == NULL || prefs->editor != NULL)
- return;
-
- has_proxies = mail_config_has_proxies (account);
- ans = e_error_run(PREFS_WINDOW(prefs), has_proxies?"mail:ask-delete-account-with-proxies":"mail:ask-delete-account",NULL);
-
- if (ans == GTK_RESPONSE_YES) {
- gint len;
-
- /* remove it from the folder-tree in the shell */
- if (account->enabled && account->source && account->source->url)
- mail_component_remove_store_by_uri (mail_component_peek (), account->source->url);
-
- /* remove all the proxies account has created*/
- if (has_proxies)
- mail_config_remove_account_proxies (account);
-
- /* remove it from the config file */
- mail_config_remove_account (account);
- accounts = mail_config_get_accounts ();
-
- mail_config_write ();
-
- gtk_list_store_remove ((GtkListStore *) model, &iter);
-
- len = e_list_length ((EList *) accounts);
- if (len > 0) {
- if ( !gtk_list_store_iter_is_valid ((GtkListStore *) model, &iter))
- gtk_tree_model_get_iter_first (model, &iter);
-
- gtk_tree_selection_select_iter (selection, &iter);
- } else {
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_edit), FALSE);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_delete), FALSE);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_default), FALSE);
- }
- }
-}
-
-static void
-account_default_clicked (GtkButton *button, gpointer user_data)
-{
- EMAccountPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- EAccount *account = NULL;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- selection = gtk_tree_view_get_selection (prefs->table);
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- gtk_tree_model_get (model, &iter, 3, &account, -1);
-
- if (account) {
- mail_config_set_default_account (account);
-
- mail_config_write ();
-
- mail_accounts_load (prefs);
- }
-}
-
-static void
-account_able_changed(EAccount *account)
-{
- MailComponent *component = mail_component_peek ();
-
- /* FIXME: do this directly by listening to the mail accounts changed events in the relevant components */
-
- if (account->source->url) {
- if (account->enabled)
- mail_component_load_store_by_uri (component,
- account->source->url,
- account->name);
- else
- mail_component_remove_store_by_uri (component, account->source->url);
- }
-
- mail_config_write ();
-}
-
-static void
-account_able_toggled (GtkCellRendererToggle *renderer, gchar *arg1, gpointer user_data)
-{
- EMAccountPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- EAccount *account = NULL;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- path = gtk_tree_path_new_from_string (arg1);
- model = gtk_tree_view_get_model (prefs->table);
- selection = gtk_tree_view_get_selection (prefs->table);
-
- if (gtk_tree_model_get_iter (model, &iter, path)) {
- gtk_tree_model_get (model, &iter, 3, &account, -1);
-
- if (mail_config_has_proxies (account)) {
- gint ans;
-
- ans = e_error_run(PREFS_WINDOW(prefs), "mail:ask-delete-proxy-accounts",NULL);
-
- if (ans == GTK_RESPONSE_NO) {
- gtk_tree_path_free (path);
- return;
- }
-
- mail_config_remove_account_proxies (account);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_edit), 1);
- }
-
- account->enabled = !account->enabled;
- e_account_list_change(mail_config_get_accounts(), account);
- account_able_changed (account);
- gtk_list_store_set ((GtkListStore *) model, &iter, 0, account->enabled, -1);
-
- /* let the rest of the application know it changed */
- }
-
- gtk_tree_path_free (path);
-}
-
-static void
-account_double_click (GtkTreeView *treeview, GtkTreePath *path,
- GtkTreeViewColumn *column, EMAccountPrefs *prefs)
-{
- account_edit_clicked (NULL, prefs);
-}
-
-static void
-account_cursor_change (GtkTreeSelection *selection, EMAccountPrefs *prefs)
-{
- EAccount *account = NULL;
- GtkTreeModel *model;
- GtkTreeIter iter;
- const gchar *url = NULL;
- gint state;
- EAccount *default_account;
- default_account = mail_config_get_default_account ();
-
- state = gconf_client_key_is_writable(mail_config_get_gconf_client(), "/apps/evolution/mail/accounts", NULL);
- if (state) {
- state = gtk_tree_selection_get_selected (selection, &model, &iter);
- if (state) {
- gtk_tree_model_get (model, &iter, 3, &account, -1);
- url = e_account_get_string (account, E_ACCOUNT_SOURCE_URL);
- } else {
- gtk_widget_grab_focus (GTK_WIDGET (prefs->mail_add));
- }
- gtk_widget_set_sensitive (GTK_WIDGET (prefs), TRUE);
- } else {
- gtk_widget_set_sensitive (GTK_WIDGET (prefs), FALSE);
- }
-
- if ( url != NULL )
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_edit), TRUE);
-
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_delete), state);
-
- if (account == default_account)
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_default), FALSE);
- else
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_default), state);
-}
-
-static void
-mail_accounts_load (EMAccountPrefs *prefs)
-{
- EAccount *default_account;
- EAccountList *accounts;
- GtkListStore *model;
- GtkTreeIter iter;
- gchar *name, *val;
- EIterator *node;
- gint row = 0;
- GtkTreeSelection *selection;
-
- model = (GtkListStore *) gtk_tree_view_get_model (prefs->table);
- gtk_list_store_clear (model);
-
- default_account = mail_config_get_default_account ();
-
- accounts = mail_config_get_accounts ();
- node = e_list_get_iterator ((EList *) accounts);
- selection = gtk_tree_view_get_selection(prefs->table);
-
- while (e_iterator_is_valid (node)) {
- EAccount *account;
- CamelURL *url;
-
- account = (EAccount *) e_iterator_get (node);
-
- if (!account->parent_uid) {
- url = account->source && account->source->url ? camel_url_new (account->source->url, NULL) : NULL;
-
- gtk_list_store_append (model, &iter);
- if (account == default_account) {
- /* translators: default account indicator */
- name = val = g_strdup_printf ("%s %s", account->name, _("[Default]"));
- } else {
- val = account->name;
- name = NULL;
- }
-
- gtk_list_store_set (model, &iter,
- 0, account->enabled,
- 1, val,
- 2, url && url->protocol ? url->protocol : (gchar *) _("None"),
- 3, account,
- -1);
- g_free (name);
-
- if (url)
- camel_url_free (url);
-
- /* select the first row by default */
- if (row == 0 && !prefs->changed)
- gtk_tree_selection_select_iter (selection, &iter);
- row++;
- }
-
- e_iterator_next (node);
- }
-
- g_object_unref (node);
-}
-
-GtkWidget *em_account_prefs_treeview_new (gchar *widget_name, gchar *string1, gchar *string2,
- gint int1, gint int2);
-
-GtkWidget *
-em_account_prefs_treeview_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2)
-{
- GtkWidget *table, *scrolled;
- GtkTreeSelection *selection;
- GtkCellRenderer *renderer;
- GtkListStore *model;
-
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN);
-
- renderer = gtk_cell_renderer_toggle_new ();
- g_object_set ((GObject *) renderer, "activatable", TRUE, NULL);
-
- model = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
- table = gtk_tree_view_new_with_model ((GtkTreeModel *) model);
- g_object_unref (model);
- gtk_tree_view_insert_column_with_attributes ((GtkTreeView *) table, -1, _("Enabled"),
- renderer, "active", 0, NULL);
-
- g_object_set_data ((GObject *) scrolled, "renderer", renderer);
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes ((GtkTreeView *) table, -1, _("Account name"),
- renderer, "text", 1, NULL);
- gtk_tree_view_insert_column_with_attributes ((GtkTreeView *)table, -1, _("Protocol"),
- renderer, "text", 2, NULL);
- selection = gtk_tree_view_get_selection ((GtkTreeView *) table);
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- gtk_tree_view_set_headers_visible ((GtkTreeView *) table, TRUE);
- atk_object_set_name (gtk_widget_get_accessible (table), _("Mail Accounts"));
-
- /* FIXME: column auto-resize? */
- /* Is this needed?
- gtk_tree_view_column_set_alignment (gtk_tree_view_get_column (prefs->table, 0), 1.0);*/
-
- gtk_container_add (GTK_CONTAINER (scrolled), table);
-
- g_object_set_data ((GObject *) scrolled, "table", table);
-
- gtk_widget_show (scrolled);
- gtk_widget_show (table);
-
- return scrolled;
-}
-
-static void
-em_account_prefs_construct (EMAccountPrefs *prefs)
-{
- GtkWidget *toplevel, *widget;
- GtkCellRenderer *renderer;
- GladeXML *gui;
- gchar *gladefile;
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- gui = glade_xml_new (gladefile, "accounts_tab", NULL);
- g_free (gladefile);
-
- prefs->gui = gui;
-
- /* get our toplevel widget */
- toplevel = glade_xml_get_widget (gui, "toplevel");
-
- /* reparent */
- g_object_ref (toplevel);
- gtk_container_remove (GTK_CONTAINER (toplevel->parent), toplevel);
- gtk_container_add (GTK_CONTAINER (prefs), toplevel);
- g_object_unref (toplevel);
-
- widget = glade_xml_get_widget (gui, "etableMailAccounts");
-
- prefs->table = (GtkTreeView *) g_object_get_data ((GObject *) widget, "table");
-
- renderer = g_object_get_data ((GObject *) widget, "renderer");
- g_signal_connect (renderer, "toggled", G_CALLBACK (account_able_toggled), prefs);
-
- prefs->changed = FALSE;
- mail_accounts_load (prefs);
- prefs->changed = TRUE;
-
- prefs->mail_add = GTK_BUTTON (glade_xml_get_widget (gui, "cmdAccountAdd"));
- g_signal_connect (prefs->mail_add, "clicked", G_CALLBACK (account_add_clicked), prefs);
-
- prefs->mail_edit = GTK_BUTTON (glade_xml_get_widget (gui, "cmdAccountEdit"));
- g_signal_connect (prefs->mail_edit, "clicked", G_CALLBACK (account_edit_clicked), prefs);
-
- prefs->mail_delete = GTK_BUTTON (glade_xml_get_widget (gui, "cmdAccountDelete"));
- g_signal_connect (prefs->mail_delete, "clicked", G_CALLBACK (account_delete_clicked), prefs);
-
- prefs->mail_default = GTK_BUTTON (glade_xml_get_widget (gui, "cmdAccountDefault"));
- g_signal_connect (prefs->mail_default, "clicked", G_CALLBACK (account_default_clicked), prefs);
-
- g_signal_connect (gtk_tree_view_get_selection (prefs->table),
- "changed", G_CALLBACK (account_cursor_change), prefs);
- g_signal_connect (prefs->table, "row-activated", G_CALLBACK (account_double_click), prefs);
-
- account_cursor_change(gtk_tree_view_get_selection(prefs->table), prefs);
-}
-
-GtkWidget *
-em_account_prefs_new (GNOME_Evolution_Shell shell)
-{
- EMAccountPrefs *new;
-
- new = (EMAccountPrefs *) g_object_new (em_account_prefs_get_type (), NULL);
- em_account_prefs_construct (new);
- new->shell = shell;
-
- return (GtkWidget *) new;
-}
diff --git a/mail/em-account-prefs.h b/mail/em-account-prefs.h
deleted file mode 100644
index 2415e1366b..0000000000
--- a/mail/em-account-prefs.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_ACCOUNT_PREFS_H__
-#define __EM_ACCOUNT_PREFS_H__
-
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-
-#include <table/e-table.h>
-
-#include "evolution-config-control.h"
-
-#include <shell/Evolution.h>
-
-G_BEGIN_DECLS
-
-#define EM_ACCOUNT_PREFS_TYPE (em_account_prefs_get_type ())
-#define EM_ACCOUNT_PREFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EM_ACCOUNT_PREFS_TYPE, EMAccountPrefs))
-#define EM_ACCOUNT_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EM_ACCOUNT_PREFS_TYPE, EMAccountPrefsClass))
-#define EM_IS_ACCOUNT_PREFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EM_ACCOUNT_PREFS_TYPE))
-#define EM_IS_ACCOUNT_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EM_ACCOUNT_PREFS_TYPE))
-
-typedef struct _EMAccountPrefs EMAccountPrefs;
-typedef struct _EMAccountPrefsClass EMAccountPrefsClass;
-
-struct _EMAccountPrefs {
- GtkVBox parent_object;
-
- GNOME_Evolution_Shell shell;
-
- GladeXML *gui;
-
- GtkWidget *druid;
- GtkWidget *editor;
-
- GtkTreeView *table;
-
- GtkButton *mail_add;
- GtkButton *mail_edit;
- GtkButton *mail_delete;
- GtkButton *mail_default;
-
- guint destroyed : 1;
- guint changed : 1;
-};
-
-struct _EMAccountPrefsClass {
- GtkVBoxClass parent_class;
-
- /* signals */
-
-};
-
-GType em_account_prefs_get_type (void);
-
-GtkWidget *em_account_prefs_new (GNOME_Evolution_Shell shell);
-
-/* needed by global config */
-#define EM_ACCOUNT_PREFS_CONTROL_ID "OAFIID:GNOME_Evolution_Mail_AccountPrefs_ConfigControl:" BASE_VERSION
-
-G_END_DECLS
-
-#endif /* __EM_ACCOUNT_PREFS_H__ */
diff --git a/mail/em-composer-prefs.c b/mail/em-composer-prefs.c
index 0a7312e837..1fd5843cec 100644
--- a/mail/em-composer-prefs.c
+++ b/mail/em-composer-prefs.c
@@ -37,8 +37,6 @@
#include "em-composer-prefs.h"
#include "composer/e-msg-composer.h"
-#include <bonobo/bonobo-generic-factory.h>
-
#include <camel/camel-iconv.h>
#include <misc/e-gui-utils.h>
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index fa9302441b..f268b14596 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -37,20 +37,23 @@
#include "mail-config.h"
#include "mail-session.h"
#include "mail-send-recv.h"
-#include "mail-component.h"
#include "e-util/e-error.h"
+#include "e-util/e-account-utils.h"
+#include "e-mail-local.h"
#include "em-utils.h"
#include "em-composer-utils.h"
#include "composer/e-msg-composer.h"
#include "composer/e-composer-autosave.h"
+#include "composer/e-composer-post-header.h"
+#include "em-folder-selector.h"
+#include "em-folder-tree.h"
#include "em-format-html.h"
+#include "em-format-html-print.h"
#include "em-format-quote.h"
#include "em-event.h"
-#include "libedataserver/e-account-list.h"
-
#include <camel/camel-folder.h>
#include <camel/camel-multipart.h>
#include <camel/camel-string-utils.h>
@@ -72,6 +75,9 @@
static EAccount * guess_account (CamelMimeMessage *message, CamelFolder *folder);
+static void em_utils_composer_send_cb (EMsgComposer *composer);
+static void em_utils_composer_save_draft_cb (EMsgComposer *composer);
+
struct emcs_t {
guint ref_count;
@@ -88,28 +94,63 @@ emcs_new (void)
{
struct emcs_t *emcs;
- emcs = g_new (struct emcs_t, 1);
+ emcs = g_new0 (struct emcs_t, 1);
emcs->ref_count = 1;
- emcs->drafts_folder = NULL;
- emcs->drafts_uid = NULL;
- emcs->folder = NULL;
- emcs->flags = 0;
- emcs->set = 0;
- emcs->uid = NULL;
return emcs;
}
static void
+emcs_set_drafts_info (struct emcs_t *emcs,
+ CamelFolder *drafts_folder,
+ const gchar *drafts_uid)
+{
+ g_return_if_fail (emcs != NULL);
+ g_return_if_fail (drafts_folder != NULL);
+ g_return_if_fail (drafts_uid != NULL);
+
+ if (emcs->drafts_folder != NULL)
+ camel_object_unref (emcs->drafts_folder);
+ g_free (emcs->drafts_uid);
+
+ camel_object_ref (drafts_folder);
+ emcs->drafts_folder = drafts_folder;
+ emcs->drafts_uid = g_strdup (drafts_uid);
+}
+
+static void
+emcs_set_folder_info (struct emcs_t *emcs,
+ CamelFolder *folder,
+ const gchar *uid,
+ guint32 flags,
+ guint32 set)
+{
+ g_return_if_fail (emcs != NULL);
+ g_return_if_fail (folder != NULL);
+ g_return_if_fail (uid != NULL);
+
+ if (emcs->folder != NULL)
+ camel_object_unref (emcs->folder);
+ g_free (emcs->uid);
+
+ camel_object_ref (folder);
+ emcs->folder = folder;
+ emcs->uid = g_strdup (uid);
+ emcs->flags = flags;
+ emcs->set = set;
+}
+
+static void
free_emcs (struct emcs_t *emcs)
{
- if (emcs->drafts_folder)
+ if (emcs->drafts_folder != NULL)
camel_object_unref (emcs->drafts_folder);
g_free (emcs->drafts_uid);
- if (emcs->folder)
+ if (emcs->folder != NULL)
camel_object_unref (emcs->folder);
g_free (emcs->uid);
+
g_free (emcs);
}
@@ -127,12 +168,6 @@ emcs_unref (struct emcs_t *emcs)
free_emcs (emcs);
}
-static void
-composer_destroy_cb (gpointer user_data, GObject *deadbeef)
-{
- emcs_unref (user_data);
-}
-
static gboolean
ask_confirm_for_unwanted_html_mail (EMsgComposer *composer, EDestination **recipients)
{
@@ -226,17 +261,6 @@ composer_send_queued_cb (CamelFolder *folder, CamelMimeMessage *msg, CamelMessag
mail_send ();
}
} else {
- if (!emcs) {
- /* disconnect the previous signal handlers */
- g_signal_handlers_disconnect_matched (send->composer, G_SIGNAL_MATCH_FUNC, 0,
- 0, NULL, em_utils_composer_send_cb, NULL);
- g_signal_handlers_disconnect_matched (send->composer, G_SIGNAL_MATCH_FUNC, 0,
- 0, NULL, em_utils_composer_save_draft_cb, NULL);
-
- /* reconnect to the signals using a non-NULL emcs for the callback data */
- em_composer_utils_setup_default_callbacks (send->composer);
- }
-
e_msg_composer_set_enable_autosave (send->composer, TRUE);
gtk_widget_show (GTK_WIDGET (send->composer));
}
@@ -416,46 +440,49 @@ composer_get_message (EMsgComposer *composer, gboolean save_html_object_data)
return message;
}
-void
-em_utils_composer_send_cb (EMsgComposer *composer, gpointer user_data)
+static void
+em_utils_composer_send_cb (EMsgComposer *composer)
{
EComposerHeaderTable *table;
CamelMimeMessage *message;
CamelMessageInfo *info;
struct _send_data *send;
- CamelFolder *mail_folder;
+ CamelFolder *folder;
EAccount *account;
table = e_msg_composer_get_header_table (composer);
account = e_composer_header_table_get_account (table);
if (!account || !account->enabled) {
- e_error_run((GtkWindow *)composer, "mail:send-no-account-enabled", NULL);
+ e_error_run (
+ GTK_WINDOW (composer),
+ "mail:send-no-account-enabled", NULL);
return;
}
- if (!(message = composer_get_message (composer, FALSE)))
+ if ((message = composer_get_message (composer, FALSE)) == NULL)
return;
- mail_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
- camel_object_ref (mail_folder);
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ camel_object_ref (folder);
/* mail the message */
- info = camel_message_info_new(NULL);
- camel_message_info_set_flags(info, CAMEL_MESSAGE_SEEN, ~0);
+ info = camel_message_info_new (NULL);
+ camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);
send = g_malloc (sizeof (*send));
- send->emcs = user_data;
+ send->emcs = g_object_get_data (G_OBJECT (composer), "emcs");
if (send->emcs)
emcs_ref (send->emcs);
send->send = TRUE;
- send->composer = composer;
- g_object_ref (composer);
+ send->composer = g_object_ref (composer);
gtk_widget_hide (GTK_WIDGET (composer));
e_msg_composer_set_enable_autosave (composer, FALSE);
- mail_append_mail (mail_folder, message, info, composer_send_queued_cb, send);
- camel_object_unref (mail_folder);
+ mail_append_mail (
+ folder, message, info, composer_send_queued_cb, send);
+
+ camel_object_unref (folder);
camel_object_unref (message);
}
@@ -495,17 +522,9 @@ save_draft_done (CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *i
composer_set_no_change (sdi->composer, FALSE, FALSE);
- if ((emcs = sdi->emcs) == NULL) {
+ if ((emcs = sdi->emcs) == NULL)
emcs = emcs_new ();
- /* disconnect the previous signal handlers */
- g_signal_handlers_disconnect_by_func (sdi->composer, G_CALLBACK (em_utils_composer_send_cb), NULL);
- g_signal_handlers_disconnect_by_func (sdi->composer, G_CALLBACK (em_utils_composer_save_draft_cb), NULL);
-
- /* reconnect to the signals using a non-NULL emcs for the callback data */
- em_composer_utils_setup_default_callbacks (sdi->composer);
- }
-
if (emcs->drafts_folder) {
/* delete the original draft message */
camel_folder_set_message_flags (emcs->drafts_folder, emcs->drafts_uid,
@@ -557,13 +576,13 @@ save_draft_folder (gchar *uri, CamelFolder *folder, gpointer data)
}
}
-void
-em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data)
+static void
+em_utils_composer_save_draft_cb (EMsgComposer *composer)
{
- const gchar *default_drafts_folder_uri = mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS);
- CamelFolder *drafts_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS);
+ CamelFolder *local_drafts_folder;
EComposerHeaderTable *table;
struct _save_draft_info *sdi;
+ const gchar *local_drafts_folder_uri;
CamelFolder *folder = NULL;
CamelMimeMessage *msg;
CamelMessageInfo *info;
@@ -573,19 +592,24 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data)
* get destroyed while we're in mail_msg_wait() a little lower
* down, waiting for the folder to open */
- g_object_ref(composer);
+ local_drafts_folder =
+ e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+ local_drafts_folder_uri =
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS);
+
+ g_object_ref (composer);
msg = e_msg_composer_get_message_draft (composer);
table = e_msg_composer_get_header_table (composer);
account = e_composer_header_table_get_account (table);
- sdi = g_malloc(sizeof(struct _save_draft_info));
+ sdi = g_malloc (sizeof(struct _save_draft_info));
sdi->composer = composer;
- sdi->emcs = user_data;
+ sdi->emcs = g_object_get_data (G_OBJECT (composer), "emcs");
if (sdi->emcs)
- emcs_ref(sdi->emcs);
+ emcs_ref (sdi->emcs);
if (account && account->drafts_folder_uri &&
- strcmp (account->drafts_folder_uri, default_drafts_folder_uri) != 0) {
+ strcmp (account->drafts_folder_uri, local_drafts_folder_uri) != 0) {
gint id;
id = mail_get_folder (account->drafts_folder_uri, 0, save_draft_folder, &folder, mail_msg_unordered_push);
@@ -601,11 +625,11 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data)
return;
}
- folder = drafts_folder;
- camel_object_ref (drafts_folder);
+ folder = local_drafts_folder;
+ camel_object_ref (local_drafts_folder);
}
} else {
- folder = drafts_folder;
+ folder = local_drafts_folder;
camel_object_ref (folder);
}
@@ -617,43 +641,24 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data)
camel_object_unref (msg);
}
-void
-em_composer_utils_setup_callbacks (EMsgComposer *composer,
- CamelFolder *folder,
- const gchar *uid,
- guint32 flags,
- guint32 set,
- CamelFolder *drafts,
- const gchar *drafts_uid)
+static void
+em_utils_composer_print_cb (EMsgComposer *composer,
+ GtkPrintOperationAction action)
{
- struct emcs_t *emcs;
-
- emcs = emcs_new ();
-
- if (folder && uid) {
- camel_object_ref (folder);
- emcs->folder = folder;
- emcs->uid = g_strdup (uid);
- emcs->flags = flags;
- emcs->set = set;
- }
-
- if (drafts && drafts_uid) {
- camel_object_ref (drafts);
- emcs->drafts_folder = drafts;
- emcs->drafts_uid = g_strdup (drafts_uid);
- }
+ CamelMimeMessage *message;
+ EMFormatHTMLPrint *efhp;
- g_signal_connect (composer, "send", G_CALLBACK (em_utils_composer_send_cb), emcs);
- g_signal_connect (composer, "save-draft", G_CALLBACK (em_utils_composer_save_draft_cb), emcs);
+ message = e_msg_composer_get_message_print (composer, 1);
- g_object_weak_ref ((GObject *) composer, (GWeakNotify) composer_destroy_cb, emcs);
+ efhp = em_format_html_print_new (NULL, action);
+ em_format_html_print_raw_message (efhp, message);
+ g_object_unref (efhp);
}
/* Composing messages... */
static EMsgComposer *
-create_new_composer (const gchar *subject, const gchar *fromuri, gboolean use_default_callbacks, gboolean lite)
+create_new_composer (const gchar *subject, const gchar *fromuri, gboolean lite)
{
EMsgComposer *composer;
EComposerHeaderTable *table;
@@ -678,9 +683,6 @@ create_new_composer (const gchar *subject, const gchar *fromuri, gboolean use_de
e_composer_header_table_set_account (table, account);
e_composer_header_table_set_subject (table, subject);
- if (use_default_callbacks)
- em_composer_utils_setup_default_callbacks (composer);
-
return composer;
}
@@ -695,7 +697,7 @@ em_utils_compose_new_message (const gchar *fromuri)
{
GtkWidget *composer;
- composer = (GtkWidget *) create_new_composer ("", fromuri, TRUE, FALSE);
+ composer = (GtkWidget *) create_new_composer ("", fromuri, FALSE);
if (composer == NULL)
return;
@@ -710,18 +712,18 @@ em_utils_compose_new_message (const gchar *fromuri)
* Opens a new composer window as a child window of @parent's toplevel
* window.
**/
-struct _EMsgComposer *
+EMsgComposer *
em_utils_compose_lite_new_message (const gchar *fromuri)
{
GtkWidget *composer;
- composer = (GtkWidget *) create_new_composer ("", fromuri, TRUE, TRUE);
+ composer = (GtkWidget *) create_new_composer ("", fromuri, TRUE);
if (composer == NULL)
return NULL;
composer_set_no_change (E_MSG_COMPOSER (composer), TRUE, TRUE);
- return (struct _EMsgComposer *)composer;
+ return E_MSG_COMPOSER (composer);
}
/**
@@ -732,7 +734,7 @@ em_utils_compose_lite_new_message (const gchar *fromuri)
* window. If @url is non-NULL, the composer fields will be filled in
* according to the values in the mailto url.
**/
-struct _EMsgComposer *
+EMsgComposer *
em_utils_compose_new_message_with_mailto (const gchar *url, const gchar *fromuri)
{
EMsgComposer *composer;
@@ -745,7 +747,6 @@ em_utils_compose_new_message_with_mailto (const gchar *url, const gchar *fromuri
composer = e_msg_composer_new ();
table = e_msg_composer_get_header_table (composer);
- em_composer_utils_setup_default_callbacks (composer);
if (fromuri
&& (account = mail_config_get_account_by_source_url(fromuri)))
@@ -753,7 +754,7 @@ em_utils_compose_new_message_with_mailto (const gchar *url, const gchar *fromuri
composer_set_no_change (composer, TRUE, url == NULL);
- if (!e_msg_composer_get_lite()) {
+ if (!e_msg_composer_get_lite ()) {
gtk_widget_show ((GtkWidget *) composer);
gdk_window_raise (((GtkWidget *) composer)->window);
}
@@ -919,10 +920,12 @@ edit_message (CamelMimeMessage *message, CamelFolder *drafts, const gchar *uid)
composer = e_msg_composer_new_with_message (message);
- if (em_utils_folder_is_templates(drafts, NULL) == TRUE)
- em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, NULL, NULL);
- else
- em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, drafts, uid);
+ if (em_utils_folder_is_drafts (drafts, NULL)) {
+ struct emcs_t *emcs;
+
+ emcs = g_object_get_data (G_OBJECT (composer), "emcs");
+ emcs_set_drafts_info (emcs, drafts, uid);
+ }
composer_set_no_change (composer, TRUE, FALSE);
@@ -1046,12 +1049,12 @@ setup_forward_attached_callbacks (EMsgComposer *composer, CamelFolder *folder, G
g_object_weak_ref ((GObject *) composer, (GWeakNotify) composer_destroy_fad_cb, fad);
}
-static struct _EMsgComposer *
+static EMsgComposer *
forward_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages, CamelMimePart *part, gchar *subject, const gchar *fromuri)
{
EMsgComposer *composer;
- composer = create_new_composer (subject, fromuri, TRUE, FALSE);
+ composer = create_new_composer (subject, fromuri, FALSE);
if (composer == NULL)
return NULL;
@@ -1132,7 +1135,7 @@ forward_non_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages,
text = em_utils_message_to_html (message, _("-------- Forwarded Message --------"), flags, &len, NULL, NULL);
if (text) {
- composer = create_new_composer (subject, fromuri, !uids || !uids->pdata [i], FALSE);
+ composer = create_new_composer (subject, fromuri, FALSE);
if (composer) {
if (CAMEL_IS_MULTIPART(camel_medium_get_content_object((CamelMedium *)message)))
@@ -1140,8 +1143,12 @@ forward_non_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages,
e_msg_composer_set_body_text (composer, text, len);
- if (uids && uids->pdata[i])
- em_composer_utils_setup_callbacks (composer, folder, uids->pdata[i], CAMEL_MESSAGE_FORWARDED, CAMEL_MESSAGE_FORWARDED, NULL, NULL);
+ if (uids && uids->pdata[i]) {
+ struct emcs_t *emcs;
+
+ emcs = g_object_get_data (G_OBJECT (composer), "emcs");
+ emcs_set_folder_info (emcs, folder, uids->pdata[i], CAMEL_MESSAGE_FORWARDED, CAMEL_MESSAGE_FORWARDED);
+ }
composer_set_no_change (composer, TRUE, FALSE);
@@ -1211,7 +1218,7 @@ em_utils_forward_quoted (CamelFolder *folder, GPtrArray *uids, const gchar *from
*
* Forwards a message in the user's configured default style.
**/
-struct _EMsgComposer *
+EMsgComposer *
em_utils_forward_message (CamelMimeMessage *message, const gchar *fromuri)
{
GPtrArray *messages;
@@ -1219,7 +1226,7 @@ em_utils_forward_message (CamelMimeMessage *message, const gchar *fromuri)
GConfClient *gconf;
gchar *subject;
gint mode;
- struct _EMsgComposer *composer = NULL;
+ EMsgComposer *composer = NULL;
messages = g_ptr_array_new ();
g_ptr_array_add (messages, message);
@@ -1299,8 +1306,6 @@ redirect_get_composer (CamelMimeMessage *message)
composer = e_msg_composer_new_redirect (message, account ? account->name : NULL);
- em_composer_utils_setup_default_callbacks (composer);
-
return composer;
}
@@ -1542,8 +1547,8 @@ em_utils_send_receipt (CamelFolder *folder, CamelMimeMessage *message)
}
/* Send the receipt */
- out_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
info = camel_message_info_new (NULL);
+ out_folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
mail_append_mail (out_folder, receipt, info, em_utils_receipt_done, NULL);
}
@@ -1638,8 +1643,8 @@ em_utils_forward_message_raw (CamelFolder *folder, CamelMimeMessage *message, co
g_free (subject);
/* and send it */
- out_folder = mail_component_get_folder (NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
info = camel_message_info_new (NULL);
+ out_folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
mail_append_mail (out_folder, forward, info, emu_forward_raw_done, NULL);
}
@@ -1654,10 +1659,10 @@ generate_account_hash (void)
EAccountList *accounts;
EIterator *iter;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
account_hash = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
- def = mail_config_get_default_account ();
+ def = e_get_default_account ();
iter = e_list_get_iterator ((EList *) accounts);
while (e_iterator_is_valid (iter)) {
@@ -2327,7 +2332,7 @@ reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessage *messag
* may be supplied in order to update the message flags once it has
* been replied to.
**/
-struct _EMsgComposer *
+EMsgComposer *
em_utils_reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessage *message, gint mode, EMFormat *source)
{
CamelInternetAddress *to, *cc;
@@ -2335,8 +2340,7 @@ em_utils_reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessag
EMsgComposer *composer;
EAccount *account;
guint32 flags;
- EMEvent *eme;
- EMEventTargetMessage *target;
+ struct emcs_t *emcs;
if (folder && uid && message == NULL) {
struct _reply_data *rd = g_malloc0(sizeof(*rd));
@@ -2389,19 +2393,8 @@ em_utils_reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessag
composer_set_body (composer, message, source);
- /** @Event: message.replying
- * @Title: Message being replied to
- * @Target: EMEventTargetMessage
- *
- * message.replying is emitted when a user starts replying to a message.
- */
-
- eme = em_event_peek();
- target = em_event_target_new_message(eme, folder, message, uid,
- mode == REPLY_MODE_ALL ? EM_EVENT_MESSAGE_REPLY_ALL | EM_EVENT_MESSAGE_REPLY : EM_EVENT_MESSAGE_REPLY, composer);
- e_event_emit((EEvent *)eme, "message.replying", (EEventTarget *)target);
-
- em_composer_utils_setup_callbacks (composer, folder, uid, flags, flags, NULL, NULL);
+ emcs = g_object_get_data (G_OBJECT (composer), "emcs");
+ emcs_set_folder_info (emcs, folder, uid, flags, flags);
composer_set_no_change (composer, TRUE, FALSE);
@@ -2410,3 +2403,105 @@ em_utils_reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessag
return composer;
}
+
+static void
+post_header_clicked_cb (EComposerPostHeader *header)
+{
+ GtkTreeSelection *selection;
+ GtkWidget *folder_tree;
+ GtkWidget *dialog;
+ GList *list;
+
+ folder_tree = em_folder_tree_new ();
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+
+ em_folder_tree_set_excluded (
+ EM_FOLDER_TREE (folder_tree),
+ EMFT_EXCLUDE_NOSELECT |
+ EMFT_EXCLUDE_VIRTUAL |
+ EMFT_EXCLUDE_VTRASH);
+
+ dialog = em_folder_selector_new (
+ EM_FOLDER_TREE (folder_tree),
+ EM_FOLDER_SELECTOR_CAN_CREATE,
+ _("Posting destination"),
+ _("Choose folders to post the message to."),
+ NULL);
+
+ list = e_composer_post_header_get_folders (header);
+ em_folder_selector_set_selected_list (
+ EM_FOLDER_SELECTOR (dialog), list);
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK) {
+ /* Prevent the header's "custom" flag from being reset,
+ * which is what the default method will do next. */
+ g_signal_stop_emission_by_name (header, "clicked");
+ goto exit;
+ }
+
+ list = em_folder_selector_get_selected_uris (
+ EM_FOLDER_SELECTOR (dialog));
+ e_composer_post_header_set_folders (header, list);
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+
+exit:
+ gtk_widget_destroy (dialog);
+}
+
+/**
+ * em_configure_new_composer:
+ * @composer: a newly created #EMsgComposer
+ *
+ * Integrates a newly created #EMsgComposer into the mail backend. The
+ * composer can't link directly to the mail backend without introducing
+ * circular library dependencies, so this function finishes configuring
+ * things the #EMsgComposer instance can't do itself.
+ **/
+void
+em_configure_new_composer (EMsgComposer *composer)
+{
+ EComposerHeaderTable *table;
+ EComposerHeaderType header_type;
+ EComposerHeader *header;
+ struct emcs_t *emcs;
+
+ g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+ header_type = E_COMPOSER_HEADER_POST_TO;
+ table = e_msg_composer_get_header_table (composer);
+ header = e_composer_header_table_get_header (table, header_type);
+
+ emcs = emcs_new ();
+
+ g_object_set_data_full (
+ G_OBJECT (composer), "emcs", emcs,
+ (GDestroyNotify) emcs_unref);
+
+ g_signal_connect (
+ composer, "send",
+ G_CALLBACK (em_utils_composer_send_cb), NULL);
+
+ g_signal_connect (
+ composer, "save-draft",
+ G_CALLBACK (em_utils_composer_save_draft_cb), NULL);
+
+ g_signal_connect (
+ composer, "print",
+ G_CALLBACK (em_utils_composer_print_cb), NULL);
+
+ /* Handle "Post To:" button clicks, which displays a folder tree
+ * widget. The composer doesn't know about folder tree widgets,
+ * so it can't handle this itself.
+ *
+ * Note: This is a G_SIGNAL_RUN_LAST signal, which allows us to
+ * stop the signal emission if the user cancels or closes
+ * the folder selector dialog. See the handler function. */
+ g_signal_connect (
+ header, "clicked",
+ G_CALLBACK (post_header_clicked_cb), NULL);
+}
diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h
index b00b3a2bd0..be29a7ae71 100644
--- a/mail/em-composer-utils.h
+++ b/mail/em-composer-utils.h
@@ -27,19 +27,11 @@
#include <glib.h>
#include <camel/camel-nntp-address.h>
-#include <mail/em-format.h>
+#include <em-format/em-format.h>
#include <composer/e-msg-composer.h>
G_BEGIN_DECLS
-void em_composer_utils_setup_callbacks (EMsgComposer *composer, CamelFolder *folder, const gchar *uid,
- guint32 flags, guint32 set, CamelFolder *drafts, const gchar *drafts_uid);
-
-#define em_composer_utils_setup_default_callbacks(composer) em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, NULL, NULL)
-
-void em_utils_composer_send_cb(EMsgComposer *composer, gpointer user_data);
-void em_utils_composer_save_draft_cb(EMsgComposer *composer, gpointer user_data);
-
void em_utils_compose_new_message (const gchar *fromuri);
EMsgComposer * em_utils_compose_lite_new_message (const gchar *fromuri);
@@ -76,6 +68,8 @@ void em_utils_get_reply_all (CamelMimeMessage *message, CamelInternetAddress *to
EMsgComposer * em_utils_reply_to_message (CamelFolder *, const gchar *uid, CamelMimeMessage *message, gint mode, EMFormat *source);
EDestination ** em_utils_camel_address_to_destination (CamelInternetAddress *iaddr);
+void em_configure_new_composer (struct _EMsgComposer *composer);
+
G_END_DECLS
#endif /* __EM_COMPOSER_UTILS_H__ */
diff --git a/mail/em-config.c b/mail/em-config.c
index 357e88555b..dcdf9b10ef 100644
--- a/mail/em-config.c
+++ b/mail/em-config.c
@@ -223,85 +223,3 @@ em_config_target_new_account(EMConfig *emp, struct _EAccount *account)
return t;
}
-
-/* ********************************************************************** */
-
-/* Popup menu plugin handler */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.item:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="IMAP4 and IMAP4v1 mail store">
- <hook class="org.gnome.mail.popupMenu:1.0"
- handler="HandlePopup">
- <menu id="any" target="select">
- <item
- type="item|toggle|radio|image|submenu|bar"
- active
- path="foo/bar"
- label="label"
- icon="foo"
- mask="select_one"
- activate="emp_view_emacs"/>
- </menu>
- </extension>
-
-*/
-
-static gpointer emph_parent_class;
-#define emph ((EMConfigHook *)eph)
-
-static const EConfigHookTargetMask emph_no_masks[] = {
- { NULL }
-};
-
-static const EConfigHookTargetMap emph_targets[] = {
- { "folder", EM_CONFIG_TARGET_FOLDER, emph_no_masks },
- { "prefs", EM_CONFIG_TARGET_PREFS, emph_no_masks },
- { "account", EM_CONFIG_TARGET_ACCOUNT, emph_no_masks },
- { NULL }
-};
-
-static void
-emph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)emph_parent_class)->finalize(o);
-}
-
-static void
-emph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = emph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.mail.config:1.0";
-
- for (i=0;emph_targets[i].type;i++)
- e_config_hook_class_add_target_map((EConfigHookClass *)klass, &emph_targets[i]);
-
- ((EConfigHookClass *)klass)->config_class = g_type_class_ref(em_config_get_type());
-}
-
-GType
-em_config_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EMConfigHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL,
- sizeof(EMConfigHook), 0, (GInstanceInitFunc) NULL,
- };
-
- emph_parent_class = g_type_class_ref(e_config_hook_get_type());
- type = g_type_register_static(e_config_hook_get_type(), "EMConfigHook", &info, 0);
- }
-
- return type;
-}
diff --git a/mail/em-config.h b/mail/em-config.h
index 656a40ec38..62e74bea51 100644
--- a/mail/em-config.h
+++ b/mail/em-config.h
@@ -67,7 +67,7 @@ struct _EMConfigTargetAccount {
EAccount *account;
/* Need also: working account, not just real account, so changes can be propagated around
- And some mechamism for controlling the gui if we're running inside a druid, e.g. enabling 'next' */
+ And some mechamism for controlling the gui if we're running inside an assistant, e.g. enabling 'next' */
};
typedef struct _EConfigItem EMConfigItem;
@@ -91,21 +91,6 @@ EMConfigTargetFolder *em_config_target_new_folder(EMConfig *emp, CamelFolder *fo
EMConfigTargetPrefs *em_config_target_new_prefs(EMConfig *emp, GConfClient *gconf);
EMConfigTargetAccount *em_config_target_new_account(EMConfig *emp, EAccount *account);
-/* ********************************************************************** */
-
-typedef struct _EMConfigHook EMConfigHook;
-typedef struct _EMConfigHookClass EMConfigHookClass;
-
-struct _EMConfigHook {
- EConfigHook hook;
-};
-
-struct _EMConfigHookClass {
- EConfigHookClass hook_class;
-};
-
-GType em_config_hook_get_type(void);
-
G_END_DECLS
#endif /* __EM_CONFIG_H__ */
diff --git a/mail/em-event.c b/mail/em-event.c
index 4e79c31d08..de8f468fa9 100644
--- a/mail/em-event.c
+++ b/mail/em-event.c
@@ -149,16 +149,6 @@ em_event_target_new_folder (EMEvent *eme, const gchar *uri, guint new)
return t;
}
-EMEventTargetFolderBrowser *
-em_event_target_new_folder_browser (EMEvent *eme, EMFolderBrowser *emfb)
-{
- EMEventTargetFolderBrowser *t = e_event_target_new(&eme->popup, EM_EVENT_TARGET_FOLDER_BROWSER, sizeof(*t));
-
- t->emfb = emfb;
-
- return t;
-}
-
EMEventTargetComposer *
em_event_target_new_composer (EMEvent *eme, const EMsgComposer *composer, guint32 flags)
{
@@ -214,89 +204,3 @@ em_event_target_new_custom_icon(EMEvent *eme, GtkTreeStore *store, GtkTreeIter *
return t;
}
-
-/* ********************************************************************** */
-
-static gpointer emeh_parent_class;
-#define emeh ((EMEventHook *)eph)
-
-static const EEventHookTargetMask emeh_folder_masks[] = {
- { "newmail", EM_EVENT_FOLDER_NEWMAIL },
- { NULL }
-};
-
-static const EEventHookTargetMask emeh_folder_browser_masks[] = {
- { "folderbrowser", EM_EVENT_FOLDER_BROWSER },
- { NULL }
-};
-
-static const EEventHookTargetMask emeh_composer_masks[] = {
- { "sendoption", EM_EVENT_COMPOSER_SEND_OPTION },
- { NULL }
-};
-
-static const EEventHookTargetMask emeh_message_masks[] = {
- { "replyall", EM_EVENT_MESSAGE_REPLY_ALL },
- { "reply", EM_EVENT_MESSAGE_REPLY },
- { NULL }
-};
-
-static const EEventHookTargetMask emeh_send_receive_masks[] = {
- { "sendreceive", EM_EVENT_SEND_RECEIVE },
- { NULL }
-};
-
-static const EEventHookTargetMask emeh_custom_icon_masks[] = {
- { "customicon", EM_EVENT_CUSTOM_ICON },
- { NULL }
-};
-
-static const EEventHookTargetMap emeh_targets[] = {
- { "folder", EM_EVENT_TARGET_FOLDER, emeh_folder_masks },
- { "folderbrowser", EM_EVENT_TARGET_FOLDER_BROWSER, emeh_folder_browser_masks },
- { "message", EM_EVENT_TARGET_MESSAGE, emeh_message_masks },
- { "composer", EM_EVENT_TARGET_COMPOSER, emeh_composer_masks},
- { "sendreceive", EM_EVENT_TARGET_SEND_RECEIVE, emeh_send_receive_masks},
- { "customicon", EM_EVENT_TARGET_CUSTOM_ICON, emeh_custom_icon_masks},
- { NULL }
-};
-
-static void
-emeh_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)emeh_parent_class)->finalize(o);
-}
-
-static void
-emeh_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = emeh_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.mail.events:1.0";
-
- for (i=0;emeh_targets[i].type;i++)
- e_event_hook_class_add_target_map((EEventHookClass *)klass, &emeh_targets[i]);
-
- ((EEventHookClass *)klass)->event = (EEvent *)em_event_peek();
-}
-
-GType
-em_event_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EMEventHookClass), NULL, NULL, (GClassInitFunc) emeh_class_init, NULL, NULL,
- sizeof(EMEventHook), 0, (GInstanceInitFunc) NULL,
- };
-
- emeh_parent_class = g_type_class_ref(e_event_hook_get_type());
- type = g_type_register_static(e_event_hook_get_type(), "EMEventHook", &info, 0);
- }
-
- return type;
-}
diff --git a/mail/em-event.h b/mail/em-event.h
index 6b3618405f..6f1366ae5f 100644
--- a/mail/em-event.h
+++ b/mail/em-event.h
@@ -28,7 +28,6 @@
#include "e-util/e-event.h"
#include "composer/e-msg-composer.h"
-#include "mail/em-folder-browser.h"
G_BEGIN_DECLS
@@ -38,18 +37,12 @@ typedef struct _EMEventClass EMEventClass;
/* Current target description */
enum _em_event_target_t {
EM_EVENT_TARGET_FOLDER,
- EM_EVENT_TARGET_FOLDER_BROWSER,
EM_EVENT_TARGET_MESSAGE,
EM_EVENT_TARGET_COMPOSER,
EM_EVENT_TARGET_SEND_RECEIVE,
EM_EVENT_TARGET_CUSTOM_ICON
};
-/* Flags for FOLDER BROWSER Events*/
-enum {
- EM_EVENT_FOLDER_BROWSER = 1<< 0
-};
-
/* Flags that describe TARGET_FOLDER */
enum {
EM_EVENT_FOLDER_NEWMAIL = 1<< 0
@@ -104,14 +97,6 @@ struct _EMEventTargetComposer {
EMsgComposer *composer;
};
-typedef struct _EMEventTargetFolderBrowser EMEventTargetFolderBrowser;
-
-struct _EMEventTargetFolderBrowser {
- EEventTarget target;
-
- EMFolderBrowser *emfb;
-};
-
typedef struct _EMEventTargetSendReceive EMEventTargetSendReceive;
struct _EMEventTargetSendReceive {
@@ -150,28 +135,12 @@ GType em_event_get_type(void);
EMEvent *em_event_peek(void);
EMEventTargetFolder *em_event_target_new_folder(EMEvent *emp, const gchar *uri, guint32 flags);
-EMEventTargetFolderBrowser *em_event_target_new_folder_browser (EMEvent *eme, EMFolderBrowser *emfb);
EMEventTargetComposer *em_event_target_new_composer(EMEvent *emp, const EMsgComposer *composer, guint32 flags);
EMEventTargetMessage *em_event_target_new_message(EMEvent *emp, CamelFolder *folder, CamelMimeMessage *message, const gchar *uid, guint32 flags,
EMsgComposer *composer);
EMEventTargetSendReceive * em_event_target_new_send_receive(EMEvent *eme, GtkWidget *table, gpointer data, gint row, guint32 flags);
EMEventTargetCustomIcon * em_event_target_new_custom_icon(EMEvent *eme, GtkTreeStore *store, GtkTreeIter *iter, const gchar *uri, guint32 flags);
-/* ********************************************************************** */
-
-typedef struct _EMEventHook EMEventHook;
-typedef struct _EMEventHookClass EMEventHookClass;
-
-struct _EMEventHook {
- EEventHook hook;
-};
-
-struct _EMEventHookClass {
- EEventHookClass hook_class;
-};
-
-GType em_event_hook_get_type(void);
-
G_END_DECLS
#endif /* __EM_EVENT_H__ */
diff --git a/mail/em-filter-editor.c b/mail/em-filter-editor.c
index 8d720742c6..b782ca8cbf 100644
--- a/mail/em-filter-editor.c
+++ b/mail/em-filter-editor.c
@@ -29,68 +29,79 @@
#include <glib/gi18n.h>
#include "e-util/e-util-private.h"
+#include "e-util/gconf-bridge.h"
#include "em-filter-editor.h"
#include "em-filter-rule.h"
-#define d(x)
+static gpointer parent_class;
-static FilterRule *create_rule (RuleEditor *re);
-
-static void em_filter_editor_class_init (EMFilterEditorClass *klass);
-static void em_filter_editor_init (EMFilterEditor *fe);
-static void em_filter_editor_finalise (GObject *obj);
-
-static RuleEditorClass *parent_class = NULL;
-
-GType
-em_filter_editor_get_type (void)
+static FilterRule *
+filter_editor_create_rule (RuleEditor *rule_editor)
{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFilterEditorClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_filter_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFilterEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_filter_editor_init,
- };
+ FilterRule *rule = filter_rule_new ();
+ FilterPart *part;
- type = g_type_register_static (RULE_TYPE_EDITOR, "EMFilterEditor", &info, 0);
- }
+ /* create a rule with 1 part & 1 action in it */
+ rule = (FilterRule *)em_filter_rule_new ();
+ part = rule_context_next_part (rule_editor->context, NULL);
+ filter_rule_add_part (rule, filter_part_clone (part));
+ part = em_filter_context_next_action (
+ (EMFilterContext *)rule_editor->context, NULL);
+ em_filter_rule_add_action (
+ (EMFilterRule *)rule, filter_part_clone (part));
- return type;
+ return rule;
}
static void
-em_filter_editor_class_init (EMFilterEditorClass *klass)
+filter_editor_class_init (EMFilterEditorClass *class)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- RuleEditorClass *re_class = (RuleEditorClass *) klass;
-
- parent_class = g_type_class_ref (rule_editor_get_type ());
+ RuleEditorClass *rule_editor_class;
- gobject_class->finalize = em_filter_editor_finalise;
+ parent_class = g_type_class_peek_parent (class);
- /* override methods */
- re_class->create_rule = create_rule;
+ rule_editor_class = RULE_EDITOR_CLASS (class);
+ rule_editor_class->create_rule = filter_editor_create_rule;
}
static void
-em_filter_editor_init (EMFilterEditor *fe)
+filter_editor_init (EMFilterEditor *filter_editor)
{
- ;
+ GConfBridge *bridge;
+ const gchar *key_prefix;
+
+ bridge = gconf_bridge_get ();
+ key_prefix = "/apps/evolution/mail/filter_editor";
+
+ gconf_bridge_bind_window_size (
+ bridge, key_prefix, GTK_WINDOW (filter_editor));
}
-static void
-em_filter_editor_finalise (GObject *obj)
+GType
+em_filter_editor_get_type (void)
{
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFilterEditorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) filter_editor_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFilterEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) filter_editor_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ RULE_TYPE_EDITOR, "EMFilterEditor", &type_info, 0);
+ }
+
+ return type;
}
/**
@@ -101,15 +112,17 @@ em_filter_editor_finalise (GObject *obj)
* Return value: A new #EMFilterEditor object.
**/
EMFilterEditor *
-em_filter_editor_new (EMFilterContext *fc, const EMFilterSource *source_names)
+em_filter_editor_new (EMFilterContext *fc,
+ const EMFilterSource *source_names)
{
- EMFilterEditor *fe = (EMFilterEditor *) g_object_new (em_filter_editor_get_type(), NULL);
+ EMFilterEditor *fe;
GladeXML *gui;
gchar *gladefile;
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "filter.glade",
- NULL);
+ fe = g_object_new (EM_TYPE_FILTER_EDITOR, NULL);
+
+ gladefile = g_build_filename (
+ EVOLUTION_GLADEDIR, "filter.glade", NULL);
gui = glade_xml_new (gladefile, "rule_editor", NULL);
g_free (gladefile);
@@ -149,7 +162,10 @@ select_source (GtkComboBox *combobox, EMFilterEditor *fe)
}
void
-em_filter_editor_construct (EMFilterEditor *fe, EMFilterContext *fc, GladeXML *gui, const EMFilterSource *source_names)
+em_filter_editor_construct (EMFilterEditor *fe,
+ EMFilterContext *fc,
+ GladeXML *gui,
+ const EMFilterSource *source_names)
{
GtkWidget *combobox;
gint i;
@@ -175,19 +191,3 @@ em_filter_editor_construct (EMFilterEditor *fe, EMFilterContext *fc, GladeXML *g
column = gtk_tree_view_get_column (GTK_TREE_VIEW (RULE_EDITOR (fe)->list), 0);
gtk_tree_view_column_set_visible (column, TRUE);
}
-
-static FilterRule *
-create_rule (RuleEditor *re)
-{
- FilterRule *rule = filter_rule_new ();
- FilterPart *part;
-
- /* create a rule with 1 part & 1 action in it */
- rule = (FilterRule *)em_filter_rule_new ();
- part = rule_context_next_part (re->context, NULL);
- filter_rule_add_part (rule, filter_part_clone (part));
- part = em_filter_context_next_action ((EMFilterContext *)re->context, NULL);
- em_filter_rule_add_action ((EMFilterRule *)rule, filter_part_clone (part));
-
- return rule;
-}
diff --git a/mail/em-filter-editor.h b/mail/em-filter-editor.h
index 8d9926b873..c725fd97b5 100644
--- a/mail/em-filter-editor.h
+++ b/mail/em-filter-editor.h
@@ -22,17 +22,32 @@
*
*/
-#ifndef _EM_FILTER_EDITOR_H
-#define _EM_FILTER_EDITOR_H
+#ifndef EM_FILTER_EDITOR_H
+#define EM_FILTER_EDITOR_H
#include "filter/rule-editor.h"
#include "em-filter-context.h"
-#define EM_FILTER_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), em_filter_editor_get_type(), EMFilterEditor))
-#define EM_FILTER_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), em_filter_editor_get_type(), EMFilterEditorClass))
-#define EM_IS_FILTER_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), em_filter_editor_get_type()))
-#define EM_IS_FILTER_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), em_filter_editor_get_type()))
-#define EM_FILTER_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), em_filter_editor_get_type(), EMFilterEditorClass))
+/* Standard GObject macros */
+#define EM_TYPE_FILTER_EDITOR \
+ (em_filter_editor_get_type ())
+#define EM_FILTER_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FILTER_EDITOR, EMFilterEditor))
+#define EM_FILTER_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FILTER_EDITOR, EMFilterEditorClass))
+#define EM_IS_FILTER_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FILTER_EDITOR))
+#define EM_IS_FILTER_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_FILTER_EDITOR))
+#define EM_FILTER_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FILTER_EDITOR, EMFilterEditorClass))
+
+G_BEGIN_DECLS
typedef struct _EMFilterEditor EMFilterEditor;
typedef struct _EMFilterEditorClass EMFilterEditorClass;
@@ -45,16 +60,19 @@ struct _EMFilterSource {
};
struct _EMFilterEditor {
- RuleEditor parent_object;
+ RuleEditor parent;
};
struct _EMFilterEditorClass {
RuleEditorClass parent_class;
};
-GType em_filter_editor_get_type (void);
-
-EMFilterEditor *em_filter_editor_new (EMFilterContext *f, const EMFilterSource *source_names);
-void em_filter_editor_construct (EMFilterEditor *fe, EMFilterContext *fc, GladeXML *gui, const EMFilterSource *source_names);
+GType em_filter_editor_get_type (void);
+EMFilterEditor *em_filter_editor_new (EMFilterContext *f,
+ const EMFilterSource *source_names);
+void em_filter_editor_construct (EMFilterEditor *fe,
+ EMFilterContext *fc,
+ GladeXML *gui,
+ const EMFilterSource *source_names);
-#endif /* ! _EM_FILTER_EDITOR_H */
+#endif /* EM_FILTER_EDITOR_H */
diff --git a/mail/em-filter-folder-element.c b/mail/em-filter-folder-element.c
index 9c87c166c9..4af699d583 100644
--- a/mail/em-filter-folder-element.c
+++ b/mail/em-filter-folder-element.c
@@ -33,7 +33,6 @@
#include "em-filter-folder-element.h"
#include "mail/em-folder-selection-button.h"
-#include "mail/mail-component.h"
#include "mail/em-utils.h"
#include "libedataserver/e-sexp.h"
#include "e-util/e-error.h"
@@ -255,8 +254,11 @@ get_widget(FilterElement *fe)
uri = ff->uri;
else
uri = em_uri_to_camel (ff->uri);
- button = em_folder_selection_button_new(_("Select Folder"), NULL);
- em_folder_selection_button_set_selection(EM_FOLDER_SELECTION_BUTTON(button), uri);
+
+ button = em_folder_selection_button_new (_("Select Folder"), NULL);
+
+ em_folder_selection_button_set_selection(
+ EM_FOLDER_SELECTION_BUTTON (button), uri);
if (!ff->store_camel_uri)
g_free(uri);
diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c
index 7a116e9ea5..8156c4fd32 100644
--- a/mail/em-folder-browser.c
+++ b/mail/em-folder-browser.c
@@ -58,13 +58,6 @@
#include <camel/camel-vee-store.h>
#include <camel/camel-operation.h>
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <bonobo/bonobo-ui-util.h>
-
/* for efilterbar stuff */
#include <libedataserver/e-sexp.h>
#include "mail-vfolder.h"
@@ -149,7 +142,6 @@ static void emfb_search_menu_activated(ESearchBar *esb, gint id, EMFolderBrowser
static void emfb_search_search_activated(ESearchBar *esb, EMFolderBrowser *emfb);
static void emfb_search_search_cleared(ESearchBar *esb);
-static gint emfb_list_key_press(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *ev, EMFolderBrowser *emfb);
static void emfb_list_message_selected (MessageList *ml, const gchar *uid, EMFolderBrowser *emfb);
static void emfb_expand_all_threads(BonoboUIComponent *uid, gpointer data, const gchar *path);
@@ -214,27 +206,6 @@ enum {
/* label IDs are set above this number */
#define VIEW_ITEMS_MASK 63
-/* Options for View */
-static EMFBSearchBarItem emfb_view_items[] = {
- {{ (gchar *) N_("All Messages"), VIEW_ALL_MESSAGES, 0 }, NULL},
- {{ (gchar *) N_("Unread Messages"), VIEW_UNREAD_MESSAGES, 0 }, "mail-unread"},
- {{ NULL, 0, 0 }, NULL},
- {{ (gchar *) N_("No Label"),VIEW_NO_LABEL, 0 }, NULL},
- {{ NULL, -1, 0 }, NULL}
-};
-
-/* TODO: Following options should be customizable */
-static EMFBSearchBarItem temp_view_items[] = {
- {{ NULL, 0, 0 }, NULL},
- {{ (gchar *) N_("Read Messages"), VIEW_READ_MESSAGES, 0 }, "mail-read"},
- {{ (gchar *) N_("Recent Messages"), VIEW_RECENT_MESSAGES, 0 }, NULL},
- {{ (gchar *) N_("Last 5 Days' Messages"), VIEW_LAST_FIVE_DAYS, 0 }, NULL},
- {{ (gchar *) N_("Messages with Attachments"), VIEW_WITH_ATTACHMENTS, 0 }, "mail-attachment"},
- {{ (gchar *) N_("Important Messages"), VIEW_MESSAGES_MARKED_AS_IMPORTANT, 0}, "emblem-important"},
- {{ (gchar *) N_("Messages Not Junk"), VIEW_NOT_JUNK, 0 }, "mail-mark-notjunk"},
- {{ NULL, -1, 0 }, NULL}
-};
-
static ESearchBarItem emfb_search_scope_items[] = {
E_FILTERBAR_CURRENT_FOLDER,
E_FILTERBAR_CURRENT_ACCOUNT,
@@ -244,239 +215,25 @@ static ESearchBarItem emfb_search_scope_items[] = {
static EMFolderViewClass *emfb_parent;
-/* Needed since the paned wont take the position its given otherwise ... */
-static void
-emfb_pane_realised(GtkWidget *w, EMFolderBrowser *emfb)
-{
- GConfClient *gconf;
-
- gconf = mail_config_get_gconf_client ();
-
- if (emfb->priv->show_wide)
- gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int(gconf, "/apps/evolution/mail/display/hpaned_size", NULL));
- else
- gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int(gconf, "/apps/evolution/mail/display/paned_size", NULL));
-}
-
-static gboolean
-emfb_pane_button_release_event(GtkWidget *w, GdkEventButton *e, EMFolderBrowser *emfb)
-{
- GConfClient *gconf = mail_config_get_gconf_client ();
-
- if (GTK_WIDGET_REALIZED (w)) {
- if (emfb->priv->show_wide)
- gconf_client_set_int(gconf, "/apps/evolution/mail/display/hpaned_size",
- gtk_paned_get_position(GTK_PANED(w)), NULL);
- else
- gconf_client_set_int(gconf, "/apps/evolution/mail/display/paned_size",
- gtk_paned_get_position(GTK_PANED(w)), NULL);
-
- }
-
- return FALSE;
-}
-
-static void
-free_one_ui_file (gpointer data,
- gpointer user_data)
-{
- g_free (data);
-}
-
-static GtkWidget *
-generate_viewoption_menu (GtkWidget *emfv)
-{
- GtkWidget *menu, *menu_item;
- gint i = 0;
- GSList *l;
-
- menu = gtk_menu_new ();
-
- for (i = 0; emfb_view_items[i].search.id != -1; ++i) {
- if (emfb_view_items[i].search.text) {
- gchar *str;
-
- str = e_str_without_underscores (_(emfb_view_items[i].search.text));
- menu_item = gtk_image_menu_item_new_with_label (str);
- if (emfb_view_items[i].image) {
- GtkWidget *image;
-
- image = gtk_image_new_from_icon_name (
- emfb_view_items[i].image,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (
- GTK_IMAGE_MENU_ITEM (menu_item),
- image);
- }
- g_free (str);
- } else {
- menu_item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
-
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (emfb_view_items[i].search.id));
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
-
- /* Add the labels */
- for (l = mail_config_get_labels (), i = 0; l; l = l->next, i++) {
- EUtilLabel *label = l->data;
- if (label->name && *(label->name)) {
- gchar *str;
- GdkPixmap *pixmap;
- GdkColor colour;
- GdkGC *gc;
- GtkWidget *image;
-
- gdk_color_parse(label->colour, &colour);
- gdk_colormap_alloc_color(gdk_colormap_get_system(), &colour, FALSE, TRUE);
-
- pixmap = gdk_pixmap_new(((GtkWidget *)emfv)->window, 16, 16, -1);
- gc = gdk_gc_new(((GtkWidget *)emfv)->window);
- gdk_gc_set_foreground(gc, &colour);
- gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, 16, 16);
- g_object_unref(gc);
-
- image = gtk_image_new_from_pixmap(pixmap, NULL);
- str = e_str_without_underscores (label->name);
- menu_item = gtk_image_menu_item_new_with_label (str);
- g_free (str);
- gtk_image_menu_item_set_image ((GtkImageMenuItem *)menu_item, image);
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (VIEW_LABEL + (VIEW_ITEMS_MASK + 1) * i));
-
- g_object_set_data_full (G_OBJECT (menu_item), "LabelTag",
- g_strdup (strncmp (label->tag, "$Label", 6) == 0 ? label->tag + 6 : label->tag),
- g_free);
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
- }
-
- for (i = 0; temp_view_items[i].search.id != -1; ++i) {
- if (temp_view_items[i].search.text) {
- gchar *str;
- str = e_str_without_underscores (_(temp_view_items[i].search.text));
- menu_item = gtk_image_menu_item_new_with_label (str);
- if (temp_view_items[i].image) {
- GtkWidget *image;
-
- image = gtk_image_new_from_icon_name (
- temp_view_items[i].image,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (
- GTK_IMAGE_MENU_ITEM (menu_item),
- image);
- }
- g_free (str);
- } else {
- menu_item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
-
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (temp_view_items[i].search.id));
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
-
- return menu;
-}
-
-#if 0
-static GArray *
-viewoption_menu_generator ()
-{
- GArray *menu = g_array_new (FALSE, FALSE, sizeof (ESearchBarItem));
- gint i = 0;
- ESearchBarItem dup_item;
- GSList *l;
-
- for (i = 0; emfb_view_items[i].search.id != -1; i++)
- g_array_append_vals (menu, &emfb_view_items[i], 1);
-
- for (l = mail_config_get_labels (); l; l = l->next) {
- ESearchBarItem item;
- EUtilLabel *label = l->data;
-
- item.text = label->name;
- item.id = VIEW_LABEL;
-
- g_array_append_vals (menu, &item, 1);
- }
-
- dup_item.id = -1;
- dup_item.text = NULL;
- g_array_append_vals (menu, &dup_item, 1);
-
- return menu;
-}
-#endif
-
-static void
-emfb_realize (GtkWidget *widget)
-{
- GtkWidget *menu;
- EMFolderBrowser *emfb = (EMFolderBrowser *)widget;
- gint id;
-
- menu = generate_viewoption_menu (widget);
- id = e_search_bar_get_viewitem_id (E_SEARCH_BAR (emfb->search));
-
- e_search_bar_set_viewoption_menu (E_SEARCH_BAR (emfb->search), menu);
-
- /* restore last selected ID, if any */
- if (id != -1)
- e_search_bar_set_viewitem_id (E_SEARCH_BAR (emfb->search), id);
-}
-
-static void
-html_scroll (GtkHTML *html,
- GtkOrientation orientation,
- GtkScrollType scroll_type,
- gfloat position,
- EMFolderBrowser *emfb)
-
-{
- if (html->binding_handled || orientation != GTK_ORIENTATION_VERTICAL || !mail_config_get_enable_magic_spacebar ())
- return;
-
- if (scroll_type == GTK_SCROLL_PAGE_FORWARD) {
- gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
- message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
- } else if (scroll_type == GTK_SCROLL_PAGE_BACKWARD) {
- gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
- message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
- }
-}
-
-static gboolean
-labels_changed_idle_cb (gpointer user_data)
-{
- EMFolderBrowser *emfb = (EMFolderBrowser*) user_data;
-
- emfb_realize (GTK_WIDGET (emfb));
-
- emfb->priv->labels_change_idle_id = 0;
-
- return FALSE;
-}
-
-static void
-gconf_labels_changed (GConfClient *client, guint cnxn_id,
- GConfEntry *entry, gpointer user_data)
-{
- EMFolderBrowser *emfb = (EMFolderBrowser*) user_data;
-
- /* regenerate menu option whenever something changed in labels */
- if (emfb && !emfb->priv->labels_change_idle_id)
- emfb->priv->labels_change_idle_id = g_idle_add (labels_changed_idle_cb, emfb);
-}
+//static void
+//html_scroll (GtkHTML *html,
+// GtkOrientation orientation,
+// GtkScrollType scroll_type,
+// gfloat position,
+// EMFolderBrowser *emfb)
+//
+//{
+// if (html->binding_handled || orientation != GTK_ORIENTATION_VERTICAL || !mail_config_get_enable_magic_spacebar ())
+// return;
+//
+// if (scroll_type == GTK_SCROLL_PAGE_FORWARD) {
+// gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
+// message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
+// } else if (scroll_type == GTK_SCROLL_PAGE_BACKWARD) {
+// gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
+// message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
+// }
+//}
static void
emfb_init(GObject *o)
@@ -494,82 +251,80 @@ emfb_init(GObject *o)
emfb->view.preview_active = TRUE;
emfb->view.list_active = TRUE;
- g_signal_connect_after (((EMFormatHTML *)(emfb->view.preview))->html, "scroll", G_CALLBACK (html_scroll), emfb);
+// g_signal_connect_after (((EMFormatHTML *)(emfb->view.preview))->html, "scroll", G_CALLBACK (html_scroll), emfb);
- g_slist_foreach (emfb->view.ui_files, free_one_ui_file, NULL);
- g_slist_free(emfb->view.ui_files);
+// g_slist_foreach (emfb->view.ui_files, free_one_ui_file, NULL);
+// g_slist_free(emfb->view.ui_files);
- emfb->view.ui_files = g_slist_append(NULL,
- g_build_filename (EVOLUTION_UIDIR,
- "evolution-mail-global.xml",
- NULL));
- emfb->view.ui_files = g_slist_append(emfb->view.ui_files,
- g_build_filename (EVOLUTION_UIDIR,
- "evolution-mail-list.xml",
- NULL));
- emfb->view.ui_files = g_slist_append(emfb->view.ui_files,
- g_build_filename (EVOLUTION_UIDIR,
- "evolution-mail-message.xml",
- NULL));
+// emfb->view.ui_files = g_slist_append(NULL,
+// g_build_filename (EVOLUTION_UIDIR,
+// "evolution-mail-global.xml",
+// NULL));
+// emfb->view.ui_files = g_slist_append(emfb->view.ui_files,
+// g_build_filename (EVOLUTION_UIDIR,
+// "evolution-mail-list.xml",
+// NULL));
+// emfb->view.ui_files = g_slist_append(emfb->view.ui_files,
+// g_build_filename (EVOLUTION_UIDIR,
+// "evolution-mail-message.xml",
+// NULL));
emfb->view.enable_map = g_slist_prepend(emfb->view.enable_map, (gpointer)emfb_enable_map);
- if (search_context) {
- const gchar *systemrules = g_object_get_data (G_OBJECT (search_context), "system");
- const gchar *userrules = g_object_get_data (G_OBJECT (search_context), "user");
- EFilterBar *efb;
- GConfClient *gconf;
-
- emfb->search = e_filter_bar_new(search_context, systemrules, userrules, emfb_search_config_search, emfb);
- efb = (EFilterBar *)emfb->search;
- efb->account_search_vf = NULL;
- efb->all_account_search_vf = NULL;
- efb->account_search_cancel = NULL;
- e_search_bar_set_menu ((ESearchBar *)emfb->search, emfb_search_items);
- e_search_bar_set_scopeoption ((ESearchBar *)emfb->search, emfb_search_scope_items);
- emfb->priv->scope_restricted = TRUE;
- g_signal_connect(emfb, "realize", G_CALLBACK(emfb_realize), NULL);
- gtk_widget_show((GtkWidget *)emfb->search);
-
- p->search_menu_activated_id = g_signal_connect(emfb->search, "menu_activated", G_CALLBACK(emfb_search_menu_activated), emfb);
- p->search_activated_id = g_signal_connect(emfb->search, "search_activated", G_CALLBACK(emfb_search_search_activated), emfb);
- g_signal_connect(emfb->search, "search_cleared", G_CALLBACK(emfb_search_search_cleared), NULL);
-
- gtk_box_pack_start((GtkBox *)emfb, (GtkWidget *)emfb->search, FALSE, TRUE, 0);
-
- gconf = mail_config_get_gconf_client ();
- emfb->priv->labels_change_notify_id = gconf_client_notify_add (gconf, E_UTIL_LABELS_GCONF_KEY, gconf_labels_changed, emfb, NULL, NULL);
- }
-
- emfb->priv->show_wide = gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/display/show_wide", NULL);
- emfb->vpane = emfb->priv->show_wide?gtk_hpaned_new():gtk_vpaned_new();
-
- g_signal_connect(emfb->vpane, "realize", G_CALLBACK(emfb_pane_realised), emfb);
- emfb->priv->vpane_resize_id = g_signal_connect(emfb->vpane, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb);
-
- gtk_widget_show(emfb->vpane);
-
- gtk_box_pack_start((GtkBox *)emfb, emfb->vpane, TRUE, TRUE, 0);
-
- gtk_paned_pack1 (GTK_PANED (emfb->vpane), GTK_WIDGET (emfb->view.list), FALSE, FALSE);
- gtk_widget_show((GtkWidget *)emfb->view.list);
-
- /* currently: just use a scrolledwindow for preview widget */
- p->scroll = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy((GtkScrolledWindow *)p->scroll, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *)p->scroll, GTK_SHADOW_IN);
- gtk_widget_show(p->scroll);
-
- html = GTK_WIDGET (emfb->view.preview->formathtml.html);
-
- p->preview = gtk_vbox_new (FALSE, 1);
- p->search_bar = e_mail_search_bar_new (GTK_HTML (html));
- gtk_container_add((GtkContainer *)p->scroll, html);
- gtk_widget_show(html);
- gtk_box_pack_start ((GtkBox *)p->preview, p->scroll, TRUE, TRUE, 0);
- gtk_box_pack_start ((GtkBox *)p->preview, p->search_bar, FALSE, FALSE, 0);
- gtk_paned_pack2 (GTK_PANED (emfb->vpane), p->preview, TRUE, FALSE);
- gtk_widget_show(p->preview);
+// if (search_context) {
+// const gchar *systemrules = g_object_get_data (G_OBJECT (search_context), "system");
+// const gchar *userrules = g_object_get_data (G_OBJECT (search_context), "user");
+// EFilterBar *efb;
+// GConfClient *gconf;
+//
+// emfb->search = e_filter_bar_new(search_context, systemrules, userrules, emfb_search_config_search, emfb);
+// efb = (EFilterBar *)emfb->search;
+// efb->account_search_vf = NULL;
+// efb->all_account_search_vf = NULL;
+// efb->account_search_cancel = NULL;
+// e_search_bar_set_menu ((ESearchBar *)emfb->search, emfb_search_items);
+// e_search_bar_set_scopeoption ((ESearchBar *)emfb->search, emfb_search_scope_items);
+// e_search_bar_scope_enable ((ESearchBar *)emfb->search, E_FILTERBAR_CURRENT_MESSAGE_ID, FALSE);
+// emfb->priv->scope_restricted = TRUE;
+// g_signal_connect(emfb, "realize", G_CALLBACK(emfb_realize), NULL);
+// gtk_widget_show((GtkWidget *)emfb->search);
+//
+// p->search_menu_activated_id = g_signal_connect(emfb->search, "menu_activated", G_CALLBACK(emfb_search_menu_activated), emfb);
+// p->search_activated_id = g_signal_connect(emfb->search, "search_activated", G_CALLBACK(emfb_search_search_activated), emfb);
+// g_signal_connect(emfb->search, "search_cleared", G_CALLBACK(emfb_search_search_cleared), NULL);
+//
+// gtk_box_pack_start((GtkBox *)emfb, (GtkWidget *)emfb->search, FALSE, TRUE, 0);
+//
+// gconf = mail_config_get_gconf_client ();
+// emfb->priv->labels_change_notify_id = gconf_client_notify_add (gconf, E_UTIL_LABELS_GCONF_KEY, gconf_labels_changed, emfb, NULL, NULL);
+// }
+//
+// emfb->priv->show_wide = gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/display/show_wide", NULL);
+// emfb->vpane = emfb->priv->show_wide?gtk_hpaned_new():gtk_vpaned_new();
+//
+// g_signal_connect(emfb->vpane, "realize", G_CALLBACK(emfb_pane_realised), emfb);
+// emfb->priv->vpane_resize_id = g_signal_connect(emfb->vpane, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb);
+//
+// gtk_widget_show(emfb->vpane);
+//
+// gtk_box_pack_start_defaults((GtkBox *)emfb, emfb->vpane);
+//
+// gtk_paned_pack1 (GTK_PANED (emfb->vpane), GTK_WIDGET (emfb->view.list), FALSE, FALSE);
+// gtk_widget_show((GtkWidget *)emfb->view.list);
+//
+// /* currently: just use a scrolledwindow for preview widget */
+// p->scroll = gtk_scrolled_window_new(NULL, NULL);
+// gtk_scrolled_window_set_policy((GtkScrolledWindow *)p->scroll, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+// gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *)p->scroll, GTK_SHADOW_IN);
+// gtk_widget_show(p->scroll);
+//
+// p->preview = gtk_vbox_new (FALSE, 6);
+// gtk_container_add((GtkContainer *)p->scroll, (GtkWidget *)emfb->view.preview->formathtml.html);
+// gtk_widget_show((GtkWidget *)emfb->view.preview->formathtml.html);
+// gtk_box_pack_start ((GtkBox *)p->preview, p->scroll, TRUE, TRUE, 0);
+// gtk_box_pack_start ((GtkBox *)p->preview, em_format_html_get_search_dialog (emfb->view.preview), FALSE, FALSE, 0);
+// gtk_paned_pack2 (GTK_PANED (emfb->vpane), p->preview, TRUE, FALSE);
+// gtk_widget_show(p->preview);
g_signal_connect_swapped (
p->search_bar, "changed",
@@ -586,23 +341,11 @@ emfb_init(GObject *o)
e_event_emit((EEvent *)eme, "emfb.created", (EEventTarget *)target);
- g_signal_connect (((EMFolderView *) emfb)->list->tree, "key_press", G_CALLBACK(emfb_list_key_press), emfb);
g_signal_connect (((EMFolderView *) emfb)->list, "message_selected", G_CALLBACK (emfb_list_message_selected), emfb);
}
static void
-emfb_finalise(GObject *o)
-{
- EMFolderBrowser *emfb = (EMFolderBrowser *)o;
-
- g_free (emfb->priv->select_uid);
- g_free (emfb->priv);
-
- ((GObjectClass *)emfb_parent)->finalize(o);
-}
-
-static void
emfb_destroy(GtkObject *o)
{
EMFolderBrowser *emfb = (EMFolderBrowser *)o;
@@ -622,8 +365,8 @@ emfb_destroy(GtkObject *o)
emfb->priv->idle_scroll_id = 0;
}
- if (emfb->view.folder && emfb->priv->folder_changed_id)
- camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
+// if (emfb->view.folder && emfb->priv->folder_changed_id)
+// camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
if (emfb->priv->labels_change_notify_id) {
GConfClient *gconf = mail_config_get_gconf_client ();
@@ -643,83 +386,6 @@ emfb_destroy(GtkObject *o)
((GtkObjectClass *)emfb_parent)->destroy(o);
}
-static void
-emfb_show_search_bar (EMFolderView *folder_view)
-{
- EMFolderBrowser *browser = (EMFolderBrowser *) folder_view;
-
- gtk_widget_show (browser->priv->search_bar);
-}
-
-static void
-emfb_class_init(GObjectClass *klass)
-{
- klass->finalize = emfb_finalise;
-
- folder_browser_signals[ACCOUNT_SEARCH_ACTIVATED] =
- g_signal_new ("account_search_activated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFolderBrowserClass, account_search_activated),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- folder_browser_signals[ACCOUNT_SEARCH_CLEARED] =
- g_signal_new ("account_search_cleared",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFolderBrowserClass, account_search_cleared),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- ((GtkObjectClass *)klass)->destroy = emfb_destroy;
- ((EMFolderViewClass *)klass)->set_folder = emfb_set_folder;
- ((EMFolderViewClass *)klass)->activate = emfb_activate;
- ((EMFolderViewClass *)klass)->show_search_bar = emfb_show_search_bar;
-}
-
-GType
-em_folder_browser_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFolderBrowserClass),
- NULL, NULL,
- (GClassInitFunc)emfb_class_init,
- NULL, NULL,
- sizeof(EMFolderBrowser), 0,
- (GInstanceInitFunc)emfb_init
- };
- emfb_parent = g_type_class_ref(em_folder_view_get_type());
- type = g_type_register_static(em_folder_view_get_type(), "EMFolderBrowser", &info, 0);
- }
-
- return type;
-}
-
-GtkWidget *em_folder_browser_new(void)
-{
- EMFolderBrowser *emfb = g_object_new(em_folder_browser_get_type(), 0);
-
- /** @HookPoint-EMMenu: Main Mail Menu
- * @Id: org.gnome.evolution.mail.browser
- * @Class: org.gnome.evolution.mail.bonobomenu:1.0
- * @Target: EMMenuTargetSelect
- *
- * The main menu of mail view of the main application window.
- * If the folder is NULL (not selected), the target will be empty, not NULL.
- */
- ((EMFolderView *)emfb)->menu = em_menu_new("org.gnome.evolution.mail.browser");
-
- return (GtkWidget *)emfb;
-}
-
void em_folder_browser_show_preview(EMFolderBrowser *emfb, gboolean state)
{
if ((emfb->view.preview_active ^ state) == 0
@@ -775,42 +441,6 @@ gboolean em_folder_browser_get_wide (EMFolderBrowser *emfb)
return emfb->priv->show_wide;
}
-void em_folder_browser_show_wide(EMFolderBrowser *emfb, gboolean state)
-{
- GtkWidget *w;
- gint paned_size;
-
- if ((emfb->priv->show_wide && state)
- || emfb->view.list == NULL) {
- emfb->priv->show_wide = state;
- return;
- }
-
- emfb->priv->show_wide = state;
-
- w = emfb->priv->show_wide?gtk_hpaned_new():gtk_vpaned_new();
-
- g_signal_handler_disconnect(emfb->vpane, emfb->priv->vpane_resize_id);
- g_signal_connect(w, "realize", G_CALLBACK(emfb_pane_realised), emfb);
- emfb->priv->vpane_resize_id = g_signal_connect(w, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb);
-
- gtk_box_pack_start((GtkBox *)emfb, w, TRUE, TRUE, 0);
- gtk_widget_reparent((GtkWidget *)emfb->view.list, w);
- gtk_widget_reparent((GtkWidget *)emfb->priv->preview, w);
- gtk_widget_destroy(emfb->vpane);
- gtk_container_child_set (GTK_CONTAINER (w), GTK_WIDGET (emfb->view.list), "resize", FALSE, "shrink", FALSE, NULL);
- gtk_container_child_set (GTK_CONTAINER (w), GTK_WIDGET (emfb->priv->preview), "resize", TRUE, "shrink", FALSE, NULL);
- gtk_container_resize_children ((GtkContainer *)w);
- emfb->vpane = w;
- gtk_widget_show(w);
-
- paned_size = gconf_client_get_int(mail_config_get_gconf_client(), emfb->priv->show_wide ? "/apps/evolution/mail/display/hpaned_size":"/apps/evolution/mail/display/paned_size", NULL);
- gtk_paned_set_position (GTK_PANED (emfb->vpane), paned_size);
-
- if (((EMFolderView *)emfb)->folder)
- em_folder_view_setup_view_instance ((EMFolderView *) emfb);
-}
-
/* ********************************************************************** */
/* FIXME: Need to separate system rules from user ones */
@@ -848,164 +478,6 @@ emfb_search_menu_activated(ESearchBar *esb, gint id, EMFolderBrowser *emfb)
}
}
-static void
-emfb_search_config_search(EFilterBar *efb, FilterRule *rule, gint id, const gchar *query, gpointer data)
-{
- EMFolderBrowser *emfb = data;
- EMailSearchBar *search_bar;
- ESearchingTokenizer *tokenizer;
- GList *partl;
- struct _camel_search_words *words;
- gint i;
- GSList *strings = NULL;
-
- /* we scan the parts of a rule, and set all the types we know about to the query string */
- partl = rule->parts;
- while (partl) {
- FilterPart *part = partl->data;
-
- if (!strcmp(part->name, "subject")) {
- FilterInput *input = (FilterInput *)filter_part_find_element(part, "subject");
- if (input)
- filter_input_set_value(input, query);
- } else if (!strcmp(part->name, "body")) {
- FilterInput *input = (FilterInput *)filter_part_find_element(part, "word");
- if (input)
- filter_input_set_value(input, query);
-
- words = camel_search_words_split((guchar *)query);
- for (i=0;i<words->len;i++)
- strings = g_slist_prepend(strings, g_strdup(words->words[i]->word));
- camel_search_words_free (words);
- } else if (!strcmp(part->name, "sender")) {
- FilterInput *input = (FilterInput *)filter_part_find_element(part, "sender");
- if (input)
- filter_input_set_value(input, query);
- } else if (!strcmp(part->name, "to")) {
- FilterInput *input = (FilterInput *)filter_part_find_element(part, "recipient");
- if (input)
- filter_input_set_value(input, query);
- }
-
- partl = partl->next;
- }
-
- search_bar = E_MAIL_SEARCH_BAR (emfb->priv->search_bar);
-
- /* XXX This is a hack, but this code is on its way out anyway.
- * Function is called once before the search bar is created. */
- if (!E_IS_MAIL_SEARCH_BAR (search_bar))
- return;
-
- tokenizer = e_mail_search_bar_get_tokenizer (search_bar);
-
- e_searching_tokenizer_set_secondary_case_sensitivity (tokenizer, FALSE);
- e_searching_tokenizer_set_secondary_search_string (tokenizer, NULL);
-
- while (strings != NULL) {
- e_searching_tokenizer_add_secondary_search_string (
- tokenizer, strings->data);
- g_free (strings->data);
- strings = g_slist_delete_link (strings, strings);
- }
-
- e_mail_search_bar_changed (search_bar);
-}
-
-static const gchar *
-get_view_query (ESearchBar *esb, CamelFolder *folder, const gchar *folder_uri)
-{
- const gchar *view_sexp = NULL;
- gint id;
- GtkWidget *menu_item;
- gchar *tag;
- gboolean duplicate = TRUE;
-
- /* Get the current selected view */
- id = e_search_bar_get_viewitem_id (esb);
- menu_item = e_search_bar_get_selected_viewitem (esb);
-
- switch (id & VIEW_ITEMS_MASK) {
- case VIEW_ALL_MESSAGES:
- /* one space indicates no filtering */
- view_sexp = " ";
- break;
-
- /* README: All the sexp below are not rocket science but it is not straightforward as well.
- I believe it is better to document the assumptions and the conventions followed for the sexp,
- before I forget so that no one else again needs to read through the code -- Sankar */
-
- case VIEW_UNREAD_MESSAGES:
- view_sexp = "(match-all (not (system-flag \"Seen\")))";
- break;
- case VIEW_READ_MESSAGES:
- view_sexp = "(match-all (system-flag \"Seen\" ))";
- break;
- case VIEW_RECENT_MESSAGES:
- if (!em_utils_folder_is_sent (folder, folder_uri))
- view_sexp = "(match-all (> (get-received-date) (- (get-current-date) 86400)))";
- else
- view_sexp = "(match-all (> (get-sent-date) (- (get-current-date) 86400)))";
- break;
- case VIEW_LAST_FIVE_DAYS:
- if (!em_utils_folder_is_sent (folder, folder_uri))
- view_sexp = " (match-all (> (get-received-date) (- (get-current-date) 432000)))";
- else
- view_sexp = " (match-all (> (get-sent-date) (- (get-current-date) 432000)))";
- break;
- case VIEW_WITH_ATTACHMENTS:
- view_sexp = "(match-all (system-flag \"Attachments\" ))";
- break;
- case VIEW_NOT_JUNK:
- view_sexp = "(match-all (not (system-flag \"junk\")))";
- break;
- case VIEW_NO_LABEL: {
- GSList *l;
- GString *s = g_string_new ("(and");
-
- for (l = mail_config_get_labels (); l; l = l->next) {
- EUtilLabel *label = (EUtilLabel *)l->data;
-
- if (label && label->tag) {
- const gchar *tag = label->tag;
-
- if (strncmp (tag, "$Label", 6) == 0)
- tag += 6;
-
- g_string_append_printf (s, " (match-all (not (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\") (user-flag \"%s\"))))", tag, tag, tag);
- /* FIXME: I dont see a way of mapping this kind of sexp into sql atm. I guess this option could be kicked out */
- /* May be we should copy what I did for system flags -- Sankar */
- }
- }
-
- g_string_append (s, ")");
-
- duplicate = FALSE;
- view_sexp = g_string_free (s, FALSE);
- } break;
- case VIEW_LABEL:
- tag = (gchar *)g_object_get_data (G_OBJECT (menu_item), "LabelTag");
- view_sexp = g_strdup_printf ("(match-all (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\") (user-flag \"%s\")))", tag, tag, tag);
- duplicate = FALSE;
- break;
- case VIEW_MESSAGES_MARKED_AS_IMPORTANT:
- view_sexp = "(match-all (system-flag \"Flagged\" ))";
- break;
- case VIEW_ANY_FIELD_CONTAINS:
- break;
-
- case VIEW_CUSTOMIZE:
- /* one space indicates no filtering, so here use two */
- view_sexp = " ";
- break;
- }
-
- if (duplicate)
- view_sexp = g_strdup (view_sexp);
-
- return view_sexp;
-}
-
struct _setup_msg {
MailMsg base;
@@ -1347,60 +819,6 @@ emfb_search_search_cleared(ESearchBar *esb)
/* ********************************************************************** */
-static gint
-emfb_list_key_press(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *ev, EMFolderBrowser *emfb)
-{
- gboolean state, folder_choose = TRUE;
- if ((ev->key.state & GDK_CONTROL_MASK) != 0)
- return FALSE;
-
- switch (ev->key.keyval) {
- case GDK_space:
- if (!emfb->view.preview->caret_mode && mail_config_get_enable_magic_spacebar ()) {
- state = gtk_html_command(((EMFormatHTML *)((EMFolderView *) emfb)->preview)->html, "scroll-forward");
- if (!state) {
- folder_choose = message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
- if (!folder_choose)
- folder_choose = message_list_select(((EMFolderView *) emfb)->list,
- MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
- }
-
- } else
- em_utils_adjustment_page(gtk_scrolled_window_get_vadjustment((GtkScrolledWindow *)emfb->priv->scroll), TRUE);
- break;
- case GDK_BackSpace:
- if (!emfb->view.preview->caret_mode && mail_config_get_enable_magic_spacebar ()) {
- state = gtk_html_command(((EMFormatHTML *)((EMFolderView *) emfb)->preview)->html, "scroll-backward");
- if (!state) {
- folder_choose = message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, CAMEL_MESSAGE_SEEN);
- if (!folder_choose)
- folder_choose = message_list_select(((EMFolderView *) emfb)->list,
- MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
- }
-
- } else
- em_utils_adjustment_page(gtk_scrolled_window_get_vadjustment((GtkScrolledWindow *)emfb->priv->scroll), FALSE);
- break;
- default:
- return FALSE;
- }
-
- if (!folder_choose && !emfb->view.preview->caret_mode && mail_config_get_enable_magic_spacebar ()) {
- /* check for unread messages. if yes .. rewindback to the folder */
- EMFolderTree *emft = g_object_get_data((GObject*)emfb, "foldertree");
- switch (ev->key.keyval) {
- case GDK_space:
- em_folder_tree_select_next_path (emft, TRUE);
- break;
- case GDK_BackSpace:
- em_folder_tree_select_prev_path (emft, TRUE);
- break;
- }
- gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
- }
- return TRUE;
-}
-
static void
emfb_list_message_selected (MessageList *ml, const gchar *uid, EMFolderBrowser *emfb)
{
@@ -1424,329 +842,6 @@ emfb_list_message_selected (MessageList *ml, const gchar *uid, EMFolderBrowser *
/* ********************************************************************** */
static void
-emfb_edit_cut(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- /* TODO: pity we can't sucblass this method, ugh, virtualise it? */
-
- if (GTK_WIDGET_HAS_FOCUS(((ESearchBar *)emfb->search)->entry))
- gtk_editable_cut_clipboard((GtkEditable *)((ESearchBar *)emfb->search)->entry);
- else if (GTK_WIDGET_HAS_FOCUS(emfb->view.preview->formathtml.html))
- em_format_html_display_cut(emfb->view.preview);
- else
- message_list_copy(emfb->view.list, TRUE);
-}
-
-static void
-emfb_edit_copy(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (GTK_WIDGET_HAS_FOCUS(((ESearchBar *)emfb->search)->entry))
- gtk_editable_copy_clipboard((GtkEditable *)((ESearchBar *)emfb->search)->entry);
- else if (GTK_WIDGET_HAS_FOCUS(emfb->view.preview->formathtml.html))
- em_format_html_display_copy(emfb->view.preview);
- else
- message_list_copy(emfb->view.list, FALSE);
-}
-
-static void
-emfb_edit_paste(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (GTK_WIDGET_HAS_FOCUS(((ESearchBar *)emfb->search)->entry))
- gtk_editable_paste_clipboard((GtkEditable *)((ESearchBar *)emfb->search)->entry);
- else
- message_list_paste(emfb->view.list);
-}
-
-static void
-emfb_edit_invert_selection(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_invert_selection(emfv->list);
-}
-
-static gboolean
-emfb_select_all_daemon (MessageList *ml)
-{
- message_list_select_all(ml);
- gtk_widget_grab_focus ((GtkWidget *)ml);
- return FALSE;
-}
-
-static void
-emfb_edit_select_all(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->list->threaded) {
-
- emfb_expand_all_threads (uid, data, path);
-
- /* The time out below is added so that the execution thread to
- expand all conversations threads would've completed.
-
- The timeout 505 is just to ensure that the value is a small delta
- more than the timeout value in expand_all_threads thread. */
-
- g_timeout_add (505, (GSourceFunc) emfb_select_all_daemon, emfv->list);
-
- } else {
- /* If there is no threading, just select-all immediately */
- emfb_select_all_daemon (emfv->list);
- }
-}
-
-static void
-emfb_edit_select_thread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select_thread(emfv->list);
-}
-
-static void
-emfb_edit_select_subthread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select_subthread (emfv->list);
-}
-
-static void
-emfb_folder_properties(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (emfb->view.folder_uri)
- em_folder_properties_show(NULL, emfb->view.folder, emfb->view.folder_uri);
-}
-
-/* VIEWTHREADED*/
-static void
-emfb_expand_all_threads(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_set_threaded_expand_all(emfv->list);
-
-}
-
-static void
-emfb_collapse_all_threads(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_set_threaded_collapse_all(emfv->list);
-}
-
-static void
-emfb_folder_copy(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
- CamelFolderInfo *fi = NULL;
- CamelException ex;
-
- /* FIXME: This function MUST become multi-threaded.
- FIXME: This interface should NOT use a folderinfo */
-
- camel_exception_init (&ex);
-
- if ((fi = camel_store_get_folder_info (emfb->view.folder->parent_store,
- emfb->view.folder->full_name,
- CAMEL_STORE_FOLDER_INFO_FAST,
- &ex)) != NULL)
- em_folder_utils_copy_folder(fi, FALSE);
-
- camel_exception_clear (&ex);
-
- return;
-}
-
-static void
-emfb_folder_move(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
- CamelFolderInfo *fi = NULL;
- CamelException ex;
-
- camel_exception_init (&ex);
-
- /* FIXME: This function MUST become multi-threaded.
- FIXME: This interface should NOT use a folderinfo */
-
- if ((fi = camel_store_get_folder_info (emfb->view.folder->parent_store,
- emfb->view.folder->full_name,
- CAMEL_STORE_FOLDER_INFO_FAST,
- &ex)) != NULL)
- em_folder_utils_copy_folder(fi, TRUE);
-
- camel_exception_clear (&ex);
-
- return;
-}
-
-static void
-emfb_folder_delete(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- em_folder_utils_delete_folder (emfb->view.folder);
-
- return;
-}
-
-static void
-emfb_folder_refresh(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
- EMFolderTree *tree = g_object_get_data (G_OBJECT (emfb), "foldertree");
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (tree)) != NULL) {
- EMEvent *e = em_event_peek();
- EMEventTargetFolder *t = em_event_target_new_folder(e, folder->full_name, 0);
- e_event_emit((EEvent *)e, "folder.refresh", (EEventTarget *)t);
- mail_refresh_folder(folder, NULL, NULL);
- }
-}
-
-static void
-emfb_folder_rename(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- em_folder_utils_rename_folder (emfb->view.folder);
-
- return;
-}
-
-static void
-emfb_folder_create(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
- CamelFolderInfo *fi = NULL;
- EMFolderTree *tree = g_object_get_data (G_OBJECT (emfb), "foldertree");
-
- /* FIXME: This function MUST be multithreaded
- FIXME: This interface should NOT use a folderinfo */
- if (emfb->view.folder) {
- if ((fi = em_folder_tree_get_selected_folder_info (tree)) != NULL) {
- em_folder_utils_create_folder (fi, tree, NULL);
- camel_folder_info_free(fi);
- }
- } else {
- em_folder_utils_create_folder (NULL, tree, NULL);
- }
-
- return;
-}
-
-static void
-emfb_folder_expunge(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (emfb->view.folder)
- em_utils_expunge_folder(gtk_widget_get_toplevel((GtkWidget *)emfb), emfb->view.folder);
-}
-
-static void
-emfb_mark_all_read(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- /* FIXME: make a 'mark messages' function? */
- EMFolderView *emfv = data;
- GPtrArray *uids;
- gint i;
-
- if (emfv->folder == NULL)
- return;
- if ( em_utils_prompt_user((GtkWindow *)emfv, "/apps/evolution/mail/prompts/mark_all_read","mail:ask-mark-all-read", NULL)) {
- uids = message_list_get_uids(emfv->list);
- camel_folder_freeze(emfv->folder);
- for (i=0;i<uids->len;i++)
- camel_folder_set_message_flags(emfv->folder, uids->pdata[i], CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
- camel_folder_thaw(emfv->folder);
- message_list_free_uids(emfv->list, uids);
- }
-}
-
-static void
-emfb_view_hide_read(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_hide_add(emfv->list, "(match-all (system-flag \"seen\"))", ML_HIDE_SAME, ML_HIDE_SAME);
-}
-
-static void
-emfb_view_hide_selected(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- /* TODO: perhaps this should sit directly on message_list? */
- /* is it worth it, it's so trivial */
-
- /* A new flag CAMEL_MESSAGE_HIDDEN is added by Sankar
- while extending the CAMEL_MESSAGE_FLAGS for proxy permissions.
- This can be used to hide messages. */
-
- uids = message_list_get_selected(emfv->list);
- message_list_hide_uids(emfv->list, uids);
- message_list_free_uids(emfv->list, uids);
-}
-
-static void
-emfb_view_show_all(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_hide_clear(emfv->list);
-}
-
-/* ********************************************************************** */
-
-static void
-emfb_mail_stop(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- mail_cancel_all();
-}
-
-static void
-emfb_tools_filters(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- em_utils_edit_filters ((GtkWidget *) emfb);
-}
-
-static void
-emfb_subscribe_editor_destroy(GtkWidget *w, EMFolderBrowser *emfb)
-{
- emfb->priv->subscribe_editor = NULL;
-}
-
-static void
-emfb_tools_subscriptions(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (emfb->priv->subscribe_editor) {
- gdk_window_show(emfb->priv->subscribe_editor->window);
- } else {
- emfb->priv->subscribe_editor = (GtkWidget *)em_subscribe_editor_new();
- e_dialog_set_transient_for ((GtkWindow *)emfb->priv->subscribe_editor, (GtkWidget *)emfb);
- g_signal_connect(emfb->priv->subscribe_editor, "destroy", G_CALLBACK(emfb_subscribe_editor_destroy), emfb);
- gtk_widget_show(emfb->priv->subscribe_editor);
- }
-}
-
-static void
emfb_focus_search(BonoboUIComponent *uid, gpointer data, const gchar *path)
{
EMFolderBrowser *emfb = data;
@@ -1760,46 +855,9 @@ emfb_help_debug (BonoboUIComponent *uid, gpointer data, const gchar *path)
mail_component_show_logger ((GtkWidget *) data);
}
-static void
-emfb_tools_vfolders(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- /* FIXME: rename/refactor this */
- vfolder_edit();
-}
-
static BonoboUIVerb emfb_verbs[] = {
- BONOBO_UI_UNSAFE_VERB ("EditCut", emfb_edit_cut),
- BONOBO_UI_UNSAFE_VERB ("EditCopy", emfb_edit_copy),
- BONOBO_UI_UNSAFE_VERB ("EditPaste", emfb_edit_paste),
-
- BONOBO_UI_UNSAFE_VERB ("EditInvertSelection", emfb_edit_invert_selection),
- BONOBO_UI_UNSAFE_VERB ("EditSelectAll", emfb_edit_select_all),
- BONOBO_UI_UNSAFE_VERB ("EditSelectThread", emfb_edit_select_thread),
- BONOBO_UI_UNSAFE_VERB ("EditSelectSubthread", emfb_edit_select_subthread),
- BONOBO_UI_UNSAFE_VERB ("ChangeFolderProperties", emfb_folder_properties),
- BONOBO_UI_UNSAFE_VERB ("FolderExpunge", emfb_folder_expunge),
- /* HideDeleted is a toggle */
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAllAsRead", emfb_mark_all_read),
- BONOBO_UI_UNSAFE_VERB ("ViewHideRead", emfb_view_hide_read),
- BONOBO_UI_UNSAFE_VERB ("ViewHideSelected", emfb_view_hide_selected),
- BONOBO_UI_UNSAFE_VERB ("ViewShowAll", emfb_view_show_all),
- /* ViewThreaded is a toggle */
-
- BONOBO_UI_UNSAFE_VERB ("ViewThreadsExpandAll", emfb_expand_all_threads),
- BONOBO_UI_UNSAFE_VERB ("ViewThreadsCollapseAll", emfb_collapse_all_threads),
-
- BONOBO_UI_UNSAFE_VERB ("FolderCopy", emfb_folder_copy),
- BONOBO_UI_UNSAFE_VERB ("FolderMove", emfb_folder_move),
- BONOBO_UI_UNSAFE_VERB ("FolderDelete", emfb_folder_delete),
- BONOBO_UI_UNSAFE_VERB ("FolderRefresh", emfb_folder_refresh),
- BONOBO_UI_UNSAFE_VERB ("FolderRename", emfb_folder_rename),
- BONOBO_UI_UNSAFE_VERB ("FolderCreate", emfb_folder_create),
BONOBO_UI_UNSAFE_VERB ("HelpDebug", emfb_help_debug),
- BONOBO_UI_UNSAFE_VERB ("MailStop", emfb_mail_stop),
- BONOBO_UI_UNSAFE_VERB ("ToolsFilters", emfb_tools_filters),
- BONOBO_UI_UNSAFE_VERB ("ToolsSubscriptions", emfb_tools_subscriptions),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolders", emfb_tools_vfolders),
BONOBO_UI_UNSAFE_VERB ("FocusSearch", emfb_focus_search),
/* ViewPreview is a toggle */
@@ -1807,227 +865,33 @@ static BonoboUIVerb emfb_verbs[] = {
BONOBO_UI_VERB_END
};
-static EPixmap emfb_pixmaps[] = {
- E_PIXMAP ("/commands/FolderCreate", "folder-new", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ChangeFolderProperties", "document-properties", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/FolderCopy", "folder-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/FolderMove", "folder-move", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAllAsRead", "mail-read", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP_END
-};
-
-static void
-emfb_hide_deleted(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_deleted", state[0] == '0', NULL);
- em_folder_view_set_hide_deleted(emfv, state[0] != '0');
-}
-
-static void
-emfb_view_threaded(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/thread_list", state[0] != '0', NULL);
-
- if (camel_object_meta_set(emfv->folder, "evolution:thread_list", state))
- camel_object_state_write(emfv->folder);
-
- /* FIXME: do set_threaded via meta-data listener on folder? */
- message_list_set_threaded(emfv->list, state[0] != '0');
-
- /* FIXME: update selection state? */
-}
-
-static void
-emfb_view_preview(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_preview", state[0] != '0', NULL);
-
- if (camel_object_meta_set(emfv->folder, "evolution:show_preview", state))
- camel_object_state_write(emfv->folder);
-
- /* FIXME: do this via folder listener */
- em_folder_browser_show_preview((EMFolderBrowser *)emfv, state[0] != '0');
-}
-
-static void
-emfb_show_next(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderBrowser *emfb = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_wide", state[0] != '0', NULL);
-
- em_folder_browser_show_wide(emfb, state[0] != '0');
-}
-
-static void
-emfb_show_below(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderBrowser *emfb = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_wide", state[0] == '0', NULL);
-
- em_folder_browser_show_wide(emfb, state[0] == '0');
-}
-
-static void
-emfb_list_scrolled (MessageList *ml, EMFolderBrowser *emfb)
-{
- EMFolderView *emfv = (EMFolderView *) emfb;
- double position;
- gchar *state;
-
- position = message_list_get_scrollbar_position (ml);
- state = g_strdup_printf ("%f", position);
-
- if (camel_object_meta_set (emfv->folder, "evolution:list_scroll_position", state))
- camel_object_state_write (emfv->folder);
-
- g_free (state);
-}
-
-static gboolean
-scroll_idle_cb (EMFolderBrowser *emfb)
-{
- EMFolderView *emfv = (EMFolderView *) emfb;
- double position;
- gchar *state;
-
- if ((state = camel_object_meta_get (emfv->folder, "evolution:list_scroll_position"))) {
- position = strtod (state, NULL);
- g_free (state);
- } else {
- position = emfb->priv->default_scroll_position;
- }
-
- message_list_set_scrollbar_position (emfv->list, position);
-
- emfb->priv->list_scrolled_id = g_signal_connect (emfv->list, "message_list_scrolled", G_CALLBACK (emfb_list_scrolled), emfb);
-
- emfb->priv->idle_scroll_id = 0;
-
- return FALSE;
-}
-
-static void
-emfb_gui_folder_changed(CamelFolder *folder, gpointer dummy, EMFolderBrowser *emfb)
-{
- if (emfb->priv->select_uid) {
- CamelMessageInfo *mi;
-
- mi = camel_folder_get_message_info(emfb->view.folder, emfb->priv->select_uid);
- if (mi) {
- /* because some sub-functions might free the pointer before it's done here */
- gchar *uid = g_strdup (emfb->priv->select_uid);
-
- camel_folder_free_message_info(emfb->view.folder, mi);
- em_folder_view_set_message (&emfb->view, uid, FALSE);
- g_free (uid);
- g_free (emfb->priv->select_uid);
- emfb->priv->select_uid = NULL;
- }
- }
-
- g_object_unref(emfb);
-}
-
-static void
-emfb_folder_changed(CamelFolder *folder, CamelFolderChangeInfo *changes, EMFolderBrowser *emfb)
-{
- g_object_ref(emfb);
- mail_async_event_emit(emfb->view.async, MAIL_ASYNC_GUI, (MailAsyncFunc)emfb_gui_folder_changed, folder, NULL, emfb);
-}
-
-static void
-emfb_etree_unfreeze (GtkWidget *widget, GdkEvent *event, EMFolderView *emfv)
-{
-
- ETableItem *item = e_tree_get_item (emfv->list->tree);
-
- g_object_set_data (G_OBJECT (((GnomeCanvasItem *) item)->canvas), "freeze-cursor", 0);
-}
-
-/* TODO: This should probably be handled by message-list, by storing/queueing
- up the select operation if its busy rebuilding the message-list */
-static void
-emfb_list_built (MessageList *ml, EMFolderBrowser *emfb)
-{
- EMFolderView *emfv = (EMFolderView *) emfb;
- double position = 0.0f;
-
- g_signal_handler_disconnect (ml, emfb->priv->list_built_id);
- emfb->priv->list_built_id = 0;
-
- if (emfv->list->cursor_uid == NULL) {
- if (emfb->priv->select_uid) {
- CamelMessageInfo *mi;
-
- /* If the message isn't in the folder yet, keep select_uid around, it could be caught by
- folder_changed, at some later date */
- mi = camel_folder_get_message_info(emfv->folder, emfb->priv->select_uid);
- if (mi) {
- camel_folder_free_message_info(emfv->folder, mi);
- em_folder_view_set_message(emfv, emfb->priv->select_uid, TRUE);
- g_free (emfb->priv->select_uid);
- emfb->priv->select_uid = NULL;
- }
-
- /* change the default to the current position */
- position = message_list_get_scrollbar_position (ml);
- } else {
- /* NOTE: not all users want this, so we need a preference for it perhaps? see bug #52887 */
- /* FIXME: if the 1st message in the list is unread, this will actually select the second unread msg */
- /*message_list_select (ml, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN, TRUE);*/
- }
- }
-
- emfb->priv->default_scroll_position = position;
-
- /* FIXME: this is a gross workaround for an etable bug that I can't fix - bug #55303 */
- /* this needs to be a lower priority than anything in e-table-item/e-canvas, since
- * e_canvas_item_region_show_relay() uses a timeout, we have to use a timeout of the
- * same interval but a lower priority. */
- emfb->priv->idle_scroll_id = g_timeout_add_full (G_PRIORITY_LOW, 250, (GSourceFunc) scroll_idle_cb, emfb, NULL);
- /* FIXME: This is another ugly hack done to hide a bug that above hack leaves. */
- g_signal_connect (((GtkScrolledWindow *) ml)->vscrollbar, "button-press-event", G_CALLBACK (emfb_etree_unfreeze), emfb);
-}
+//static gboolean
+//emfb_select_all_daemon (MessageList *ml)
+//{
+// message_list_select_all(ml);
+// gtk_widget_grab_focus ((GtkWidget *)ml);
+// return FALSE;
+//}
+
+//static void
+//emfb_hide_deleted(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
+//{
+// GConfClient *gconf;
+// EMFolderView *emfv = data;
+//
+// if (type != Bonobo_UIComponent_STATE_CHANGED)
+// return;
+//
+// gconf = mail_config_get_gconf_client ();
+// gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_deleted", state[0] == '0', NULL);
+// em_folder_view_set_hide_deleted(emfv, state[0] != '0');
+//}
static void
emfb_set_search_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
{
EMFolderBrowser *emfb = (EMFolderBrowser *) emfv;
- const gchar *state;
+ gchar *state;
message_list_freeze(emfv->list);
@@ -2041,10 +905,10 @@ emfb_set_search_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri
emfb->priv->idle_scroll_id = 0;
}
- if (emfb->view.folder) {
- camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
- emfb->priv->folder_changed_id = 0;
- }
+// if (emfb->view.folder) {
+// camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
+// emfb->priv->folder_changed_id = 0;
+// }
emfb_parent->set_folder(emfv, folder, uri);
@@ -2066,7 +930,7 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
struct _EMFolderBrowserPrivate *p = emfb->priv;
gboolean different_folder;
- message_list_freeze(emfv->list);
+// message_list_freeze(emfv->list);
if (emfb->priv->list_scrolled_id) {
g_signal_handler_disconnect (emfv->list, emfb->priv->list_scrolled_id);
@@ -2078,16 +942,16 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
emfb->priv->idle_scroll_id = 0;
}
- if (emfb->view.folder && emfb->priv->folder_changed_id) {
- camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
- emfb->priv->folder_changed_id = 0;
- }
-
- different_folder =
- emfb->view.folder != NULL &&
- folder != emfb->view.folder;
-
- emfb_parent->set_folder(emfv, folder, uri);
+// if (emfb->view.folder && emfb->priv->folder_changed_id) {
+// camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
+// emfb->priv->folder_changed_id = 0;
+// }
+//
+// different_folder =
+// emfb->view.folder != NULL &&
+// folder != emfb->view.folder;
+//
+// emfb_parent->set_folder(emfv, folder, uri);
/* This is required since we get activated the first time
before the folder is open and need to override the
@@ -2109,32 +973,32 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
gconf_client_set_bool (gconf, "/apps/evolution/mail/display/safe_list", FALSE, NULL);
}
- mail_refresh_folder(folder, NULL, NULL);
-
- emfb->priv->folder_changed_id = camel_object_hook_event(folder, "folder_changed",
- (CamelObjectEventHookFunc)emfb_folder_changed, emfb);
-
- /* FIXME: this mostly copied from activate() */
- if ((sstate = camel_object_meta_get(folder, "evolution:show_preview"))) {
- state = sstate[0] != '0';
- g_free(sstate);
- } else
- state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_preview", NULL);
- em_folder_browser_show_preview(emfb, state);
- if (emfv->uic)
- bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewPreview", "state", state?"1":"0", NULL);
-
- if ((sstate = camel_object_meta_get(folder, "evolution:thread_list"))) {
- state = sstate[0] != '0';
- g_free(sstate);
- } else
- state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/thread_list", NULL);
- message_list_set_threaded(emfv->list, state);
- if (emfv->uic) {
- bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreaded", "state", state?"1":"0", NULL);
- bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreadsCollapseAll", "sensitive", state?"1":"0", NULL);
- bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreadsExpandAll", "sensitive", state?"1":"0", NULL);
- }
+// mail_refresh_folder(folder, NULL, NULL);
+//
+// emfb->priv->folder_changed_id = camel_object_hook_event(folder, "folder_changed",
+// (CamelObjectEventHookFunc)emfb_folder_changed, emfb);
+//
+// /* FIXME: this mostly copied from activate() */
+// if ((sstate = camel_object_meta_get(folder, "evolution:show_preview"))) {
+// state = sstate[0] != '0';
+// g_free(sstate);
+// } else
+// state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_preview", NULL);
+// em_folder_browser_show_preview(emfb, state);
+// if (emfv->uic)
+// bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewPreview", "state", state?"1":"0", NULL);
+//
+// if ((sstate = camel_object_meta_get(folder, "evolution:thread_list"))) {
+// state = sstate[0] != '0';
+// g_free(sstate);
+// } else
+// state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/thread_list", NULL);
+// message_list_set_threaded(emfv->list, state);
+// if (emfv->uic) {
+// bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreaded", "state", state?"1":"0", NULL);
+// bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreadsCollapseAll", "sensitive", state?"1":"0", NULL);
+// bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreadsExpandAll", "sensitive", state?"1":"0", NULL);
+// }
if (emfv->uic) {
state = (folder->folder_flags & CAMEL_FOLDER_IS_TRASH) == 0;
@@ -2170,26 +1034,26 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
e_search_bar_paint ((ESearchBar *)emfb->search);
}
- /* This function gets triggered several times at startup,
- * so we don't want to reset the message suppression state
- * unless we're actually switching to a different folder. */
- if (different_folder)
- p->suppress_message_selection = FALSE;
-
- if (!p->suppress_message_selection)
- sstate = camel_object_meta_get (
- folder, "evolution:selected_uid");
- else
- sstate = NULL;
-
- g_free (p->select_uid);
- p->select_uid = sstate;
-
- if (emfv->list->cursor_uid == NULL && emfb->priv->list_built_id == 0)
- p->list_built_id = g_signal_connect(emfv->list, "message_list_built", G_CALLBACK (emfb_list_built), emfv);
- }
-
- message_list_thaw(emfv->list);
+// /* This function gets triggered several times at startup,
+// * so we don't want to reset the message suppression state
+// * unless we're actually switching to a different folder. */
+// if (different_folder)
+// p->suppress_message_selection = FALSE;
+//
+// if (!p->suppress_message_selection)
+// sstate = camel_object_meta_get (
+// folder, "evolution:selected_uid");
+// else
+// sstate = NULL;
+//
+// g_free (p->select_uid);
+// p->select_uid = sstate;
+//
+// if (emfv->list->cursor_uid == NULL && emfb->priv->list_built_id == 0)
+// p->list_built_id = g_signal_connect(emfv->list, "message_list_built", G_CALLBACK (emfb_list_built), emfv);
+// }
+//
+// message_list_thaw(emfv->list);
}
static void
@@ -2201,98 +1065,20 @@ emfb_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
gchar *sstate;
EMFolderBrowser *emfb = (EMFolderBrowser *) emfv;
- gconf = mail_config_get_gconf_client ();
-
- /* parent loads all ui files via ui_files */
- emfb_parent->activate(emfv, uic, act);
-
- bonobo_ui_component_add_verb_list_with_data(uic, emfb_verbs, emfv);
- e_pixmaps_update(uic, emfb_pixmaps);
-
- /* FIXME: finish */
- /* (Pre)view pane size (do this first because it affects the
- preview settings - see folder_browser_set_message_preview()
- internals for details) */
- g_signal_handler_block(emfb->vpane, emfb->priv->vpane_resize_id);
- gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int (gconf, emfb->priv->show_wide ? "/apps/evolution/mail/display/hpaned_size": "/apps/evolution/mail/display/paned_size", NULL));
- g_signal_handler_unblock(emfb->vpane, emfb->priv->vpane_resize_id);
-
- /* (Pre)view toggle */
- if (emfv->folder
- && (sstate = camel_object_meta_get(emfv->folder, "evolution:show_preview"))) {
- state = sstate[0] == '1';
- g_free(sstate);
- } else {
- state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_preview", NULL);
- }
-
- bonobo_ui_component_set_prop(uic, "/commands/ViewPreview", "state", state?"1":"0", NULL);
- em_folder_browser_show_preview((EMFolderBrowser *)emfv, state);
- bonobo_ui_component_add_listener(uic, "ViewPreview", emfb_view_preview, emfv);
-
/* Stop button */
state = mail_msg_active((guint)-1);
bonobo_ui_component_set_prop(uic, "/commands/MailStop", "sensitive", state?"1":"0", NULL);
- /* HideDeleted */
- state = !gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_deleted", NULL);
- if (emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH)) {
- state = FALSE;
- bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", "0", NULL);
- } else
- bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", "1", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "state", state ? "1" : "0", NULL);
- bonobo_ui_component_add_listener(uic, "HideDeleted", emfb_hide_deleted, emfv);
- em_folder_view_set_hide_deleted(emfv, state); /* <- not sure if this optimal, but it'll do */
-
- /* FIXME: If we have no folder, we can't do a few of the lookups we need,
- perhaps we should postpone till we can */
-
- /* ViewThreaded */
- if (emfv->folder
- && (sstate = camel_object_meta_get(emfv->folder, "evolution:thread_list"))) {
- state = sstate[0] != '0';
- g_free(sstate);
- } else {
- state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/thread_list", NULL);
- }
-
- bonobo_ui_component_set_prop(uic, "/commands/ViewThreaded", "state", state?"1":"0", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/ViewThreadsCollapseAll", "sensitive", state?"1":"0", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/ViewThreadsExpandAll", "sensitive", state?"1":"0", NULL);
- bonobo_ui_component_add_listener(uic, "ViewThreaded", emfb_view_threaded, emfv);
- message_list_set_threaded(emfv->list, state);
-
- /* Show wide display */
- if (emfb->priv->show_wide) {
- bonobo_ui_component_set_prop(uic, "/commands/ViewAfter", "state", "1", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/ViewBelow", "state", "0", NULL);
- } else {
- bonobo_ui_component_set_prop(uic, "/commands/ViewAfter", "state", "0", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/ViewBelow", "state", "1", NULL);
- }
-
- bonobo_ui_component_add_listener(uic, "ViewAfter", emfb_show_next, emfv);
- bonobo_ui_component_add_listener(uic, "ViewBelow", emfb_show_below, emfv);
- /* em_folder_browser_show_wide((EMFolderBrowser *)emfv, state); */
-
- /* FIXME: Selection state */
-
- /* FIXME: property menu customisation */
- /*folder_browser_setup_property_menu (fb, fb->uicomp);*/
-
- if (((EMFolderBrowser *)emfv)->search)
- e_search_bar_set_ui_component((ESearchBar *)((EMFolderBrowser *)emfv)->search, uic);
- } else {
- const BonoboUIVerb *v;
-
- for (v = &emfb_verbs[0]; v->cname; v++)
- bonobo_ui_component_remove_verb(uic, v->cname);
-
- if (((EMFolderBrowser *)emfv)->search)
- e_search_bar_set_ui_component((ESearchBar *)((EMFolderBrowser *)emfv)->search, NULL);
-
- emfb_parent->activate(emfv, uic, act);
+// /* HideDeleted */
+// state = !gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_deleted", NULL);
+// if (emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH)) {
+// state = FALSE;
+// bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", "0", NULL);
+// } else
+// bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", "1", NULL);
+// bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "state", state ? "1" : "0", NULL);
+// bonobo_ui_component_add_listener(uic, "HideDeleted", emfb_hide_deleted, emfv);
+// em_folder_view_set_hide_deleted(emfv, state); /* <- not sure if this optimal, but it'll do */
}
}
diff --git a/mail/em-folder-properties.c b/mail/em-folder-properties.c
index 709491a686..a7236e66dd 100644
--- a/mail/em-folder-properties.c
+++ b/mail/em-folder-properties.c
@@ -39,7 +39,7 @@
#include "em-folder-properties.h"
#include "em-config.h"
-#include "mail-component.h"
+#include "e-mail-local.h"
#include "mail-ops.h"
#include "mail-mt.h"
#include "mail-vfolder.h"
@@ -287,7 +287,10 @@ static EMConfigItem emfp_items[] = {
static gboolean emfp_items_translated = FALSE;
static void
-emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota, gpointer data)
+emfp_dialog_got_folder_quota (CamelFolder *folder,
+ const gchar *folder_uri,
+ CamelFolderQuotaInfo *quota,
+ gpointer data)
{
GtkWidget *dialog, *w;
struct _prop_data *prop_data;
@@ -295,20 +298,25 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
gint32 count, i,deleted;
EMConfig *ec;
EMConfigTargetFolder *target;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
CamelArgGetV *arggetv;
CamelArgV *argv;
+ CamelStore *local_store;
gboolean hide_deleted;
GConfClient *gconf;
CamelStore *store;
- gchar *uri = (gchar *)data;
- if (folder == NULL) {
- g_free (uri);
+ if (folder == NULL)
return;
- }
store = folder->parent_store;
+ shell_view = E_SHELL_VIEW (data);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ local_store = e_mail_local_get_store ();
+
prop_data = g_malloc0 (sizeof (*prop_data));
prop_data->object = folder;
camel_object_ref (folder);
@@ -341,7 +349,7 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
camel_object_get (folder, NULL, CAMEL_FOLDER_TOTAL, &prop_data->total, NULL);
}
- if (store == mail_component_peek_local_store(NULL)
+ if (store == local_store
&& (!strcmp(prop_data->name, "Drafts")
|| !strcmp(prop_data->name, "Templates")
|| !strcmp(prop_data->name, "Inbox")
@@ -387,11 +395,11 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
g_free (arggetv);
prop_data->argv = argv;
- dialog = gtk_dialog_new_with_buttons (_("Folder Properties"), NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- NULL);
+ dialog = gtk_dialog_new_with_buttons (
+ _("Folder Properties"), GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
gtk_window_set_default_size ((GtkWindow *) dialog, 192, 160);
gtk_widget_ensure_style (dialog);
gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *) dialog)->vbox, 12);
@@ -411,7 +419,7 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
l = g_slist_prepend(l, &emfp_items[i]);
e_config_add_items((EConfig *)ec, l, emfp_commit, NULL, emfp_free, prop_data);
- target = em_config_target_new_folder(ec, folder, uri);
+ target = em_config_target_new_folder(ec, folder, folder_uri);
e_config_set_target((EConfig *)ec, (EConfigTarget *)target);
w = e_config_create_widget((EConfig *)ec);
@@ -421,15 +429,17 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
g_signal_connect (dialog, "response", G_CALLBACK (emfp_dialog_response), prop_data);
gtk_widget_show (dialog);
-
- g_free (uri);
}
static void
emfp_dialog_got_folder (gchar *uri, CamelFolder *folder, gpointer data)
{
+ EShellView *shell_view = data;
+
/* this should be called in a thread too */
- mail_get_folder_quota (folder, emfp_dialog_got_folder_quota, g_strdup (uri), mail_msg_unordered_push);
+ mail_get_folder_quota (
+ folder, uri, emfp_dialog_got_folder_quota,
+ shell_view, mail_msg_unordered_push);
}
/**
@@ -442,27 +452,32 @@ emfp_dialog_got_folder (gchar *uri, CamelFolder *folder, gpointer data)
* as NULL, then the folder @uri will be loaded first.
**/
void
-em_folder_properties_show(GtkWindow *parent, CamelFolder *folder, const gchar *uri)
+em_folder_properties_show (EShellView *shell_view,
+ CamelFolder *folder,
+ const gchar *uri)
{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+ g_return_if_fail (uri != NULL);
+
/* HACK: its the old behaviour, not very 'neat' but it works */
- if (!strncmp(uri, "vfolder:", 8)) {
- CamelURL *url = camel_url_new(uri, NULL);
+ if (!strncmp (uri, "vfolder:", 8)) {
+ CamelURL *url = camel_url_new (uri, NULL);
/* MORE HACK: UNMATCHED is a special folder which you can't modify, so check for it here */
if (url == NULL
|| url->fragment == NULL
|| strcmp(url->fragment, CAMEL_UNMATCHED_NAME) != 0) {
if (url)
- camel_url_free(url);
- vfolder_edit_rule(uri);
+ camel_url_free (url);
+ vfolder_edit_rule (uri);
return;
}
- if (url)
- camel_url_free(url);
+ if (url != NULL)
+ camel_url_free (url);
}
if (folder == NULL)
- mail_get_folder(uri, 0, emfp_dialog_got_folder, NULL, mail_msg_unordered_push);
+ mail_get_folder(uri, 0, emfp_dialog_got_folder, shell_view, mail_msg_unordered_push);
else
- emfp_dialog_got_folder((gchar *)uri, folder, NULL);
+ emfp_dialog_got_folder((gchar *)uri, folder, shell_view);
}
diff --git a/mail/em-folder-properties.h b/mail/em-folder-properties.h
index 958a5669c3..330be151a3 100644
--- a/mail/em-folder-properties.h
+++ b/mail/em-folder-properties.h
@@ -24,12 +24,14 @@
#ifndef __EM_FOLDER_PROPERTIES_H__
#define __EM_FOLDER_PROPERTIES_H__
-#include <gtk/gtk.h>
#include <camel/camel-folder.h>
+#include <shell/e-shell-view.h>
G_BEGIN_DECLS
-void em_folder_properties_show(GtkWindow *parent, CamelFolder *folder, const gchar *uri);
+void em_folder_properties_show (EShellView *shell_view,
+ CamelFolder *folder,
+ const gchar *uri);
G_END_DECLS
diff --git a/mail/em-folder-selection-button.c b/mail/em-folder-selection-button.c
index 983c4a180f..ec818221b4 100644
--- a/mail/em-folder-selection-button.c
+++ b/mail/em-folder-selection-button.c
@@ -25,11 +25,9 @@
#endif
#include <string.h>
-
-#include <e-util/e-util.h>
#include <glib/gi18n.h>
+#include <e-util/e-util.h>
-#include "mail-component.h"
#include "mail-config.h"
#include "em-folder-tree.h"
#include "em-folder-selector.h"
@@ -37,21 +35,15 @@
#include "em-folder-selection-button.h"
-static void em_folder_selection_button_class_init (EMFolderSelectionButtonClass *klass);
-static void em_folder_selection_button_init (EMFolderSelectionButton *emfsb);
-static void em_folder_selection_button_destroy (GtkObject *obj);
-static void em_folder_selection_button_finalize (GObject *obj);
-static void em_folder_selection_button_clicked (GtkButton *button);
-
-static GtkButtonClass *parent_class = NULL;
+#define EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonPrivate))
struct _EMFolderSelectionButtonPrivate {
GtkWidget *icon;
GtkWidget *label;
- GtkWidget *selector;
-
- gchar *uri; /* for single-select mode */
+ gchar *uri; /* for single-select mode */
GList *uris; /* for multi-select mode */
gchar *title;
@@ -61,223 +53,377 @@ struct _EMFolderSelectionButtonPrivate {
};
enum {
+ PROP_0,
+ PROP_CAPTION,
+ PROP_MULTISELECT,
+ PROP_TITLE
+};
+
+enum {
SELECTED,
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0 };
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
-GType
-em_folder_selection_button_get_type (void)
+static void
+folder_selection_button_unselected (EMFolderSelectionButton *button)
{
- static GType type = 0;
+ const gchar *text;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderSelectionButtonClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_selection_button_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderSelectionButton),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_selection_button_init,
- };
+ text = _("<click here to select a folder>");
+ gtk_image_set_from_pixbuf (GTK_IMAGE (button->priv->icon), NULL);
+ gtk_label_set_text (GTK_LABEL (button->priv->label), text);
+}
+
+static void
+folder_selection_button_set_contents (EMFolderSelectionButton *button)
+{
+ EAccount *account;
+ GtkLabel *label;
+ const gchar *uri;
+ gchar *folder_name;
+
+ uri = button->priv->uri;
+ label = GTK_LABEL (button->priv->label);
+ folder_name = em_utils_folder_name_from_uri (uri);
- type = g_type_register_static (GTK_TYPE_BUTTON, "EMFolderSelectionButton", &info, 0);
+ if (folder_name == NULL) {
+ folder_selection_button_unselected (button);
+ return;
}
- return type;
+ account = mail_config_get_account_by_source_url (uri);
+
+ if (account != NULL) {
+ gchar *tmp = folder_name;
+
+ folder_name = g_strdup_printf (
+ "%s/%s", e_account_get_string (
+ account, E_ACCOUNT_NAME), _(folder_name));
+ gtk_label_set_text (label, folder_name);
+ g_free (tmp);
+ } else
+ gtk_label_set_text (label, _(folder_name));
+
+ g_free (folder_name);
}
static void
-em_folder_selection_button_class_init (EMFolderSelectionButtonClass *klass)
+folder_selection_button_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
- GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
-
- parent_class = g_type_class_ref (GTK_TYPE_BUTTON);
-
- object_class->finalize = em_folder_selection_button_finalize;
- gtk_object_class->destroy = em_folder_selection_button_destroy;
- button_class->clicked = em_folder_selection_button_clicked;
-
- signals[SELECTED] = g_signal_new ("selected",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderSelectionButtonClass, selected),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ switch (property_id) {
+ case PROP_CAPTION:
+ em_folder_selection_button_set_caption (
+ EM_FOLDER_SELECTION_BUTTON (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_MULTISELECT:
+ em_folder_selection_button_set_multiselect (
+ EM_FOLDER_SELECTION_BUTTON (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_TITLE:
+ em_folder_selection_button_set_title (
+ EM_FOLDER_SELECTION_BUTTON (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-set_contents_unselected (EMFolderSelectionButton *button)
+folder_selection_button_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- gtk_image_set_from_pixbuf (GTK_IMAGE (button->priv->icon), NULL);
- gtk_label_set_text (GTK_LABEL (button->priv->label), _("<click here to select a folder>"));
+ switch (property_id) {
+ case PROP_CAPTION:
+ g_value_set_string (
+ value,
+ em_folder_selection_button_get_caption (
+ EM_FOLDER_SELECTION_BUTTON (object)));
+ return;
+
+ case PROP_MULTISELECT:
+ g_value_set_boolean (
+ value,
+ em_folder_selection_button_get_multiselect (
+ EM_FOLDER_SELECTION_BUTTON (object)));
+ return;
+
+ case PROP_TITLE:
+ g_value_set_string (
+ value,
+ em_folder_selection_button_get_title (
+ EM_FOLDER_SELECTION_BUTTON (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-set_contents (EMFolderSelectionButton *button)
+folder_selection_button_finalize (GObject *object)
{
- struct _EMFolderSelectionButtonPrivate *priv = button->priv;
- gchar *folder_name = em_utils_folder_name_from_uri (priv->uri);
+ EMFolderSelectionButtonPrivate *priv;
- if (folder_name) {
- EAccount *account = mail_config_get_account_by_source_url (priv->uri);
+ priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (object);
- if (account) {
- gchar *tmp = folder_name;
- folder_name = g_strdup_printf ("%s/%s", e_account_get_string (account, E_ACCOUNT_NAME), folder_name);
- g_free (tmp);
- gtk_label_set_text (GTK_LABEL (priv->label), folder_name);
- } else
- gtk_label_set_text (GTK_LABEL (priv->label), _(folder_name));
+ g_list_foreach (priv->uris, (GFunc) g_free, NULL);
+ g_list_free (priv->uris);
- g_free (folder_name);
- } else {
- set_contents_unselected (button);
- }
+ g_free (priv->title);
+ g_free (priv->caption);
+ g_free (priv->uri);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-em_folder_selection_button_init (EMFolderSelectionButton *emfsb)
+folder_selection_button_destroy (GtkObject *object)
{
- struct _EMFolderSelectionButtonPrivate *priv;
- GtkWidget *box;
+ EMFolderSelectionButtonPrivate *priv;
- priv = g_new0 (struct _EMFolderSelectionButtonPrivate, 1);
- emfsb->priv = priv;
+ priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (object);
- priv->multiple_select = FALSE;
+ /* Chain up to parent's destroy() method. */
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
- box = gtk_hbox_new (FALSE, 4);
+static void
+folder_selection_button_clicked (GtkButton *button)
+{
+ EMFolderSelectionButtonPrivate *priv;
+ EMFolderTree *emft;
+ GtkWidget *dialog;
+ GtkTreeSelection *selection;
+ GtkSelectionMode mode;
- priv->icon = gtk_image_new ();
- gtk_widget_show (priv->icon);
- gtk_box_pack_start (GTK_BOX (box), priv->icon, FALSE, TRUE, 0);
+ priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (button);
- priv->label = gtk_label_new ("");
- gtk_widget_show (priv->label);
- gtk_label_set_justify (GTK_LABEL (priv->label), GTK_JUSTIFY_LEFT);
- gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.0);
- gtk_box_pack_start (GTK_BOX (box), priv->label, TRUE, TRUE, 0);
+ emft = (EMFolderTree *) em_folder_tree_new ();
- gtk_widget_show (box);
- gtk_container_add (GTK_CONTAINER (emfsb), box);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (emft));
+ if (priv->multiple_select)
+ mode = GTK_SELECTION_MULTIPLE;
+ else
+ mode = GTK_SELECTION_SINGLE;
+ gtk_tree_selection_set_mode (selection, mode);
- set_contents (emfsb);
-}
+ em_folder_tree_set_excluded (
+ emft, EMFT_EXCLUDE_NOSELECT |
+ EMFT_EXCLUDE_VIRTUAL | EMFT_EXCLUDE_VTRASH);
-static void
-em_folder_selection_button_destroy (GtkObject *obj)
-{
- struct _EMFolderSelectionButtonPrivate *priv = ((EMFolderSelectionButton *) obj)->priv;
+ dialog = em_folder_selector_new (
+ emft, EM_FOLDER_SELECTOR_CAN_CREATE,
+ priv->title, priv->caption, NULL);
- if (priv->selector) {
- gtk_widget_destroy(priv->selector);
- priv->selector = NULL;
+ if (priv->multiple_select)
+ em_folder_selector_set_selected_list (
+ EM_FOLDER_SELECTOR (dialog), priv->uris);
+ else
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog), priv->uri);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ if (priv->multiple_select) {
+ GList *uris;
+
+ uris = em_folder_selector_get_selected_uris (
+ EM_FOLDER_SELECTOR (dialog));
+ em_folder_selection_button_set_selection_mult (
+ EM_FOLDER_SELECTION_BUTTON (button), uris);
+ } else {
+ const gchar *uri;
+
+ uri = em_folder_selector_get_selected_uri (
+ EM_FOLDER_SELECTOR (dialog));
+ em_folder_selection_button_set_selection (
+ EM_FOLDER_SELECTION_BUTTON (button), uri);
}
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
+ g_signal_emit (button, signals[SELECTED], 0);
+
+exit:
+ gtk_widget_destroy (dialog);
}
static void
-em_folder_selection_button_finalize (GObject *obj)
+folder_selection_button_class_init (EMFolderSelectionButtonClass *class)
{
- struct _EMFolderSelectionButtonPrivate *priv = ((EMFolderSelectionButton *) obj)->priv;
-
- GList *lst = ((EMFolderSelectionButton*) obj)->priv->uris;
- g_list_foreach (lst, (GFunc) g_free, NULL);
- g_list_free (lst);
-
- g_free (priv->title);
- g_free (priv->caption);
- g_free (priv->uri);
- g_free (priv);
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+ GtkButtonClass *button_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFolderSelectionButtonPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = folder_selection_button_set_property;
+ object_class->get_property = folder_selection_button_get_property;
+ object_class->finalize = folder_selection_button_finalize;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = folder_selection_button_destroy;
+
+ button_class = GTK_BUTTON_CLASS (class);
+ button_class->clicked = folder_selection_button_clicked;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CAPTION,
+ g_param_spec_string (
+ "caption",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MULTISELECT,
+ g_param_spec_boolean (
+ "multiselect",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TITLE,
+ g_param_spec_string (
+ "title",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[SELECTED] = g_signal_new (
+ "selected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderSelectionButtonClass, selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
-emfsb_selector_response (EMFolderSelector *emfs, gint response, EMFolderSelectionButton *button)
+folder_selection_button_init (EMFolderSelectionButton *emfsb)
{
- if (response == GTK_RESPONSE_OK) {
- if (button->priv->multiple_select) {
- GList *uris = em_folder_selector_get_selected_uris (emfs);
+ GtkWidget *box;
- em_folder_selection_button_set_selection_mult (button, uris);
- g_signal_emit (button, signals[SELECTED], 0);
- } else {
- const gchar *uri = em_folder_selector_get_selected_uri (emfs);
+ emfsb->priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (emfsb);
- em_folder_selection_button_set_selection (button, uri);
- g_signal_emit (button, signals[SELECTED], 0);
- }
- }
+ emfsb->priv->multiple_select = FALSE;
- gtk_widget_destroy ((GtkWidget *) emfs);
+ box = gtk_hbox_new (FALSE, 4);
+
+ emfsb->priv->icon = gtk_image_new ();
+ gtk_widget_show (emfsb->priv->icon);
+ gtk_box_pack_start (GTK_BOX (box), emfsb->priv->icon, FALSE, TRUE, 0);
+
+ emfsb->priv->label = gtk_label_new ("");
+ gtk_widget_show (emfsb->priv->label);
+ gtk_label_set_justify (GTK_LABEL (emfsb->priv->label), GTK_JUSTIFY_LEFT);
+ gtk_misc_set_alignment (GTK_MISC (emfsb->priv->label), 0.0, 0.0);
+ gtk_box_pack_start (GTK_BOX (box), emfsb->priv->label, TRUE, TRUE, 0);
+
+ gtk_widget_show (box);
+ gtk_container_add (GTK_CONTAINER (emfsb), box);
+
+ folder_selection_button_set_contents (emfsb);
}
-static void
-em_folder_selection_button_clicked (GtkButton *button)
+GType
+em_folder_selection_button_get_type (void)
{
- struct _EMFolderSelectionButtonPrivate *priv = EM_FOLDER_SELECTION_BUTTON (button)->priv;
- EMFolderTreeModel *model;
- EMFolderTree *emft;
- GtkWidget *dialog;
+ static GType type = 0;
- if (GTK_BUTTON_CLASS (parent_class)->clicked != NULL)
- (* GTK_BUTTON_CLASS (parent_class)->clicked) (button);
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderSelectionButtonClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_selection_button_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderSelectionButton),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_selection_button_init,
+ NULL /* value_table */
+ };
- if (priv->selector) {
- gtk_window_present((GtkWindow *)priv->selector);
- return;
+ type = g_type_register_static (
+ GTK_TYPE_BUTTON, "EMFolderSelectionButton",
+ &type_info, 0);
}
- model = mail_component_peek_tree_model (mail_component_peek ());
- emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
- g_object_unref (model);
- em_folder_tree_set_multiselect (emft, priv->multiple_select);
- em_folder_tree_set_excluded(emft, EMFT_EXCLUDE_NOSELECT|EMFT_EXCLUDE_VIRTUAL|EMFT_EXCLUDE_VTRASH);
- dialog = em_folder_selector_new (emft, EM_FOLDER_SELECTOR_CAN_CREATE, priv->title, priv->caption, NULL);
- if (priv->multiple_select)
- em_folder_selector_set_selected_list ((EMFolderSelector *) dialog, priv->uris);
- else
- em_folder_selector_set_selected ((EMFolderSelector *) dialog, priv->uri);
- g_signal_connect (dialog, "response", G_CALLBACK (emfsb_selector_response), button);
- priv->selector = dialog;
- g_signal_connect(dialog, "destroy", G_CALLBACK(gtk_widget_destroyed), &priv->selector);
- gtk_widget_show (dialog);
+ return type;
}
GtkWidget *
-em_folder_selection_button_new (const gchar *title, const gchar *caption)
+em_folder_selection_button_new (const gchar *title,
+ const gchar *caption)
{
- EMFolderSelectionButton *button = g_object_new (EM_TYPE_FOLDER_SELECTION_BUTTON, NULL);
+ return g_object_new (
+ EM_TYPE_FOLDER_SELECTION_BUTTON,
+ "title", title, "caption", caption, NULL);
+}
- button->priv->title = g_strdup (title);
- button->priv->caption = g_strdup (caption);
+const gchar *
+em_folder_selection_button_get_caption (EMFolderSelectionButton *button)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
- return GTK_WIDGET (button);
+ return button->priv->caption;
}
void
-em_folder_selection_button_set_selection (EMFolderSelectionButton *button, const gchar *uri)
+em_folder_selection_button_set_caption (EMFolderSelectionButton *button,
+ const gchar *caption)
{
- struct _EMFolderSelectionButtonPrivate *priv = button->priv;
+ g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
+
+ g_free (button->priv->caption);
+ button->priv->caption = g_strdup (caption);
+
+ g_object_notify (G_OBJECT (button), "caption");
+}
+
+gboolean
+em_folder_selection_button_get_multiselect (EMFolderSelectionButton *button)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), FALSE);
+
+ return button->priv->multiple_select;
+}
+void
+em_folder_selection_button_set_multiselect (EMFolderSelectionButton *button,
+ gboolean multiselect)
+{
g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
- if (priv->uri != uri) {
- g_free (priv->uri);
- priv->uri = g_strdup (uri);
- }
+ button->priv->multiple_select = multiselect;
- set_contents (button);
+ g_object_notify (G_OBJECT (button), "multiselect");
}
const gchar *
@@ -289,20 +435,40 @@ em_folder_selection_button_get_selection (EMFolderSelectionButton *button)
}
void
-em_folder_selection_button_set_selection_mult (EMFolderSelectionButton *button, GList *uris)
+em_folder_selection_button_set_selection (EMFolderSelectionButton *button,
+ const gchar *uri)
+{
+ g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
+
+ if (g_strcmp0 (button->priv->uri, uri) == 0)
+ return;
+
+ g_free (button->priv->uri);
+ button->priv->uri = g_strdup (uri);
+
+ folder_selection_button_set_contents (button);
+}
+
+GList *
+em_folder_selection_button_get_selection_mult (EMFolderSelectionButton *button)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
+
+ return button->priv->uris;
+}
+
+void
+em_folder_selection_button_set_selection_mult (EMFolderSelectionButton *button,
+ GList *uris)
{
- struct _EMFolderSelectionButtonPrivate *priv = button->priv;
gchar *caption, *tmp, *tmp2;
g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
- if (priv->uris) {
- g_list_foreach (priv->uris, (GFunc) g_free, NULL);
- g_list_free (priv->uris);
- priv->uris = NULL;
- }
+ g_list_foreach (button->priv->uris, (GFunc) g_free, NULL);
+ g_list_free (button->priv->uris);
- priv->uris = uris;
+ button->priv->uris = uris;
/* compile the name */
caption = g_strdup ("");
@@ -319,34 +485,36 @@ em_folder_selection_button_set_selection_mult (EMFolderSelectionButton *button,
/* apparently, we do not know this folder, so we'll just skip it */
g_free (uris->data);
uris = g_list_next (uris);
- priv->uris = g_list_remove (priv->uris, uris->data);
+ button->priv->uris = g_list_remove (
+ button->priv->uris, uris->data);
}
}
if (caption[0])
- gtk_label_set_text (GTK_LABEL (priv->label), caption + 2);
+ gtk_label_set_text (
+ GTK_LABEL (button->priv->label), caption + 2);
else
- set_contents_unselected (button);
+ folder_selection_button_unselected (button);
g_free (caption);
}
-GList *
-em_folder_selection_button_get_selection_mult (EMFolderSelectionButton *button)
+const gchar *
+em_folder_selection_button_get_title (EMFolderSelectionButton *button)
{
- g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
+ g_return_val_if_fail (EM_FOLDER_SELECTION_BUTTON (button), NULL);
- return button->priv->uris;
+ return button->priv->title;
}
void
-em_folder_selection_button_set_multiselect (EMFolderSelectionButton *button, gboolean value)
+em_folder_selection_button_set_title (EMFolderSelectionButton *button,
+ const gchar *title)
{
- button->priv->multiple_select = value;
-}
+ g_return_if_fail (EM_FOLDER_SELECTION_BUTTON (button));
-gboolean
-em_folder_selection_button_get_multiselect (EMFolderSelectionButton *button)
-{
- return button->priv->multiple_select;
+ g_free (button->priv->title);
+ button->priv->title = g_strdup (title);
+
+ g_object_notify (G_OBJECT (button), "title");
}
diff --git a/mail/em-folder-selection-button.h b/mail/em-folder-selection-button.h
index d30867435e..cc75fac1dd 100644
--- a/mail/em-folder-selection-button.h
+++ b/mail/em-folder-selection-button.h
@@ -21,26 +21,39 @@
*
*/
-#ifndef __EM_FOLDER_SELECTION_BUTTON_H__
-#define __EM_FOLDER_SELECTION_BUTTON_H__
+#ifndef EM_FOLDER_SELECTION_BUTTON_H
+#define EM_FOLDER_SELECTION_BUTTON_H
#include <gtk/gtk.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_SELECTION_BUTTON \
+ (em_folder_selection_button_get_type ())
+#define EM_FOLDER_SELECTION_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButton))
+#define EM_FOLDER_SELECTION_BUTTON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonClass))
+#define EM_IS_FOLDER_SELECTION_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON))
+#define EM_IS_FOLDER_SELECTION_BUTTON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON))
+#define EM_FOLDER_SELECTION_BUTTON_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonClass))
-#define EM_TYPE_FOLDER_SELECTION_BUTTON (em_folder_selection_button_get_type ())
-#define EM_FOLDER_SELECTION_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButton))
-#define EM_FOLDER_SELECTION_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonClass))
-#define EM_IS_FOLDER_SELECTION_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON))
-#define EM_IS_FOLDER_SELECTION_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON))
+G_BEGIN_DECLS
-typedef struct _EMFolderSelectionButton EMFolderSelectionButton;
-typedef struct _EMFolderSelectionButtonClass EMFolderSelectionButtonClass;
+typedef struct _EMFolderSelectionButton EMFolderSelectionButton;
+typedef struct _EMFolderSelectionButtonClass EMFolderSelectionButtonClass;
+typedef struct _EMFolderSelectionButtonPrivate EMFolderSelectionButtonPrivate;
struct _EMFolderSelectionButton {
GtkButton parent;
-
- struct _EMFolderSelectionButtonPrivate *priv;
+ EMFolderSelectionButtonPrivate *priv;
};
struct _EMFolderSelectionButtonClass {
@@ -48,22 +61,39 @@ struct _EMFolderSelectionButtonClass {
/* Signals. */
- void (* selected) (EMFolderSelectionButton *button);
+ void (*selected) (EMFolderSelectionButton *button);
};
-GType em_folder_selection_button_get_type (void);
-
-GtkWidget *em_folder_selection_button_new (const gchar *title, const gchar *caption);
-
-void em_folder_selection_button_set_selection (EMFolderSelectionButton *button, const gchar *uri);
-const gchar *em_folder_selection_button_get_selection (EMFolderSelectionButton *button);
-
-void em_folder_selection_button_set_selection_mult (EMFolderSelectionButton *button, GList *uris);
-GList *em_folder_selection_button_get_selection_mult (EMFolderSelectionButton *button);
-
-void em_folder_selection_button_set_multiselect (EMFolderSelectionButton *button, gboolean value);
-gboolean em_folder_selection_button_get_multiselect (EMFolderSelectionButton *button);
+GType em_folder_selection_button_get_type (void);
+GtkWidget * em_folder_selection_button_new
+ (const gchar *title,
+ const gchar *caption);
+const gchar * em_folder_selection_button_get_caption
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_caption
+ (EMFolderSelectionButton *button,
+ const gchar *caption);
+gboolean em_folder_selection_button_get_multiselect
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_multiselect
+ (EMFolderSelectionButton *button,
+ gboolean multiselect);
+const gchar * em_folder_selection_button_get_selection
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_selection
+ (EMFolderSelectionButton *button,
+ const gchar *uri);
+GList * em_folder_selection_button_get_selection_mult
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_selection_mult
+ (EMFolderSelectionButton *button,
+ GList *uris);
+const gchar * em_folder_selection_button_get_title
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_title
+ (EMFolderSelectionButton *button,
+ const gchar *title);
G_END_DECLS
-#endif /* __EM_FOLDER_SELECTION_BUTTON_H__ */
+#endif /* EM_FOLDER_SELECTION_BUTTON_H */
diff --git a/mail/em-folder-selection.c b/mail/em-folder-selection.c
index 8fe6292e32..1e77525c9b 100644
--- a/mail/em-folder-selection.c
+++ b/mail/em-folder-selection.c
@@ -32,53 +32,46 @@
#include "em-folder-tree.h"
#include "em-folder-selector.h"
#include "em-folder-selection.h"
-#include "mail-component.h"
/* TODO: rmeove this file, it could just go on em-folder-selection or em-utils */
-struct _select_folder_data {
- void (*done) (const gchar *uri, gpointer data);
- gpointer data;
-};
-
-static void
-emfs_selector_response(EMFolderSelector *emfs, gint response, struct _select_folder_data *d)
-{
- if (response == GTK_RESPONSE_OK) {
- const gchar *uri = em_folder_selector_get_selected_uri(emfs);
-
- d->done(uri, d->data);
- }
-
- gtk_widget_destroy((GtkWidget *)emfs);
-}
-
void
-em_select_folder (GtkWindow *parent_window, const gchar *title, const gchar *oklabel, const gchar *default_uri,
- EMFTExcludeFunc exclude,
- void (*done) (const gchar *uri, gpointer user_data), gpointer user_data)
+em_select_folder (const gchar *title,
+ const gchar *oklabel,
+ const gchar *default_uri,
+ EMFTExcludeFunc exclude,
+ void (*done) (const gchar *uri, gpointer user_data),
+ gpointer user_data)
{
- struct _select_folder_data *d;
- EMFolderTreeModel *model;
GtkWidget *dialog;
EMFolderTree *emft;
- model = mail_component_peek_tree_model (mail_component_peek ());
- emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
+ g_return_if_fail (done != NULL);
+
+ /* XXX Do we leak this reference? */
+ emft = (EMFolderTree *) em_folder_tree_new ();
+
if (exclude)
- em_folder_tree_set_excluded_func(emft, exclude, user_data);
+ em_folder_tree_set_excluded_func (emft, exclude, user_data);
else
- em_folder_tree_set_excluded (emft, EMFT_EXCLUDE_NOSELECT|EMFT_EXCLUDE_VIRTUAL|EMFT_EXCLUDE_VTRASH);
+ em_folder_tree_set_excluded (
+ emft, EMFT_EXCLUDE_NOSELECT |
+ EMFT_EXCLUDE_VIRTUAL | EMFT_EXCLUDE_VTRASH);
- dialog = em_folder_selector_new(emft, EM_FOLDER_SELECTOR_CAN_CREATE, title, NULL, oklabel);
+ dialog = em_folder_selector_new (
+ emft, EM_FOLDER_SELECTOR_CAN_CREATE, title, NULL, oklabel);
- d = g_malloc0(sizeof(*d));
- d->data = user_data;
- d->done = done;
- g_signal_connect(dialog, "response", G_CALLBACK (emfs_selector_response), d);
- g_object_set_data_full((GObject *)dialog, "e-select-data", d, (GDestroyNotify)g_free);
- gtk_widget_show(dialog);
+ if (default_uri != NULL)
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog), default_uri);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+ const gchar *uri;
+
+ uri = em_folder_selector_get_selected_uri (
+ EM_FOLDER_SELECTOR (dialog));
+ done (uri, user_data);
+ }
- if (default_uri)
- em_folder_selector_set_selected((EMFolderSelector *)dialog, default_uri);
+ gtk_widget_destroy (dialog);
}
diff --git a/mail/em-folder-selection.h b/mail/em-folder-selection.h
index af3243fdd5..3f6b4b3a3b 100644
--- a/mail/em-folder-selection.h
+++ b/mail/em-folder-selection.h
@@ -24,15 +24,16 @@
#ifndef EM_FOLDER_SELECTION_H
#define EM_FOLDER_SELECTION_H
-#include <gtk/gtk.h>
-#include "em-folder-tree.h"
+#include <glib.h>
G_BEGIN_DECLS
-void em_select_folder (GtkWindow *parent_window, const gchar *title, const gchar *oklabel, const gchar *default_uri,
- EMFTExcludeFunc exclude,
- void (*done)(const gchar *uri, gpointer data),
- gpointer data);
+void em_select_folder (const gchar *title,
+ const gchar *oklabel,
+ const gchar *default_uri,
+ EMFTExcludeFunc exclude,
+ void (*done)(const gchar *uri, gpointer data),
+ gpointer data);
G_END_DECLS
diff --git a/mail/em-folder-selector.c b/mail/em-folder-selector.c
index 95339ff8ad..198264e62b 100644
--- a/mail/em-folder-selector.c
+++ b/mail/em-folder-selector.c
@@ -21,14 +21,8 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <string.h>
-
#include <glib/gi18n.h>
-
#include <e-util/e-util.h>
#include <misc/e-gui-utils.h>
@@ -43,82 +37,83 @@
#define d(x)
extern CamelSession *session;
+static gpointer parent_class;
-static void em_folder_selector_class_init (EMFolderSelectorClass *klass);
-static void em_folder_selector_init (EMFolderSelector *emfs);
-static void em_folder_selector_destroy (GtkObject *obj);
-static void em_folder_selector_finalize (GObject *obj);
+static void
+folder_selector_finalize (GObject *object)
+{
+ EMFolderSelector *emfs = EM_FOLDER_SELECTOR (object);
-static GtkDialogClass *parent_class = NULL;
+ g_free (emfs->selected_path);
+ g_free (emfs->selected_uri);
+ g_free (emfs->created_uri);
-GType
-em_folder_selector_get_type (void)
-{
- static GType type = 0;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderSelectorClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_selector_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderSelector),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_selector_init,
- };
+static void
+folder_selector_destroy (GtkObject *object)
+{
+ EMFolderSelector *emfs = EM_FOLDER_SELECTOR (object);
+ GtkTreeModel *model;
- type = g_type_register_static (GTK_TYPE_DIALOG, "EMFolderSelector", &info, 0);
+ if (emfs->created_id != 0) {
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emfs->emft));
+ g_signal_handler_disconnect (model, emfs->created_id);
+ emfs->created_id = 0;
}
- return type;
+ /* Chain up to parent's destroy() method. */
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
-em_folder_selector_class_init (EMFolderSelectorClass *klass)
+folder_selector_class_init (EMFolderSelectorClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+
+ parent_class = g_type_class_peek_parent (class);
- parent_class = g_type_class_ref (GTK_TYPE_DIALOG);
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = folder_selector_finalize;
- object_class->finalize = em_folder_selector_finalize;
- gtk_object_class->destroy = em_folder_selector_destroy;
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = folder_selector_destroy;
}
static void
-em_folder_selector_init (EMFolderSelector *emfs)
+folder_selector_init (EMFolderSelector *emfs)
{
emfs->selected_path = NULL;
emfs->selected_uri = NULL;
}
-static void
-em_folder_selector_destroy (GtkObject *obj)
+GType
+em_folder_selector_get_type (void)
{
- EMFolderSelector *emfs = (EMFolderSelector *) obj;
- EMFolderTreeModel *model;
-
- if (emfs->created_id != 0) {
- model = em_folder_tree_get_model (emfs->emft);
- g_signal_handler_disconnect (model, emfs->created_id);
- emfs->created_id = 0;
- }
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
-}
+ static GType type = 0;
-static void
-em_folder_selector_finalize (GObject *obj)
-{
- EMFolderSelector *emfs = (EMFolderSelector *) obj;
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderSelectorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_selector_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_selector_init,
+ NULL /* value_table */
+ };
- g_free (emfs->selected_path);
- g_free (emfs->selected_uri);
- g_free (emfs->created_uri);
+ type = g_type_register_static (
+ GTK_TYPE_DIALOG, "EMFolderSelector", &type_info, 0);
+ }
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ return type;
}
static void
@@ -128,7 +123,9 @@ emfs_response (GtkWidget *dialog, gint response, EMFolderSelector *emfs)
return;
g_object_set_data ((GObject *)emfs->emft, "select", GUINT_TO_POINTER (1));
- em_folder_utils_create_folder (NULL, emfs->emft, GTK_WINDOW (dialog));
+
+ /* FIXME Pass a parent window. */
+ em_folder_utils_create_folder (NULL, emfs->emft, NULL);
g_signal_stop_emission_by_name (emfs, "response");
}
@@ -168,7 +165,7 @@ folder_activated_cb (EMFolderTree *emft, const gchar *path, const gchar *uri, EM
void
em_folder_selector_construct (EMFolderSelector *emfs, EMFolderTree *emft, guint32 flags, const gchar *title, const gchar *text, const gchar *oklabel)
{
- GtkWidget *label;
+ GtkWidget *widget;
gtk_window_set_modal (GTK_WINDOW (emfs), FALSE);
gtk_window_set_default_size (GTK_WINDOW (emfs), 350, 300);
@@ -190,19 +187,29 @@ em_folder_selector_construct (EMFolderSelector *emfs, EMFolderTree *emft, guint3
gtk_dialog_set_response_sensitive (GTK_DIALOG (emfs), GTK_RESPONSE_OK, FALSE);
gtk_dialog_set_default_response (GTK_DIALOG (emfs), GTK_RESPONSE_OK);
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_box_pack_end (
+ GTK_BOX (GTK_DIALOG (emfs)->vbox), widget, TRUE, TRUE, 6);
+ gtk_widget_show (widget);
+
emfs->emft = emft;
- gtk_widget_show ((GtkWidget *) emft);
+ gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (emft));
+ gtk_widget_show (GTK_WIDGET (emft));
g_signal_connect (emfs->emft, "folder-selected", G_CALLBACK (folder_selected_cb), emfs);
g_signal_connect (emfs->emft, "folder-activated", G_CALLBACK (folder_activated_cb), emfs);
- gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), (GtkWidget *)emft, TRUE, TRUE, 6);
if (text != NULL) {
- label = gtk_label_new (text);
- gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
- gtk_widget_show (label);
+ widget = gtk_label_new (text);
+ gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_LEFT);
+ gtk_widget_show (widget);
- gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), label, FALSE, TRUE, 6);
+ gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), widget, FALSE, TRUE, 6);
}
gtk_widget_grab_focus ((GtkWidget *) emfs->emft);
diff --git a/mail/em-folder-selector.h b/mail/em-folder-selector.h
index f358fc059d..131c4a4574 100644
--- a/mail/em-folder-selector.h
+++ b/mail/em-folder-selector.h
@@ -26,17 +26,30 @@
#include <gtk/gtk.h>
-#define EM_TYPE_FOLDER_SELECTOR (em_folder_selector_get_type ())
-#define EM_FOLDER_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelector))
-#define EM_FOLDER_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
-#define EM_IS_FOLDER_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_SELECTOR))
-#define EM_IS_FOLDER_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EM_TYPE_FOLDER_SELECTOR))
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_SELECTOR \
+ (em_folder_selector_get_type ())
+#define EM_FOLDER_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelector))
+#define EM_FOLDER_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
+#define EM_IS_FOLDER_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FOLDER_SELECTOR))
+#define EM_IS_FOLDER_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_FOLDER_SELECTOR))
+#define EM_FOLDER_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
G_BEGIN_DECLS
-typedef struct _EMFolderSelector EMFolderSelector;
+typedef struct _EMFolderSelector EMFolderSelector;
+typedef struct _EMFolderSelectorClass EMFolderSelectorClass;
typedef struct _EMFolderSelectorPrivate EMFolderSelectorPrivate;
-typedef struct _EMFolderSelectorClass EMFolderSelectorClass;
struct _EMFolderSelector {
GtkDialog parent;
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index 0a2ce6204e..9154e13c48 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -20,9 +20,7 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "em-folder-tree-model.h"
#include <stdio.h>
#include <string.h>
@@ -32,13 +30,8 @@
#include <errno.h>
#include <sys/stat.h>
-#include <libxml/parser.h>
-
-#include <libedataserver/e-xml-utils.h>
-#include <libedataserver/e-data-server-util.h>
-
-#include <e-util/e-util.h>
-#include <e-util/e-mktemp.h>
+#include "e-util/e-util.h"
+#include "e-util/e-account-utils.h"
#include <glib/gi18n.h>
@@ -50,7 +43,6 @@
#include "mail-mt.h"
/* sigh, these 2 only needed for outbox total count checking - a mess */
-#include "mail-component.h"
#include "mail-folder-cache.h"
#include "em-utils.h"
@@ -60,22 +52,39 @@
#include <camel/camel-folder.h>
#include <camel/camel-vee-store.h>
-#include "em-folder-tree-model.h"
+#include "e-mail-local.h"
-#define u(x) /* unread count debug */
#define d(x)
-/* GObject virtual method overrides */
-static void em_folder_tree_model_class_init (EMFolderTreeModelClass *klass);
-static void em_folder_tree_model_init (EMFolderTreeModel *model);
-static void em_folder_tree_model_finalize (GObject *obj);
+#define EM_FOLDER_TREE_MODEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelPrivate))
+
+struct _EMFolderTreeModelPrivate {
+ /* This is set by EMailShellSidebar. It allows new EMFolderTree
+ * instances to initialize their selection and expanded states to
+ * mimic the sidebar. */
+ GtkTreeSelection *selection; /* weak reference */
+
+ EAccountList *accounts;
-/* interface init methods */
-static void tree_model_iface_init (GtkTreeModelIface *iface);
-static void tree_sortable_iface_init (GtkTreeSortableIface *iface);
+ /* EAccount -> EMFolderTreeStoreInfo */
+ GHashTable *account_index;
-static void account_changed (EAccountList *accounts, EAccount *account, gpointer user_data);
-static void account_removed (EAccountList *accounts, EAccount *account, gpointer user_data);
+ /* CamelStore -> EMFolderTreeStoreInfo */
+ GHashTable *store_index;
+
+ /* URI -> GtkTreeRowReference */
+ GHashTable *uri_index;
+
+ gulong account_changed_id;
+ gulong account_removed_id;
+};
+
+enum {
+ PROP_0,
+ PROP_SELECTION
+};
enum {
LOADING_ROW,
@@ -86,94 +95,30 @@ enum {
extern CamelStore *vfolder_store;
-static guint signals[LAST_SIGNAL] = { 0, };
-static GtkTreeStoreClass *parent_class = NULL;
-
-GType
-em_folder_tree_model_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderTreeModelClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_tree_model_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderTreeModel),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_tree_model_init,
- };
- static const GInterfaceInfo tree_model_info = {
- (GInterfaceInitFunc) tree_model_iface_init,
- NULL,
- NULL
- };
- static const GInterfaceInfo sortable_info = {
- (GInterfaceInitFunc) tree_sortable_iface_init,
- NULL,
- NULL
- };
-
- type = g_type_register_static (GTK_TYPE_TREE_STORE, "EMFolderTreeModel", &info, 0);
-
- g_type_add_interface_static (type, GTK_TYPE_TREE_MODEL,
- &tree_model_info);
- g_type_add_interface_static (type, GTK_TYPE_TREE_SORTABLE,
- &sortable_info);
- }
-
- return type;
-}
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
static void
-em_folder_tree_model_class_init (EMFolderTreeModelClass *klass)
+store_info_free (EMFolderTreeModelStoreInfo *si)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_ref (GTK_TYPE_TREE_STORE);
-
- object_class->finalize = em_folder_tree_model_finalize;
-
- /* signals */
- signals[LOADING_ROW] =
- g_signal_new ("loading-row",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeModelClass, loading_row),
- NULL, NULL,
- e_marshal_VOID__POINTER_POINTER,
- G_TYPE_NONE, 2,
- G_TYPE_POINTER,
- G_TYPE_POINTER);
-
- signals[LOADED_ROW] =
- g_signal_new ("loaded-row",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeModelClass, loaded_row),
- NULL, NULL,
- e_marshal_VOID__POINTER_POINTER,
- G_TYPE_NONE, 2,
- G_TYPE_POINTER,
- G_TYPE_POINTER);
-
- signals[FOLDER_ADDED] =
- g_signal_new ("folder-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeModelClass, folder_added),
- NULL, NULL,
- e_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2,
- G_TYPE_STRING,
- G_TYPE_STRING);
+ camel_object_remove_event (si->store, si->created_id);
+ camel_object_remove_event (si->store, si->deleted_id);
+ camel_object_remove_event (si->store, si->renamed_id);
+ camel_object_remove_event (si->store, si->subscribed_id);
+ camel_object_remove_event (si->store, si->unsubscribed_id);
+
+ g_free (si->display_name);
+ camel_object_unref (si->store);
+ gtk_tree_row_reference_free (si->row);
+ g_hash_table_destroy (si->full_hash);
+ g_free (si);
}
static gint
-sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
+folder_tree_model_sort (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
{
gchar *aname, *bname;
CamelStore *store;
@@ -181,13 +126,21 @@ sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data
guint32 aflags, bflags;
gint rv = -2;
- gtk_tree_model_get (model, a, COL_BOOL_IS_STORE, &is_store,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_DISPLAY_NAME, &aname, COL_UINT_FLAGS, &aflags, -1);
- gtk_tree_model_get (model, b, COL_STRING_DISPLAY_NAME, &bname, COL_UINT_FLAGS, &bflags, -1);
+ gtk_tree_model_get (
+ model, a,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_DISPLAY_NAME, &aname,
+ COL_UINT_FLAGS, &aflags, -1);
+
+ gtk_tree_model_get (
+ model, b,
+ COL_STRING_DISPLAY_NAME, &bname,
+ COL_UINT_FLAGS, &bflags, -1);
if (is_store) {
- /* On This Computer is always first and Search Folders is always last */
+ /* On This Computer is always first, and Search Folders
+ * is always last. */
if (!strcmp (aname, _("On This Computer")))
rv = -1;
else if (!strcmp (bname, _("On This Computer")))
@@ -197,13 +150,13 @@ sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data
else if (!strcmp (bname, _("Search Folders")))
rv = -1;
} else if (store == vfolder_store) {
- /* UNMATCHED is always last */
+ /* UNMATCHED is always last. */
if (aname && !strcmp (aname, _("UNMATCHED")))
rv = 1;
else if (bname && !strcmp (bname, _("UNMATCHED")))
rv = -1;
} else {
- /* Inbox is always first */
+ /* Inbox is always first. */
if ((aflags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
rv = -1;
else if ((bflags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
@@ -226,136 +179,203 @@ sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data
}
static void
-store_info_free (struct _EMFolderTreeModelStoreInfo *si)
+account_changed_cb (EAccountList *accounts,
+ EAccount *account,
+ EMFolderTreeModel *model)
{
- camel_object_remove_event (si->store, si->created_id);
- camel_object_remove_event (si->store, si->deleted_id);
- camel_object_remove_event (si->store, si->renamed_id);
- camel_object_remove_event (si->store, si->subscribed_id);
- camel_object_remove_event (si->store, si->unsubscribed_id);
+ EMFolderTreeModelStoreInfo *si;
+ CamelProvider *provider;
+ CamelStore *store;
+ CamelException ex;
+ gchar *uri;
- g_free (si->display_name);
- camel_object_unref (si->store);
- gtk_tree_row_reference_free (si->row);
- g_hash_table_destroy (si->full_hash);
- g_free (si);
-}
+ si = g_hash_table_lookup (model->priv->account_index, account);
+ if (si == NULL)
+ return;
-static void
-emft_model_unread_count_changed (GtkTreeModel *model, GtkTreeIter *iter)
-{
- GtkTreeIter parent_iter;
- GtkTreeIter child_iter = *iter;
+ em_folder_tree_model_remove_store (model, si->store);
- g_signal_handlers_block_by_func (
- model, emft_model_unread_count_changed, NULL);
+ /* check if store needs to be added at all*/
+ if (!account->enabled ||!(uri = account->source->url))
+ return;
- /* Folders are displayed with a bold weight to indicate that
- they contain unread messages. We signal that parent rows
- have changed here to update them. */
+ camel_exception_init (&ex);
+ if (!(provider = camel_provider_get(uri, &ex))) {
+ camel_exception_clear (&ex);
+ return;
+ }
- while (gtk_tree_model_iter_parent (model, &parent_iter, &child_iter)) {
- GtkTreePath *parent_path;
+ /* make sure the new store belongs in the tree */
+ if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+ return;
- parent_path = gtk_tree_model_get_path (model, &parent_iter);
- gtk_tree_model_row_changed (model, parent_path, &parent_iter);
- gtk_tree_path_free (parent_path);
- child_iter = parent_iter;
+ if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
+ camel_exception_clear (&ex);
+ return;
}
- g_signal_handlers_unblock_by_func (
- model, emft_model_unread_count_changed, NULL);
+ em_folder_tree_model_add_store (model, store, account->name);
+ camel_object_unref (store);
}
static void
-em_folder_tree_model_init (EMFolderTreeModel *model)
+account_removed_cb (EAccountList *accounts,
+ EAccount *account,
+ EMFolderTreeModel *model)
{
- model->store_hash = g_hash_table_new_full (
- g_direct_hash, g_direct_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) store_info_free);
+ EMFolderTreeModelStoreInfo *si;
- model->uri_hash = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) gtk_tree_row_reference_free);
-
- gtk_tree_sortable_set_default_sort_func ((GtkTreeSortable *) model, sort_cb, NULL, NULL);
+ si = g_hash_table_lookup (model->priv->account_index, account);
+ if (si == NULL)
+ return;
- model->accounts = mail_config_get_accounts ();
- model->account_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
- model->account_changed_id = g_signal_connect (model->accounts, "account-changed", G_CALLBACK (account_changed), model);
- model->account_removed_id = g_signal_connect (model->accounts, "account-removed", G_CALLBACK (account_removed), model);
- /* g_signal_connect (model, "row-changed", G_CALLBACK (emft_model_unread_count_changed), NULL); */
+ em_folder_tree_model_remove_store (model, si->store);
}
static void
-em_folder_tree_model_finalize (GObject *obj)
+folder_tree_model_selection_finalized_cb (EMFolderTreeModel *model)
{
- EMFolderTreeModel *model = (EMFolderTreeModel *) obj;
+ model->priv->selection = NULL;
- g_free (model->filename);
- if (model->state)
- xmlFreeDoc (model->state);
-
- g_hash_table_destroy (model->store_hash);
- g_hash_table_destroy (model->uri_hash);
+ g_object_notify (G_OBJECT (model), "selection");
+}
- g_hash_table_destroy (model->account_hash);
- g_signal_handler_disconnect (model->accounts, model->account_changed_id);
- g_signal_handler_disconnect (model->accounts, model->account_removed_id);
+static void
+folder_tree_model_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SELECTION:
+ em_folder_tree_model_set_selection (
+ EM_FOLDER_TREE_MODEL (object),
+ g_value_get_object (value));
+ return;
+ }
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-tree_model_iface_init (GtkTreeModelIface *iface)
+folder_tree_model_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- ;
+ switch (property_id) {
+ case PROP_SELECTION:
+ g_value_set_object (
+ value,
+ em_folder_tree_model_get_selection (
+ EM_FOLDER_TREE_MODEL (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-tree_sortable_iface_init (GtkTreeSortableIface *iface)
+folder_tree_model_dispose (GObject *object)
{
- ;
+ EMFolderTreeModelPrivate *priv;
+
+ priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (object);
+
+ if (priv->selection != NULL) {
+ g_object_weak_unref (
+ G_OBJECT (priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, object);
+ priv->selection = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-em_folder_tree_model_load_state (EMFolderTreeModel *model, const gchar *filename)
+folder_tree_model_finalize (GObject *object)
{
- xmlNodePtr root, node;
+ EMFolderTreeModelPrivate *priv;
- if (model->state)
- xmlFreeDoc (model->state);
+ priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (object);
- if ((model->state = e_xml_parse_file (filename)) != NULL) {
- node = xmlDocGetRootElement (model->state);
- if (!node || strcmp ((gchar *)node->name, "tree-state") != 0) {
- /* it is not expected XML file, thus free it and use the default */
- xmlFreeDoc (model->state);
- } else
- return;
- }
+ g_hash_table_destroy (priv->account_index);
+ g_hash_table_destroy (priv->store_index);
+ g_hash_table_destroy (priv->uri_index);
- /* setup some defaults - expand "Local Folders" and "Search Folders" */
- model->state = xmlNewDoc ((const guchar *)"1.0");
- root = xmlNewDocNode (model->state, NULL, (const guchar *)"tree-state", NULL);
- xmlDocSetRootElement (model->state, root);
+ g_signal_handler_disconnect (
+ priv->accounts, priv->account_changed_id);
+ g_signal_handler_disconnect (
+ priv->accounts, priv->account_removed_id);
- node = xmlNewChild (root, NULL, (const guchar *)"node", NULL);
- xmlSetProp (node, (const guchar *)"name", (const guchar *)"local");
- xmlSetProp (node, (const guchar *)"expand", (const guchar *)"true");
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
- node = xmlNewChild (root, NULL, (const guchar *)"node", NULL);
- xmlSetProp (node, (const guchar *)"name", (const guchar *)"vfolder");
- xmlSetProp (node, (const guchar *)"expand", (const guchar *)"true");
+static void
+folder_tree_model_class_init (EMFolderTreeModelClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFolderTreeModelPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = folder_tree_model_set_property;
+ object_class->get_property = folder_tree_model_get_property;
+ object_class->dispose = folder_tree_model_dispose;
+ object_class->finalize = folder_tree_model_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTION,
+ g_param_spec_object (
+ "selection",
+ "Selection",
+ NULL,
+ GTK_TYPE_TREE_SELECTION,
+ G_PARAM_READWRITE));
+
+ signals[LOADING_ROW] = g_signal_new (
+ "loading-row",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeModelClass, loading_row),
+ NULL, NULL,
+ e_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ signals[LOADED_ROW] = g_signal_new (
+ "loaded-row",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeModelClass, loaded_row),
+ NULL, NULL,
+ e_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ signals[FOLDER_ADDED] = g_signal_new (
+ "folder-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeModelClass, folder_added),
+ NULL, NULL,
+ e_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
}
-EMFolderTreeModel *
-em_folder_tree_model_new (const gchar *evolution_dir)
+static void
+folder_tree_model_init (EMFolderTreeModel *model)
{
- EMFolderTreeModel *model;
- gchar *filename;
+ GHashTable *store_index;
+ GHashTable *uri_index;
GType col_types[] = {
G_TYPE_STRING, /* display name */
@@ -371,80 +391,134 @@ em_folder_tree_model_new (const gchar *evolution_dir)
G_TYPE_UINT /* last known unread count */
};
- model = g_object_new (EM_TYPE_FOLDER_TREE_MODEL, NULL);
- gtk_tree_store_set_column_types ((GtkTreeStore *) model, NUM_COLUMNS, col_types);
- gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable *) model,
- GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
- GTK_SORT_ASCENDING);
+ store_index = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) store_info_free);
- filename = g_build_filename (evolution_dir, "mail", "config", "folder-tree-expand-state.xml", NULL);
- em_folder_tree_model_load_state (model, filename);
- model->filename = filename;
+ uri_index = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) gtk_tree_row_reference_free);
- return model;
+ model->priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (model);
+ model->priv->store_index = store_index;
+ model->priv->uri_index = uri_index;
+
+ gtk_tree_store_set_column_types (
+ GTK_TREE_STORE (model), NUM_COLUMNS, col_types);
+ gtk_tree_sortable_set_default_sort_func (
+ GTK_TREE_SORTABLE (model),
+ folder_tree_model_sort, NULL, NULL);
+ gtk_tree_sortable_set_sort_column_id (
+ GTK_TREE_SORTABLE (model),
+ GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+ GTK_SORT_ASCENDING);
+
+ model->priv->accounts = e_get_account_list ();
+ model->priv->account_index =
+ g_hash_table_new (g_direct_hash, g_direct_equal);
+ model->priv->account_changed_id = g_signal_connect (
+ model->priv->accounts, "account-changed",
+ G_CALLBACK (account_changed_cb), model);
+ model->priv->account_removed_id = g_signal_connect (
+ model->priv->accounts, "account-removed",
+ G_CALLBACK (account_removed_cb), model);
}
-static void
-account_changed (EAccountList *accounts, EAccount *account, gpointer user_data)
+GType
+em_folder_tree_model_get_type (void)
{
- EMFolderTreeModel *model = user_data;
- struct _EMFolderTreeModelStoreInfo *si;
- CamelProvider *provider;
- CamelStore *store;
- CamelException ex;
- gchar *uri;
+ static GType type = 0;
- if (!(si = g_hash_table_lookup (model->account_hash, account)))
- return;
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderTreeModelClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_tree_model_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderTreeModel),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_tree_model_init,
+ NULL /* value_table */
+ };
- em_folder_tree_model_remove_store (model, si->store);
+ type = g_type_register_static (
+ GTK_TYPE_TREE_STORE, "EMFolderTreeModel",
+ &type_info, 0);
+ }
- /* check if store needs to be added at all*/
- if (!account->enabled ||!(uri = account->source->url))
- return;
+ return type;
+}
- camel_exception_init (&ex);
- if (!(provider = camel_provider_get(uri, &ex))) {
- camel_exception_clear (&ex);
- return;
- }
+EMFolderTreeModel *
+em_folder_tree_model_new (void)
+{
+ return g_object_new (EM_TYPE_FOLDER_TREE_MODEL, NULL);
+}
- /* make sure the new store belongs in the tree */
- if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
- return;
+EMFolderTreeModel *
+em_folder_tree_model_get_default (void)
+{
+ static EMFolderTreeModel *default_folder_tree_model;
- if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
- camel_exception_clear (&ex);
- return;
- }
+ if (G_UNLIKELY (default_folder_tree_model == NULL))
+ default_folder_tree_model = em_folder_tree_model_new ();
- em_folder_tree_model_add_store (model, store, account->name);
- camel_object_unref (store);
+ return default_folder_tree_model;
}
-static void
-account_removed (EAccountList *accounts, EAccount *account, gpointer user_data)
+GtkTreeSelection *
+em_folder_tree_model_get_selection (EMFolderTreeModel *model)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
+
+ return GTK_TREE_SELECTION (model->priv->selection);
+}
+
+void
+em_folder_tree_model_set_selection (EMFolderTreeModel *model,
+ GtkTreeSelection *selection)
{
- EMFolderTreeModel *model = user_data;
- struct _EMFolderTreeModelStoreInfo *si;
+ g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
- if (!(si = g_hash_table_lookup (model->account_hash, account)))
- return;
+ if (selection != NULL)
+ g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
- em_folder_tree_model_remove_store (model, si->store);
+ if (model->priv->selection != NULL) {
+ g_object_weak_unref (
+ G_OBJECT (model->priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, model);
+ model->priv->selection = NULL;
+ }
+
+ model->priv->selection = selection;
+
+ if (model->priv->selection != NULL)
+ g_object_weak_ref (
+ G_OBJECT (model->priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, model);
+
+ g_object_notify (G_OBJECT (model), "selection");
}
void
-em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *iter,
- struct _EMFolderTreeModelStoreInfo *si,
- CamelFolderInfo *fi, gint fully_loaded)
+em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
+ GtkTreeIter *iter,
+ EMFolderTreeModelStoreInfo *si,
+ CamelFolderInfo *fi,
+ gint fully_loaded)
{
GtkTreeRowReference *uri_row, *path_row;
GtkTreeStore *tree_store;
guint unread;
GtkTreePath *path;
GtkTreeIter sub;
- gboolean load = FALSE, is_drafts = FALSE, is_templates = FALSE;
+ gboolean load = FALSE;
+ gboolean is_drafts = FALSE;
+ gboolean is_templates = FALSE;
CamelFolder *folder;
gboolean emitted = FALSE;
const gchar *name;
@@ -461,20 +535,28 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
if (!fully_loaded)
load = fi->child == NULL && !(fi->flags & (CAMEL_FOLDER_NOCHILDREN | CAMEL_FOLDER_NOINFERIORS));
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
- uri_row = gtk_tree_row_reference_new ((GtkTreeModel *) model, path);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
+ uri_row = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path);
path_row = gtk_tree_row_reference_copy (uri_row);
gtk_tree_path_free (path);
- g_hash_table_insert (model->uri_hash, g_strdup (fi->uri), uri_row);
- g_hash_table_insert (si->full_hash, g_strdup (fi->full_name), path_row);
+ g_hash_table_insert (
+ model->priv->uri_index, g_strdup (fi->uri), uri_row);
+ g_hash_table_insert (
+ si->full_hash, g_strdup (fi->full_name), path_row);
/* HACK: if we have the folder, and its the outbox folder, we need the total count, not unread */
/* HACK2: We do the same to the draft folder */
/* This is duplicated in mail-folder-cache too, should perhaps be functionised */
unread = fi->unread;
if (mail_note_get_folder_from_uri(fi->uri, &folder) && folder) {
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)) {
+ CamelFolder *local_drafts;
+ CamelFolder *local_outbox;
+
+ local_drafts = e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+
+ if (folder == local_outbox) {
gint total;
if ((total = camel_folder_get_message_count (folder)) > 0) {
@@ -486,7 +568,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
unread = total > 0 ? total : 0;
}
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)) {
+ if (folder == local_drafts) {
gint total;
if ((total = camel_folder_get_message_count (folder)) > 0) {
@@ -505,7 +587,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
/* TODO: maybe this should be handled by mail_get_folderinfo (except em-folder-tree doesn't use it, duh) */
flags = fi->flags;
name = fi->name;
- if (si->store == mail_component_peek_local_store(NULL)) {
+ if (si->store == e_mail_local_get_store ()) {
if (!strcmp(fi->full_name, "Drafts")) {
name = _("Drafts");
is_drafts = TRUE;
@@ -589,7 +671,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
COL_UINT_UNREAD_LAST_SEL, 0,
-1);
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
g_signal_emit (model, signals[LOADING_ROW], 0, path, iter);
gtk_tree_path_free (path);
return;
@@ -602,7 +684,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
gtk_tree_store_append (tree_store, &sub, iter);
if (!emitted) {
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
g_signal_emit (model, signals[LOADED_ROW], 0, path, iter);
gtk_tree_path_free (path);
emitted = TRUE;
@@ -614,23 +696,26 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
}
if (!emitted) {
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
g_signal_emit (model, signals[LOADED_ROW], 0, path, iter);
gtk_tree_path_free (path);
}
}
static void
-folder_subscribed (CamelStore *store, CamelFolderInfo *fi, EMFolderTreeModel *model)
+folder_subscribed (CamelStore *store,
+ CamelFolderInfo *fi,
+ EMFolderTreeModel *model)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
GtkTreeIter parent, iter;
GtkTreePath *path;
gboolean load;
gchar *dirname, *p;
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
goto done;
/* make sure we don't already know about it? */
@@ -643,140 +728,159 @@ folder_subscribed (CamelStore *store, CamelFolderInfo *fi, EMFolderTreeModel *mo
p = strrchr(dirname, '/');
if (p == NULL) {
/* user subscribed to a toplevel folder */
- row = si->row;
+ reference = si->row;
} else {
*p = 0;
- row = g_hash_table_lookup (si->full_hash, dirname);
-
- /* if row is NULL, don't bother adding to the tree,
- * when the user expands enough nodes - it will be
- * added auto-magically */
- if (row == NULL)
- goto done;
+ reference = g_hash_table_lookup (si->full_hash, dirname);
}
- path = gtk_tree_row_reference_get_path (row);
- if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &parent, path))) {
- gtk_tree_path_free (path);
+ if (!gtk_tree_row_reference_valid (reference))
goto done;
- }
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent, path);
gtk_tree_path_free (path);
/* make sure parent's subfolders have already been loaded */
- gtk_tree_model_get ((GtkTreeModel *) model, &parent, COL_BOOL_LOAD_SUBDIRS, &load, -1);
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &parent,
+ COL_BOOL_LOAD_SUBDIRS, &load, -1);
if (load)
goto done;
/* append a new node */
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, &parent);
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent);
em_folder_tree_model_set_folder_info (model, &iter, si, fi, TRUE);
g_signal_emit (model, signals[FOLDER_ADDED], 0, fi->full_name, fi->uri);
- done:
-
+done:
camel_object_unref (store);
camel_folder_info_free (fi);
}
static void
-folder_subscribed_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_subscribed_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelFolderInfo *fi;
camel_object_ref (store);
fi = camel_folder_info_clone (event_data);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_subscribed, store, fi, model);
+
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_subscribed, store, fi, model);
}
static void
-folder_unsubscribed (CamelStore *store, CamelFolderInfo *fi, EMFolderTreeModel *model)
+folder_unsubscribed (CamelStore *store,
+ CamelFolderInfo *fi,
+ EMFolderTreeModel *model)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
GtkTreePath *path;
GtkTreeIter iter;
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
goto done;
- if (!(row = g_hash_table_lookup (si->full_hash, fi->full_name)))
+ reference = g_hash_table_lookup (si->full_hash, fi->full_name);
+ if (!gtk_tree_row_reference_valid (reference))
goto done;
- path = gtk_tree_row_reference_get_path (row);
- if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path))) {
- gtk_tree_path_free (path);
- goto done;
- }
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ gtk_tree_path_free (path);
em_folder_tree_model_remove_folders (model, si, &iter);
- done:
-
+done:
camel_object_unref (store);
camel_folder_info_free (fi);
}
static void
-folder_unsubscribed_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_unsubscribed_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelFolderInfo *fi;
camel_object_ref (store);
fi = camel_folder_info_clone (event_data);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_unsubscribed, store, fi, model);
+
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_unsubscribed, store, fi, model);
}
static void
-folder_created_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_created_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelFolderInfo *fi;
- /* we only want created events to do more work if we don't support subscriptions */
+ /* We only want created events to do more
+ * work if we don't support subscriptions. */
if (camel_store_supports_subscriptions (store))
return;
camel_object_ref (store);
fi = camel_folder_info_clone (event_data);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_subscribed, store, fi, model);
+
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_subscribed, store, fi, model);
}
static void
-folder_deleted_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_deleted_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelFolderInfo *fi;
- /* we only want deleted events to do more work if we don't support subscriptions */
+ /* We only want deleted events to do more
+ * work if we don't support subscriptions. */
if (camel_store_supports_subscriptions (store))
return;
camel_object_ref (store);
fi = camel_folder_info_clone (event_data);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_unsubscribed_cb, store, fi, model);
+
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_unsubscribed_cb, store, fi, model);
}
static void
-folder_renamed (CamelStore *store, CamelRenameInfo *info, EMFolderTreeModel *model)
+folder_renamed (CamelStore *store,
+ CamelRenameInfo *info,
+ EMFolderTreeModel *model)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
GtkTreeIter root, iter;
GtkTreePath *path;
gchar *parent, *p;
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
goto done;
- if (!(row = g_hash_table_lookup (si->full_hash, info->old_base)))
+ reference = g_hash_table_lookup (si->full_hash, info->old_base);
+ if (!gtk_tree_row_reference_valid (reference))
goto done;
- path = gtk_tree_row_reference_get_path (row);
- if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path))) {
- gtk_tree_path_free (path);
- goto done;
- }
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ gtk_tree_path_free (path);
em_folder_tree_model_remove_folders (model, si, &iter);
@@ -784,36 +888,25 @@ folder_renamed (CamelStore *store, CamelRenameInfo *info, EMFolderTreeModel *mod
p = strrchr(parent, '/');
if (p)
*p = 0;
- if (p == NULL || parent == p) {
+ if (p == NULL || parent == p)
/* renamed to a toplevel folder on the store */
- path = gtk_tree_row_reference_get_path (si->row);
- } else {
- if (!(row = g_hash_table_lookup (si->full_hash, parent))) {
- /* NOTE: this should never happen, but I
- * suppose if it does in reality, we can add
- * code here to add the missing nodes to the
- * tree */
- g_warning ("This shouldn't be reached\n");
- g_free (parent);
- goto done;
- }
-
- path = gtk_tree_row_reference_get_path (row);
- }
+ reference = si->row;
+ else
+ reference = g_hash_table_lookup (si->full_hash, parent);
g_free (parent);
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &root, path)) {
- gtk_tree_path_free (path);
- g_warning ("This shouldn't be reached\n");
+ if (!gtk_tree_row_reference_valid (reference))
goto done;
- }
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, &root);
- em_folder_tree_model_set_folder_info (model, &iter, si, info->new, TRUE);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &root, path);
+ gtk_tree_path_free (path);
- done:
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &root);
+ em_folder_tree_model_set_folder_info (model, &iter, si, info->new, TRUE);
+done:
camel_object_unref (store);
g_free (info->old_base);
@@ -822,7 +915,9 @@ folder_renamed (CamelStore *store, CamelRenameInfo *info, EMFolderTreeModel *mod
}
static void
-folder_renamed_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_renamed_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelRenameInfo *rinfo, *info = event_data;
@@ -832,14 +927,19 @@ folder_renamed_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *mo
rinfo->old_base = g_strdup (info->old_base);
rinfo->new = camel_folder_info_clone (info->new);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_renamed, store, rinfo, model);
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_renamed, store, rinfo, model);
}
void
-em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, const gchar *display_name)
+em_folder_tree_model_add_store (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *display_name)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
+ GtkTreeStore *tree_store;
GtkTreeIter root, iter;
GtkTreePath *path;
EAccount *account;
@@ -849,62 +949,77 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, con
g_return_if_fail (CAMEL_IS_STORE (store));
g_return_if_fail (display_name != NULL);
- if ((si = g_hash_table_lookup (model->store_hash, store)))
+ tree_store = GTK_TREE_STORE (model);
+
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si != NULL)
em_folder_tree_model_remove_store (model, store);
- uri = camel_url_to_string (((CamelService *) store)->url, CAMEL_URL_HIDE_ALL);
+ uri = camel_url_to_string (
+ ((CamelService *) store)->url, CAMEL_URL_HIDE_ALL);
account = mail_config_get_account_by_source_url (uri);
/* add the store to the tree */
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, NULL);
- gtk_tree_store_set ((GtkTreeStore *) model, &iter,
- COL_STRING_DISPLAY_NAME, display_name,
- COL_POINTER_CAMEL_STORE, store,
- COL_STRING_FULL_NAME, NULL,
- COL_BOOL_LOAD_SUBDIRS, TRUE,
- COL_BOOL_IS_STORE, TRUE,
- COL_STRING_URI, uri, -1);
-
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, &iter);
- row = gtk_tree_row_reference_new ((GtkTreeModel *) model, path);
-
- si = g_new (struct _EMFolderTreeModelStoreInfo, 1);
+ gtk_tree_store_append (tree_store, &iter, NULL);
+ gtk_tree_store_set (
+ tree_store, &iter,
+ COL_STRING_DISPLAY_NAME, display_name,
+ COL_POINTER_CAMEL_STORE, store,
+ COL_STRING_FULL_NAME, NULL,
+ COL_BOOL_LOAD_SUBDIRS, TRUE,
+ COL_BOOL_IS_STORE, TRUE,
+ COL_STRING_URI, uri, -1);
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+ reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path);
+
+ si = g_new (EMFolderTreeModelStoreInfo, 1);
si->display_name = g_strdup (display_name);
camel_object_ref (store);
si->store = store;
si->account = account;
- si->row = row;
+ si->row = gtk_tree_row_reference_copy (reference);
si->full_hash = g_hash_table_new_full (
g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) gtk_tree_row_reference_free);
- g_hash_table_insert (model->store_hash, store, si);
- g_hash_table_insert (model->account_hash, account, si);
+ g_hash_table_insert (model->priv->store_index, store, si);
+ g_hash_table_insert (model->priv->account_index, account, si);
+
+ /* Transfer ownership of the URI and GtkTreeRowReference. */
+ g_hash_table_insert (model->priv->uri_index, uri, reference);
/* each store has folders... but we don't load them until the user demands them */
root = iter;
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, &root);
- gtk_tree_store_set ((GtkTreeStore *) model, &iter,
- COL_STRING_DISPLAY_NAME, _("Loading..."),
- COL_POINTER_CAMEL_STORE, NULL,
- COL_STRING_FULL_NAME, NULL,
- COL_BOOL_LOAD_SUBDIRS, FALSE,
- COL_BOOL_IS_STORE, FALSE,
- COL_STRING_URI, NULL,
- COL_UINT_UNREAD, 0,
- COL_UINT_UNREAD_LAST_SEL, 0,
- -1);
-
- g_free (uri);
+ gtk_tree_store_append (tree_store, &iter, &root);
+ gtk_tree_store_set (
+ tree_store, &iter,
+ COL_STRING_DISPLAY_NAME, _("Loading..."),
+ COL_POINTER_CAMEL_STORE, NULL,
+ COL_STRING_FULL_NAME, NULL,
+ COL_BOOL_LOAD_SUBDIRS, FALSE,
+ COL_BOOL_IS_STORE, FALSE,
+ COL_STRING_URI, NULL,
+ COL_UINT_UNREAD, 0,
+ COL_UINT_UNREAD_LAST_SEL, 0, -1);
/* listen to store events */
-#define CAMEL_CALLBACK(func) ((CamelObjectEventHookFunc) func)
- si->created_id = camel_object_hook_event (store, "folder_created", CAMEL_CALLBACK (folder_created_cb), model);
- si->deleted_id = camel_object_hook_event (store, "folder_deleted", CAMEL_CALLBACK (folder_deleted_cb), model);
- si->renamed_id = camel_object_hook_event (store, "folder_renamed", CAMEL_CALLBACK (folder_renamed_cb), model);
- si->subscribed_id = camel_object_hook_event (store, "folder_subscribed", CAMEL_CALLBACK (folder_subscribed_cb), model);
- si->unsubscribed_id = camel_object_hook_event (store, "folder_unsubscribed", CAMEL_CALLBACK (folder_unsubscribed_cb), model);
+ si->created_id = camel_object_hook_event (
+ store, "folder_created",
+ (CamelObjectEventHookFunc) folder_created_cb, model);
+ si->deleted_id = camel_object_hook_event (
+ store, "folder_deleted",
+ (CamelObjectEventHookFunc) folder_deleted_cb, model);
+ si->renamed_id = camel_object_hook_event (
+ store, "folder_renamed",
+ (CamelObjectEventHookFunc) folder_renamed_cb, model);
+ si->subscribed_id = camel_object_hook_event (
+ store, "folder_subscribed",
+ (CamelObjectEventHookFunc) folder_subscribed_cb, model);
+ si->unsubscribed_id = camel_object_hook_event (
+ store, "folder_unsubscribed",
+ (CamelObjectEventHookFunc) folder_unsubscribed_cb, model);
g_signal_emit (model, signals[LOADED_ROW], 0, path, &root);
gtk_tree_path_free (path);
@@ -916,50 +1031,55 @@ em_folder_tree_model_remove_uri (EMFolderTreeModel *model, const gchar *uri)
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (uri != NULL);
- g_hash_table_remove (model->uri_hash, uri);
+ g_hash_table_remove (model->priv->uri_index, uri);
}
static void
-em_folder_tree_model_remove_store_info (EMFolderTreeModel *model, CamelStore *store)
+em_folder_tree_model_remove_store_info (EMFolderTreeModel *model,
+ CamelStore *store)
{
- struct _EMFolderTreeModelStoreInfo *si;
+ EMFolderTreeModelStoreInfo *si;
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (CAMEL_IS_STORE (store));
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return;
- g_hash_table_remove (model->account_hash, si->account);
- /* store_hash owns and frees the si structure, thus free it after done with it */
- g_hash_table_remove (model->store_hash, si->store);
+ g_hash_table_remove (model->priv->account_index, si->account);
+ g_hash_table_remove (model->priv->store_index, si->store);
}
void
-em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderTreeModelStoreInfo *si, GtkTreeIter *toplevel)
+em_folder_tree_model_remove_folders (EMFolderTreeModel *model,
+ EMFolderTreeModelStoreInfo *si,
+ GtkTreeIter *toplevel)
{
gchar *uri, *full_name;
gboolean is_store, go;
GtkTreeIter iter;
- if (gtk_tree_model_iter_children ((GtkTreeModel *) model, &iter, toplevel)) {
+ if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, toplevel)) {
do {
GtkTreeIter next = iter;
- go = gtk_tree_model_iter_next ((GtkTreeModel *) model, &next);
+ go = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &next);
em_folder_tree_model_remove_folders (model, si, &iter);
iter = next;
} while (go);
}
- gtk_tree_model_get ((GtkTreeModel *) model, toplevel, COL_STRING_URI, &uri,
- COL_STRING_FULL_NAME, &full_name,
- COL_BOOL_IS_STORE, &is_store, -1);
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), toplevel,
+ COL_STRING_URI, &uri,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_BOOL_IS_STORE, &is_store, -1);
- if (full_name)
+ if (full_name != NULL)
g_hash_table_remove (si->full_hash, full_name);
- if (uri)
+ if (uri != NULL)
em_folder_tree_model_remove_uri (model, uri);
gtk_tree_store_remove ((GtkTreeStore *) model, toplevel);
@@ -972,298 +1092,36 @@ em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderT
}
void
-em_folder_tree_model_remove_store (EMFolderTreeModel *model, CamelStore *store)
+em_folder_tree_model_remove_store (EMFolderTreeModel *model,
+ CamelStore *store)
{
- struct _EMFolderTreeModelStoreInfo *si;
+ EMFolderTreeModelStoreInfo *si;
GtkTreePath *path;
GtkTreeIter iter;
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (CAMEL_IS_STORE (store));
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return;
path = gtk_tree_row_reference_get_path (si->row);
- gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
gtk_tree_path_free (path);
/* recursively remove subfolders and finally the toplevel store */
em_folder_tree_model_remove_folders (model, si, &iter);
}
-static xmlNodePtr
-find_xml_node (xmlNodePtr root, const gchar *name)
-{
- xmlNodePtr node;
- gchar *nname;
-
- node = root->children;
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "node")) {
- nname = (gchar *)xmlGetProp (node, (const guchar *)"name");
- if (nname && !strcmp (nname, name)) {
- xmlFree (nname);
- return node;
- }
-
- xmlFree (nname);
- }
-
- node = node->next;
- }
-
- return node;
-}
-
-gboolean
-em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const gchar *key)
-{
- xmlNodePtr node;
- const gchar *name;
- gchar *buf, *p;
-
- /* This code needs to be rewritten.
- First it doesn't belong on the model
- Second, it shouldn't use an xml tree to store a bit table in memory! */
-
- node = model->state ? model->state->children : NULL;
- if (!node || strcmp ((gchar *)node->name, "tree-state") != 0)
- return FALSE;
-
- name = buf = g_alloca (strlen (key) + 1);
- p = g_stpcpy (buf, key);
- if (p[-1] == '/')
- p[-1] = '\0';
- p = NULL;
-
- do {
- if ((p = strchr (name, '/')))
- *p = '\0';
-
- if ((node = find_xml_node (node, name))) {
- gboolean expanded;
-
- buf = (gchar *)xmlGetProp (node, (const guchar *)"expand");
- expanded = buf && !strcmp ((gchar *)buf, "true");
- xmlFree (buf);
-
- if (!expanded || p == NULL)
- return expanded;
- }
-
- name = p ? p + 1 : NULL;
- } while (name && node);
-
- return FALSE;
-}
-
-void
-em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const gchar *key, gboolean expanded)
-{
- xmlNodePtr node, parent;
- const gchar *name;
- gchar *buf, *p;
-
- if (model->state == NULL)
- model->state = xmlNewDoc ((const guchar *)"1.0");
-
- if (!model->state->children) {
- node = xmlNewDocNode (model->state, NULL, (const guchar *)"tree-state", NULL);
- xmlDocSetRootElement (model->state, node);
- } else {
- node = model->state->children;
- }
-
- name = buf = g_alloca (strlen (key) + 1);
- p = g_stpcpy (buf, key);
- if (p[-1] == '/')
- p[-1] = '\0';
- p = NULL;
-
- do {
- parent = node;
- if ((p = strchr (name, '/')))
- *p = '\0';
-
- if (!(node = find_xml_node (node, name))) {
- if (!expanded) {
- /* node doesn't exist, so we don't need to set expanded to FALSE */
- return;
- }
-
- /* node (or parent node) doesn't exist, need to add it */
- node = xmlNewChild (parent, NULL, (const guchar *)"node", NULL);
- xmlSetProp (node, (const guchar *)"name", (guchar *)name);
- }
-
- xmlSetProp (node, (const guchar *)"expand", (const guchar *)(expanded || p ? "true" : "false"));
-
- name = p ? p + 1 : NULL;
- } while (name);
-}
-
-/**
- * emftm_uri_to_key
- * Converts uri to key used in functions like em_folder_tree_model_[s/g]et_expanded.
- * @param uri Uri to be converted.
- * @return Key of the uri or NULL, if failed. Returned value should be clear by g_free.
- **/
-static gchar *
-emftm_uri_to_key (const gchar *uri)
-{
- CamelException ex = { 0 };
- CamelStore *store;
- CamelURL *url;
- gchar *key;
-
- if (!uri)
- return NULL;
-
- store = (CamelStore *)camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex);
- camel_exception_clear(&ex);
-
- url = camel_url_new (uri, NULL);
-
- if (store == NULL || url == NULL) {
- key = NULL;
- } else {
- const gchar *path;
- EAccount *account;
-
- if (((CamelService *)store)->provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH)
- path = url->fragment;
- else
- path = url->path && url->path[0]=='/' ? url->path+1:url->path;
-
- if (path == NULL)
- path = "";
-
- if ( (account = mail_config_get_account_by_source_url (uri)) )
- key = g_strdup_printf ("%s/%s", account->uid, path);
- else if (CAMEL_IS_VEE_STORE (store))
- key = g_strdup_printf ("vfolder/%s", path);
- else
- key = g_strdup_printf ("local/%s", path);
- }
-
- if (url)
- camel_url_free (url);
-
- if (store)
- camel_object_unref (store);
-
- return key;
-}
-
-/**
- * em_folder_tree_model_get_expanded_uri
- * Same as @ref em_folder_tree_model_get_expanded, but here we use uri, not key for node.
- **/
gboolean
-em_folder_tree_model_get_expanded_uri (EMFolderTreeModel *model, const gchar *uri)
+em_folder_tree_model_is_type_inbox (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full)
{
- gchar *key;
- gboolean expanded;
-
- g_return_val_if_fail (model != NULL, FALSE);
- g_return_val_if_fail (uri != NULL, FALSE);
-
- key = emftm_uri_to_key (uri);
- expanded = key && em_folder_tree_model_get_expanded (model, key);
-
- g_free (key);
-
- return expanded;
-}
-
-/**
- * em_folder_tree_model_set_expanded_uri
- * Same as @ref em_folder_tree_model_set_expanded, but here we use uri, not key for node.
- **/
-void
-em_folder_tree_model_set_expanded_uri (EMFolderTreeModel *model, const gchar *uri, gboolean expanded)
-{
- gchar *key;
-
- g_return_if_fail (model != NULL);
- g_return_if_fail (uri != NULL);
-
- key = emftm_uri_to_key (uri);
- if (key)
- em_folder_tree_model_set_expanded (model, key, expanded);
-
- g_free (key);
-}
-
-void
-em_folder_tree_model_save_state (EMFolderTreeModel *model)
-{
- gchar *dirname;
-
- if (model->state == NULL)
- return;
-
- dirname = g_path_get_dirname (model->filename);
- if (g_mkdir_with_parents (dirname, 0777) == -1 && errno != EEXIST) {
- g_free (dirname);
- return;
- }
-
- g_free (dirname);
-
- e_xml_save_file (model->filename, model->state);
-}
-
-static void
-expand_foreach_r (EMFolderTreeModel *model, xmlNodePtr parent, const gchar *dirname, EMFTModelExpandFunc func, gpointer user_data)
-{
- xmlNodePtr node = parent->children;
- gchar *path, *name, *expand;
-
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "node")) {
- name = (gchar *)xmlGetProp (node, (const guchar *)"name");
- expand = (gchar *)xmlGetProp (node, (const guchar *)"expand");
-
- if (expand && name && !strcmp ((gchar *)expand, "true")) {
- if (dirname)
- path = g_strdup_printf ("%s/%s", dirname, name);
- else
- path = g_strdup (name);
-
- func (model, path, user_data);
- if (node->children)
- expand_foreach_r (model, node, path, func, user_data);
- g_free (path);
- }
-
- xmlFree (expand);
- xmlFree (name);
- }
-
- node = node->next;
- }
-}
-
-void
-em_folder_tree_model_expand_foreach (EMFolderTreeModel *model, EMFTModelExpandFunc func, gpointer user_data)
-{
- xmlNodePtr root;
-
- root = model->state ? model->state->children : NULL;
- if (!root || !root->children || strcmp ((gchar *)root->name, "tree-state") != 0)
- return;
-
- expand_foreach_r (model, root, NULL, func, user_data);
-}
-
-gboolean
-em_folder_tree_model_is_type_inbox (EMFolderTreeModel *model, CamelStore *store, const gchar *full)
-{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
- GtkTreePath *tree_path;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
GtkTreeIter iter;
guint32 flags;
@@ -1271,40 +1129,33 @@ em_folder_tree_model_is_type_inbox (EMFolderTreeModel *model, CamelStore *store,
g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
g_return_val_if_fail (full != NULL, FALSE);
- u(printf("Checking if the folder is an INBOX type %p '%s' %d\n", store, full, unread));
-
- if (!(si = g_hash_table_lookup (model->store_hash, store))) {
- u(printf(" can't find store\n"));
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return FALSE;
- }
- if (!(row = g_hash_table_lookup (si->full_hash, full))) {
- u(printf(" can't find row\n"));
+ reference = g_hash_table_lookup (si->full_hash, full);
+ if (!gtk_tree_row_reference_valid (reference))
return FALSE;
- }
- tree_path = gtk_tree_row_reference_get_path (row);
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, tree_path)) {
- gtk_tree_path_free (tree_path);
- return FALSE;
- }
-
- gtk_tree_path_free (tree_path);
-
- gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, COL_UINT_FLAGS, &flags, -1);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ gtk_tree_path_free (path);
- if ((flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
- return TRUE;
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &iter,
+ COL_UINT_FLAGS, &flags, -1);
- return FALSE;
+ return ((flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX);
}
gchar *
-em_folder_tree_model_get_folder_name (EMFolderTreeModel *model, CamelStore *store, const gchar *full)
+em_folder_tree_model_get_folder_name (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
- GtkTreePath *tree_path;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
GtkTreeIter iter;
gchar *name = NULL;
@@ -1312,140 +1163,100 @@ em_folder_tree_model_get_folder_name (EMFolderTreeModel *model, CamelStore *stor
g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
g_return_val_if_fail (full != NULL, NULL);
- if (!(si = g_hash_table_lookup (model->store_hash, store))) {
- u(printf(" can't find store\n"));
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return NULL;
- }
- if (!(row = g_hash_table_lookup (si->full_hash, full))) {
- u(printf(" can't find row\n"));
+ reference = g_hash_table_lookup (si->full_hash, full);
+ if (!gtk_tree_row_reference_valid (reference))
return NULL;
- }
- tree_path = gtk_tree_row_reference_get_path (row);
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, tree_path)) {
- gtk_tree_path_free (tree_path);
- return NULL;
- }
-
- gtk_tree_path_free (tree_path);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ gtk_tree_path_free (path);
- gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, COL_STRING_DISPLAY_NAME, &name, -1);
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &iter,
+ COL_STRING_DISPLAY_NAME, &name, -1);
return name;
}
void
-em_folder_tree_model_set_unread_count (EMFolderTreeModel *model, CamelStore *store, const gchar *full, gint unread)
+em_folder_tree_model_set_unread_count (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full,
+ gint unread)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
- GtkTreePath *tree_path;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
+ GtkTreeModel *tree_model;
+ GtkTreePath *path;
+ GtkTreeIter parent;
GtkTreeIter iter;
guint old_unread = 0;
- gchar *uri, *sel_uri;
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (CAMEL_IS_STORE (store));
g_return_if_fail (full != NULL);
- u(printf("set unread count %p '%s' %d\n", store, full, unread));
-
if (unread < 0)
return;
- if (!(si = g_hash_table_lookup (model->store_hash, store))) {
- u(printf(" can't find store\n"));
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return;
- }
- if (!(row = g_hash_table_lookup (si->full_hash, full))) {
- u(printf(" can't find row\n"));
+ reference = g_hash_table_lookup (si->full_hash, full);
+ if (!gtk_tree_row_reference_valid (reference))
return;
- }
- tree_path = gtk_tree_row_reference_get_path (row);
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, tree_path)) {
- gtk_tree_path_free (tree_path);
- return;
- }
+ tree_model = GTK_TREE_MODEL (model);
- gtk_tree_path_free (tree_path);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (tree_model, &iter, path);
+ gtk_tree_path_free (path);
- sel_uri = em_folder_tree_model_get_selected (model);
gtk_tree_model_get (
- GTK_TREE_MODEL (model), &iter,
- COL_UINT_UNREAD_LAST_SEL, &old_unread,
- COL_STRING_URI, &uri, -1);
- if (!(g_strcmp0 (sel_uri, uri) != 0 && unread > old_unread))
- old_unread = unread;
+ tree_model, &iter,
+ COL_UINT_UNREAD_LAST_SEL, &old_unread, -1);
+
gtk_tree_store_set (
GTK_TREE_STORE (model), &iter,
COL_UINT_UNREAD, unread,
- COL_UINT_UNREAD_LAST_SEL, old_unread, -1);
-
- g_free (uri);
- g_free (sel_uri);
+ COL_UINT_UNREAD_LAST_SEL, MIN (old_unread, unread), -1);
- /* May be this is from where we should propagate unread count to parents etc. */
- emft_model_unread_count_changed (GTK_TREE_MODEL (model), &iter);
+ /* Folders are displayed with a bold weight to indicate that
+ * they contain unread messages. We signal that parent rows
+ * have changed here to update them. */
+ while (gtk_tree_model_iter_parent (tree_model, &parent, &iter)) {
+ path = gtk_tree_model_get_path (tree_model, &parent);
+ gtk_tree_model_row_changed (tree_model, path, &parent);
+ gtk_tree_path_free (path);
+ iter = parent;
+ }
}
-gchar *
-em_folder_tree_model_get_selected (EMFolderTreeModel *model)
+EMFolderTreeModelStoreInfo *
+em_folder_tree_model_lookup_store_info (EMFolderTreeModel *model,
+ CamelStore *store)
{
- xmlNodePtr node;
- gchar *buf, *uri;
-
- node = model->state ? model->state->children : NULL;
- if (!node || strcmp ((gchar *)node->name, "tree-state") != 0)
- return NULL;
-
- node = node->children;
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "selected"))
- break;
- node = node->next;
- }
-
- if (node == NULL)
- return NULL;
-
- buf = (gchar *)xmlGetProp (node, (guchar *)"uri");
- uri = g_strdup (buf);
- xmlFree (buf);
+ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
- if (uri && !*uri) {
- g_free (uri);
- return NULL;
- }
- return uri;
+ return g_hash_table_lookup (model->priv->store_index, store);
}
-void
-em_folder_tree_model_set_selected (EMFolderTreeModel *model, const gchar *uri)
+GtkTreeRowReference *
+em_folder_tree_model_lookup_uri (EMFolderTreeModel *model,
+ const gchar *uri)
{
- xmlNodePtr root, node;
-
- if (model->state == NULL)
- model->state = xmlNewDoc ((guchar *)"1.0");
+ GtkTreeRowReference *reference;
- if (!model->state->children) {
- root = xmlNewDocNode (model->state, NULL, (const guchar *)"tree-state", NULL);
- xmlDocSetRootElement (model->state, root);
- } else {
- root = model->state->children;
- }
-
- node = root->children;
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "selected"))
- break;
- node = node->next;
- }
+ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
- if (node == NULL)
- node = xmlNewChild (root, NULL, (const guchar *)"selected", NULL);
+ reference = g_hash_table_lookup (model->priv->uri_index, uri);
- xmlSetProp (node, (const guchar *)"uri", (guchar *)uri);
+ return gtk_tree_row_reference_valid (reference) ? reference : NULL;
}
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index f0bf091eb1..d75e57c0b4 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -20,28 +20,37 @@
*
*/
-#ifndef __EM_FOLDER_TREE_MODEL_H__
-#define __EM_FOLDER_TREE_MODEL_H__
+#ifndef EM_FOLDER_TREE_MODEL_H
+#define EM_FOLDER_TREE_MODEL_H
#include <gtk/gtk.h>
-
-#include <libxml/tree.h>
-
#include <camel/camel-store.h>
-
#include <libedataserver/e-account-list.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_TREE_MODEL \
+ (em_folder_tree_model_get_type ())
+#define EM_FOLDER_TREE_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModel))
+#define EM_FOLDER_TREE_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelClass))
+#define EM_IS_FOLDER_TREE_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FOLDER_TREE_MODEL))
+#define EM_IS_FOLDER_TREE_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_FOLDER_TREE_MODEL))
+#define EM_FOLDER_TREE_MODEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelClass))
-#define EM_TYPE_FOLDER_TREE_MODEL (em_folder_tree_model_get_type ())
-#define EM_FOLDER_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModel))
-#define EM_FOLDER_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelClass))
-#define EM_IS_FOLDER_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_TREE_MODEL))
-#define EM_IS_FOLDER_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EM_TYPE_FOLDER_TREE_MODEL))
-#define EM_FOLDER_TREE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelClass))
+G_BEGIN_DECLS
typedef struct _EMFolderTreeModel EMFolderTreeModel;
typedef struct _EMFolderTreeModelClass EMFolderTreeModelClass;
+typedef struct _EMFolderTreeModelPrivate EMFolderTreeModelPrivate;
typedef struct _EMFolderTreeModelStoreInfo EMFolderTreeModelStoreInfo;
enum {
@@ -78,71 +87,77 @@ struct _EMFolderTreeModelStoreInfo {
};
struct _EMFolderTreeModel {
- GtkTreeStore parent_object;
-
- gchar *filename; /* state filename */
- xmlDocPtr state; /* saved expanded state from previous session */
-
- GHashTable *store_hash; /* maps CamelStore's to store-info's */
- GHashTable *uri_hash; /* maps URI's to GtkTreeRowReferences */
-
- EAccountList *accounts;
- GHashTable *account_hash; /* maps accounts to store-info's */
- gulong account_changed_id;
- gulong account_removed_id;
+ GtkTreeStore parent;
+ EMFolderTreeModelPrivate *priv;
};
struct _EMFolderTreeModelClass {
GtkTreeStoreClass parent_class;
/* signals */
- void (* loading_row) (EMFolderTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter);
-
- void (* loaded_row) (EMFolderTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter);
+ void (*loading_row) (EMFolderTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter);
- void (* folder_added) (EMFolderTreeModel *model,
- const gchar *path,
- const gchar *uri);
+ void (*loaded_row) (EMFolderTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter);
- void (* store_added) (EMFolderTreeModel *model,
- const gchar *uri);
+ void (*folder_added) (EMFolderTreeModel *model,
+ const gchar *path,
+ const gchar *uri);
};
-GType em_folder_tree_model_get_type (void);
-
-EMFolderTreeModel *em_folder_tree_model_new (const gchar *evolution_dir);
-
-void em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *iter,
- struct _EMFolderTreeModelStoreInfo *si,
- CamelFolderInfo *fi, gint fully_loaded);
-
-void em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, const gchar *display_name);
-void em_folder_tree_model_remove_store (EMFolderTreeModel *model, CamelStore *store);
-void em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderTreeModelStoreInfo *si,
- GtkTreeIter *toplevel);
-
-gchar *em_folder_tree_model_get_selected (EMFolderTreeModel *model);
-void em_folder_tree_model_set_selected (EMFolderTreeModel *model, const gchar *uri);
-
-gboolean em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const gchar *key);
-void em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const gchar *key, gboolean expanded);
-
-gboolean em_folder_tree_model_get_expanded_uri (EMFolderTreeModel *model, const gchar *uri);
-void em_folder_tree_model_set_expanded_uri (EMFolderTreeModel *model, const gchar *uri, gboolean expanded);
-
-void em_folder_tree_model_save_state (EMFolderTreeModel *model);
-
-typedef void (* EMFTModelExpandFunc) (EMFolderTreeModel *model, const gchar *path, gpointer user_data);
-void em_folder_tree_model_expand_foreach (EMFolderTreeModel *model, EMFTModelExpandFunc func, gpointer user_data);
-
-void em_folder_tree_model_set_unread_count (EMFolderTreeModel *model, CamelStore *store, const gchar *path, gint unread);
-gboolean em_folder_tree_model_is_type_inbox (EMFolderTreeModel *model, CamelStore *store, const gchar *full);
-gchar * em_folder_tree_model_get_folder_name (EMFolderTreeModel *model, CamelStore *store, const gchar *full);
+GType em_folder_tree_model_get_type (void);
+EMFolderTreeModel *
+ em_folder_tree_model_new (void);
+EMFolderTreeModel *
+ em_folder_tree_model_get_default(void);
+GtkTreeSelection *
+ em_folder_tree_model_get_selection
+ (EMFolderTreeModel *model);
+void em_folder_tree_model_set_selection
+ (EMFolderTreeModel *model,
+ GtkTreeSelection *selection);
+void em_folder_tree_model_set_folder_info
+ (EMFolderTreeModel *model,
+ GtkTreeIter *iter,
+ EMFolderTreeModelStoreInfo *si,
+ CamelFolderInfo *fi,
+ gint fully_loaded);
+void em_folder_tree_model_add_store
+ (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *display_name);
+void em_folder_tree_model_remove_store
+ (EMFolderTreeModel *model,
+ CamelStore *store);
+void em_folder_tree_model_remove_folders
+ (EMFolderTreeModel *model,
+ EMFolderTreeModelStoreInfo *si,
+ GtkTreeIter *toplevel);
+void em_folder_tree_model_set_unread_count
+ (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *path,
+ gint unread);
+gboolean em_folder_tree_model_is_type_inbox
+ (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full);
+gchar * em_folder_tree_model_get_folder_name
+ (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full);
+EMFolderTreeModelStoreInfo *
+ em_folder_tree_model_lookup_store_info
+ (EMFolderTreeModel *model,
+ CamelStore *store);
+GtkTreeRowReference *
+ em_folder_tree_model_lookup_uri
+ (EMFolderTreeModel *model,
+ const gchar *uri);
G_END_DECLS
-#endif /* __EM_FOLDER_TREE_MODEL_H__ */
+#endif /* EM_FOLDER_TREE_MODEL_H */
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index b13a47a0e0..7c9293ca19 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -48,6 +48,7 @@
#include <camel/camel-file-utils.h>
#include <camel/camel-stream-fs.h>
+#include "e-util/e-account-utils.h"
#include "e-util/e-mktemp.h"
#include "e-util/e-request.h"
#include "e-util/e-icon-factory.h"
@@ -60,12 +61,10 @@
#include "mail-ops.h"
#include "mail-tools.h"
#include "mail-config.h"
-#include "mail-component.h"
#include "mail-send-recv.h"
#include "mail-vfolder.h"
#include "em-utils.h"
-#include "em-popup.h"
#include "em-folder-tree.h"
#include "em-folder-utils.h"
#include "em-folder-selector.h"
@@ -73,8 +72,14 @@
#include "em-folder-properties.h"
#include "em-event.h"
+#include "e-mail-local.h"
+
#define d(x)
+#define EM_FOLDER_TREE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FOLDER_TREE, EMFolderTreePrivate))
+
struct _selected_uri {
gchar *key; /* store:path or account/path */
gchar *uri;
@@ -83,9 +88,6 @@ struct _selected_uri {
};
struct _EMFolderTreePrivate {
- GtkTreeView *treeview;
- EMFolderTreeModel *model;
-
GSList *select_uris; /* selected_uri structures of each path pending selection. */
GHashTable *select_uris_table; /*Removed as they're encountered, so use this to find uri's not presnet but selected */
@@ -93,14 +95,11 @@ struct _EMFolderTreePrivate {
gboolean (*excluded_func)(EMFolderTree *emft, GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
gpointer excluded_data;
- guint do_multiselect:1; /* multiple select mode */
guint cursor_set:1; /* set to TRUE means we or something
* else has set the cursor, otherwise
* we need to set it when we set the
* selection */
- guint save_state_id;
-
guint autoscroll_id;
guint autoexpand_id;
GtkTreeRowReference *autoexpand_row;
@@ -115,7 +114,7 @@ struct _EMFolderTreePrivate {
enum {
FOLDER_ACTIVATED, /* aka double-clicked or user hit enter */
FOLDER_SELECTED,
- HIDDEN_KEY_EVENT,
+ POPUP_EVENT,
LAST_SIGNAL
};
@@ -154,101 +153,613 @@ static guint signals[LAST_SIGNAL] = { 0 };
extern CamelSession *session;
extern CamelStore *vfolder_store;
-static void em_folder_tree_class_init (EMFolderTreeClass *klass);
-static void em_folder_tree_init (EMFolderTree *emft);
-static void em_folder_tree_destroy (GtkObject *obj);
-static void em_folder_tree_finalize (GObject *obj);
+struct _emft_selection_data {
+ GtkTreeModel *model;
+ GtkTreeIter *iter;
+ gboolean set;
+};
-static gboolean emft_save_state (EMFolderTree *emft);
-static void emft_queue_save_state (EMFolderTree *emft);
+static gpointer parent_class = NULL;
-static void emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter *iter, gboolean expanded);
+struct _EMFolderTreeGetFolderInfo {
+ MailMsg base;
-static void emft_tree_row_activated (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, EMFolderTree *emft);
-static gboolean emft_tree_test_collapse_row (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *path, EMFolderTree *emft);
-static void emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *path, EMFolderTree *emft);
-static gboolean emft_tree_button_press (GtkTreeView *treeview, GdkEventButton *event, EMFolderTree *emft);
-static void emft_tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft);
-static gboolean emft_tree_user_event (GtkTreeView *treeview, GdkEvent *e, EMFolderTree *emft);
-static gboolean emft_popup_menu (GtkWidget *widget);
+ /* input data */
+ GtkTreeRowReference *root;
+ EMFolderTree *emft;
+ CamelStore *store;
+ guint32 flags;
+ gchar *top;
-struct _emft_selection_data {
+ /* output data */
+ CamelFolderInfo *fi;
+};
+
+static gchar *
+emft_get_folder_info__desc (struct _EMFolderTreeGetFolderInfo *m)
+{
+ gchar *ret, *name;
+
+ name = camel_service_get_name((CamelService *)m->store, TRUE);
+ ret = g_strdup_printf(_("Scanning folders in \"%s\""), name);
+ g_free(name);
+ return ret;
+}
+
+static void
+emft_get_folder_info__exec (struct _EMFolderTreeGetFolderInfo *m)
+{
+ guint32 flags = m->flags | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+
+ m->fi = camel_store_get_folder_info (m->store, m->top, flags, &m->base.ex);
+}
+
+static void
+emft_get_folder_info__done (struct _EMFolderTreeGetFolderInfo *m)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreeIter root, iter, titer;
+ CamelFolderInfo *fi;
+ GtkTreeView *tree_view;
GtkTreeModel *model;
- GtkTreeIter *iter;
- gboolean set;
+ GtkTreePath *path;
+ gboolean is_store;
+
+ /* check that we haven't been destroyed */
+ g_return_if_fail (GTK_IS_TREE_VIEW (m->emft));
+
+ /* check that our parent folder hasn't been deleted/unsubscribed */
+ if (!gtk_tree_row_reference_valid (m->root))
+ return;
+
+ tree_view = GTK_TREE_VIEW (m->emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ si = em_folder_tree_model_lookup_store_info (
+ EM_FOLDER_TREE_MODEL (model), m->store);
+ if (si == NULL) {
+ /* store has been removed in the interim - do nothing */
+ return;
+ }
+
+ path = gtk_tree_row_reference_get_path (m->root);
+ gtk_tree_model_get_iter (model, &root, path);
+
+ /* if we had an error, then we need to re-set the load subdirs state and collapse the node */
+ if (!m->fi && camel_exception_is_set(&m->base.ex)) {
+ gtk_tree_store_set(
+ GTK_TREE_STORE (model), &root,
+ COL_BOOL_LOAD_SUBDIRS, TRUE, -1);
+ gtk_tree_view_collapse_row (tree_view, path);
+ gtk_tree_path_free (path);
+ return;
+ }
+
+ gtk_tree_path_free (path);
+
+ /* make sure we still need to load the tree subfolders... */
+ gtk_tree_model_get (model, &root, COL_BOOL_IS_STORE, &is_store, -1);
+
+ /* get the first child (which will be a dummy node) */
+ gtk_tree_model_iter_children (model, &iter, &root);
+
+ /* Traverse to the last valid iter */
+ titer = iter;
+ while (gtk_tree_model_iter_next (model, &iter))
+ titer = iter; /* Preserve the last valid iter */
+
+ iter = titer;
+
+ /* FIXME: camel's IMAP code is totally on crack here, @top's
+ * folder info should be @fi and fi->child should be what we
+ * want to fill our tree with... *sigh* */
+ if (m->top && m->fi && !strcmp (m->fi->full_name, m->top)) {
+ if (!(fi = m->fi->child))
+ fi = m->fi->next;
+ } else
+ fi = m->fi;
+
+ if (fi == NULL) {
+ /* no children afterall... remove the "Loading..." placeholder node */
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+
+ if (is_store) {
+ path = gtk_tree_model_get_path (model, &root);
+ gtk_tree_view_collapse_row (tree_view, path);
+ gtk_tree_path_free (path);
+ return;
+ }
+ } else {
+ gint fully_loaded = (m->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? TRUE : FALSE;
+
+ do {
+ gboolean known = g_hash_table_lookup (si->full_hash, fi->full_name) != NULL;
+
+ if (!known)
+ em_folder_tree_model_set_folder_info (
+ EM_FOLDER_TREE_MODEL (model),
+ &iter, si, fi, fully_loaded);
+
+ if ((fi = fi->next) != NULL && !known)
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &root);
+ } while (fi != NULL);
+ }
+
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), &root,
+ COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
+}
+
+static void
+emft_get_folder_info__free (struct _EMFolderTreeGetFolderInfo *m)
+{
+ camel_store_free_folder_info (m->store, m->fi);
+
+ gtk_tree_row_reference_free (m->root);
+ g_object_unref(m->emft);
+ camel_object_unref (m->store);
+ g_free (m->top);
+}
+
+static MailMsgInfo get_folder_info_info = {
+ sizeof (struct _EMFolderTreeGetFolderInfo),
+ (MailMsgDescFunc) emft_get_folder_info__desc,
+ (MailMsgExecFunc) emft_get_folder_info__exec,
+ (MailMsgDoneFunc) emft_get_folder_info__done,
+ (MailMsgFreeFunc) emft_get_folder_info__free
};
-static GtkVBoxClass *parent_class = NULL;
+static void
+folder_tree_emit_popup_event (EMFolderTree *emft,
+ GdkEvent *event)
+{
+ g_signal_emit (emft, signals[POPUP_EVENT], 0, event);
+}
-GType
-em_folder_tree_get_type (void)
+static void
+emft_free_select_uri (struct _selected_uri *u)
{
- static GType type = 0;
+ g_free (u->uri);
+ if (u->store)
+ camel_object_unref (u->store);
+ g_free (u->key);
+ g_free (u->path);
+ g_free (u);
+}
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderTreeClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_tree_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderTree),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_tree_init,
- };
+static gboolean
+emft_select_func (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean selected)
+{
+ EMFolderTreePrivate *priv;
+ GtkTreeView *tree_view;
+ gboolean is_store;
+ guint32 flags;
+ GtkTreeIter iter;
+
+ tree_view = gtk_tree_selection_get_tree_view (selection);
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (tree_view);
+
+ if (selected)
+ return TRUE;
+
+ if (priv->excluded == 0 && priv->excluded_func == NULL)
+ return TRUE;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return TRUE;
+
+ if (priv->excluded_func != NULL)
+ return priv->excluded_func(
+ EM_FOLDER_TREE (tree_view), model,
+ &iter, priv->excluded_data);
+
+ gtk_tree_model_get (
+ model, &iter, COL_UINT_FLAGS, &flags,
+ COL_BOOL_IS_STORE, &is_store, -1);
+
+ if (is_store)
+ flags |= CAMEL_FOLDER_NOSELECT;
+
+ return (flags & priv->excluded) == 0;
+}
+
+static void
+emft_clear_selected_list(EMFolderTree *emft)
+{
+ EMFolderTreePrivate *priv = emft->priv;
+
+ g_slist_foreach(priv->select_uris, (GFunc) emft_free_select_uri, NULL);
+ g_slist_free(priv->select_uris);
+ g_hash_table_destroy(priv->select_uris_table);
+ priv->select_uris = NULL;
+ priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
+ priv->cursor_set = FALSE;
+}
+
+static void
+emft_selection_changed_cb (EMFolderTree *emft,
+ GtkTreeSelection *selection)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GList *list;
+ guint32 flags = 0;
+ guint unread = 0;
+ guint old_unread = 0;
+ gchar *full_name = NULL;
+ gchar *uri = NULL;
- type = g_type_register_static (GTK_TYPE_VBOX, "EMFolderTree", &info, 0);
+ list = gtk_tree_selection_get_selected_rows (selection, &model);
+
+ if (list == NULL)
+ goto exit;
+
+ gtk_tree_model_get_iter (model, &iter, list->data);
+
+ gtk_tree_model_get (
+ model, &iter,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags,
+ COL_UINT_UNREAD, &unread, COL_UINT_UNREAD_LAST_SEL,
+ &old_unread, -1);
+
+ /* Sync unread counts to distinguish new incoming mail. */
+ if (unread != old_unread)
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), &iter,
+ COL_UINT_UNREAD_LAST_SEL, unread, -1);
+
+exit:
+ g_signal_emit (
+ emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
+
+ g_free (full_name);
+ g_free (uri);
+
+ g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (list);
+}
+
+static void
+folder_tree_finalize (GObject *object)
+{
+ EMFolderTreePrivate *priv;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (object);
+
+ if (priv->select_uris != NULL) {
+ g_slist_foreach (
+ priv->select_uris,
+ (GFunc) emft_free_select_uri, NULL);
+ g_slist_free (priv->select_uris);
+ g_hash_table_destroy (priv->select_uris_table);
+ priv->select_uris = NULL;
}
- return type;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-em_folder_tree_class_init (EMFolderTreeClass *klass)
+em_folder_tree_destroy (GtkObject *object)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ EMFolderTreePrivate *priv;
+ GtkTreeModel *model;
- parent_class = g_type_class_ref (GTK_TYPE_VBOX);
+ priv = EM_FOLDER_TREE_GET_PRIVATE (object);
- object_class->finalize = em_folder_tree_finalize;
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
+
+ if (priv->loaded_row_id != 0) {
+ g_signal_handler_disconnect (model, priv->loaded_row_id);
+ priv->loaded_row_id = 0;
+ }
+
+ if (priv->autoscroll_id != 0) {
+ g_source_remove (priv->autoscroll_id);
+ priv->autoscroll_id = 0;
+ }
+
+ if (priv->autoexpand_id != 0) {
+ gtk_tree_row_reference_free (priv->autoexpand_row);
+ priv->autoexpand_row = NULL;
+
+ g_source_remove (priv->autoexpand_id);
+ priv->autoexpand_id = 0;
+ }
+
+ /* Chain up to parent's destroy() method. */
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+static gboolean
+emft_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ EMFolderTreePrivate *priv;
+ GtkWidgetClass *widget_class;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreePath *path;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (widget);
+
+ tree_view = GTK_TREE_VIEW (widget);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE)
+ emft_clear_selected_list (EM_FOLDER_TREE (widget));
+
+ priv->cursor_set = TRUE;
+
+ if (event->button != 3)
+ goto chainup;
+
+ if (!gtk_tree_view_get_path_at_pos (
+ tree_view, event->x, event->y,
+ &path, NULL, NULL, NULL))
+ goto chainup;
+
+ /* select/focus the row that was right-clicked */
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
+
+ gtk_tree_path_free (path);
+
+ folder_tree_emit_popup_event (
+ EM_FOLDER_TREE (tree_view), (GdkEvent *) event);
+
+chainup:
+
+ /* Chain up to parent's button_press_event() method. */
+ widget_class = GTK_WIDGET_CLASS (parent_class);
+ return widget_class->button_press_event (widget, event);
+}
+
+static gboolean
+emft_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ EMFolderTreePrivate *priv;
+ GtkWidgetClass *widget_class;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (widget);
+
+ tree_view = GTK_TREE_VIEW (widget);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE)
+ emft_clear_selected_list (EM_FOLDER_TREE (widget));
+
+ priv->cursor_set = TRUE;
+
+ /* Chain up to parent's key_press_event() method. */
+ widget_class = GTK_WIDGET_CLASS (parent_class);
+ return widget_class->key_press_event (widget, event);
+}
+
+static gboolean
+emft_popup_menu (GtkWidget *widget)
+{
+ folder_tree_emit_popup_event (EM_FOLDER_TREE (widget), NULL);
+
+ return TRUE;
+}
+
+static void
+emft_row_activated (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column)
+{
+ EMFolderTreePrivate *priv;
+ GtkTreeModel *model;
+ gchar *full_name, *uri;
+ GtkTreeIter iter;
+ guint32 flags;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (tree_view);
+
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (priv->skip_double_click)
+ return;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return;
+
+ gtk_tree_model_get (
+ model, &iter, COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags, -1);
+
+ emft_clear_selected_list (EM_FOLDER_TREE (tree_view));
+
+ g_signal_emit (
+ tree_view, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
+
+ g_signal_emit (
+ tree_view, signals[FOLDER_ACTIVATED], 0, full_name, uri);
+
+ g_free (full_name);
+ g_free (uri);
+}
+
+static gboolean
+emft_test_collapse_row (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter cursor;
+
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &cursor))
+ goto exit;
+
+ /* Select the collapsed node IFF it is a
+ * parent of the currently selected folder. */
+ if (gtk_tree_store_is_ancestor (GTK_TREE_STORE (model), iter, &cursor))
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
+
+exit:
+ return FALSE;
+}
+
+static void
+emft_row_expanded (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ struct _EMFolderTreeGetFolderInfo *msg;
+ GtkTreeModel *model;
+ CamelStore *store;
+ gchar *full_name;
+ gboolean load;
+
+ model = gtk_tree_view_get_model (tree_view);
+
+ gtk_tree_model_get (
+ model, iter,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_LOAD_SUBDIRS, &load, -1);
+
+ if (!load) {
+ g_free (full_name);
+ return;
+ }
+
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), iter,
+ COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
+
+ msg = mail_msg_new (&get_folder_info_info);
+ msg->root = gtk_tree_row_reference_new (model, path);
+ camel_object_ref (store);
+ msg->store = store;
+ msg->emft = g_object_ref (tree_view);
+ msg->top = full_name;
+ msg->flags =
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE |
+ CAMEL_STORE_FOLDER_INFO_FAST;
+
+ mail_msg_unordered_push (msg);
+}
+
+static void
+folder_tree_class_init (EMFolderTreeClass *class)
+{
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+ GtkWidgetClass *widget_class;
+ GtkTreeViewClass *tree_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFolderTreePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = folder_tree_finalize;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
gtk_object_class->destroy = em_folder_tree_destroy;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->button_press_event = emft_button_press_event;
+ widget_class->key_press_event = emft_key_press_event;
widget_class->popup_menu = emft_popup_menu;
- signals[FOLDER_SELECTED] =
- g_signal_new ("folder-selected",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeClass, folder_selected),
- NULL, NULL,
- e_marshal_VOID__STRING_STRING_UINT,
- G_TYPE_NONE, 3,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_UINT);
-
- signals[FOLDER_ACTIVATED] =
- g_signal_new ("folder-activated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeClass, folder_activated),
- NULL, NULL,
- e_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- signals[HIDDEN_KEY_EVENT] =
- g_signal_new ("hidden-key-event",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFolderTreeClass, hidden_key_event),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1, GDK_TYPE_EVENT);
+ tree_view_class = GTK_TREE_VIEW_CLASS (class);
+ tree_view_class->row_activated = emft_row_activated;
+ tree_view_class->test_collapse_row = emft_test_collapse_row;
+ tree_view_class->row_expanded = emft_row_expanded;
+
+ signals[FOLDER_SELECTED] = g_signal_new (
+ "folder-selected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeClass, folder_selected),
+ NULL, NULL,
+ e_marshal_VOID__STRING_STRING_UINT,
+ G_TYPE_NONE, 3,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_UINT);
+
+ signals[FOLDER_ACTIVATED] = g_signal_new (
+ "folder-activated",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeClass, folder_activated),
+ NULL, NULL,
+ e_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMFolderTreeClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+}
+
+static void
+folder_tree_init (EMFolderTree *emft)
+{
+ GtkTreeSelection *selection;
+ GHashTable *select_uris_table;
+ EMFolderTreeModel *model;
+
+ select_uris_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+ emft->priv = EM_FOLDER_TREE_GET_PRIVATE (emft);
+ emft->priv->select_uris_table = select_uris_table;
+
+ model = em_folder_tree_model_get_default ();
+ gtk_tree_view_set_model (GTK_TREE_VIEW (emft), GTK_TREE_MODEL (model));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (emft));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (emft_selection_changed_cb), emft);
+}
+
+GType
+em_folder_tree_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderTreeClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_tree_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderTree),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_tree_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TREE_VIEW, "EMFolderTree", &type_info, 0);
+ }
+
+ return type;
}
static gboolean
@@ -277,7 +788,7 @@ static void
render_display_name (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
- gboolean is_store, bold, subdirs_unread = FALSE;
+ gboolean is_store, bold;
guint unread;
gchar *display;
gchar *name;
@@ -286,36 +797,28 @@ render_display_name (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
COL_BOOL_IS_STORE, &is_store,
COL_UINT_UNREAD, &unread, -1);
- bold = is_store || unread;
-
- if (gtk_tree_model_iter_has_child (model, iter)) {
- gboolean expanded = TRUE;
-
- g_object_get (renderer, "is-expanded", &expanded, NULL);
-
- if (!bold || !expanded)
- subdirs_unread = subdirs_contain_unread (model, iter);
+ if (!(bold = is_store || unread)) {
+ if (gtk_tree_model_iter_has_child (model, iter))
+ bold = subdirs_contain_unread (model, iter);
}
- bold = bold || subdirs_unread;
-
if (!is_store && unread) {
/* Translators: This is the string used for displaying the
- * folder names in folder trees. The first "%s" will be
- * replaced by the folder's name and "%u" will be replaced
- * with the number of unread messages in the folder. The
- * second %s will be replaced with a "+" letter for collapsed
- * folders with unread messages in some subfolder too,
- * or with an empty string for other cases.
+ * folder names in folder trees. "%s" will be replaced by
+ * the folder's name and "%u" will be replaced with the
+ * number of unread messages in the folder.
*
- * Most languages should translate this as "%s (%u%s)". The
+ * Most languages should translate this as "%s (%u)". The
* languages that use localized digits (like Persian) may
* need to replace "%u" with "%Iu". Right-to-left languages
* (like Arabic and Hebrew) may need to add bidirectional
* formatting codes to take care of the cases the folder
* name appears in either direction.
+ *
+ * Do not translate the "folder-display|" part. Remove it
+ * from your translation.
*/
- display = g_strdup_printf (C_("folder-display", "%s (%u%s)"), name, unread, subdirs_unread ? "+" : "");
+ display = g_strdup_printf (C_("folder-display", "%s (%u)"), name, unread);
g_free (name);
} else
display = name;
@@ -333,10 +836,13 @@ render_icon (GtkTreeViewColumn *column,
GtkTreeModel *model,
GtkTreeIter *iter)
{
+ GtkTreeSelection *selection;
+ GtkWidget *tree_view;
GIcon *icon;
guint unread;
guint old_unread;
gchar *icon_name;
+ gboolean row_selected;
gtk_tree_model_get (
model, iter,
@@ -349,8 +855,12 @@ render_icon (GtkTreeViewColumn *column,
icon = g_themed_icon_new (icon_name);
+ tree_view = gtk_tree_view_column_get_tree_view (column);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+ row_selected = gtk_tree_selection_iter_is_selected (selection, iter);
+
/* Show an emblem if there's new mail. */
- if (unread > old_unread) {
+ if (!row_selected && unread > old_unread) {
GIcon *temp_icon;
GEmblem *emblem;
@@ -368,133 +878,21 @@ render_icon (GtkTreeViewColumn *column,
g_object_set (renderer, "gicon", icon, NULL);
g_object_unref (icon);
- g_free (icon_name);
-}
-
-static gboolean
-emft_select_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer data)
-{
- EMFolderTree *emft = data;
- gboolean is_store;
- guint32 flags;
- GtkTreeIter iter;
-
- /* NB: This will be called with selection==NULL from tree_row_activated */
- if (emft->priv->excluded == 0 && emft->priv->excluded_func == NULL)
- return TRUE;
-
- if (!gtk_tree_model_get_iter(model, &iter, path))
- return TRUE;
-
- if (emft->priv->excluded_func != NULL)
- return emft->priv->excluded_func(emft, model, &iter, emft->priv->excluded_data);
-
- gtk_tree_model_get(model, &iter, COL_UINT_FLAGS, &flags, COL_BOOL_IS_STORE, &is_store, -1);
- if (is_store)
- flags |= CAMEL_FOLDER_NOSELECT;
-
- return (flags & emft->priv->excluded) == 0;
-}
-
-static void
-emft_free_select_uri(gpointer v, gpointer data)
-{
- struct _selected_uri *u = v;
-
- g_free(u->uri);
- if (u->store)
- camel_object_unref(u->store);
- g_free(u->key);
- g_free(u->path);
- g_free(u);
-}
-
-static void
-em_folder_tree_init (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv;
-
- priv = g_new0 (struct _EMFolderTreePrivate, 1);
- priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
- priv->treeview = NULL;
- priv->model = NULL;
- priv->drag_row = NULL;
- priv->skip_double_click = FALSE;
-
- emft->priv = priv;
-}
-
-static void
-em_folder_tree_finalize (GObject *obj)
-{
- EMFolderTree *emft = (EMFolderTree *) obj;
-
- if (emft->priv->select_uris) {
- g_slist_foreach(emft->priv->select_uris, emft_free_select_uri, emft);
- g_slist_free(emft->priv->select_uris);
- g_hash_table_destroy(emft->priv->select_uris_table);
- emft->priv->select_uris = NULL;
- }
-
- g_free (emft->priv);
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-em_folder_tree_destroy (GtkObject *obj)
-{
- EMFolderTree *emft = (EMFolderTree *) obj;
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- if (priv->loading_row_id != 0) {
- g_signal_handler_disconnect (priv->model, priv->loading_row_id);
- priv->loading_row_id = 0;
- }
-
- if (priv->loaded_row_id != 0) {
- g_signal_handler_disconnect (priv->model, priv->loaded_row_id);
- priv->loaded_row_id = 0;
- }
-
- if (priv->save_state_id != 0) {
- g_source_remove (priv->save_state_id);
- emft_save_state (emft);
- }
-
- if (priv->autoscroll_id != 0) {
- g_source_remove (priv->autoscroll_id);
- priv->autoscroll_id = 0;
- }
-
- if (priv->autoexpand_id != 0) {
- gtk_tree_row_reference_free (priv->autoexpand_row);
- priv->autoexpand_row = NULL;
-
- g_source_remove (priv->autoexpand_id);
- priv->autoexpand_id = 0;
- }
-
- priv->treeview = NULL;
- priv->model = NULL;
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
}
static GtkTreeView *
-folder_tree_new (EMFolderTree *emft, EMFolderTreeModel *model)
+folder_tree_new (EMFolderTree *emft)
{
GtkTreeSelection *selection;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkWidget *tree;
- gboolean side_bar_search;
GConfClient *gconf;
gconf = mail_config_get_gconf_client ();
- side_bar_search = gconf_client_get_bool (gconf, "/apps/evolution/mail/display/side_bar_search", NULL);
- tree = gtk_tree_view_new_with_model ((GtkTreeModel *) model);
+ /* FIXME Gross hack */
+ tree = GTK_WIDGET (emft);
GTK_WIDGET_SET_FLAGS(tree, GTK_CAN_FOCUS);
column = gtk_tree_view_column_new ();
@@ -516,84 +914,99 @@ folder_tree_new (EMFolderTree *emft, EMFolderTreeModel *model)
selection = gtk_tree_view_get_selection ((GtkTreeView *) tree);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- gtk_tree_selection_set_select_function(selection, emft_select_func, emft, NULL);
+ gtk_tree_selection_set_select_function (
+ selection, (GtkTreeSelectionFunc)
+ emft_select_func, NULL, NULL);
gtk_tree_view_set_headers_visible ((GtkTreeView *) tree, FALSE);
gtk_tree_view_set_search_column((GtkTreeView *)tree, COL_STRING_DISPLAY_NAME);
- gtk_tree_view_set_enable_search((GtkTreeView *)tree, side_bar_search);
return (GtkTreeView *) tree;
}
static void
-em_folder_tree_construct (EMFolderTree *emft, EMFolderTreeModel *model)
+folder_tree_copy_expanded_cb (GtkTreeView *unused,
+ GtkTreePath *path,
+ GtkTreeView *tree_view)
+{
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
+}
+
+static void
+folder_tree_copy_selection_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GtkTreeView *tree_view)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkTreeSelection *selection;
- GtkWidget *scrolled;
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN);
+ selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_select_path (selection, path);
+
+ /* Center the tree view on the selected path. */
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.0);
+}
- priv->model = model;
- priv->treeview = folder_tree_new (emft, model);
- gtk_widget_show ((GtkWidget *) priv->treeview);
+static void
+folder_tree_copy_state (EMFolderTree *emft)
+{
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
- g_signal_connect (priv->treeview, "row-expanded", G_CALLBACK (emft_tree_row_expanded), emft);
- g_signal_connect (priv->treeview, "test-collapse-row", G_CALLBACK (emft_tree_test_collapse_row), emft);
- g_signal_connect (priv->treeview, "row-activated", G_CALLBACK (emft_tree_row_activated), emft);
- g_signal_connect (priv->treeview, "button-press-event", G_CALLBACK (emft_tree_button_press), emft);
- g_signal_connect (priv->treeview, "key-press-event", G_CALLBACK (emft_tree_user_event), emft);
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
- selection = gtk_tree_view_get_selection ((GtkTreeView *) priv->treeview);
- g_signal_connect (selection, "changed", G_CALLBACK (emft_tree_selection_changed), emft);
+ selection = em_folder_tree_model_get_selection (
+ EM_FOLDER_TREE_MODEL (model));
+ if (selection == NULL)
+ return;
- gtk_container_add ((GtkContainer *) scrolled, (GtkWidget *) priv->treeview);
- gtk_widget_show (scrolled);
+ gtk_tree_view_map_expanded_rows (
+ tree_view, (GtkTreeViewMappingFunc)
+ folder_tree_copy_expanded_cb, emft);
- gtk_box_pack_start ((GtkBox *) emft, scrolled, TRUE, TRUE, 0);
+ gtk_tree_selection_selected_foreach (
+ selection, (GtkTreeSelectionForeachFunc)
+ folder_tree_copy_selection_cb, emft);
}
-GtkWidget *
-em_folder_tree_new (void)
+static void
+em_folder_tree_construct (EMFolderTree *emft)
{
- EMFolderTreeModel *model;
- EMFolderTree *emft;
-
- model = em_folder_tree_model_new (e_get_user_data_dir ());
- emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
- g_object_unref (model);
-
- return (GtkWidget *) emft;
+ folder_tree_new (emft);
+ folder_tree_copy_state (emft);
+ gtk_widget_show (GTK_WIDGET (emft));
}
/* NOTE: Removes and frees the selected uri structure */
static void
emft_select_uri(EMFolderTree *emft, GtkTreePath *path, struct _selected_uri *u)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
- selection = gtk_tree_view_get_selection(priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.8f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.8f, 0.0f);
g_hash_table_remove(priv->select_uris_table, u->key);
priv->select_uris = g_slist_remove(priv->select_uris, u);
- emft_free_select_uri((gpointer)u, NULL);
+ emft_free_select_uri(u);
}
static void
-emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft)
+emft_expand_node (const gchar *key, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
struct _EMFolderTreeModelStoreInfo *si;
GtkTreeRowReference *row;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GtkTreePath *path;
EAccount *account;
CamelStore *store;
@@ -611,7 +1024,10 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
memcpy (uid, key, n);
uid[n] = '\0';
- if ((account = mail_config_get_account_by_uid (uid)) && account->enabled) {
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if ((account = e_get_account_by_uid (uid)) && account->enabled) {
CamelException ex;
camel_exception_init (&ex);
@@ -626,7 +1042,7 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
camel_object_ref (store);
} else if (!strcmp (uid, "local")) {
- if (!(store = mail_component_peek_local_store (NULL)))
+ if (!(store = e_mail_local_get_store ()))
return;
camel_object_ref (store);
@@ -634,7 +1050,9 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
return;
}
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
+ si = em_folder_tree_model_lookup_store_info (
+ EM_FOLDER_TREE_MODEL (model), store);
+ if (si == NULL) {
camel_object_unref (store);
return;
}
@@ -648,7 +1066,7 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
row = si->row;
path = gtk_tree_row_reference_get_path (row);
- gtk_tree_view_expand_to_path (priv->treeview, path);
+ gtk_tree_view_expand_to_path (tree_view, path);
u = g_hash_table_lookup(emft->priv->select_uris_table, key);
if (u)
@@ -660,15 +1078,17 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
static void
emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTreeIter *iter, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreeView *tree_view;
gboolean is_store;
CamelStore *store;
EAccount *account;
gchar *full_name;
gchar *key;
struct _selected_uri *u;
- gboolean is_expanded;
+
+ tree_view = GTK_TREE_VIEW (emft);
gtk_tree_model_get ((GtkTreeModel *) model, iter,
COL_STRING_FULL_NAME, &full_name,
@@ -676,8 +1096,8 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
COL_BOOL_IS_STORE, &is_store,
-1);
- si = g_hash_table_lookup (model->store_hash, store);
- if ((account = mail_config_get_account_by_name (si->display_name))) {
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if ((account = e_get_account_by_name (si->display_name))) {
key = g_strdup_printf ("%s/%s", account->uid, full_name ? full_name : "");
} else if (CAMEL_IS_VEE_STORE (store)) {
/* vfolder store */
@@ -687,21 +1107,14 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
key = g_strdup_printf ("local/%s", full_name ? full_name : "");
}
- is_expanded = em_folder_tree_model_get_expanded (model, key);
u = g_hash_table_lookup(priv->select_uris_table, key);
- if (is_expanded || u) {
- if (is_expanded) {
- gtk_tree_view_expand_to_path (priv->treeview, tree_path);
- gtk_tree_view_expand_row (priv->treeview, tree_path, FALSE);
- } else {
- gchar *c = strrchr (key, '/');
+ if (u) {
+ gchar *c = strrchr (key, '/');
- *c = '\0';
- emft_expand_node (model, key, emft);
- }
+ *c = '\0';
+ emft_expand_node (key, emft);
- if (u)
- emft_select_uri(emft, tree_path, u);
+ emft_select_uri(emft, tree_path, u);
}
g_free (full_name);
@@ -709,21 +1122,25 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
}
GtkWidget *
-em_folder_tree_new_with_model (EMFolderTreeModel *model)
+em_folder_tree_new (void)
{
EMFolderTree *emft;
+ GtkTreeModel *model;
AtkObject *a11y;
emft = g_object_new (EM_TYPE_FOLDER_TREE, NULL);
- em_folder_tree_construct (emft, model);
- g_object_ref (model);
+ em_folder_tree_construct (emft);
- em_folder_tree_model_expand_foreach (model, (EMFTModelExpandFunc)emft_expand_node, emft);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
- emft->priv->loading_row_id = g_signal_connect (model, "loading-row", G_CALLBACK (emft_maybe_expand_row), emft);
- emft->priv->loaded_row_id = g_signal_connect (model, "loaded-row", G_CALLBACK (emft_maybe_expand_row), emft);
+ emft->priv->loading_row_id = g_signal_connect (
+ model, "loading-row",
+ G_CALLBACK (emft_maybe_expand_row), emft);
+ emft->priv->loaded_row_id = g_signal_connect (
+ model, "loaded-row",
+ G_CALLBACK (emft_maybe_expand_row), emft);
- a11y = gtk_widget_get_accessible (GTK_WIDGET (emft->priv->treeview));
+ a11y = gtk_widget_get_accessible (GTK_WIDGET (emft));
atk_object_set_name (a11y, _("Mail Folder Tree"));
return (GtkWidget *) emft;
@@ -732,7 +1149,7 @@ em_folder_tree_new_with_model (EMFolderTreeModel *model)
static void
tree_drag_begin (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreePath *path;
@@ -752,8 +1169,9 @@ tree_drag_begin (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
static void
tree_drag_data_delete(GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gchar *full_name = NULL;
+ GtkTreeModel *model;
GtkTreePath *src_path;
gboolean is_store;
CamelStore *store;
@@ -763,13 +1181,16 @@ tree_drag_data_delete(GtkWidget *widget, GdkDragContext *context, EMFolderTree *
if (!priv->drag_row || (src_path = gtk_tree_row_reference_get_path (priv->drag_row)))
return;
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, src_path))
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
+ if (!gtk_tree_model_get_iter (model, &iter, src_path))
goto fail;
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FULL_NAME, &full_name,
- COL_BOOL_IS_STORE, &is_store, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_BOOL_IS_STORE, &is_store, -1);
if (is_store)
goto fail;
@@ -786,8 +1207,9 @@ fail:
static void
tree_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection, guint info, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gchar *full_name = NULL, *uri = NULL;
+ GtkTreeModel *model;
GtkTreePath *src_path;
CamelFolder *folder;
CamelStore *store;
@@ -797,13 +1219,16 @@ tree_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData
if (!priv->drag_row || !(src_path = gtk_tree_row_reference_get_path(priv->drag_row)))
return;
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, src_path))
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
+ if (!gtk_tree_model_get_iter (model, &iter, src_path))
goto fail;
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, -1);
/* make sure user isn't trying to drag on a placeholder row */
if (full_name == NULL)
@@ -959,61 +1384,22 @@ tree_drag_data_action(struct _DragDataReceivedAsync *m)
}
static void
-emft_drop_popup_copy(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _DragDataReceivedAsync *m = data;
-
- m->action = GDK_ACTION_COPY;
- tree_drag_data_action(m);
-}
-
-static void
-emft_drop_popup_move(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _DragDataReceivedAsync *m = data;
-
- m->action = GDK_ACTION_MOVE;
- tree_drag_data_action(m);
-}
-
-static void
-emft_drop_popup_cancel(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _DragDataReceivedAsync *m = data;
-
- m->aborted = TRUE;
- mail_msg_unref(m);
-}
-
-static EPopupItem emft_drop_popup_menu[] = {
- { E_POPUP_ITEM, (gchar *) "00.emc.00", (gchar *) N_("_Copy to Folder"), emft_drop_popup_copy, NULL, NULL, 1 },
- { E_POPUP_ITEM, (gchar *) "00.emc.01", (gchar *) N_("_Move to Folder"), emft_drop_popup_move, NULL, NULL, 1 },
- { E_POPUP_ITEM, (gchar *) "00.emc.02", (gchar *) N_("_Copy"), emft_drop_popup_copy, NULL, (gchar *) "folder-copy", 2 },
- { E_POPUP_ITEM, (gchar *) "00.emc.03", (gchar *) N_("_Move"), emft_drop_popup_move, NULL, (gchar *) "folder-move", 2 },
- { E_POPUP_BAR, (gchar *) "10.emc" },
- { E_POPUP_ITEM, (gchar *) "99.emc.00", (gchar *) N_("Cancel _Drag"), emft_drop_popup_cancel, NULL, (gchar *) "dialog-cancel", 0 },
-};
-
-static void
-emft_drop_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static void
tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection, guint info, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewDropPosition pos;
+ GtkTreeModel *model;
+ GtkTreeView *tree_view;
GtkTreePath *dest_path;
struct _DragDataReceivedAsync *m;
gboolean is_store;
CamelStore *store;
GtkTreeIter iter;
gchar *full_name;
- gint i;
- if (!gtk_tree_view_get_dest_row_at_pos (priv->treeview, x, y, &dest_path, &pos))
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &dest_path, &pos))
return;
/* this means we are receiving no data */
@@ -1022,15 +1408,16 @@ tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint
return;
}
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, dest_path)) {
+ if (!gtk_tree_model_get_iter (model, &iter, dest_path)) {
gtk_drag_finish(context, FALSE, FALSE, GDK_CURRENT_TIME);
return;
}
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_IS_STORE, &is_store,
- COL_STRING_FULL_NAME, &full_name, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_STRING_FULL_NAME, &full_name, -1);
/* make sure user isn't try to drop on a placeholder row */
if (full_name == NULL && !is_store) {
@@ -1053,30 +1440,7 @@ tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint
memcpy(m->selection->data, selection->data, selection->length);
m->selection->length = selection->length;
- if (context->action == GDK_ACTION_ASK) {
- EMPopup *emp;
- gint mask;
- GSList *menus = NULL;
- GtkMenu *menu;
-
- emp = em_popup_new("org.gnome.mail.storageset.popup.drop");
- if (info != DND_DROP_TYPE_FOLDER)
- mask = ~1;
- else
- mask = ~2;
-
- for (i=0;i<sizeof(emft_drop_popup_menu)/sizeof(emft_drop_popup_menu[0]);i++) {
- EPopupItem *item = &emft_drop_popup_menu[i];
-
- if ((item->visible & mask) == 0)
- menus = g_slist_append(menus, item);
- }
- e_popup_add_items((EPopup *)emp, menus, NULL, emft_drop_popup_free, m);
- menu = e_popup_create_menu_once((EPopup *)emp, NULL, mask);
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
- } else {
- tree_drag_data_action(m);
- }
+ tree_drag_data_action(m);
}
static gboolean
@@ -1088,27 +1452,32 @@ is_special_local_folder (const gchar *name)
static GdkAtom
emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
{
- struct _EMFolderTreePrivate *p = emft->priv;
+ EMFolderTreePrivate *p = emft->priv;
gchar *full_name = NULL, *uri = NULL, *src_uri = NULL;
CamelStore *local, *sstore, *dstore;
GdkAtom atom = GDK_NONE;
gboolean is_store;
+ GtkTreeModel *model;
GtkTreeIter iter;
GList *targets;
guint32 flags = 0;
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
/* This is a bit of a mess, but should handle all the cases properly */
- if (!gtk_tree_model_get_iter((GtkTreeModel *)p->model, &iter, path))
+ if (!gtk_tree_model_get_iter (model, &iter, path))
return GDK_NONE;
- gtk_tree_model_get((GtkTreeModel *)p->model, &iter, COL_BOOL_IS_STORE, &is_store,
- COL_STRING_FULL_NAME, &full_name,
- COL_UINT_FLAGS, &flags,
- COL_POINTER_CAMEL_STORE, &dstore,
- COL_STRING_URI, &uri, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_UINT_FLAGS, &flags,
+ COL_POINTER_CAMEL_STORE, &dstore,
+ COL_STRING_URI, &uri, -1);
- local = mail_component_peek_local_store (NULL);
+ local = e_mail_local_get_store ();
targets = context->targets;
@@ -1150,10 +1519,11 @@ emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
GtkTreePath *src_path = gtk_tree_row_reference_get_path(p->drag_row);
if (src_path) {
- if (gtk_tree_model_get_iter((GtkTreeModel *)p->model, &iter, src_path))
- gtk_tree_model_get((GtkTreeModel *)p->model, &iter,
- COL_POINTER_CAMEL_STORE, &sstore,
- COL_STRING_URI, &src_uri, -1);
+ if (gtk_tree_model_get_iter (model, &iter, src_path))
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &sstore,
+ COL_STRING_URI, &src_uri, -1);
/* can't dnd onto itself or below itself - bad things happen,
no point dragging to where we were either */
@@ -1284,12 +1654,15 @@ emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
static gboolean
tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewColumn *column;
+ GtkTreeView *tree_view;
gint cell_x, cell_y;
GtkTreePath *path;
GdkAtom target;
+ tree_view = GTK_TREE_VIEW (emft);
+
if (priv->autoscroll_id != 0) {
g_source_remove (priv->autoscroll_id);
priv->autoscroll_id = 0;
@@ -1303,7 +1676,7 @@ tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guin
priv->autoexpand_id = 0;
}
- if (!gtk_tree_view_get_path_at_pos (priv->treeview, x, y, &path, &column, &cell_x, &cell_y))
+ if (!gtk_tree_view_get_path_at_pos (tree_view, x, y, &path, &column, &cell_x, &cell_y))
return FALSE;
target = emft_drop_target(emft, context, path);
@@ -1317,7 +1690,7 @@ tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guin
static void
tree_drag_end (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
if (priv->drag_row) {
gtk_tree_row_reference_free (priv->drag_row);
@@ -1330,7 +1703,10 @@ tree_drag_end (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
static void
tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
+
+ tree_view = GTK_TREE_VIEW (emft);
if (priv->autoscroll_id != 0) {
g_source_remove (priv->autoscroll_id);
@@ -1345,7 +1721,7 @@ tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolde
priv->autoexpand_id = 0;
}
- gtk_tree_view_set_drag_dest_row(emft->priv->treeview, NULL, GTK_TREE_VIEW_DROP_BEFORE);
+ gtk_tree_view_set_drag_dest_row(tree_view, NULL, GTK_TREE_VIEW_DROP_BEFORE);
}
#define SCROLL_EDGE_SIZE 15
@@ -1353,19 +1729,20 @@ tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolde
static gboolean
tree_autoscroll (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkAdjustment *vadjustment;
+ GtkTreeView *tree_view;
GdkRectangle rect;
GdkWindow *window;
gint offset, y;
gfloat value;
/* get the y pointer position relative to the treeview */
- window = gtk_tree_view_get_bin_window (priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ window = gtk_tree_view_get_bin_window (tree_view);
gdk_window_get_pointer (window, NULL, &y, NULL);
/* rect is in coorinates relative to the scrolled window relative to the treeview */
- gtk_tree_view_get_visible_rect (priv->treeview, &rect);
+ gtk_tree_view_get_visible_rect (tree_view, &rect);
/* move y into the same coordinate system as rect */
y += rect.y;
@@ -1377,7 +1754,7 @@ tree_autoscroll (EMFolderTree *emft)
return TRUE;
}
- vadjustment = gtk_tree_view_get_vadjustment (priv->treeview);
+ vadjustment = gtk_tree_view_get_vadjustment (tree_view);
value = CLAMP (vadjustment->value + offset, 0.0, vadjustment->upper - vadjustment->page_size);
gtk_adjustment_set_value (vadjustment, value);
@@ -1388,11 +1765,13 @@ tree_autoscroll (EMFolderTree *emft)
static gboolean
tree_autoexpand (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
GtkTreePath *path;
+ tree_view = GTK_TREE_VIEW (emft);
path = gtk_tree_row_reference_get_path (priv->autoexpand_row);
- gtk_tree_view_expand_row (priv->treeview, path, FALSE);
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
gtk_tree_path_free (path);
return TRUE;
@@ -1401,16 +1780,20 @@ tree_autoexpand (EMFolderTree *emft)
static gboolean
tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeModel *model = (GtkTreeModel *) priv->model;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewDropPosition pos;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GdkDragAction action = 0;
GtkTreePath *path;
GtkTreeIter iter;
GdkAtom target;
gint i;
- if (!gtk_tree_view_get_dest_row_at_pos(priv->treeview, x, y, &path, &pos))
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (!gtk_tree_view_get_dest_row_at_pos(tree_view, x, y, &path, &pos))
return FALSE;
if (priv->autoscroll_id == 0)
@@ -1418,7 +1801,7 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
gtk_tree_model_get_iter (model, &iter, path);
- if (gtk_tree_model_iter_has_child (model, &iter) && !gtk_tree_view_row_expanded (priv->treeview, path)) {
+ if (gtk_tree_model_iter_has_child (model, &iter) && !gtk_tree_view_row_expanded (tree_view, path)) {
if (priv->autoexpand_id != 0) {
GtkTreePath *autoexpand_path;
@@ -1454,10 +1837,10 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
action = context->suggested_action;
if (action == GDK_ACTION_COPY && (context->actions & GDK_ACTION_MOVE))
action = GDK_ACTION_MOVE;
- gtk_tree_view_set_drag_dest_row(priv->treeview, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+ gtk_tree_view_set_drag_dest_row(tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
break;
default:
- gtk_tree_view_set_drag_dest_row(priv->treeview, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+ gtk_tree_view_set_drag_dest_row(tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
action = context->suggested_action;
break;
}
@@ -1476,12 +1859,15 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
void
em_folder_tree_enable_drag_and_drop (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv;
+ EMFolderTreePrivate *priv;
+ GtkTreeView *tree_view;
static gint setup = 0;
gint i;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+ tree_view = GTK_TREE_VIEW (emft);
+
priv = emft->priv;
if (!setup) {
for (i=0; i<NUM_DRAG_TYPES; i++)
@@ -1493,35 +1879,35 @@ em_folder_tree_enable_drag_and_drop (EMFolderTree *emft)
setup = 1;
}
- gtk_drag_source_set((GtkWidget *)priv->treeview, GDK_BUTTON1_MASK, drag_types, NUM_DRAG_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
- gtk_drag_dest_set((GtkWidget *)priv->treeview, GTK_DEST_DEFAULT_ALL, drop_types, NUM_DROP_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
+ gtk_drag_source_set((GtkWidget *)tree_view, GDK_BUTTON1_MASK, drag_types, NUM_DRAG_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ gtk_drag_dest_set((GtkWidget *)tree_view, GTK_DEST_DEFAULT_ALL, drop_types, NUM_DROP_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE);
- g_signal_connect (priv->treeview, "drag-begin", G_CALLBACK (tree_drag_begin), emft);
- g_signal_connect (priv->treeview, "drag-data-delete", G_CALLBACK (tree_drag_data_delete), emft);
- g_signal_connect (priv->treeview, "drag-data-get", G_CALLBACK (tree_drag_data_get), emft);
- g_signal_connect (priv->treeview, "drag-data-received", G_CALLBACK (tree_drag_data_received), emft);
- g_signal_connect (priv->treeview, "drag-drop", G_CALLBACK (tree_drag_drop), emft);
- g_signal_connect (priv->treeview, "drag-end", G_CALLBACK (tree_drag_end), emft);
- g_signal_connect (priv->treeview, "drag-leave", G_CALLBACK (tree_drag_leave), emft);
- g_signal_connect (priv->treeview, "drag-motion", G_CALLBACK (tree_drag_motion), emft);
+ g_signal_connect (tree_view, "drag-begin", G_CALLBACK (tree_drag_begin), emft);
+ g_signal_connect (tree_view, "drag-data-delete", G_CALLBACK (tree_drag_data_delete), emft);
+ g_signal_connect (tree_view, "drag-data-get", G_CALLBACK (tree_drag_data_get), emft);
+ g_signal_connect (tree_view, "drag-data-received", G_CALLBACK (tree_drag_data_received), emft);
+ g_signal_connect (tree_view, "drag-drop", G_CALLBACK (tree_drag_drop), emft);
+ g_signal_connect (tree_view, "drag-end", G_CALLBACK (tree_drag_end), emft);
+ g_signal_connect (tree_view, "drag-leave", G_CALLBACK (tree_drag_leave), emft);
+ g_signal_connect (tree_view, "drag-motion", G_CALLBACK (tree_drag_motion), emft);
}
void
-em_folder_tree_set_multiselect (EMFolderTree *tree, gboolean mode)
+em_folder_tree_set_excluded (EMFolderTree *emft, guint32 flags)
{
- GtkTreeSelection *sel = gtk_tree_view_get_selection ((GtkTreeView *) tree->priv->treeview);
-
- tree->priv->do_multiselect = mode;
- gtk_tree_selection_set_mode (sel, mode ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE);
-}
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
-void em_folder_tree_set_excluded(EMFolderTree *emft, guint32 flags)
-{
emft->priv->excluded = flags;
}
-void em_folder_tree_set_excluded_func(EMFolderTree *emft, EMFTExcludeFunc exclude, gpointer data)
+void
+em_folder_tree_set_excluded_func (EMFolderTree *emft,
+ EMFTExcludeFunc exclude,
+ gpointer data)
{
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+ g_return_if_fail (exclude != NULL);
+
emft->priv->excluded_func = exclude;
emft->priv->excluded_data = data;
}
@@ -1529,10 +1915,14 @@ void em_folder_tree_set_excluded_func(EMFolderTree *emft, EMFTExcludeFunc exclud
GList *
em_folder_tree_get_selected_uris (EMFolderTree *emft)
{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (emft->priv->treeview);
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GList *list = NULL, *rows, *l;
GSList *sl;
- GtkTreeModel *model;
+
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
/* at first, add lost uris */
for (sl = emft->priv->select_uris; sl; sl = g_slist_next(sl))
@@ -1569,31 +1959,22 @@ get_selected_uris_path_iterate (GtkTreeModel *model, GtkTreePath *treepath, GtkT
GList *
em_folder_tree_get_selected_paths (EMFolderTree *emft)
{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (emft->priv->treeview);
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
GList *list = NULL;
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
gtk_tree_selection_selected_foreach (selection, get_selected_uris_path_iterate, &list);
return list;
}
-static void
-emft_clear_selected_list(EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- g_slist_foreach(priv->select_uris, emft_free_select_uri, emft);
- g_slist_free(priv->select_uris);
- g_hash_table_destroy(priv->select_uris_table);
- priv->select_uris = NULL;
- priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
- priv->cursor_set = FALSE;
-}
-
void
em_folder_tree_set_selected_list (EMFolderTree *emft, GList *list, gboolean expand_only)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gint id = 0;
/* FIXME: need to remove any currently selected stuff? */
@@ -1646,8 +2027,7 @@ em_folder_tree_set_selected_list (EMFolderTree *emft, GList *list, gboolean expa
end = strrchr(expand_key, '/');
do {
- emft_expand_node(priv->model, expand_key, emft);
- em_folder_tree_model_set_expanded(priv->model, expand_key, TRUE);
+ emft_expand_node(expand_key, emft);
*end = 0;
end = strrchr(expand_key, '/');
} while (end);
@@ -1679,680 +2059,15 @@ dump_fi (CamelFolderInfo *fi, gint depth)
}
#endif
-struct _EMFolderTreeGetFolderInfo {
- MailMsg base;
-
- /* input data */
- GtkTreeRowReference *root;
- EMFolderTree *emft;
- CamelStore *store;
- guint32 flags;
- gchar *top;
-
- /* output data */
- CamelFolderInfo *fi;
-};
-
-static gchar *
-emft_get_folder_info__desc (struct _EMFolderTreeGetFolderInfo *m)
-{
- gchar *ret, *name;
-
- name = camel_service_get_name((CamelService *)m->store, TRUE);
- ret = g_strdup_printf(_("Scanning folders in \"%s\""), name);
- g_free(name);
- return ret;
-}
-
-static void
-emft_get_folder_info__exec (struct _EMFolderTreeGetFolderInfo *m)
-{
- guint32 flags = m->flags | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-
- m->fi = camel_store_get_folder_info (m->store, m->top, flags, &m->base.ex);
-}
-
-static void
-emft_get_folder_info__done (struct _EMFolderTreeGetFolderInfo *m)
-{
- struct _EMFolderTreePrivate *priv = m->emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeIter root, iter, titer;
- CamelFolderInfo *fi;
- GtkTreeStore *model;
- GtkTreePath *path;
- gboolean is_store;
-
- /* check that we haven't been destroyed */
- if (priv->treeview == NULL)
- return;
-
- /* check that our parent folder hasn't been deleted/unsubscribed */
- if (!gtk_tree_row_reference_valid (m->root))
- return;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, m->store))) {
- /* store has been removed in the interim - do nothing */
- return;
- }
-
- model = (GtkTreeStore *) gtk_tree_view_get_model (priv->treeview);
-
- path = gtk_tree_row_reference_get_path (m->root);
- gtk_tree_model_get_iter ((GtkTreeModel *) model, &root, path);
-
- /* if we had an error, then we need to re-set the load subdirs state and collapse the node */
- if (!m->fi && camel_exception_is_set(&m->base.ex)) {
- gtk_tree_store_set(model, &root, COL_BOOL_LOAD_SUBDIRS, TRUE, -1);
- gtk_tree_view_collapse_row (priv->treeview, path);
- gtk_tree_path_free (path);
- return;
- }
-
- gtk_tree_path_free (path);
-
- /* make sure we still need to load the tree subfolders... */
- gtk_tree_model_get ((GtkTreeModel *) model, &root,
- COL_BOOL_IS_STORE, &is_store,
- -1);
-
- /* get the first child (which will be a dummy node) */
- gtk_tree_model_iter_children ((GtkTreeModel *) model, &iter, &root);
-
- /* Traverse to the last valid iter */
- titer = iter;
- while (gtk_tree_model_iter_next((GtkTreeModel *) model, &iter))
- titer = iter; /* Preserve the last valid iter */
-
- iter = titer;
-
- /* FIXME: camel's IMAP code is totally on crack here, @top's
- * folder info should be @fi and fi->child should be what we
- * want to fill our tree with... *sigh* */
- if (m->top && m->fi && !strcmp (m->fi->full_name, m->top)) {
- if (!(fi = m->fi->child))
- fi = m->fi->next;
- } else
- fi = m->fi;
-
- if (fi == NULL) {
- /* no children afterall... remove the "Loading..." placeholder node */
- emft_update_model_expanded_state (priv, &root, FALSE);
-
- gtk_tree_store_remove (model, &iter);
-
- if (is_store) {
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, &root);
- gtk_tree_view_collapse_row (priv->treeview, path);
- emft_queue_save_state (m->emft);
- gtk_tree_path_free (path);
- return;
- }
- } else {
- gint fully_loaded = (m->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? TRUE : FALSE;
-
- do {
- gboolean known = g_hash_table_lookup (si->full_hash, fi->full_name) != NULL;
-
- if (!known)
- em_folder_tree_model_set_folder_info (priv->model, &iter, si, fi, fully_loaded);
-
- if ((fi = fi->next) != NULL && !known)
- gtk_tree_store_append (model, &iter, &root);
- } while (fi != NULL);
- }
-
- gtk_tree_store_set (model, &root, COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
- emft_queue_save_state (m->emft);
-}
-
-static void
-emft_get_folder_info__free (struct _EMFolderTreeGetFolderInfo *m)
-{
- camel_store_free_folder_info (m->store, m->fi);
-
- gtk_tree_row_reference_free (m->root);
- g_object_unref(m->emft);
- camel_object_unref (m->store);
- g_free (m->top);
-}
-
-static MailMsgInfo get_folder_info_info = {
- sizeof (struct _EMFolderTreeGetFolderInfo),
- (MailMsgDescFunc) emft_get_folder_info__desc,
- (MailMsgExecFunc) emft_get_folder_info__exec,
- (MailMsgDoneFunc) emft_get_folder_info__done,
- (MailMsgFreeFunc) emft_get_folder_info__free
-};
-
-static void
-emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter *iter, gboolean expanded)
-{
- struct _EMFolderTreeModelStoreInfo *si;
- gboolean is_store;
- CamelStore *store;
- EAccount *account;
- gchar *full_name;
- gchar *key;
-
- gtk_tree_model_get ((GtkTreeModel *) priv->model, iter,
- COL_STRING_FULL_NAME, &full_name,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_IS_STORE, &is_store,
- -1);
-
- si = g_hash_table_lookup (priv->model->store_hash, store);
- if ((account = mail_config_get_account_by_name (si->display_name))) {
- key = g_strdup_printf ("%s/%s", account->uid, full_name ? full_name : "");
- } else if (CAMEL_IS_VEE_STORE (store)) {
- /* vfolder store */
- key = g_strdup_printf ("vfolder/%s", full_name ? full_name : "");
- } else {
- /* local store */
- key = g_strdup_printf ("local/%s", full_name ? full_name : "");
- }
-
- em_folder_tree_model_set_expanded (priv->model, key, expanded);
- g_free (full_name);
- g_free (key);
-}
-
-static void
-emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeGetFolderInfo *m;
- GtkTreeModel *model;
- CamelStore *store;
- gchar *full_name;
- gboolean load;
-
- model = gtk_tree_view_get_model (treeview);
-
- gtk_tree_model_get (model, root,
- COL_STRING_FULL_NAME, &full_name,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_LOAD_SUBDIRS, &load,
- -1);
-
- emft_update_model_expanded_state (priv, root, TRUE);
-
- if (!load) {
- emft_queue_save_state (emft);
- g_free (full_name);
- return;
- }
-
- gtk_tree_store_set ((GtkTreeStore *)model, root, COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
-
- m = mail_msg_new (&get_folder_info_info);
- m->root = gtk_tree_row_reference_new (model, tree_path);
- camel_object_ref (store);
- m->store = store;
- m->emft = emft;
- g_object_ref(emft);
- m->top = full_name;
- m->flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST;
-
- mail_msg_unordered_push (m);
-}
-
-static gboolean
-emft_tree_test_collapse_row (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter cursor;
-
- selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected (selection, &model, &cursor)) {
- /* select the collapsed node IFF it is a parent of the currently selected folder */
- if (gtk_tree_store_is_ancestor ((GtkTreeStore *) model, root, &cursor))
- gtk_tree_view_set_cursor (treeview, tree_path, NULL, FALSE);
- }
-
- emft_update_model_expanded_state (emft->priv, root, FALSE);
- emft_queue_save_state (emft);
-
- return FALSE;
-}
-
-static void
-emft_tree_row_activated (GtkTreeView *treeview, GtkTreePath *tree_path, GtkTreeViewColumn *column, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeModel *model = (GtkTreeModel *) priv->model;
- gchar *full_name, *uri;
- GtkTreeIter iter;
- guint32 flags;
-
- if (!emft_select_func(NULL, model, tree_path, FALSE, emft))
- return;
-
- if (!gtk_tree_model_get_iter (model, &iter, tree_path))
- return;
-
- gtk_tree_model_get (model, &iter, COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags, -1);
-
- emft_clear_selected_list(emft);
-
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
- g_signal_emit (emft, signals[FOLDER_ACTIVATED], 0, full_name, uri);
-
- g_free(full_name);
- g_free(uri);
-}
-
-#if 0
-static void
-emft_popup_view (GtkWidget *item, EMFolderTree *emft)
-{
-
-}
-
-static void
-emft_popup_open_new (GtkWidget *item, EMFolderTree *emft)
-{
-}
-#endif
-
-static void
-emft_popup_copy(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi = NULL;
-
- /* FIXME: use async apis */
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL)
- em_folder_utils_copy_folder(fi, FALSE);
-}
-
-static void
-emft_popup_move(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi = NULL;
-
- /* FIXME: use async apis */
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL)
- em_folder_utils_copy_folder(fi, TRUE);
-}
-
-static void
-emft_popup_new_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi;
-
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL) {
- em_folder_utils_create_folder (fi, emft, NULL);
- camel_folder_info_free(fi);
- }
-}
-
-static void
-selfunc (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
- struct _emft_selection_data *dat = (struct _emft_selection_data *) data;
-
- dat->model = model;
- if (!dat->set)
- *(dat->iter) = *iter;
- dat->set = TRUE;
-}
-
-static gboolean
-emft_selection_get_selected (GtkTreeSelection *selection, GtkTreeModel **model, GtkTreeIter *iter)
-{
- struct _emft_selection_data dat = { NULL, iter, FALSE };
-
- if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_MULTIPLE) {
- gtk_tree_selection_selected_foreach (selection, selfunc, &dat);
- if (model)
- *model = dat.model;
- return dat.set;
- } else {
- return gtk_tree_selection_get_selected (selection, model, iter);
- }
-}
-
-static void
-emft_popup_delete_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- em_folder_utils_delete_folder(folder);
- }
-}
-
-static void
-emft_popup_rename_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- em_folder_utils_rename_folder(folder);
- }
-}
-
-static void
-emft_popup_refresh_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- EMEvent *e = em_event_peek();
- EMEventTargetFolder *t = em_event_target_new_folder(e, folder->full_name, 0);
- e_event_emit((EEvent *)e, "folder.refresh", (EEventTarget *)t);
- mail_refresh_folder(folder, NULL, NULL);
- }
-}
-
-static void
-emft_popup_flush_outbox (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- mail_send ();
-}
-
-static void
-emft_popup_empty_trash (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- em_utils_empty_trash (data);
-}
-
-static void
-emft_popup_properties (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *uri;
-
- selection = gtk_tree_view_get_selection (priv->treeview);
- if (!emft_selection_get_selected (selection, &model, &iter))
- return;
-
- gtk_tree_model_get (model, &iter, COL_STRING_URI, &uri, -1);
- em_folder_properties_show (NULL, NULL, uri);
- g_free (uri);
-}
-
-static void
-emft_popup_uvfolder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- gchar *meta = camel_object_meta_get(folder, "vfolder:unread");
- if (!meta || strcmp(meta, "false") == 0)
- camel_object_meta_set(folder, "vfolder:unread", "true");
- else
- camel_object_meta_set(folder, "vfolder:unread", "false");
- camel_object_state_write (folder);
- g_free (meta);
- }
-}
-
-static EPopupItem emft_popup_items[] = {
-#if 0
- { E_POPUP_ITEM, "00.emc.00", N_("_View"), emft_popup_view, NULL, NULL, EM_POPUP_FOLDER_SELECT },
- { E_POPUP_ITEM, "00.emc.01", N_("Open in _New Window"), emft_popup_open_new, NULL, NULL, EM_POPUP_FOLDER_SELECT },
-
- { E_POPUP_BAR, "10.emc" },
-#endif
- /* FIXME: need to disable for nochildren folders */
- { E_POPUP_ITEM, (gchar *) "10.emc.00", (gchar *) N_("_New Folder..."), emft_popup_new_folder, NULL, (gchar *) "folder-new", 0, EM_POPUP_FOLDER_INFERIORS },
-
- { E_POPUP_ITEM, (gchar *) "10.emc.05", (gchar *) N_("_Copy..."), emft_popup_copy, NULL, (gchar *) "folder-copy", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT },
- { E_POPUP_ITEM, (gchar *) "10.emc.06", (gchar *) N_("_Move..."), emft_popup_move, NULL, (gchar *) "folder-move", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
-
- /* FIXME: need to disable for undeletable folders */
- { E_POPUP_BAR, (gchar *) "20.emc" },
- { E_POPUP_ITEM, (gchar *) "20.emc.01", (gchar *) N_("_Delete"), emft_popup_delete_folder, NULL, (gchar *) "edit-delete", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
-
- { E_POPUP_BAR, (gchar *) "30.emc" },
- { E_POPUP_ITEM, (gchar *) "30.emc.02", (gchar *) N_("_Rename..."), emft_popup_rename_folder, NULL, NULL, 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
- { E_POPUP_ITEM, (gchar *) "30.emc.03", (gchar *) N_("Re_fresh"), emft_popup_refresh_folder, NULL, (gchar *) "view-refresh", EM_POPUP_FOLDER_NONSTATIC, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT},
- { E_POPUP_ITEM, (gchar *) "30.emc.04", (gchar *) N_("Fl_ush Outbox"), emft_popup_flush_outbox, NULL, (gchar *) "mail-send", EM_POPUP_FOLDER_OUTBOX, 0 },
-
- { E_POPUP_BAR, (gchar *) "99.emc" },
- { E_POPUP_ITEM, (gchar *) "99.emc.00", (gchar *) N_("_Properties"), emft_popup_properties, NULL, (gchar *) "document-properties", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT }
-};
-static EPopupItem trash_popup_item = {E_POPUP_ITEM, (gchar *) "30.emc.05", (gchar *) N_("_Empty Trash"), emft_popup_empty_trash,NULL,NULL, 1, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT};
-
-static void
-emft_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static gboolean
-emft_popup (EMFolderTree *emft, GdkEvent *event)
-{
- GtkTreeView *treeview;
- GtkTreeSelection *selection;
- CamelStore *local, *store;
- EMPopupTargetFolder *target;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GSList *menus = NULL;
- guint32 info_flags = 0;
- guint32 flags = 0;
- guint32 folder_type_flags = 0;
- gboolean isstore;
- gchar *uri, *full_name;
- GtkMenu *menu;
- EMPopup *emp;
- CamelFolder *selfolder = NULL;
- gint i;
-
- treeview = emft->priv->treeview;
-
- /* this centralises working out when the user's done something */
- emft_tree_user_event(treeview, (GdkEvent *)event, emft);
-
- /* FIXME: we really need the folderinfo to build a proper menu */
- selection = gtk_tree_view_get_selection (treeview);
- if (!emft_selection_get_selected (selection, &model, &iter))
- return FALSE;
-
- gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_URI, &uri, COL_STRING_FULL_NAME, &full_name,
- COL_BOOL_IS_STORE, &isstore, COL_UINT_FLAGS, &folder_type_flags, -1);
-
- /* Stores have full_name == NULL, otherwise its just a placeholder */
- /* NB: This is kind of messy */
- if (!isstore && full_name == NULL) {
- g_free (uri);
- return FALSE;
- }
-
- /* TODO: em_popup_target_folder_new? */
- if (isstore) {
- flags |= EM_POPUP_FOLDER_STORE;
- } else {
- flags |= EM_POPUP_FOLDER_FOLDER;
-
- local = mail_component_peek_local_store (NULL);
-
- /* don't allow deletion of special local folders */
- if (!(store == local && is_special_local_folder (full_name)))
- flags |= EM_POPUP_FOLDER_DELETE;
-
- /* hack for vTrash/vJunk */
- if (!strcmp (full_name, CAMEL_VTRASH_NAME) || !strcmp (full_name, CAMEL_VJUNK_NAME))
- info_flags |= CAMEL_FOLDER_VIRTUAL | CAMEL_FOLDER_NOINFERIORS;
-
- selfolder = em_folder_tree_get_selected_folder (emft);
-
- if (folder_type_flags & CAMEL_FOLDER_SYSTEM)
- flags &= ~EM_POPUP_FOLDER_DELETE;
-
- if (em_utils_folder_is_outbox (selfolder, NULL))
- info_flags |= CAMEL_FOLDER_TYPE_OUTBOX;
- }
-
- /** @HookPoint-EMPopup: Folder Tree Context Menu
- * @Id: org.gnome.evolution.mail.foldertree.popup
- * @Class: org.gnome.evolution.mail.popup:1.0
- * @Target: EMPopupTargetFolder
- *
- * This is the context menu shown on the folder tree.
- */
- emp = em_popup_new ("org.gnome.evolution.mail.foldertree.popup");
-
- /* FIXME: pass valid fi->flags here */
- target = em_popup_target_new_folder (emp, uri, info_flags, flags);
-
- for (i = 0; i < sizeof (emft_popup_items) / sizeof (emft_popup_items[0]); i++)
- menus = g_slist_prepend (menus, &emft_popup_items[i]);
-
- if ((folder_type_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH)
- menus = g_slist_prepend (menus, &trash_popup_item);
- if (!isstore && strstr(uri, "vfolder")) {
- /* This is a vfolder, so lets add hacked up menu item. */
- static EPopupItem *item = NULL;
- gchar *meta = camel_object_meta_get (selfolder, "vfolder:unread");
-
- if (!item)
- item = g_malloc0(sizeof(*item));
- if (meta && (strcmp (meta, "true") == 0))
- item->type = E_POPUP_TOGGLE | E_POPUP_ACTIVE;
- else
- item->type = E_POPUP_TOGGLE & ~E_POPUP_ACTIVE;
- item->path = (gchar *) "99.emc.99";
- item->label = _("_Unread Search Folder");
- item->activate = emft_popup_uvfolder;
- item->visible = EM_POPUP_FOLDER_SELECT;
- item->user_data = NULL;
- menus = g_slist_prepend (menus, item);
- g_free (meta);
- }
-
- e_popup_add_items ((EPopup *)emp, menus, NULL, emft_popup_free, emft);
-
- menu = e_popup_create_menu_once ((EPopup *)emp, (EPopupTarget *)target, 0);
-
- if (event == NULL || event->type == GDK_KEY_PRESS) {
- /* FIXME: menu pos function */
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
- } else {
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
- }
-
- g_free (full_name);
- g_free (uri);
-
- return TRUE;
-}
-
-static gboolean
-emft_popup_menu (GtkWidget *widget)
-{
- return emft_popup (EM_FOLDER_TREE (widget), NULL);
-}
-
-static gboolean
-emft_tree_button_press (GtkTreeView *treeview, GdkEventButton *event, EMFolderTree *emft)
-{
- GtkTreeSelection *selection;
- GtkTreePath *tree_path;
-
- /* this centralises working out when the user's done something */
- emft_tree_user_event(treeview, (GdkEvent *)event, emft);
-
- if (event->button != 3 && !(event->button == 1 && event->type == GDK_2BUTTON_PRESS))
- return FALSE;
-
- if (!gtk_tree_view_get_path_at_pos (treeview, (gint) event->x, (gint) event->y, &tree_path, NULL, NULL, NULL))
- return FALSE;
-
- /* select/focus the row that was right-clicked or double-clicked */
- selection = gtk_tree_view_get_selection (treeview);
- gtk_tree_selection_select_path(selection, tree_path);
- gtk_tree_view_set_cursor (treeview, tree_path, NULL, FALSE);
-
- if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
- if (emft->priv->skip_double_click) {
- return FALSE;
- }
- emft_tree_row_activated (treeview, tree_path, NULL, emft);
- gtk_tree_path_free (tree_path);
- return TRUE;
- }
-
- gtk_tree_path_free (tree_path);
-
- return emft_popup (emft, (GdkEvent *)event);
-}
-
-/* This is called for keyboard and mouse events, it seems the only way
- * we know the user has done something to the selection as opposed to
- * code or initialisation processes */
-static gboolean
-emft_tree_user_event (GtkTreeView *treeview, GdkEvent *e, EMFolderTree *emft)
-{
- if (e && e->type == GDK_KEY_PRESS && (e->key.keyval == GDK_space || e->key.keyval == '.' || e->key.keyval == ',' || e->key.keyval == '[' || e->key.keyval == ']')) {
- g_signal_emit (emft, signals [HIDDEN_KEY_EVENT], 0, e);
-
- return TRUE;
- }
- if (!emft->priv->do_multiselect)
- emft_clear_selected_list(emft);
-
- emft->priv->cursor_set = TRUE;
-
- return FALSE;
-}
-
-static void
-emft_tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft)
-{
- gchar *full_name, *uri;
- GtkTreeModel *model;
- GtkTreeIter iter;
- guint32 flags;
- guint unread = 0;
- guint old_unread = 0;
-
- if (!emft_selection_get_selected (selection, &model, &iter)) {
- em_folder_tree_model_set_selected (emft->priv->model, NULL);
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, NULL, NULL, 0);
- emft_queue_save_state (emft);
- return;
- }
-
- gtk_tree_model_get (
- model, &iter,
- COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags,
- COL_UINT_UNREAD, &unread, COL_UINT_UNREAD_LAST_SEL,
- &old_unread, -1);
-
- /* Sync unread counts to distinguish new incoming mail. */
- if (unread != old_unread)
- gtk_tree_store_set (
- GTK_TREE_STORE (model), &iter,
- COL_UINT_UNREAD_LAST_SEL, unread, -1);
-
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
- g_free(uri);
- g_free(full_name);
-}
-
void
-em_folder_tree_set_selected (EMFolderTree *emft, const gchar *uri, gboolean expand_only)
+em_folder_tree_set_selected (EMFolderTree *emft,
+ const gchar *uri,
+ gboolean expand_only)
{
GList *l = NULL;
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+
if (uri && uri[0])
l = g_list_append(l, (gpointer)uri);
@@ -2363,16 +2078,18 @@ em_folder_tree_set_selected (EMFolderTree *emft, const gchar *uri, gboolean expa
void
em_folder_tree_select_next_path (EMFolderTree *emft, gboolean skip_read_folders)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter, parent, child;
GtkTreePath *current_path, *path = NULL;
guint unread = 0;
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection(tree_view);
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
current_path = gtk_tree_model_get_path (model, &iter);
@@ -2407,16 +2124,16 @@ em_folder_tree_select_next_path (EMFolderTree *emft, gboolean skip_read_folders)
}
if (path) {
- if (!gtk_tree_view_row_expanded (emft->priv->treeview, path))
- gtk_tree_view_expand_to_path (emft->priv->treeview, path);
+ if (!gtk_tree_view_row_expanded (tree_view, path))
+ gtk_tree_view_expand_to_path (tree_view, path);
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.5f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
}
return;
}
@@ -2442,16 +2159,18 @@ get_last_child (GtkTreeModel *model, GtkTreeIter *iter)
void
em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter, child;
GtkTreePath *path = NULL, *current_path = NULL;
guint unread = 0;
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
@@ -2485,17 +2204,17 @@ em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
}
if (path) {
- if (!gtk_tree_view_row_expanded (priv->treeview, path)) {
- gtk_tree_view_expand_to_path (priv->treeview, path);
+ if (!gtk_tree_view_row_expanded (tree_view, path)) {
+ gtk_tree_view_expand_to_path (tree_view, path);
}
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.5f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
}
return;
}
@@ -2503,6 +2222,7 @@ em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
gchar *
em_folder_tree_get_selected_uri (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2510,9 +2230,13 @@ em_folder_tree_get_selected_uri (EMFolderTree *emft)
g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, COL_STRING_URI, &uri, -1);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_URI, &uri, -1);
return uri;
}
@@ -2520,6 +2244,7 @@ em_folder_tree_get_selected_uri (EMFolderTree *emft)
gchar *
em_folder_tree_get_selected_path (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2527,9 +2252,13 @@ em_folder_tree_get_selected_path (EMFolderTree *emft)
g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, COL_STRING_FULL_NAME, &name, -1);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_FULL_NAME, &name, -1);
return name;
}
@@ -2537,6 +2266,7 @@ em_folder_tree_get_selected_path (EMFolderTree *emft)
CamelFolder *
em_folder_tree_get_selected_folder (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2549,7 +2279,9 @@ em_folder_tree_get_selected_folder (EMFolderTree *emft)
camel_exception_init (&ex);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
if (gtk_tree_selection_get_selected(selection, &model, &iter))
gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
COL_STRING_FULL_NAME, &full_name, -1);
@@ -2565,6 +2297,7 @@ em_folder_tree_get_selected_folder (EMFolderTree *emft)
CamelFolderInfo *
em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2577,7 +2310,9 @@ em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
camel_exception_init (&ex);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
if (gtk_tree_selection_get_selected(selection, &model, &iter))
gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
COL_STRING_FULL_NAME, &full_name,
@@ -2606,54 +2341,6 @@ em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
return fi;
}
-EMFolderTreeModel *
-em_folder_tree_get_model (EMFolderTree *emft)
-{
- g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
-
- return emft->priv->model;
-}
-
-EMFolderTreeModelStoreInfo *
-em_folder_tree_get_model_storeinfo (EMFolderTree *emft, CamelStore *store)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
- g_return_val_if_reached (NULL);
- }
- return si;
-}
-
-static gboolean
-emft_save_state (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- em_folder_tree_model_save_state (priv->model);
- priv->save_state_id = 0;
-
- return FALSE;
-}
-
-static void
-emft_queue_save_state (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- if (priv->save_state_id != 0)
- return;
-
- priv->save_state_id = g_timeout_add_seconds (1, (GSourceFunc) emft_save_state, emft);
-}
-
-GtkWidget *
-em_folder_tree_get_tree_view (EMFolderTree *emft)
-{
- return (GtkWidget *)emft->priv->treeview;
-}
-
void
em_folder_tree_set_skip_double_click (EMFolderTree *emft, gboolean skip)
{
diff --git a/mail/em-folder-tree.h b/mail/em-folder-tree.h
index e8b607151c..74b79d37ee 100644
--- a/mail/em-folder-tree.h
+++ b/mail/em-folder-tree.h
@@ -21,25 +21,37 @@
*
*/
-#ifndef __EM_FOLDER_TREE_H__
-#define __EM_FOLDER_TREE_H__
+#ifndef EM_FOLDER_TREE_H
+#define EM_FOLDER_TREE_H
#include <gtk/gtk.h>
#include <camel/camel-store.h>
-
-#include "mail/em-folder-tree-model.h"
+#include <mail/em-folder-tree-model.h>
+
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_TREE \
+ (em_folder_tree_get_type ())
+#define EM_FOLDER_TREE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FOLDER_TREE, EMFolderTree))
+#define EM_FOLDER_TREE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FOLDER_TREE, EMFolderTreeClass))
+#define EM_IS_FOLDER_TREE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FOLDER_TREE))
+#define EM_IS_FOLDER_TREE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_FOLDER_TREE))
+#define EM_FOLDER_TREE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FOLDER_TREE, EMFolderTreeClass))
G_BEGIN_DECLS
-#define EM_TYPE_FOLDER_TREE (em_folder_tree_get_type ())
-#define EM_FOLDER_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_TREE, EMFolderTree))
-#define EM_FOLDER_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_TREE, EMFolderTreeClass))
-#define EM_IS_FOLDER_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_TREE))
-#define EM_IS_FOLDER_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EM_TYPE_FOLDER_TREE))
-#define EM_FOLDER_TREE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EM_TYPE_FOLDER_TREE, EMFolderTreeClass))
-
typedef struct _EMFolderTree EMFolderTree;
typedef struct _EMFolderTreeClass EMFolderTreeClass;
+typedef struct _EMFolderTreePrivate EMFolderTreePrivate;
/* not sure this api is the best, but its the easiest to implement and will cover what we need */
#define EMFT_EXCLUDE_NOSELECT CAMEL_FOLDER_NOSELECT
@@ -51,28 +63,29 @@ typedef struct _EMFolderTreeClass EMFolderTreeClass;
typedef gboolean (*EMFTExcludeFunc)(EMFolderTree *emft, GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
struct _EMFolderTree {
- GtkVBox parent_object;
-
- struct _EMFolderTreePrivate *priv;
+ GtkTreeView parent_object;
+ EMFolderTreePrivate *priv;
};
struct _EMFolderTreeClass {
- GtkVBoxClass parent_class;
+ GtkTreeViewClass parent_class;
/* signals */
- void (* folder_activated) (EMFolderTree *emft, const gchar *full_name, const gchar *uri);
- void (* folder_selected) (EMFolderTree *emft, const gchar *full_name, const gchar *uri, guint32 flags);
- void (* hidden_key_event) (EMFolderTree *emft, GdkEvent *event);
+ void (*folder_activated) (EMFolderTree *emft,
+ const gchar *full_name,
+ const gchar *uri);
+ void (*folder_selected) (EMFolderTree *emft,
+ const gchar *full_name,
+ const gchar *uri,
+ guint32 flags);
+ void (*popup_event) (EMFolderTree *emft);
};
-GType em_folder_tree_get_type (void);
-
-GtkWidget *em_folder_tree_new (void);
-GtkWidget *em_folder_tree_new_with_model (EMFolderTreeModel *model);
+GType em_folder_tree_get_type (void);
+GtkWidget * em_folder_tree_new (void);
void em_folder_tree_enable_drag_and_drop (EMFolderTree *emft);
-void em_folder_tree_set_multiselect (EMFolderTree *emft, gboolean mode);
void em_folder_tree_set_excluded(EMFolderTree *emft, guint32 flags);
void em_folder_tree_set_excluded_func(EMFolderTree *emft, EMFTExcludeFunc exclude, gpointer data);
@@ -88,13 +101,9 @@ gchar *em_folder_tree_get_selected_path (EMFolderTree *emft);
CamelFolder *em_folder_tree_get_selected_folder (EMFolderTree *emft);
CamelFolderInfo *em_folder_tree_get_selected_folder_info (EMFolderTree *emft);
-EMFolderTreeModel *em_folder_tree_get_model (EMFolderTree *emft);
-EMFolderTreeModelStoreInfo *em_folder_tree_get_model_storeinfo (EMFolderTree *emft, CamelStore *store);
-
gboolean em_folder_tree_create_folder (EMFolderTree *emft, const gchar *full_name, const gchar *uri);
-GtkWidget * em_folder_tree_get_tree_view (EMFolderTree *emft);
void em_folder_tree_set_skip_double_click (EMFolderTree *emft, gboolean skip);
G_END_DECLS
-#endif /* __EM_FOLDER_TREE_H__ */
+#endif /* EM_FOLDER_TREE_H */
diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c
index 528802c052..700e445beb 100644
--- a/mail/em-folder-utils.c
+++ b/mail/em-folder-utils.c
@@ -57,12 +57,10 @@
#include "mail-ops.h"
#include "mail-tools.h"
#include "mail-config.h"
-#include "mail-component.h"
#include "mail-vfolder.h"
#include "mail-folder-cache.h"
#include "em-utils.h"
-#include "em-popup.h"
#include "em-folder-tree.h"
#include "em-folder-tree-model.h"
#include "em-folder-utils.h"
@@ -70,6 +68,9 @@
#include "em-folder-selection.h"
#include "em-folder-properties.h"
+#include "e-mail-local.h"
+#include "e-mail-store.h"
+
#define d(x)
extern CamelSession *session;
@@ -268,6 +269,7 @@ emfu_copy_folder_selected (const gchar *uri, gpointer data)
{
struct _copy_folder_data *cfd = data;
CamelStore *fromstore = NULL, *tostore = NULL;
+ CamelStore *local_store;
const gchar *tobase = NULL;
CamelException ex;
CamelURL *url;
@@ -279,13 +281,15 @@ emfu_copy_folder_selected (const gchar *uri, gpointer data)
camel_exception_init (&ex);
+ local_store = e_mail_local_get_store ();
+
if (!(fromstore = camel_session_get_store (session, cfd->fi->uri, &ex))) {
e_error_run(NULL,
cfd->delete?"mail:no-move-folder-notexist":"mail:no-copy-folder-notexist", cfd->fi->full_name, uri, ex.desc, NULL);
goto fail;
}
- if (cfd->delete && fromstore == mail_component_peek_local_store (NULL) && emfu_is_special_local_folder (cfd->fi->full_name)) {
+ if (cfd->delete && fromstore == local_store && emfu_is_special_local_folder (cfd->fi->full_name)) {
GtkWidget *w = e_error_new (NULL,
"mail:no-rename-special-folder", cfd->fi->full_name, NULL);
em_utils_show_error_silent (w);
@@ -351,17 +355,22 @@ emfu_copy_folder_exclude(EMFolderTree *tree, GtkTreeModel *model, GtkTreeIter *i
/* FIXME: this interface references the folderinfo without copying it */
/* FIXME: these functions must be documented */
void
-em_folder_utils_copy_folder(CamelFolderInfo *folderinfo, gint delete)
+em_folder_utils_copy_folder (CamelFolderInfo *folderinfo,
+ gint delete)
{
struct _copy_folder_data *cfd;
+ g_return_if_fail (folderinfo != NULL);
+
cfd = g_malloc (sizeof (*cfd));
cfd->fi = folderinfo;
cfd->delete = delete;
- em_select_folder (NULL, _("Select folder"), delete?_("_Move"):_("C_opy"),
- NULL, emfu_copy_folder_exclude,
- emfu_copy_folder_selected, cfd);
+ em_select_folder (
+ _("Select folder"),
+ delete ? _("_Move") : _("C_opy"),
+ NULL, emfu_copy_folder_exclude,
+ emfu_copy_folder_selected, cfd);
}
static void
@@ -397,13 +406,13 @@ emfu_delete_response (GtkWidget *dialog, gint response, gpointer data)
void
em_folder_utils_delete_folder (CamelFolder *folder)
{
- CamelStore *local;
+ CamelStore *local_store;
GtkWidget *dialog;
gint flags = 0;
- local = mail_component_peek_local_store (NULL);
+ local_store = e_mail_local_get_store ();
- if (folder->parent_store == local && emfu_is_special_local_folder (folder->full_name)) {
+ if (folder->parent_store == local_store && emfu_is_special_local_folder (folder->full_name)) {
dialog = e_error_new (NULL, "mail:no-delete-special-folder", folder->full_name, NULL);
em_utils_show_error_silent (dialog);
return;
@@ -432,14 +441,14 @@ em_folder_utils_rename_folder (CamelFolder *folder)
{
gchar *prompt, *new_name;
const gchar *p;
- CamelStore *local;
+ CamelStore *local_store;
gboolean done = FALSE;
gsize base_len;
- local = mail_component_peek_local_store (NULL);
+ local_store = e_mail_local_get_store ();
/* don't allow user to rename one of the special local folders */
- if (folder->parent_store == local && emfu_is_special_local_folder (folder->full_name)) {
+ if (folder->parent_store == local_store && emfu_is_special_local_folder (folder->full_name)) {
e_error_run(NULL,
"mail:no-rename-special-folder", folder->full_name, NULL);
return;
@@ -627,6 +636,7 @@ static void
emfu_popup_new_folder_response (EMFolderSelector *emfs, gint response, gpointer data)
{
EMFolderTreeModelStoreInfo *si;
+ GtkTreeModel *model;
const gchar *uri, *path;
CamelException ex;
CamelStore *store;
@@ -650,7 +660,10 @@ emfu_popup_new_folder_response (EMFolderSelector *emfs, gint response, gpointer
return;
}
- if (!(si = em_folder_tree_get_model_storeinfo (emfs->emft, store))) {
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emfs->emft));
+ si = em_folder_tree_model_lookup_store_info (
+ EM_FOLDER_TREE_MODEL (model), store);
+ if (si == NULL) {
camel_object_unref (store);
g_return_if_reached();
}
@@ -686,13 +699,11 @@ void
em_folder_utils_create_folder (CamelFolderInfo *folderinfo, EMFolderTree *emft, GtkWindow *parent)
{
EMFolderTree *folder_tree;
- EMFolderTreeModel *model;
GtkWidget *dialog;
- model = mail_component_peek_tree_model (mail_component_peek ());
- folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
+ folder_tree = (EMFolderTree *) em_folder_tree_new ();
- dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
+ dialog = em_folder_selector_create_new (folder_tree, 0, _("Create Folder"), _("Specify where to create the folder:"));
if (folderinfo != NULL)
em_folder_selector_set_selected ((EMFolderSelector *) dialog, folderinfo->uri);
if (parent) {
@@ -705,6 +716,72 @@ em_folder_utils_create_folder (CamelFolderInfo *folderinfo, EMFolderTree *emft,
gtk_widget_show (dialog);
}
+struct _folder_unsub_t {
+ MailMsg base;
+ gchar *folder_uri;
+};
+
+static gchar *
+emfu_unsubscribe_folder__desc (struct _folder_unsub_t *msg)
+{
+ return g_strdup_printf (
+ _("Unsubscribing from folder \"%s\""), msg->folder_uri);
+}
+
+static void
+emfu_unsubscribe_folder__exec (struct _folder_unsub_t *msg)
+{
+ CamelStore *store;
+ CamelURL *url;
+ const gchar *path = NULL;
+ gint url_flags;
+
+ store = camel_session_get_store (
+ session, msg->folder_uri, &msg->base.ex);
+ if (store == NULL)
+ return;
+
+ url = camel_url_new (msg->folder_uri, NULL);
+ url_flags = CAMEL_SERVICE (store)->provider->url_flags;
+
+ if (url_flags & CAMEL_URL_FRAGMENT_IS_PATH)
+ path = url->fragment;
+ else if (url->path != NULL && *url->path != '\0')
+ path = url->path + 1;
+
+ if (path != NULL)
+ camel_store_unsubscribe_folder (store, path, &msg->base.ex);
+
+ camel_url_free (url);
+}
+
+static void
+emfu_unsubscribe_folder__free (struct _folder_unsub_t *msg)
+{
+ g_free (msg->folder_uri);
+}
+
+static MailMsgInfo unsubscribe_info = {
+ sizeof (struct _folder_unsub_t),
+ (MailMsgDescFunc) emfu_unsubscribe_folder__desc,
+ (MailMsgExecFunc) emfu_unsubscribe_folder__exec,
+ (MailMsgDoneFunc) NULL,
+ (MailMsgFreeFunc) emfu_unsubscribe_folder__free
+};
+
+void
+em_folder_utils_unsubscribe_folder (const gchar *folder_uri)
+{
+ struct _folder_unsub_t *unsub;
+
+ g_return_if_fail (folder_uri != NULL);
+
+ unsub = mail_msg_new (&unsubscribe_info);
+ unsub->folder_uri = g_strdup (folder_uri);
+
+ mail_msg_unordered_push (unsub);
+}
+
const gchar *
em_folder_utils_get_icon_name (guint32 flags)
{
diff --git a/mail/em-folder-utils.h b/mail/em-folder-utils.h
index d0c5e986c6..d0db789b96 100644
--- a/mail/em-folder-utils.h
+++ b/mail/em-folder-utils.h
@@ -24,7 +24,7 @@
#ifndef EM_FOLDER_UTILS_H
#define EM_FOLDER_UTILS_H
-#include <glib.h>
+#include <gtk/gtk.h>
#include <camel/camel-folder.h>
#include <camel/camel-store.h>
#include <mail/em-folder-tree.h>
@@ -41,14 +41,14 @@ gint em_folder_utils_copy_folders (CamelStore *fromstore,
* most rely on the wrong data. */
void em_folder_utils_copy_folder (CamelFolderInfo *folderinfo,
- gint delete);
-
+ gboolean delete);
void em_folder_utils_delete_folder (CamelFolder *folder);
void em_folder_utils_rename_folder (CamelFolder *folder);
-
void em_folder_utils_create_folder (CamelFolderInfo *folderinfo,
- EMFolderTree * emft,
+ EMFolderTree *emft,
GtkWindow *parent);
+void em_folder_utils_unsubscribe_folder
+ (const gchar *folder_uri);
const gchar * em_folder_utils_get_icon_name (guint32 flags);
diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c
index 5923e6ef9c..3f76572f18 100644
--- a/mail/em-folder-view.c
+++ b/mail/em-folder-view.c
@@ -27,6 +27,7 @@
#include <sys/stat.h>
#include <unistd.h>
+#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gdk/gdkkeysyms.h>
@@ -54,13 +55,6 @@
#include <camel/camel-offline-store.h>
#include <camel/camel-vee-store.h>
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <bonobo/bonobo-ui-util.h>
-
#include <gtkhtml/gtkhtml.h>
#include <gtkhtml/gtkhtml-embedded.h>
#include <gtkhtml/gtkhtml-stream.h>
@@ -71,10 +65,8 @@
#include "menus/gal-view-etable.h"
#include "menus/gal-view-factory-etable.h"
#include "menus/gal-view-instance.h"
-#include "menus/gal-view-menus.h"
#include "misc/e-charset-picker.h"
-#include <misc/e-filter-bar.h>
#include <misc/e-spinner.h>
#include "e-util/e-error.h"
@@ -84,6 +76,7 @@
#include "e-util/e-profile-event.h"
#include "e-util/e-util-private.h"
#include "e-util/e-util-labels.h"
+#include "shell/e-shell.h"
#include "filter/filter-rule.h"
@@ -94,109 +87,76 @@
#include "em-folder-browser.h"
#include "em-mailer-prefs.h"
#include "em-folder-browser.h"
-#include "em-message-browser.h"
#include "message-list.h"
#include "em-utils.h"
#include "em-composer-utils.h"
#include "em-menu.h"
#include "em-event.h"
+#include "e-mail-shell-backend.h"
#include "mail-mt.h"
#include "mail-ops.h"
#include "mail-config.h"
#include "mail-autofilter.h"
#include "mail-vfolder.h"
-#include "mail-component.h"
#include "mail-tools.h"
-#include "evolution-shell-component-utils.h" /* Pixmap stuff, sigh */
-
#ifdef HAVE_XFREE
#include <X11/XF86keysym.h>
#endif
-static void emfv_list_message_selected(MessageList *ml, const gchar *uid, EMFolderView *emfv);
-static void emfv_list_built(MessageList *ml, EMFolderView *emfv);
-static gint emfv_list_right_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, EMFolderView *emfv);
-static void emfv_list_double_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, EMFolderView *emfv);
-static gint emfv_list_key_press(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *ev, EMFolderView *emfv);
-static void emfv_list_selection_change(ETree *tree, EMFolderView *emfv);
-
-static void emfv_format_link_clicked(EMFormatHTMLDisplay *efhd, const gchar *uri, EMFolderView *);
-static gint emfv_format_popup_event(EMFormatHTMLDisplay *efhd, GdkEventButton *event, const gchar *uri, CamelMimePart *part, EMFolderView *);
-
-static void emfv_enable_menus(EMFolderView *emfv);
-
-static void emfv_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri);
-static void emfv_set_folder_uri(EMFolderView *emfv, const gchar *uri);
-static void emfv_set_message(EMFolderView *emfv, const gchar *uid, gint nomarkseen);
-static void emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint state);
-
-static void emfv_message_reply(EMFolderView *emfv, gint mode);
-static void vfolder_type_current (EMFolderView *emfv, gint type);
-static void filter_type_current (EMFolderView *emfv, gint type);
-
-static void emfv_setting_setup(EMFolderView *emfv);
-
-static void emfv_on_url_cb(GObject *emitter, const gchar *url, EMFolderView *emfv);
-static void emfv_on_url(EMFolderView *emfv, const gchar *uri, const gchar *nice_uri);
-
-static void emfv_set_seen (EMFolderView *emfv, const gchar *uid);
-static gboolean emfv_on_html_button_released_cb (GtkHTML *html, GdkEventButton *button, EMFolderView *emfv);
-static gboolean emfv_popup_menu (GtkWidget *widget);
-
/* this is added to emfv->enable_map in :init() */
static const EMFolderViewEnable emfv_enable_map[] = {
{ "EditCut", EM_POPUP_SELECT_MANY },
{ "EditCopy", EM_FOLDER_VIEW_SELECT_SELECTION },
{ "EditPaste", EM_POPUP_SELECT_FOLDER },
- { "SelectAllText", EM_POPUP_SELECT_ONE },
+// { "SelectAllText", EM_POPUP_SELECT_ONE },
/* FIXME: should these be single-selection? */
{ "MailNext", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_NEXT_MSG },
- { "MailNextFlagged", EM_POPUP_SELECT_MANY },
- { "MailNextUnread", EM_POPUP_SELECT_MANY },
- { "MailNextThread", EM_POPUP_SELECT_MANY },
+// { "MailNextFlagged", EM_POPUP_SELECT_MANY },
+// { "MailNextUnread", EM_POPUP_SELECT_MANY },
+// { "MailNextThread", EM_POPUP_SELECT_MANY },
{ "MailPrevious", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_PREV_MSG },
- { "MailPreviousFlagged", EM_POPUP_SELECT_MANY },
- { "MailPreviousUnread", EM_POPUP_SELECT_MANY },
+// { "MailPreviousFlagged", EM_POPUP_SELECT_MANY },
+// { "MailPreviousUnread", EM_POPUP_SELECT_MANY },
{ "AddSenderToAddressbook", EM_POPUP_SELECT_ADD_SENDER },
- { "MessageApplyFilters", EM_POPUP_SELECT_MANY },
- { "MessageFilterJunk", EM_POPUP_SELECT_MANY },
- { "MessageCopy", EM_POPUP_SELECT_MANY },
- { "MessageDelete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_DELETE },
- { "MessageDeleteKey", EM_POPUP_SELECT_MANY},
- { "MessageForward", EM_POPUP_SELECT_MANY },
- { "MessageForwardAttached", EM_POPUP_SELECT_MANY },
- { "MessageForwardInline", EM_POPUP_SELECT_ONE },
- { "MessageForwardQuoted", EM_POPUP_SELECT_ONE },
- { "MessageRedirect", EM_POPUP_SELECT_ONE },
- { "MessageMarkAsRead", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_READ },
- { "MessageMarkAsUnRead", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_UNREAD },
- { "MessageMarkAsImportant", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_IMPORTANT },
- { "MessageMarkAsUnimportant", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_UNIMPORTANT },
- { "MessageMarkAsJunk", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_JUNK },
- { "MessageMarkAsNotJunk", EM_POPUP_SELECT_MANY},
+// { "MessageApplyFilters", EM_POPUP_SELECT_MANY },
+// { "MessageFilterJunk", EM_POPUP_SELECT_MANY },
+// { "MessageCopy", EM_POPUP_SELECT_MANY },
+// { "MessageDelete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_DELETE },
+// { "MessageDeleteKey", EM_POPUP_SELECT_MANY},
+// { "MessageForward", EM_POPUP_SELECT_MANY },
+// { "MessageForwardAttached", EM_POPUP_SELECT_MANY },
+// { "MessageForwardInline", EM_POPUP_SELECT_ONE },
+// { "MessageForwardQuoted", EM_POPUP_SELECT_ONE },
+// { "MessageRedirect", EM_POPUP_SELECT_ONE },
+// { "MessageMarkAsRead", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_READ },
+// { "MessageMarkAsUnRead", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_UNREAD },
+// { "MessageMarkAsImportant", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_IMPORTANT },
+// { "MessageMarkAsUnimportant", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_UNIMPORTANT },
+// { "MessageMarkAsJunk", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_JUNK },
+// { "MessageMarkAsNotJunk", EM_POPUP_SELECT_MANY},
{ "MessageFollowUpFlag", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_FLAG_FOLLOWUP },
{ "MessageFollowUpComplete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_FLAG_COMPLETED },
{ "MessageFollowUpClear", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_FLAG_CLEAR },
- { "MessageMove", EM_POPUP_SELECT_MANY },
- { "MessageOpen", EM_POPUP_SELECT_MANY },
- { "MessageReplyAll", EM_POPUP_SELECT_ONE },
- { "MessageReplyList", EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST },
- { "MessageReplySender", EM_POPUP_SELECT_ONE },
- { "MessageEdit", EM_POPUP_SELECT_ONE },
- { "MessageSaveAs", EM_POPUP_SELECT_MANY },
+// { "MessageMove", EM_POPUP_SELECT_MANY },
+// { "MessageOpen", EM_POPUP_SELECT_MANY },
+// { "MessageReplyAll", EM_POPUP_SELECT_ONE },
+// { "MessageReplyList", EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST },
+// { "MessageReplySender", EM_POPUP_SELECT_ONE },
+// { "MessageEdit", EM_POPUP_SELECT_ONE },
+// { "MessageSaveAs", EM_POPUP_SELECT_MANY },
{ "MessageSearch", EM_POPUP_SELECT_ONE| EM_FOLDER_VIEW_PREVIEW_PRESENT },
- { "MessageUndelete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_UNDELETE },
- { "PrintMessage", EM_POPUP_SELECT_ONE },
- { "PrintPreviewMessage", EM_POPUP_SELECT_ONE },
+// { "MessageUndelete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_UNDELETE },
+// { "PrintMessage", EM_POPUP_SELECT_ONE },
+// { "PrintPreviewMessage", EM_POPUP_SELECT_ONE },
- { "TextZoomIn", EM_POPUP_SELECT_ONE },
- { "TextZoomOut", EM_POPUP_SELECT_ONE },
- { "TextZoomReset", EM_POPUP_SELECT_ONE },
+// { "TextZoomIn", EM_POPUP_SELECT_ONE },
+// { "TextZoomOut", EM_POPUP_SELECT_ONE },
+// { "TextZoomReset", EM_POPUP_SELECT_ONE },
{ "ToolsFilterMailingList", EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST},
{ "ToolsFilterRecipient", EM_POPUP_SELECT_ONE },
@@ -207,11 +167,11 @@ static const EMFolderViewEnable emfv_enable_map[] = {
{ "ToolsVFolderSender", EM_POPUP_SELECT_ONE },
{ "ToolsVFolderSubject", EM_POPUP_SELECT_ONE },
- { "ViewLoadImages", EM_POPUP_SELECT_ONE },
- { "ViewSource", EM_POPUP_SELECT_ONE },
+// { "ViewLoadImages", EM_POPUP_SELECT_ONE },
+// { "ViewSource", EM_POPUP_SELECT_ONE },
- /* always enabled */
- { "MailStop", 0 },
+// /* always enabled */
+// { "MailStop", 0 },
{ NULL },
};
@@ -225,9 +185,6 @@ struct _EMFolderViewPrivate {
GtkWidget *invisible;
gchar *selection_uri;
- GalViewInstance *view_instance;
- GalViewMenus *view_menus;
-
gchar *selected_uid;
};
@@ -244,147 +201,55 @@ extern CamelSession *session;
static guint signals[LAST_SIGNAL];
-static void emfv_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint time_stamp, EMFolderView *emfv);
-static void emfv_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, EMFolderView *emfv);
-
-#ifdef ENABLE_PROFILING
-static void
-emfv_format_complete(EMFormat *emf, EMFolderView *emfv)
-{
- e_profile_event_emit("goto.done", emf->uid?emf->uid:"", 0);
-}
-#endif
-
static void
emfv_init(GObject *o)
{
EMFolderView *emfv = (EMFolderView *)o;
struct _EMFolderViewPrivate *p;
- gtk_box_set_homogeneous (GTK_BOX (emfv), FALSE);
-
- p = emfv->priv = g_malloc0(sizeof(struct _EMFolderViewPrivate));
-
- emfv->statusbar_active = TRUE;
- emfv->list_active = FALSE;
-
- emfv->ui_files = g_slist_append(NULL,
- g_build_filename (EVOLUTION_UIDIR,
- "evolution-mail-message.xml",
- NULL));
-
- emfv->ui_app_name = "evolution-mail";
+// gtk_box_set_homogeneous (GTK_BOX (emfv), FALSE);
+//
+// p = emfv->priv = g_malloc0(sizeof(struct _EMFolderViewPrivate));
+//
+// emfv->statusbar_active = TRUE;
+// emfv->list_active = FALSE;
+//
+// emfv->ui_files = g_slist_append(NULL,
+// g_build_filename (EVOLUTION_UIDIR,
+// "evolution-mail-message.xml",
+// NULL));
+//
+// emfv->ui_app_name = "evolution-mail";
emfv->enable_map = g_slist_prepend(NULL, (gpointer)emfv_enable_map);
- emfv->list = (MessageList *)message_list_new();
- g_signal_connect(emfv->list, "message_selected", G_CALLBACK(emfv_list_message_selected), emfv);
- g_signal_connect(emfv->list, "message_list_built", G_CALLBACK(emfv_list_built), emfv);
-
- /* FIXME: should this hang off message-list instead? */
- g_signal_connect(emfv->list->tree, "right_click", G_CALLBACK(emfv_list_right_click), emfv);
- g_signal_connect(emfv->list->tree, "double_click", G_CALLBACK(emfv_list_double_click), emfv);
- g_signal_connect(emfv->list->tree, "key_press", G_CALLBACK(emfv_list_key_press), emfv);
- g_signal_connect(emfv->list->tree, "selection_change", G_CALLBACK(emfv_list_selection_change), emfv);
-
- emfv->preview = (EMFormatHTMLDisplay *)em_format_html_display_new();
- /* FIXME: set_session should NOT be called here. Should it be a constructor attribute? */
- em_format_set_session ((EMFormat *) emfv->preview, session);
- g_signal_connect(emfv->preview, "link_clicked", G_CALLBACK(emfv_format_link_clicked), emfv);
+// emfv->list = (MessageList *)message_list_new();
+// g_signal_connect(emfv->list, "message_selected", G_CALLBACK(emfv_list_message_selected), emfv);
+// g_signal_connect(emfv->list, "message_list_built", G_CALLBACK(emfv_list_built), emfv);
+//
+// /* FIXME: should this hang off message-list instead? */
+// g_signal_connect(emfv->list->tree, "right_click", G_CALLBACK(emfv_list_right_click), emfv);
+// g_signal_connect(emfv->list->tree, "double_click", G_CALLBACK(emfv_list_double_click), emfv);
+// g_signal_connect(emfv->list->tree, "key_press", G_CALLBACK(emfv_list_key_press), emfv);
+// g_signal_connect(emfv->list->tree, "selection_change", G_CALLBACK(emfv_list_selection_change), emfv);
+//
+// emfv->preview = (EMFormatHTMLDisplay *)em_format_html_display_new();
+// /* FIXME: set_session should NOT be called here. Should it be a constructor attribute? */
+// em_format_set_session ((EMFormat *) emfv->preview, session);
+// g_signal_connect(emfv->preview, "link_clicked", G_CALLBACK(emfv_format_link_clicked), emfv);
g_signal_connect(emfv->preview, "popup_event", G_CALLBACK(emfv_format_popup_event), emfv);
- g_signal_connect (emfv->preview, "on_url", G_CALLBACK (emfv_on_url_cb), emfv);
- g_signal_connect (((EMFormatHTML *)emfv->preview)->html, "button-release-event", G_CALLBACK (emfv_on_html_button_released_cb), emfv);
-#ifdef ENABLE_PROFILING
- g_signal_connect(emfv->preview, "complete", G_CALLBACK (emfv_format_complete), emfv);
-#endif
- p->invisible = gtk_invisible_new();
- g_signal_connect(p->invisible, "selection_get", G_CALLBACK(emfv_selection_get), emfv);
- g_signal_connect(p->invisible, "selection_clear_event", G_CALLBACK(emfv_selection_clear_event), emfv);
- gtk_selection_add_target(p->invisible, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0);
- gtk_selection_add_target(p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1);
+// g_signal_connect (emfv->preview, "on_url", G_CALLBACK (emfv_on_url_cb), emfv);
+// g_signal_connect (((EMFormatHTML *)emfv->preview)->html, "button-release-event", G_CALLBACK (emfv_on_html_button_released_cb), emfv);
+//#ifdef ENABLE_PROFILING
+// g_signal_connect(emfv->preview, "complete", G_CALLBACK (emfv_format_complete), emfv);
+//#endif
+// p->invisible = gtk_invisible_new();
+// g_signal_connect(p->invisible, "selection_get", G_CALLBACK(emfv_selection_get), emfv);
+// g_signal_connect(p->invisible, "selection_clear_event", G_CALLBACK(emfv_selection_clear_event), emfv);
+// gtk_selection_add_target(p->invisible, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0);
+// gtk_selection_add_target(p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1);
emfv->async = mail_async_event_new();
-
- emfv_setting_setup(emfv);
-}
-
-static void
-free_one_ui_file (gpointer data,
- gpointer user_data)
-{
- g_free (data);
-}
-
-static void
-emfv_finalise(GObject *o)
-{
- EMFolderView *emfv = (EMFolderView *)o;
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- g_slist_foreach (emfv->ui_files, free_one_ui_file, NULL);
- g_slist_free(emfv->ui_files);
- g_slist_free(emfv->enable_map);
-
- g_free(p);
-
- ((GObjectClass *)emfv_parent)->finalize(o);
-}
-
-static void
-emfv_destroy (GtkObject *o)
-{
- EMFolderView *emfv = (EMFolderView *) o;
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- p->destroyed = TRUE;
-
- if (emfv->list && emfv->list->seen_id) {
- g_source_remove(emfv->list->seen_id);
- emfv->list->seen_id = 0;
- }
-
- if (p->setting_notify_id) {
- GConfClient *gconf = gconf_client_get_default();
-
- gconf_client_notify_remove(gconf, p->setting_notify_id);
- p->setting_notify_id = 0;
- g_object_unref(gconf);
- }
-
- if (emfv->folder) {
- camel_object_unref(emfv->folder);
- g_free(emfv->folder_uri);
- emfv->folder = NULL;
- emfv->folder_uri = NULL;
- }
-
- if (emfv->async) {
- mail_async_event_destroy(emfv->async);
- emfv->async = NULL;
- }
-
- if (p->invisible) {
- gtk_object_destroy((GtkObject *)p->invisible);
- p->invisible = NULL;
- }
-
- if (p->selected_id != 0) {
- g_source_remove(p->selected_id);
- p->selected_id = 0;
- }
-
- g_free(p->selected_uid);
- p->selected_uid = NULL;
-
- g_free (emfv->displayed_uid);
- emfv->displayed_uid = NULL;
-
- emfv->preview = NULL;
- emfv->list = NULL;
- emfv->preview_active = FALSE;
- emfv->uic = NULL;
-
- ((GtkObjectClass *) emfv_parent)->destroy (o);
}
static void
@@ -403,7 +268,7 @@ emfv_class_init(GObjectClass *klass)
((EMFolderViewClass *)klass)->set_message = emfv_set_message;
((EMFolderViewClass *)klass)->activate = emfv_activate;
- ((EMFolderViewClass *)klass)->on_url = emfv_on_url;
+// ((EMFolderViewClass *)klass)->on_url = emfv_on_url;
signals[EMFV_ON_URL] = g_signal_new ("on-url",
G_OBJECT_CLASS_TYPE (klass),
@@ -433,1080 +298,33 @@ emfv_class_init(GObjectClass *klass)
0);
}
-GType
-em_folder_view_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFolderViewClass),
- NULL, NULL,
- (GClassInitFunc)emfv_class_init,
- NULL, NULL,
- sizeof(EMFolderView), 0,
- (GInstanceInitFunc)emfv_init
- };
- emfv_parent = g_type_class_ref(gtk_vbox_get_type());
- type = g_type_register_static(gtk_vbox_get_type(), "EMFolderView", &info, 0);
- }
-
- return type;
-}
-
-GtkWidget *em_folder_view_new(void)
-{
- EMFolderView *emfv = g_object_new(em_folder_view_get_type(), NULL);
-
- return (GtkWidget *)emfv;
-}
-
-/* flag all selected messages. Return number flagged */
-/* FIXME: Should this be part of message-list instead? */
-gint
-em_folder_view_mark_selected(EMFolderView *emfv, guint32 mask, guint32 set)
-{
- GPtrArray *uids;
- gint i;
-
- if (emfv->folder == NULL)
- return 0;
-
- uids = message_list_get_selected(emfv->list);
- if (!CAMEL_IS_VEE_FOLDER(emfv->folder))
- camel_folder_freeze(emfv->folder);
-
- for (i=0; i<uids->len; i++)
- camel_folder_set_message_flags(emfv->folder, uids->pdata[i], mask, set);
-
- message_list_free_uids(emfv->list, uids);
- if (!CAMEL_IS_VEE_FOLDER(emfv->folder))
- camel_folder_thaw(emfv->folder);
-
- return i;
-}
-
-/* should this be elsewhere/take a uid list? */
-gint
-em_folder_view_open_selected(EMFolderView *emfv)
-{
- GPtrArray *uids, *views;
- gint i = 0;
-
- uids = message_list_get_selected(emfv->list);
-
- if (uids->len >= 10) {
- gchar *num = g_strdup_printf("%d", uids->len);
- gint doit;
-
- doit = em_utils_prompt_user((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emfv),
- "/apps/evolution/mail/prompts/open_many",
- "mail:ask-open-many", num, NULL);
- g_free(num);
- if (!doit) {
- message_list_free_uids(emfv->list, uids);
- return 0;
- }
- }
-
- if (em_utils_folder_is_drafts(emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_templates(emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_outbox(emfv->folder, emfv->folder_uri)) {
- em_utils_edit_messages(emfv->folder, uids, TRUE);
- return uids->len;
- }
-
- /* for vfolders we need to edit the *original*, not the vfolder copy */
- views = g_ptr_array_new();
- for (i=0;i<uids->len;i++) {
- if (camel_object_is((CamelObject *)emfv->folder, camel_vee_folder_get_type())) {
- CamelVeeMessageInfo *vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(emfv->folder, uids->pdata[i]);
-
- if (vinfo) {
- gchar *uid;
- /* TODO: get_location shouldn't strdup the uid */
- CamelFolder *f = camel_vee_folder_get_location((CamelVeeFolder *)emfv->folder, vinfo, &uid);
- gchar *uri = mail_tools_folder_to_url(f);
-
- if (em_utils_folder_is_drafts(f, uri) || em_utils_folder_is_outbox(f, uri)) {
- GPtrArray *edits = g_ptr_array_new();
-
- g_ptr_array_add(edits, uid);
- em_utils_edit_messages(f, edits, TRUE);
- } else {
- g_free(uid);
- g_ptr_array_add(views, g_strdup(uids->pdata[i]));
- }
- g_free(uri);
- }
- } else {
- g_ptr_array_add(views, g_strdup(uids->pdata[i]));
- }
- }
-
- /* TODO: have an em_utils_open_messages call? */
- for (i=0; i<views->len; i++) {
- EMMessageBrowser *emmb;
-
- emmb = (EMMessageBrowser *)em_message_browser_window_new();
- message_list_set_threaded(((EMFolderView *)emmb)->list, emfv->list->threaded);
- /* always keep actual message in a list view, even it doesn't belong to the filter anymore */
- message_list_ensure_message (((EMFolderView *)emmb)->list, views->pdata[i]);
- message_list_set_search (((EMFolderView *)emmb)->list, emfv->list->search);
- em_folder_view_set_hide_deleted((EMFolderView *)emmb, emfv->hide_deleted);
- /* FIXME: session needs to be passed easier than this */
- em_format_set_session((EMFormat *)((EMFolderView *)emmb)->preview, ((EMFormat *)emfv->preview)->session);
- em_folder_view_set_folder((EMFolderView *)emmb, emfv->folder, emfv->folder_uri);
- em_folder_view_set_message((EMFolderView *)emmb, views->pdata[i], FALSE);
- gtk_widget_show(emmb->window);
- /* TODO: this loads the message twice (!) */
- em_utils_handle_receipt (emfv->folder, uids->pdata[i], NULL);
- g_free(views->pdata[i]);
- }
- g_ptr_array_free(views, TRUE);
-
- message_list_free_uids(emfv->list, uids);
-
- return i;
-}
-
-/* ******************************************************************************** */
-static void
-emfv_list_display_view(GalViewInstance *instance, GalView *view, EMFolderView *emfv)
-{
- if (GAL_IS_VIEW_ETABLE(view))
- gal_view_etable_attach_tree(GAL_VIEW_ETABLE(view), emfv->list->tree);
-}
-
-static void
-emfv_setup_view_instance(EMFolderView *emfv)
-{
- static GalViewCollection *collection = NULL;
- struct _EMFolderViewPrivate *p = emfv->priv;
- gboolean outgoing, show_wide=FALSE;
- gchar *id;
-
- g_return_if_fail (emfv->folder);
- g_return_if_fail (emfv->folder_uri);
-
- if (collection == NULL) {
- ETableSpecification *spec;
- GalViewFactory *factory;
- const gchar *evolution_dir;
- gchar *dir;
- gchar *galviewsmaildir;
- gchar *etspecfile;
-
- collection = gal_view_collection_new ();
-
- gal_view_collection_set_title (collection, _("Mail"));
-
- evolution_dir = mail_component_peek_base_directory (mail_component_peek ());
- galviewsmaildir = g_build_filename (EVOLUTION_GALVIEWSDIR,
- "mail",
- NULL);
- dir = g_build_filename (evolution_dir, "views", NULL);
- gal_view_collection_set_storage_directories (collection, galviewsmaildir, dir);
- g_free (dir);
- g_free (galviewsmaildir);
-
- spec = e_table_specification_new ();
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "message-list.etspec",
- NULL);
- if (!e_table_specification_load_from_file (spec, etspecfile))
- g_error ("Unable to load ETable specification file "
- "for mail");
- g_free (etspecfile);
-
- factory = gal_view_factory_etable_new (spec);
- g_object_unref (spec);
- gal_view_collection_add_factory (collection, factory);
- g_object_unref (factory);
-
- gal_view_collection_load (collection);
- }
-
- if (p->view_instance) {
- g_object_unref(p->view_instance);
- p->view_instance = NULL;
- }
-
- if (p->view_menus) {
- g_object_unref(p->view_menus);
- p->view_menus = NULL;
- }
-
- /* TODO: should this go through mail-config api? */
- id = mail_config_folder_to_safe_url (emfv->folder);
- p->view_instance = gal_view_instance_new (collection, id);
-
- show_wide = emfv->list_active ? em_folder_browser_get_wide ((EMFolderBrowser *) emfv):FALSE;
- if (show_wide) {
- gchar *safe_id, *filename;
-
- /* Force to use the wide view */
- g_free (p->view_instance->custom_filename);
- g_free (p->view_instance->current_view_filename);
- safe_id = g_strdup (id);
- e_filename_make_safe (safe_id);
- filename = g_strdup_printf ("custom_wide_view-%s.xml", safe_id);
- p->view_instance->custom_filename = g_build_filename (collection->local_dir, filename, NULL);
- g_free (filename);
- filename = g_strdup_printf ("current_wide_view-%s.xml", safe_id);
- p->view_instance->current_view_filename = g_build_filename (collection->local_dir, filename, NULL);
- g_free (filename);
- g_free (safe_id);
- }
- g_free (id);
-
- outgoing = em_utils_folder_is_drafts (emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_sent (emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_outbox (emfv->folder, emfv->folder_uri);
-
- if (outgoing) {
- if (show_wide)
- gal_view_instance_set_default_view(p->view_instance, "Wide_View_Sent");
- else
- gal_view_instance_set_default_view(p->view_instance, "As_Sent_Folder");
- } else if (show_wide) {
- gal_view_instance_set_default_view(p->view_instance, "Wide_View_Normal");
- }
-
- gal_view_instance_load(p->view_instance);
-
- if (!gal_view_instance_exists(p->view_instance)) {
- struct stat st;
- gchar *path;
-
- path = mail_config_folder_to_cachename (emfv->folder, "et-header-");
- if (path && g_stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) {
- ETableSpecification *spec;
- ETableState *state;
- GalView *view;
- gchar *etspecfile;
-
- spec = e_table_specification_new ();
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "message-list.etspec",
- NULL);
- e_table_specification_load_from_file (spec, etspecfile);
- g_free (etspecfile);
- view = gal_view_etable_new (spec, "");
- g_object_unref (spec);
-
- state = e_table_state_new ();
- e_table_state_load_from_file (state, path);
- gal_view_etable_set_state (GAL_VIEW_ETABLE (view), state);
- g_object_unref (state);
-
- gal_view_instance_set_custom_view(p->view_instance, view);
- g_object_unref (view);
- }
-
- g_free (path);
- }
-
- g_signal_connect(p->view_instance, "display_view", G_CALLBACK(emfv_list_display_view), emfv);
- emfv_list_display_view(p->view_instance, gal_view_instance_get_current_view(p->view_instance), emfv);
-
- if (emfv->list_active && emfv->uic) {
- p->view_menus = gal_view_menus_new(p->view_instance);
- gal_view_menus_apply(p->view_menus, emfv->uic, NULL);
- }
-}
-
-void em_folder_view_setup_view_instance (EMFolderView *emfv)
-{
- emfv_setup_view_instance (emfv);
-}
-
-/* ********************************************************************** */
-
-static void
-emfv_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
-{
- gint isout = (folder && uri
- && (em_utils_folder_is_drafts(folder, uri)
- || em_utils_folder_is_sent(folder, uri)
- || em_utils_folder_is_outbox(folder, uri)));
-
- if (folder == emfv->folder)
- return;
-
- if (emfv->priv->selected_id)
- g_source_remove(emfv->priv->selected_id);
-
- if (emfv->preview)
- em_format_format ((EMFormat *) emfv->preview, NULL, NULL, NULL);
-
- message_list_set_folder(emfv->list, folder, uri, isout);
- g_free(emfv->folder_uri);
- emfv->folder_uri = uri ? g_strdup(uri):NULL;
-
- if (emfv->folder) {
- emfv->hide_deleted = emfv->list->hidedeleted; /* <- a bit nasty but makes it track the display better */
- mail_sync_folder (emfv->folder, NULL, NULL);
- camel_object_unref(emfv->folder);
- }
-
- emfv->folder = folder;
- if (folder) {
- /* We need to set this up to get the right view options for the message-list,
- * even if we're not showing it */
- emfv_setup_view_instance(emfv);
- camel_object_ref(folder);
- }
-
- emfv_enable_menus(emfv);
-
- /* TODO: should probably be called after all processing, not just this class's impl */
- g_signal_emit(emfv, signals[EMFV_LOADED], 0);
-}
-
-static void
-emfv_got_folder(gchar *uri, CamelFolder *folder, gpointer data)
-{
- EMFolderView *emfv = data;
-
- em_folder_view_set_folder(emfv, folder, uri);
-}
-
-static void
-emfv_set_folder_uri(EMFolderView *emfv, const gchar *uri)
-{
- mail_get_folder(uri, 0, emfv_got_folder, emfv, mail_msg_fast_ordered_push);
-}
-
-static void
-emfv_set_message(EMFolderView *emfv, const gchar *uid, gint nomarkseen)
-{
- e_profile_event_emit("goto.uid", uid?uid:"<none>", 0);
-
- /* This could possible race with other set messages, but likelyhood is small */
- emfv->priv->nomarkseen = nomarkseen;
- message_list_select_uid(emfv->list, uid);
- /* force an update, since we may not get an updated event if we select the same uid */
- emfv_list_message_selected(emfv->list, uid, emfv);
-}
-
-/* ********************************************************************** */
-
-static void
-emfv_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint time_stamp, EMFolderView *emfv)
-{
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- if (p->selection_uri == NULL)
- return;
-
- gtk_selection_data_set(data, data->target, 8, (guchar *)p->selection_uri, strlen(p->selection_uri));
-}
-
-static void
-emfv_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, EMFolderView *emfv)
-{
-#if 0 /* do i care? */
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- g_free(p->selection_uri);
- p->selection_uri = NULL;
-#endif
-}
+//static void
+//emfv_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint time_stamp, EMFolderView *emfv)
+//{
+// struct _EMFolderViewPrivate *p = emfv->priv;
+//
+// if (p->selection_uri == NULL)
+// return;
+//
+// gtk_selection_data_set(data, data->target, 8, (guchar *)p->selection_uri, strlen(p->selection_uri));
+//}
+
+//static void
+//emfv_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, EMFolderView *emfv)
+//{
+//#if 0 /* do i care? */
+// struct _EMFolderViewPrivate *p = emfv->priv;
+//
+// g_free(p->selection_uri);
+// p->selection_uri = NULL;
+//#endif
+//}
/* ********************************************************************** */
/* Popup menu
In many cases these are the functions called by the bonobo callbacks too */
-static void
-emfv_popup_open(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_open_selected(emfv);
-}
-
-static void
-emfv_popup_edit (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail((GtkWidget *)emfv))
- return;
-
- uids = message_list_get_selected(emfv->list);
- em_utils_edit_messages (emfv->folder, uids, FALSE);
-}
-
-static void
-emfv_popup_saveas(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- uids = message_list_get_selected(emfv->list);
- em_utils_save_messages((GtkWidget *)emfv, emfv->folder, uids);
-}
-
-static void
-emfv_view_load_images(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_load_http((EMFormatHTML *)emfv->preview);
-}
-
-static void
-emfv_popup_print(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_print(emfv, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-}
-
-static void
-emfv_popup_copy_text(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- gtk_html_copy (((EMFormatHTML *)emfv->preview)->html);
-}
-
-static void
-emfv_popup_source(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- EMMessageBrowser *emmb;
- GPtrArray *uids;
-
- uids = message_list_get_selected(emfv->list);
-
- emmb = (EMMessageBrowser *)em_message_browser_window_new();
- em_format_set_session((EMFormat *)((EMFolderView *)emmb)->preview, ((EMFormat *)emfv->preview)->session);
- message_list_ensure_message (((EMFolderView *)emmb)->list, uids->pdata[0]);
- em_folder_view_set_folder((EMFolderView *)emmb, emfv->folder, emfv->folder_uri);
- em_format_set_mode((EMFormat *)((EMFolderView *)emmb)->preview, EM_FORMAT_SOURCE);
- em_folder_view_set_message((EMFolderView *)emmb, uids->pdata[0], FALSE);
- gtk_widget_show(emmb->window);
-
- message_list_free_uids(emfv->list, uids);
-}
-
-static void
-emfv_mail_compose(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (!em_utils_check_user_can_send_mail((GtkWidget *)emfv))
- return;
-
- em_utils_compose_new_message(emfv->folder_uri);
-}
-
-static void
-emfv_popup_reply_sender(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- emfv_message_reply(emfv, REPLY_MODE_SENDER);
-}
-
-static void
-emfv_popup_reply_list(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- emfv_message_reply(emfv, REPLY_MODE_LIST);
-}
-
-static void
-emfv_popup_reply_all(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- emfv_message_reply(emfv, REPLY_MODE_ALL);
-}
-
-static void
-emfv_popup_forward(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail((GtkWidget *)emfv))
- return;
-
- uids = message_list_get_selected(emfv->list);
- em_utils_forward_messages (emfv->folder, uids, emfv->folder_uri);
-}
-
-static void
-emfv_popup_flag_followup(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
-
- em_utils_flag_for_followup((GtkWidget *)emfv, emfv->folder, uids);
-}
-
-static void
-emfv_popup_flag_completed(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- uids = message_list_get_selected(emfv->list);
- em_utils_flag_for_followup_completed((GtkWidget *)emfv, emfv->folder, uids);
-
- if (emfv->preview)
- em_format_redraw (EM_FORMAT (emfv->preview));
-}
-
-static void
-emfv_popup_flag_clear(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
-
- em_utils_flag_for_followup_clear((GtkWidget *)emfv, emfv->folder, uids);
-
- if (emfv->preview)
- em_format_redraw (EM_FORMAT (emfv->preview));
-}
-
-static void
-emfv_popup_mark_read(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
-}
-
-static void
-emfv_popup_mark_unread(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, 0);
-
- if (emfv->list->seen_id) {
- g_source_remove(emfv->list->seen_id);
- emfv->list->seen_id = 0;
- }
-}
-
-static void
-emfv_popup_mark_important(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_FLAGGED);
-}
-
-static void
-emfv_popup_mark_unimportant(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_FLAGGED, 0);
-}
-
-static void
-emfv_select_next_message (EMFolderView *emfv, gint count, gboolean always_can_previous)
-{
- if (emfv && count == 1) {
- if (!message_list_select (emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0) && (emfv->hide_deleted || always_can_previous))
- message_list_select (emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
- }
-}
-
-static void
-emfv_popup_mark_junk (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- gint count;
-
- count = em_folder_view_mark_selected(emfv,
- CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN,
- CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN);
-
- emfv_select_next_message (emfv, count, TRUE);
-}
-
-static void
-emfv_popup_mark_nojunk (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- gint count;
-
- count = em_folder_view_mark_selected(emfv,
- CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN,
- CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN);
-
- emfv_select_next_message (emfv, count, TRUE);
-}
-
-#define DelInVFolderCheckName "DelInVFolderCheck"
-#define DelInVFolderKey "/apps/evolution/mail/prompts/delete_in_vfolder"
-
-static void
-emfv_delete_msg_response (GtkWidget *dialog, gint response, gpointer data)
-{
- if (response == GTK_RESPONSE_OK) {
- EMFolderView *emfv = data;
- gint count;
- GPtrArray *uids;
-
- if (dialog) {
- GList *children, *l;
- GtkWidget *check = NULL;
-
- children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox));
- for (l = children; l; l = l->next) {
- if (GTK_IS_ALIGNMENT (l->data)) {
- check = gtk_bin_get_child (GTK_BIN (l->data));
-
- if (check && GTK_IS_CHECK_BUTTON (check) &&
- !strcmp (gtk_widget_get_name (check), DelInVFolderCheckName))
- break;
-
- check = NULL;
- }
- }
-
- if (check) {
- GConfClient *gconf = gconf_client_get_default ();
- gconf_client_set_bool (gconf, DelInVFolderKey, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)), NULL);
- g_object_unref (gconf);
- }
-
- g_list_free (children);
- }
-
- uids = message_list_get_selected(emfv->list);
- if (!CAMEL_IS_VEE_FOLDER(emfv->folder))
- camel_folder_freeze(emfv->folder);
-
- for (count=0; count < uids->len; count++) {
- if (camel_folder_get_message_flags (emfv->folder, uids->pdata[count]) & CAMEL_MESSAGE_USER_NOT_DELETABLE) {
- if (emfv->preview_active) {
- GtkHTMLStream *hstream = gtk_html_begin(((EMFormatHTML *)emfv->preview)->html);
-
- gtk_html_stream_printf(hstream, "<h2>%s</h2><p>%s</p>",
- _("Mail Deletion Failed"),
- _("You do not have sufficient permissions to delete this mail."));
- gtk_html_stream_close(hstream, GTK_HTML_STREAM_OK);
- } else {
- GtkWidget *w = e_error_new (NULL, "mail:no-delete-permission", "", NULL);
- em_utils_show_error_silent (w);
- }
-
- count = -1;
- break;
- } else
- camel_folder_set_message_flags(emfv->folder, uids->pdata[count], CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED );
- }
-
- message_list_free_uids(emfv->list, uids);
- if (!CAMEL_IS_VEE_FOLDER(emfv->folder))
- camel_folder_thaw(emfv->folder);
-
- emfv_select_next_message (emfv, count, FALSE);
- }
-
- if (dialog)
- gtk_widget_destroy (dialog);
-}
-
-static void
-emfv_popup_delete (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GConfClient *gconf = gconf_client_get_default ();
-
- if (emfv->folder && emfv->folder->parent_store && CAMEL_IS_VEE_STORE (emfv->folder->parent_store)
- && !gconf_client_get_bool (gconf, DelInVFolderKey, NULL)) {
- GtkWidget *dialog, *checkbox, *align;
-
- dialog = e_error_new (NULL, "mail:ask-delete-vfolder-msg", emfv->folder->full_name, NULL);
- g_signal_connect (dialog, "response", G_CALLBACK (emfv_delete_msg_response), emfv);
- checkbox = gtk_check_button_new_with_label (_("Do not ask me again."));
- gtk_widget_set_name (checkbox, DelInVFolderCheckName);
- align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
- gtk_container_add (GTK_CONTAINER (align), checkbox);
- gtk_widget_show (checkbox);
- gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox), align, TRUE, TRUE, 6);
- gtk_widget_show (align);
- gtk_widget_show (dialog);
- } else {
- emfv_delete_msg_response (NULL, GTK_RESPONSE_OK, emfv);
- }
-
- g_object_unref (gconf);
-}
-#undef DelInVFolderCheckName
-#undef DelInVFolderKey
-
-static void
-emfv_popup_undelete(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_DELETED, 0);
-}
-
-struct _move_data {
- EMFolderView *emfv;
- GPtrArray *uids;
- gint delete;
-};
-
-static gchar *default_xfer_messages_uri = NULL;
-
-static void
-emfv_popup_move_cb(const gchar *uri, gpointer data)
-{
- struct _move_data *d = data;
-
- if (uri) {
- g_free (default_xfer_messages_uri);
- default_xfer_messages_uri = g_strdup (uri);
- mail_transfer_messages(d->emfv->folder, d->uids, d->delete, uri, 0, NULL, NULL);
- } else
- em_utils_uids_free(d->uids);
-
- g_object_unref(d->emfv);
- g_free(d);
-}
-
-static void
-emfv_popup_move(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- struct _move_data *d;
-
- d = g_malloc(sizeof(*d));
- d->emfv = emfv;
- g_object_ref(emfv);
- d->uids = message_list_get_selected(emfv->list);
- d->delete = TRUE;
-
- em_select_folder ((GtkWindow *) emfv, _("Select folder"), _("_Move"), default_xfer_messages_uri, NULL, emfv_popup_move_cb, d);
-}
-
-static void
-emfv_popup_copy(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- struct _move_data *d;
-
- d = g_malloc(sizeof(*d));
- d->emfv = emfv;
- g_object_ref(emfv);
- d->uids = message_list_get_selected(emfv->list);
- d->delete = FALSE;
-
- em_select_folder ((GtkWindow *) emfv, _("Select folder"), _("C_opy"), default_xfer_messages_uri, NULL, emfv_popup_move_cb, d);
-}
-
-static void
-emfv_set_label (EMFolderView *emfv, const gchar *label)
-{
- GPtrArray *uids = message_list_get_selected (emfv->list);
- gint i;
-
- for (i = 0; i < uids->len; i++)
- camel_folder_set_message_user_flag (emfv->folder, uids->pdata[i], label, TRUE);
-
- message_list_free_uids (emfv->list, uids);
-}
-
-static void
-emfv_unset_label (EMFolderView *emfv, const gchar *label)
-{
- GPtrArray *uids = message_list_get_selected (emfv->list);
- gint i;
-
- for (i = 0; i < uids->len; i++) {
- camel_folder_set_message_user_flag (emfv->folder, uids->pdata[i], label, FALSE);
- camel_folder_set_message_user_tag (emfv->folder, uids->pdata[i], "label", NULL);
- }
-
- message_list_free_uids (emfv->list, uids);
-}
-
-static void
-emfv_popup_label_clear(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GSList *l;
- EUtilLabel *label;
-
- for (l = mail_config_get_labels (); l; l = l->next) {
- label = l->data;
- emfv_unset_label(emfv, label->tag);
- }
-}
-
-static void
-emfv_popup_label_set(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
-
- if (pitem->type & E_POPUP_ACTIVE)
- emfv_set_label (emfv, pitem->user_data);
- else
- emfv_unset_label (emfv, pitem->user_data);
-}
-
-static void
-emfv_popup_label_new (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- gchar *tag = e_util_labels_add_with_dlg (NULL, NULL);
-
- if (tag) {
- emfv_set_label (emfv, tag);
- g_free (tag);
- }
-}
-
-static void
-emfv_popup_add_sender(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
- CamelMessageInfo *info;
- const gchar *addr;
-
- if (uids->len == 1
- && (info = camel_folder_get_message_info(emfv->folder, uids->pdata[0])) != NULL
- && (addr = camel_message_info_from(info)) != NULL
- && addr[0] != 0)
- em_utils_add_address((GtkWidget *)emfv, addr);
-
- em_utils_uids_free(uids);
-}
-
-static void
-emfv_popup_apply_filters(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
-
- mail_filter_on_demand(emfv->folder, uids);
-}
-
-static void
-emfv_popup_filter_junk(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
-
- mail_filter_junk(emfv->folder, uids);
-}
-
-/* filter callbacks, this will eventually be a wizard, see
- filter_type_current/vfolder_type_current for implementation */
-
-#define EMFV_POPUP_AUTO_TYPE(autotype, name, type) \
-static void \
-name(EPopup *ep, EPopupItem *item, gpointer data) \
-{ \
- EMFolderView *emfv = data; \
- autotype(emfv, type); \
-}
-
-EMFV_POPUP_AUTO_TYPE(vfolder_type_current, emfv_popup_vfolder_subject, AUTO_SUBJECT)
-EMFV_POPUP_AUTO_TYPE(vfolder_type_current, emfv_popup_vfolder_sender, AUTO_FROM)
-EMFV_POPUP_AUTO_TYPE(vfolder_type_current, emfv_popup_vfolder_recipients, AUTO_TO)
-EMFV_POPUP_AUTO_TYPE(vfolder_type_current, emfv_popup_vfolder_mlist, AUTO_MLIST)
-
-EMFV_POPUP_AUTO_TYPE(filter_type_current, emfv_popup_filter_subject, AUTO_SUBJECT)
-EMFV_POPUP_AUTO_TYPE(filter_type_current, emfv_popup_filter_sender, AUTO_FROM)
-EMFV_POPUP_AUTO_TYPE(filter_type_current, emfv_popup_filter_recipients, AUTO_TO)
-EMFV_POPUP_AUTO_TYPE(filter_type_current, emfv_popup_filter_mlist, AUTO_MLIST)
-
-/* TODO: Move some of these to be 'standard' menu's */
-
-static EPopupItem emfv_popup_items[] = {
- { E_POPUP_ITEM, (gchar *) "00.emfv.00", (gchar *) N_("_Copy"), emfv_popup_copy_text, NULL, (gchar *) "edit-copy", EM_FOLDER_VIEW_SELECT_DISPLAY|EM_FOLDER_VIEW_SELECT_SELECTION },
-
- { E_POPUP_BAR, (gchar *) "10.emfv", NULL, NULL, NULL, NULL },
-
- { E_POPUP_ITEM, (gchar *) "10.emfv.00", (gchar *) N_("_Reply to Sender"), emfv_popup_reply_sender, NULL, (gchar *) "mail-reply-sender", EM_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "10.emfv.01", (gchar *) N_("Reply to _All"), emfv_popup_reply_all, NULL, (gchar *) "mail-reply-all", EM_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "10.emfv.02", (gchar *) N_("_Forward"), emfv_popup_forward, NULL, (gchar *) "mail-forward", EM_POPUP_SELECT_MANY },
-
- { E_POPUP_BAR, (gchar *) "20.emfv", NULL, NULL, NULL, NULL },
- /* EM_POPUP_EDIT was used here. This is changed to EM_POPUP_SELECT_ONE as Edit-as-new-messaeg need not be restricted to Sent-Items folder alone */
- { E_POPUP_ITEM, (gchar *) "20.emfv.00", (gchar *) N_("_Edit as New Message..."), emfv_popup_edit, NULL, NULL, EM_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "20.emfv.01", (gchar *) N_("_Save As..."), emfv_popup_saveas, NULL, (gchar *) "document-save-as", EM_POPUP_SELECT_MANY },
- { E_POPUP_ITEM, (gchar *) "20.emfv.02", (gchar *) N_("_Print..."), emfv_popup_print, NULL, (gchar *) "document-print", EM_POPUP_SELECT_ONE },
-
- { E_POPUP_BAR, (gchar *) "40.emfv", NULL, NULL, NULL, NULL },
- { E_POPUP_ITEM, (gchar *) "40.emfv.00", (gchar *) N_("_Delete"), emfv_popup_delete, NULL, (gchar *) "edit-delete", EM_POPUP_SELECT_DELETE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "40.emfv.01", (gchar *) N_("U_ndelete"), emfv_popup_undelete, NULL, NULL, EM_POPUP_SELECT_UNDELETE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "40.emfv.02", (gchar *) N_("_Move to Folder..."), emfv_popup_move, NULL, (gchar *) "mail-move", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "40.emfv.03", (gchar *) N_("_Copy to Folder..."), emfv_popup_copy, NULL, (gchar *) "mail-copy", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_BAR, (gchar *) "50.emfv", NULL, NULL, NULL, NULL },
- { E_POPUP_ITEM, (gchar *) "50.emfv.00", (gchar *) N_("Mar_k as Read"), emfv_popup_mark_read, NULL, (gchar *) "mail-mark-read", EM_POPUP_SELECT_MARK_READ|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "50.emfv.01", (gchar *) N_("Mark as _Unread"), emfv_popup_mark_unread, NULL, (gchar *) "mail-mark-unread", EM_POPUP_SELECT_MARK_UNREAD|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "50.emfv.02", (gchar *) N_("Mark as _Important"), emfv_popup_mark_important, NULL, (gchar *) "mail-mark-important", EM_POPUP_SELECT_MARK_IMPORTANT|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "50.emfv.03", (gchar *) N_("Mark as Un_important"), emfv_popup_mark_unimportant, NULL, NULL, EM_POPUP_SELECT_MARK_UNIMPORTANT|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "50.emfv.04", (gchar *) N_("Mark as _Junk"), emfv_popup_mark_junk, NULL, (gchar *) "mail-mark-junk", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY|EM_POPUP_SELECT_JUNK },
- { E_POPUP_ITEM, (gchar *) "50.emfv.05", (gchar *) N_("Mark as _Not Junk"), emfv_popup_mark_nojunk, NULL, (gchar *) "mail-mark-notjunk", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY|EM_POPUP_SELECT_NOT_JUNK },
- { E_POPUP_ITEM, (gchar *) "50.emfv.06", (gchar *) N_("Mark for Follo_w Up..."), emfv_popup_flag_followup, NULL, (gchar *) "stock_mail-flag-for-followup", EM_POPUP_SELECT_FLAG_FOLLOWUP|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_SUBMENU, (gchar *) "60.label.00", (gchar *) N_("_Label"), NULL, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "60.label.00/00.label", (gchar *) N_("_None"), emfv_popup_label_clear, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_BAR, (gchar *) "60.label.00/00.label.00", NULL, NULL, NULL, NULL },
- { E_POPUP_BAR, (gchar *) "60.label.00/01.label", NULL, NULL, NULL, NULL },
- { E_POPUP_ITEM, (gchar *) "60.label.00/01.label.00", (gchar *) N_("_New Label"), emfv_popup_label_new, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_BAR, (gchar *) "70.emfv.06", NULL, NULL, NULL, NULL },
-
- { E_POPUP_ITEM, (gchar *) "70.emfv.07", (gchar *) N_("Fla_g Completed"), emfv_popup_flag_completed, NULL, (gchar *) "stock_mail-flag-for-followup-done", EM_POPUP_SELECT_FLAG_COMPLETED|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "70.emfv.08", (gchar *) N_("Cl_ear Flag"), emfv_popup_flag_clear, NULL, NULL, EM_POPUP_SELECT_FLAG_CLEAR|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_BAR, (gchar *) "90.filter", NULL, NULL, NULL, NULL },
- { E_POPUP_SUBMENU, (gchar *) "90.filter.00", (gchar *) N_("Crea_te Rule From Message"), NULL, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- /* Translators: The following strings are used while creating a new search folder, to specify what parameter the search folder would be based on. */
- { E_POPUP_ITEM, (gchar *) "90.filter.00/00.00", (gchar *) N_("Search Folder based on _Subject"), emfv_popup_vfolder_subject, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/00.01", (gchar *) N_("Search Folder based on Se_nder"), emfv_popup_vfolder_sender, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/00.02", (gchar *) N_("Search Folder based on _Recipients"), emfv_popup_vfolder_recipients, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/00.03", (gchar *) N_("Search Folder based on Mailing _List"),
- emfv_popup_vfolder_mlist, NULL, NULL, EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_BAR, (gchar *) "90.filter.00/10", NULL, NULL, NULL, NULL },
- /* Translators: The following strings are used while creating a new message filter, to specify what parameter the filter would be based on. */
- { E_POPUP_ITEM, (gchar *) "90.filter.00/10.00", (gchar *) N_("Filter based on Sub_ject"), emfv_popup_filter_subject, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/10.01", (gchar *) N_("Filter based on Sen_der"), emfv_popup_filter_sender, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/10.02", (gchar *) N_("Filter based on Re_cipients"), emfv_popup_filter_recipients, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/10.03", (gchar *) N_("Filter based on _Mailing List"),
- emfv_popup_filter_mlist, NULL, NULL, EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST|EM_FOLDER_VIEW_SELECT_LISTONLY },
-};
-
-static enum _e_popup_t
-emfv_popup_labels_get_state_for_tag (EMFolderView *emfv, GPtrArray *uids, const gchar *label_tag)
-{
- enum _e_popup_t state = 0;
- gint i;
- gboolean exists = FALSE, not_exists = FALSE;
-
- g_return_val_if_fail (emfv != 0, state);
- g_return_val_if_fail (label_tag != NULL, state);
-
- for (i = 0; i < uids->len && (!exists || !not_exists); i++) {
- if (camel_folder_get_message_user_flag (emfv->folder, uids->pdata[i], label_tag))
- exists = TRUE;
- else {
- const gchar *label = e_util_labels_get_new_tag (camel_folder_get_message_user_tag (emfv->folder, uids->pdata[i], "label"));
-
- /* backward compatibility... */
- if (label && !strcmp (label, label_tag))
- exists = TRUE;
- else
- not_exists = TRUE;
- }
- }
-
- if (exists && not_exists)
- state = E_POPUP_INCONSISTENT;
- else if (exists)
- state = E_POPUP_ACTIVE;
-
- return state;
-}
-
-static void
-emfv_popup_labels_free(EPopup *ep, GSList *l, gpointer data)
-{
- while (l) {
- GSList *n = l->next;
- EPopupItem *item = l->data;
-
- g_free(item->path);
- g_free(item);
-
- g_slist_free_1(l);
- l = n;
- }
-}
-
-static void
-emfv_popup_items_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static void
-emfv_popup(EMFolderView *emfv, GdkEvent *event, gint on_display)
-{
- GSList *menus = NULL, *l, *label_list = NULL;
- GtkMenu *menu;
- EMPopup *emp;
- EMPopupTargetSelect *target;
- gint i;
-
- /** @HookPoint-EMPopup: Message List Context Menu
- * @Id: org.gnome.evolution.mail.folderview.popup.select
- * @Type: EMPopup
- * @Target: EMPopupTargetSelect
- *
- * This is the context menu shown on the message list or over a message.
- */
- emp = em_popup_new("org.gnome.evolution.mail.folderview.popup");
- target = em_folder_view_get_popup_target(emfv, emp, on_display);
-
- for (i=0;i<sizeof(emfv_popup_items)/sizeof(emfv_popup_items[0]);i++)
- menus = g_slist_prepend(menus, &emfv_popup_items[i]);
-
- e_popup_add_items((EPopup *)emp, menus, NULL, emfv_popup_items_free, emfv);
-
- i = 1;
- if (!on_display) {
- GPtrArray *uids = message_list_get_selected (emfv->list);
-
- for (l = mail_config_get_labels (); l; l = l->next) {
- EPopupItem *item;
- EUtilLabel *label = l->data;
- GdkPixmap *pixmap;
- GdkColor colour;
- GdkGC *gc;
-
- item = g_malloc0(sizeof(*item));
- item->type = E_POPUP_TOGGLE | emfv_popup_labels_get_state_for_tag (emfv, uids, label->tag);
- item->path = g_strdup_printf("60.label.00/00.label.%02d", i++);
- item->label = label->name;
- item->activate = emfv_popup_label_set;
- item->user_data = label->tag;
-
- item->visible = EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY;
-
- gdk_color_parse (label->colour, &colour);
- gdk_colormap_alloc_color(gdk_colormap_get_system(), &colour, FALSE, TRUE);
-
- pixmap = gdk_pixmap_new(((GtkWidget *)emfv)->window, 16, 16, -1);
- gc = gdk_gc_new(((GtkWidget *)emfv)->window);
- gdk_gc_set_foreground(gc, &colour);
- gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, 16, 16);
- g_object_unref(gc);
-
- item->image = gtk_image_new_from_pixmap(pixmap, NULL);
- gtk_widget_show(item->image);
-
- label_list = g_slist_prepend(label_list, item);
- }
-
- message_list_free_uids (emfv->list, uids);
- }
-
- e_popup_add_items((EPopup *)emp, label_list, NULL, emfv_popup_labels_free, emfv);
-
- menu = e_popup_create_menu_once((EPopup *)emp, (EPopupTarget *)target, 0);
-
- if (event == NULL || event->type == GDK_KEY_PRESS) {
- /* FIXME: menu pos function */
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, event ? event->key.time : gtk_get_current_event_time());
- } else {
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
- }
-}
-
/* ********************************************************************** */
/* Bonobo menu's */
@@ -1519,57 +337,6 @@ from(BonoboUIComponent *uid, gpointer data, const gchar *path) \
to(NULL, NULL, data); \
}
-EMFV_MAP_CALLBACK(emfv_add_sender_addressbook, emfv_popup_add_sender)
-EMFV_MAP_CALLBACK(emfv_message_apply_filters, emfv_popup_apply_filters)
-EMFV_MAP_CALLBACK(emfv_message_filter_junk, emfv_popup_filter_junk)
-EMFV_MAP_CALLBACK(emfv_message_copy, emfv_popup_copy)
-EMFV_MAP_CALLBACK(emfv_message_move, emfv_popup_move)
-EMFV_MAP_CALLBACK(emfv_message_forward, emfv_popup_forward)
-EMFV_MAP_CALLBACK(emfv_message_reply_all, emfv_popup_reply_all)
-EMFV_MAP_CALLBACK(emfv_message_reply_list, emfv_popup_reply_list)
-EMFV_MAP_CALLBACK(emfv_message_reply_sender, emfv_popup_reply_sender)
-EMFV_MAP_CALLBACK(emfv_message_mark_read, emfv_popup_mark_read)
-EMFV_MAP_CALLBACK(emfv_message_mark_unread, emfv_popup_mark_unread)
-EMFV_MAP_CALLBACK(emfv_message_mark_important, emfv_popup_mark_important)
-EMFV_MAP_CALLBACK(emfv_message_mark_unimportant, emfv_popup_mark_unimportant)
-EMFV_MAP_CALLBACK(emfv_message_mark_junk, emfv_popup_mark_junk)
-EMFV_MAP_CALLBACK(emfv_message_mark_nojunk, emfv_popup_mark_nojunk)
-EMFV_MAP_CALLBACK(emfv_message_delete, emfv_popup_delete)
-EMFV_MAP_CALLBACK(emfv_message_undelete, emfv_popup_undelete)
-EMFV_MAP_CALLBACK(emfv_message_followup_flag, emfv_popup_flag_followup)
-EMFV_MAP_CALLBACK(emfv_message_followup_clear, emfv_popup_flag_clear)
-EMFV_MAP_CALLBACK(emfv_message_followup_completed, emfv_popup_flag_completed)
-EMFV_MAP_CALLBACK(emfv_message_open, emfv_popup_open)
-EMFV_MAP_CALLBACK(emfv_message_edit, emfv_popup_edit)
-EMFV_MAP_CALLBACK(emfv_message_saveas, emfv_popup_saveas)
-EMFV_MAP_CALLBACK(emfv_print_message, emfv_popup_print)
-EMFV_MAP_CALLBACK(emfv_message_source, emfv_popup_source)
-
-static void
-emfv_empty_trash(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- em_utils_empty_trash (gtk_widget_get_toplevel ((GtkWidget *) emfv));
-}
-
-static void
-prepare_offline(gpointer key, gpointer value, gpointer data)
-{
- CamelService *service = key;
-
- if (CAMEL_IS_DISCO_STORE(service)
- || CAMEL_IS_OFFLINE_STORE(service)) {
- mail_store_prepare_offline((CamelStore *)service);
- }
-}
-
-static void
-emfv_prepare_offline(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- mail_component_stores_foreach(mail_component_peek(), prepare_offline, NULL);
-}
-
static void
emfv_edit_cut(BonoboUIComponent *uid, gpointer data, const gchar *path)
{
@@ -1600,646 +367,83 @@ emfv_edit_paste(BonoboUIComponent *uid, gpointer data, const gchar *path)
message_list_paste(emfv->list);
}
-static void
-emfv_select_all_text(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- gboolean selected;
-
- gtk_html_select_all (((EMFormatHTML *)emfv->preview)->html);
- selected = gtk_html_command (((EMFormatHTML *)emfv->preview)->html, "is-selection-active");
- bonobo_ui_component_set_prop(emfv->uic, "/commands/EditCopy", "sensitive", selected?"1":"0", NULL);
-
-}
-
-static void
-emfv_mail_next(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- e_profile_event_emit("goto.next", "", 0);
-
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0);
-}
-
-static void
-emfv_mail_next_flagged(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT|MESSAGE_LIST_SELECT_WRAP, CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED);
-}
-
-static void
-emfv_mail_next_unread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- gtk_widget_grab_focus((GtkWidget *) emfv->list);
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
-}
-
-static void
-emfv_mail_next_thread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select_next_thread(emfv->list);
-}
-
-static void
-emfv_mail_previous(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
-}
-
-static void
-emfv_mail_previous_flagged(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS|MESSAGE_LIST_SELECT_WRAP, CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED);
-}
-
-static void
-emfv_mail_previous_unread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- gtk_widget_grab_focus((GtkWidget *) emfv->list);
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
-}
-
-static void
-emfv_message_forward_attached (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- uids = message_list_get_selected (emfv->list);
- em_utils_forward_attached (emfv->folder, uids, emfv->folder_uri);
-}
-
-static void
-emfv_message_forward_inline (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- uids = message_list_get_selected (emfv->list);
- em_utils_forward_inline (emfv->folder, uids, emfv->folder_uri);
-}
-
-static void
-emfv_message_forward_quoted (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- uids = message_list_get_selected (emfv->list);
- em_utils_forward_quoted (emfv->folder, uids, emfv->folder_uri);
-}
-
-static void
-emfv_message_redirect (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->list->cursor_uid == NULL)
- return;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- em_utils_redirect_message_by_uid (emfv->folder, emfv->list->cursor_uid);
-}
-
-static gboolean
-html_contains_nonwhitespace (const gchar *html, gint len)
-{
- const gchar *p;
- gunichar c = 0;
-
- if (!html || len<=0)
- return FALSE;
-
- p = html;
-
- while (p && p - html < len) {
- c = g_utf8_get_char (p);
- if (!c)
- break;
-
- if (c == '<') {
- /* skip until next '>' */
- while (c = g_utf8_get_char (p), c && c != '>' && p - html < len)
- p = g_utf8_next_char (p);
- if (!c)
- break;
- }else if (c == '&') {
- /* sequence '&nbsp;' is a space */
- if (g_ascii_strncasecmp (p, "&nbsp;", 6) == 0)
- p = p + 5;
- else
- break;
- }else if (!g_unichar_isspace (c)) {
- break;
- }
-
- p = g_utf8_next_char (p);
- }
-
- return p - html < len - 1 && c != 0;
-}
-
-static void
-emfv_message_reply(EMFolderView *emfv, gint mode)
-{
- gchar *html = NULL;
- gint len;
-
- if (emfv->list->cursor_uid == NULL)
- return;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- if (gtk_html_command(((EMFormatHTML *)emfv->preview)->html, "is-selection-active")
- && (html = gtk_html_get_selection_html (((EMFormatHTML *)emfv->preview)->html, &len))
- && len && html[0] && html_contains_nonwhitespace (html, len)) {
- CamelMimeMessage *msg, *src;
- struct _camel_header_raw *header;
-
- src = (CamelMimeMessage *)((EMFormat *)emfv->preview)->message;
- msg = camel_mime_message_new();
-
- /* need to strip content- headers */
- header = ((CamelMimePart *)src)->headers;
- while (header) {
- if (g_ascii_strncasecmp(header->name, "content-", 8) != 0)
- camel_medium_add_header((CamelMedium *)msg, header->name, header->value);
- header = header->next;
- }
- camel_mime_part_set_encoding((CamelMimePart *)msg, CAMEL_TRANSFER_ENCODING_8BIT);
- camel_mime_part_set_content((CamelMimePart *)msg,
- html, len, "text/html");
- em_utils_reply_to_message (emfv->folder, emfv->list->cursor_uid, msg, mode, NULL);
- camel_object_unref(msg);
- } else {
- em_utils_reply_to_message (emfv->folder, emfv->list->cursor_uid, NULL, mode, (EMFormat *)emfv->preview);
- }
-
- g_free (html);
-}
-
-static void
-emfv_message_search(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- em_folder_view_show_search_bar (emfv);
-}
-
-static void
-emfv_print_preview_message(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- em_folder_view_print(emfv, GTK_PRINT_OPERATION_ACTION_PREVIEW);
-}
-
-static void
-emfv_text_zoom_in(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_display_zoom_in(emfv->preview);
-}
-
-static void
-emfv_text_zoom_out(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_display_zoom_out(emfv->preview);
-}
-
-static void
-emfv_text_zoom_reset(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_display_zoom_reset(emfv->preview);
-}
-
-/* ********************************************************************** */
-
-struct _filter_data {
- const gchar *source;
- gchar *uri;
- gint type;
-};
-
-static void
-filter_data_free (struct _filter_data *fdata)
-{
- g_free (fdata->uri);
- g_free (fdata);
-}
-
-static void
-filter_type_got_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, gpointer user_data)
-{
- struct _filter_data *data = user_data;
-
- if (msg)
- filter_gui_add_from_message (msg, data->source, data->type);
-
- filter_data_free (data);
-}
-
-static void
-filter_type_uid (CamelFolder *folder, const gchar *uid, const gchar *source, gint type)
-{
- struct _filter_data *data;
-
- data = g_malloc0 (sizeof (*data));
- data->type = type;
- data->source = source;
-
- mail_get_message (folder, uid, filter_type_got_message, data, mail_msg_unordered_push);
-}
-
-static void
-filter_type_current (EMFolderView *emfv, gint type)
-{
- const gchar *source;
- GPtrArray *uids;
-
- if (em_utils_folder_is_sent (emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_outbox (emfv->folder, emfv->folder_uri))
- source = FILTER_SOURCE_OUTGOING;
- else
- source = FILTER_SOURCE_INCOMING;
-
- uids = message_list_get_selected (emfv->list);
-
- if (uids->len == 1)
- filter_type_uid (emfv->folder, (gchar *) uids->pdata[0], source, type);
-
- em_utils_uids_free (uids);
-}
-
-EMFV_MAP_CALLBACK(emfv_tools_filter_subject, emfv_popup_filter_subject)
-EMFV_MAP_CALLBACK(emfv_tools_filter_sender, emfv_popup_filter_sender)
-EMFV_MAP_CALLBACK(emfv_tools_filter_recipient, emfv_popup_filter_recipients)
-EMFV_MAP_CALLBACK(emfv_tools_filter_mlist, emfv_popup_filter_mlist)
-
-static void
-vfolder_type_got_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, gpointer user_data)
-{
- struct _filter_data *data = user_data;
-
- if (msg)
- vfolder_gui_add_from_message (msg, data->type, data->uri);
-
- filter_data_free (data);
-}
-
-static void
-emp_uri_popup_vfolder_sender(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
- CamelURL *url;
- CamelInternetAddress *addr;
-
- url = camel_url_new(t->uri, NULL);
- if (url == NULL) {
- g_warning("cannot parse url '%s'", t->uri);
- return;
- }
-
- if (url->path && url->path[0]) {
- /* ensures vfolder is running */
- vfolder_load_storage ();
-
- addr = camel_internet_address_new ();
- camel_address_decode (CAMEL_ADDRESS (addr), url->path);
- vfolder_gui_add_from_address (addr, AUTO_FROM, emfv->folder_uri);
- camel_object_unref (addr);
- }
-
- camel_url_free(url);
-
-}
-
-static void
-emp_uri_popup_vfolder_recipient(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
- CamelURL *url;
- CamelInternetAddress *addr;
-
- url = camel_url_new(t->uri, NULL);
- if (url == NULL) {
- g_warning("cannot parse url '%s'", t->uri);
- return;
- }
-
- if (url->path && url->path[0]) {
- /* ensures vfolder is running */
- vfolder_load_storage ();
-
- addr = camel_internet_address_new ();
- camel_address_decode (CAMEL_ADDRESS (addr), url->path);
- vfolder_gui_add_from_address (addr, AUTO_TO, emfv->folder_uri);
- camel_object_unref (addr);
- }
-
- camel_url_free(url);
-}
-
-static void
-vfolder_type_uid (CamelFolder *folder, const gchar *uid, const gchar *uri, gint type)
-{
- struct _filter_data *data;
-
- data = g_malloc0 (sizeof (*data));
- data->type = type;
- data->uri = g_strdup (uri);
-
- mail_get_message (folder, uid, vfolder_type_got_message, data, mail_msg_unordered_push);
-}
-
-static void
-vfolder_type_current (EMFolderView *emfv, gint type)
-{
- GPtrArray *uids;
-
- uids = message_list_get_selected (emfv->list);
-
- if (uids->len == 1) {
- /* ensures vfolder is running */
- vfolder_load_storage ();
-
- vfolder_type_uid (emfv->folder, (gchar *) uids->pdata[0], emfv->folder_uri, type);
- }
-
- em_utils_uids_free (uids);
-}
-
-EMFV_MAP_CALLBACK(emfv_tools_vfolder_subject, emfv_popup_vfolder_subject)
-EMFV_MAP_CALLBACK(emfv_tools_vfolder_sender, emfv_popup_vfolder_sender)
-EMFV_MAP_CALLBACK(emfv_tools_vfolder_recipient, emfv_popup_vfolder_recipients)
-EMFV_MAP_CALLBACK(emfv_tools_vfolder_mlist, emfv_popup_vfolder_mlist)
+//static void
+//emp_uri_popup_vfolder_sender(EPopup *ep, EPopupItem *pitem, gpointer data)
+//{
+// EMFolderView *emfv = data;
+// EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
+// CamelURL *url;
+// CamelInternetAddress *addr;
+//
+// url = camel_url_new(t->uri, NULL);
+// if (url == NULL) {
+// g_warning("cannot parse url '%s'", t->uri);
+// return;
+// }
+//
+// if (url->path && url->path[0]) {
+// /* ensures vfolder is running */
+// vfolder_load_storage ();
+//
+// addr = camel_internet_address_new ();
+// camel_address_decode (CAMEL_ADDRESS (addr), url->path);
+// vfolder_gui_add_from_address (addr, AUTO_FROM, emfv->folder_uri);
+// camel_object_unref (addr);
+// }
+//
+// camel_url_free(url);
+//
+//}
+
+//static void
+//emp_uri_popup_vfolder_recipient(EPopup *ep, EPopupItem *pitem, gpointer data)
+//{
+// EMFolderView *emfv = data;
+// EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
+// CamelURL *url;
+// CamelInternetAddress *addr;
+//
+// url = camel_url_new(t->uri, NULL);
+// if (url == NULL) {
+// g_warning("cannot parse url '%s'", t->uri);
+// return;
+// }
+//
+// if (url->path && url->path[0]) {
+// /* ensures vfolder is running */
+// vfolder_load_storage ();
+//
+// addr = camel_internet_address_new ();
+// camel_address_decode (CAMEL_ADDRESS (addr), url->path);
+// vfolder_gui_add_from_address (addr, AUTO_TO, emfv->folder_uri);
+// camel_object_unref (addr);
+// }
+//
+// camel_url_free(url);
+//}
/* ********************************************************************** */
static BonoboUIVerb emfv_message_verbs[] = {
- BONOBO_UI_UNSAFE_VERB ("EmptyTrash", emfv_empty_trash),
- BONOBO_UI_UNSAFE_VERB ("PrepareForOffline", emfv_prepare_offline),
BONOBO_UI_UNSAFE_VERB ("EditCut", emfv_edit_cut),
BONOBO_UI_UNSAFE_VERB ("EditCopy", emfv_edit_copy),
BONOBO_UI_UNSAFE_VERB ("EditPaste", emfv_edit_paste),
- BONOBO_UI_UNSAFE_VERB ("SelectAllText", emfv_select_all_text),
-
- BONOBO_UI_UNSAFE_VERB ("MailNext", emfv_mail_next),
- BONOBO_UI_UNSAFE_VERB ("MailNextFlagged", emfv_mail_next_flagged),
- BONOBO_UI_UNSAFE_VERB ("MailNextUnread", emfv_mail_next_unread),
- BONOBO_UI_UNSAFE_VERB ("MailNextThread", emfv_mail_next_thread),
- BONOBO_UI_UNSAFE_VERB ("MailPrevious", emfv_mail_previous),
- BONOBO_UI_UNSAFE_VERB ("MailPreviousFlagged", emfv_mail_previous_flagged),
- BONOBO_UI_UNSAFE_VERB ("MailPreviousUnread", emfv_mail_previous_unread),
-
- BONOBO_UI_UNSAFE_VERB ("AddSenderToAddressbook", emfv_add_sender_addressbook),
-
- BONOBO_UI_UNSAFE_VERB ("MessageApplyFilters", emfv_message_apply_filters),
- BONOBO_UI_UNSAFE_VERB ("MessageFilterJunk", emfv_message_filter_junk),
- BONOBO_UI_UNSAFE_VERB ("MessageCopy", emfv_message_copy),
- BONOBO_UI_UNSAFE_VERB ("MessageDelete", emfv_message_delete),
- BONOBO_UI_UNSAFE_VERB ("MessageDeleteKey", emfv_message_delete),
- BONOBO_UI_UNSAFE_VERB ("MessageForward", emfv_message_forward),
- BONOBO_UI_UNSAFE_VERB ("MessageForwardAttached", emfv_message_forward_attached),
- BONOBO_UI_UNSAFE_VERB ("MessageForwardInline", emfv_message_forward_inline),
- BONOBO_UI_UNSAFE_VERB ("MessageForwardQuoted", emfv_message_forward_quoted),
- BONOBO_UI_UNSAFE_VERB ("MessageRedirect", emfv_message_redirect),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsRead", emfv_message_mark_read),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsUnRead", emfv_message_mark_unread),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsImportant", emfv_message_mark_important),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsUnimportant", emfv_message_mark_unimportant),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsJunk", emfv_message_mark_junk),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsNotJunk", emfv_message_mark_nojunk),
- BONOBO_UI_UNSAFE_VERB ("MessageFollowUpFlag", emfv_message_followup_flag),
- BONOBO_UI_UNSAFE_VERB ("MessageFollowUpComplete", emfv_message_followup_completed),
- BONOBO_UI_UNSAFE_VERB ("MessageFollowUpClear", emfv_message_followup_clear),
- BONOBO_UI_UNSAFE_VERB ("MessageMove", emfv_message_move),
- BONOBO_UI_UNSAFE_VERB ("MessageOpen", emfv_message_open),
- BONOBO_UI_UNSAFE_VERB ("MessageReplyAll", emfv_message_reply_all),
- BONOBO_UI_UNSAFE_VERB ("MessageReplyList", emfv_message_reply_list),
- BONOBO_UI_UNSAFE_VERB ("MessageReplySender", emfv_message_reply_sender),
- BONOBO_UI_UNSAFE_VERB ("MessageEdit", emfv_message_edit),
- BONOBO_UI_UNSAFE_VERB ("MessageSaveAs", emfv_message_saveas),
- BONOBO_UI_UNSAFE_VERB ("MessageSearch", emfv_message_search),
- BONOBO_UI_UNSAFE_VERB ("MessageUndelete", emfv_message_undelete),
-
- BONOBO_UI_UNSAFE_VERB ("PrintMessage", emfv_print_message),
- BONOBO_UI_UNSAFE_VERB ("PrintPreviewMessage", emfv_print_preview_message),
-
- BONOBO_UI_UNSAFE_VERB ("TextZoomIn", emfv_text_zoom_in),
- BONOBO_UI_UNSAFE_VERB ("TextZoomOut", emfv_text_zoom_out),
- BONOBO_UI_UNSAFE_VERB ("TextZoomReset", emfv_text_zoom_reset),
-
- BONOBO_UI_UNSAFE_VERB ("ViewSource", emfv_message_source),
-
- BONOBO_UI_UNSAFE_VERB ("MailCompose", emfv_mail_compose),
-
- /* TODO: This stuff should just be 1 item that runs a wizard */
- BONOBO_UI_UNSAFE_VERB ("ToolsFilterMailingList", emfv_tools_filter_mlist),
- BONOBO_UI_UNSAFE_VERB ("ToolsFilterRecipient", emfv_tools_filter_recipient),
- BONOBO_UI_UNSAFE_VERB ("ToolsFilterSender", emfv_tools_filter_sender),
- BONOBO_UI_UNSAFE_VERB ("ToolsFilterSubject", emfv_tools_filter_subject),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolderMailingList", emfv_tools_vfolder_mlist),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolderRecipient", emfv_tools_vfolder_recipient),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolderSender", emfv_tools_vfolder_sender),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolderSubject", emfv_tools_vfolder_subject),
-
- BONOBO_UI_UNSAFE_VERB ("ViewLoadImages", emfv_view_load_images),
- /* ViewHeaders stuff is a radio */
- /* CaretMode is a toggle */
-
- BONOBO_UI_VERB_END
-};
-static EPixmap emfv_message_pixmaps[] = {
-
- E_PIXMAP ("/commands/EditCopy", "edit-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/EditCut", "edit-cut", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/EditPaste", "edit-paste", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MailCompose", "mail-message-new", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageApplyFilters", "stock_mail-filters-apply", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageCopy", "mail-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageDelete", "user-trash", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageFilterJunk", "mail-mark-junk", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageFollowUpFlag", "stock_mail-flag-for-followup", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageForward", "mail-forward", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsImportant", "mail-mark-important", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsJunk", "mail-mark-junk", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsNotJunk", "mail-mark-notjunk", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsRead", "mail-mark-read", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsUnRead", "mail-mark-unread", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMove", "mail-move", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageReplyAll", "mail-reply-all", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageReplySender", "mail-reply-sender", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageSaveAs", "document-save-as", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageSearch", "edit-find", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/PrintMessage", "document-print", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/PrintPreviewMessage", "document-print-preview", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TextZoomIn", "zoom-in", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TextZoomOut", "zoom-out", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TextZoomReset", "zoom-original", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ViewLoadImages", "image-x-generic", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP ("/menu/MessagePlaceholder/Message/MessageNavigation/GoTo", "go-jump", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageReplySender", "mail-reply-sender", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageReplyAll", "mail-reply-all", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageForward", "mail-forward", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/PrintMessage", "document-print", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMove", "mail-move", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageCopy", "mail-copy", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageDelete", "edit-delete", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMarkAsJunk", "mail-mark-junk", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMarkAsNotJunk", "mail-mark-notjunk", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailNextButtons/MailNext", "go-next", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailNextButtons/MailPrevious", "go-previous", GTK_ICON_SIZE_LARGE_TOOLBAR),
-
- E_PIXMAP_END
-};
-
-static void
-emfv_enable_menus(EMFolderView *emfv)
-{
- guint32 disable_mask;
- GString *name;
- GSList *l;
+// BONOBO_UI_UNSAFE_VERB ("SelectAllText", emfv_select_all_text),
- if (emfv->uic == NULL)
- return;
+// BONOBO_UI_UNSAFE_VERB ("MessageDelete", emfv_message_delete),
+// BONOBO_UI_UNSAFE_VERB ("MessageDeleteKey", emfv_message_delete),
+// BONOBO_UI_UNSAFE_VERB ("MessageOpen", emfv_message_open),
+// BONOBO_UI_UNSAFE_VERB ("MessageSearch", emfv_message_search),
- {
- if (emfv->menu && emfv->folder) {
- EMMenuTargetSelect *t;
-
- t = em_menu_target_new_select(emfv->menu, emfv->folder, emfv->folder_uri, message_list_get_selected(emfv->list));
- t->target.widget = GTK_WIDGET (emfv);
- e_menu_update_target((EMenu *)emfv->menu, t);
- }
- }
+// BONOBO_UI_UNSAFE_VERB ("ViewSource", emfv_message_source),
- if (emfv->folder) {
- EMPopup *emp = em_popup_new("dummy");
- EMPopupTargetSelect *t;
-
- t = em_folder_view_get_popup_target(emfv, emp, FALSE);
- disable_mask = t->target.mask;
- e_popup_target_free((EPopup *)emp, t);
- g_object_unref(emp);
- } else {
- disable_mask = ~0;
- }
-
- name = g_string_new("");
- for (l = emfv->enable_map; l; l = l->next) {
- EMFolderViewEnable *map = l->data;
- gint i;
-
- for (i=0;map[i].name;i++) {
- gint state = (map[i].mask & disable_mask) == 0;
-
- g_string_printf(name, "/commands/%s", map[i].name);
- bonobo_ui_component_set_prop(emfv->uic, name->str, "sensitive", state?"1":"0", NULL);
- }
- }
-
- g_string_free(name, TRUE);
-}
-
-static void
-emfv_view_mode(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- EMFolderView *emfv = data;
- gint i;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- /* TODO: I don't like this stuff much, is there any way we can move listening for such events
- elsehwere? Probably not I guess, unless there's a EMFolderViewContainer for bonobo usage
- of a folder view */
-
- i = state[0] != '0';
-
- em_format_set_mode((EMFormat *)emfv->preview, i);
-
- if (EM_FOLDER_VIEW_GET_CLASS (emfv)->update_message_style) {
- GConfClient *gconf = mail_config_get_gconf_client ();
-
- gconf_client_set_int (gconf, "/apps/evolution/mail/display/message_style", i, NULL);
- }
-}
-
-static void
-emfv_caret_mode(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- em_format_html_display_set_caret_mode(emfv->preview, state[0] != '0');
-
- gconf_client_set_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/display/caret_mode", state[0] != '0', NULL);
-}
-
-static void
-emfv_charset_changed(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- /* menu items begin with "Charset-" = 8 characters */
- if (state[0] != '0' && strlen(path) > 8) {
- path += 8;
- /* default charset used in mail view */
- if (!strcmp(path, _("Default")))
- path = NULL;
-
- em_format_set_charset((EMFormat *)emfv->preview, path);
- }
-}
+ BONOBO_UI_VERB_END
+};
static void
emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
{
- struct _EMFolderViewPrivate *p = emfv->priv;
if (act) {
em_format_mode_t style;
@@ -2252,27 +456,25 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
bonobo_ui_util_set_ui(uic, PREFIX, (gchar *)l->data, emfv->ui_app_name, NULL);
bonobo_ui_component_add_verb_list_with_data(uic, emfv_message_verbs, emfv);
- e_pixmaps_update(uic, emfv_message_pixmaps);
-
/* must do plugin menu's after main ones because of bonobo bustedness */
if (emfv->menu)
e_menu_activate((EMenu *)emfv->menu, uic, act);
- state = emfv->preview->caret_mode;
- bonobo_ui_component_set_prop(uic, "/commands/CaretMode", "state", state?"1":"0", NULL);
- bonobo_ui_component_add_listener(uic, "CaretMode", emfv_caret_mode, emfv);
+// state = emfv->preview->caret_mode;
+// bonobo_ui_component_set_prop(uic, "/commands/CaretMode", "state", state?"1":"0", NULL);
+// bonobo_ui_component_add_listener(uic, "CaretMode", emfv_caret_mode, emfv);
- style = ((EMFormat *)emfv->preview)->mode?EM_FORMAT_ALLHEADERS:EM_FORMAT_NORMAL;
- if (style)
- bonobo_ui_component_set_prop(uic, "/commands/ViewFullHeaders", "state", "1", NULL);
- bonobo_ui_component_add_listener(uic, "ViewFullHeaders", emfv_view_mode, emfv);
- em_format_set_mode((EMFormat *)emfv->preview, style);
+// style = ((EMFormat *)emfv->preview)->mode?EM_FORMAT_ALLHEADERS:EM_FORMAT_NORMAL;
+// if (style)
+// bonobo_ui_component_set_prop(uic, "/commands/ViewFullHeaders", "state", "1", NULL);
+// bonobo_ui_component_add_listener(uic, "ViewFullHeaders", emfv_view_mode, emfv);
+// em_format_set_mode((EMFormat *)emfv->preview, style);
if (emfv->folder)
bonobo_ui_component_set_prop(uic, "/commands/MessageEdit", "sensitive", "0", NULL);
- /* default charset used in mail view */
- e_charset_picker_bonobo_ui_populate (uic, "/menu/View", _("Default"), emfv_charset_changed, emfv);
+// /* default charset used in mail view */
+// e_charset_picker_bonobo_ui_populate (uic, "/menu/View", _("Default"), emfv_charset_changed, emfv);
emfv_enable_menus(emfv);
if (emfv->statusbar_active)
@@ -2291,16 +493,6 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
for (v = &emfv_message_verbs[0]; v->cname; v++)
bonobo_ui_component_remove_verb(uic, v->cname);
- if (p->view_instance) {
- g_object_unref(p->view_instance);
- p->view_instance = NULL;
- }
-
- if (p->view_menus) {
- g_object_unref(p->view_menus);
- p->view_menus = NULL;
- }
-
if (emfv->folder)
mail_sync_folder(emfv->folder, NULL, NULL);
@@ -2308,37 +500,6 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
}
}
-gint
-em_folder_view_print (EMFolderView *emfv, GtkPrintOperationAction action)
-{
- EMFormatHTMLPrint *efhp;
- GPtrArray *uids;
-
- if (emfv->folder == NULL)
- return 0;
-
- uids = message_list_get_selected (emfv->list);
- if (uids->len != 1)
- goto exit;
-
- efhp = em_format_html_print_new (
- (EMFormatHTML *) emfv->preview, action);
- em_format_set_session (
- (EMFormat *) efhp,
- ((EMFormat *) emfv->preview)->session);
- em_format_merge_handler ((EMFormat *) efhp,
- (EMFormat *) emfv->preview);
-
- em_format_html_print_message (
- efhp, emfv->folder, uids->pdata[0]);
- g_object_unref (efhp);
-
-exit:
- message_list_free_uids (emfv->list, uids);
-
- return 0;
-}
-
EMPopupTargetSelect *
em_folder_view_get_popup_target(EMFolderView *emfv, EMPopup *emp, gint on_display)
{
@@ -2381,18 +542,6 @@ em_folder_view_get_popup_target(EMFolderView *emfv, EMPopup *emp, gint on_displa
}
void
-em_folder_view_set_statusbar (EMFolderView *emfv, gboolean statusbar)
-{
- g_return_if_fail (emfv);
-
- emfv->statusbar_active = statusbar;
-
- if (statusbar && emfv->uic)
- bonobo_ui_component_set_translate (emfv->uic, "/",
- "<status><item name=\"main\"/></status>", NULL);
-}
-
-void
em_folder_view_set_hide_deleted(EMFolderView *emfv, gboolean status)
{
if (emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH))
@@ -2441,6 +590,7 @@ emfv_list_done_message_selected(CamelFolder *folder, const gchar *uid, CamelMime
EMFolderView *emfv = data;
EMEvent *eme;
EMEventTargetMessage *target;
+ EShell *shell;
if (emfv->preview == NULL) {
emfv->priv->nomarkseen = FALSE;
@@ -2452,7 +602,8 @@ emfv_list_done_message_selected(CamelFolder *folder, const gchar *uid, CamelMime
e_profile_event_emit("goto.loaded", emfv->displayed_uid, 0);
- mail_indicate_new_mail (FALSE);
+ shell = e_shell_backend_get_shell (mail_shell_backend);
+ e_shell_event (shell, "mail-icon", "evolution-mail");
/** @Event: message.reading
* @Title: Viewing a message
@@ -2535,100 +686,6 @@ emfv_message_selected_timeout(gpointer data)
return FALSE;
}
-static void
-emfv_list_message_selected(MessageList *ml, const gchar *uid, EMFolderView *emfv)
-{
- e_profile_event_emit("goto.listuid", uid, 0);
-
- if (emfv->preview_active) {
- if (emfv->priv->selected_id != 0)
- g_source_remove(emfv->priv->selected_id);
-
- emfv->priv->selected_id = g_timeout_add(100, emfv_message_selected_timeout, emfv);
-
- g_free(emfv->priv->selected_uid);
- emfv->priv->selected_uid = g_strdup(uid);
- }
-
- emfv_enable_menus(emfv);
-
- g_signal_emit(emfv, signals[EMFV_CHANGED], 0);
-}
-
-static void
-emfv_list_built(MessageList *ml, EMFolderView *emfv)
-{
- if (!emfv->priv->destroyed) {
- emfv_enable_menus(emfv);
- g_signal_emit(emfv, signals[EMFV_LOADED], 0);
- }
-}
-
-static void
-emfv_list_double_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, EMFolderView *emfv)
-{
- /* Ignore double-clicks on columns that handle thier own state */
- if (MESSAGE_LIST_COLUMN_IS_ACTIVE (col))
- return;
-
- em_folder_view_open_selected(emfv);
-}
-
-static gint
-emfv_list_right_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, EMFolderView *emfv)
-{
- emfv_popup(emfv, event, FALSE);
-
- return TRUE;
-}
-
-static gint
-emfv_list_key_press(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *ev, EMFolderView *emfv)
-{
- GPtrArray *uids;
- gint i;
- guint32 flags;
-
- if ((ev->key.state & GDK_CONTROL_MASK) != 0)
- return FALSE;
-
- switch (ev->key.keyval) {
- case GDK_Return:
- case GDK_KP_Enter:
- case GDK_ISO_Enter:
- em_folder_view_open_selected(emfv);
- break;
-#ifdef HAVE_XFREE
- case XF86XK_Reply:
- emfv_message_reply(emfv, REPLY_MODE_ALL);
- break;
- case XF86XK_MailForward:
- uids = message_list_get_selected(emfv->list);
- em_utils_forward_messages (emfv->folder, uids, emfv->folder_uri);
- break;
-#endif /* HAVE_XFREE */
- case '!':
- uids = message_list_get_selected(emfv->list);
-
- camel_folder_freeze(emfv->folder);
- for (i = 0; i < uids->len; i++) {
- flags = camel_folder_get_message_flags(emfv->folder, uids->pdata[i]) ^ CAMEL_MESSAGE_FLAGGED;
- if (flags & CAMEL_MESSAGE_FLAGGED)
- flags &= ~CAMEL_MESSAGE_DELETED;
- camel_folder_set_message_flags(emfv->folder, uids->pdata[i],
- CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_DELETED, flags);
- }
- camel_folder_thaw(emfv->folder);
-
- message_list_free_uids(emfv->list, uids);
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
static gboolean
emfv_popup_menu (GtkWidget *widget)
{
@@ -2649,53 +706,25 @@ emfv_popup_menu (GtkWidget *widget)
return TRUE;
}
-static void
-emfv_list_selection_change(ETree *tree, EMFolderView *emfv)
-{
- /* we can't just listen to the message-list message selected thing, since we dont get them
- in all cases. blah */
- g_signal_emit(emfv, signals[EMFV_CHANGED], 0);
-}
-
-static void
-emfv_format_link_clicked(EMFormatHTMLDisplay *efhd, const gchar *uri, EMFolderView *emfv)
-{
- if (!strncmp (uri, "##", 2))
- return;
-
- if (!g_ascii_strncasecmp (uri, "mailto:", 7)) {
- em_utils_compose_new_message_with_mailto (uri, emfv->folder_uri);
- } else if (*uri == '#') {
- gtk_html_jump_to_anchor (((EMFormatHTML *) efhd)->html, uri + 1);
- } else if (!g_ascii_strncasecmp (uri, "thismessage:", 12)) {
- /* ignore */
- } else if (!g_ascii_strncasecmp (uri, "cid:", 4)) {
- /* ignore */
- } else {
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, uri);
- }
-}
-
-static void
-emp_uri_popup_link_copy(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- g_free(p->selection_uri);
- p->selection_uri = g_strdup(pitem->user_data);
-
- gtk_selection_owner_set(p->invisible, GDK_SELECTION_PRIMARY, gtk_get_current_event_time());
- gtk_selection_owner_set(p->invisible, GDK_SELECTION_CLIPBOARD, gtk_get_current_event_time());
-}
+//static void
+//emp_uri_popup_link_copy(EPopup *ep, EPopupItem *pitem, gpointer data)
+//{
+// EMFolderView *emfv = data;
+// struct _EMFolderViewPrivate *p = emfv->priv;
+//
+// g_free(p->selection_uri);
+// p->selection_uri = em_utils_url_unescape_amp(pitem->user_data);
+//
+// gtk_selection_owner_set(p->invisible, GDK_SELECTION_PRIMARY, gtk_get_current_event_time());
+// gtk_selection_owner_set(p->invisible, GDK_SELECTION_CLIPBOARD, gtk_get_current_event_time());
+//}
static EPopupItem emfv_uri_popups[] = {
- { E_POPUP_ITEM, (gchar *) "00.uri.15", (gchar *) N_("_Copy Link Location"), emp_uri_popup_link_copy, NULL, (gchar *) "edit-copy", EM_POPUP_URI_NOT_MAILTO },
+// { E_POPUP_ITEM, (gchar *) "00.uri.15", (gchar *) N_("_Copy Link Location"), emp_uri_popup_link_copy, NULL, (gchar *) "edit-copy", EM_POPUP_URI_NOT_MAILTO },
- { E_POPUP_SUBMENU, (gchar *) "99.uri.00", (gchar *) N_("Create _Search Folder"), NULL, NULL, NULL, EM_POPUP_URI_MAILTO },
- { E_POPUP_ITEM, (gchar *) "99.uri.00/00.10", (gchar *) N_("_From this Address"), emp_uri_popup_vfolder_sender, NULL, NULL, EM_POPUP_URI_MAILTO },
- { E_POPUP_ITEM, (gchar *) "99.uri.00/00.00", (gchar *) N_("_To this Address"), emp_uri_popup_vfolder_recipient, NULL, NULL, EM_POPUP_URI_MAILTO },
+// { E_POPUP_SUBMENU, (gchar *) "99.uri.00", (gchar *) N_("Create _Search Folder"), NULL, NULL, NULL, EM_POPUP_URI_MAILTO },
+// { E_POPUP_ITEM, (gchar *) "99.uri.00/00.10", (gchar *) N_("_From this Address"), emp_uri_popup_vfolder_sender, NULL, NULL, EM_POPUP_URI_MAILTO },
+// { E_POPUP_ITEM, (gchar *) "99.uri.00/00.00", (gchar *) N_("_To this Address"), emp_uri_popup_vfolder_recipient, NULL, NULL, EM_POPUP_URI_MAILTO },
};
static void
@@ -2914,43 +943,17 @@ emfv_set_seen(EMFolderView *emfv, const gchar *uid)
/* keep these two tables in sync */
enum {
- EMFV_ANIMATE_IMAGES = 1,
- EMFV_CHARSET,
- EMFV_CITATION_COLOUR,
- EMFV_CITATION_MARK,
- EMFV_CARET_MODE,
- EMFV_MESSAGE_STYLE,
- EMFV_MARK_SEEN,
- EMFV_MARK_SEEN_TIMEOUT,
- EMFV_LOAD_HTTP,
+ EMFV_CHARSET = 1,
EMFV_HEADERS,
- EMFV_SHOW_PREVIEW,
EMFV_SHOW_DELETED,
- EMFV_THREAD_LIST,
- EMFV_PANED_SIZE,
- EMFV_SENDER_PHOTO,
- EMFV_PHOTO_LOCAL,
EMFV_SETTINGS /* last, for loop count */
};
/* IF these get too long, update key field */
static const gchar * const emfv_display_keys[] = {
- "animate_images",
"charset",
- "citation_colour",
- "mark_citations",
- "caret_mode",
- "message_style",
- "mark_seen",
- "mark_seen_timeout",
- "load_http_images",
"headers",
- "show_preview",
"show_deleted",
- "thread_list",
- "paned_size",
- "sender_photo",
- "photo_local",
};
static GHashTable *emfv_setting_key;
@@ -2970,49 +973,9 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold
g_return_if_fail (tkey != NULL);
switch (GPOINTER_TO_INT(g_hash_table_lookup(emfv_setting_key, tkey+1))) {
- case EMFV_ANIMATE_IMAGES:
- em_format_html_display_set_animate(emfv->preview, gconf_value_get_bool (value));
- break;
case EMFV_CHARSET:
em_format_set_default_charset((EMFormat *)emfv->preview, gconf_value_get_string (value));
break;
- case EMFV_CITATION_COLOUR: {
- const gchar *s;
- GdkColor colour;
- guint32 rgb;
-
- s = gconf_value_get_string (value);
- gdk_color_parse(s?s:"#737373", &colour);
- rgb = ((colour.red & 0xff00) << 8) | (colour.green & 0xff00) | ((colour.blue & 0xff00) >> 8);
- em_format_html_set_mark_citations((EMFormatHTML *)emfv->preview,
- ((EMFormatHTML *)emfv->preview)->mark_citations, rgb);
- break; }
- case EMFV_CITATION_MARK:
- em_format_html_set_mark_citations((EMFormatHTML *)emfv->preview,
- gconf_value_get_bool (value),
- ((EMFormatHTML *)emfv->preview)->citation_colour);
- break;
- case EMFV_CARET_MODE:
- em_format_html_display_set_caret_mode(emfv->preview, gconf_value_get_bool (value));
- break;
- case EMFV_MESSAGE_STYLE:
- if (EM_FOLDER_VIEW_GET_CLASS (emfv)->update_message_style) {
- gint style = gconf_value_get_int (value);
-
- if (style < EM_FORMAT_NORMAL || style > EM_FORMAT_SOURCE)
- style = EM_FORMAT_NORMAL;
- em_format_set_mode((EMFormat *)emfv->preview, style);
- }
- break;
- case EMFV_MARK_SEEN:
- emfv->mark_seen = gconf_value_get_bool (value);
- break;
- case EMFV_MARK_SEEN_TIMEOUT:
- emfv->mark_seen_timeout = gconf_value_get_int (value);
- break;
- case EMFV_LOAD_HTTP:
- em_format_html_set_load_http((EMFormatHTML *)emfv->preview, gconf_value_get_int(value));
- break;
case EMFV_HEADERS: {
GSList *header_config_list, *p;
EMFormat *emf = (EMFormat *)emfv->preview;
@@ -3037,45 +1000,6 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold
if (emf->message)
em_format_redraw(emf);
break; }
- case EMFV_SENDER_PHOTO: {
- EMFormat *emf = (EMFormat *)emfv->preview;
-
- emf->show_photo = gconf_value_get_bool (value);
- if (emf->message)
- em_format_redraw(emf);
-
- break; }
- case EMFV_PHOTO_LOCAL: {
- EMFormat *emf = (EMFormat *)emfv->preview;
-
- emf->photo_local = gconf_value_get_bool (value);
-
- break; }
- case EMFV_SHOW_PREVIEW: {
- gboolean state_gconf, state_camel;
- gchar *ret;
-
- /* If emfv->folder hasn't been initialized, do nothing */
- if (!emfv->folder)
- return;
-
- state_gconf = gconf_value_get_bool (value);
- if (state_gconf == FALSE)
- emfv_enable_menus (emfv);
-
- if ((ret = camel_object_meta_get (emfv->folder, "evolution:show_preview"))) {
- state_camel = (ret[0] != '0');
- g_free (ret);
- if (state_gconf == state_camel)
- return;
- }
-
- if (camel_object_meta_set (emfv->folder, "evolution:show_preview", state_gconf ? "1" : "0"))
- camel_object_state_write (emfv->folder);
- if (emfv->list_active)
- em_folder_browser_show_preview ((EMFolderBrowser *)emfv, state_gconf);
- bonobo_ui_component_set_prop (emfv->uic, "/commands/ViewPreview", "state", state_gconf ? "1" : "0", NULL);
- break; }
case EMFV_SHOW_DELETED: {
gboolean state;
@@ -3086,155 +1010,5 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold
if (emfv->uic)
bonobo_ui_component_set_prop (emfv->uic, "/commands/HideDeleted", "state", state ? "0" : "1", NULL);
break; }
- case EMFV_THREAD_LIST: {
- gboolean state_gconf, state_camel;
- gchar *ret;
-
- /* If emfv->folder or emfv->list hasn't been initialized, do nothing */
- if (!emfv->folder || !emfv->list)
- return;
-
- state_gconf = gconf_value_get_bool (value);
- if ((ret = camel_object_meta_get (emfv->folder, "evolution:thread_list"))) {
- state_camel = (ret[0] != '0');
- g_free (ret);
- if (state_gconf == state_camel)
- return;
- }
-
- if (camel_object_meta_set (emfv->folder, "evolution:thread_list", state_gconf ? "1" : "0"))
- camel_object_state_write (emfv->folder);
- message_list_set_threaded (emfv->list, state_gconf);
- bonobo_ui_component_set_prop (emfv->uic, "/commands/ViewThreaded", "state", state_gconf ? "1" : "0", NULL);
- break; }
- case EMFV_PANED_SIZE: {
- EMFolderBrowser *emfb = (EMFolderBrowser *)emfv;
- gint paned_size;
-
- if (!emfv->list_active || !emfb->vpane || !emfv->preview_active)
- return;
-
- paned_size = gconf_value_get_int (value);
- if (paned_size == gtk_paned_get_position (GTK_PANED (emfb->vpane)))
- return;
-
- gtk_paned_set_position (GTK_PANED (emfb->vpane), paned_size);
- break; }
- }
-}
-
-static void
-emfv_setting_setup(EMFolderView *emfv)
-{
- GConfClient *gconf = gconf_client_get_default();
- GConfEntry *entry;
- GError *err = NULL;
- gint i;
- gchar key[64];
-
- if (emfv_setting_key == NULL) {
- emfv_setting_key = g_hash_table_new(g_str_hash, g_str_equal);
- for (i=1;i<EMFV_SETTINGS;i++)
- g_hash_table_insert(emfv_setting_key, (gpointer)emfv_display_keys[i-1], GINT_TO_POINTER(i));
- }
-
- gconf_client_add_dir(gconf, "/apps/evolution/mail/display", GCONF_CLIENT_PRELOAD_NONE, NULL);
-
- for (i=1;err == NULL && i<EMFV_SETTINGS;i++) {
- sprintf(key, "/apps/evolution/mail/display/%s", emfv_display_keys[i-1]);
- entry = gconf_client_get_entry(gconf, key, NULL, TRUE, &err);
- if (entry) {
- emfv_setting_notify(gconf, 0, entry, emfv);
- gconf_entry_free(entry);
- }
- }
-
- if (err) {
- g_warning("Could not load display settings: %s", err->message);
- g_error_free(err);
}
-
- emfv->priv->setting_notify_id = gconf_client_notify_add(gconf, "/apps/evolution/mail/display",
- (GConfClientNotifyFunc)emfv_setting_notify,
- emfv, NULL, NULL);
- g_object_unref(gconf);
-}
-
-static void
-emfv_on_url (EMFolderView *emfv, const gchar *uri, const gchar *nice_uri)
-{
- if (emfv->statusbar_active) {
- if (emfv->uic) {
- bonobo_ui_component_set_status (emfv->uic, nice_uri, NULL);
- /* Make sure the node keeps existing if nice_url == NULL */
- if (!nice_uri)
- bonobo_ui_component_set_translate (
- emfv->uic, "/", "<status><item name=\"main\"/></status>", NULL);
- }
- }
-}
-
-static void
-emfv_on_url_cb (GObject *emitter, const gchar *url, EMFolderView *emfv)
-{
- gchar *nice_url = NULL;
-
- if (url) {
- if (strncmp (url, "mailto:", 7) == 0) {
- CamelInternetAddress *cia = camel_internet_address_new();
- CamelURL *curl;
- gchar *addr;
-
- curl = camel_url_new(url, NULL);
- camel_address_decode((CamelAddress *)cia, curl->path);
- addr = camel_address_format((CamelAddress *)cia);
- nice_url = g_strdup_printf (_("Click to mail %s"), addr&&addr[0]?addr:(url + 7));
- g_free(addr);
- camel_url_free(curl);
- camel_object_unref(cia);
- } else if (strncmp (url, "callto:", 7) == 0 || strncmp (url, "h323:", 5) == 0 || strncmp (url, "sip:", 4) == 0) {
- CamelInternetAddress *cia = camel_internet_address_new();
- CamelURL *curl;
- gchar *addr;
-
- curl = camel_url_new(url, NULL);
- camel_address_decode((CamelAddress *)cia, curl->path);
- addr = camel_address_format((CamelAddress *)cia);
- nice_url = g_strdup_printf (_("Click to call %s"), addr&&addr[0]?addr:(url + 7));
- g_free(addr);
- camel_url_free(curl);
- camel_object_unref(cia);
- } else if (!strncmp (url, "##", 2)) {
- nice_url = g_strdup (_("Click to hide/unhide addresses"));
- } else
- nice_url = g_strdup_printf (_("Click to open %s"), url);
- }
-
- g_signal_emit (emfv, signals[EMFV_ON_URL], 0, url, nice_url);
-
- g_free (nice_url);
-}
-
-static gboolean
-emfv_on_html_button_released_cb (GtkHTML *html, GdkEventButton *button, EMFolderView *emfv)
-{
- gboolean selected;
-
- selected = gtk_html_command (html, "is-selection-active");
- bonobo_ui_component_set_prop(emfv->uic, "/commands/EditCopy", "sensitive", selected?"1":"0", NULL);
-
- return FALSE;
-}
-
-void
-em_folder_view_show_search_bar (EMFolderView *emfv)
-{
- EMFolderViewClass *class;
-
- g_return_if_fail (EM_IS_FOLDER_VIEW (emfv));
-
- class = EM_FOLDER_VIEW_GET_CLASS (emfv);
- g_return_if_fail (class->show_search_bar != NULL);
-
- class->show_search_bar (emfv);
}
diff --git a/mail/em-folder-view.h b/mail/em-folder-view.h
index bb25f390ea..2c276914c0 100644
--- a/mail/em-folder-view.h
+++ b/mail/em-folder-view.h
@@ -143,6 +143,9 @@ GtkWidget *em_folder_view_new(void);
#define em_folder_view_set_folder_uri(emfv, uri) EM_FOLDER_VIEW_GET_CLASS (emfv)->set_folder_uri((emfv), (uri))
#define em_folder_view_set_message(emfv, uid, nomarkseen) EM_FOLDER_VIEW_GET_CLASS (emfv)->set_message((emfv), (uid), (nomarkseen))
+void em_folder_view_select_next_message(EMFolderView *emfv, gint count, gboolean always_can_previous);
+void em_folder_view_message_reply(EMFolderView *emfv, gint mode);
+
EMPopupTargetSelect *em_folder_view_get_popup_target(EMFolderView *emfv, EMPopup *emp, gint on_display);
gint em_folder_view_mark_selected(EMFolderView *emfv, guint32 mask, guint32 set);
diff --git a/mail/em-format-hook.h b/mail/em-format-hook.h
index 8312404451..e0560f4994 100644
--- a/mail/em-format-hook.h
+++ b/mail/em-format-hook.h
@@ -28,7 +28,7 @@
#include "libedataserver/e-msgport.h"
#include "e-util/e-plugin.h"
-#include "mail/em-format.h"
+#include "em-format/em-format.h"
G_BEGIN_DECLS
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index 003eb37f8c..38e3af3587 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -74,28 +74,63 @@
#include "mail-config.h"
+#include "e-mail-display.h"
#include "e-mail-attachment-bar.h"
#include "em-format-html-display.h"
#include "em-icon-stream.h"
#include "em-utils.h"
-#include "em-popup.h"
-#include "e-icon-entry.h"
#include "widgets/misc/e-attachment-button.h"
#include "widgets/misc/e-attachment-view.h"
#define d(x)
+#define EM_FORMAT_HTML_DISPLAY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayPrivate))
+
struct _EMFormatHTMLDisplayPrivate {
GtkWidget *attachment_view; /* weak reference */
};
-static gint efhd_html_button_press_event (GtkWidget *widget, GdkEventButton *event, EMFormatHTMLDisplay *efh);
-static void efhd_html_link_clicked (GtkHTML *html, const gchar *url, EMFormatHTMLDisplay *efhd);
-static void efhd_html_on_url (GtkHTML *html, const gchar *url, EMFormatHTMLDisplay *efhd);
+struct _smime_pobject {
+ EMFormatHTMLPObject object;
+
+ gint signature;
+ CamelCipherValidity *valid;
+ GtkWidget *widget;
+};
+
+/* TODO: move the dialogue elsehwere */
+/* FIXME: also in em-format-html.c */
+static const struct {
+ const gchar *icon, *shortdesc, *description;
+} smime_sign_table[5] = {
+ { "stock_signature-bad", N_("Unsigned"), N_("This message is not signed. There is no guarantee that this message is authentic.") },
+ { "stock_signature-ok", N_("Valid signature"), N_("This message is signed and is valid meaning that it is very likely that this message is authentic.") },
+ { "stock_signature-bad", N_("Invalid signature"), N_("The signature of this message cannot be verified, it may have been altered in transit.") },
+ { "stock_signature", N_("Valid signature, but cannot verify sender"), N_("This message is signed with a valid signature, but the sender of the message cannot be verified.") },
+ { "stock_signature-bad", N_("Signature exists, but need public key"), N_("This message is signed with a signature, but there is no corresponding public key.") },
+
+};
+
+static const struct {
+ const gchar *icon, *shortdesc, *description;
+} smime_encrypt_table[4] = {
+ { "stock_lock-broken", N_("Unencrypted"), N_("This message is not encrypted. Its content may be viewed in transit across the Internet.") },
+ { "stock_lock-ok", N_("Encrypted, weak"), N_("This message is encrypted, but with a weak encryption algorithm. It would be difficult, but not impossible for an outsider to view the content of this message in a practical amount of time.") },
+ { "stock_lock-ok", N_("Encrypted"), N_("This message is encrypted. It would be difficult for an outsider to view the content of this message.") },
+ { "stock_lock-ok", N_("Encrypted, strong"), N_("This message is encrypted, with a strong encryption algorithm. It would be very difficult for an outsider to view the content of this message in a practical amount of time.") },
+};
+
+static const gchar *smime_sign_colour[5] = {
+ "", " bgcolor=\"#88bb88\"", " bgcolor=\"#bb8888\"", " bgcolor=\"#e8d122\"",""
+};
static void efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri);
static gboolean efhd_attachment_image(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
static void efhd_message_add_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info);
+static gboolean efhd_attachment_button (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
+static gboolean efhd_attachment_optional (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *object);
struct _attach_puri {
EMFormatPURI puri;
@@ -108,7 +143,6 @@ struct _attach_puri {
GtkWidget *forward, *down;
/* currently no way to correlate this data to the frame :( */
GtkHTML *frame;
- CamelStream *output;
guint shown:1;
/* Embedded Frame */
@@ -131,463 +165,14 @@ struct _attach_puri {
camel_cipher_validity_encrypt_t encrypt;
};
-static void efhd_iframe_created(GtkHTML *html, GtkHTML *iframe, EMFormatHTMLDisplay *efh);
-/*static void efhd_url_requested(GtkHTML *html, const gchar *url, GtkHTMLStream *handle, EMFormatHTMLDisplay *efh);
- static gboolean efhd_object_requested(GtkHTML *html, GtkHTMLEmbedded *eb, EMFormatHTMLDisplay *efh);*/
-
static void efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info);
-static const EMFormatHandler *efhd_find_handler(EMFormat *emf, const gchar *mime_type);
-static void efhd_format_clone(EMFormat *, CamelFolder *folder, const gchar *, CamelMimeMessage *msg, EMFormat *);
-static void efhd_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt);
-static void efhd_format_source(EMFormat *, CamelStream *, CamelMimePart *);
-static void efhd_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const gchar *, const EMFormatHandler *);
-static void efhd_format_optional(EMFormat *, CamelStream *, CamelMimePart *, CamelStream *);
-static void efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
-
static void efhd_builtin_init(EMFormatHTMLDisplayClass *efhc);
-enum {
- EFHD_LINK_CLICKED,
- EFHD_POPUP_EVENT,
- EFHD_ON_URL,
- EFHD_LAST_SIGNAL
-};
-
-static guint efhd_signals[EFHD_LAST_SIGNAL] = { 0 };
-
-static EMFormatHTMLClass *efhd_parent;
-static EMFormatClass *efhd_format_class;
-
-static void
-efhd_gtkhtml_realise(GtkHTML *html, EMFormatHTMLDisplay *efhd)
-{
- GtkStyle *style;
-
- /* FIXME: does this have to be re-done every time we draw? */
-
- /* My favorite thing to do... muck around with colors so we respect people's stupid themes.
- However, we only do this if we are rendering to the screen -- we ignore the theme
- when we are printing. */
- style = gtk_widget_get_style((GtkWidget *)html);
- if (style) {
- gint state = GTK_WIDGET_STATE(html);
- gushort r, g, b;
-
- r = style->fg[state].red >> 8;
- g = style->fg[state].green >> 8;
- b = style->fg[state].blue >> 8;
-
- efhd->formathtml.header_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-
- r = style->bg[state].red >> 8;
- g = style->bg[state].green >> 8;
- b = style->bg[state].blue >> 8;
-
- efhd->formathtml.body_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-
- r = style->dark[state].red >> 8;
- g = style->dark[state].green >> 8;
- b = style->dark[state].blue >> 8;
-
- efhd->formathtml.frame_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-
- r = style->base[GTK_STATE_NORMAL].red >> 8;
- g = style->base[GTK_STATE_NORMAL].green >> 8;
- b = style->base[GTK_STATE_NORMAL].blue >> 8;
-
- efhd->formathtml.content_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-
- r = style->text[state].red >> 8;
- g = style->text[state].green >> 8;
- b = style->text[state].blue >> 8;
-
- efhd->formathtml.text_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-#undef DARKER
- }
-}
+static gpointer parent_class;
static void
-efhd_gtkhtml_style_set(GtkHTML *html, GtkStyle *old, EMFormatHTMLDisplay *efhd)
-{
- efhd_gtkhtml_realise(html, efhd);
- em_format_redraw((EMFormat *)efhd);
-}
-
-static void
-efhd_init(GObject *o)
-{
- EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)o;
-#define efh ((EMFormatHTML *)efhd)
-
- efhd->priv = g_malloc0(sizeof(*efhd->priv));
-
- g_signal_connect(efh->html, "realize", G_CALLBACK(efhd_gtkhtml_realise), o);
- g_signal_connect(efh->html, "style-set", G_CALLBACK(efhd_gtkhtml_style_set), o);
- /* we want to convert url's etc */
- efh->text_html_flags |= CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
-#undef efh
-
- efhd->nobar = getenv("EVOLUTION_NO_BAR") != NULL;
-}
-
-static void
-efhd_finalise(GObject *o)
-{
- EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)o;
-
- /* check pending stuff */
-
- g_free(efhd->priv);
-
- ((GObjectClass *)efhd_parent)->finalize(o);
-}
-
-static gboolean
-efhd_bool_accumulator(GSignalInvocationHint *ihint, GValue *out, const GValue *in, gpointer data)
-{
- gboolean val = g_value_get_boolean(in);
-
- g_value_set_boolean(out, val);
-
- return !val;
-}
-
-static void
-efhd_class_init(GObjectClass *klass)
-{
- ((EMFormatClass *)klass)->find_handler = efhd_find_handler;
- ((EMFormatClass *)klass)->format_clone = efhd_format_clone;
- ((EMFormatClass *)klass)->format_error = efhd_format_error;
- ((EMFormatClass *)klass)->format_source = efhd_format_source;
- ((EMFormatClass *)klass)->format_attachment = efhd_format_attachment;
- ((EMFormatClass *)klass)->format_optional = efhd_format_optional;
- ((EMFormatClass *)klass)->format_secure = efhd_format_secure;
-
- klass->finalize = efhd_finalise;
-
- efhd_signals[EFHD_LINK_CLICKED] =
- g_signal_new("link_clicked",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, link_clicked),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-
- efhd_signals[EFHD_POPUP_EVENT] =
- g_signal_new("popup_event",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, popup_event),
- efhd_bool_accumulator, NULL,
- e_marshal_BOOLEAN__BOXED_POINTER_POINTER,
- G_TYPE_BOOLEAN, 3,
- GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
- G_TYPE_POINTER, G_TYPE_POINTER);
-
- efhd_signals[EFHD_ON_URL] =
- g_signal_new("on_url",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, on_url),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- efhd_builtin_init((EMFormatHTMLDisplayClass *)klass);
-}
-
-GType
-em_format_html_display_get_type (void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFormatHTMLDisplayClass),
- NULL, NULL,
- (GClassInitFunc)efhd_class_init,
- NULL, NULL,
- sizeof(EMFormatHTMLDisplay), 0,
- (GInstanceInitFunc)efhd_init
- };
- efhd_parent = g_type_class_ref(em_format_html_get_type());
- efhd_format_class = g_type_class_ref(em_format_get_type());
- type = g_type_register_static(em_format_html_get_type(), "EMFormatHTMLDisplay", &info, 0);
- }
-
- return type;
-}
-
-static gboolean
-efhd_scroll_event(GtkWidget *w, GdkEventScroll *event, EMFormatHTMLDisplay *efhd)
-{
- if (event->state & GDK_CONTROL_MASK)
- {
- if (event->direction == GDK_SCROLL_UP)
- {
- gtk_html_zoom_in (efhd->formathtml.html);
- }
- else if (event->direction == GDK_SCROLL_DOWN)
- {
- gtk_html_zoom_out (efhd->formathtml.html);
- }
- return TRUE;
- }
- return FALSE;
-}
-
-EMFormatHTMLDisplay *em_format_html_display_new(void)
-{
- EMFormatHTMLDisplay *efhd;
-
- efhd = g_object_new(em_format_html_display_get_type(), 0);
-
- g_signal_connect(efhd->formathtml.html, "iframe_created", G_CALLBACK(efhd_iframe_created), efhd);
- g_signal_connect(efhd->formathtml.html, "link_clicked", G_CALLBACK(efhd_html_link_clicked), efhd);
- g_signal_connect(efhd->formathtml.html, "on_url", G_CALLBACK(efhd_html_on_url), efhd);
- g_signal_connect(efhd->formathtml.html, "button_press_event", G_CALLBACK(efhd_html_button_press_event), efhd);
- g_signal_connect(efhd->formathtml.html,"scroll_event", G_CALLBACK(efhd_scroll_event), efhd);
-
- return efhd;
-}
-
-void em_format_html_display_goto_anchor(EMFormatHTMLDisplay *efhd, const gchar *name)
-{
- printf("FIXME: go to anchor '%s'\n", name);
-}
-
-void em_format_html_display_set_animate(EMFormatHTMLDisplay *efhd, gboolean state)
-{
- efhd->animate = state;
- gtk_html_set_animate(((EMFormatHTML *)efhd)->html, state);
-}
-
-void em_format_html_display_set_caret_mode(EMFormatHTMLDisplay *efhd, gboolean state)
-{
- efhd->caret_mode = state;
- gtk_html_set_caret_mode(((EMFormatHTML *)efhd)->html, state);
-}
-
-void
-em_format_html_display_cut (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_cut (((EMFormatHTML *) efhd)->html);
-}
-
-void
-em_format_html_display_copy (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_copy (((EMFormatHTML *) efhd)->html);
-}
-
-void
-em_format_html_display_paste (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_paste (((EMFormatHTML *) efhd)->html, FALSE);
-}
-
-void
-em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_zoom_in (((EMFormatHTML *) efhd)->html);
-}
-
-void
-em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_zoom_out (((EMFormatHTML *) efhd)->html);
-}
-
-void
-em_format_html_display_zoom_reset (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_zoom_reset (((EMFormatHTML *) efhd)->html);
-}
-
-/* ********************************************************************** */
-
-static void
-efhd_iframe_created(GtkHTML *html, GtkHTML *iframe, EMFormatHTMLDisplay *efh)
-{
- d(printf("Iframe created %p ... \n", iframe));
-
- g_signal_connect(iframe, "button_press_event", G_CALLBACK (efhd_html_button_press_event), efh);
-
- return;
-}
-
-static void
-efhd_get_uri_puri (GtkWidget *html, GdkEventButton *event, EMFormatHTMLDisplay *efhd, gchar **uri, EMFormatPURI **puri)
-{
- gchar *url, *img_url;
-
- g_return_if_fail (html != NULL);
- g_return_if_fail (GTK_IS_HTML (html));
- g_return_if_fail (efhd != NULL);
-
- if (event) {
- url = gtk_html_get_url_at (GTK_HTML (html), event->x, event->y);
- img_url = gtk_html_get_image_src_at (GTK_HTML (html), event->x, event->y);
- } else {
- url = gtk_html_get_cursor_url (GTK_HTML (html));
- img_url = gtk_html_get_cursor_image_src (GTK_HTML (html));
- }
-
- if (img_url) {
- if (!(strstr (img_url, "://") || g_ascii_strncasecmp (img_url, "cid:", 4) == 0)) {
- gchar *u = g_filename_to_uri (img_url, NULL, NULL);
- g_free (img_url);
- img_url = u;
- }
- }
-
- if (puri) {
- if (url)
- *puri = em_format_find_puri ((EMFormat *)efhd, url);
-
- if (!*puri && img_url)
- *puri = em_format_find_puri ((EMFormat *)efhd, img_url);
- }
-
- if (uri) {
- *uri = NULL;
- if (img_url && g_ascii_strncasecmp (img_url, "cid:", 4) != 0) {
- if (url)
- *uri = g_strdup_printf ("%s\n%s", url, img_url);
- else {
- *uri = img_url;
- img_url = NULL;
- }
- } else {
- *uri = url;
- url = NULL;
- }
- }
-
- g_free (url);
- g_free (img_url);
-}
-
-static gint
-efhd_html_button_press_event (GtkWidget *widget, GdkEventButton *event, EMFormatHTMLDisplay *efhd)
-{
- gchar *uri = NULL;
- EMFormatPURI *puri = NULL;
- gboolean res = FALSE;
-
- if (event->button != 3)
- return FALSE;
-
- d(printf("popup button pressed\n"));
-
- efhd_get_uri_puri (widget, event, efhd, &uri, &puri);
-
- if (uri && !strncmp (uri, "##", 2)) {
- g_free (uri);
- return TRUE;
- }
-
- g_signal_emit((GtkObject *)efhd, efhd_signals[EFHD_POPUP_EVENT], 0, event, uri, puri?puri->part:NULL, &res);
-
- g_free (uri);
-
- return res;
-}
-
-gboolean
-em_format_html_display_popup_menu (EMFormatHTMLDisplay *efhd)
-{
- GtkHTML *html;
- gchar *uri = NULL;
- EMFormatPURI *puri = NULL;
- gboolean res = FALSE;
-
- html = efhd->formathtml.html;
-
- efhd_get_uri_puri (GTK_WIDGET (html), NULL, efhd, &uri, &puri);
-
- g_signal_emit ((GtkObject *)efhd, efhd_signals[EFHD_POPUP_EVENT], 0, NULL, uri, puri?puri->part:NULL, &res);
-
- g_free (uri);
-
- return res;
-}
-
-static void
-efhd_html_link_clicked (GtkHTML *html, const gchar *url, EMFormatHTMLDisplay *efhd)
-{
- d(printf("link clicked event '%s'\n", url));
- if (url && !strncmp(url, "##", 2)) {
- if (!strcmp (url, "##TO##"))
- if (!(((EMFormatHTML *) efhd)->header_wrap_flags & EM_FORMAT_HTML_HEADER_TO))
- ((EMFormatHTML *) efhd)->header_wrap_flags |= EM_FORMAT_HTML_HEADER_TO;
- else
- ((EMFormatHTML *) efhd)->header_wrap_flags &= ~EM_FORMAT_HTML_HEADER_TO;
- else if (!strcmp (url, "##CC##"))
- if (!(((EMFormatHTML *) efhd)->header_wrap_flags & EM_FORMAT_HTML_HEADER_CC))
- ((EMFormatHTML *) efhd)->header_wrap_flags |= EM_FORMAT_HTML_HEADER_CC;
- else
- ((EMFormatHTML *) efhd)->header_wrap_flags &= ~EM_FORMAT_HTML_HEADER_CC;
- else if (!strcmp (url, "##BCC##")) {
- if (!(((EMFormatHTML *) efhd)->header_wrap_flags & EM_FORMAT_HTML_HEADER_BCC))
- ((EMFormatHTML *) efhd)->header_wrap_flags |= EM_FORMAT_HTML_HEADER_BCC;
- else
- ((EMFormatHTML *) efhd)->header_wrap_flags &= ~EM_FORMAT_HTML_HEADER_BCC;
- }
- em_format_redraw((EMFormat *)efhd);
- } else
- g_signal_emit((GObject *)efhd, efhd_signals[EFHD_LINK_CLICKED], 0, url);
-}
-
-static void
-efhd_html_on_url (GtkHTML *html, const gchar *url, EMFormatHTMLDisplay *efhd)
-{
- d(printf("on_url event '%s'\n", url));
-
- g_signal_emit((GObject *)efhd, efhd_signals[EFHD_ON_URL], 0, url);
-}
-
-/* ********************************************************************** */
-
-/* TODO: move the dialogue elsehwere */
-/* FIXME: also in em-format-html.c */
-static const struct {
- const gchar *icon, *shortdesc, *description;
-} smime_sign_table[5] = {
- { "stock_signature-bad", N_("Unsigned"), N_("This message is not signed. There is no guarantee that this message is authentic.") },
- { "stock_signature-ok", N_("Valid signature"), N_("This message is signed and is valid meaning that it is very likely that this message is authentic.") },
- { "stock_signature-bad", N_("Invalid signature"), N_("The signature of this message cannot be verified, it may have been altered in transit.") },
- { "stock_signature", N_("Valid signature, but cannot verify sender"), N_("This message is signed with a valid signature, but the sender of the message cannot be verified.") },
- { "stock_signature-bad", N_("Signature exists, but need public key"), N_("This message is signed with a signature, but there is no corresponding public key.") },
-
-};
-
-static const struct {
- const gchar *icon, *shortdesc, *description;
-} smime_encrypt_table[4] = {
- { "stock_lock-broken", N_("Unencrypted"), N_("This message is not encrypted. Its content may be viewed in transit across the Internet.") },
- { "stock_lock-ok", N_("Encrypted, weak"), N_("This message is encrypted, but with a weak encryption algorithm. It would be difficult, but not impossible for an outsider to view the content of this message in a practical amount of time.") },
- { "stock_lock-ok", N_("Encrypted"), N_("This message is encrypted. It would be difficult for an outsider to view the content of this message.") },
- { "stock_lock-ok", N_("Encrypted, strong"), N_("This message is encrypted, with a strong encryption algorithm. It would be very difficult for an outsider to view the content of this message in a practical amount of time.") },
-};
-
-static const gchar *smime_sign_colour[5] = {
- "", " bgcolor=\"#88bb88\"", " bgcolor=\"#bb8888\"", " bgcolor=\"#e8d122\"",""
-};
-
-struct _smime_pobject {
- EMFormatHTMLPObject object;
-
- gint signature;
- CamelCipherValidity *valid;
- GtkWidget *widget;
-};
-
-static void
-efhd_xpkcs7mime_free(EMFormatHTMLPObject *o)
+efhd_xpkcs7mime_free (EMFormatHTMLPObject *o)
{
struct _smime_pobject *po = (struct _smime_pobject *)o;
@@ -597,21 +182,18 @@ efhd_xpkcs7mime_free(EMFormatHTMLPObject *o)
}
static void
-efhd_xpkcs7mime_info_response(GtkWidget *w, guint button, struct _smime_pobject *po)
+efhd_xpkcs7mime_info_response (GtkWidget *widget,
+ guint button,
+ struct _smime_pobject *po)
{
- gtk_widget_destroy(w);
+ gtk_widget_destroy (widget);
po->widget = NULL;
}
#ifdef HAVE_NSS
static void
-efhd_xpkcs7mime_viewcert_foad(GtkWidget *w, guint button, struct _smime_pobject *po)
-{
- gtk_widget_destroy(w);
-}
-
-static void
-efhd_xpkcs7mime_viewcert_clicked(GtkWidget *button, struct _smime_pobject *po)
+efhd_xpkcs7mime_viewcert_clicked (GtkWidget *button,
+ struct _smime_pobject *po)
{
CamelCipherCertInfo *info = g_object_get_data((GObject *)button, "e-cert-info");
ECertDB *db = e_cert_db_peek();
@@ -628,7 +210,7 @@ efhd_xpkcs7mime_viewcert_clicked(GtkWidget *button, struct _smime_pobject *po)
/* oddly enough certificate_viewer_show doesn't ... */
gtk_widget_show(w);
- g_signal_connect(w, "response", G_CALLBACK(efhd_xpkcs7mime_viewcert_foad), po);
+ g_signal_connect(w, "response", G_CALLBACK(gtk_widget_destroy), NULL);
if (w && po->widget)
gtk_window_set_transient_for ((GtkWindow *)w, (GtkWindow *)po->widget);
@@ -641,7 +223,9 @@ efhd_xpkcs7mime_viewcert_clicked(GtkWidget *button, struct _smime_pobject *po)
#endif
static void
-efhd_xpkcs7mime_add_cert_table(GtkWidget *vbox, CamelDList *certlist, struct _smime_pobject *po)
+efhd_xpkcs7mime_add_cert_table (GtkWidget *vbox,
+ CamelDList *certlist,
+ struct _smime_pobject *po)
{
CamelCipherCertInfo *info = (CamelCipherCertInfo *)certlist->head;
GtkTable *table = (GtkTable *)gtk_table_new(camel_dlist_length(certlist), 2, FALSE);
@@ -700,7 +284,8 @@ efhd_xpkcs7mime_add_cert_table(GtkWidget *vbox, CamelDList *certlist, struct _sm
}
static void
-efhd_xpkcs7mime_validity_clicked(GtkWidget *button, EMFormatHTMLPObject *pobject)
+efhd_xpkcs7mime_validity_clicked (GtkWidget *button,
+ EMFormatHTMLPObject *pobject)
{
struct _smime_pobject *po = (struct _smime_pobject *)pobject;
GladeXML *xml;
@@ -711,10 +296,9 @@ efhd_xpkcs7mime_validity_clicked(GtkWidget *button, EMFormatHTMLPObject *pobject
/* FIXME: window raise? */
return;
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-dialogs.glade",
- NULL);
- xml = glade_xml_new(gladefile, "message_security_dialog", NULL);
+ gladefile = g_build_filename (
+ EVOLUTION_GLADEDIR, "mail-dialogs.glade", NULL);
+ xml = glade_xml_new (gladefile, "message_security_dialog", NULL);
g_free (gladefile);
po->widget = glade_xml_get_widget(xml, "message_security_dialog");
@@ -790,9 +374,12 @@ efhd_xpkcs7mime_validity_clicked(GtkWidget *button, EMFormatHTMLPObject *pobject
}
static gboolean
-efhd_xpkcs7mime_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
+efhd_xpkcs7mime_button (EMFormatHTML *efh,
+ GtkHTMLEmbedded *eb,
+ EMFormatHTMLPObject *pobject)
{
- GtkWidget *icon, *button;
+ GtkWidget *container;
+ GtkWidget *widget;
struct _smime_pobject *po = (struct _smime_pobject *)pobject;
const gchar *icon_name;
@@ -802,25 +389,171 @@ efhd_xpkcs7mime_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
else
icon_name = smime_encrypt_table[po->valid->encrypt.status].icon;
- icon = gtk_image_new_from_icon_name (
- icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
- gtk_widget_show(icon);
+ container = GTK_WIDGET (eb);
- button = gtk_button_new();
- g_signal_connect(button, "clicked", G_CALLBACK(efhd_xpkcs7mime_validity_clicked), pobject);
+ widget = gtk_button_new ();
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (efhd_xpkcs7mime_validity_clicked), pobject);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
- gtk_container_add((GtkContainer *)button, icon);
- gtk_widget_show(button);
- gtk_container_add((GtkContainer *)eb, button);
+ container = widget;
+
+ widget = gtk_image_new_from_icon_name (
+ icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
return TRUE;
}
static void
-efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
+efhd_format_clone (EMFormat *emf,
+ CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *msg,
+ EMFormat *src)
+{
+ if (emf != src)
+ EM_FORMAT_HTML (emf)->header_wrap_flags = 0;
+
+ /* Chain up to parent's format_clone() method. */
+ EM_FORMAT_CLASS (parent_class)->
+ format_clone (emf, folder, uid, msg, src);
+}
+
+static void
+efhd_format_attachment (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part,
+ const gchar *mime_type,
+ const EMFormatHandler *handle)
+{
+ gchar *classid, *text, *html;
+ struct _attach_puri *info;
+
+ classid = g_strdup_printf ("attachment%s", emf->part_id->str);
+ info = (struct _attach_puri *) em_format_add_puri (
+ emf, sizeof (*info), classid, part, efhd_attachment_frame);
+ em_format_html_add_pobject (
+ EM_FORMAT_HTML (emf), sizeof (EMFormatHTMLPObject),
+ classid, part, efhd_attachment_button);
+ info->handle = handle;
+ info->shown = em_format_is_inline (
+ emf, info->puri.part_id, info->puri.part, handle);
+ info->snoop_mime_type = emf->snoop_mime_type;
+ info->attachment = e_attachment_new ();
+ e_attachment_set_mime_part (info->attachment, info->puri.part);
+
+ if (emf->valid) {
+ info->sign = emf->valid->sign.status;
+ info->encrypt = emf->valid->encrypt.status;
+ }
+
+ camel_stream_write_string (
+ stream, EM_FORMAT_HTML_VPAD
+ "<table cellspacing=0 cellpadding=0><tr><td>"
+ "<table width=10 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td>");
+
+ camel_stream_printf (
+ stream, "<td><object classid=\"%s\"></object></td>", classid);
+
+ camel_stream_write_string (
+ stream, "<td><table width=3 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td><td><font size=-1>");
+
+ /* output some info about it */
+ /* FIXME: should we look up mime_type from object again? */
+ text = em_format_describe_part (part, mime_type);
+ html = camel_text_to_html (
+ text, EM_FORMAT_HTML (emf)->text_html_flags &
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
+ camel_stream_write_string (stream, html);
+ g_free (html);
+ g_free (text);
+
+ camel_stream_write_string (
+ stream, "</font></td></tr><tr></table>\n"
+ EM_FORMAT_HTML_VPAD);
+
+ if (handle && info->shown)
+ handle->handler (emf, stream, part, handle);
+
+ g_free (classid);
+}
+
+static void
+efhd_format_optional (EMFormat *emf,
+ CamelStream *fstream,
+ CamelMimePart *part,
+ CamelStream *mstream)
{
- /* Note: We call EMFormatClass directly, not EMFormatHTML, our parent */
- efhd_format_class->format_secure(emf, stream, part, valid);
+ gchar *classid, *html;
+ struct _attach_puri *info;
+ CamelStream *stream;
+
+ if (CAMEL_IS_STREAM_FILTER (fstream) && ((CamelStreamFilter *) fstream)->source)
+ stream = ((CamelStreamFilter *) fstream)->source;
+ else
+ stream = fstream;
+
+ classid = g_strdup_printf ("optional%s", emf->part_id->str);
+ info = (struct _attach_puri *) em_format_add_puri (
+ emf, sizeof (*info), classid, part, efhd_attachment_frame);
+ em_format_html_add_pobject (
+ EM_FORMAT_HTML (emf), sizeof (EMFormatHTMLPObject),
+ classid, part, efhd_attachment_optional);
+ info->handle = em_format_find_handler (emf, "text/plain");
+ info->shown = FALSE;
+ info->snoop_mime_type = "text/plain";
+ info->attachment = e_attachment_new ();
+ e_attachment_set_mime_part (info->attachment, info->puri.part);
+ info->mstream = (CamelStreamMem *) mstream;
+ if (emf->valid) {
+ info->sign = emf->valid->sign.status;
+ info->encrypt = emf->valid->encrypt.status;
+ }
+
+ camel_stream_write_string (
+ stream, EM_FORMAT_HTML_VPAD
+ "<table cellspacing=0 cellpadding=0><tr><td>"
+ "<h3><font size=-1 color=red>");
+
+ html = camel_text_to_html (
+ _("Evolution cannot render this email as it is too "
+ "large to process. You can view it unformatted or "
+ "with an external text editor."),
+ EM_FORMAT_HTML (emf)->text_html_flags &
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
+ camel_stream_write_string (stream, html);
+ camel_stream_write_string (
+ stream, "</font></h3></td></tr></table>\n");
+ camel_stream_write_string (
+ stream, "<table cellspacing=0 cellpadding=0><tr>");
+ camel_stream_printf (
+ stream, "<td><object classid=\"%s\"></object>"
+ "</td></tr></table>", classid);
+
+ g_free(html);
+
+ camel_stream_write_string (
+ stream, EM_FORMAT_HTML_VPAD);
+
+ g_free (classid);
+}
+
+static void
+efhd_format_secure (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part,
+ CamelCipherValidity *valid)
+{
+ EMFormatClass *format_class;
+
+ format_class = g_type_class_peek (EM_TYPE_FORMAT);
+ format_class->format_secure (emf, stream, part, valid);
if (emf->valid == valid
&& (valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE
@@ -828,24 +561,45 @@ efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Came
gchar *classid;
struct _smime_pobject *pobj;
- camel_stream_printf (stream, "<table border=0 width=\"100%%\" cellpadding=3 cellspacing=0%s><tr>",
- smime_sign_colour[valid->sign.status]);
-
- classid = g_strdup_printf("smime:///em-format-html/%s/icon/signed", emf->part_id->str);
- pobj = (struct _smime_pobject *)em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(*pobj), classid, part, efhd_xpkcs7mime_button);
+ camel_stream_printf (
+ stream, "<table border=0 width=\"100%%\" "
+ "cellpadding=3 cellspacing=0%s><tr>",
+ smime_sign_colour[valid->sign.status]);
+
+ classid = g_strdup_printf (
+ "smime:///em-format-html/%s/icon/signed",
+ emf->part_id->str);
+ pobj = (struct _smime_pobject *) em_format_html_add_pobject (
+ EM_FORMAT_HTML (emf), sizeof (*pobj),
+ classid, part, efhd_xpkcs7mime_button);
pobj->valid = camel_cipher_validity_clone(valid);
pobj->object.free = efhd_xpkcs7mime_free;
- camel_stream_printf(stream, "<td valign=center><object classid=\"%s\"></object></td><td width=100%% valign=center>", classid);
- g_free(classid);
+ camel_stream_printf (
+ stream, "<td valign=center><object classid=\"%s\">"
+ "</object></td><td width=100%% valign=center>",
+ classid);
+ g_free (classid);
+
if (valid->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
- camel_stream_printf (stream, "%s", _(smime_sign_table[valid->sign.status].shortdesc));
+ const gchar *desc;
+ gint status;
+
+ status = valid->sign.status;
+ desc = smime_sign_table[status].shortdesc;
+ camel_stream_printf (stream, "%s", gettext (desc));
}
if (valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) {
+ const gchar *desc;
+ gint status;
+
if (valid->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
camel_stream_printf (stream, "<br>");
}
- camel_stream_printf (stream, "%s", _(smime_encrypt_table[valid->encrypt.status].shortdesc));
+
+ status = valid->encrypt.status;
+ desc = smime_encrypt_table[status].shortdesc;
+ camel_stream_printf (stream, "%s", gettext (desc));
}
camel_stream_printf(stream, "</td></tr></table>");
@@ -853,6 +607,80 @@ efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Came
}
static void
+efhd_class_init (EMFormatHTMLDisplayClass *class)
+{
+ EMFormatClass *format_class;
+ EMFormatHTMLClass *format_html_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFormatHTMLDisplayPrivate));
+
+ format_class = EM_FORMAT_CLASS (class);
+ format_class->format_clone = efhd_format_clone;
+ format_class->format_attachment = efhd_format_attachment;
+ format_class->format_optional = efhd_format_optional;
+ format_class->format_secure = efhd_format_secure;
+
+ format_html_class = EM_FORMAT_HTML_CLASS (class);
+ format_html_class->html_widget_type = E_TYPE_MAIL_DISPLAY;
+
+ efhd_builtin_init (class);
+}
+
+static void
+efhd_init (EMFormatHTMLDisplay *efhd)
+{
+ GtkHTML *html;
+
+ html = EM_FORMAT_HTML (efhd)->html;
+
+ efhd->priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (efhd);
+
+ e_mail_display_set_formatter (
+ E_MAIL_DISPLAY (html), EM_FORMAT_HTML (efhd));
+
+ /* we want to convert url's etc */
+ EM_FORMAT_HTML (efhd)->text_html_flags |=
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
+}
+
+GType
+em_format_html_display_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFormatHTMLDisplayClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) efhd_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFormatHTMLDisplay),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) efhd_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ EM_TYPE_FORMAT_HTML, "EMFormatHTMLDisplay",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+EMFormatHTMLDisplay *
+em_format_html_display_new (void)
+{
+ return g_object_new (EM_TYPE_FORMAT_HTML_DISPLAY, NULL);
+}
+
+/* ********************************************************************** */
+
+static void
efhd_image(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatHandler *handle)
{
gchar *classid;
@@ -915,20 +743,6 @@ efhd_builtin_init(EMFormatHTMLDisplayClass *efhc)
em_format_class_add_handler((EMFormatClass *)efhc, &type_builtin_table[i]);
}
-static const EMFormatHandler *
-efhd_find_handler(EMFormat *emf, const gchar *mime_type)
-{
- return ((EMFormatClass *) efhd_parent)->find_handler (emf, mime_type);
-}
-
-static void efhd_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *src)
-{
- if (emf != src)
- ((EMFormatHTML *) emf)->header_wrap_flags = 0;
-
- ((EMFormatClass *)efhd_parent)->format_clone(emf, folder, uid, msg, src);
-}
-
static void
efhd_write_image(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
{
@@ -940,7 +754,8 @@ efhd_write_image(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
camel_stream_close(stream);
}
-static void efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
+static void
+efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
{
const gchar *flag, *comp, *due;
time_t date;
@@ -997,21 +812,11 @@ static void efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePar
camel_stream_printf(stream, "</td></tr></table>");
}
-/* TODO: if these aren't going to do anything should remove */
-static void efhd_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt)
-{
- ((EMFormatClass *)efhd_parent)->format_error(emf, stream, txt);
-}
-
-static void efhd_format_source(EMFormat *emf, CamelStream *stream, CamelMimePart *part)
-{
- ((EMFormatClass *)efhd_parent)->format_source(emf, stream, part);
-}
-
/* ********************************************************************** */
-/* Checks on the widget whether it can be processed, based on the state of EMFormatHTML.
- The widget should have set "efh" data as the EMFormatHTML instance. */
+/* Checks on the widget whether it can be processed, based on the
+ * state of EMFormatHTML. The widget should have set "efh" data as
+ * the EMFormatHTML instance. */
static gboolean
efhd_can_process_attachment (GtkWidget *button)
{
@@ -1025,18 +830,6 @@ efhd_can_process_attachment (GtkWidget *button)
return efh && efh->state != EM_FORMAT_HTML_STATE_RENDERING;
}
-/* if it hasn't been processed yet, format the attachment */
-static void
-efhd_attachment_show(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _attach_puri *info = data;
-
- d(printf("show attachment button called %p\n", info));
-
- info->shown = ~info->shown;
- em_format_set_inline(info->puri.format, info->puri.part_id, info->shown);
-}
-
static void
efhd_attachment_button_expanded (GtkWidget *widget,
GParamSpec *pspec,
@@ -1045,119 +838,9 @@ efhd_attachment_button_expanded (GtkWidget *widget,
if (!efhd_can_process_attachment (widget))
return;
- efhd_attachment_show (NULL, NULL, info);
-}
-
-static void
-efhd_image_fit(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _attach_puri *info = data;
-
- info->fit_width = ((GtkWidget *)((EMFormatHTML *)info->puri.format)->html)->allocation.width - 12;
- gtk_image_set_from_pixbuf(info->image, em_icon_stream_get_image(info->puri.cid, info->fit_width, info->fit_height));
-}
-
-static void
-efhd_image_unfit(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _attach_puri *info = data;
-
- info->fit_width = 0;
- gtk_image_set_from_pixbuf((GtkImage *)info->image, em_icon_stream_get_image(info->puri.cid, info->fit_width, info->fit_height));
-}
-
-static EPopupItem efhd_menu_items[] = {
- { E_POPUP_BAR, (gchar *) "05.display" },
- { E_POPUP_ITEM, (gchar *) "05.display.00", (gchar *) N_("_View Inline"), efhd_attachment_show },
- { E_POPUP_ITEM, (gchar *) "05.display.00", (gchar *) N_("_Hide"), efhd_attachment_show },
- { E_POPUP_ITEM, (gchar *) "05.display.01", (gchar *) N_("_Fit to Width"), efhd_image_fit, NULL, NULL, EM_POPUP_PART_IMAGE },
- { E_POPUP_ITEM, (gchar *) "05.display.01", (gchar *) N_("Show _Original Size"), efhd_image_unfit, NULL, NULL, EM_POPUP_PART_IMAGE },
-};
-
-static void
-efhd_menu_items_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static void
-efhd_popup_place_widget(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
-{
- GtkWidget *w = user_data;
-
- gdk_window_get_origin(gtk_widget_get_parent_window(w), x, y);
- *x += w->allocation.x + w->allocation.width;
- *y += w->allocation.y;
-}
-
-static gboolean
-efhd_attachment_popup(GtkWidget *w, GdkEventButton *event, struct _attach_puri *info)
-{
- GtkMenu *menu;
- GSList *menus = NULL;
- EMPopup *emp;
- EMPopupTargetPart *target;
-
- d(printf("attachment popup, button %d\n", event->button));
-
- if (event && event->button != 1 && event->button != 3) {
- /* ?? gtk_propagate_event(GTK_WIDGET (user_data), (GdkEvent *)event);*/
- return FALSE;
- }
-
- if (!efhd_can_process_attachment (w))
- return FALSE;
-
- /** @HookPoint-EMPopup: Attachment Button Context Menu
- * @Id: org.gnome.evolution.mail.formathtmldisplay.popup
- * @Class: org.gnome.evolution.mail.popup:1.0
- * @Target: EMPopupTargetPart
- *
- * This is the drop-down menu shown when a user clicks on the down arrow
- * of the attachment button in inline mail content.
- */
- emp = em_popup_new("org.gnome.evolution.mail.formathtmldisplay.popup");
- target = em_popup_target_new_part(emp, info->puri.part, info->handle?info->handle->mime_type:NULL);
- target->target.widget = w;
-
- /* add our local menus */
- if (info->handle) {
- /* show/hide menus, only if we have an inline handler */
- menus = g_slist_prepend(menus, &efhd_menu_items[0]);
- menus = g_slist_prepend(menus, &efhd_menu_items[info->shown?2:1]);
- if (info->shown && info->image) {
- if (info->fit_width != 0) {
- if (em_icon_stream_is_resized(info->puri.cid, info->fit_width, info->fit_height))
- menus = g_slist_prepend(menus, &efhd_menu_items[4]);
- } else
- menus = g_slist_prepend(menus, &efhd_menu_items[3]);
- }
- }
-
- e_popup_add_items((EPopup *)emp, menus, NULL, efhd_menu_items_free, info);
-
- menu = e_popup_create_menu_once((EPopup *)emp, (EPopupTarget *)target, 0);
- if (event)
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button, event->time);
- else
- gtk_menu_popup(menu, NULL, NULL, (GtkMenuPositionFunc)efhd_popup_place_widget, w, 0, gtk_get_current_event_time());
-
- return TRUE;
-}
-
-static gboolean
-efhd_image_popup(GtkWidget *w, GdkEventButton *event, struct _attach_puri *info)
-{
- if (event && event->button != 3)
- return FALSE;
-
- return efhd_attachment_popup(w, event, info);
-}
-
-static gboolean
-efhd_attachment_popup_menu(GtkWidget *w, struct _attach_puri *info)
-{
- return efhd_attachment_popup(w, NULL, info);
+ info->shown = ~info->shown;
+ em_format_set_inline (
+ info->puri.format, info->puri.part_id, info->shown);
}
/* ********************************************************************** */
@@ -1316,9 +999,7 @@ efhd_image_unallocate (struct _EMFormatPURI * puri)
struct _attach_puri *info = (struct _attach_puri *) puri;
g_signal_handlers_disconnect_by_func(info->html, efhd_image_resized, info);
- g_signal_handlers_disconnect_by_func(info->event_box, efhd_image_popup, info);
g_signal_handlers_disconnect_by_func(info->event_box, efhd_change_cursor, info);
- g_signal_handlers_disconnect_by_func(info->event_box, efhd_attachment_popup_menu, info);
g_signal_handlers_disconnect_by_func(info->event_box, efhd_image_fit_width, info);
}
@@ -1369,9 +1050,7 @@ efhd_attachment_image(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObjec
g_signal_connect(box, "drag-data-get", G_CALLBACK(efhd_drag_data_get), pobject);
g_signal_connect (box, "drag-data-delete", G_CALLBACK(efhd_drag_data_delete), pobject);
- g_signal_connect(box, "button_press_event", G_CALLBACK(efhd_image_popup), info);
g_signal_connect(box, "enter-notify-event", G_CALLBACK(efhd_change_cursor), info);
- g_signal_connect(box, "popup_menu", G_CALLBACK(efhd_attachment_popup_menu), info);
g_signal_connect(box, "button-press-event", G_CALLBACK(efhd_image_fit_width), info);
g_object_set_data (G_OBJECT (box), "efh", efh);
@@ -1435,38 +1114,35 @@ efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
return TRUE;
}
-/* not used currently */
-/* frame source callback */
static void
-efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
+efhd_attachment_frame (EMFormat *emf,
+ CamelStream *stream,
+ EMFormatPURI *puri)
{
struct _attach_puri *info = (struct _attach_puri *)puri;
- if (info->shown) {
- d(printf("writing to frame content, handler is '%s'\n", info->handle->mime_type));
- info->handle->handler(emf, stream, info->puri.part, info->handle);
- camel_stream_close(stream);
- } else {
- /* FIXME: this is leaked if the object is closed without showing it
- NB: need a virtual puri_free method? */
- info->output = stream;
- camel_object_ref(stream);
- }
+ if (info->shown)
+ info->handle->handler (
+ emf, stream, info->puri.part, info->handle);
+
+ camel_stream_close (stream);
}
static void
efhd_bar_resize (EMFormatHTML *efh,
GtkAllocation *event)
{
- EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) efh;
+ EMFormatHTMLDisplayPrivate *priv;
GtkWidget *widget;
gint width;
+ priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (efh);
+
widget = GTK_WIDGET (efh->html);
width = widget->allocation.width - 12;
if (width > 0) {
- widget = efhd->priv->attachment_view;
+ widget = priv->attachment_view;
gtk_widget_set_size_request (widget, width, -1);
}
}
@@ -1476,12 +1152,18 @@ efhd_add_bar (EMFormatHTML *efh,
GtkHTMLEmbedded *eb,
EMFormatHTMLPObject *pobject)
{
- EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) efh;
+ EMFormatHTMLDisplayPrivate *priv;
GtkWidget *widget;
+ /* XXX See note in efhd_message_add_bar(). */
+ if (!EM_IS_FORMAT_HTML_DISPLAY (efh))
+ return FALSE;
+
+ priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (efh);
+
widget = e_mail_attachment_bar_new ();
gtk_container_add (GTK_CONTAINER (eb), widget);
- efhd->priv->attachment_view = widget;
+ priv->attachment_view = widget;
gtk_widget_hide (widget);
g_signal_connect_swapped (
@@ -1499,8 +1181,12 @@ efhd_message_add_bar (EMFormat *emf,
{
const gchar *classid = "attachment-bar";
+ /* XXX Apparently this installs the callback for -all-
+ * EMFormatHTML subclasses, not just this subclass.
+ * Bad idea. So we have to filter out other types
+ * in the callback. */
em_format_html_add_pobject (
- (EMFormatHTML *) emf,
+ EM_FORMAT_HTML (emf),
sizeof (EMFormatHTMLPObject),
classid, part, efhd_add_bar);
@@ -1509,63 +1195,6 @@ efhd_message_add_bar (EMFormat *emf,
}
static void
-efhd_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type, const EMFormatHandler *handle)
-{
- gchar *classid, *text, *html;
- struct _attach_puri *info;
-
- classid = g_strdup_printf ("attachment%s", emf->part_id->str);
- info = (struct _attach_puri *)em_format_add_puri (
- emf, sizeof (*info), classid, part, efhd_attachment_frame);
- em_format_html_add_pobject (
- (EMFormatHTML *) emf, sizeof (EMFormatHTMLPObject),
- classid, part, efhd_attachment_button);
- info->handle = handle;
- info->shown = em_format_is_inline (
- emf, info->puri.part_id, info->puri.part, handle);
- info->snoop_mime_type = emf->snoop_mime_type;
- info->attachment = e_attachment_new ();
- e_attachment_set_mime_part (info->attachment, info->puri.part);
-
- if (emf->valid) {
- info->sign = emf->valid->sign.status;
- info->encrypt = emf->valid->encrypt.status;
- }
-
- camel_stream_write_string (
- stream, EM_FORMAT_HTML_VPAD
- "<table cellspacing=0 cellpadding=0><tr><td>"
- "<table width=10 cellspacing=0 cellpadding=0>"
- "<tr><td></td></tr></table></td>");
-
- camel_stream_printf (
- stream, "<td><object classid=\"%s\"></object></td>", classid);
-
- camel_stream_write_string (
- stream, "<td><table width=3 cellspacing=0 cellpadding=0>"
- "<tr><td></td></tr></table></td><td><font size=-1>");
-
- /* output some info about it */
- /* FIXME: should we look up mime_type from object again? */
- text = em_format_describe_part (part, mime_type);
- html = camel_text_to_html (
- text, ((EMFormatHTML *)emf)->text_html_flags &
- CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_write_string (stream, html);
- g_free (html);
- g_free (text);
-
- camel_stream_write_string (
- stream, "</font></td></tr><tr></table>\n"
- EM_FORMAT_HTML_VPAD);
-
- if (handle && info->shown)
- handle->handler(emf, stream, part, handle);
-
- g_free(classid);
-}
-
-static void
efhd_optional_button_show (GtkWidget *widget, GtkWidget *w)
{
GtkWidget *label = g_object_get_data (G_OBJECT (widget), "text-label");
@@ -1641,9 +1270,6 @@ efhd_attachment_optional(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPOb
a11y = gtk_widget_get_accessible (button);
atk_object_set_name (a11y, _("Attachment"));
- g_signal_connect(button, "button_press_event", G_CALLBACK(efhd_attachment_popup), info);
- g_signal_connect(button, "popup_menu", G_CALLBACK(efhd_attachment_popup_menu), info);
- g_signal_connect(button, "clicked", G_CALLBACK(efhd_attachment_popup_menu), info);
gtk_box_pack_start(GTK_BOX (mainbox), button, FALSE, FALSE, 6);
gtk_widget_show_all(mainbox);
@@ -1678,50 +1304,3 @@ efhd_attachment_optional(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPOb
return TRUE;
}
-static void
-efhd_format_optional(EMFormat *emf, CamelStream *fstream, CamelMimePart *part, CamelStream *mstream)
-{
- gchar *classid, *html;
- struct _attach_puri *info;
- CamelStream *stream;
-
- if (CAMEL_IS_STREAM_FILTER (fstream) && ((CamelStreamFilter *) fstream)->source)
- stream = ((CamelStreamFilter *) fstream)->source;
- else
- stream = fstream;
-
- classid = g_strdup_printf("optional%s", emf->part_id->str);
- info = (struct _attach_puri *)em_format_add_puri(emf, sizeof(*info), classid, part, efhd_attachment_frame);
- em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_attachment_optional);
- info->handle = em_format_find_handler(emf, "text/plain");
- info->shown = FALSE;
- info->snoop_mime_type = "text/plain";
- info->attachment = e_attachment_new ();
- e_attachment_set_mime_part (info->attachment, info->puri.part);
- info->mstream = (CamelStreamMem *)mstream;
- if (emf->valid) {
- info->sign = emf->valid->sign.status;
- info->encrypt = emf->valid->encrypt.status;
- }
-
- camel_stream_write_string(stream,
- EM_FORMAT_HTML_VPAD
- "<table cellspacing=0 cellpadding=0><tr><td><h3><font size=-1 color=red>");
-
- html = camel_text_to_html(_("Evolution cannot render this email as it is too large to process. You can view it unformatted or with an external text editor."), ((EMFormatHTML *)emf)->text_html_flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_write_string(stream, html);
- camel_stream_write_string(stream,
- "</font></h3></td></tr></table>\n");
- camel_stream_write_string(stream,
- "<table cellspacing=0 cellpadding=0>"
- "<tr>");
- camel_stream_printf(stream, "<td><object classid=\"%s\"></object></td></tr></table>", classid);
-
- g_free(html);
-
- camel_stream_write_string(stream,
-/* "</font></h2></td></tr></table>\n" */
- EM_FORMAT_HTML_VPAD);
-
- g_free(classid);
-}
diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h
index d85809f0b0..4626598cb5 100644
--- a/mail/em-format-html-display.h
+++ b/mail/em-format-html-display.h
@@ -53,70 +53,20 @@ typedef struct _EMFormatHTMLDisplayClass EMFormatHTMLDisplayClass;
typedef struct _EMFormatHTMLDisplayPrivate EMFormatHTMLDisplayPrivate;
struct _EMFormatHTMLDisplay {
- EMFormatHTML formathtml;
-
+ EMFormatHTML parent;
EMFormatHTMLDisplayPrivate *priv;
struct _ESearchingTokenizer *search_tok;
-
- guint animate:1;
- guint caret_mode:1;
- guint nobar:1;
};
-#define EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY (0)
-#define EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY (1)
-#define EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE (1<<8)
-
struct _EMFormatHTMLDisplayClass {
- EMFormatHTMLClass formathtml_class;
-
- /* a link clicked normally */
- void (*link_clicked)(EMFormatHTMLDisplay *efhd, const gchar *uri);
- /* a part or a link button pressed event */
- gint (*popup_event)(EMFormatHTMLDisplay *efhd, GdkEventButton *event, const gchar *uri, CamelMimePart *part);
- /* the mouse is over a link */
- void (*on_url)(EMFormatHTMLDisplay *efhd, const gchar *uri);
+ EMFormatHTMLClass parent_class;
};
GType em_format_html_display_get_type (void);
EMFormatHTMLDisplay *
em_format_html_display_new (void);
-void em_format_html_display_goto_anchor
- (EMFormatHTMLDisplay *efhd,
- const gchar *name);
-
-void em_format_html_display_set_animate
- (EMFormatHTMLDisplay *efhd,
- gboolean state);
-void em_format_html_display_set_caret_mode
- (EMFormatHTMLDisplay *efhd,
- gboolean state);
-
-void em_format_html_display_set_search
- (EMFormatHTMLDisplay *efhd,
- gint type,
- GSList *strings);
-void em_format_html_display_search (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_search_with
- (EMFormatHTMLDisplay *efhd,
- gchar *word);
-void em_format_html_display_search_close
- (EMFormatHTMLDisplay *efhd);
-
-void em_format_html_display_cut (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_copy (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_paste (EMFormatHTMLDisplay *efhd);
-
-void em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_zoom_reset
- (EMFormatHTMLDisplay *efhd);
-
-gboolean em_format_html_display_popup_menu
- (EMFormatHTMLDisplay *efhd);
-
G_END_DECLS
#endif /* EM_FORMAT_HTML_DISPLAY_H */
diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c
index 86242b1467..fb9b1a74a5 100644
--- a/mail/em-format-html-print.c
+++ b/mail/em-format-html-print.c
@@ -38,22 +38,27 @@
static gpointer parent_class = NULL;
static void
-efhp_finalize (GObject *o)
+efhp_finalize (GObject *object)
{
- EMFormatHTMLPrint *efhp = (EMFormatHTMLPrint *)o;
+ EMFormatHTMLPrint *efhp = (EMFormatHTMLPrint *)object;
gtk_widget_destroy (efhp->window);
if (efhp->source != NULL)
g_object_unref (efhp->source);
- ((GObjectClass *) parent_class)->finalize (o);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-efhp_class_init (GObjectClass *class)
+efhp_class_init (EMFormatHTMLPrintClass *class)
{
+ GObjectClass *object_class;
+
parent_class = g_type_class_peek_parent (class);
- class->finalize = efhp_finalize;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = efhp_finalize;
}
static void
@@ -93,7 +98,7 @@ em_format_html_print_get_type (void)
};
type = g_type_register_static (
- em_format_html_get_type (), "EMFormatHTMLPrint",
+ EM_TYPE_FORMAT_HTML, "EMFormatHTMLPrint",
&type_info, 0);
}
@@ -101,7 +106,8 @@ em_format_html_print_get_type (void)
}
EMFormatHTMLPrint *
-em_format_html_print_new (EMFormatHTML *source, GtkPrintOperationAction action)
+em_format_html_print_new (EMFormatHTML *source,
+ GtkPrintOperationAction action)
{
EMFormatHTMLPrint *efhp;
@@ -210,9 +216,7 @@ emfhp_got_message (CamelFolder *folder, const gchar *uid,
return;
}
- if (efhp->source != NULL)
- ((EMFormatHTML *)efhp)->load_http =
- efhp->source->load_http_now;
+ em_format_html_load_images (EM_FORMAT_HTML (efhp));
g_signal_connect (
efhp, "complete", G_CALLBACK (emfhp_complete), efhp);
@@ -229,9 +233,10 @@ em_format_html_print_message (EMFormatHTMLPrint *efhp,
g_object_ref (efhp);
/* Wrap flags to display all entries by default.*/
- ((EMFormatHTML *) efhp)->header_wrap_flags |= EM_FORMAT_HTML_HEADER_TO
- | EM_FORMAT_HTML_HEADER_CC
- | EM_FORMAT_HTML_HEADER_BCC;
+ EM_FORMAT_HTML (efhp)->header_wrap_flags |=
+ EM_FORMAT_HTML_HEADER_TO |
+ EM_FORMAT_HTML_HEADER_CC |
+ EM_FORMAT_HTML_HEADER_BCC;
mail_get_message (
folder, uid, emfhp_got_message, efhp, mail_msg_unordered_push);
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 038ca4b61b..b9657a1fd9 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -49,7 +49,6 @@
#include "e-util/e-util.h"
#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-embedded.h>
#include <gtkhtml/gtkhtml-stream.h>
#include <glib/gi18n.h>
@@ -75,7 +74,6 @@
#include <libedataserver/e-msgport.h>
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-mt.h"
@@ -85,6 +83,10 @@
#define d(x)
+#define EM_FORMAT_HTML_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FORMAT_HTML, EMFormatHTMLPrivate))
+
#define EFM_MESSAGE_START_ANAME "evolution#message#start"
#define EFH_MESSAGE_START "<A name=\"" EFM_MESSAGE_START_ANAME "\"></A>"
@@ -105,6 +107,27 @@ struct _EMFormatHTMLPrivate {
EDList pending_jobs;
GMutex *lock;
+
+ GdkColor colors[EM_FORMAT_HTML_NUM_COLOR_TYPES];
+ MailConfigHTTPMode image_loading_policy;
+
+ guint load_images_now : 1;
+ guint only_local_photos : 1;
+ guint show_sender_photo : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_BODY_COLOR,
+ PROP_CITATION_COLOR,
+ PROP_CONTENT_COLOR,
+ PROP_FRAME_COLOR,
+ PROP_HEADER_COLOR,
+ PROP_IMAGE_LOADING_POLICY,
+ PROP_MARK_CITATIONS,
+ PROP_ONLY_LOCAL_PHOTOS,
+ PROP_SHOW_SENDER_PHOTO,
+ PROP_TEXT_COLOR
};
static void efh_url_requested(GtkHTML *html, const gchar *url, GtkHTMLStream *handle, EMFormatHTML *efh);
@@ -113,67 +136,243 @@ static void efh_gtkhtml_destroy(GtkHTML *html, EMFormatHTML *efh);
static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info);
-static void efh_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource);
-static void efh_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt);
-static void efh_format_source(EMFormat *, CamelStream *, CamelMimePart *);
-static void efh_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const gchar *, const EMFormatHandler *);
static void efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
-static gboolean efh_busy(EMFormat *);
static void efh_builtin_init(EMFormatHTMLClass *efhc);
static void efh_write_image(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri);
-static EMFormatClass *efh_parent;
+static gpointer parent_class;
static CamelDataCache *emfh_http_cache;
#define EMFH_HTTP_CACHE_PATH "http"
+/* Sigh, this is so we have a cancellable, async rendering thread */
+struct _format_msg {
+ MailMsg base;
+
+ EMFormatHTML *format;
+ EMFormat *format_source;
+ EMHTMLStream *estream;
+ CamelFolder *folder;
+ gchar *uid;
+ CamelMimeMessage *message;
+};
+
+static gchar *
+efh_format_desc (struct _format_msg *m)
+{
+ return g_strdup(_("Formatting message"));
+}
+
static void
-efh_free_cache(struct _EMFormatHTMLCache *efhc)
+efh_format_exec (struct _format_msg *m)
{
- if (efhc->textmp)
- camel_object_unref(efhc->textmp);
- g_free(efhc);
+ struct _EMFormatHTMLJob *job;
+ struct _EMFormatPURITree *puri_level;
+ gint cancelled = FALSE;
+ CamelURL *base;
+
+ if (m->format->html == NULL)
+ return;
+
+ camel_stream_printf (
+ (CamelStream *)m->estream,
+ "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n"
+ "<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\">\n</head>\n"
+ "<body bgcolor =\"#%06x\" text=\"#%06x\" marginwidth=6 marginheight=6>\n",
+ e_color_to_value (
+ &m->format->priv->colors[
+ EM_FORMAT_HTML_COLOR_BODY]),
+ e_color_to_value (
+ &m->format->priv->colors[
+ EM_FORMAT_HTML_COLOR_HEADER]));
+
+ /* <insert top-header stuff here> */
+
+ if (((EMFormat *)m->format)->mode == EM_FORMAT_SOURCE) {
+ em_format_format_source((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message);
+ } else {
+ const EMFormatHandler *handle;
+
+ handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/prefix");
+ if (handle)
+ handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
+ handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/rfc822");
+ if (handle)
+ handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
+ }
+
+ camel_stream_flush((CamelStream *)m->estream);
+
+ puri_level = ((EMFormat *)m->format)->pending_uri_level;
+ base = ((EMFormat *)m->format)->base;
+
+ do {
+ /* now dispatch any added tasks ... */
+ g_mutex_lock(m->format->priv->lock);
+ while ((job = (struct _EMFormatHTMLJob *)e_dlist_remhead(&m->format->priv->pending_jobs))) {
+ g_mutex_unlock(m->format->priv->lock);
+
+ /* This is an implicit check to see if the gtkhtml has been destroyed */
+ if (!cancelled)
+ cancelled = m->format->html == NULL;
+
+ /* Now do an explicit check for user cancellation */
+ if (!cancelled)
+ cancelled = camel_operation_cancel_check(NULL);
+
+ /* call jobs even if cancelled, so they can clean up resources */
+ ((EMFormat *)m->format)->pending_uri_level = job->puri_level;
+ if (job->base)
+ ((EMFormat *)m->format)->base = job->base;
+ job->callback(job, cancelled);
+ ((EMFormat *)m->format)->base = base;
+
+ /* clean up the job */
+ camel_object_unref(job->stream);
+ if (job->base)
+ camel_url_free(job->base);
+ g_free(job);
+
+ g_mutex_lock(m->format->priv->lock);
+ }
+ g_mutex_unlock(m->format->priv->lock);
+
+ if (m->estream) {
+ /* Closing this base stream can queue more jobs, so we need
+ to check the list again after we've finished */
+ d(printf("out of jobs, closing root stream\n"));
+ camel_stream_write_string((CamelStream *)m->estream, "</body>\n</html>\n");
+ camel_stream_close((CamelStream *)m->estream);
+ camel_object_unref(m->estream);
+ m->estream = NULL;
+ }
+
+ /* e_dlist_empty is atomic and doesn't need locking */
+ } while (!e_dlist_empty(&m->format->priv->pending_jobs));
+
+ d(printf("out of jobs, done\n"));
+
+ ((EMFormat *)m->format)->pending_uri_level = puri_level;
}
static void
-efh_init(GObject *o)
+efh_format_done (struct _format_msg *m)
{
- EMFormatHTML *efh = (EMFormatHTML *)o;
+ d(printf("formatting finished\n"));
- efh->priv = g_malloc0(sizeof(*efh->priv));
+ m->format->priv->format_id = -1;
+ m->format->priv->load_images_now = FALSE;
+ m->format->state = EM_FORMAT_HTML_STATE_NONE;
+ g_signal_emit_by_name(m->format, "complete");
+}
- e_dlist_init(&efh->pending_object_list);
- e_dlist_init(&efh->priv->pending_jobs);
- efh->priv->lock = g_mutex_new();
- efh->priv->format_id = -1;
- efh->priv->text_inline_parts = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) efh_free_cache);
+static void
+efh_format_free (struct _format_msg *m)
+{
+ d(printf("formatter freed\n"));
+ g_object_unref(m->format);
+ if (m->estream) {
+ camel_stream_close((CamelStream *)m->estream);
+ camel_object_unref(m->estream);
+ }
+ if (m->folder)
+ camel_object_unref(m->folder);
+ g_free(m->uid);
+ if (m->message)
+ camel_object_unref(m->message);
+ if (m->format_source)
+ g_object_unref(m->format_source);
+}
- efh->html = (GtkHTML *)gtk_html_new();
- gtk_html_set_blocking(efh->html, FALSE);
- gtk_html_set_caret_first_focus_anchor (efh->html, EFM_MESSAGE_START_ANAME);
- g_object_ref_sink(efh->html);
-
- gtk_html_set_default_content_type(efh->html, "text/html; charset=utf-8");
- gtk_html_set_editable(efh->html, FALSE);
-
- g_signal_connect(efh->html, "destroy", G_CALLBACK(efh_gtkhtml_destroy), efh);
- g_signal_connect(efh->html, "url_requested", G_CALLBACK(efh_url_requested), efh);
- g_signal_connect(efh->html, "object_requested", G_CALLBACK(efh_object_requested), efh);
-
- efh->body_colour = 0xeeeeee;
- efh->header_colour = 0xeeeeee;
- efh->text_colour = 0;
- efh->frame_colour = 0x3f3f3f;
- efh->content_colour = 0xffffff;
- efh->text_html_flags = CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES
- | CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
- efh->show_icon = TRUE;
- efh->state = EM_FORMAT_HTML_STATE_NONE;
+static MailMsgInfo efh_format_info = {
+ sizeof (struct _format_msg),
+ (MailMsgDescFunc) efh_format_desc,
+ (MailMsgExecFunc) efh_format_exec,
+ (MailMsgDoneFunc) efh_format_done,
+ (MailMsgFreeFunc) efh_format_free
+};
+
+static gboolean
+efh_format_timeout(struct _format_msg *m)
+{
+ GtkHTMLStream *hstream;
+ EMFormatHTML *efh = m->format;
+ struct _EMFormatHTMLPrivate *p = efh->priv;
+
+ if (m->format->html == NULL) {
+ mail_msg_unref(m);
+ return FALSE;
+ }
+
+ d(printf("timeout called ...\n"));
+ if (p->format_id != -1) {
+ d(printf(" still waiting for cancellation to take effect, waiting ...\n"));
+ return TRUE;
+ }
+
+ g_return_val_if_fail (e_dlist_empty(&p->pending_jobs), FALSE);
+
+ d(printf(" ready to go, firing off format thread\n"));
+
+ /* call super-class to kick it off */
+ EM_FORMAT_CLASS (parent_class)->format_clone (
+ EM_FORMAT (efh), m->folder, m->uid,
+ m->message, m->format_source);
+ em_format_html_clear_pobject(m->format);
+
+ /* FIXME: method off EMFormat? */
+ if (((EMFormat *)efh)->valid) {
+ camel_cipher_validity_free(((EMFormat *)efh)->valid);
+ ((EMFormat *)efh)->valid = NULL;
+ ((EMFormat *)efh)->valid_parent = NULL;
+ }
+
+ if (m->message == NULL) {
+ hstream = gtk_html_begin(efh->html);
+ gtk_html_stream_close(hstream, GTK_HTML_STREAM_OK);
+ mail_msg_unref(m);
+ p->last_part = NULL;
+ } else {
+ efh->state = EM_FORMAT_HTML_STATE_RENDERING;
+
+ if (p->last_part != m->message) {
+ hstream = gtk_html_begin (efh->html);
+ gtk_html_stream_printf (hstream, "<h5>%s</h5>", _("Formatting Message..."));
+ gtk_html_stream_close (hstream, GTK_HTML_STREAM_OK);
+ }
+
+ hstream = NULL;
+ m->estream = (EMHTMLStream *)em_html_stream_new(efh->html, hstream);
+
+ if (p->last_part == m->message) {
+ em_html_stream_set_flags (m->estream,
+ GTK_HTML_BEGIN_KEEP_SCROLL | GTK_HTML_BEGIN_KEEP_IMAGES
+ | GTK_HTML_BEGIN_BLOCK_UPDATES | GTK_HTML_BEGIN_BLOCK_IMAGES);
+ } else {
+ /* clear cache of inline-scanned text parts */
+ g_hash_table_remove_all(p->text_inline_parts);
+
+ p->last_part = m->message;
+ }
+
+ efh->priv->format_id = m->base.seq;
+ mail_msg_unordered_push (m);
+ }
+
+ efh->priv->format_timeout_id = 0;
+ efh->priv->format_timeout_msg = NULL;
+
+ return FALSE;
+}
+
+static void
+efh_free_cache(struct _EMFormatHTMLCache *efhc)
+{
+ if (efhc->textmp)
+ camel_object_unref(efhc->textmp);
+ g_free(efhc);
}
static void
@@ -190,8 +389,8 @@ efh_gtkhtml_destroy(GtkHTML *html, EMFormatHTML *efh)
if (efh->priv->format_id != -1)
mail_msg_cancel(efh->priv->format_id);
- if (efh->html) {
- g_object_unref(efh->html);
+ if (efh->html != NULL) {
+ g_object_unref (efh->html);
efh->html = NULL;
}
}
@@ -209,122 +408,719 @@ efh_insert_cache(EMFormatHTML *efh, const gchar *partid)
}
static void
-efh_finalise(GObject *o)
+efh_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_BODY_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_BODY,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_CITATION_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_CITATION,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_CONTENT_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_CONTENT,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_FRAME_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_FRAME,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_HEADER_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_HEADER,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_IMAGE_LOADING_POLICY:
+ em_format_html_set_image_loading_policy (
+ EM_FORMAT_HTML (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_MARK_CITATIONS:
+ em_format_html_set_mark_citations (
+ EM_FORMAT_HTML (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_ONLY_LOCAL_PHOTOS:
+ em_format_html_set_only_local_photos (
+ EM_FORMAT_HTML (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SHOW_SENDER_PHOTO:
+ em_format_html_set_show_sender_photo (
+ EM_FORMAT_HTML (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_TEXT_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_TEXT,
+ g_value_get_boxed (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+efh_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdkColor color;
+
+ switch (property_id) {
+ case PROP_BODY_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_BODY,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_CITATION_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_CITATION,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_CONTENT_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_CONTENT,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_FRAME_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_FRAME,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_HEADER_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_HEADER,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_IMAGE_LOADING_POLICY:
+ g_value_set_int (
+ value,
+ em_format_html_get_image_loading_policy (
+ EM_FORMAT_HTML (object)));
+ return;
+
+ case PROP_MARK_CITATIONS:
+ g_value_set_boolean (
+ value, em_format_html_get_mark_citations (
+ EM_FORMAT_HTML (object)));
+ return;
+
+ case PROP_ONLY_LOCAL_PHOTOS:
+ g_value_set_boolean (
+ value, em_format_html_get_only_local_photos (
+ EM_FORMAT_HTML (object)));
+ return;
+
+ case PROP_SHOW_SENDER_PHOTO:
+ g_value_set_boolean (
+ value, em_format_html_get_show_sender_photo (
+ EM_FORMAT_HTML (object)));
+ return;
+
+ case PROP_TEXT_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_TEXT,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+efh_finalize (GObject *object)
{
- EMFormatHTML *efh = (EMFormatHTML *)o;
+ EMFormatHTML *efh = EM_FORMAT_HTML (object);
/* FIXME: check for leaked stuff */
- em_format_html_clear_pobject(efh);
+ em_format_html_clear_pobject (efh);
+ efh_gtkhtml_destroy (efh->html, efh);
+
+ g_hash_table_destroy (efh->priv->text_inline_parts);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+efh_format_clone (EMFormat *emf,
+ CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *msg,
+ EMFormat *emfsource)
+{
+ EMFormatHTML *efh = EM_FORMAT_HTML (emf);
+ struct _format_msg *m;
- efh_gtkhtml_destroy(efh->html, efh);
+ /* How to sub-class ? Might need to adjust api ... */
- g_hash_table_destroy(efh->priv->text_inline_parts);
+ if (efh->html == NULL)
+ return;
+
+ d(printf("efh_format called\n"));
+ if (efh->priv->format_timeout_id != 0) {
+ d(printf(" timeout for last still active, removing ...\n"));
+ g_source_remove(efh->priv->format_timeout_id);
+ efh->priv->format_timeout_id = 0;
+ mail_msg_unref(efh->priv->format_timeout_msg);
+ efh->priv->format_timeout_msg = NULL;
+ }
- g_free(efh->priv);
+ if (emfsource != NULL)
+ g_object_ref (emfsource);
- ((GObjectClass *)efh_parent)->finalize(o);
+ if (folder != NULL)
+ camel_object_ref (folder);
+
+ if (msg != NULL)
+ camel_object_ref (msg);
+
+ m = mail_msg_new (&efh_format_info);
+ m->format = g_object_ref (emf);
+ m->format_source = emfsource;
+ m->folder = folder;
+ m->uid = g_strdup (uid);
+ m->message = msg;
+
+ if (efh->priv->format_id == -1) {
+ d(printf(" idle, forcing format\n"));
+ efh_format_timeout (m);
+ } else {
+ d(printf(" still busy, cancelling and queuing wait\n"));
+ /* cancel and poll for completion */
+ mail_msg_cancel (efh->priv->format_id);
+ efh->priv->format_timeout_msg = m;
+ efh->priv->format_timeout_id = g_timeout_add (
+ 100, (GSourceFunc) efh_format_timeout, m);
+ }
}
static void
-efh_base_init(EMFormatHTMLClass *efhklass)
+efh_format_error (EMFormat *emf,
+ CamelStream *stream,
+ const gchar *txt)
{
- efh_builtin_init(efhklass);
+ gchar *html;
+
+ html = camel_text_to_html (
+ txt, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
+ camel_stream_printf (
+ stream, "<em><font color=\"red\">%s</font></em><br>", html);
+ g_free (html);
}
static void
-efh_class_init(GObjectClass *klass)
+efh_format_source (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part)
{
- ((EMFormatClass *)klass)->format_clone = efh_format_clone;
- ((EMFormatClass *)klass)->format_error = efh_format_error;
- ((EMFormatClass *)klass)->format_source = efh_format_source;
- ((EMFormatClass *)klass)->format_attachment = efh_format_attachment;
- ((EMFormatClass *)klass)->format_secure = efh_format_secure;
- ((EMFormatClass *)klass)->busy = efh_busy;
-
- klass->finalize = efh_finalise;
+ CamelStreamFilter *filtered_stream;
+ CamelMimeFilter *filter;
+ CamelDataWrapper *dw = (CamelDataWrapper *) part;
+
+ filtered_stream = camel_stream_filter_new_with_stream (stream);
+
+ filter = camel_mime_filter_tohtml_new (
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES |
+ CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT, 0);
+ camel_stream_filter_add (filtered_stream, filter);
+ camel_object_unref (filter);
+
+ camel_stream_write_string (stream, "<table><tr><td><tt>");
+ em_format_format_text (emf, (CamelStream *) filtered_stream, dw);
+ camel_object_unref (filtered_stream);
+
+ camel_stream_write_string(stream, "</tt></td></tr></table>");
+}
+
+static void
+efh_format_attachment (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part,
+ const gchar *mime_type,
+ const EMFormatHandler *handle)
+{
+ gchar *text, *html;
+
+ /* we display all inlined attachments only */
+
+ /* this could probably be cleaned up ... */
+ camel_stream_write_string (
+ stream,
+ "<table border=1 cellspacing=0 cellpadding=0><tr><td>"
+ "<table width=10 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td>"
+ "<td><table width=3 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td><td><font size=-1>\n");
+
+ /* output some info about it */
+ text = em_format_describe_part(part, mime_type);
+ html = camel_text_to_html (
+ text, ((EMFormatHTML *)emf)->text_html_flags &
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
+ camel_stream_write_string (stream, html);
+ g_free (html);
+ g_free (text);
+
+ camel_stream_write_string (stream, "</font></td></tr><tr></table>");
+
+ if (handle && em_format_is_inline (emf, emf->part_id->str, part, handle))
+ handle->handler (emf, stream, part, handle);
+}
+
+static gboolean
+efh_busy (EMFormat *emf)
+{
+ EMFormatHTMLPrivate *priv;
+
+ priv = EM_FORMAT_HTML_GET_PRIVATE (emf);
+
+ return (priv->format_id != -1);
+}
+static void
+efh_base_init (EMFormatHTMLClass *class)
+{
+ efh_builtin_init (class);
+}
+
+static void
+efh_class_init (EMFormatHTMLClass *class)
+{
+ GObjectClass *object_class;
+ EMFormatClass *format_class;
+ gchar *pathname;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFormatHTMLPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = efh_set_property;
+ object_class->get_property = efh_get_property;
+ object_class->finalize = efh_finalize;
+
+ format_class = EM_FORMAT_CLASS (class);
+ format_class->format_clone = efh_format_clone;
+ format_class->format_error = efh_format_error;
+ format_class->format_source = efh_format_source;
+ format_class->format_attachment = efh_format_attachment;
+ format_class->format_secure = efh_format_secure;
+ format_class->busy = efh_busy;
+
+ class->html_widget_type = GTK_TYPE_HTML;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_BODY_COLOR,
+ g_param_spec_boxed (
+ "body-color",
+ "Body Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CITATION_COLOR,
+ g_param_spec_boxed (
+ "citation-color",
+ "Citation Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTENT_COLOR,
+ g_param_spec_boxed (
+ "content-color",
+ "Content Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FRAME_COLOR,
+ g_param_spec_boxed (
+ "frame-color",
+ "Frame Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HEADER_COLOR,
+ g_param_spec_boxed (
+ "header-color",
+ "Header Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ /* FIXME Make this a proper enum property. */
+ g_object_class_install_property (
+ object_class,
+ PROP_IMAGE_LOADING_POLICY,
+ g_param_spec_int (
+ "image-loading-policy",
+ "Image Loading Policy",
+ NULL,
+ 0,
+ G_MAXINT,
+ MAIL_CONFIG_HTTP_ALWAYS,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MARK_CITATIONS,
+ g_param_spec_boolean (
+ "mark-citations",
+ "Mark Citations",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ONLY_LOCAL_PHOTOS,
+ g_param_spec_boolean (
+ "only-local-photos",
+ "Only Local Photos",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_SENDER_PHOTO,
+ g_param_spec_boolean (
+ "show-sender-photo",
+ "Show Sender Photo",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TEXT_COLOR,
+ g_param_spec_boxed (
+ "text-color",
+ "Text Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ /* cache expiry - 2 hour access, 1 day max */
+ pathname = g_build_filename (
+ e_get_user_data_dir (), "cache", NULL);
+ emfh_http_cache = camel_data_cache_new (pathname, 0, NULL);
+ if (emfh_http_cache) {
+ camel_data_cache_set_expire_age(emfh_http_cache, 24*60*60);
+ camel_data_cache_set_expire_access(emfh_http_cache, 2*60*60);
+ }
+ g_free (pathname);
+}
+
+static void
+efh_init (EMFormatHTML *efh,
+ EMFormatHTMLClass *class)
+{
+ GtkHTML *html;
+ GdkColor *color;
+
+ efh->priv = EM_FORMAT_HTML_GET_PRIVATE (efh);
+
+ e_dlist_init(&efh->pending_object_list);
+ e_dlist_init(&efh->priv->pending_jobs);
+ efh->priv->lock = g_mutex_new();
+ efh->priv->format_id = -1;
+ efh->priv->text_inline_parts = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) efh_free_cache);
+
+ html = g_object_new (class->html_widget_type, NULL);
+ efh->html = g_object_ref_sink (html);
+
+ gtk_html_set_blocking (html, FALSE);
+ gtk_html_set_caret_first_focus_anchor (html, EFM_MESSAGE_START_ANAME);
+ gtk_html_set_default_content_type (html, "text/html; charset=utf-8");
+ gtk_html_set_editable (html, FALSE);
+
+ g_signal_connect (
+ html, "url-requested",
+ G_CALLBACK (efh_url_requested), efh);
+ g_signal_connect (
+ html, "object-requested",
+ G_CALLBACK (efh_object_requested), efh);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_BODY];
+ gdk_color_parse ("#eeeeee", color);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_CONTENT];
+ gdk_color_parse ("#ffffff", color);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_FRAME];
+ gdk_color_parse ("#3f3f3f", color);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_HEADER];
+ gdk_color_parse ("#eeeeee", color);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_TEXT];
+ gdk_color_parse ("#000000", color);
+
+ efh->text_html_flags =
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES |
+ CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+ efh->show_icon = TRUE;
+ efh->state = EM_FORMAT_HTML_STATE_NONE;
+
+ g_signal_connect_swapped (
+ efh, "notify::mark-citations",
+ G_CALLBACK (em_format_redraw), NULL);
}
GType
-em_format_html_get_type(void)
+em_format_html_get_type (void)
{
static GType type = 0;
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFormatHTMLClass),
- (GBaseInitFunc)efh_base_init, NULL,
- (GClassInitFunc)efh_class_init,
- NULL, NULL,
- sizeof(EMFormatHTML), 0,
- (GInstanceInitFunc)efh_init
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFormatHTMLClass),
+ (GBaseInitFunc) efh_base_init,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) efh_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFormatHTML),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) efh_init,
+ NULL /* value_table */
};
- const gchar *base_directory = e_get_user_data_dir ();
- gchar *path;
-
- /* Trigger creation of mail component. */
- mail_component_peek ();
- efh_parent = g_type_class_ref(em_format_get_type());
- type = g_type_register_static(em_format_get_type(), "EMFormatHTML", &info, 0);
-
- /* cache expiry - 2 hour access, 1 day max */
- path = alloca(strlen(base_directory)+16);
- sprintf(path, "%s/cache", base_directory);
- emfh_http_cache = camel_data_cache_new(path, 0, NULL);
- if (emfh_http_cache) {
- camel_data_cache_set_expire_age(emfh_http_cache, 24*60*60);
- camel_data_cache_set_expire_access(emfh_http_cache, 2*60*60);
- }
+ type = g_type_register_static (
+ em_format_get_type(), "EMFormatHTML",
+ &type_info, G_TYPE_FLAG_ABSTRACT);
}
return type;
}
-EMFormatHTML *em_format_html_new(void)
+void
+em_format_html_load_images (EMFormatHTML *efh)
{
- EMFormatHTML *efh;
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
- efh = g_object_new(em_format_html_get_type(), NULL);
+ if (efh->priv->image_loading_policy == MAIL_CONFIG_HTTP_ALWAYS)
+ return;
- return efh;
+ /* This will remain set while we're still
+ * rendering the same message, then it wont be. */
+ efh->priv->load_images_now = TRUE;
+ em_format_redraw (EM_FORMAT (efh));
}
-/* force loading of http images */
-void em_format_html_load_http(EMFormatHTML *emfh)
+void
+em_format_html_get_color (EMFormatHTML *efh,
+ EMFormatHTMLColorType type,
+ GdkColor *color)
{
- if (emfh->load_http == MAIL_CONFIG_HTTP_ALWAYS)
- return;
+ GdkColor *format_color;
- /* This will remain set while we're still rendering the same message, then it wont be */
- emfh->load_http_now = TRUE;
- d(printf("redrawing with images forced on\n"));
- em_format_redraw((EMFormat *)emfh);
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+ g_return_if_fail (type < EM_FORMAT_HTML_NUM_COLOR_TYPES);
+ g_return_if_fail (color != NULL);
+
+ format_color = &efh->priv->colors[type];
+
+ color->red = format_color->red;
+ color->green = format_color->green;
+ color->blue = format_color->blue;
}
void
-em_format_html_set_load_http(EMFormatHTML *emfh, gint style)
+em_format_html_set_color (EMFormatHTML *efh,
+ EMFormatHTMLColorType type,
+ const GdkColor *color)
{
- if (emfh->load_http != style) {
- emfh->load_http = style;
- em_format_redraw((EMFormat *)emfh);
+ GdkColor *format_color;
+ const gchar *property_name;
+
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+ g_return_if_fail (type < EM_FORMAT_HTML_NUM_COLOR_TYPES);
+ g_return_if_fail (color != NULL);
+
+ format_color = &efh->priv->colors[type];
+
+ if (gdk_color_equal (color, format_color))
+ return;
+
+ format_color->red = color->red;
+ format_color->green = color->green;
+ format_color->blue = color->blue;
+
+ switch (type) {
+ case EM_FORMAT_HTML_COLOR_BODY:
+ property_name = "body-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_CITATION:
+ property_name = "citation-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_CONTENT:
+ property_name = "content-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_FRAME:
+ property_name = "frame-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_HEADER:
+ property_name = "header-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_TEXT:
+ property_name = "text-color";
+ break;
+ default:
+ g_return_if_reached ();
}
+
+ g_object_notify (G_OBJECT (efh), property_name);
+}
+
+MailConfigHTTPMode
+em_format_html_get_image_loading_policy (EMFormatHTML *efh)
+{
+ g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), 0);
+
+ return efh->priv->image_loading_policy;
}
void
-em_format_html_set_mark_citations(EMFormatHTML *emfh, gint state, guint32 citation_colour)
+em_format_html_set_image_loading_policy (EMFormatHTML *efh,
+ MailConfigHTTPMode policy)
{
- if (emfh->mark_citations ^ state || emfh->citation_colour != citation_colour) {
- emfh->mark_citations = state;
- emfh->citation_colour = citation_colour;
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
- if (state)
- emfh->text_html_flags |= CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
- else
- emfh->text_html_flags &= ~CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+ if (policy == efh->priv->image_loading_policy)
+ return;
- em_format_redraw((EMFormat *)emfh);
- }
+ efh->priv->image_loading_policy = policy;
+
+ g_object_notify (G_OBJECT (efh), "image-loading-policy");
+}
+
+gboolean
+em_format_html_get_mark_citations (EMFormatHTML *efh)
+{
+ guint32 flags;
+
+ g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE);
+
+ flags = efh->text_html_flags;
+
+ return ((flags & CAMEL_MIME_FILTER_TOHTML_MARK_CITATION) != 0);
+}
+
+void
+em_format_html_set_mark_citations (EMFormatHTML *efh,
+ gboolean mark_citations)
+{
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+
+ if (mark_citations)
+ efh->text_html_flags |=
+ CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+ efh->text_html_flags &=
+ ~CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+
+ g_object_notify (G_OBJECT (efh), "mark-citations");
+}
+
+gboolean
+em_format_html_get_only_local_photos (EMFormatHTML *efh)
+{
+ g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE);
+
+ return efh->priv->only_local_photos;
+}
+
+void
+em_format_html_set_only_local_photos (EMFormatHTML *efh,
+ gboolean only_local_photos)
+{
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+
+ efh->priv->only_local_photos = only_local_photos;
+
+ g_object_notify (G_OBJECT (efh), "only-local-photos");
+}
+
+gboolean
+em_format_html_get_show_sender_photo (EMFormatHTML *efh)
+{
+ g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE);
+
+ return efh->priv->show_sender_photo;
+}
+
+void
+em_format_html_set_show_sender_photo (EMFormatHTML *efh,
+ gboolean show_sender_photo)
+{
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+
+ efh->priv->show_sender_photo = show_sender_photo;
+
+ g_object_notify (G_OBJECT (efh), "show-sender-photo");
}
CamelMimePart *
@@ -482,12 +1278,15 @@ static void emfh_gethttp(struct _EMFormatHTMLJob *job, gint cancelled)
instream = cistream = camel_data_cache_get(emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL);
if (instream == NULL) {
+ MailConfigHTTPMode policy;
gchar *proxy;
- if (!(job->format->load_http_now
- || job->format->load_http == MAIL_CONFIG_HTTP_ALWAYS
- || (job->format->load_http == MAIL_CONFIG_HTTP_SOMETIMES
- && em_utils_in_addressbook((CamelInternetAddress *)camel_mime_message_get_from(job->format->format.message), FALSE)))) {
+ policy = em_format_html_get_image_loading_policy (job->format);
+
+ if (!(job->format->priv->load_images_now
+ || policy == MAIL_CONFIG_HTTP_ALWAYS
+ || (policy == MAIL_CONFIG_HTTP_SOMETIMES
+ && em_utils_in_addressbook((CamelInternetAddress *)camel_mime_message_get_from(job->format->parent.message), FALSE)))) {
/* TODO: Ideally we would put the http requests into another queue and only send them out
if the user selects 'load images', when they do. The problem is how to maintain this
state with multiple renderings, and how to adjust the thread dispatch/setup routine to handle it */
@@ -676,7 +1475,11 @@ static const gchar *smime_sign_colour[4] = {
static void
efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
{
- efh_parent->format_secure(emf, stream, part, valid);
+ EMFormatClass *format_class;
+
+ format_class = EM_FORMAT_GET_CLASS (emf);
+ g_return_if_fail (format_class->format_secure != NULL);
+ format_class->format_secure (emf, stream, part, valid);
/* To explain, if the validity is the same, then we are the
base validity and now have a combined sign/encrypt validity
@@ -730,6 +1533,7 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
CamelContentType *type;
const gchar *format;
guint32 flags;
+ guint32 rgb;
gint i, count, len;
struct _EMFormatHTMLCache *efhc;
@@ -786,8 +1590,10 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
camel_content_type_unref(ct);
}
+ rgb = e_color_to_value (
+ &efh->priv->colors[EM_FORMAT_HTML_COLOR_CITATION]);
filtered_stream = camel_stream_filter_new_with_stream(stream);
- html_filter = camel_mime_filter_tohtml_new(flags, efh->citation_colour);
+ html_filter = camel_mime_filter_tohtml_new(flags, rgb);
camel_stream_filter_add(filtered_stream, html_filter);
camel_object_unref(html_filter);
@@ -803,9 +1609,17 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
type = camel_mime_part_get_content_type(newpart);
if (camel_content_type_is (type, "text", "*") && !camel_content_type_is(type, "text", "calendar")) {
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n",
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n",
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_FRAME]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_CONTENT]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_TEXT]));
camel_stream_write_string(stream, "<tt>\n" EFH_MESSAGE_START);
em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, (CamelDataWrapper *)newpart);
camel_stream_flush((CamelStream *)filtered_stream);
@@ -843,9 +1657,17 @@ efh_text_enriched(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, E
camel_stream_filter_add(filtered_stream, enriched);
camel_object_unref(enriched);
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n" EFH_MESSAGE_START,
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n" EFH_MESSAGE_START,
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_FRAME]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_CONTENT]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_TEXT]));
em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, (CamelDataWrapper *)part);
@@ -880,10 +1702,18 @@ efh_text_html(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFor
EMFormatPURI *puri;
gchar *cid = NULL;
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; color: #%06x;\">\n"
- "<!-- text/html -->\n" EFH_MESSAGE_START,
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; color: #%06x;\">\n"
+ "<!-- text/html -->\n" EFH_MESSAGE_START,
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_FRAME]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_CONTENT]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_TEXT]));
/* TODO: perhaps we don't need to calculate this anymore now base is handled better */
/* calculate our own location string so add_puri doesn't do it
@@ -1020,9 +1850,17 @@ efh_message_deliverystatus(EMFormatHTML *efh, CamelStream *stream, CamelMimePart
guint32 rgb = 0x737373;
/* Yuck, this is copied from efh_text_plain */
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n",
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n",
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_FRAME]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_CONTENT]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_TEXT]));
filtered_stream = camel_stream_filter_new_with_stream(stream);
html_filter = camel_mime_filter_tohtml_new(efh->text_html_flags, rgb);
@@ -1214,284 +2052,17 @@ static EMFormatHandler type_builtin_table[] = {
static void
efh_builtin_init(EMFormatHTMLClass *efhc)
{
- gint i;
-
- for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++)
- em_format_class_add_handler((EMFormatClass *)efhc, &type_builtin_table[i]);
-}
-
-/* ********************************************************************** */
-
-/* Sigh, this is so we have a cancellable, async rendering thread */
-struct _format_msg {
- MailMsg base;
-
- EMFormatHTML *format;
- EMFormat *format_source;
- EMHTMLStream *estream;
- CamelFolder *folder;
- gchar *uid;
- CamelMimeMessage *message;
-};
-
-static gchar *
-efh_format_desc (struct _format_msg *m)
-{
- return g_strdup(_("Formatting message"));
-}
-
-static void
-efh_format_exec (struct _format_msg *m)
-{
- struct _EMFormatHTMLJob *job;
- struct _EMFormatPURITree *puri_level;
- gint cancelled = FALSE;
- CamelURL *base;
-
- if (m->format->html == NULL)
- return;
-
- camel_stream_printf((CamelStream *)m->estream,
- "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n"
- "<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\">\n</head>\n"
- "<body bgcolor =\"#%06x\" text=\"#%06x\" marginwidth=6 marginheight=6>\n",
- m->format->body_colour & 0xffffff,
- m->format->header_colour & 0xffffff);
-
- /* <insert top-header stuff here> */
-
- if (((EMFormat *)m->format)->mode == EM_FORMAT_SOURCE) {
- em_format_format_source((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message);
- } else {
- const EMFormatHandler *handle;
-
- handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/prefix");
- if (handle)
- handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
- handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/rfc822");
- if (handle)
- handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
- handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/post-header-closure");
- if (handle && !((EMFormat *)m->format)->print)
- handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
-
- }
-
- camel_stream_flush((CamelStream *)m->estream);
-
- puri_level = ((EMFormat *)m->format)->pending_uri_level;
- base = ((EMFormat *)m->format)->base;
-
- do {
- /* now dispatch any added tasks ... */
- g_mutex_lock(m->format->priv->lock);
- while ((job = (struct _EMFormatHTMLJob *)e_dlist_remhead(&m->format->priv->pending_jobs))) {
- g_mutex_unlock(m->format->priv->lock);
-
- /* This is an implicit check to see if the gtkhtml has been destroyed */
- if (!cancelled)
- cancelled = m->format->html == NULL;
-
- /* Now do an explicit check for user cancellation */
- if (!cancelled)
- cancelled = camel_operation_cancel_check(NULL);
-
- /* call jobs even if cancelled, so they can clean up resources */
- ((EMFormat *)m->format)->pending_uri_level = job->puri_level;
- if (job->base)
- ((EMFormat *)m->format)->base = job->base;
- job->callback(job, cancelled);
- ((EMFormat *)m->format)->base = base;
-
- /* clean up the job */
- camel_object_unref(job->stream);
- if (job->base)
- camel_url_free(job->base);
- g_free(job);
-
- g_mutex_lock(m->format->priv->lock);
- }
- g_mutex_unlock(m->format->priv->lock);
-
- if (m->estream) {
- /* Closing this base stream can queue more jobs, so we need
- to check the list again after we've finished */
- d(printf("out of jobs, closing root stream\n"));
- camel_stream_write_string((CamelStream *)m->estream, "</body>\n</html>\n");
- camel_stream_close((CamelStream *)m->estream);
- camel_object_unref(m->estream);
- m->estream = NULL;
- }
-
- /* e_dlist_empty is atomic and doesn't need locking */
- } while (!e_dlist_empty(&m->format->priv->pending_jobs));
-
- d(printf("out of jobs, done\n"));
-
- ((EMFormat *)m->format)->pending_uri_level = puri_level;
-}
-
-static void
-efh_format_done (struct _format_msg *m)
-{
- d(printf("formatting finished\n"));
-
- m->format->load_http_now = FALSE;
- m->format->priv->format_id = -1;
- m->format->state = EM_FORMAT_HTML_STATE_NONE;
- g_signal_emit_by_name(m->format, "complete");
-}
-
-static void
-efh_format_free (struct _format_msg *m)
-{
- d(printf("formatter freed\n"));
- g_object_unref(m->format);
- if (m->estream) {
- camel_stream_close((CamelStream *)m->estream);
- camel_object_unref(m->estream);
- }
- if (m->folder)
- camel_object_unref(m->folder);
- g_free(m->uid);
- if (m->message)
- camel_object_unref(m->message);
- if (m->format_source)
- g_object_unref(m->format_source);
-}
-
-static MailMsgInfo efh_format_info = {
- sizeof (struct _format_msg),
- (MailMsgDescFunc) efh_format_desc,
- (MailMsgExecFunc) efh_format_exec,
- (MailMsgDoneFunc) efh_format_done,
- (MailMsgFreeFunc) efh_format_free
-};
-
-static gboolean
-efh_format_timeout(struct _format_msg *m)
-{
- GtkHTMLStream *hstream;
- EMFormatHTML *efh = m->format;
- struct _EMFormatHTMLPrivate *p = efh->priv;
-
- if (m->format->html == NULL) {
- mail_msg_unref(m);
- return FALSE;
- }
-
- d(printf("timeout called ...\n"));
- if (p->format_id != -1) {
- d(printf(" still waiting for cancellation to take effect, waiting ...\n"));
- return TRUE;
- }
-
- g_return_val_if_fail (e_dlist_empty(&p->pending_jobs), FALSE);
-
- d(printf(" ready to go, firing off format thread\n"));
-
- /* call super-class to kick it off */
- efh_parent->format_clone((EMFormat *)efh, m->folder, m->uid, m->message, m->format_source);
- em_format_html_clear_pobject(m->format);
-
- /* FIXME: method off EMFormat? */
- if (((EMFormat *)efh)->valid) {
- camel_cipher_validity_free(((EMFormat *)efh)->valid);
- ((EMFormat *)efh)->valid = NULL;
- ((EMFormat *)efh)->valid_parent = NULL;
- }
-
- if (m->message == NULL) {
- hstream = gtk_html_begin(efh->html);
- gtk_html_stream_close(hstream, GTK_HTML_STREAM_OK);
- mail_msg_unref(m);
- p->last_part = NULL;
- } else {
- efh->state = EM_FORMAT_HTML_STATE_RENDERING;
-
- if (p->last_part != m->message) {
- hstream = gtk_html_begin (efh->html);
- gtk_html_stream_printf (hstream, "<h5>%s</h5>", _("Formatting Message..."));
- gtk_html_stream_close (hstream, GTK_HTML_STREAM_OK);
- }
-
- hstream = NULL;
- m->estream = (EMHTMLStream *)em_html_stream_new(efh->html, hstream);
-
- if (p->last_part == m->message) {
- em_html_stream_set_flags (m->estream,
- GTK_HTML_BEGIN_KEEP_SCROLL | GTK_HTML_BEGIN_KEEP_IMAGES
- | GTK_HTML_BEGIN_BLOCK_UPDATES | GTK_HTML_BEGIN_BLOCK_IMAGES);
- } else {
- /* clear cache of inline-scanned text parts */
- g_hash_table_remove_all(p->text_inline_parts);
-
- p->last_part = m->message;
- }
-
- efh->priv->format_id = m->base.seq;
- mail_msg_unordered_push (m);
- }
-
- efh->priv->format_timeout_id = 0;
- efh->priv->format_timeout_msg = NULL;
-
- return FALSE;
-}
-
-static void efh_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource)
-{
- EMFormatHTML *efh = (EMFormatHTML *)emf;
- struct _format_msg *m;
-
- /* How to sub-class ? Might need to adjust api ... */
-
- if (efh->html == NULL)
- return;
-
- d(printf("efh_format called\n"));
- if (efh->priv->format_timeout_id != 0) {
- d(printf(" timeout for last still active, removing ...\n"));
- g_source_remove(efh->priv->format_timeout_id);
- efh->priv->format_timeout_id = 0;
- mail_msg_unref(efh->priv->format_timeout_msg);
- efh->priv->format_timeout_msg = NULL;
- }
+ EMFormatClass *efc;
+ gint ii;
- m = mail_msg_new(&efh_format_info);
- m->format = (EMFormatHTML *)emf;
- g_object_ref(emf);
- m->format_source = emfsource;
- if (emfsource)
- g_object_ref(emfsource);
- m->folder = folder;
- if (folder)
- camel_object_ref(folder);
- m->uid = g_strdup(uid);
- m->message = msg;
- if (msg)
- camel_object_ref(msg);
+ efc = (EMFormatClass *) efhc;
- if (efh->priv->format_id == -1) {
- d(printf(" idle, forcing format\n"));
- efh_format_timeout(m);
- } else {
- d(printf(" still busy, cancelling and queuing wait\n"));
- /* cancel and poll for completion */
- mail_msg_cancel(efh->priv->format_id);
- efh->priv->format_timeout_msg = m;
- efh->priv->format_timeout_id = g_timeout_add(100, (GSourceFunc)efh_format_timeout, m);
- }
+ for (ii = 0; ii < G_N_ELEMENTS (type_builtin_table); ii++)
+ em_format_class_add_handler (
+ efc, &type_builtin_table[ii]);
}
-static void efh_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt)
-{
- gchar *html;
-
- html = camel_text_to_html (txt, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL|CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_printf(stream, "<em><font color=\"red\">%s</font></em><br>", html);
- g_free(html);
-}
+/* ********************************************************************** */
static void
efh_format_text_header (EMFormatHTML *emfh, CamelStream *stream, const gchar *label, const gchar *value, guint32 flags)
@@ -1852,10 +2423,12 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part)
charset = camel_iconv_charset_name(charset);
if (!efh->simple_headers)
- camel_stream_printf(stream,
- "<font color=\"#%06x\">\n"
- "<table cellpadding=\"0\" width=\"100%%\">",
- efh->header_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<font color=\"#%06x\">\n"
+ "<table cellpadding=\"0\" width=\"100%%\">",
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_HEADER]));
hdr_charset = emf->charset ? emf->charset : emf->default_charset;
@@ -1937,7 +2510,8 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part)
face = !g_ascii_strcasecmp (h->name, "Face");
while (header) {
- if (emf->show_photo && !photo_name && !g_ascii_strcasecmp (header->name, "From"))
+ if (em_format_html_get_show_sender_photo (efh) &&
+ !photo_name && !g_ascii_strcasecmp (header->name, "From"))
photo_name = header->value;
if (!mailer_shown && mailer && (!g_ascii_strcasecmp (header->name, "X-Mailer") ||
@@ -1995,10 +2569,12 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part)
if (photo_name) {
gchar *classid;
CamelMimePart *photopart;
+ gboolean only_local_photo;
cia = camel_internet_address_new();
camel_address_decode((CamelAddress *) cia, (const gchar *) photo_name);
- photopart = em_utils_contact_photo (cia, emf->photo_local);
+ only_local_photo = em_format_html_get_only_local_photos (efh);
+ photopart = em_utils_contact_photo (cia, only_local_photo);
if (photopart) {
contact_has_photo = TRUE;
@@ -2056,7 +2632,8 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part)
}
}
-static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
+static void
+efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
{
const EMFormatHandler *handle;
@@ -2088,57 +2665,3 @@ static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart
emf->valid = save;
emf->valid_parent = save_parent;
}
-
-static void efh_format_source(EMFormat *emf, CamelStream *stream, CamelMimePart *part)
-{
- CamelStreamFilter *filtered_stream;
- CamelMimeFilter *html_filter;
- CamelDataWrapper *dw = (CamelDataWrapper *)part;
-
- filtered_stream = camel_stream_filter_new_with_stream ((CamelStream *) stream);
- html_filter = camel_mime_filter_tohtml_new (CAMEL_MIME_FILTER_TOHTML_CONVERT_NL
- | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES
- | CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT, 0);
- camel_stream_filter_add(filtered_stream, html_filter);
- camel_object_unref(html_filter);
-
- camel_stream_write_string((CamelStream *)stream, "<table><tr><td><tt>");
- em_format_format_text(emf, (CamelStream *)filtered_stream, dw);
- camel_object_unref(filtered_stream);
-
- camel_stream_write_string(stream, "</tt></td></tr></table>");
-}
-
-static void
-efh_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type, const EMFormatHandler *handle)
-{
- gchar *text, *html;
-
- /* we display all inlined attachments only */
-
- /* this could probably be cleaned up ... */
- camel_stream_write_string(stream,
- "<table border=1 cellspacing=0 cellpadding=0><tr><td>"
- "<table width=10 cellspacing=0 cellpadding=0>"
- "<tr><td></td></tr></table></td>"
- "<td><table width=3 cellspacing=0 cellpadding=0>"
- "<tr><td></td></tr></table></td><td><font size=-1>\n");
-
- /* output some info about it */
- text = em_format_describe_part(part, mime_type);
- html = camel_text_to_html(text, ((EMFormatHTML *)emf)->text_html_flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_write_string(stream, html);
- g_free(html);
- g_free(text);
-
- camel_stream_write_string(stream, "</font></td></tr><tr></table>");
-
- if (handle && em_format_is_inline(emf, emf->part_id->str, part, handle))
- handle->handler(emf, stream, part, handle);
-}
-
-static gboolean
-efh_busy(EMFormat *emf)
-{
- return (((EMFormatHTML *)emf)->priv->format_id != -1);
-}
diff --git a/mail/em-format-html.h b/mail/em-format-html.h
index 81a6811de5..4f9c0b209b 100644
--- a/mail/em-format-html.h
+++ b/mail/em-format-html.h
@@ -22,13 +22,13 @@
*/
/*
- Concrete class for formatting mails to html
+ Abstract class for formatting mails to html
*/
#ifndef EM_FORMAT_HTML_H
#define EM_FORMAT_HTML_H
-#include <mail/em-format.h>
+#include <em-format/em-format.h>
#include <mail/mail-config.h>
#include <camel/camel-medium.h>
#include <camel/camel-mime-part.h>
@@ -73,6 +73,16 @@ typedef enum {
EM_FORMAT_HTML_STATE_RENDERING
} EMFormatHTMLState;
+typedef enum {
+ EM_FORMAT_HTML_COLOR_BODY, /* header area background */
+ EM_FORMAT_HTML_COLOR_CITATION, /* citation font color */
+ EM_FORMAT_HTML_COLOR_CONTENT, /* message area background */
+ EM_FORMAT_HTML_COLOR_FRAME, /* frame around message area */
+ EM_FORMAT_HTML_COLOR_HEADER, /* header font color */
+ EM_FORMAT_HTML_COLOR_TEXT, /* message font color */
+ EM_FORMAT_HTML_NUM_COLOR_TYPES
+} EMFormatHTMLColorType;
+
/* A HTMLJob will be executed in another thread, in sequence.
It's job is to write to its stream, close it if successful,
then exit. */
@@ -196,8 +206,7 @@ struct _EMFormatHTMLPObject {
* multipart/related objects and inline images.
**/
struct _EMFormatHTML {
- EMFormat format;
-
+ EMFormat parent;
EMFormatHTMLPrivate *priv;
GtkHTML *html;
@@ -207,15 +216,6 @@ struct _EMFormatHTML {
GSList *headers;
guint32 text_html_flags; /* default flags for text to html conversion */
- guint32 body_colour; /* header box colour */
- guint32 header_colour;
- guint32 text_colour;
- guint32 frame_colour;
- guint32 content_colour;
- guint32 citation_colour;
- guint load_http:2;
- guint load_http_now:1;
- guint mark_citations:1;
guint simple_headers:1; /* simple header format, no box/table */
guint hide_headers:1; /* no headers at all */
guint show_icon:1; /* show an icon when the sender used Evo */
@@ -225,19 +225,40 @@ struct _EMFormatHTML {
};
struct _EMFormatHTMLClass {
- EMFormatClass format_class;
+ EMFormatClass parent_class;
+
+ GType html_widget_type;
};
GType em_format_html_get_type (void);
-EMFormatHTML * em_format_html_new (void);
-void em_format_html_load_http (EMFormatHTML *efh);
-
-void em_format_html_set_load_http (EMFormatHTML *efh,
- gint style);
+void em_format_html_load_images (EMFormatHTML *efh);
+void em_format_html_get_color (EMFormatHTML *efh,
+ EMFormatHTMLColorType type,
+ GdkColor *color);
+void em_format_html_set_color (EMFormatHTML *efh,
+ EMFormatHTMLColorType type,
+ const GdkColor *color);
+MailConfigHTTPMode
+ em_format_html_get_image_loading_policy
+ (EMFormatHTML *efh);
+void em_format_html_set_image_loading_policy
+ (EMFormatHTML *efh,
+ MailConfigHTTPMode policy);
+gboolean em_format_html_get_mark_citations
+ (EMFormatHTML *efh);
void em_format_html_set_mark_citations
(EMFormatHTML *efh,
- gint state,
- guint32 citation_colour);
+ gboolean mark_citations);
+gboolean em_format_html_get_only_local_photos
+ (EMFormatHTML *efh);
+void em_format_html_set_only_local_photos
+ (EMFormatHTML *efh,
+ gboolean only_local_photos);
+gboolean em_format_html_get_show_sender_photo
+ (EMFormatHTML *efh);
+void em_format_html_set_show_sender_photo
+ (EMFormatHTML *efh,
+ gboolean show_sender_photo);
/* retrieves a pseudo-part icon wrapper for a file */
CamelMimePart * em_format_html_file_part (EMFormatHTML *efh,
@@ -261,7 +282,6 @@ EMFormatHTMLPObject *
void em_format_html_remove_pobject (EMFormatHTML *efh,
EMFormatHTMLPObject *pobject);
void em_format_html_clear_pobject (EMFormatHTML *efh);
-
EMFormatHTMLJob *
em_format_html_job_new (EMFormatHTML *efh,
void (*callback)(EMFormatHTMLJob *job, gint cancelled),
diff --git a/mail/em-html-stream.c b/mail/em-html-stream.c
index 3f0177e7a4..cc3c795d32 100644
--- a/mail/em-html-stream.c
+++ b/mail/em-html-stream.c
@@ -27,84 +27,39 @@
#endif
#include <stdio.h>
-#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-stream.h>
#include <gtk/gtk.h>
#include "em-html-stream.h"
#define d(x)
-static void em_html_stream_class_init (EMHTMLStreamClass *klass);
-static void em_html_stream_init (CamelObject *object);
-static void em_html_stream_finalize (CamelObject *object);
-
-static gssize emhs_sync_write(CamelStream *stream, const gchar *buffer, gsize n);
-static gint emhs_sync_close(CamelStream *stream);
-static gint emhs_sync_flush(CamelStream *stream);
-
static EMSyncStreamClass *parent_class = NULL;
-CamelType
-em_html_stream_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- parent_class = (EMSyncStreamClass *)em_sync_stream_get_type();
- type = camel_type_register (em_sync_stream_get_type(),
- "EMHTMLStream",
- sizeof (EMHTMLStream),
- sizeof (EMHTMLStreamClass),
- (CamelObjectClassInitFunc) em_html_stream_class_init,
- NULL,
- (CamelObjectInitFunc) em_html_stream_init,
- (CamelObjectFinalizeFunc) em_html_stream_finalize);
- }
-
- return type;
-}
-
-static void
-em_html_stream_class_init (EMHTMLStreamClass *klass)
-{
- ((EMSyncStreamClass *)klass)->sync_write = emhs_sync_write;
- ((EMSyncStreamClass *)klass)->sync_flush = emhs_sync_flush;
- ((EMSyncStreamClass *)klass)->sync_close = emhs_sync_close;
-}
-
-static void
-em_html_stream_init (CamelObject *object)
-{
- /*EMHTMLStream *emhs = (EMHTMLStream *)object;*/
-}
-
static void
-emhs_cleanup(EMHTMLStream *emhs)
+emhs_cleanup (EMHTMLStream *emhs)
{
if (emhs->sync.cancel && emhs->html_stream)
- gtk_html_stream_close (emhs->html_stream, GTK_HTML_STREAM_ERROR);
+ gtk_html_stream_close (
+ emhs->html_stream, GTK_HTML_STREAM_ERROR);
+
emhs->html_stream = NULL;
emhs->sync.cancel = TRUE;
- g_signal_handler_disconnect(emhs->html, emhs->destroy_id);
- g_object_unref(emhs->html);
+ g_signal_handler_disconnect (emhs->html, emhs->destroy_id);
+ g_object_unref (emhs->html);
emhs->html = NULL;
}
static void
-em_html_stream_finalize (CamelObject *object)
+emhs_gtkhtml_destroy (GtkHTML *html,
+ EMHTMLStream *emhs)
{
- EMHTMLStream *emhs = (EMHTMLStream *)object;
-
- d(printf("%p: finalising stream\n", object));
- if (emhs->html_stream) {
- d(printf("%p: html stream still open - error\n", object));
- /* set 'in finalise' flag */
- camel_stream_close((CamelStream *)emhs);
- }
+ emhs->sync.cancel = TRUE;
+ emhs_cleanup (emhs);
}
static gssize
-emhs_sync_write(CamelStream *stream, const gchar *buffer, gsize n)
+emhs_sync_write (CamelStream *stream,
+ const gchar *buffer,
+ gsize n)
{
EMHTMLStream *emhs = EM_HTML_STREAM (stream);
@@ -112,9 +67,10 @@ emhs_sync_write(CamelStream *stream, const gchar *buffer, gsize n)
return -1;
if (emhs->html_stream == NULL)
- emhs->html_stream = gtk_html_begin_full (emhs->html, NULL, NULL, emhs->flags);
+ emhs->html_stream = gtk_html_begin_full (
+ emhs->html, NULL, NULL, emhs->flags);
- gtk_html_stream_write(emhs->html_stream, buffer, n);
+ gtk_html_stream_write (emhs->html_stream, buffer, n);
return (gssize) n;
}
@@ -133,48 +89,93 @@ emhs_sync_flush(CamelStream *stream)
}
static gint
-emhs_sync_close(CamelStream *stream)
+emhs_sync_close (CamelStream *stream)
{
EMHTMLStream *emhs = (EMHTMLStream *)stream;
if (emhs->html_stream == NULL)
return -1;
- gtk_html_stream_close(emhs->html_stream, GTK_HTML_STREAM_OK);
- emhs_cleanup(emhs);
+ gtk_html_stream_close (emhs->html_stream, GTK_HTML_STREAM_OK);
+ emhs_cleanup (emhs);
return 0;
}
static void
-emhs_gtkhtml_destroy(GtkHTML *html, EMHTMLStream *emhs)
+em_html_stream_class_init (EMHTMLStreamClass *class)
{
- d(printf("%p: emhs gtkhtml destroy\n", emhs));
- emhs->sync.cancel = TRUE;
- emhs_cleanup(emhs);
+ EMSyncStreamClass *sync_stream_class;
+
+ parent_class = (EMSyncStreamClass *)em_sync_stream_get_type();
+
+ sync_stream_class = EM_SYNC_STREAM_CLASS (class);
+ sync_stream_class->sync_write = emhs_sync_write;
+ sync_stream_class->sync_flush = emhs_sync_flush;
+ sync_stream_class->sync_close = emhs_sync_close;
+}
+
+static void
+em_html_stream_init (EMHTMLStream *emhs)
+{
+}
+
+static void
+em_html_stream_finalize (EMHTMLStream *emhs)
+{
+ if (emhs->html_stream) {
+ /* set 'in finalise' flag */
+ camel_stream_close (CAMEL_STREAM (emhs));
+ }
+}
+
+CamelType
+em_html_stream_get_type (void)
+{
+ static CamelType type = CAMEL_INVALID_TYPE;
+
+ if (G_UNLIKELY (type == CAMEL_INVALID_TYPE)) {
+ type = camel_type_register (
+ em_sync_stream_get_type(),
+ "EMHTMLStream",
+ sizeof (EMHTMLStream),
+ sizeof (EMHTMLStreamClass),
+ (CamelObjectClassInitFunc) em_html_stream_class_init,
+ NULL,
+ (CamelObjectInitFunc) em_html_stream_init,
+ (CamelObjectFinalizeFunc) em_html_stream_finalize);
+ }
+
+ return type;
}
/* TODO: Could pass NULL for html_stream, and do a gtk_html_begin
on first data -> less flashing */
CamelStream *
-em_html_stream_new(GtkHTML *html, GtkHTMLStream *html_stream)
+em_html_stream_new (GtkHTML *html,
+ GtkHTMLStream *html_stream)
{
EMHTMLStream *new;
+ g_return_val_if_fail (GTK_IS_HTML (html), NULL);
+
new = EM_HTML_STREAM (camel_object_new (EM_HTML_STREAM_TYPE));
new->html_stream = html_stream;
- new->html = html;
+ new->html = g_object_ref (html);
new->flags = 0;
- g_object_ref(html);
- new->destroy_id = g_signal_connect(html, "destroy", G_CALLBACK(emhs_gtkhtml_destroy), new);
+ new->destroy_id = g_signal_connect (
+ html, "destroy",
+ G_CALLBACK (emhs_gtkhtml_destroy), new);
- em_sync_stream_set_buffer_size(&new->sync, 8192);
+ em_sync_stream_set_buffer_size (&new->sync, 8192);
- return (CamelStream *)new;
+ return CAMEL_STREAM (new);
}
void
em_html_stream_set_flags (EMHTMLStream *emhs, GtkHTMLBeginFlags flags)
{
+ g_return_if_fail (EM_IS_HTML_STREAM (emhs));
+
emhs->flags = flags;
}
diff --git a/mail/em-html-stream.h b/mail/em-html-stream.h
index abd12e154f..7bf79470dd 100644
--- a/mail/em-html-stream.h
+++ b/mail/em-html-stream.h
@@ -24,34 +24,46 @@
#ifndef EM_HTML_STREAM_H
#define EM_HTML_STREAM_H
-G_BEGIN_DECLS
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
+#include <mail/em-sync-stream.h>
+
+#define EM_HTML_STREAM_TYPE \
+ (em_html_stream_get_type ())
+#define EM_HTML_STREAM(obj) \
+ (CAMEL_CHECK_CAST \
+ ((obj), EM_HTML_STREAM_TYPE, EMHTMLStream))
+#define EM_HTML_STREAM_CLASS(cls) \
+ (CAMEL_CHECK_CLASS_CAST \
+ ((cls), EM_HTML_STREAM_TYPE, EMHTMLStreamClass))
+#define EM_IS_HTML_STREAM(obj) \
+ (CAMEL_CHECK_TYPE \
+ ((obj), EM_HTML_STREAM_TYPE))
-#define EM_HTML_STREAM_TYPE (em_html_stream_get_type ())
-#define EM_HTML_STREAM(obj) (CAMEL_CHECK_CAST((obj), EM_HTML_STREAM_TYPE, EMHTMLStream))
-#define EM_HTML_STREAM_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), EM_HTML_STREAM_TYPE, EMHTMLStreamClass))
-#define EM_IS_HTML_STREAM(o) (CAMEL_CHECK_TYPE((o), EM_HTML_STREAM_TYPE))
+G_BEGIN_DECLS
-#include "mail/em-sync-stream.h"
+typedef struct _EMHTMLStream EMHTMLStream;
+typedef struct _EMHTMLStreamClass EMHTMLStreamClass;
-typedef struct _EMHTMLStream {
+struct _EMHTMLStream {
EMSyncStream sync;
guint destroy_id;
GtkHTML *html;
GtkHTMLStream *html_stream;
GtkHTMLBeginFlags flags;
-} EMHTMLStream;
+};
-typedef struct {
+struct _EMHTMLStreamClass {
EMSyncStreamClass parent_class;
-} EMHTMLStreamClass;
-
-CamelType em_html_stream_get_type (void);
+};
-/* the html_stream is closed when we are finalised (with an error), or closed (ok) */
-CamelStream *em_html_stream_new(GtkHTML *html, GtkHTMLStream *html_stream);
-void em_html_stream_set_flags (EMHTMLStream *emhs, GtkHTMLBeginFlags flags);
+CamelType em_html_stream_get_type (void);
+CamelStream * em_html_stream_new (GtkHTML *html,
+ GtkHTMLStream *html_stream);
+void em_html_stream_set_flags (EMHTMLStream *emhs,
+ GtkHTMLBeginFlags flags);
G_END_DECLS
diff --git a/mail/em-inline-filter.c b/mail/em-inline-filter.c
index 1adfb52980..5daae1109b 100644
--- a/mail/em-inline-filter.c
+++ b/mail/em-inline-filter.c
@@ -32,6 +32,7 @@
#include <camel/camel-stream-mem.h>
#include "em-utils.h"
+#include "em-format/em-format.h"
#define d(x)
@@ -175,7 +176,7 @@ emif_add_part(EMInlineFilter *emif, const gchar *data, gint len)
/* pre-snoop the mime type of unknown objects, and poke and hack it into place */
if (camel_content_type_is(dw->mime_type, "application", "octet-stream")
- && (mimetype = em_utils_snoop_type(part))
+ && (mimetype = em_format_snoop_type(part))
&& strcmp(mimetype, "application/octet-stream") != 0) {
camel_data_wrapper_set_mime_type(dw, mimetype);
camel_mime_part_set_content_type(part, mimetype);
diff --git a/mail/em-junk-hook.c b/mail/em-junk-hook.c
deleted file mode 100644
index d032823bed..0000000000
--- a/mail/em-junk-hook.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Vivek Jain <jvivek@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <glib.h>
-#include "em-junk-hook.h"
-#include "mail-session.h"
-#include "e-util/e-error.h"
-#include "em-utils.h"
-#include <camel/camel-junk-plugin.h>
-#include <glib/gi18n.h>
-
-static GHashTable *emjh_types;
-static GObjectClass *parent_class = NULL;
-
-static gpointer emjh_parent_class;
-static GObjectClass *emj_parent;
-#define emjh ((EMJunkHook *)eph)
-
-#define d(x)
-
-static const EPluginHookTargetKey emjh_flag_map[] = {
- { NULL }
-};
-
-/* ********************************************************************** */
-
-/* Mail junk plugin */
-
-/*
- <hook class="org.gnome.evolution.mail.junk:1.0">
- <group id="EMJunk">
- <item check_junk="sa_check_junk"
- report_junk="sa_report_junk"
- report_non_junk="sa_report_non_junk"
- commit_reports = "sa_commit_reports"/>
- </group>
- </hook>
-
-*/
-
-static void manage_error (const gchar *msg, GError *error);
-
-GQuark
-em_junk_error_quark (void)
-{
- return g_quark_from_static_string ("em-junk-error-quark");
-}
-
-static const gchar *
-em_junk_get_name (CamelJunkPlugin *csp);
-
-static void
-em_junk_init(CamelJunkPlugin *csp)
-{
- struct _EMJunkHookItem *item = (EMJunkHookItem *)csp;
-
- ((EPluginClass *)G_OBJECT_GET_CLASS(item->hook->hook.plugin))->enable(item->hook->hook.plugin, 1);
-}
-
-static const gchar *
-em_junk_get_name (CamelJunkPlugin *csp)
-{
- struct _EMJunkHookItem *item = (EMJunkHookItem *)csp;
-
- if (item->hook && item->hook->hook.plugin->enabled) {
- return (item->hook->hook.plugin->name);
- } else
- return _("None");
-
-}
-
-static gboolean
-em_junk_check_junk(CamelJunkPlugin *csp, CamelMimeMessage *m)
-{
- struct _EMJunkHookItem *item = (EMJunkHookItem *)csp;
-
- if (item->hook && item->hook->hook.plugin->enabled) {
- gboolean res;
- EMJunkHookTarget target = {
- m,
- NULL
- };
-
- res = e_plugin_invoke(item->hook->hook.plugin, item->check_junk, &target) != NULL;
-
- manage_error ("mail:junk-check-error", target.error);
-
- return res;
- }
-
- return FALSE;
-}
-
-static void
-em_junk_report_junk(CamelJunkPlugin *csp, CamelMimeMessage *m)
-{
- struct _EMJunkHookItem *item = (EMJunkHookItem *)csp;
-
- if (item->hook && item->hook->hook.plugin->enabled) {
- EMJunkHookTarget target = {
- m,
- NULL
- };
-
- e_plugin_invoke(item->hook->hook.plugin, item->report_junk, &target);
-
- manage_error ("mail:junk-report-error", target.error);
- }
-}
-
-static void
-em_junk_report_non_junk(CamelJunkPlugin *csp, CamelMimeMessage *m)
-{
- struct _EMJunkHookItem *item = (EMJunkHookItem *)csp;
-
- if (item->hook && item->hook->hook.plugin->enabled) {
- EMJunkHookTarget target = {
- m,
- NULL
- };
- e_plugin_invoke(item->hook->hook.plugin, item->report_non_junk, &target);
- manage_error ("mail:junk-not-report-error", target.error);
- }
-}
-
-static void
-em_junk_commit_reports(CamelJunkPlugin *csp)
-{
- struct _EMJunkHookItem *item = (EMJunkHookItem *)csp;
-
- if (item->hook && item->hook->hook.plugin->enabled)
- e_plugin_invoke(item->hook->hook.plugin, item->commit_reports, NULL);
-
-}
-
-static void
-emj_dispose (GObject *object)
-{
- if (parent_class->dispose)
- parent_class->dispose (object);
-}
-
-static void
-emj_finalize (GObject *object)
-{
- if (parent_class->finalize)
- parent_class->finalize (object);
-}
-
-static void
-emjh_free_item(EMJunkHookItem *item)
-{
- g_free (item->check_junk);
- g_free (item->report_junk);
- g_free (item->report_non_junk);
- g_free (item->commit_reports);
- g_free(item);
-}
-
-static void
-emjh_free_group(EMJunkHookGroup *group)
-{
- g_slist_foreach(group->items, (GFunc)emjh_free_item, NULL);
- g_slist_free(group->items);
-
- g_free(group->id);
- g_free(group);
-}
-
-static struct _EMJunkHookItem *
-emjh_construct_item(EPluginHook *eph, EMJunkHookGroup *group, xmlNodePtr root)
-{
- struct _EMJunkHookItem *item;
- CamelJunkPlugin junk_plugin = {
- em_junk_get_name,
- 1,
- em_junk_check_junk,
- em_junk_report_junk,
- em_junk_report_non_junk,
- em_junk_commit_reports,
- em_junk_init,
- };
-
- d(printf(" loading group item\n"));
- item = g_malloc0(sizeof(*item));
- item->csp = junk_plugin;
- item->check_junk = e_plugin_xml_prop(root, "check_junk");
- item->report_junk = e_plugin_xml_prop(root, "report_junk");
- item->report_non_junk = e_plugin_xml_prop(root, "report_non_junk");
- item->commit_reports = e_plugin_xml_prop(root, "commit_reports");
- item->validate_binary = e_plugin_xml_prop(root, "validate_binary");
-
- item->plugin_name = e_plugin_xml_prop(root, "name");
- item->hook = emjh;
-
- if (item->check_junk == NULL || item->report_junk == NULL || item->report_non_junk == NULL || item->commit_reports == NULL)
- goto error;
-
- /* Add the plugin to the session plugin list*/
- mail_session_add_junk_plugin (item->plugin_name, CAMEL_JUNK_PLUGIN (&(item->csp)));
-
- return item;
-error:
- printf ("ERROR");
- emjh_free_item (item);
- return NULL;
-}
-
-static struct _EMJunkHookGroup *
-emjh_construct_group(EPluginHook *eph, xmlNodePtr root)
-{
- struct _EMJunkHookGroup *group;
- xmlNodePtr node;
-
- d(printf(" loading group\n"));
- group = g_malloc0(sizeof(*group));
-
- group->id = e_plugin_xml_prop(root, "id");
- if (group->id == NULL)
- goto error;
-
- node = root->children;
-
- /* We'll processs only the first item from xml file*/
- while (node) {
- if (0 == strcmp((gchar *)node->name, "item")) {
- struct _EMJunkHookItem *item;
-
- item = emjh_construct_item(eph, group, node);
- if (item)
- group->items = g_slist_append(group->items, item);
- break;
- }
-
- node = node->next;
- }
-
- return group;
-error:
- emjh_free_group(group);
-
- return NULL;
-}
-
-static gint
-emjh_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root)
-{
- xmlNodePtr node;
-
- d(printf("loading junk hook\n"));
-
- if (((EPluginHookClass *)emjh_parent_class)->construct(eph, ep, root) == -1)
- return -1;
-
- if (!ep->enabled) {
- g_warning ("ignored this junk plugin: not enabled");
- return -1;
- }
-
- node = root->children;
- while (node) {
- if (strcmp((gchar *)node->name, "group") == 0) {
- struct _EMJunkHookGroup *group;
-
- group = emjh_construct_group(eph, node);
- if (group) {
- emjh->groups = g_slist_append(emjh->groups, group);
- }
- }
- node = node->next;
- }
-
- eph->plugin = ep;
-
- return 0;
-}
-
-struct manage_error_idle_data
-{
- const gchar *msg;
- GError *error;
-};
-
-static void
-free_mei (gpointer data)
-{
- struct manage_error_idle_data *mei = (struct manage_error_idle_data*) data;
-
- if (!mei)
- return;
-
- g_error_free (mei->error);
- g_free (mei);
-}
-
-static gboolean
-manage_error_idle (gpointer data)
-{
- GtkWidget *w;
- struct manage_error_idle_data *mei = (struct manage_error_idle_data *) data;
-
- if (!mei)
- return FALSE;
-
- w = e_error_new (NULL, mei->msg, mei->error->message, NULL);
- em_utils_show_error_silent (w);
-
- return FALSE;
-}
-
-static void
-manage_error (const gchar *msg, GError *error)
-{
- struct manage_error_idle_data *mei;
-
- if (!error)
- return;
-
- mei = g_new0 (struct manage_error_idle_data, 1);
- mei->msg = msg; /* it's a static string, should be safe to use it as this */
- mei->error = error;
-
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, manage_error_idle, mei, free_mei);
-}
-
-/*XXX: don't think we need here*/
-static void
-emjh_enable(EPluginHook *eph, gint state)
-{
- GSList *g;
-
- g = emjh->groups;
- if (emjh_types == NULL)
- return;
-
-}
-
-static void
-emjh_finalise(GObject *o)
-{
- EPluginHook *eph = (EPluginHook *)o;
-
- g_slist_foreach(emjh->groups, (GFunc)emjh_free_group, NULL);
- g_slist_free(emjh->groups);
-
- ((GObjectClass *)emjh_parent_class)->finalize(o);
-}
-
-static void
-emjh_class_init(EPluginHookClass *klass)
-{
- ((GObjectClass *)klass)->finalize = emjh_finalise;
- klass->construct = emjh_construct;
- klass->enable = emjh_enable;
- klass->id = "org.gnome.evolution.mail.junk:1.0";
-}
-
-GType
-em_junk_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EMJunkHookClass), NULL, NULL, (GClassInitFunc) emjh_class_init, NULL, NULL,
- sizeof(EMJunkHook), 0, (GInstanceInitFunc) NULL,
- };
-
- emjh_parent_class = g_type_class_ref(e_plugin_hook_get_type());
- type = g_type_register_static(e_plugin_hook_get_type(), "EMJunkHook", &info, 0);
- }
-
- return type;
-}
-
-static void
-emj_class_init (EMJunkClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- parent_class = g_type_class_peek_parent (klass);
- object_class->dispose = emj_dispose;
- object_class->finalize = emj_finalize;
-}
-
-GType
-emj_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EMJunkClass), NULL, NULL, (GClassInitFunc) emj_class_init, NULL, NULL,
- sizeof(EMJunk), 0, (GInstanceInitFunc) NULL,
- };
-
- emj_parent = g_type_class_ref(G_TYPE_OBJECT);
- type = g_type_register_static(G_TYPE_OBJECT, "EMJunk", &info, 0);
- }
-
- return type;
-}
-
-void
-em_junk_hook_register_type(GType type)
-{
- EMJunk *klass;
-
- if (emjh_types == NULL)
- emjh_types = g_hash_table_new(g_str_hash, g_str_equal);
-
- d(printf("registering junk plugin type '%s'\n", g_type_name(type)));
-
- klass = g_type_class_ref(type);
- g_hash_table_insert(emjh_types, (gpointer)g_type_name(type), klass);
-}
diff --git a/mail/em-junk-hook.h b/mail/em-junk-hook.h
deleted file mode 100644
index 39d18421ef..0000000000
--- a/mail/em-junk-hook.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Vivek Jain <jvivek@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_JUNK_HOOK_H__
-#define __EM_JUNK_HOOK_H__
-
-#include "e-util/e-plugin.h"
-
-#include <camel/camel-junk-plugin.h>
-#include <camel/camel-mime-message.h>
-
-G_BEGIN_DECLS
-
-typedef struct _EMJunkHookItem EMJunkHookItem;
-typedef struct _EMJunkHookGroup EMJunkHookGroup;
-typedef struct _EMJunkHook EMJunkHook;
-typedef struct _EMJunkHookClass EMJunkHookClass;
-typedef struct _EMJunk EMJunk;
-typedef struct _EMJunkClass EMJunkClass;
-
-typedef struct _EMJunkHookTarget EMJunkHookTarget;
-
-typedef void (*EMJunkHookFunc)(struct _EPlugin *plugin, EMJunkHookTarget *data);
-
-GQuark em_junk_error_quark (void);
-
-#define EM_JUNK_ERROR em_junk_error_quark ()
-
-struct _EMJunkHookTarget {
- CamelMimeMessage *m;
- GError *error;
-};
-
-struct _EMJunkHookItem {
- CamelJunkPlugin csp;
- struct _EMJunkHook *hook; /* parent pointer */
- gchar *check_junk;
- gchar *report_junk;
- gchar *report_non_junk;
- gchar *commit_reports;
- gchar *validate_binary;
- gchar *plugin_name;
-};
-
-struct _EMJunkHookGroup {
- struct _EMJunkHook *hook; /* parent pointer */
- gchar *id; /* target id */
- GSList *items; /* items to consider */
-};
-
-struct _EMJunkHook {
- EPluginHook hook;
- GSList *groups;
-};
-
-struct _EMJunkHookClass {
- EPluginHookClass hook_class;
-
- /* which class to add matching items to */
- GHashTable *junk_classes;
-};
-
-GType em_junk_hook_get_type(void);
-void em_junk_hook_register_type(GType type);
-
-struct _EMJunk {
- GObject object;
-
- CamelJunkPlugin csp;
-};
-
-struct _EMJunkClass {
- GObjectClass parent_class;
- /* which class to add matching items to */
- GHashTable *junk_classes;
-};
-
-GType emj_get_type(void);
-
-G_END_DECLS
-
-#endif /* __EM_JUNK_HOOK_H__ */
diff --git a/widgets/table/table-test.h b/mail/em-junk.c
index 8b179bafdf..6af215ed7a 100644
--- a/widgets/table/table-test.h
+++ b/mail/em-junk.c
@@ -1,4 +1,5 @@
/*
+ * em-junk.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,13 +16,16 @@
*
*
* Authors:
- * Miguel de Icaza (miguel@gnu.org)
+ * Vivek Jain <jvivek@novell.com>
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-void table_browser_test (void);
-void multi_cols_test (void);
-void check_test (void);
-void e_table_test (void);
+#include "em-junk.h"
+
+GQuark
+em_junk_error_quark (void)
+{
+ return g_quark_from_static_string ("em-junk-error-quark");
+}
diff --git a/mail/em-junk.h b/mail/em-junk.h
new file mode 100644
index 0000000000..79493caf2f
--- /dev/null
+++ b/mail/em-junk.h
@@ -0,0 +1,66 @@
+/*
+ * em-junk.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Vivek Jain <jvivek@novell.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef EM_JUNK_H
+#define EM_JUNK_H
+
+#include <e-util/e-plugin.h>
+#include <camel/camel-junk-plugin.h>
+#include <camel/camel-mime-message.h>
+
+#define EM_JUNK_ERROR (em_junk_error_quark ())
+
+G_BEGIN_DECLS
+
+typedef struct _EMJunkTarget EMJunkTarget;
+typedef struct _EMJunkInterface EMJunkInterface;
+
+typedef void (*EMJunkHookFunc) (EPlugin *plugin, EMJunkTarget *data);
+
+struct _EMJunkTarget {
+ CamelMimeMessage *m;
+ GError *error;
+};
+
+struct _EMJunkInterface {
+ CamelJunkPlugin camel;
+
+ /* The hook forwards calls from Camel to the EPlugin. */
+ EPluginHook *hook;
+
+ /* These are symbol names in the EPlugin. */
+ gchar *check_junk;
+ gchar *report_junk;
+ gchar *report_notjunk;
+ gchar *commit_reports;
+ gchar *validate_binary;
+
+ gchar *plugin_name;
+};
+
+GQuark em_junk_error_quark (void);
+
+G_END_DECLS
+
+#endif /* EM_JUNK_H */
diff --git a/mail/em-menu.c b/mail/em-menu.c
deleted file mode 100644
index bb8063e7dc..0000000000
--- a/mail/em-menu.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <gtk/gtk.h>
-
-#include "em-menu.h"
-#include "libedataserver/e-msgport.h"
-#include "em-utils.h"
-#include "em-composer-utils.h"
-
-#include <camel/camel-store.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-string-utils.h>
-#include <camel/camel-mime-utils.h>
-#include <camel/camel-mime-part.h>
-#include <camel/camel-url.h>
-
-#include <camel/camel-vee-folder.h>
-#include <camel/camel-vtrash-folder.h>
-
-#include <gconf/gconf.h>
-#include <gconf/gconf-client.h>
-
-#include <e-util/e-util.h>
-
-static void emp_standard_menu_factory(EMenu *emp, gpointer data);
-
-static GObjectClass *emp_parent;
-
-static void
-emp_init(GObject *o)
-{
- /*EMMenu *emp = (EMMenu *)o; */
-}
-
-static void
-emp_finalise(GObject *o)
-{
- ((GObjectClass *)emp_parent)->finalize(o);
-}
-
-static void
-emp_target_free(EMenu *ep, EMenuTarget *t)
-{
- switch (t->type) {
- case EM_MENU_TARGET_SELECT: {
- EMMenuTargetSelect *s = (EMMenuTargetSelect *)t;
-
- if (s->folder)
- camel_object_unref(s->folder);
- g_free(s->uri);
- if (s->uids)
- em_utils_uids_free(s->uids);
- break; }
- }
-
- ((EMenuClass *)emp_parent)->target_free(ep, t);
-}
-
-static void
-emp_class_init(GObjectClass *klass)
-{
- klass->finalize = emp_finalise;
- ((EMenuClass *)klass)->target_free = emp_target_free;
-
- e_menu_class_add_factory((EMenuClass *)klass, NULL, (EMenuFactoryFunc)emp_standard_menu_factory, NULL);
-}
-
-GType
-em_menu_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMMenuClass),
- NULL, NULL,
- (GClassInitFunc)emp_class_init,
- NULL, NULL,
- sizeof(EMMenu), 0,
- (GInstanceInitFunc)emp_init
- };
- emp_parent = g_type_class_ref(e_menu_get_type());
- type = g_type_register_static(e_menu_get_type(), "EMMenu", &info, 0);
- }
-
- return type;
-}
-
-EMMenu *em_menu_new(const gchar *menuid)
-{
- EMMenu *emp = g_object_new(em_menu_get_type(), NULL);
-
- e_menu_construct(&emp->popup, menuid);
-
- return emp;
-}
-
-/**
- * em_menu_target_new_select:
- * @folder: The selection will ref this for the life of it.
- * @folder_uri:
- * @uids: The selection will free this when done with it.
- *
- * Create a new selection popup target.
- *
- * Return value:
- **/
-EMMenuTargetSelect *
-em_menu_target_new_select(EMMenu *emp, CamelFolder *folder, const gchar *folder_uri, GPtrArray *uids)
-{
- EMMenuTargetSelect *t = e_menu_target_new(&emp->popup, EM_MENU_TARGET_SELECT, sizeof(*t));
- guint32 mask = ~0;
- gint i;
- const gchar *tmp;
-
- /* NB: This is identical to em-popup-target-new-select function */
-
- t->uids = uids;
- t->folder = folder;
- t->uri = g_strdup(folder_uri);
-
- if (folder == NULL) {
- t->target.mask = mask;
-
- return t;
- }
-
- camel_object_ref(folder);
- mask &= ~EM_MENU_SELECT_FOLDER;
-
- if (em_utils_folder_is_sent(folder, folder_uri))
- mask &= ~EM_MENU_SELECT_EDIT;
-
- if (!(em_utils_folder_is_drafts(folder, folder_uri)
- || em_utils_folder_is_outbox(folder, folder_uri))
- && uids->len == 1)
- mask &= ~EM_MENU_SELECT_ADD_SENDER;
-
- if (uids->len == 1)
- mask &= ~EM_MENU_SELECT_ONE;
-
- if (uids->len >= 1)
- mask &= ~EM_MENU_SELECT_MANY;
-
- for (i = 0; i < uids->len; i++) {
- CamelMessageInfo *info = camel_folder_get_message_info(folder, uids->pdata[i]);
- guint32 flags;
-
- if (info == NULL)
- continue;
-
- flags = camel_message_info_flags(info);
-
- if (flags & CAMEL_MESSAGE_SEEN)
- mask &= ~EM_MENU_SELECT_MARK_UNREAD;
- else
- mask &= ~EM_MENU_SELECT_MARK_READ;
-
- if (flags & CAMEL_MESSAGE_DELETED)
- mask &= ~EM_MENU_SELECT_UNDELETE;
- else
- mask &= ~EM_MENU_SELECT_DELETE;
-
- if (flags & CAMEL_MESSAGE_FLAGGED)
- mask &= ~EM_MENU_SELECT_MARK_UNIMPORTANT;
- else
- mask &= ~EM_MENU_SELECT_MARK_IMPORTANT;
-
- if (flags & CAMEL_MESSAGE_JUNK)
- mask &= ~EM_MENU_SELECT_MARK_NOJUNK;
- else
- mask &= ~EM_MENU_SELECT_MARK_JUNK;
-
- tmp = camel_message_info_user_tag(info, "follow-up");
- if (tmp && *tmp) {
- mask &= ~EM_MENU_SELECT_FLAG_CLEAR;
- tmp = camel_message_info_user_tag(info, "completed-on");
- if (tmp == NULL || *tmp == 0)
- mask &= ~EM_MENU_SELECT_FLAG_COMPLETED;
- } else
- mask &= ~EM_MENU_SELECT_FLAG_FOLLOWUP;
-
- if (i == 0 && uids->len == 1
- && (tmp = camel_message_info_mlist(info))
- && tmp[0] != 0)
- mask &= ~EM_MENU_SELECT_MAILING_LIST;
-
- camel_folder_free_message_info(folder, info);
- }
-
- t->target.mask = mask;
-
- return t;
-}
-
-/**
- * em_menu_target_new_window:
- * @emp:
- * @window:
- *
- * create a dummy target which references some sort of widget.
- *
- * Return value:
- **/
-EMMenuTargetWidget *
-em_menu_target_new_widget(EMMenu *emp, GtkWidget *w)
-{
- EMMenuTargetWidget *t = e_menu_target_new(&emp->popup, EM_MENU_TARGET_WIDGET, sizeof(*t));
- guint32 mask = ~0;
-
- t->target.mask = mask;
- t->target.widget = w;
-
- return t;
-}
-
-static void
-emp_standard_menu_factory(EMenu *emp, gpointer data)
-{
- /* noop */
-}
-
-/* ********************************************************************** */
-
-/* menu plugin handler */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.item:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="IMAP4 and IMAP4v1 mail store">
- <hook class="org.gnome.mail.popupMenu:1.0"
- handler="HandlePopup">
- <menu id="any" target="select">
- <item
- type="item|toggle|radio|image|submenu|bar"
- active
- path="foo/bar"
- label="label"
- icon="foo"
- mask="select_one"
- activate="emp_view_emacs"/>
- </menu>
- </extension>
-
-*/
-
-static gpointer emph_parent_class;
-#define emph ((EMMenuHook *)eph)
-
-static const EMenuHookTargetMask emph_select_masks[] = {
- { "one", EM_MENU_SELECT_ONE },
- { "many", EM_MENU_SELECT_MANY },
- { "mark_read", EM_MENU_SELECT_MARK_READ },
- { "mark_unread", EM_MENU_SELECT_MARK_UNREAD },
- { "delete", EM_MENU_SELECT_DELETE },
- { "undelete", EM_MENU_SELECT_UNDELETE },
- { "mailing_list", EM_MENU_SELECT_MAILING_LIST },
- { "resend", EM_MENU_SELECT_EDIT },
- { "mark_important", EM_MENU_SELECT_MARK_IMPORTANT },
- { "mark_unimportant", EM_MENU_SELECT_MARK_UNIMPORTANT },
- { "flag_followup", EM_MENU_SELECT_FLAG_FOLLOWUP },
- { "flag_completed", EM_MENU_SELECT_FLAG_COMPLETED },
- { "flag_clear", EM_MENU_SELECT_FLAG_CLEAR },
- { "add_sender", EM_MENU_SELECT_ADD_SENDER },
- { "mark_junk", EM_MENU_SELECT_MARK_JUNK },
- { "mark_nojunk", EM_MENU_SELECT_MARK_NOJUNK },
- { "folder", EM_MENU_SELECT_FOLDER },
- { NULL }
-};
-
-/* dummy widget target, probably wont have any useful masks.
- this should probably be a more specific target type */
-static const EMenuHookTargetMask emph_widget_masks[] = {
- { NULL }
-};
-
-static const EMenuHookTargetMap emph_targets[] = {
- { "select", EM_MENU_TARGET_SELECT, emph_select_masks },
- { "widget", EM_MENU_TARGET_WIDGET, emph_widget_masks },
- { NULL }
-};
-
-static void
-emph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)emph_parent_class)->finalize(o);
-}
-
-static void
-emph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = emph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.mail.bonobomenu:1.0";
-
- for (i=0;emph_targets[i].type;i++)
- e_menu_hook_class_add_target_map((EMenuHookClass *)klass, &emph_targets[i]);
-
- /* FIXME: leaks parent set class? */
- ((EMenuHookClass *)klass)->menu_class = g_type_class_ref(em_menu_get_type());
-}
-
-GType
-em_menu_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EMMenuHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL,
- sizeof(EMMenuHook), 0, (GInstanceInitFunc) NULL,
- };
-
- emph_parent_class = g_type_class_ref(e_menu_hook_get_type());
- type = g_type_register_static(e_menu_hook_get_type(), "EMMenuHook", &info, 0);
- }
-
- return type;
-}
diff --git a/mail/em-menu.h b/mail/em-menu.h
deleted file mode 100644
index b2e66916e3..0000000000
--- a/mail/em-menu.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michel Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_MENU_H__
-#define __EM_MENU_H__
-
-#include <glib-object.h>
-#include <camel/camel-folder.h>
-
-#include "e-util/e-menu.h"
-
-G_BEGIN_DECLS
-
-typedef struct _EMMenu EMMenu;
-typedef struct _EMMenuClass EMMenuClass;
-
-/* Current target description */
-/* Types of popup tagets */
-enum _em_menu_target_t {
- EM_MENU_TARGET_SELECT,
- EM_MENU_TARGET_WIDGET
-};
-
-/* Flags that describe a TARGET_SELECT */
-enum {
- EM_MENU_SELECT_ONE = 1<<1,
- EM_MENU_SELECT_MANY = 1<<2,
- EM_MENU_SELECT_MARK_READ = 1<<3,
- EM_MENU_SELECT_MARK_UNREAD = 1<<4,
- EM_MENU_SELECT_DELETE = 1<<5,
- EM_MENU_SELECT_UNDELETE = 1<<6,
- EM_MENU_SELECT_MAILING_LIST = 1<<7,
- EM_MENU_SELECT_EDIT = 1<<8,
- EM_MENU_SELECT_MARK_IMPORTANT = 1<<9,
- EM_MENU_SELECT_MARK_UNIMPORTANT = 1<<10,
- EM_MENU_SELECT_FLAG_FOLLOWUP = 1<<11,
- EM_MENU_SELECT_FLAG_COMPLETED = 1<<12,
- EM_MENU_SELECT_FLAG_CLEAR = 1<<13,
- EM_MENU_SELECT_ADD_SENDER = 1<<14,
- EM_MENU_SELECT_MARK_JUNK = 1<<15,
- EM_MENU_SELECT_MARK_NOJUNK = 1<<16,
- EM_MENU_SELECT_FOLDER = 1<<17, /* do we have any folder at all? */
- EM_MENU_SELECT_LAST = 1<<18 /* reserve 2 slots */
-};
-
-/* Flags that describe a TARGET_WIDGET (none)
- this should probably be a more specific target type */
-
-typedef struct _EMMenuTargetSelect EMMenuTargetSelect;
-
-struct _EMMenuTargetSelect {
- EMenuTarget target;
- CamelFolder *folder;
- gchar *uri;
- GPtrArray *uids;
-};
-
-typedef struct _EMMenuTargetWidget EMMenuTargetWidget;
-
-struct _EMMenuTargetWidget {
- EMenuTarget target;
-};
-
-typedef struct _EMenuItem EMMenuItem;
-
-/* The object */
-struct _EMMenu {
- EMenu popup;
-
- struct _EMMenuPrivate *priv;
-};
-
-struct _EMMenuClass {
- EMenuClass popup_class;
-};
-
-GType em_menu_get_type(void);
-
-EMMenu *em_menu_new(const gchar *menuid);
-
-EMMenuTargetSelect *em_menu_target_new_select(EMMenu *emp, CamelFolder *folder, const gchar *folder_uri, GPtrArray *uids);
-EMMenuTargetWidget *em_menu_target_new_widget(EMMenu *emp, GtkWidget *w);
-
-/* ********************************************************************** */
-
-typedef struct _EMMenuHook EMMenuHook;
-typedef struct _EMMenuHookClass EMMenuHookClass;
-
-struct _EMMenuHook {
- EMenuHook hook;
-};
-
-struct _EMMenuHookClass {
- EMenuHookClass hook_class;
-};
-
-GType em_menu_hook_get_type(void);
-
-G_END_DECLS
-
-#endif /* __EM_MENU_H__ */
diff --git a/mail/em-message-browser.c b/mail/em-message-browser.c
deleted file mode 100644
index fec31575b7..0000000000
--- a/mail/em-message-browser.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#ifdef G_OS_WIN32
-/* Work around 'DATADIR' and 'interface' lossage in <windows.h> */
-#define DATADIR crap_DATADIR
-#include <windows.h>
-#undef DATADIR
-#undef interface
-#endif
-
-#include <gdk/gdkkeysyms.h>
-
-#include <gconf/gconf-client.h>
-
-#include <camel/camel-folder.h>
-
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-window.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <bonobo/bonobo-ui-util.h>
-
-#include "e-util/e-util-private.h"
-
-#include "e-mail-search-bar.h"
-#include "em-format-html-display.h"
-#include "em-message-browser.h"
-#include "em-menu.h"
-
-#include "evolution-shell-component-utils.h" /* Pixmap stuff, sigh */
-
-#define EM_MESSAGE_BROWSER_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowserPrivate))
-
-#define DEFAULT_WIDTH 600
-#define DEFAULT_HEIGHT 400
-
-struct _EMMessageBrowserPrivate {
- GtkWidget *preview; /* container for message display */
- GtkWidget *search_bar;
-};
-
-static gpointer parent_class;
-static GtkAllocation window_size = { 0, 0, 0, 0 };
-
-static void
-emmb_close (BonoboUIComponent *uid,
- gpointer data,
- const gchar *path)
-{
- EMMessageBrowser *emmb = data;
- GtkWidget *toplevel;
-
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (emmb));
- gtk_widget_destroy (toplevel);
-}
-
-static BonoboUIVerb emmb_verbs[] = {
- BONOBO_UI_UNSAFE_VERB ("MessageBrowserClose", emmb_close),
- BONOBO_UI_VERB_END
-};
-
-static void
-emmb_set_message (EMFolderView *emfv,
- const gchar *uid,
- gint nomarkseen)
-{
- EMMessageBrowser *emmb = EM_MESSAGE_BROWSER (emfv);
- EMFolderViewClass *folder_view_class;
- CamelMessageInfo *info;
-
- /* Chain up to parent's set_message() method. */
- folder_view_class = EM_FOLDER_VIEW_CLASS (parent_class);
- folder_view_class->set_message (emfv, uid, nomarkseen);
-
- if (uid == NULL) {
- gtk_widget_destroy (GTK_WIDGET (emfv));
- return;
- }
-
- info = camel_folder_get_message_info (emfv->folder, uid);
-
- if (info != NULL) {
- gtk_window_set_title (
- GTK_WINDOW (emmb->window),
- camel_message_info_subject (info));
- camel_folder_free_message_info (emfv->folder, info);
- }
-
- /* Well we don't know if it got displayed (yet) ... but whatever ... */
- if (!nomarkseen)
- camel_folder_set_message_flags (
- emfv->folder, uid,
- CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
-}
-
-static void
-emmb_activate (EMFolderView *emfv,
- BonoboUIComponent *uic,
- gint state)
-{
- EMFolderViewClass *folder_view_class;
-
- folder_view_class = EM_FOLDER_VIEW_CLASS (parent_class);
-
- if (state) {
- /* Chain up to parent's activate() method. */
- folder_view_class->activate (emfv, uic, state);
-
- bonobo_ui_component_add_verb_list_with_data (
- uic, emmb_verbs, emfv);
- bonobo_ui_component_set_prop(
- uic, "/commands/EditPaste", "sensitive", "0", NULL);
- } else {
- const BonoboUIVerb *verb;
-
- for (verb = &emmb_verbs[0]; verb->cname; verb++)
- bonobo_ui_component_remove_verb (uic, verb->cname);
-
- /* Chain up to parent's activate() method. */
- folder_view_class->activate (emfv, uic, state);
- }
-}
-
-static void
-emmb_list_message_selected_cb (struct _MessageList *ml,
- const gchar *uid,
- EMMessageBrowser *emmb)
-{
- EMFolderView *emfv = EM_FOLDER_VIEW (emmb);
- CamelMessageInfo *info;
-
- if (uid == NULL)
- return;
-
- info = camel_folder_get_message_info (emfv->folder, uid);
- if (info == NULL)
- return;
-
- gtk_window_set_title (
- GTK_WINDOW (emmb->window),
- camel_message_info_subject (info));
- gtk_widget_grab_focus (
- GTK_WIDGET (emfv->preview->formathtml.html));
-
- camel_folder_free_message_info (emfv->folder, info);
-}
-
-static void
-emmb_window_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- GConfClient *client;
-
- /* FIXME Have GConfBridge handle this. */
-
- /* save to in-memory variable for current session access */
- window_size = *allocation;
-
- /* save the setting across sessions */
- client = gconf_client_get_default ();
- gconf_client_set_int (
- client, "/apps/evolution/mail/message_window/width",
- window_size.width, NULL);
- gconf_client_set_int (
- client, "/apps/evolution/mail/message_window/height",
- window_size.height, NULL);
- g_object_unref (client);
-}
-
-static gint
-emmb_key_press_event_cb (EMMessageBrowser *emmb,
- GdkEventKey *event)
-{
- if (event->keyval == GDK_Escape) {
- GtkWidget *toplevel;
-
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (emmb));
- gtk_widget_destroy (toplevel);
- g_signal_stop_emission_by_name (emmb, "key-press-event");
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-emmb_destroy (GtkObject *gtk_object)
-{
- EMFolderView *emfv = EM_FOLDER_VIEW (gtk_object);
-
- if (emfv->list) {
- gtk_widget_destroy (GTK_WIDGET (emfv->list));
- emfv->list = NULL;
- }
-
- /* Chain up to parent's destroy() method. */
- GTK_OBJECT_CLASS (parent_class)->destroy (gtk_object);
-}
-
-static void
-emmb_show_search_bar (EMFolderView *folder_view)
-{
- EMMessageBrowser *browser = EM_MESSAGE_BROWSER (folder_view);
-
- gtk_widget_show (browser->priv->search_bar);
-}
-
-static void
-emmb_class_init (EMMessageBrowserClass *class)
-{
- GtkObjectClass *gtk_object_class;
- EMFolderViewClass *folder_view_class;
-
- parent_class = g_type_class_peek_parent (class);
- g_type_class_add_private (class, sizeof (EMMessageBrowserPrivate));
-
- gtk_object_class = GTK_OBJECT_CLASS (class);
- gtk_object_class->destroy = emmb_destroy;
-
- folder_view_class = EM_FOLDER_VIEW_CLASS (class);
- folder_view_class->update_message_style = FALSE;
- folder_view_class->set_message = emmb_set_message;
- folder_view_class->activate = emmb_activate;
- folder_view_class->show_search_bar = emmb_show_search_bar;
-}
-
-static void
-emmb_init (EMMessageBrowser *emmb)
-{
- EMFolderView *emfv = EM_FOLDER_VIEW (emmb);
- GtkWidget *container;
- GtkWidget *widget;
- gchar *filename;
-
- emmb->priv = EM_MESSAGE_BROWSER_GET_PRIVATE (emmb);
-
- emfv->preview_active = TRUE;
-
- g_slist_foreach (emfv->ui_files, (GFunc) g_free, NULL);
- g_slist_free (emfv->ui_files);
- emfv->ui_files = NULL;
-
- filename = g_build_filename (
- EVOLUTION_UIDIR, "evolution-mail-messagedisplay.xml", NULL);
- emfv->ui_files = g_slist_append (emfv->ui_files, filename);
-
- filename = g_build_filename (
- EVOLUTION_UIDIR, "evolution-mail-message.xml", NULL);
- emfv->ui_files = g_slist_append (emfv->ui_files, filename);
-
- gtk_box_set_spacing (GTK_BOX (emmb), 1);
-
- container = GTK_WIDGET (emmb);
-
- widget = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (
- GTK_SCROLLED_WINDOW (widget),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (
- GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
- gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
- emmb->priv->preview = widget;
- gtk_widget_show (widget);
-
- widget = e_mail_search_bar_new (emfv->preview->formathtml.html);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emmb->priv->search_bar = widget;
- gtk_widget_hide (widget);
-
- g_signal_connect_swapped (
- widget, "changed",
- G_CALLBACK (em_format_redraw), emfv->preview);
-
- container = emmb->priv->preview;
-
- widget = GTK_WIDGET (emfv->preview->formathtml.html);
- gtk_container_add (GTK_CONTAINER (container), widget);
- gtk_widget_show (widget);
-
- /** @HookPoint-EMMenu: Standalone Message View Menu
- * @Id: org.gnome.evolution.mail.messagebrowser
- * @Class: org.gnome.evolution.mail.bonobomenu:1.0
- * @Target: EMMenuTargetSelect
- *
- * The main menu of standalone message viewer.
- */
- EM_FOLDER_VIEW (emmb)->menu =
- em_menu_new ("org.gnome.evolution.mail.messagebrowser");
-}
-
-GType
-em_message_browser_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EMMessageBrowserClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) emmb_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EMMessageBrowser),
- 0, /* n_preallocs */
- (GInstanceInitFunc) emmb_init,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- EM_TYPE_FOLDER_VIEW, "EMMessageBrowser",
- &type_info, 0);
- }
-
- return type;
-}
-
-GtkWidget *
-em_message_browser_new (void)
-{
- return g_object_new (EM_TYPE_MESSAGE_BROWSER, NULL);
-}
-
-GtkWidget *
-em_message_browser_window_new (void)
-{
- EMMessageBrowser *emmb;
- BonoboUIContainer *uicont;
- BonoboUIComponent *uic;
-
- emmb = (EMMessageBrowser *) em_message_browser_new ();
- gtk_widget_show (GTK_WIDGET (emmb));
-
- /* FIXME: title set elsewhere? */
- emmb->window = g_object_new (
- BONOBO_TYPE_WINDOW, "title", "Evolution", NULL);
- bonobo_window_set_contents (
- BONOBO_WINDOW (emmb->window), GTK_WIDGET (emmb));
-
- uic = bonobo_ui_component_new_default ();
- uicont = bonobo_window_get_ui_container (BONOBO_WINDOW (emmb->window));
- bonobo_ui_component_set_container (uic, BONOBO_OBJREF (uicont), NULL);
-
- em_folder_view_activate (EM_FOLDER_VIEW (emmb), uic, TRUE);
-
- if (window_size.width == 0) {
- /* initialize @window_size with the previous session's size */
-
- /* FIXME Have GConfBridge handle this. */
-
- GConfClient *client;
- GError *error = NULL;
-
- client = gconf_client_get_default ();
-
- window_size.width = gconf_client_get_int (
- client, "/apps/evolution/mail/message_window/width",
- &error);
- if (error != NULL) {
- window_size.width = DEFAULT_WIDTH;
- g_clear_error (&error);
- }
-
- window_size.height = gconf_client_get_int (
- client, "/apps/evolution/mail/message_window/height",
- &error);
- if (error != NULL) {
- window_size.height = DEFAULT_HEIGHT;
- g_clear_error (&error);
- }
-
- g_object_unref (client);
- }
-
- gtk_window_set_default_size (
- GTK_WINDOW (emmb->window),
- window_size.width, window_size.height);
-
- g_signal_connect (
- emmb->window, "size-allocate",
- G_CALLBACK (emmb_window_size_allocate), NULL);
- g_signal_connect (
- EM_FOLDER_VIEW (emmb)->list, "message_selected",
- G_CALLBACK (emmb_list_message_selected_cb), emmb);
- g_signal_connect (
- emmb, "key-press-event",
- G_CALLBACK (emmb_key_press_event_cb), NULL);
-
- /* cleanup? */
-
- return GTK_WIDGET (emmb);
-}
diff --git a/mail/em-message-browser.h b/mail/em-message-browser.h
deleted file mode 100644
index d394adc9ba..0000000000
--- a/mail/em-message-browser.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EM_MESSAGE_BROWSER_H
-#define EM_MESSAGE_BROWSER_H
-
-#include <gtk/gtk.h>
-#include "em-folder-view.h"
-
-/* Standard GObject macros */
-#define EM_TYPE_MESSAGE_BROWSER \
- (em_message_browser_get_type ())
-#define EM_MESSAGE_BROWSER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowser))
-#define EM_MESSAGE_BROWSER_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowserClass))
-#define EM_IS_MESSAGE_BROWSER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), EM_TYPE_MESSAGE_BROWSER))
-#define EM_IS_MESSAGE_BROWSER_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), EM_TYPE_MESSAGE_BROWSER))
-#define EM_MESSAGE_BROWSER_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowserClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EMMessageBrowser EMMessageBrowser;
-typedef struct _EMMessageBrowserClass EMMessageBrowserClass;
-typedef struct _EMMessageBrowserPrivate EMMessageBrowserPrivate;
-
-struct _EMMessageBrowser {
- EMFolderView parent;
-
- /* container, if setup */
- GtkWidget *window;
-
- EMMessageBrowserPrivate *priv;
-};
-
-struct _EMMessageBrowserClass {
- EMFolderViewClass parent_class;
-};
-
-GType em_message_browser_get_type (void);
-
-GtkWidget * em_message_browser_new (void);
-
-/* Also sets up a bonobo container window w/ docks and so on. */
-GtkWidget * em_message_browser_window_new (void);
-
-G_END_DECLS
-
-#endif /* EM_MESSAGE_BROWSER_H */
diff --git a/mail/em-popup.c b/mail/em-popup.c
deleted file mode 100644
index 4fc912ba07..0000000000
--- a/mail/em-popup.c
+++ /dev/null
@@ -1,888 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <gio/gio.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-#include "em-popup.h"
-#include "libedataserver/e-msgport.h"
-#include "em-utils.h"
-#include "em-composer-utils.h"
-
-#include <camel/camel-store.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-string-utils.h>
-#include <camel/camel-mime-utils.h>
-#include <camel/camel-mime-part.h>
-#include <camel/camel-url.h>
-#include <camel/camel-stream-mem.h>
-
-#include <camel/camel-vee-folder.h>
-#include <camel/camel-vtrash-folder.h>
-
-#include <gconf/gconf.h>
-#include <gconf/gconf-client.h>
-
-#include <libedataserver/e-data-server-util.h>
-#include <e-util/e-util.h>
-#include "e-attachment.h"
-
-static void emp_standard_menu_factory(EPopup *emp, gpointer data);
-
-static GObjectClass *emp_parent;
-
-static void
-emp_init(GObject *o)
-{
- /*EMPopup *emp = (EMPopup *)o; */
-}
-
-static void
-emp_finalise(GObject *o)
-{
- ((GObjectClass *)emp_parent)->finalize(o);
-}
-
-static void
-emp_target_free(EPopup *ep, EPopupTarget *t)
-{
- switch (t->type) {
- case EM_POPUP_TARGET_SELECT: {
- EMPopupTargetSelect *s = (EMPopupTargetSelect *)t;
-
- if (s->folder)
- camel_object_unref(s->folder);
- g_free(s->uri);
- if (s->uids)
- em_utils_uids_free(s->uids);
- break; }
- case EM_POPUP_TARGET_URI: {
- EMPopupTargetURI *s = (EMPopupTargetURI *)t;
-
- g_free(s->uri);
- break; }
- case EM_POPUP_TARGET_PART: {
- EMPopupTargetPart *s = (EMPopupTargetPart *)t;
-
- camel_object_unref(s->part);
- g_free(s->mime_type);
- break; }
- case EM_POPUP_TARGET_FOLDER: {
- EMPopupTargetFolder *s = (EMPopupTargetFolder *)t;
-
- g_free(s->uri);
- break; }
- }
-
- ((EPopupClass *)emp_parent)->target_free(ep, t);
-}
-
-static void
-emp_class_init(GObjectClass *klass)
-{
- klass->finalize = emp_finalise;
- ((EPopupClass *)klass)->target_free = emp_target_free;
-
- e_popup_class_add_factory((EPopupClass *)klass, NULL, emp_standard_menu_factory, NULL);
-}
-
-GType
-em_popup_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMPopupClass),
- NULL, NULL,
- (GClassInitFunc)emp_class_init,
- NULL, NULL,
- sizeof(EMPopup), 0,
- (GInstanceInitFunc)emp_init
- };
- emp_parent = g_type_class_ref(e_popup_get_type());
- type = g_type_register_static(e_popup_get_type(), "EMPopup", &info, 0);
- }
-
- return type;
-}
-
-EMPopup *em_popup_new(const gchar *menuid)
-{
- EMPopup *emp = g_object_new(em_popup_get_type(), NULL);
-
- e_popup_construct(&emp->popup, menuid);
-
- return emp;
-}
-
-/**
- * em_popup_target_new_select:
- * @folder: The selection will ref this for the life of it.
- * @folder_uri:
- * @uids: The selection will free this when done with it.
- *
- * Create a new selection popup target.
- *
- * Return value:
- **/
-EMPopupTargetSelect *
-em_popup_target_new_select(EMPopup *emp, CamelFolder *folder, const gchar *folder_uri, GPtrArray *uids)
-{
- EMPopupTargetSelect *t = e_popup_target_new(&emp->popup, EM_POPUP_TARGET_SELECT, sizeof(*t));
- CamelStore *store = CAMEL_STORE (folder->parent_store);
- guint32 mask = ~0;
- gboolean draft_or_outbox;
- gint i;
- const gchar *tmp;
-
- t->uids = uids;
- t->folder = folder;
- t->uri = g_strdup(folder_uri);
-
- if (folder == NULL) {
- t->target.mask = mask;
-
- return t;
- }
-
- camel_object_ref(folder);
- mask &= ~EM_POPUP_SELECT_FOLDER;
-
- if (em_utils_folder_is_sent(folder, folder_uri))
- mask &= ~EM_POPUP_SELECT_EDIT;
-
- draft_or_outbox = em_utils_folder_is_drafts(folder, folder_uri) || em_utils_folder_is_outbox(folder, folder_uri);
- if (!draft_or_outbox && uids->len == 1)
- mask &= ~EM_POPUP_SELECT_ADD_SENDER;
-
- if (uids->len == 1)
- mask &= ~EM_POPUP_SELECT_ONE;
-
- if (uids->len >= 1)
- mask &= ~EM_POPUP_SELECT_MANY;
-
- for (i = 0; i < uids->len; i++) {
- CamelMessageInfo *info = camel_folder_get_message_info(folder, uids->pdata[i]);
- guint32 flags;
-
- if (info == NULL)
- continue;
-
- flags = camel_message_info_flags(info);
- if (flags & CAMEL_MESSAGE_SEEN)
- mask &= ~EM_POPUP_SELECT_MARK_UNREAD;
- else
- mask &= ~EM_POPUP_SELECT_MARK_READ;
-
- if ((store->flags & CAMEL_STORE_VJUNK) && !draft_or_outbox) {
- if ((flags & CAMEL_MESSAGE_JUNK))
- mask &= ~EM_POPUP_SELECT_NOT_JUNK;
- else
- mask &= ~EM_POPUP_SELECT_JUNK;
- } else if (draft_or_outbox) {
- /* Show none option */
- mask |= EM_POPUP_SELECT_NOT_JUNK;
- mask |= EM_POPUP_SELECT_JUNK;
- } else {
- /* Show both options */
- mask &= ~EM_POPUP_SELECT_NOT_JUNK;
- mask &= ~EM_POPUP_SELECT_JUNK;
- }
-
- if (flags & CAMEL_MESSAGE_DELETED)
- mask &= ~EM_POPUP_SELECT_UNDELETE;
- else
- mask &= ~EM_POPUP_SELECT_DELETE;
-
- if (flags & CAMEL_MESSAGE_FLAGGED)
- mask &= ~EM_POPUP_SELECT_MARK_UNIMPORTANT;
- else
- mask &= ~EM_POPUP_SELECT_MARK_IMPORTANT;
-
- tmp = camel_message_info_user_tag(info, "follow-up");
- if (tmp && *tmp) {
- mask &= ~EM_POPUP_SELECT_FLAG_CLEAR;
- tmp = camel_message_info_user_tag(info, "completed-on");
- if (tmp == NULL || *tmp == 0)
- mask &= ~EM_POPUP_SELECT_FLAG_COMPLETED;
- } else
- mask &= ~EM_POPUP_SELECT_FLAG_FOLLOWUP;
-
- if (i == 0 && uids->len == 1
- && (tmp = camel_message_info_mlist(info))
- && tmp[0] != 0)
- mask &= ~EM_POPUP_SELECT_MAILING_LIST;
-
- camel_folder_free_message_info(folder, info);
- }
-
- t->target.mask = mask;
-
- return t;
-}
-
-EMPopupTargetURI *
-em_popup_target_new_uri(EMPopup *emp, const gchar *uri)
-{
- EMPopupTargetURI *t = e_popup_target_new(&emp->popup, EM_POPUP_TARGET_URI, sizeof(*t));
- guint32 mask = ~0;
-
- t->uri = g_strdup(uri);
-
- if (g_ascii_strncasecmp(uri, "http:", 5) == 0
- || g_ascii_strncasecmp(uri, "https:", 6) == 0)
- mask &= ~EM_POPUP_URI_HTTP;
-
- if (g_ascii_strncasecmp(uri, "mailto:", 7) == 0)
- mask &= ~EM_POPUP_URI_MAILTO;
- else
- mask &= ~(EM_POPUP_URI_NOT_MAILTO|~mask);
-
- t->target.mask = mask;
-
- return t;
-}
-
-EMPopupTargetPart *
-em_popup_target_new_part(EMPopup *emp, CamelMimePart *part, const gchar *mime_type)
-{
- EMPopupTargetPart *t = e_popup_target_new(&emp->popup, EM_POPUP_TARGET_PART, sizeof(*t));
- guint32 mask = ~0;
-
- t->part = part;
- camel_object_ref(part);
- if (mime_type)
- t->mime_type = g_strdup(mime_type);
- else
- t->mime_type = camel_data_wrapper_get_mime_type((CamelDataWrapper *)part);
-
- camel_strdown(t->mime_type);
-
- if (CAMEL_IS_MIME_MESSAGE(camel_medium_get_content_object((CamelMedium *)part)))
- mask &= ~EM_POPUP_PART_MESSAGE;
-
- if (strncmp(t->mime_type, "image/", 6) == 0)
- mask &= ~EM_POPUP_PART_IMAGE;
-
- t->target.mask = mask;
-
- return t;
-}
-
-/* TODO: This should be based on the CamelFolderInfo, but ... em-folder-tree doesn't keep it? */
-EMPopupTargetFolder *
-em_popup_target_new_folder (EMPopup *emp, const gchar *uri, guint32 info_flags, guint32 popup_flags)
-{
- EMPopupTargetFolder *t = e_popup_target_new(&emp->popup, EM_POPUP_TARGET_FOLDER, sizeof(*t));
- guint32 mask = ~0;
- CamelURL *url;
-
- t->uri = g_strdup(uri);
-
- if (popup_flags & EM_POPUP_FOLDER_STORE)
- mask &= ~(EM_POPUP_FOLDER_STORE|EM_POPUP_FOLDER_INFERIORS);
- else
- mask &= ~EM_POPUP_FOLDER_FOLDER;
-
- url = camel_url_new(uri, NULL);
- if (url == NULL)
- goto done;
-
- if (!(popup_flags & EM_POPUP_FOLDER_STORE)) {
- const gchar *path;
-
- if (popup_flags & EM_POPUP_FOLDER_DELETE)
- mask &= ~EM_POPUP_FOLDER_DELETE;
-
- if (!(info_flags & CAMEL_FOLDER_NOINFERIORS))
- mask &= ~EM_POPUP_FOLDER_INFERIORS;
-
- if (info_flags & CAMEL_FOLDER_TYPE_OUTBOX)
- mask &= ~EM_POPUP_FOLDER_OUTBOX;
- else
- mask &= ~EM_POPUP_FOLDER_NONSTATIC;
-
- if (!(info_flags & CAMEL_FOLDER_NOSELECT))
- mask &= ~EM_POPUP_FOLDER_SELECT;
-
- if (info_flags & CAMEL_FOLDER_VIRTUAL)
- mask |= EM_POPUP_FOLDER_DELETE|EM_POPUP_FOLDER_INFERIORS;
-
- if ((path = url->fragment ? url->fragment : url->path)) {
- if ((!strcmp (url->protocol, "vfolder") && !strcmp (path, CAMEL_UNMATCHED_NAME))
- || (!strcmp (url->protocol, "maildir") && !strcmp (path, "."))) /* hack for maildir toplevel folder */
- mask |= EM_POPUP_FOLDER_DELETE|EM_POPUP_FOLDER_INFERIORS;
- }
- }
-
- camel_url_free(url);
-done:
- t->target.mask = mask;
-
- return t;
-}
-
-/* ********************************************************************** */
-
-static void
-emp_part_popup_saveas(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimePart *part = NULL;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- em_utils_save_part(ep->target->widget, _("Save As..."), part);
-}
-
-static void
-emp_part_popup_set_background(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- GConfClient *gconf;
- gchar *str, *filename, *path, *extension;
- guint i=1;
- CamelMimePart *part = NULL;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- if (!part)
- return;
-
- filename = g_strdup(camel_mime_part_get_filename(part));
-
- /* if filename is blank, create a default filename based on MIME type */
- if (!filename || !filename[0]) {
- CamelContentType *ct;
-
- ct = camel_mime_part_get_content_type(part);
- g_free (filename);
- filename = g_strdup_printf (_("untitled_image.%s"), ct->subtype);
- }
-
- e_filename_make_safe(filename);
-
- path = g_build_filename(g_get_home_dir(), ".gnome2", "wallpapers", filename, NULL);
-
- extension = strrchr(filename, '.');
- if (extension)
- *extension++ = 0;
-
- /* if file exists, stick a (number) on the end */
- while (g_file_test(path, G_FILE_TEST_EXISTS)) {
- gchar *name;
- name = g_strdup_printf(extension?"%s (%d).%s":"%s (%d)", filename, i++, extension);
- g_free(path);
- path = g_build_filename(g_get_home_dir(), ".gnome2", "wallpapers", name, NULL);
- g_free(name);
- }
-
- g_free(filename);
-
- if (em_utils_save_part_to_file(ep->target->widget, path, part)) {
- gconf = gconf_client_get_default();
-
- /* if the filename hasn't changed, blank the filename before
- * setting it so that gconf detects a change and updates it */
- if ((str = gconf_client_get_string(gconf, "/desktop/gnome/background/picture_filename", NULL)) != NULL
- && strcmp (str, path) == 0) {
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_filename", "", NULL);
- }
-
- g_free (str);
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_filename", path, NULL);
-
- /* if GNOME currently doesn't display a picture, set to "wallpaper"
- * display mode, otherwise leave it alone */
- if ((str = gconf_client_get_string(gconf, "/desktop/gnome/background/picture_options", NULL)) == NULL
- || strcmp(str, "none") == 0) {
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_options", "wallpaper", NULL);
- }
-
- gconf_client_suggest_sync(gconf, NULL);
-
- g_free(str);
- g_object_unref(gconf);
- }
-
- g_free(path);
-}
-
-static void
-emp_part_popup_reply_sender(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_SENDER, NULL);
-}
-
-static void
-emp_part_popup_reply_list (EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_LIST, NULL);
-}
-
-static void
-emp_part_popup_reply_all (EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_ALL, NULL);
-}
-
-static void
-emp_part_popup_forward (EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- /* TODO: have a emfv specific override so we can get the parent folder uri */
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *) part);
- em_utils_forward_message(message, NULL);
-}
-
-static EMPopupItem emp_standard_object_popups[] = {
- { E_POPUP_ITEM, (gchar *) "00.part.00", (gchar *) N_("_Save As..."), emp_part_popup_saveas, NULL, (gchar *) "document-save-as", 0 },
- { E_POPUP_ITEM, (gchar *) "00.part.10", (gchar *) N_("Set as _Background"), emp_part_popup_set_background, NULL, NULL, EM_POPUP_PART_IMAGE },
- { E_POPUP_BAR, (gchar *) "10.part", NULL, NULL, NULL, NULL, EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, (gchar *) "10.part.00", (gchar *) N_("_Reply to sender"), emp_part_popup_reply_sender, NULL, (gchar *) "mail-reply-sender" , EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, (gchar *) "10.part.01", (gchar *) N_("Reply to _List"), emp_part_popup_reply_list, NULL, NULL, EM_POPUP_PART_MESSAGE},
- { E_POPUP_ITEM, (gchar *) "10.part.03", (gchar *) N_("Reply to _All"), emp_part_popup_reply_all, NULL, (gchar *) "mail-reply-all", EM_POPUP_PART_MESSAGE},
- { E_POPUP_BAR, (gchar *) "20.part", NULL, NULL, NULL, NULL, EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, (gchar *) "20.part.00", (gchar *) N_("_Forward"), emp_part_popup_forward, NULL, (gchar *) "mail-forward", EM_POPUP_PART_MESSAGE },
-};
-
-static const EPopupItem emp_standard_part_apps_bar = { E_POPUP_BAR, (gchar *) "99.object" };
-
-/* ********************************************************************** */
-
-static void
-emp_uri_popup_link_open(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
-
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, t->uri);
-}
-
-static void
-emp_uri_popup_address_send(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
-
- /* TODO: have an emfv specific override to get the from uri */
- em_utils_compose_new_message_with_mailto(t->uri, NULL);
-}
-
-static void
-emp_uri_popup_address_add(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
- CamelURL *url;
-
- url = camel_url_new(t->uri, NULL);
- if (url == NULL) {
- g_warning("cannot parse url '%s'", t->uri);
- return;
- }
-
- if (url->path && url->path[0])
- em_utils_add_address(ep->target->widget, url->path);
-
- camel_url_free(url);
-}
-
-static EPopupItem emp_standard_uri_popups[] = {
- { E_POPUP_ITEM, (gchar *) "00.uri.00", (gchar *) N_("_Open Link in Browser"), emp_uri_popup_link_open, NULL, NULL, EM_POPUP_URI_HTTP },
- { E_POPUP_ITEM, (gchar *) "00.uri.10", (gchar *) N_("_Send New Message To..."), emp_uri_popup_address_send, NULL, (gchar *) "mail-message-new", EM_POPUP_URI_MAILTO },
- { E_POPUP_ITEM, (gchar *) "00.uri.20", (gchar *) N_("_Add to Address Book"), emp_uri_popup_address_add, NULL, (gchar *) "contact-new", EM_POPUP_URI_MAILTO },
-};
-
-/* ********************************************************************** */
-
-#define LEN(x) (sizeof(x)/sizeof(x[0]))
-
-static void
-emp_apps_open_in(EPopup *ep, EPopupItem *item, gpointer data)
-{
- gchar *path;
- EPopupTarget *target = ep->target;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) target)->part;
-
- path = em_utils_temp_save_part(target->widget, part, TRUE);
- if (path) {
- GAppInfo *app = item->user_data;
- GList *uris = NULL;
- GError *error = NULL;
-
- if (g_app_info_supports_files (app)) {
- GFile *file = g_file_new_for_path (path);
-
- uris = g_list_append (uris, file);
- g_app_info_launch (app, uris, NULL, &error);
- g_object_unref (file);
- } else {
- gchar *uri;
-
- uri = e_util_filename_to_uri (path);
- uris = g_list_append (uris, uri);
-
- g_app_info_launch_uris (app, uris, NULL, &error);
- g_free (uri);
- }
-
- if (error) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_list_free (uris);
- g_free (path);
- }
-}
-
-static void
-emp_apps_popup_free(EPopup *ep, GSList *free_list, gpointer data)
-{
- while (free_list) {
- GSList *n = free_list->next;
- EPopupItem *item = free_list->data;
-
- if (item->user_data && item->activate == emp_apps_open_in)
- g_object_unref (item->user_data);
-
- g_free(item->path);
- g_free(item->label);
- g_free(item);
- g_slist_free_1(free_list);
-
- free_list = n;
- }
-}
-
-static void
-emp_standard_items_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static void
-emp_add_vcard (EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *target = ep->target;
- CamelMimePart *part;
- CamelDataWrapper *content;
- CamelStreamMem *mem;
-
- part = ((EMPopupTargetPart *) target)->part;
-
- if (!part)
- return;
-
- content = camel_medium_get_content_object (CAMEL_MEDIUM (part));
- mem = CAMEL_STREAM_MEM (camel_stream_mem_new ());
-
- if (camel_data_wrapper_decode_to_stream (content, CAMEL_STREAM (mem)) == -1 ||
- !mem->buffer->data)
- g_warning ("Read part's content failed!");
- else {
- GString *vcard = g_string_new_len ((const gchar *) mem->buffer->data, mem->buffer->len);
-
- em_utils_add_vcard (target->widget, vcard->str);
-
- g_string_free (vcard, TRUE);
- }
-
- camel_object_unref (mem);
-}
-
-static void
-emp_standard_menu_factory(EPopup *emp, gpointer data)
-{
- gint i, len;
- EPopupItem *items;
- GSList *menus = NULL;
- GList *apps = NULL;
- gchar *mime_type = NULL;
- const gchar *filename = NULL;
-
- switch (emp->target->type) {
-#if 0
- case EM_POPUP_TARGET_SELECT:
- return;
- items = emp_standard_select_popups;
- len = LEN(emp_standard_select_popups);
- break;
-#endif
- case EM_POPUP_TARGET_URI: {
- /*EMPopupTargetURI *t = (EMPopupTargetURI *)target;*/
-
- items = emp_standard_uri_popups;
- len = LEN(emp_standard_uri_popups);
- break; }
- case EM_POPUP_TARGET_PART: {
- EMPopupTargetPart *t = (EMPopupTargetPart *)emp->target;
- mime_type = camel_data_wrapper_get_mime_type((CamelDataWrapper *)t->part);
- filename = camel_mime_part_get_filename(t->part);
-
- items = emp_standard_object_popups;
- len = LEN(emp_standard_object_popups);
- break; }
- default:
- items = NULL;
- len = 0;
- }
-
- if (mime_type) {
- gchar *cp;
-
- /* GIO expects lowercase MIME types. */
- for (cp = mime_type; *cp != '\0'; cp++)
- *cp = g_ascii_tolower (*cp);
-
- cp = g_content_type_from_mime_type (mime_type);
- apps = g_app_info_get_all_for_type (cp ? cp : mime_type);
- g_free (cp);
-
- if (apps == NULL || strcmp (mime_type, "application/octet-stream") == 0) {
- if (filename != NULL) {
- gchar *name_type;
-
- name_type = e_util_guess_mime_type (filename, FALSE);
- cp = g_content_type_from_mime_type (name_type);
- /* show alternative apps first */
- apps = g_list_concat (g_app_info_get_all_for_type (cp ? cp : name_type), apps);
- g_free (cp);
- g_free (name_type);
- }
- }
-
- if (apps) {
- GString *label = g_string_new("");
- GSList *open_menus = NULL;
- GList *l;
-
- menus = g_slist_prepend(menus, (gpointer)&emp_standard_part_apps_bar);
-
- for (l = apps, i = 0; l; l = l->next, i++) {
- GAppInfo *app = l->data;
- EPopupItem *item;
-
- item = g_malloc0(sizeof(*item));
- item->type = E_POPUP_ITEM;
- item->path = g_strdup_printf("99.object.%02d", i);
- item->label = g_strdup_printf(_("Open in %s..."), g_app_info_get_name (app));
- item->activate = emp_apps_open_in;
- item->user_data = app;
-
- open_menus = g_slist_prepend(open_menus, item);
- }
-
- if (open_menus)
- e_popup_add_items(emp, open_menus, NULL, emp_apps_popup_free, NULL);
-
- g_string_free(label, TRUE);
- g_list_free(apps);
- }
-
- if (g_ascii_strcasecmp (mime_type, "text/x-vcard") == 0||
- g_ascii_strcasecmp (mime_type, "text/vcard") == 0) {
- EPopupItem *item;
-
- item = g_malloc0 (sizeof (*item));
- item->type = E_POPUP_ITEM;
- item->path = (gchar *) "00.00.vcf.00"; /* make it first item */
- item->label = _("_Add to Address Book");
- item->activate = emp_add_vcard;
- item->user_data = NULL;
- item->image = (gchar *) "contact-new";
-
- e_popup_add_items (emp, g_slist_append (NULL, item), NULL, NULL, NULL);
- }
-
- g_free (mime_type);
- }
-
- for (i=0;i<len;i++) {
- if ((items[i].visible & emp->target->mask) == 0)
- menus = g_slist_prepend(menus, &items[i]);
- }
-
- if (menus)
- e_popup_add_items(emp, menus, NULL, emp_standard_items_free, NULL);
-}
-
-/* ********************************************************************** */
-
-/* Popup menu plugin handler */
-
-/*
-<e-plugin
- class="org.gnome.mail.plugin.popup:1.0"
- id="org.gnome.mail.plugin.popup.item:1.0"
- type="shlib"
- location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
- name="imap"
- description="IMAP4 and IMAP4v1 mail store">
- <hook class="org.gnome.mail.popupMenu:1.0"
- handler="HandlePopup">
- <menu id="any" target="select">
- <item
- type="item|toggle|radio|image|submenu|bar"
- active
- path="foo/bar"
- label="label"
- icon="foo"
- mask="select_one"
- activate="emp_view_emacs"/>
- </menu>
- </extension>
-
-*/
-
-static gpointer emph_parent_class;
-#define emph ((EMPopupHook *)eph)
-
-static const EPopupHookTargetMask emph_select_masks[] = {
- { "one", EM_POPUP_SELECT_ONE },
- { "many", EM_POPUP_SELECT_MANY },
- { "mark_read", EM_POPUP_SELECT_MARK_READ },
- { "mark_unread", EM_POPUP_SELECT_MARK_UNREAD },
- { "delete", EM_POPUP_SELECT_DELETE },
- { "undelete", EM_POPUP_SELECT_UNDELETE },
- { "mailing_list", EM_POPUP_SELECT_MAILING_LIST },
- { "resend", EM_POPUP_SELECT_EDIT },
- { "mark_important", EM_POPUP_SELECT_MARK_IMPORTANT },
- { "mark_unimportant", EM_POPUP_SELECT_MARK_UNIMPORTANT },
- { "flag_followup", EM_POPUP_SELECT_FLAG_FOLLOWUP },
- { "flag_completed", EM_POPUP_SELECT_FLAG_COMPLETED },
- { "flag_clear", EM_POPUP_SELECT_FLAG_CLEAR },
- { "add_sender", EM_POPUP_SELECT_ADD_SENDER },
- { "folder", EM_POPUP_SELECT_FOLDER },
- { "junk", EM_POPUP_SELECT_JUNK },
- { "not_junk", EM_POPUP_SELECT_NOT_JUNK },
- { NULL }
-};
-
-static const EPopupHookTargetMask emph_uri_masks[] = {
- { "http", EM_POPUP_URI_HTTP },
- { "mailto", EM_POPUP_URI_MAILTO },
- { "notmailto", EM_POPUP_URI_NOT_MAILTO },
- { NULL }
-};
-
-static const EPopupHookTargetMask emph_part_masks[] = {
- { "message", EM_POPUP_PART_MESSAGE },
- { "image", EM_POPUP_PART_IMAGE },
- { NULL }
-};
-
-static const EPopupHookTargetMask emph_folder_masks[] = {
- { "folder", EM_POPUP_FOLDER_FOLDER },
- { "store", EM_POPUP_FOLDER_STORE },
- { "inferiors", EM_POPUP_FOLDER_INFERIORS },
- { "delete", EM_POPUP_FOLDER_DELETE },
- { "select", EM_POPUP_FOLDER_SELECT },
- { "outbox", EM_POPUP_FOLDER_OUTBOX },
- { "nonstatic", EM_POPUP_FOLDER_NONSTATIC },
- { NULL }
-};
-
-static const EPopupHookTargetMap emph_targets[] = {
- { "select", EM_POPUP_TARGET_SELECT, emph_select_masks },
- { "uri", EM_POPUP_TARGET_URI, emph_uri_masks },
- { "part", EM_POPUP_TARGET_PART, emph_part_masks },
- { "folder", EM_POPUP_TARGET_FOLDER, emph_folder_masks },
- { NULL }
-};
-
-static void
-emph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)emph_parent_class)->finalize(o);
-}
-
-static void
-emph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = emph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.mail.popup:1.0";
-
- for (i=0;emph_targets[i].type;i++)
- e_popup_hook_class_add_target_map((EPopupHookClass *)klass, &emph_targets[i]);
-
- ((EPopupHookClass *)klass)->popup_class = g_type_class_ref(em_popup_get_type());
-}
-
-GType
-em_popup_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EMPopupHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL,
- sizeof(EMPopupHook), 0, (GInstanceInitFunc) NULL,
- };
-
- emph_parent_class = g_type_class_ref(e_popup_hook_get_type());
- type = g_type_register_static(e_popup_hook_get_type(), "EMPopupHook", &info, 0);
- }
-
- return type;
-}
diff --git a/mail/em-popup.h b/mail/em-popup.h
deleted file mode 100644
index f7182e9358..0000000000
--- a/mail/em-popup.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michel Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_POPUP_H__
-#define __EM_POPUP_H__
-
-#include <glib-object.h>
-#include <camel/camel-folder.h>
-
-#include "e-util/e-popup.h"
-
-G_BEGIN_DECLS
-
-typedef struct _EMPopup EMPopup;
-typedef struct _EMPopupClass EMPopupClass;
-
-/**
- * enum _em_popup_target_t - A list of mail popup target types.
- *
- * @EM_POPUP_TARGET_SELECT: A selection of messages.
- * @EM_POPUP_TARGET_URI: A URI.
- * @EM_POPUP_TARGET_PART: A CamelMimePart message part.
- * @EM_POPUP_TARGET_FOLDER: A folder URI.
- *
- * Defines the value of the targetid for all EMPopup target types.
- **/
-enum _em_popup_target_t {
- EM_POPUP_TARGET_SELECT,
- EM_POPUP_TARGET_URI,
- EM_POPUP_TARGET_PART,
- EM_POPUP_TARGET_FOLDER
-};
-
-/**
- * enum _em_popup_target_select_t - EMPopupTargetSelect qualifiers.
- *
- * @EM_POPUP_SELECT_ONE: Only one item is selected.
- * @EM_POPUP_SELECT_MANY: One ore more items are selected.
- * @EM_POPUP_SELECT_MARK_READ: Message(s) are unseen and can be
- * marked seen.
- * @EM_POPUP_SELECT_MARK_UNREAD: Message(s) are seen and can be
- * marked unseen.
- * @EM_POPUP_SELECT_DELETE: Message(s) are undeleted and can
- * be marked deleted.
- * @EM_POPUP_SELECT_UNDELETE: Message(s) are deleted and can be
- * undeleted.
- * @EM_POPUP_SELECT_MAILING_LIST: If one message is selected, and it
- * contains a message list tag.
- * @EM_POPUP_SELECT_EDIT: The message can be opened for editing (the
- * folder is a sent folder).
- * @EM_POPUP_SELECT_MARK_IMPORTANT: Message(s) are not marked
- * important.
- * @EM_POPUP_SELECT_MARK_UNIMPORTANT: Message(s) are marked
- * important.
- * @EM_POPUP_SELECT_FLAG_FOLLOWUP: Message(s) are not flagged for
- * followup.
- * @EM_POPUP_SELECT_FLAG_COMPLETED: Message(s) are not flagged completed.
- * @EM_POPUP_SELECT_FLAG_CLEAR: Message(s) are flagged for followup.
- * @EM_POPUP_SELECT_ADD_SENDER: The message contains sender addresses
- * which might be added to the addressbook. i.e. it isn't a message in
- * the Sent or Drafts folders.
- * @EM_POPUP_SELECT_FOLDER: A folder is set on the selection.
- * @EM_POPUP_SELECT_LAST: The last bit used, can be used to add
- * additional types from derived application code.
- *
- **/
-enum _em_popup_target_select_t {
- EM_POPUP_SELECT_ONE = 1<<1,
- EM_POPUP_SELECT_MANY = 1<<2,
- EM_POPUP_SELECT_MARK_READ = 1<<3,
- EM_POPUP_SELECT_MARK_UNREAD = 1<<4,
- EM_POPUP_SELECT_DELETE = 1<<5,
- EM_POPUP_SELECT_UNDELETE = 1<<6,
- EM_POPUP_SELECT_MAILING_LIST = 1<<7,
- EM_POPUP_SELECT_EDIT = 1<<8,
- EM_POPUP_SELECT_MARK_IMPORTANT = 1<<9,
- EM_POPUP_SELECT_MARK_UNIMPORTANT = 1<<10,
- EM_POPUP_SELECT_FLAG_FOLLOWUP = 1<<11,
- EM_POPUP_SELECT_FLAG_COMPLETED = 1<<12,
- EM_POPUP_SELECT_FLAG_CLEAR = 1<<13,
- EM_POPUP_SELECT_ADD_SENDER = 1<<14,
- EM_POPUP_SELECT_FOLDER = 1<<15, /* do we have any folder at all? */
- EM_POPUP_SELECT_JUNK = 1<<16,
- EM_POPUP_SELECT_NOT_JUNK = 1<<17,
- EM_POPUP_SELECT_LAST = 1<<18
-};
-
-/**
- * enum _em_popup_target_uri_t - EMPopupTargetURI qualifiers.
- *
- * @EM_POPUP_URI_HTTP: This is a HTTP or HTTPS url.
- * @EM_POPUP_URI_MAILTO: This is a MAILTO url.
- * @EM_POPUP_URI_NOT_MAILTO: This is not a MAILTO url.
- *
- **/
-enum _em_popup_target_uri_t {
- EM_POPUP_URI_HTTP = 1<<0,
- EM_POPUP_URI_MAILTO = 1<<1,
- EM_POPUP_URI_NOT_MAILTO = 1<<2
-};
-
-/**
- * enum _em_popup_target_part_t - EMPopupTargetPart qualifiers.
- *
- * @EM_POPUP_PART_MESSAGE: This is a message type.
- * @EM_POPUP_PART_IMAGE: This is an image type.
- *
- **/
-enum _em_popup_target_part_t {
- EM_POPUP_PART_MESSAGE = 1<<0,
- EM_POPUP_PART_IMAGE = 1<<1
-};
-
-/**
- * enum _em_popup_target_folder_t - EMPopupTargetFolder qualifiers.
- *
- * @EM_POPUP_FOLDER_FOLDER: This is a normal folder.
- * @EM_POPUP_FOLDER_STORE: This is a store.
- * @EM_POPUP_FOLDER_INFERIORS: This folder may have child folders.
- * @EM_POPUP_FOLDER_DELETE: This folder can be deleted or renamed.
- * @EM_POPUP_FOLDER_SELECT: This folder exists and can be selected or
- * opened.
- *
- **/
-enum _em_popup_target_folder_t {
- EM_POPUP_FOLDER_FOLDER = 1<<0, /* normal folder */
- EM_POPUP_FOLDER_STORE = 1<<1, /* root/nonselectable folder, i.e. store */
- EM_POPUP_FOLDER_INFERIORS = 1<<2, /* folder can have children */
- EM_POPUP_FOLDER_DELETE = 1<<3, /* folder can be deleted/renamed */
- EM_POPUP_FOLDER_SELECT = 1<<4, /* folder can be selected/opened */
- EM_POPUP_FOLDER_OUTBOX = 1<<5, /* Outbox folder */
- EM_POPUP_FOLDER_NONSTATIC = 1<<6 /* Except static folders like Outbox.*/
-};
-
-typedef struct _EMPopupTargetSelect EMPopupTargetSelect;
-typedef struct _EMPopupTargetURI EMPopupTargetURI;
-typedef struct _EMPopupTargetPart EMPopupTargetPart;
-typedef struct _EMPopupTargetFolder EMPopupTargetFolder;
-
-/**
- * struct _EMPopupTargetURI - An inline URI.
- *
- * @target: Superclass.
- * @uri: The encoded URI to which this target applies.
- *
- * Used to represent popup-menu context on any URI object.
- **/
-struct _EMPopupTargetURI {
- EPopupTarget target;
- gchar *uri;
-};
-
-/**
- * struct _EMPopupTargetSelect - A list of messages.
- *
- * @target: Superclass.
- * @folder: The CamelFolder of the selected messages.
- * @uri: The encoded URI represending this folder.
- * @uids: An array of UID strings of messages within @folder.
- *
- * Used to represent a selection of messages as context for a popup
- * menu. All items may be NULL if the current view has no active
- * folder selected.
- **/
-struct _EMPopupTargetSelect {
- EPopupTarget target;
- CamelFolder *folder;
- gchar *uri;
- GPtrArray *uids;
-};
-
-/**
- * struct _EMPopupTargetPart - A Camel object.
- *
- * @target: Superclass.
- * @mime_type: MIME type of the part. This may be a calculated type
- * not matching the @part's MIME type.
- * @part: A CamelMimePart representing a message or attachment.
- *
- * Used to represent a message part as context for a popup menu. This
- * is used for both attachments and inline-images.
- **/
-struct _EMPopupTargetPart {
- EPopupTarget target;
- gchar *mime_type;
- CamelMimePart *part;
-};
-
-/**
- * struct _EMPopupTargetFolder - A folder uri.
- *
- * @target: Superclass.
- * @uri: A folder URI.
- *
- * This target is used to represent folder context.
- **/
-struct _EMPopupTargetFolder {
- EPopupTarget target;
- gchar *uri;
-};
-
-typedef struct _EPopupItem EMPopupItem;
-
-/* The object */
-struct _EMPopup {
- EPopup popup;
-
- struct _EMPopupPrivate *priv;
-};
-
-struct _EMPopupClass {
- EPopupClass popup_class;
-};
-
-GType em_popup_get_type(void);
-
-EMPopup *em_popup_new(const gchar *menuid);
-
-EMPopupTargetURI *em_popup_target_new_uri(EMPopup *emp, const gchar *uri);
-EMPopupTargetSelect *em_popup_target_new_select(EMPopup *emp, CamelFolder *folder, const gchar *folder_uri, GPtrArray *uids);
-EMPopupTargetPart *em_popup_target_new_part(EMPopup *emp, CamelMimePart *part, const gchar *mime_type);
-EMPopupTargetFolder *em_popup_target_new_folder(EMPopup *emp, const gchar *uri, guint32 info_flags, guint32 popup_flags);
-
-/* ********************************************************************** */
-
-typedef struct _EMPopupHook EMPopupHook;
-typedef struct _EMPopupHookClass EMPopupHookClass;
-
-struct _EMPopupHook {
- EPopupHook hook;
-};
-
-struct _EMPopupHookClass {
- EPopupHookClass hook_class;
-};
-
-GType em_popup_hook_get_type(void);
-
-G_END_DECLS
-
-#endif /* __EM_POPUP_H__ */
diff --git a/mail/em-search-context.c b/mail/em-search-context.c
index 22369b4f60..7bc43a18be 100644
--- a/mail/em-search-context.c
+++ b/mail/em-search-context.c
@@ -33,35 +33,40 @@
#include "filter/filter-option.h"
#include "filter/filter-int.h"
-static FilterElement *em_search_new_element(RuleContext *rc, const gchar *type);
+static gpointer parent_class;
-static RuleContextClass *parent_class = NULL;
-
-static void
-em_search_context_finalise (GObject *obj)
+static FilterElement *
+search_context_new_element (RuleContext *context,
+ const gchar *type)
{
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ if (strcmp (type, "system-flag") == 0)
+ return (FilterElement *) filter_option_new ();
+
+ if (strcmp (type, "score") == 0)
+ return (FilterElement *) filter_int_new_type ("score", -3, 3);
+
+ /* Chain up to parent's new_element() method. */
+ return RULE_CONTEXT_CLASS (parent_class)->new_element (context, type);
}
static void
-em_search_context_class_init (EMSearchContextClass *klass)
+search_context_class_init (EMSearchContextClass *class)
{
- parent_class = g_type_class_ref (RULE_TYPE_CONTEXT);
+ RuleContextClass *rule_context_class;
- ((GObjectClass *)klass)->finalize = em_search_context_finalise;
- ((RuleContextClass *)klass)->new_element = em_search_new_element;
+ parent_class = g_type_class_peek_parent (class);
+
+ rule_context_class = RULE_CONTEXT_CLASS (class);
+ rule_context_class->new_element = search_context_new_element;
}
static void
-em_search_context_init (EMSearchContext *vc)
+search_context_init (EMSearchContext *vc)
{
- rule_context_add_part_set ((RuleContext *)vc, "partset", filter_part_get_type (),
- rule_context_add_part, rule_context_next_part);
-
- rule_context_add_rule_set ((RuleContext *)vc, "ruleset", filter_rule_get_type (),
- rule_context_add_rule, rule_context_next_rule);
+ RuleContext *rule_context;
- ((RuleContext *)vc)->flags = RULE_CONTEXT_THREADING | RULE_CONTEXT_GROUPING;
+ rule_context = RULE_CONTEXT (vc);
+ rule_context->flags = RULE_CONTEXT_THREADING | RULE_CONTEXT_GROUPING;
}
GType
@@ -69,46 +74,29 @@ em_search_context_get_type (void)
{
static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
sizeof (EMSearchContextClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_search_context_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) search_context_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
sizeof (EMSearchContext),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_search_context_init,
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) search_context_init,
+ NULL /* value_table */
};
- type = g_type_register_static (RULE_TYPE_CONTEXT, "EMSearchContext", &info, 0);
+ type = g_type_register_static (
+ RULE_TYPE_CONTEXT, "EMSearchContext", &type_info, 0);
}
return type;
}
-/**
- * em_search_context_new:
- *
- * Create a new EMSearchContext object.
- *
- * Return value: A new #EMSearchContext object.
- **/
-EMSearchContext *
+RuleContext *
em_search_context_new (void)
{
- return (EMSearchContext *) g_object_new (EM_SEARCH_TYPE_CONTEXT, NULL, NULL);
-}
-
-static FilterElement *
-em_search_new_element(RuleContext *rc, const gchar *type)
-{
- if (!strcmp (type, "system-flag")) {
- return (FilterElement *) filter_option_new ();
- } else if (!strcmp (type, "score")) {
- return (FilterElement *) filter_int_new_type("score", -3, 3);
- } else {
- return parent_class->new_element(rc, type);
- }
+ return g_object_new (EM_SEARCH_TYPE_CONTEXT, NULL);
}
diff --git a/mail/em-search-context.h b/mail/em-search-context.h
index 47dc6ea86a..d8b890270c 100644
--- a/mail/em-search-context.h
+++ b/mail/em-search-context.h
@@ -22,31 +22,46 @@
*
*/
-#ifndef _EM_SEARCH_CONTEXT_H
-#define _EM_SEARCH_CONTEXT_H
+#ifndef EM_SEARCH_CONTEXT_H
+#define EM_SEARCH_CONTEXT_H
-#include "filter/rule-context.h"
+#include <filter/rule-context.h>
-#define EM_SEARCH_TYPE_CONTEXT (em_search_context_get_type ())
-#define EM_SEARCH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_SEARCH_TYPE_CONTEXT, EMSearchContext))
-#define EM_SEARCH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_SEARCH_TYPE_CONTEXT, EMSearchContextClass))
-#define IS_EM_SEARCH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_SEARCH_TYPE_CONTEXT))
-#define IS_EM_SEARCH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EM_SEARCH_TYPE_CONTEXT))
-#define EM_SEARCH_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EM_SEARCH_TYPE_CONTEXT, EMSearchContextClass))
+/* Standard GObject macros */
+#define EM_SEARCH_TYPE_CONTEXT \
+ (em_search_context_get_type ())
+#define EM_SEARCH_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_SEARCH_TYPE_CONTEXT, EMSearchContext))
+#define EM_SEARCH_CONTEXT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_SEARCH_TYPE_CONTEXT, EMSearchContextClass))
+#define EM_IS_SEARCH_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_SEARCH_TYPE_CONTEXT))
+#define EM_IS_SEARCH_CONTEXT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_SEARCH_TYPE_CONTEXT))
+#define EM_SEARCH_CONTEXT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_SEARCH_TYPE_CONTEXT, EMSearchContextClass))
+
+G_BEGIN_DECLS
typedef struct _EMSearchContext EMSearchContext;
typedef struct _EMSearchContextClass EMSearchContextClass;
struct _EMSearchContext {
- RuleContext parent_object;
+ RuleContext parent;
};
struct _EMSearchContextClass {
RuleContextClass parent_class;
};
-GType em_search_context_get_type (void);
+GType em_search_context_get_type (void);
+RuleContext * em_search_context_new (void);
-EMSearchContext *em_search_context_new (void);
+G_END_DECLS
-#endif /* ! _EM_SEARCH_CONTEXT_H */
+#endif /* EM_SEARCH_CONTEXT_H */
diff --git a/mail/em-subscribe-editor.c b/mail/em-subscribe-editor.c
index 4d20b31baa..d572c89eaf 100644
--- a/mail/em-subscribe-editor.c
+++ b/mail/em-subscribe-editor.c
@@ -35,8 +35,9 @@
#include "camel/camel-exception.h"
#include "camel/camel-store.h"
#include "camel/camel-session.h"
-#include "libedataserver/e-account-list.h"
#include "libedataserver/e-msgport.h"
+
+#include "e-util/e-account-utils.h"
#include "e-util/e-util-private.h"
#include "em-subscribe-editor.h"
@@ -820,7 +821,8 @@ window_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
g_object_unref (gconf);
}
-GtkDialog *em_subscribe_editor_new(void)
+GtkWidget *
+em_subscribe_editor_new(void)
{
EMSubscribeEditor *se;
EAccountList *accounts;
@@ -895,7 +897,7 @@ GtkDialog *em_subscribe_editor_new(void)
1, TRUE,
-1);
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
for (iter = e_list_get_iterator ((EList *) accounts);
e_iterator_is_valid (iter);
e_iterator_next (iter)) {
@@ -945,5 +947,5 @@ GtkDialog *em_subscribe_editor_new(void)
gtk_window_set_default_size ((GtkWindow *) se->dialog, window_size.width, window_size.height);
g_signal_connect (se->dialog, "size-allocate", G_CALLBACK (window_size_allocate), NULL);
- return se->dialog;
+ return GTK_WIDGET (se->dialog);
}
diff --git a/mail/em-subscribe-editor.h b/mail/em-subscribe-editor.h
index 36710ec0c5..d10d68bbb8 100644
--- a/mail/em-subscribe-editor.h
+++ b/mail/em-subscribe-editor.h
@@ -23,6 +23,6 @@
#include <gtk/gtk.h>
-GtkDialog *em_subscribe_editor_new(void);
+GtkWidget *em_subscribe_editor_new(void);
#endif /* ! _EM_SUBSCRIBE_EDITOR_H */
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 5544a7d403..da0e3e2a57 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -56,7 +56,6 @@
#include <gio/gio.h>
-#include "mail-component.h"
#include "mail-mt.h"
#include "mail-ops.h"
#include "mail-tools.h"
@@ -69,24 +68,52 @@
#include "e-util/e-util.h"
#include "e-util/e-util-private.h"
#include "e-util/e-mktemp.h"
-#include "libedataserver/e-account-list.h"
+#include "e-util/e-account-utils.h"
#include "e-util/e-dialog-utils.h"
#include "e-util/e-error.h"
+#include "shell/e-shell.h"
+#include "widgets/misc/e-alert-activity.h"
+#include "widgets/misc/e-attachment.h"
#include "em-utils.h"
#include "em-composer-utils.h"
-#include "em-folder-view.h"
#include "em-format-quote.h"
-#include "em-account-editor.h"
-#include "e-attachment.h"
-#include "e-activity-handler.h"
+#include "e-mail-local.h"
static void emu_save_part_done (CamelMimePart *part, gchar *name, gint done, gpointer data);
-extern CamelSession *session;
-
#define d(x)
+const gchar *
+em_utils_get_data_dir (void)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ /* XXX This is a temporary solution until I can figure out a
+ * better way. Ideally, nothing below the module layer
+ * should need to know about the user data directory. */
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ return e_shell_backend_get_data_dir (shell_backend);
+}
+
+const gchar *
+em_utils_get_config_dir (void)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ /* XXX This is a temporary solution until I can figure out a
+ * better way. Ideally, nothing below the module layer
+ * should need to know about the user config directory. */
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ return e_shell_backend_get_config_dir (shell_backend);
+}
+
/**
* em_utils_prompt_user:
* @parent: parent window
@@ -175,64 +202,24 @@ em_utils_uids_free (GPtrArray *uids)
g_ptr_array_free (uids, TRUE);
}
-static void
-druid_destroy_cb (gpointer user_data, GObject *deadbeef)
-{
- gtk_main_quit ();
-}
-
-/**
- * em_utils_configure_account:
- * @parent: parent window for the druid to be a child of.
- *
- * Displays a druid allowing the user to configure an account. If
- * @parent is non-NULL, then the druid will be created as a child
- * window of @parent's toplevel window.
- *
- * Returns %TRUE if an account has been configured or %FALSE
- * otherwise.
- **/
-gboolean
-em_utils_configure_account (GtkWidget *parent)
-{
- EMAccountEditor *emae;
-
- emae = em_account_editor_new(NULL, EMAE_DRUID, "org.gnome.evolution.mail.config.accountDruid");
- if (parent != NULL)
- e_dialog_set_transient_for ((GtkWindow *)emae->editor, parent);
-
- g_object_weak_ref((GObject *)emae->editor, (GWeakNotify) druid_destroy_cb, NULL);
- gtk_widget_show(emae->editor);
- gtk_grab_add(emae->editor);
- gtk_main();
-
- return mail_config_is_configured();
-}
-
/**
* em_utils_check_user_can_send_mail:
- * @parent: parent window for the druid to be a child of.
- *
- * If no accounts have been configured, the user will be given a
- * chance to configure an account. In the case that no accounts are
- * configured, a druid will be created. If @parent is non-NULL, then
- * the druid will be created as a child window of @parent's toplevel
- * window.
*
* Returns %TRUE if the user has an account configured (to send mail)
* or %FALSE otherwise.
**/
gboolean
-em_utils_check_user_can_send_mail (GtkWidget *parent)
+em_utils_check_user_can_send_mail (void)
{
+ EAccountList *account_list;
EAccount *account;
- if (!mail_config_is_configured ()) {
- if (!em_utils_configure_account (parent))
- return FALSE;
- }
+ account_list = e_get_account_list ();
+
+ if (e_list_length ((EList *) account_list) == 0)
+ return FALSE;
- if (!(account = mail_config_get_default_account ()))
+ if (!(account = e_get_default_account ()))
return FALSE;
/* Check for a transport */
@@ -252,11 +239,12 @@ em_filter_editor_response (GtkWidget *dialog, gint button, gpointer user_data)
EMFilterContext *fc;
if (button == GTK_RESPONSE_OK) {
+ const gchar *data_dir;
gchar *user;
+ data_dir = em_utils_get_data_dir ();
fc = g_object_get_data ((GObject *) dialog, "context");
- user = g_strdup_printf ("%s/filters.xml",
- mail_component_peek_base_directory (mail_component_peek ()));
+ user = g_strdup_printf ("%s/filters.xml", data_dir);
rule_context_save ((RuleContext *) fc, user);
g_free (user);
}
@@ -283,7 +271,7 @@ static EMFilterSource em_filter_source_element_names[] = {
void
em_utils_edit_filters (GtkWidget *parent)
{
- const gchar *base_directory = mail_component_peek_base_directory (mail_component_peek ());
+ const gchar *data_dir;
gchar *user, *system;
EMFilterContext *fc;
@@ -292,8 +280,10 @@ em_utils_edit_filters (GtkWidget *parent)
return;
}
+ data_dir = em_utils_get_data_dir ();
+
fc = em_filter_context_new ();
- user = g_strdup_printf ("%s/filters.xml", base_directory);
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
rule_context_load ((RuleContext *) fc, system, user);
g_free (user);
@@ -383,12 +373,14 @@ emu_save_get_filename_for_part (CamelMimePart *part)
* Saves a mime part to disk (prompting the user for filename).
**/
void
-em_utils_save_part (GtkWidget *parent, const gchar *prompt, CamelMimePart *part)
+em_utils_save_part (GtkWindow *parent, const gchar *prompt, CamelMimePart *part)
{
GtkWidget *file_chooser;
const gchar *utf8_filename;
gchar *uri = NULL, *filename;
+ g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
+
utf8_filename = emu_save_get_filename_for_part (part);
filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
em_filename_make_safe (filename);
@@ -498,12 +490,14 @@ get_unique_file_names (GSList *parts)
}
void
-em_utils_save_parts (GtkWidget *parent, const gchar *prompt, GSList *parts)
+em_utils_save_parts (GtkWindow *parent, const gchar *prompt, GSList *parts)
{
GtkWidget *file_chooser;
gchar *path_uri;
GSList *iter, *file_names, *iter_file;
+ g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
+
file_chooser = e_file_get_save_filesel (
parent, prompt, NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
@@ -553,7 +547,7 @@ exit:
* Returns %TRUE if saving succeeded, %FALSE otherwise
**/
gboolean
-em_utils_save_part_to_file(GtkWidget *parent, const gchar *filename, CamelMimePart *part)
+em_utils_save_part_to_file(GtkWindow *parent, const gchar *filename, CamelMimePart *part)
{
gint done;
gchar *dirname;
@@ -564,7 +558,7 @@ em_utils_save_part_to_file(GtkWidget *parent, const gchar *filename, CamelMimePa
dirname = g_path_get_dirname(filename);
if (g_mkdir_with_parents(dirname, 0777) == -1) {
- GtkWidget *w = e_error_new((GtkWindow *)parent, "mail:no-create-path", filename, g_strerror(errno), NULL);
+ GtkWidget *w = e_error_new(parent, "mail:no-create-path", filename, g_strerror(errno), NULL);
g_free(dirname);
em_utils_show_error_silent (w);
return FALSE;
@@ -573,13 +567,13 @@ em_utils_save_part_to_file(GtkWidget *parent, const gchar *filename, CamelMimePa
if (g_access(filename, F_OK) == 0) {
if (g_access(filename, W_OK) != 0) {
- e_error_run((GtkWindow *)parent, E_ERROR_ASK_FILE_EXISTS_OVERWRITE, filename, NULL);
+ e_error_run(parent, E_ERROR_ASK_FILE_EXISTS_OVERWRITE, filename, NULL);
return FALSE;
}
}
if (g_stat(filename, &st) != -1 && !S_ISREG(st.st_mode)) {
- GtkWidget *w = e_error_new((GtkWindow *)parent, "mail:no-write-path-notfile", filename, NULL);
+ GtkWidget *w = e_error_new(parent, "mail:no-write-path-notfile", filename, NULL);
em_utils_show_error_silent (w);
return FALSE;
}
@@ -632,13 +626,14 @@ emu_save_messages_response(GtkWidget *filesel, gint response, struct _save_messa
* user for filename).
**/
void
-em_utils_save_messages (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids)
+em_utils_save_messages (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids)
{
struct _save_messages_data *data;
GtkWidget *filesel;
gchar *filename = NULL;
CamelMessageInfo *info = NULL;
+ g_return_if_fail (GTK_IS_WINDOW (parent));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
g_return_if_fail (uids != NULL);
@@ -678,7 +673,7 @@ emu_add_address_cb(BonoboListener *listener, const gchar *name, const CORBA_any
/* one of email or vcard should be always NULL, never both of them */
static void
-emu_add_address_or_vcard (GtkWidget *parent, const gchar *email, const gchar *vcard)
+emu_add_address_or_vcard (GtkWindow *parent, const gchar *email, const gchar *vcard)
{
GtkWidget *win;
GtkWidget *control;
@@ -701,14 +696,7 @@ emu_add_address_or_vcard (GtkWidget *parent, const gchar *email, const gchar *vc
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title((GtkWindow *)win, _("Add address"));
- if (parent && !GTK_IS_WINDOW (parent)) {
- parent = gtk_widget_get_toplevel (parent);
- if (!parent || !(GTK_WIDGET_TOPLEVEL (parent)))
- parent = NULL;
- }
-
- if (parent)
- gtk_window_set_transient_for ((GtkWindow *)win, ((GtkWindow *)parent));
+ gtk_window_set_transient_for ((GtkWindow *)win, parent);
gtk_window_set_position((GtkWindow *)win, GTK_WIN_POS_CENTER_ON_PARENT);
gtk_window_set_type_hint((GtkWindow *)win, GDK_WINDOW_TYPE_HINT_DIALOG);
@@ -739,8 +727,10 @@ emu_add_address_or_vcard (GtkWidget *parent, const gchar *email, const gchar *vc
* Add address @email to the addressbook.
**/
void
-em_utils_add_address (GtkWidget *parent, const gchar *email)
+em_utils_add_address (GtkWindow *parent, const gchar *email)
{
+ g_return_if_fail (GTK_IS_WINDOW (parent));
+
emu_add_address_or_vcard (parent, email, NULL);
}
@@ -749,67 +739,19 @@ em_utils_add_address (GtkWidget *parent, const gchar *email)
* Adds whole vCard to the addressbook.
**/
void
-em_utils_add_vcard (GtkWidget *parent, const gchar *vcard)
+em_utils_add_vcard (GtkWindow *parent, const gchar *vcard)
{
+ g_return_if_fail (GTK_IS_WINDOW (parent));
+
emu_add_address_or_vcard (parent, NULL, vcard);
}
/* ********************************************************************** */
/* Flag-for-Followup... */
-/* tag-editor callback data */
-struct ted_t {
- EMFolderView *emfv;
- MessageTagEditor *editor;
- CamelFolder *folder;
- GPtrArray *uids;
-};
-
-static void
-ted_free (struct ted_t *ted)
-{
- camel_object_unref (ted->folder);
- em_utils_uids_free (ted->uids);
- g_free (ted);
-}
-
-static void
-tag_editor_response (GtkWidget *dialog, gint button, struct ted_t *ted)
-{
- CamelFolder *folder;
- CamelTag *tags, *t;
- GPtrArray *uids;
- gint i;
-
- if (button == GTK_RESPONSE_OK && (tags = message_tag_editor_get_tag_list (ted->editor))) {
- folder = ted->folder;
- uids = ted->uids;
-
- camel_folder_freeze (folder);
- for (i = 0; i < uids->len; i++) {
- CamelMessageInfo *mi = camel_folder_get_message_info(folder, uids->pdata[i]);
-
- if (mi) {
- for (t = tags; t; t = t->next)
- camel_message_info_set_user_tag(mi, t->name, t->value);
-
- camel_message_info_free(mi);
- }
- }
-
- camel_folder_thaw (folder);
- camel_tag_list_free (&tags);
-
- if (ted->emfv->preview)
- em_format_redraw (EM_FORMAT (ted->emfv->preview));
- }
-
- gtk_widget_destroy (dialog);
-}
-
/**
* em_utils_flag_for_followup:
- * @parent: parent window
+ * @reader: an #EMailReader
* @folder: folder containing messages to flag
* @uids: uids of messages to flag
*
@@ -817,38 +759,38 @@ tag_editor_response (GtkWidget *dialog, gint button, struct ted_t *ted)
* @folder and @uids.
**/
void
-em_utils_flag_for_followup (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids)
+em_utils_flag_for_followup (EMailReader *reader,
+ CamelFolder *folder,
+ GPtrArray *uids)
{
- GtkWidget *editor;
- struct ted_t *ted;
+ EMFormatHTMLDisplay *html_display;
+ MessageTagEditor *editor;
+ GtkWindow *parent;
+ CamelTag *tags;
gint i;
+ g_return_if_fail (E_IS_MAIL_READER (reader));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
g_return_if_fail (uids != NULL);
- editor = (GtkWidget *) message_tag_followup_new ();
-
- if (parent != NULL)
- e_dialog_set_transient_for ((GtkWindow *) editor, parent);
-
- camel_object_ref (folder);
-
- ted = g_new (struct ted_t, 1);
- ted->emfv = (EMFolderView *) parent;
- ted->editor = MESSAGE_TAG_EDITOR (editor);
- ted->folder = folder;
- ted->uids = uids;
+ editor = message_tag_followup_new ();
+ parent = e_mail_reader_get_window (reader);
+ gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
for (i = 0; i < uids->len; i++) {
CamelMessageInfo *info;
info = camel_folder_get_message_info (folder, uids->pdata[i]);
- if (info) {
- message_tag_followup_append_message (MESSAGE_TAG_FOLLOWUP (editor),
- camel_message_info_from (info),
- camel_message_info_subject (info));
- camel_message_info_free(info);
- }
+
+ if (info == NULL)
+ continue;
+
+ message_tag_followup_append_message (
+ MESSAGE_TAG_FOLLOWUP (editor),
+ camel_message_info_from (info),
+ camel_message_info_subject (info));
+
+ camel_message_info_free(info);
}
/* special-case... */
@@ -857,18 +799,49 @@ em_utils_flag_for_followup (GtkWidget *parent, CamelFolder *folder, GPtrArray *u
info = camel_folder_get_message_info (folder, uids->pdata[0]);
if (info) {
- const CamelTag *tags = camel_message_info_user_tags(info);
+ tags = (CamelTag *) camel_message_info_user_tags (info);
if (tags)
- message_tag_editor_set_tag_list (MESSAGE_TAG_EDITOR (editor), (CamelTag *)tags);
- camel_message_info_free(info);
+ message_tag_editor_set_tag_list (editor, tags);
+ camel_message_info_free (info);
}
}
- g_signal_connect (editor, "response", G_CALLBACK (tag_editor_response), ted);
- g_object_weak_ref ((GObject *) editor, (GWeakNotify) ted_free, ted);
+ if (gtk_dialog_run (GTK_DIALOG (editor)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ tags = message_tag_editor_get_tag_list (editor);
+ if (tags == NULL)
+ goto exit;
+
+ camel_folder_freeze (folder);
+ for (i = 0; i < uids->len; i++) {
+ CamelMessageInfo *info;
+ CamelTag *iter;
+
+ info = camel_folder_get_message_info(folder, uids->pdata[i]);
+
+ if (info == NULL)
+ continue;
+
+ for (iter = tags; iter != NULL; iter = iter->next)
+ camel_message_info_set_user_tag (
+ info, iter->name, iter->value);
+
+ camel_message_info_free (info);
+ }
- gtk_widget_show (editor);
+ camel_folder_thaw (folder);
+ camel_tag_list_free (&tags);
+
+ html_display = e_mail_reader_get_html_display (reader);
+ em_format_redraw (EM_FORMAT (html_display));
+
+exit:
+ /* XXX We shouldn't be freeing this. */
+ em_utils_uids_free (uids);
+
+ gtk_widget_destroy (GTK_WIDGET (editor));
}
/**
@@ -881,10 +854,11 @@ em_utils_flag_for_followup (GtkWidget *parent, CamelFolder *folder, GPtrArray *u
* @folder and @uids.
**/
void
-em_utils_flag_for_followup_clear (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids)
+em_utils_flag_for_followup_clear (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids)
{
gint i;
+ g_return_if_fail (GTK_IS_WINDOW (parent));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
g_return_if_fail (uids != NULL);
@@ -915,11 +889,12 @@ em_utils_flag_for_followup_clear (GtkWidget *parent, CamelFolder *folder, GPtrAr
* Flag-for-Followup.
**/
void
-em_utils_flag_for_followup_completed (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids)
+em_utils_flag_for_followup_completed (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids)
{
gchar *now;
gint i;
+ g_return_if_fail (GTK_IS_WINDOW (parent));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
g_return_if_fail (uids != NULL);
@@ -1375,19 +1350,23 @@ em_utils_temp_save_part(GtkWidget *parent, CamelMimePart *part, gboolean mode)
gboolean
em_utils_folder_is_templates (CamelFolder *folder, const gchar *uri)
{
+ CamelFolder *local_templates_folder;
EAccountList *accounts;
EAccount *account;
EIterator *iter;
gint is = FALSE;
gchar *templates_uri;
- if (folder == mail_component_get_folder (NULL, MAIL_COMPONENT_FOLDER_TEMPLATES))
+ local_templates_folder =
+ e_mail_local_get_folder (E_MAIL_FOLDER_TEMPLATES);
+
+ if (folder == local_templates_folder)
return TRUE;
- if (uri == NULL)
+ if (folder == NULL || uri == NULL)
return FALSE;
- accounts = mail_config_get_accounts();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator ((EList *)accounts);
while (e_iterator_is_valid (iter)) {
account = (EAccount *)e_iterator_get (iter);
@@ -1422,19 +1401,23 @@ em_utils_folder_is_templates (CamelFolder *folder, const gchar *uri)
gboolean
em_utils_folder_is_drafts(CamelFolder *folder, const gchar *uri)
{
+ CamelFolder *local_drafts_folder;
EAccountList *accounts;
EAccount *account;
EIterator *iter;
gint is = FALSE;
gchar *drafts_uri;
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS))
+ local_drafts_folder =
+ e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+
+ if (folder == local_drafts_folder)
return TRUE;
- if (uri == NULL)
+ if (folder == NULL || uri == NULL)
return FALSE;
- accounts = mail_config_get_accounts();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator((EList *)accounts);
while (e_iterator_is_valid(iter)) {
account = (EAccount *)e_iterator_get(iter);
@@ -1469,19 +1452,22 @@ em_utils_folder_is_drafts(CamelFolder *folder, const gchar *uri)
gboolean
em_utils_folder_is_sent(CamelFolder *folder, const gchar *uri)
{
+ CamelFolder *local_sent_folder;
EAccountList *accounts;
EAccount *account;
EIterator *iter;
gint is = FALSE;
gchar *sent_uri;
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT))
+ local_sent_folder = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
+
+ if (folder == local_sent_folder)
return TRUE;
- if (uri == NULL)
+ if (folder == NULL || uri == NULL)
return FALSE;
- accounts = mail_config_get_accounts();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator((EList *)accounts);
while (e_iterator_is_valid(iter)) {
account = (EAccount *)e_iterator_get(iter);
@@ -1516,8 +1502,13 @@ em_utils_folder_is_sent(CamelFolder *folder, const gchar *uri)
gboolean
em_utils_folder_is_outbox(CamelFolder *folder, const gchar *uri)
{
+ CamelFolder *local_outbox_folder;
+
+ local_outbox_folder =
+ e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+
/* <Highlander>There can be only one.</Highlander> */
- return folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
+ return folder == local_outbox_folder;
}
/**
@@ -1592,53 +1583,6 @@ em_utils_get_proxy_uri (const gchar *pUri)
}
/**
- * em_utils_part_to_html:
- * @part:
- *
- * Converts a mime part's contents into html text. If @credits is given,
- * then it will be used as an attribution string, and the
- * content will be cited. Otherwise no citation or attribution
- * will be performed.
- *
- * Return Value: The part in displayable html format.
- **/
-gchar *
-em_utils_part_to_html(CamelMimePart *part, gssize *len, EMFormat *source)
-{
- EMFormatQuote *emfq;
- CamelStreamMem *mem;
- GByteArray *buf;
- gchar *text;
-
- buf = g_byte_array_new ();
- mem = (CamelStreamMem *) camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (mem, buf);
-
- emfq = em_format_quote_new(NULL, (CamelStream *)mem, 0);
- ((EMFormat *) emfq)->composer = TRUE;
- em_format_set_session((EMFormat *)emfq, session);
- if (source) {
- /* copy over things we can, other things are internal, perhaps need different api than 'clone' */
- if (source->default_charset)
- em_format_set_default_charset((EMFormat *)emfq, source->default_charset);
- if (source->charset)
- em_format_set_default_charset((EMFormat *)emfq, source->charset);
- }
- em_format_part((EMFormat *) emfq, (CamelStream *)mem, part);
- g_object_unref(emfq);
-
- camel_stream_write((CamelStream *) mem, "", 1);
- camel_object_unref(mem);
-
- text = (gchar *)buf->data;
- if (len)
- *len = buf->len-1;
- g_byte_array_free (buf, FALSE);
-
- return text;
-}
-
-/**
* em_utils_message_to_html:
* @message:
* @credits:
@@ -1666,7 +1610,6 @@ em_utils_message_to_html(CamelMimeMessage *message, const gchar *credits, guint3
emfq = em_format_quote_new(credits, (CamelStream *)mem, flags);
((EMFormat *) emfq)->composer = TRUE;
- em_format_set_session((EMFormat *)emfq, session);
if (!source) {
GConfClient *gconf;
@@ -1740,7 +1683,7 @@ em_utils_empty_trash (GtkWidget *parent)
camel_exception_init (&ex);
/* expunge all remote stores */
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator ((EList *) accounts);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
@@ -1909,7 +1852,7 @@ gchar *em_uri_to_camel(const gchar *euri)
uid = g_strdup(eurl->host);
}
- accounts = mail_config_get_accounts();
+ accounts = e_get_account_list ();
account = e_account_list_find(accounts, E_ACCOUNT_FIND_UID, uid);
g_free(uid);
@@ -2294,93 +2237,12 @@ em_utils_contact_photo (CamelInternetAddress *cia, gboolean local)
return part;
}
-/**
- * em_utils_snoop_type:
- * @part:
- *
- * Tries to snoop the mime type of a part.
- *
- * Return value: NULL if unknown (more likely application/octet-stream).
- **/
-const gchar *
-em_utils_snoop_type(CamelMimePart *part)
-{
- /* cache is here only to be able still return const gchar * */
- static GHashTable *types_cache = NULL;
-
- const gchar *filename;
- gchar *name_type = NULL, *magic_type = NULL, *res, *tmp;
- CamelDataWrapper *dw;
-
- filename = camel_mime_part_get_filename (part);
- if (filename != NULL)
- name_type = e_util_guess_mime_type (filename, FALSE);
-
- dw = camel_medium_get_content_object((CamelMedium *)part);
- if (!camel_data_wrapper_is_offline(dw)) {
- CamelStreamMem *mem = (CamelStreamMem *)camel_stream_mem_new();
-
- if (camel_data_wrapper_decode_to_stream(dw, (CamelStream *)mem) > 0) {
- gchar *ct = g_content_type_guess (filename, mem->buffer->data, mem->buffer->len, NULL);
-
- if (ct)
- magic_type = g_content_type_get_mime_type (ct);
-
- g_free (ct);
- }
- camel_object_unref(mem);
- }
-
- d(printf("snooped part, magic_type '%s' name_type '%s'\n", magic_type, name_type));
-
- /* If gvfs doesn't recognize the data by magic, but it
- * contains English words, it will call it text/plain. If the
- * filename-based check came up with something different, use
- * that instead and if it returns "application/octet-stream"
- * try to do better with the filename check.
- */
-
- if (magic_type) {
- if (name_type
- && (!strcmp(magic_type, "text/plain")
- || !strcmp(magic_type, "application/octet-stream")))
- res = name_type;
- else
- res = magic_type;
- } else
- res = name_type;
-
- if (res != name_type)
- g_free (name_type);
-
- if (res != magic_type)
- g_free (magic_type);
-
- if (!types_cache)
- types_cache = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) NULL);
-
- if (res) {
- tmp = g_hash_table_lookup (types_cache, res);
- if (tmp) {
- g_free (res);
- res = tmp;
- } else {
- g_hash_table_insert (types_cache, res, res);
- }
- }
-
- return res;
-
- /* We used to load parts to check their type, we dont anymore,
- see bug #11778 for some discussion */
-}
-
void
em_utils_clear_get_password_canceled_accounts_flag (void)
{
EAccountList *accounts;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
if (accounts) {
EIterator *iter;
@@ -2400,25 +2262,73 @@ em_utils_clear_get_password_canceled_accounts_flag (void)
}
}
-static void error_response(GtkObject *o, gint button, gpointer data)
-{
- gtk_widget_destroy((GtkWidget *)o);
-}
-
void
em_utils_show_error_silent (GtkWidget *widget)
{
- EActivityHandler *handler = mail_component_peek_activity_handler (mail_component_peek ());
- if (!g_object_get_data ((GObject *) widget, "response-handled"))
- g_signal_connect(widget, "response", G_CALLBACK(error_response), NULL);
- e_activity_handler_make_error (handler, "mail", E_LOG_ERROR, widget);
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EActivity *activity;
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ activity = e_alert_activity_new_warning (widget);
+ e_shell_backend_add_activity (shell_backend, activity);
+ g_object_unref (activity);
+
+ if (g_object_get_data (G_OBJECT (widget), "response-handled") == NULL)
+ g_signal_connect (
+ widget, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
}
void
em_utils_show_info_silent (GtkWidget *widget)
{
- EActivityHandler *handler = mail_component_peek_activity_handler (mail_component_peek ());
- if (!g_object_get_data ((GObject *) widget, "response-handled"))
- g_signal_connect(widget, "response", G_CALLBACK(error_response), NULL);
- e_activity_handler_make_error (handler, "mail", E_LOG_WARNINGS, widget);
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EActivity *activity;
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ activity = e_alert_activity_new_info (widget);
+ e_shell_backend_add_activity (shell_backend, activity);
+ g_object_unref (activity);
+
+ if (g_object_get_data (G_OBJECT (widget), "response-handled") == NULL)
+ g_signal_connect (
+ widget, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+}
+
+gchar *
+em_utils_url_unescape_amp (const gchar *url)
+{
+ gchar *buff;
+ gint i, j, amps;
+
+ if (!url)
+ return NULL;
+
+ amps = 0;
+ for (i = 0; url [i]; i++) {
+ if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
+ amps++;
+ }
+
+ buff = g_strdup (url);
+
+ if (!amps)
+ return buff;
+
+ for (i = 0, j = 0; url [i]; i++, j++) {
+ buff [j] = url [i];
+
+ if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
+ i += 4;
+ }
+ buff [j] = 0;
+
+ return buff;
}
diff --git a/mail/em-utils.h b/mail/em-utils.h
index 22b47b5be2..14dc8cef23 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -25,33 +25,43 @@
#include <gtk/gtk.h>
#include <sys/types.h>
+#include <camel/camel-exception.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-internet-address.h>
+#include <camel/camel-mime-message.h>
+#include <camel/camel-mime-part.h>
+#include <camel/camel-stream.h>
-#include <mail/em-format.h>
+#include <mail/e-mail-reader.h>
G_BEGIN_DECLS
+struct _EMFormat;
+
+const gchar * em_utils_get_data_dir (void);
+const gchar * em_utils_get_config_dir (void);
+
gboolean em_utils_prompt_user(GtkWindow *parent, const gchar *promptkey, const gchar *tag, const gchar *arg0, ...);
GPtrArray *em_utils_uids_copy (GPtrArray *uids);
void em_utils_uids_free (GPtrArray *uids);
-gboolean em_utils_configure_account (GtkWidget *parent);
-gboolean em_utils_check_user_can_send_mail (GtkWidget *parent);
+gboolean em_utils_check_user_can_send_mail (void);
void em_utils_edit_filters (GtkWidget *parent);
void em_filename_make_safe (gchar *string);
void em_utils_edit_vfolders (GtkWidget *parent);
-void em_utils_save_part(GtkWidget *parent, const gchar *prompt, CamelMimePart *part);
-gboolean em_utils_save_part_to_file(GtkWidget *parent, const gchar *filename, CamelMimePart *part);
-void em_utils_save_messages (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids);
+void em_utils_save_part(GtkWindow *parent, const gchar *prompt, CamelMimePart *part);
+gboolean em_utils_save_part_to_file(GtkWindow *parent, const gchar *filename, CamelMimePart *part);
+void em_utils_save_messages (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
-void em_utils_add_address(GtkWidget *parent, const gchar *email);
-void em_utils_add_vcard(GtkWidget *parent, const gchar *vcard);
+void em_utils_add_address(GtkWindow *parent, const gchar *email);
+void em_utils_add_vcard(GtkWindow *parent, const gchar *vcard);
-void em_utils_flag_for_followup (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids);
-void em_utils_flag_for_followup_clear (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids);
-void em_utils_flag_for_followup_completed (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids);
+void em_utils_flag_for_followup (EMailReader *reader, CamelFolder *folder, GPtrArray *uids);
+void em_utils_flag_for_followup_clear (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
+void em_utils_flag_for_followup_completed (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
/* This stuff that follows probably doesn't belong here, then again, the stuff above probably belongs elsewhere */
@@ -65,7 +75,7 @@ void em_utils_selection_set_urilist(GtkSelectionData *data, CamelFolder *folder,
void em_utils_selection_get_urilist(GtkSelectionData *data, CamelFolder *folder);
gchar *em_utils_temp_save_part(GtkWidget *parent, CamelMimePart *part, gboolean mode);
-void em_utils_save_parts (GtkWidget *parent, const gchar *prompt, GSList * parts);
+void em_utils_save_parts (GtkWindow *parent, const gchar *prompt, GSList * parts);
gboolean em_utils_folder_is_drafts(CamelFolder *folder, const gchar *uri);
gboolean em_utils_folder_is_templates(CamelFolder *folder, const gchar *uri);
@@ -77,8 +87,7 @@ void em_utils_adjustment_page(GtkAdjustment *adj, gboolean down);
gchar *em_utils_get_proxy_uri (const gchar *uri);
/* FIXME: should this have an override charset? */
-gchar *em_utils_part_to_html(CamelMimePart *part, gssize *len, EMFormat *source);
-gchar *em_utils_message_to_html(CamelMimeMessage *msg, const gchar *credits, guint32 flags, gssize *len, EMFormat *source, const gchar *append);
+gchar *em_utils_message_to_html(CamelMimeMessage *msg, const gchar *credits, guint32 flags, gssize *len, struct _EMFormat *source, const gchar *append);
void em_utils_expunge_folder (GtkWidget *parent, CamelFolder *folder);
void em_utils_empty_trash (GtkWidget *parent);
@@ -98,11 +107,12 @@ void em_utils_show_info_silent (GtkWidget *widget);
gboolean em_utils_in_addressbook (CamelInternetAddress *addr, gboolean local_only);
CamelMimePart *em_utils_contact_photo (CamelInternetAddress *addr, gboolean local);
-const gchar *em_utils_snoop_type(CamelMimePart *part);
-
/* clears flag 'get_password_canceled' at every known accounts, so if needed, get_password will show dialog */
void em_utils_clear_get_password_canceled_accounts_flag (void);
+/* Unescapes &amp; back to a real & in URIs */
+gchar *em_utils_url_unescape_amp (const gchar *url);
+
G_END_DECLS
#endif /* __EM_UTILS_H__ */
diff --git a/mail/em-vfolder-editor.c b/mail/em-vfolder-editor.c
index 13a41c1888..058ad0a957 100644
--- a/mail/em-vfolder-editor.c
+++ b/mail/em-vfolder-editor.c
@@ -31,40 +31,49 @@
#include <glib/gi18n.h>
#include "e-util/e-util-private.h"
+#include "e-util/gconf-bridge.h"
#include "em-vfolder-editor.h"
#include "em-vfolder-rule.h"
-#define d(x)
+static gpointer parent_class;
-static FilterRule *create_rule (RuleEditor *re);
+static FilterRule *
+vfolder_editor_create_rule (RuleEditor *rule_editor)
+{
+ FilterRule *rule = filter_rule_new ();
+ FilterPart *part;
-static RuleEditorClass *parent_class = NULL;
+ /* create a rule with 1 part in it */
+ rule = (FilterRule *) em_vfolder_rule_new ();
+ part = rule_context_next_part (rule_editor->context, NULL);
+ filter_rule_add_part (rule, filter_part_clone (part));
-static void
-em_vfolder_editor_finalise (GObject *obj)
-{
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ return rule;
}
static void
-em_vfolder_editor_class_init (EMVFolderEditorClass *klass)
+vfolder_editor_class_init (EMVFolderEditorClass *class)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- RuleEditorClass *re_class = (RuleEditorClass *) klass;
+ RuleEditorClass *rule_editor_class;
- parent_class = g_type_class_ref (rule_editor_get_type ());
+ parent_class = g_type_class_peek_parent (class);
- gobject_class->finalize = em_vfolder_editor_finalise;
-
- /* override methods */
- re_class->create_rule = create_rule;
+ rule_editor_class = RULE_EDITOR_CLASS (class);
+ rule_editor_class->create_rule = vfolder_editor_create_rule;
}
static void
-em_vfolder_editor_init (EMVFolderEditor *ve)
+vfolder_editor_init (EMVFolderEditor *vfolder_editor)
{
- ;
+ GConfBridge *bridge;
+ const gchar *key_prefix;
+
+ bridge = gconf_bridge_get ();
+ key_prefix = "/apps/evolution/mail/vfolder_editor";
+
+ gconf_bridge_bind_window_size (
+ bridge, key_prefix, GTK_WINDOW (vfolder_editor));
}
GType
@@ -72,20 +81,22 @@ em_vfolder_editor_get_type (void)
{
static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
sizeof (EMVFolderEditorClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_vfolder_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) vfolder_editor_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
sizeof (EMVFolderEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_vfolder_editor_init,
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) vfolder_editor_init,
+ NULL /* value_table */
};
- type = g_type_register_static (RULE_TYPE_EDITOR, "EMVFolderEditor", &info, 0);
+ type = g_type_register_static (
+ RULE_TYPE_EDITOR, "EMVFolderEditor", &type_info, 0);
}
return type;
@@ -98,16 +109,17 @@ em_vfolder_editor_get_type (void)
*
* Return value: A new #EMVFolderEditor object.
**/
-EMVFolderEditor *
+GtkWidget *
em_vfolder_editor_new (EMVFolderContext *vc)
{
- EMVFolderEditor *ve = (EMVFolderEditor *) g_object_new (em_vfolder_editor_get_type(), NULL);
+ EMVFolderEditor *ve;
GladeXML *gui;
gchar *gladefile;
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "filter.glade",
- NULL);
+ ve = g_object_new (EM_TYPE_VFOLDER_EDITOR, NULL);
+
+ gladefile = g_build_filename (
+ EVOLUTION_GLADEDIR, "filter.glade", NULL);
gui = glade_xml_new (gladefile, "rule_editor", NULL);
g_free (gladefile);
@@ -116,19 +128,5 @@ em_vfolder_editor_new (EMVFolderContext *vc)
gtk_widget_hide (glade_xml_get_widget (gui, "filter_source_combobox"));
g_object_unref (gui);
- return ve;
-}
-
-static FilterRule *
-create_rule (RuleEditor *re)
-{
- FilterRule *rule = filter_rule_new ();
- FilterPart *part;
-
- /* create a rule with 1 part in it */
- rule = (FilterRule *) em_vfolder_rule_new ();
- part = rule_context_next_part (re->context, NULL);
- filter_rule_add_part (rule, filter_part_clone (part));
-
- return rule;
+ return GTK_WIDGET (ve);
}
diff --git a/mail/em-vfolder-editor.h b/mail/em-vfolder-editor.h
index 58bcd566a1..2a48c46e87 100644
--- a/mail/em-vfolder-editor.h
+++ b/mail/em-vfolder-editor.h
@@ -21,32 +21,47 @@
*
*/
-#ifndef _EM_VFOLDER_EDITOR_H
-#define _EM_VFOLDER_EDITOR_H
+#ifndef EM_VFOLDER_EDITOR_H
+#define EM_VFOLDER_EDITOR_H
#include "filter/rule-editor.h"
#include "em-vfolder-context.h"
-#define EM_VFOLDER_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), em_vfolder_editor_get_type(), EMVFolderEditor))
-#define EM_VFOLDER_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), em_vfolder_editor_get_type(), EMVFolderEditorClass))
-#define EM_IS_VFOLDER_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), em_vfolder_editor_get_type()))
-#define EM_IS_VFOLDER_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), em_vfolder_editor_get_type()))
-#define EM_VFOLDER_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), em_vfolder_editor_get_type(), EMVFolderEditorClass))
+/* Standard GObject macros */
+#define EM_TYPE_VFOLDER_EDITOR \
+ (em_vfolder_editor_get_type ())
+#define EM_VFOLDER_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_VFOLDER_EDITOR, EMVFolderEditor))
+#define EM_VFOLDER_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_VFOLDER_EDITOR, EMVFolderEditorClass))
+#define EM_IS_VFOLDER_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_VFOLDER_EDITOR))
+#define EM_IS_VFOLDER_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_VFOLDER_EDITOR))
+#define EM_VFOLDER_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_VFOLDER_EDITOR, EMVFolderEditorClass))
+
+G_BEGIN_DECLS
typedef struct _EMVFolderEditor EMVFolderEditor;
typedef struct _EMVFolderEditorClass EMVFolderEditorClass;
struct _EMVFolderEditor {
- RuleEditor parent_object;
-
+ RuleEditor parent;
};
struct _EMVFolderEditorClass {
RuleEditorClass parent_class;
};
-GType em_vfolder_editor_get_type (void);
+GType em_vfolder_editor_get_type (void);
+GtkWidget * em_vfolder_editor_new (EMVFolderContext *vc);
-EMVFolderEditor *em_vfolder_editor_new (EMVFolderContext *vc);
+G_END_DECLS
-#endif /* ! _EM_VFOLDER_EDITOR_H */
+#endif /* EM_VFOLDER_EDITOR_H */
diff --git a/mail/em-vfolder-rule.c b/mail/em-vfolder-rule.c
index 7f78c06079..c357065414 100644
--- a/mail/em-vfolder-rule.c
+++ b/mail/em-vfolder-rule.c
@@ -34,10 +34,10 @@
#include "camel/camel-url.h"
#include "em-vfolder-context.h"
#include "em-vfolder-rule.h"
+#include "mail/e-mail-store.h"
#include "mail/em-utils.h"
#include "mail/em-folder-tree.h"
#include "mail/em-folder-selector.h"
-#include "mail/mail-component.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
@@ -507,8 +507,8 @@ source_add(GtkWidget *widget, struct _source_data *data)
EMFolderTree *emft;
GtkWidget *dialog;
- emft =(EMFolderTree *)em_folder_tree_new_with_model(mail_component_peek_tree_model(mail_component_peek()));
- em_folder_tree_set_excluded(emft, EMFT_EXCLUDE_NOSELECT);
+ emft =(EMFolderTree *) em_folder_tree_new ();
+ em_folder_tree_set_excluded (emft, EMFT_EXCLUDE_NOSELECT);
dialog = em_folder_selector_new(emft, EM_FOLDER_SELECTOR_CAN_CREATE, _("Select Folder"), NULL, _("_Add"));
gtk_window_set_transient_for ((GtkWindow *)dialog, (GtkWindow *)gtk_widget_get_toplevel(widget));
diff --git a/mail/evolution-mail.schemas.in b/mail/evolution-mail.schemas.in
index 1ba01e59fe..d6483110c7 100644
--- a/mail/evolution-mail.schemas.in
+++ b/mail/evolution-mail.schemas.in
@@ -26,7 +26,7 @@
<locale name="C">
<short>Spell check inline</short>
<long>
- Draw spelling error indicators on words as you type.
+ Draw spelling error indicators on words as you type.
</long>
</locale>
</schema>
@@ -40,7 +40,7 @@
<locale name="C">
<short>Automatic link recognition</short>
<long>
- Recognize links in text and replace them.
+ Recognize links in text and replace them.
</long>
</locale>
</schema>
@@ -54,7 +54,7 @@
<locale name="C">
<short>Automatic emoticon recognition</short>
<long>
- Recognize emoticons in text and replace them with images.
+ Recognize emoticons in text and replace them with images.
</long>
</locale>
</schema>
@@ -82,7 +82,7 @@
<locale name="C">
<short>Always request read receipt</short>
<long>
- Whether a read receipt request gets added to every message by default.
+ Whether a read receipt request gets added to every message by default.
</long>
</locale>
</schema>
@@ -364,7 +364,7 @@
<locale name="C">
<short>Enable/disable caret mode</short>
<long>
- Enable caret mode, so that you can see a cursor when reading mail.
+ Enable caret mode, so that you can see a cursor when reading mail.
</long>
</locale>
</schema>
@@ -415,6 +415,20 @@
</schema>
<schema>
+ <key>/schema/apps/evolution/mail/display/show_all_headers</key>
+ <applyto>/apps/evolution/mail/display/show_all_headers</applyto>
+ <owner>evolution-mail</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Show all message headers</short>
+ <long>
+ Show all the headers when viewing a messages.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/evolution/mail/display/headers</key>
<applyto>/apps/evolution/mail/display/headers</applyto>
<owner>evolution-mail</owner>
@@ -511,7 +525,7 @@
<locale name="C">
<short>Determines whether to use the same fonts for both "From" and "Subject" lines in the "Messages" column in vertical view.</short>
<long>
- Determines whether to use the same fonts for both "From" and "Subject" lines in the "Messages" column in vertical view.
+ Determines whether to use the same fonts for both "From" and "Subject" lines in the "Messages" column in vertical view.
</long>
</locale>
</schema>
@@ -617,16 +631,19 @@
</schema>
<schema>
- <key>/schemas/apps/evolution/mail/display/show_wide</key>
- <applyto>/apps/evolution/mail/display/show_wide</applyto>
+ <key>/schemas/apps/evolution/mail/display/layout</key>
+ <applyto>/apps/evolution/mail/display/layout</applyto>
<owner>evolution-mail</owner>
- <type>bool</type>
- <default>false</default>
+ <type>int</type>
+ <default>0</default>
<locale name="C">
- <short>Use side-by-side or wide layout</short>
- <long>
- If the &quot;Preview&quot; pane is on, then show it side-by-side rather than vertically.
- </long>
+ <short>Layout style</short>
+ <long>
+ The layout style determines where to place the preview pane
+ in relation to the message list. "0" (Classic View) places
+ the preview pane below the message list. "1" (Vertical View)
+ places the preview pane next to the message list.
+ </long>
</locale>
</schema>
@@ -639,7 +656,7 @@
<locale name="C">
<short>Variable width font</short>
<long>
- The variable width font for mail display.
+ The variable width font for mail display.
</long>
</locale>
</schema>
@@ -653,7 +670,7 @@
<locale name="C">
<short>Terminal font</short>
<long>
- The terminal font for mail display.
+ The terminal font for mail display.
</long>
</locale>
</schema>
@@ -667,7 +684,7 @@
<locale name="C">
<short>Use custom fonts</short>
<long>
- Use custom fonts for displaying mail.
+ Use custom fonts for displaying mail.
</long>
</locale>
</schema>
@@ -695,8 +712,8 @@
<locale name="C">
<short>Compress display of addresses in TO/CC/BCC</short>
<long>
- Compress display of addresses in TO/CC/BCC to the number
- specified in address_count.
+ Compress display of addresses in TO/CC/BCC to the number
+ specified in address_count.
</long>
</locale>
</schema>
@@ -710,7 +727,7 @@
<locale name="C">
<short>Allows Evolution to display text part of limited size</short>
<long>
- Enable to render message text part of limited size.
+ Enable to render message text part of limited size.
</long>
</locale>
</schema>
@@ -724,9 +741,9 @@
<locale name="C">
<short>Text message part limit</short>
<long>
- This decides the max size of the text part that can be formatted under
- Evolution. The default is 4MB / 4096 KB and is specified in terms of KB.
- </long>
+ This decides the max size of the text part that can be formatted under
+ Evolution. The default is 4MB / 4096 KB and is specified in terms of KB.
+ </long>
</locale>
</schema>
@@ -740,7 +757,7 @@
<short>Number of addresses to display in TO/CC/BCC</short>
<long>
This sets the number of addresses to show in default message list
- view, beyond which a '...' is shown.
+ view, beyond which a '...' is shown.
</long>
</locale>
</schema>
@@ -769,8 +786,8 @@
<locale name="C">
<short>Default value for thread expand state</short>
<long>
- This setting specifies whether the threads should be in expanded
- or collapsed state by default. Evolution requires a restart.
+ This setting specifies whether the threads should be in expanded
+ or collapsed state by default. Evolution requires a restart.
</long>
</locale>
</schema>
@@ -784,36 +801,48 @@
<locale name="C">
<short>Whether sort threads based on latest message in that thread</short>
<long>
- This setting specifies whether the threads should be sorted based
- on latest message in each thread, rather than by message's date.
- Evolution requires a restart.
+ This setting specifies whether the threads should be sorted based
+ on latest message in each thread, rather than by message's date.
+ Evolution requires a restart.
</long>
</locale>
</schema>
- <!-- Message Window -->
+ <!-- Mail Browser -->
<schema>
- <key>/schemas/apps/evolution/mail/message_window/width</key>
- <applyto>/apps/evolution/mail/message_window/width</applyto>
+ <key>/schemas/apps/evolution/mail/mail_browser_width</key>
+ <applyto>/apps/evolution/mail/mail_browser_width</applyto>
<owner>evolution-mail</owner>
<type>int</type>
<default>600</default>
<locale name="C">
- <short>Message Window default width</short>
- <long>Default width of the message window.</long>
+ <short>Mail browser width</short>
+ <long>Default width of the mail browser window.</long>
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/mail/message_window/height</key>
- <applyto>/apps/evolution/mail/message_window/height</applyto>
+ <key>/schemas/apps/evolution/mail/mail_browser_height</key>
+ <applyto>/apps/evolution/mail/mail_browser_height</applyto>
<owner>evolution-mail</owner>
<type>int</type>
<default>400</default>
<locale name="C">
- <short>Message Window default height</short>
- <long>Default height of the message window.</long>
+ <short>Mail browser height</short>
+ <long>Default height of the mail browser window.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/mail/mail_browser_maximized</key>
+ <applyto>/apps/evolution/mail/mail_browser_maximized</applyto>
+ <owner>evolution-mail</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Mail browser maximized</short>
+ <long>Default maximized state of the mail browser window.</long>
</locale>
</schema>
@@ -986,8 +1015,8 @@
<locale name="C">
<short>Prompt when user tries to open 10 or more messages at once</short>
<long>
- If a user tries to open 10 or more messages at one time, ask the user
- if they really want to do it.
+ If a user tries to open 10 or more messages at one time, ask the user
+ if they really want to do it.
</long>
</locale>
</schema>
@@ -1001,7 +1030,7 @@
<locale name="C">
<short>Prompt while marking multiple messages</short>
<long>
- Enable or disable the prompt whilst marking multiple messages.
+ Enable or disable the prompt whilst marking multiple messages.
</long>
</locale>
</schema>
@@ -1015,8 +1044,8 @@
<locale name="C">
<short>Prompt to check if the user wants to go offline immediately </short>
<long>
- It disables/enables the repeated prompts to ask if offline
- sync is required before going into offline mode.
+ It disables/enables the repeated prompts to ask if offline
+ sync is required before going into offline mode.
</long>
</locale>
</schema>
@@ -1030,9 +1059,9 @@
<locale name="C">
<short>Prompt when deleting messages in search folder</short>
<long>
- It disables/enables the repeated prompts to warn that deleting
- messages from a search folder permanently deletes the message, not
- simply removing it from the search results.
+ It disables/enables the repeated prompts to warn that deleting
+ messages from a search folder permanently deletes the message, not
+ simply removing it from the search results.
</long>
</locale>
</schema>
@@ -1062,7 +1091,7 @@
<locale name="C">
<short>Minimum days between emptying the trash on exit</short>
<long>
- Minimum time between emptying the trash on exit, in days.
+ Minimum time between emptying the trash on exit, in days.
</long>
</locale>
</schema>
@@ -1076,7 +1105,7 @@
<locale name="C">
<short>Last time empty trash was run</short>
<long>
- The last time empty trash was run, in days since the epoch.
+ The last time empty trash was run, in days since the epoch.
</long>
</locale>
</schema>
@@ -1090,7 +1119,7 @@
<locale name="C">
<short>Amount of time in seconds the error should be shown on the status bar.</short>
<long>
- Amount of time in seconds the error should be shown on the status bar.
+ Amount of time in seconds the error should be shown on the status bar.
</long>
</locale>
</schema>
@@ -1168,7 +1197,7 @@
<locale name="C">
<short>Minimum days between emptying the junk on exit</short>
<long>
- Minimum time between emptying the junk on exit, in days.
+ Minimum time between emptying the junk on exit, in days.
</long>
</locale>
</schema>
@@ -1182,7 +1211,7 @@
<locale name="C">
<short>Last time empty junk was run</short>
<long>
- The last time empty junk was run, in days since the epoch.
+ The last time empty junk was run, in days since the epoch.
</long>
</locale>
</schema>
@@ -1197,8 +1226,8 @@
<short>The default plugin for Junk hook</short>
<long>
This is the default junk plugin, even though there are multiple plugins
- enabled. If the default listed plugin is disabled, then it won't fall back
- to the other available plugins.
+ enabled. If the default listed plugin is disabled, then it won't fall back
+ to the other available plugins.
</long>
</locale>
</schema>
@@ -1211,10 +1240,10 @@
<default>true</default>
<locale name="C">
<short>Use only local spam tests.</short>
- <long>
- Use only the local spam tests (no DNS).
- </long>
- </locale>
+ <long>
+ Use only the local spam tests (no DNS).
+ </long>
+ </locale>
</schema>
<schema>
@@ -1240,7 +1269,7 @@
<locale name="C">
<short>Determines whether to lookup in address book for sender email</short>
<long>
- Determines whether to lookup the sender email in address book. If found, it shouldn't be a spam. It looks up in the books marked for autocompletion. It can be slow, if remote address books (like LDAP) are marked for autocompletion.
+ Determines whether to lookup the sender email in address book. If found, it shouldn't be a spam. It looks up in the books marked for autocompletion. It can be slow, if remote address books (like LDAP) are marked for autocompletion.
</long>
</locale>
</schema>
@@ -1254,7 +1283,7 @@
<locale name="C">
<short>Determines whether to look up addresses for junk filtering in local address book only</short>
<long>
- This option is related to the key lookup_addressbook and is used to determine whether to look up addresses in local address book only to exclude mail sent by known contacts from junk filtering.
+ This option is related to the key lookup_addressbook and is used to determine whether to look up addresses in local address book only to exclude mail sent by known contacts from junk filtering.
</long>
</locale>
</schema>
@@ -1282,7 +1311,7 @@
<locale name="C">
<short>Custom headers to use while checking for junk.</short>
<long>
- Custom headers to use while checking for junk. The list elements
+ Custom headers to use while checking for junk. The list elements
are string in the format "headername=value".
</long>
</locale>
@@ -1363,6 +1392,50 @@
<!-- Widget States -->
<schema>
+ <key>/schemas/apps/evolution/mail/filter_editor_height</key>
+ <applyto>/apps/evolution/mail/filter_editor_height</applyto>
+ <type>int</type>
+ <default>650</default>
+ <locale name="C">
+ <short>"Filter Editor" window height</short>
+ <long>
+ Initial height of the "Filter Editor" window.
+ The value updates as the user resizes the window vertically.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/mail/filter_editor_maximized</key>
+ <applyto>/apps/evolution/mail/filter_editor_maximized</applyto>
+ <type>bool</type>
+ <locale name="C">
+ <short>"Filter Editor" window maximize state</short>
+ <long>
+ Initial maximize state of the "Filter Editor" window.
+ The value updates when the user maximizes or unmaximizes the
+ window. Note, this particular value is not used by Evolution
+ since the "Filter Editor" window cannot be maximized. This
+ key exists only as an implementation detail.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/mail/filter_editor_width</key>
+ <applyto>/apps/evolution/mail/filter_editor_width</applyto>
+ <type>int</type>
+ <default>400</default>
+ <locale name="C">
+ <short>"Filter Editor" window width</short>
+ <long>
+ Initial width of the "Filter Editor" window.
+ The value updates as the user resizes the window horizontally.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/evolution/mail/send_recv_height</key>
<applyto>/apps/evolution/mail/send_recv_height</applyto>
<owner>evolution-mail</owner>
@@ -1409,6 +1482,50 @@
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/evolution/mail/vfolder_editor_height</key>
+ <applyto>/apps/evolution/mail/vfolder_editor_height</applyto>
+ <type>int</type>
+ <default>650</default>
+ <locale name="C">
+ <short>"Search Folder Editor" window height</short>
+ <long>
+ Initial height of the "Search Folder Editor" window.
+ The value updates as the user resizes the window vertically.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/mail/vfolder_editor_maximized</key>
+ <applyto>/apps/evolution/mail/vfolder_editor_maximized</applyto>
+ <type>bool</type>
+ <locale name="C">
+ <short>"Search Folder Editor" window maximize state</short>
+ <long>
+ Initial maximize state of the "Search Folder Editor" window.
+ The value updates when the user maximizes or unmaximizes the
+ window. Note, this particular value is not used by Evolution
+ since the "Search Folder Editor" window cannot be maximized.
+ This key exists only as an implementation detail.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/mail/vfolder_editor_width</key>
+ <applyto>/apps/evolution/mail/vfolder_editor_width</applyto>
+ <type>int</type>
+ <default>400</default>
+ <locale name="C">
+ <short>"Search Folder Editor" window width</short>
+ <long>
+ Initial width of the "Search Folder Editor" window.
+ The value updates as the user resizes the window horizontally.
+ </long>
+ </locale>
+ </schema>
+
<!-- Others -->
<schema>
diff --git a/mail/filtertypes.xml b/mail/filtertypes.xml
index f2f69c4c06..a93b887271 100644
--- a/mail/filtertypes.xml
+++ b/mail/filtertypes.xml
@@ -636,7 +636,7 @@
</option>
</input>
<input type="optionlist" name="versus">
- <dynamic func="e_util_labels_get_filter_options"/>
+ <dynamic func="e_mail_labels_get_filter_options"/>
</input>
</part>
@@ -923,7 +923,7 @@
<title>Set Label</title>
<code>(set-label ${label})</code>
<input type="optionlist" name="label">
- <dynamic func="e_util_labels_get_filter_options"/>
+ <dynamic func="e_mail_labels_get_filter_options"/>
</input>
</part>
<part name="colour">
diff --git a/mail/importers/Makefile.am b/mail/importers/Makefile.am
index 5e46a54c4d..bd38762ea2 100644
--- a/mail/importers/Makefile.am
+++ b/mail/importers/Makefile.am
@@ -1,6 +1,5 @@
if OS_WIN32
WIN32_BOOTSTRAP_LIBS = \
- $(top_builddir)/win32/libevolution-mail-shared.la \
$(top_builddir)/win32/libevolution-mail.la
endif
@@ -10,6 +9,7 @@ AM_CPPFLAGS = -I.. \
-I$(srcdir)/.. \
-I$(top_srcdir) \
-I$(top_srcdir)/widgets \
+ $(EVOLUTION_MAIL_CFLAGS) \
-DG_LOG_DOMAIN=\"evolution-mail-importer\" \
-DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
$(IMPORTERS_CFLAGS)
@@ -27,6 +27,7 @@ libevolution_mail_importers_la_LIBADD = \
$(WIN32_BOOTSTRAP_LIBS) \
$(top_builddir)/e-util/libeutil.la \
$(top_builddir)/filter/libfilter.la \
+ $(top_builddir)/mail/libevolution-mail.la \
$(IMPORTERS_LIBS)
-include $(top_srcdir)/git.mk
diff --git a/mail/importers/evolution-mbox-importer.c b/mail/importers/evolution-mbox-importer.c
index 7cd2b34b22..ade34526fc 100644
--- a/mail/importers/evolution-mbox-importer.c
+++ b/mail/importers/evolution-mbox-importer.c
@@ -40,9 +40,10 @@
#include <camel/camel-exception.h>
+#include "mail/e-mail-local.h"
+#include "mail/e-mail-store.h"
#include "mail/em-folder-selection-button.h"
-
-#include "mail/mail-component.h"
+#include "mail/em-folder-tree-model.h"
#include "mail/mail-mt.h"
#include "mail-importer.h"
@@ -73,15 +74,18 @@ static GtkWidget *
mbox_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im)
{
GtkWidget *hbox, *w;
+ const gchar *local_inbox_uri;
+
+ local_inbox_uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_INBOX);
hbox = gtk_hbox_new(FALSE, 0);
w = gtk_label_new(_("Destination folder:"));
gtk_box_pack_start((GtkBox *)hbox, w, FALSE, TRUE, 6);
- w = em_folder_selection_button_new(_("Select folder"), _("Select folder to import into"));
- em_folder_selection_button_set_selection((EMFolderSelectionButton *)w,
- mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_INBOX));
+ w = em_folder_selection_button_new(
+ _("Select folder"), _("Select folder to import into"));
+ em_folder_selection_button_set_selection((EMFolderSelectionButton *)w, local_inbox_uri);
g_signal_connect(w, "selected", G_CALLBACK(folder_selected), target);
gtk_box_pack_start((GtkBox *)hbox, w, FALSE, TRUE, 6);
diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c
index daecfaee53..61726dd37f 100644
--- a/mail/importers/mail-importer.c
+++ b/mail/importers/mail-importer.c
@@ -36,7 +36,6 @@
#include <glib.h>
#include <glib/gstdio.h>
-#include <gmodule.h>
#include <glib/gi18n.h>
#include <camel/camel-folder.h>
#include <camel/camel-store.h>
@@ -46,10 +45,12 @@
#include <camel/camel-stream-mem.h>
#include "e-util/e-util-private.h"
+#include "shell/e-shell-backend.h"
-#include "mail/mail-mt.h"
-#include "mail/mail-component.h"
-#include "mail/mail-tools.h"
+#include "mail-mt.h"
+#include "mail-tools.h"
+#include "e-mail-local.h"
+#include "em-utils.h"
#include "mail-importer.h"
@@ -113,23 +114,6 @@ mail_importer_add_line (MailImporter *importer,
camel_message_info_free(info);
}
-struct _BonoboObject *mail_importer_factory_cb(struct _BonoboGenericFactory *factory, const gchar *iid, gpointer data)
-{
-#if 0
- if (strcmp(iid, ELM_INTELLIGENT_IMPORTER_IID) == 0)
- return elm_intelligent_importer_new();
- else if (strcmp(iid, PINE_INTELLIGENT_IMPORTER_IID) == 0)
- return pine_intelligent_importer_new();
- else if (strcmp(iid, NETSCAPE_INTELLIGENT_IMPORTER_IID) == 0)
- return netscape_intelligent_importer_new();
- else if (strcmp(iid, MBOX_IMPORTER_IID) == 0)
- return mbox_importer_new();
- else if (strcmp(iid, OUTLOOK_IMPORTER_IID) == 0)
- return outlook_importer_new();
-#endif
- return NULL;
-}
-
struct _import_mbox_msg {
MailMsg base;
@@ -203,7 +187,7 @@ import_mbox_exec (struct _import_mbox_msg *m)
}
if (m->uri == NULL || m->uri[0] == 0)
- folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_INBOX);
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_INBOX);
else
folder = mail_tool_uri_to_folder(m->uri, CAMEL_STORE_FOLDER_CREATE, &m->base.ex);
@@ -360,6 +344,7 @@ import_folders_rec(struct _import_folders_data *m, const gchar *filepath, const
GDir *dir;
const gchar *d;
struct stat st;
+ const gchar *data_dir;
gchar *filefull, *foldersub, *uri, *utf8_filename;
const gchar *folder;
@@ -367,6 +352,8 @@ import_folders_rec(struct _import_folders_data *m, const gchar *filepath, const
if (dir == NULL)
return;
+ data_dir = em_utils_get_data_dir ();
+
utf8_filename = g_filename_to_utf8 (filepath, -1, NULL, NULL, NULL);
camel_operation_start(NULL, _("Scanning %s"), utf8_filename);
g_free (utf8_filename);
@@ -395,9 +382,9 @@ import_folders_rec(struct _import_folders_data *m, const gchar *filepath, const
break;
}
/* FIXME: need a better way to get default store location */
- uri = g_strdup_printf("mbox:%s/local#%s", mail_component_peek_base_directory(NULL), folder);
+ uri = g_strdup_printf("mbox:%s/local#%s", data_dir, folder);
} else {
- uri = g_strdup_printf("mbox:%s/local#%s/%s", mail_component_peek_base_directory(NULL), folderparent, folder);
+ uri = g_strdup_printf("mbox:%s/local#%s/%s", data_dir, folderparent, folder);
}
printf("importing to uri %s\n", uri);
diff --git a/mail/importers/mail-importer.h b/mail/importers/mail-importer.h
index 6c5878e633..d751547827 100644
--- a/mail/importers/mail-importer.h
+++ b/mail/importers/mail-importer.h
@@ -24,10 +24,8 @@
#ifndef __MAIL_IMPORTER_H__
#define __MAIL_IMPORTER_H__
-#include <bonobo/bonobo-generic-factory.h>
-#include <camel/camel-folder.h>
-
#include <e-util/e-import.h>
+#include <camel/camel-folder.h>
typedef struct _MailImporter MailImporter;
struct _MailImporter {
@@ -57,22 +55,6 @@ EImportImporter *mbox_importer_peek(void);
EImportImporter *elm_importer_peek(void);
EImportImporter *pine_importer_peek(void);
-#define ELM_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Elm_Intelligent_Importer:" BASE_VERSION
-#define PINE_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Pine_Intelligent_Importer:" BASE_VERSION
-#define NETSCAPE_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Netscape_Intelligent_Importer:" BASE_VERSION
-
-#define MBOX_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Mbox_Importer:" BASE_VERSION
-#define OUTLOOK_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Outlook_Importer:" BASE_VERSION
-
-BonoboObject *elm_intelligent_importer_new(void);
-BonoboObject *pine_intelligent_importer_new(void);
-BonoboObject *netscape_intelligent_importer_new(void);
-
-BonoboObject *mbox_importer_new(void);
-BonoboObject *outlook_importer_new(void);
-
-BonoboObject *mail_importer_factory_cb(BonoboGenericFactory *factory, const gchar *iid, gpointer data);
-
/* Defines copied from nsMsgMessageFlags.h in Mozilla source. */
/* Evolution only cares about these headers I think */
#define MSG_FLAG_READ 0x0001
diff --git a/mail/mail-autofilter.c b/mail/mail-autofilter.c
index 2efa02e972..ece7e75ca5 100644
--- a/mail/mail-autofilter.c
+++ b/mail/mail-autofilter.c
@@ -32,7 +32,6 @@
#include "mail-vfolder.h"
#include "mail-autofilter.h"
-#include "mail-component.h"
#include "em-utils.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
@@ -345,14 +344,15 @@ void
filter_gui_add_from_message (CamelMimeMessage *msg, const gchar *source, gint flags)
{
EMFilterContext *fc;
+ const gchar *data_dir;
gchar *user, *system;
FilterRule *rule;
g_return_if_fail (msg != NULL);
fc = em_filter_context_new ();
- user = g_strdup_printf ("%s/filters.xml",
- mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
rule_context_load ((RuleContext *)fc, system, user);
g_free (system);
@@ -370,6 +370,7 @@ void
mail_filter_rename_uri(CamelStore *store, const gchar *olduri, const gchar *newuri)
{
EMFilterContext *fc;
+ const gchar *data_dir;
gchar *user, *system;
GList *changed;
gchar *eolduri, *enewuri;
@@ -378,7 +379,8 @@ mail_filter_rename_uri(CamelStore *store, const gchar *olduri, const gchar *newu
enewuri = em_uri_from_camel(newuri);
fc = em_filter_context_new ();
- user = g_strdup_printf ("%s/filters.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
rule_context_load ((RuleContext *)fc, system, user);
g_free (system);
@@ -402,6 +404,7 @@ void
mail_filter_delete_uri(CamelStore *store, const gchar *uri)
{
EMFilterContext *fc;
+ const gchar *data_dir;
gchar *user, *system;
GList *deleted;
gchar *euri;
@@ -409,7 +412,8 @@ mail_filter_delete_uri(CamelStore *store, const gchar *uri)
euri = em_uri_from_camel(uri);
fc = em_filter_context_new ();
- user = g_strdup_printf ("%s/filters.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
rule_context_load ((RuleContext *)fc, system, user);
g_free (system);
diff --git a/mail/mail-component-factory.c b/mail/mail-component-factory.c
deleted file mode 100644
index 9a95823bd4..0000000000
--- a/mail/mail-component-factory.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "mail-component.h"
-#include "em-account-prefs.h"
-#include "em-mailer-prefs.h"
-#include "em-composer-prefs.h"
-#include "em-network-prefs.h"
-
-#include "mail-config-factory.h"
-#include "mail-config.h"
-#include "mail-mt.h"
-
-#include "em-popup.h"
-#include "em-menu.h"
-#include "em-event.h"
-#include "em-config.h"
-#include "em-format-hook.h"
-#include "em-junk-hook.h"
-#include "em-format-html-display.h"
-
-#include "importers/mail-importer.h"
-#include "e-util/e-import.h"
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-shlib-factory.h>
-
-#include <string.h>
-
-/* TODO: clean up these definitions */
-
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Mail_Factory:" BASE_VERSION
-#define COMPONENT_ID "OAFIID:GNOME_Evolution_Mail_Component:" BASE_VERSION
-#define FOLDER_INFO_ID "OAFIID:GNOME_Evolution_FolderInfo:" BASE_VERSION
-
-static BonoboObject *
-factory(BonoboGenericFactory *factory, const gchar *component_id, gpointer closure)
-{
- BonoboObject *o;
-
- if (strcmp (component_id, COMPONENT_ID) == 0) {
- MailComponent *component = mail_component_peek ();
-
- bonobo_object_ref (BONOBO_OBJECT (component));
- return BONOBO_OBJECT (component);
- } else if (strcmp (component_id, EM_ACCOUNT_PREFS_CONTROL_ID) == 0
- || strcmp (component_id, EM_MAILER_PREFS_CONTROL_ID) == 0
- || strcmp (component_id, EM_COMPOSER_PREFS_CONTROL_ID) == 0
- || strcmp (component_id, EM_NETWORK_PREFS_CONTROL_ID) == 0) {
- return mail_config_control_factory_cb (factory, component_id, CORBA_OBJECT_NIL);
- }
-
- o = mail_importer_factory_cb(factory, component_id, NULL);
- if (o == NULL)
- g_warning (FACTORY_ID ": Don't know what to do with %s", component_id);
-
- return o;
-}
-
-static Bonobo_Unknown
-make_factory (PortableServer_POA poa, const gchar *iid, gpointer impl_ptr, CORBA_Environment *ev)
-{
- static gint init = 0;
-
- if (!init) {
- EImportClass *klass;
-
- init = 1;
-
- mail_config_init();
- mail_msg_init();
-
- e_plugin_hook_register_type(em_popup_hook_get_type());
- e_plugin_hook_register_type(em_menu_hook_get_type());
- e_plugin_hook_register_type(em_config_hook_get_type());
-
- em_format_hook_register_type(em_format_get_type());
- em_format_hook_register_type(em_format_html_get_type());
- em_format_hook_register_type(em_format_html_display_get_type());
- em_junk_hook_register_type(emj_get_type());
-
- e_plugin_hook_register_type(em_format_hook_get_type());
- e_plugin_hook_register_type(em_event_hook_get_type());
- e_plugin_hook_register_type(em_junk_hook_get_type());
-
- klass = g_type_class_ref(e_import_get_type());
- e_import_class_add_importer(klass, mbox_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, elm_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, pine_importer_peek(), NULL, NULL);
- }
-
- return bonobo_shlib_factory_std (FACTORY_ID, poa, impl_ptr, factory, NULL, ev);
-}
-
-static BonoboActivationPluginObject plugin_list[] = {
- { FACTORY_ID, make_factory},
- { NULL }
-};
-
-const BonoboActivationPlugin Bonobo_Plugin_info = {
- plugin_list, "Evolution Mail component factory"
-};
diff --git a/mail/mail-component.c b/mail/mail-component.c
index 4e19002ca0..46c48b5516 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -37,7 +37,7 @@
#include <libedataserver/e-data-server-util.h>
#include "em-utils.h"
#include "em-composer-utils.h"
-#include "em-format.h"
+#include "em-format/em-format.h"
#include "em-folder-tree.h"
#include "em-folder-browser.h"
#include "em-message-browser.h"
@@ -99,35 +99,6 @@
#define d(x)
-static void create_local_item_cb(EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data);
-static void view_changed_timeout_remove (EComponentView *component_view);
-
-#define MAIL_COMPONENT_DEFAULT(mc) if (mc == NULL) mc = mail_component_peek();
-
-extern gint camel_application_is_exiting;
-
-#define PARENT_TYPE evolution_component_get_type ()
-static BonoboObjectClass *parent_class = NULL;
-const gchar *x_mailer = "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT;
-#define OFFLINE 0
-#define ONLINE 1
-
-struct _store_info {
- CamelStore *store;
- gchar *name;
-
- /* we keep a reference to these so they remain around for the session */
- CamelFolder *vtrash;
- CamelFolder *vjunk;
-
- /* for setup only */
- void (*done)(CamelStore *store, CamelFolderInfo *info, gpointer data);
- gpointer done_data;
-
- gint ref_count:31;
- guint removed:1;
-};
-
struct _MailComponentPrivate {
GMutex *lock;
@@ -158,359 +129,9 @@ struct _MailComponentPrivate {
guint mail_sync_in_progress; /* is greater than 0 if still waiting to finish sync on some store */
};
-/* indexed by _mail_component_folder_t */
-static struct {
- const gchar *name;
- gchar *uri;
- CamelFolder *folder;
-} mc_default_folders[] = {
- /* translators: standard local mailbox names */
- { N_("Inbox"), },
- { N_("Drafts"), },
- { N_("Outbox"), },
- { N_("Sent"), },
- { N_("Templates"), },
- { "Inbox", }, /* 'always local' inbox */
-};
-
-static struct _store_info *
-store_info_new(CamelStore *store, const gchar *name)
-{
- struct _store_info *si;
-
- si = g_malloc0(sizeof(*si));
- si->ref_count = 1;
- if (name == NULL)
- si->name = camel_service_get_name((CamelService *)store, TRUE);
- else
- si->name = g_strdup(name);
- si->store = store;
- camel_object_ref(store);
- /* If these are vfolders then they need to be opened now,
- * otherwise they wont keep track of all folders */
- if ((store->flags & CAMEL_STORE_VTRASH) != 0)
- si->vtrash = camel_store_get_trash(store, NULL);
- if ((store->flags & CAMEL_STORE_VJUNK) != 0)
- si->vjunk = camel_store_get_junk(store, NULL);
-
- return si;
-}
-
-static void
-store_info_ref(struct _store_info *si)
-{
- si->ref_count++;
-}
-
-static void
-store_info_unref(struct _store_info *si)
-{
- if (si->ref_count > 1) {
- si->ref_count--;
- return;
- }
-
- if (si->vtrash)
- camel_object_unref(si->vtrash);
- if (si->vjunk)
- camel_object_unref(si->vjunk);
- camel_object_unref(si->store);
- g_free(si->name);
- g_free(si);
-}
-
-static gboolean
-mc_add_store_done(CamelStore *store, CamelFolderInfo *info, gpointer data)
-{
- struct _store_info *si = data;
-
- if (si->done)
- si->done(store, info, si);
-
- if (!si->removed) {
- /* let the counters know about the already opened junk/trash folders */
- if (si->vtrash)
- mail_note_folder(si->vtrash);
- if (si->vjunk)
- mail_note_folder(si->vjunk);
- }
-
- store_info_unref(si);
-
- return TRUE;
-}
-
-/* Utility functions. */
-static void
-mc_add_store(MailComponent *component, CamelStore *store, const gchar *name, void (*done)(CamelStore *store, CamelFolderInfo *info, gpointer data))
-{
- struct _store_info *si;
-
- MAIL_COMPONENT_DEFAULT(component);
-
- si = store_info_new(store, name);
- si->done = done;
- g_hash_table_insert(component->priv->store_hash, store, si);
- em_folder_tree_model_add_store(component->priv->model, store, si->name);
- store_info_ref(si);
- mail_note_store(store, NULL, mc_add_store_done, si);
-}
-
-static void
-mc_add_local_store_done(CamelStore *store, CamelFolderInfo *info, gpointer data)
-{
- /*MailComponent *mc = data;*/
- gint i;
-
- for (i=0;i<sizeof(mc_default_folders)/sizeof(mc_default_folders[0]);i++) {
- if (mc_default_folders[i].folder)
- mail_note_folder(mc_default_folders[i].folder);
- }
-}
-
-static void
-mc_add_local_store(CamelStore *store, const gchar *name, MailComponent *mc)
-{
- mc_add_store(mc, store, name, mc_add_local_store_done);
- camel_object_unref(store);
- g_object_unref(mc);
-}
-
-static void
-mc_setup_local_store(MailComponent *mc)
-{
- MailComponentPrivate *p = mc->priv;
- CamelURL *url;
- gchar *tmp;
- CamelException ex;
- gint i;
-
- g_mutex_lock(p->lock);
- if (p->local_store != NULL) {
- g_mutex_unlock(p->lock);
- return;
- }
-
- camel_exception_init(&ex);
-
- url = camel_url_new("mbox:", NULL);
- tmp = g_build_filename (p->base_directory, "local", NULL);
- camel_url_set_path(url, tmp);
- g_free(tmp);
- tmp = camel_url_to_string(url, 0);
- p->local_store = (CamelStore *)camel_session_get_service(session, tmp, CAMEL_PROVIDER_STORE, &ex);
- g_free(tmp);
- if (p->local_store == NULL)
- goto fail;
-
- for (i=0;i<sizeof(mc_default_folders)/sizeof(mc_default_folders[0]);i++) {
- /* FIXME: should this uri be account relative? */
- camel_url_set_fragment(url, mc_default_folders[i].name);
- mc_default_folders[i].uri = camel_url_to_string(url, 0);
- mc_default_folders[i].folder = camel_store_get_folder(p->local_store, mc_default_folders[i].name,
- CAMEL_STORE_FOLDER_CREATE, &ex);
- camel_exception_clear(&ex);
- }
-
- camel_url_free(url);
- g_mutex_unlock(p->lock);
-
- g_object_ref(mc);
- camel_object_ref(p->local_store);
- mail_async_event_emit(p->async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)mc_add_local_store, p->local_store, _("On This Computer"), mc);
-
- return;
-fail:
- g_mutex_unlock(p->lock);
-
- g_warning("Could not setup local store/folder: %s", ex.desc);
-
- camel_url_free(url);
- camel_exception_clear(&ex);
-}
-
-static void
-load_accounts (MailComponent *component, EAccountList *accounts)
-{
- EIterator *iter;
-
- /* Load each service (don't connect!). Check its provider and
- * see if this belongs in the shell's folder list. If so, add
- * it.
- */
-
- iter = e_list_get_iterator ((EList *) accounts);
- while (e_iterator_is_valid (iter)) {
- EAccountService *service;
- EAccount *account;
- const gchar *name;
-
- account = (EAccount *) e_iterator_get (iter);
- service = account->source;
- name = account->name;
-
- /* HACK: mbox url's are handled by the local store setup above,
- any that come through as account sources are really movemail sources! */
- if (account->enabled
- && service->url != NULL
- && service->url[0]
- && strncmp(service->url, "mbox:", 5) != 0)
- mail_component_load_store_by_uri (component, service->url, name);
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-}
-
-static void
-setup_search_context (MailComponent *component)
-{
- MailComponentPrivate *priv = component->priv;
-
- if (priv->search_context == NULL) {
- gchar *user = g_build_filename(component->priv->base_directory, "searches.xml", NULL);
- gchar *system = g_build_filename (EVOLUTION_PRIVDATADIR, "searchtypes.xml", NULL);
-
- priv->search_context = (RuleContext *)em_search_context_new ();
- g_object_set_data_full (G_OBJECT (priv->search_context), "user", user, g_free);
- g_object_set_data_full (G_OBJECT (priv->search_context), "system", system, g_free);
- rule_context_load (priv->search_context, system, user);
- }
-}
-
-static void
-mc_startup(MailComponent *mc)
-{
- static gint started = 0;
- GConfClient *gconf;
-
- if (started)
- return;
- started = 1;
-
- mc_setup_local_store(mc);
- load_accounts(mc, mail_config_get_accounts());
-
- gconf = mail_config_get_gconf_client();
-
- if (gconf_client_get_bool (gconf, "/apps/evolution/mail/display/enable_vfolders", NULL))
- vfolder_load_storage();
-}
-
-static void
-folder_selected_cb (EMFolderTree *emft, const gchar *path, const gchar *uri, guint32 flags, EMFolderView *view)
-{
- EMFolderTreeModel *model;
-
- if ((flags & CAMEL_FOLDER_NOSELECT) || !path) {
- em_folder_view_set_folder (view, NULL, NULL);
- } else {
- model = em_folder_tree_get_model (emft);
- em_folder_tree_model_set_selected (model, uri);
- em_folder_tree_model_save_state (model);
-
- em_folder_view_set_folder_uri (view, uri);
- }
-}
-
-static void
-tree_hidden_key_event_cb (EMFolderTree *emft, GdkEvent *event, EMFolderView *view)
-{
- if (event && event->type == GDK_KEY_PRESS && view && view->list) {
- switch (event->key.keyval) {
- case '[':
- case ',':
- gtk_widget_grab_focus ((GtkWidget *) view->list);
- message_list_select (view->list, MESSAGE_LIST_SELECT_PREVIOUS|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
- break;
- case ']':
- case '.':
- gtk_widget_grab_focus ((GtkWidget *) view->list);
- message_list_select (view->list, MESSAGE_LIST_SELECT_NEXT|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
- break;
- }
- }
-}
-
-static gint
-check_autosave(gpointer data)
-{
- e_msg_composer_check_autosave(NULL);
-
- return FALSE;
-}
-
-static void
-view_control_activate_cb (BonoboControl *control, gboolean activate, EMFolderView *view)
-{
- BonoboUIComponent *uic;
- static gint recover = 0;
-
- uic = bonobo_control_get_ui_component (control);
- g_return_if_fail (uic != NULL);
-
- if (activate) {
- Bonobo_UIContainer container;
-
- container = bonobo_control_get_remote_ui_container (control, NULL);
- bonobo_ui_component_set_container (uic, container, NULL);
- bonobo_object_release_unref (container, NULL);
-
- g_return_if_fail (container == bonobo_ui_component_get_container(uic));
- g_return_if_fail (container != CORBA_OBJECT_NIL);
-
- em_folder_view_activate (view, uic, activate);
- e_user_creatable_items_handler_activate(g_object_get_data((GObject *)view, "e-creatable-items-handler"), uic);
- } else {
- em_folder_view_activate (view, uic, activate);
- bonobo_ui_component_unset_container (uic, NULL);
- }
-
- /* This is a weird place to put it, but createControls does it too early.
- I also think we should wait to do it until we actually visit the mailer.
- The delay is arbitrary - without it it shows up before the main window */
- if (!recover) {
- recover = 1;
- g_timeout_add(1000, check_autosave, NULL);
- }
-}
-
/* GObject methods. */
static void
-impl_dispose (GObject *object)
-{
- MailComponentPrivate *priv = MAIL_COMPONENT (object)->priv;
-
- if (priv->mail_sync_id) {
- g_source_remove (priv->mail_sync_id);
- priv->mail_sync_id = 0;
- }
-
- view_changed_timeout_remove ((EComponentView *)object);
-
- if (priv->activity_handler != NULL) {
- g_object_unref (priv->activity_handler);
- priv->activity_handler = NULL;
- }
-
- if (priv->search_context != NULL) {
- g_object_unref (priv->search_context);
- priv->search_context = NULL;
- }
-
- if (priv->local_store != NULL) {
- camel_object_unref (priv->local_store);
- priv->local_store = NULL;
- }
-
- priv->component_view = NULL;
-
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
impl_finalize (GObject *object)
{
MailComponentPrivate *priv = MAIL_COMPONENT (object)->priv;
@@ -542,157 +163,6 @@ view_on_url (GObject *emitter, const gchar *url, const gchar *nice_url, MailComp
}
static void
-view_changed(EMFolderView *emfv, EComponentView *component_view)
-{
- EInfoLabel *el = g_object_get_data((GObject *)component_view, "info-label");
- CORBA_Environment ev;
-
- CORBA_exception_init(&ev);
-
- if (emfv->folder) {
- gchar *name, *title;
- const gchar *use_name; /* will contain localized name, if necessary */
- guint32 visible, unread, deleted, junked, junked_not_deleted;
- GPtrArray *selected;
- GString *tmp = g_string_new("");
-
- camel_object_get(emfv->folder, NULL,
- CAMEL_FOLDER_NAME, &name,
- CAMEL_FOLDER_DELETED, &deleted,
- CAMEL_FOLDER_VISIBLE, &visible,
- CAMEL_FOLDER_JUNKED, &junked,
- CAMEL_FOLDER_JUNKED_NOT_DELETED, &junked_not_deleted,
- CAMEL_FOLDER_UNREAD, &unread, NULL);
-
- selected = message_list_get_selected(emfv->list);
-
- /* This is so that if any of these are
- * shared/reused, we fallback to the standard
- * display behaviour */
- if (selected->len > 1)
- g_string_append_printf(tmp, ngettext ("%d selected, ", "%d selected, ", selected->len), selected->len);
-
- if (CAMEL_IS_VTRASH_FOLDER(emfv->folder)) {
- if (((CamelVTrashFolder *)emfv->folder)->type == CAMEL_VTRASH_FOLDER_TRASH) {
- g_string_append_printf(tmp, ngettext ("%d deleted", "%d deleted", deleted), deleted);
- } else {
- guint32 num = junked_not_deleted;
-
- if (!emfv->hide_deleted)
- num = junked;
-
- g_string_append_printf (tmp, ngettext ("%d junk", "%d junk", num), num);
- }
- } else if (em_utils_folder_is_drafts(emfv->folder, emfv->folder_uri)) {
- g_string_append_printf(tmp, ngettext ("%d draft", "%d drafts", visible), visible);
- } else if (em_utils_folder_is_sent(emfv->folder, emfv->folder_uri)) {
- g_string_append_printf(tmp, ngettext ("%d sent", "%d sent", visible), visible);
- } else if (em_utils_folder_is_outbox(emfv->folder, emfv->folder_uri)) {
- g_string_append_printf(tmp, ngettext ("%d unsent", "%d unsent", visible), visible);
- /* HACK: hardcoded inbox or maildir '.' folder */
- } else {
- if (!emfv->hide_deleted)
- visible += deleted - junked + junked_not_deleted;
- if (unread && selected->len <= 1)
- g_string_append_printf(tmp, ngettext ("%d unread, ", "%d unread, ", unread), unread);
- g_string_append_printf(tmp, ngettext ("%d total", "%d total", visible), visible);
- }
-
- message_list_free_uids(emfv->list, selected);
-
- if (emfv->folder->parent_store == mail_component_peek_local_store(NULL)
- && (!strcmp (name, "Drafts") || !strcmp (name, "Inbox")
- || !strcmp (name, "Outbox") || !strcmp (name, "Sent") || !strcmp (name, "Templates")))
- use_name = _(name);
- else if (!strcmp (name, "INBOX"))
- use_name = _("Inbox");
- else
- use_name = name;
-
- e_info_label_set_info (el, use_name, tmp->str);
- title = g_strdup_printf ("%s (%s)", use_name, tmp->str);
- e_component_view_set_title(component_view, title);
- g_free(title);
-
- g_string_free(tmp, TRUE);
- camel_object_free(emfv->folder, CAMEL_FOLDER_NAME, name);
- } else {
- e_info_label_set_info(el, _("Mail"), "");
- e_component_view_set_title(component_view, _("Mail"));
- }
-}
-
-static void
-view_changed_timeout_remove (EComponentView *component_view)
-{
- gpointer v;
- EInfoLabel *el;
- EMFolderView *emfv;
-
- v = g_object_get_data((GObject *)component_view, "view-changed-timeout");
- if (v) {
- g_source_remove(GPOINTER_TO_INT(v));
- g_object_set_data((GObject *)component_view, "view-changed-timeout", NULL);
-
- el = g_object_get_data((GObject *)component_view, "info-label");
- emfv = g_object_get_data((GObject *)el, "folderview");
- g_object_unref(el);
- g_object_unref(emfv);
- }
-}
-
-static gint
-view_changed_timeout(gpointer d)
-{
- EComponentView *component_view = d;
- EInfoLabel *el = g_object_get_data((GObject *)component_view, "info-label");
- EMFolderView *emfv = g_object_get_data((GObject *)el, "folderview");
-
- view_changed(emfv, component_view);
-
- g_object_set_data((GObject *)component_view, "view-changed-timeout", NULL);
-
- g_object_unref(el);
- g_object_unref(emfv);
-
- return 0;
-}
-
-static void
-view_changed_cb(EMFolderView *emfv, EComponentView *component_view)
-{
- MailComponent *mc = mail_component_peek ();
- gpointer v;
- EInfoLabel *el = g_object_get_data((GObject *)component_view, "info-label");
-
- v = g_object_get_data((GObject *)component_view, "view-changed-timeout");
-
- if (mc->priv->quit_state != -1) {
- if (v) {
- g_source_remove(GPOINTER_TO_INT(v));
- g_object_set_data((GObject *)component_view, "view-changed-timeout", NULL);
- g_object_unref (emfv);
- g_object_unref (el);
- }
-
- return;
-
- }
- /* This can get called 3 times every cursor move, so
- we don't need to/want to run it immediately */
-
- /* NB: we should have a 'view' struct/object to manage this crap, but this'll do for now */
- if (v) {
- g_source_remove(GPOINTER_TO_INT(v));
- } else {
- g_object_ref(emfv);
- g_object_ref(el);
- }
-
- g_object_set_data((GObject *)component_view, "view-changed-timeout", GINT_TO_POINTER(g_timeout_add(250, view_changed_timeout, component_view)));
-}
-
-static void
disable_folder_tree (gpointer *emfb, GtkWidget *widget)
{
gtk_widget_set_sensitive (widget, FALSE);
@@ -759,60 +229,59 @@ impl_createView (PortableServer_Servant servant,
em_folder_browser_suppress_message_selection (
(EMFolderBrowser *) view_widget);
- tree_widget = (GtkWidget *) em_folder_tree_new_with_model (priv->model);
- em_folder_tree_set_excluded ((EMFolderTree *) tree_widget, 0);
- em_folder_tree_enable_drag_and_drop ((EMFolderTree *) tree_widget);
-
- if ((uri = em_folder_tree_model_get_selected (priv->model))) {
- gboolean expanded;
-
- expanded = em_folder_tree_model_get_expanded_uri (priv->model, uri);
- em_folder_tree_set_selected ((EMFolderTree *) tree_widget, uri, FALSE);
- em_folder_view_set_folder_uri ((EMFolderView *) view_widget, uri);
-
- if (!expanded)
- em_folder_tree_model_set_expanded_uri (priv->model, uri, expanded);
-
- g_free (uri);
- }
+// tree_widget = (GtkWidget *) em_folder_tree_new_with_model (priv->model);
+// em_folder_tree_set_excluded ((EMFolderTree *) tree_widget, 0);
+// em_folder_tree_enable_drag_and_drop ((EMFolderTree *) tree_widget);
+
+// if ((uri = em_folder_tree_model_get_selected (priv->model))) {
+// gboolean expanded;
+//
+// expanded = em_folder_tree_model_get_expanded_uri (priv->model, uri);
+// em_folder_tree_set_selected ((EMFolderTree *) tree_widget, uri, FALSE);
+// em_folder_view_set_folder_uri ((EMFolderView *) view_widget, uri);
+//
+// if (!expanded)
+// em_folder_tree_model_set_expanded_uri (priv->model, uri, expanded);
+//
+// g_free (uri);
+// }
em_format_set_session ((EMFormat *) ((EMFolderView *) view_widget)->preview, session);
g_signal_connect (view_widget, "on-url", G_CALLBACK (view_on_url), mail_component);
em_folder_view_set_statusbar ((EMFolderView*)view_widget, FALSE);
- statusbar_widget = e_task_bar_new ();
- e_activity_handler_attach_task_bar (priv->activity_handler, E_TASK_BAR (statusbar_widget));
+// statusbar_widget = e_task_bar_new ();
+// e_activity_handler_attach_task_bar (priv->activity_handler, E_TASK_BAR (statusbar_widget));
gtk_widget_show (tree_widget);
gtk_widget_show (view_widget);
gtk_widget_show (statusbar_widget);
- vbox = gtk_vbox_new(FALSE, 0);
- info = e_info_label_new("evolution-mail");
- e_info_label_set_info((EInfoLabel *)info, _("Mail"), "");
- gtk_box_pack_start((GtkBox *)vbox, info, FALSE, TRUE, 0);
- gtk_box_pack_start((GtkBox *)vbox, tree_widget, TRUE, TRUE, 0);
+// vbox = gtk_vbox_new(FALSE, 0);
+// info = e_info_label_new("evolution-mail");
+// e_info_label_set_info((EInfoLabel *)info, _("Mail"), "");
+// gtk_box_pack_start((GtkBox *)vbox, info, FALSE, TRUE, 0);
+// gtk_box_pack_start((GtkBox *)vbox, tree_widget, TRUE, TRUE, 0);
gtk_widget_show(info);
gtk_widget_show(vbox);
- component_view = e_component_view_new(parent, "mail", vbox, view_widget, statusbar_widget);
-
- g_object_set_data((GObject *)component_view, "info-label", info);
-
- g_object_set_data_full((GObject *)view_widget, "e-creatable-items-handler",
- e_user_creatable_items_handler_new("mail", create_local_item_cb, tree_widget),
- (GDestroyNotify)g_object_unref);
+// component_view = e_component_view_new(parent, "mail", vbox, view_widget, statusbar_widget);
+//
+// g_object_set_data((GObject *)component_view, "info-label", info);
+//
+// g_object_set_data_full((GObject *)view_widget, "e-creatable-items-handler",
+// e_user_creatable_items_handler_new("mail", create_local_item_cb, tree_widget),
+// (GDestroyNotify)g_object_unref);
g_signal_connect (component_view->view_control, "activate", G_CALLBACK (view_control_activate_cb), view_widget);
- g_signal_connect (tree_widget, "folder-selected", G_CALLBACK (folder_selected_cb), view_widget);
- g_signal_connect (tree_widget, "hidden-key-event", G_CALLBACK (tree_hidden_key_event_cb), view_widget);
+// g_signal_connect (tree_widget, "folder-selected", G_CALLBACK (folder_selected_cb), view_widget);
g_signal_connect((EMFolderBrowser *)view_widget, "account_search_cleared", G_CALLBACK (enable_folder_tree), tree_widget);
g_signal_connect(((EMFolderBrowser *)view_widget), "account_search_activated", G_CALLBACK (disable_folder_tree), tree_widget);
- g_signal_connect(view_widget, "changed", G_CALLBACK(view_changed_cb), component_view);
- g_signal_connect(view_widget, "loaded", G_CALLBACK(view_changed_cb), component_view);
+// g_signal_connect(view_widget, "changed", G_CALLBACK(view_changed_cb), component_view);
+// g_signal_connect(view_widget, "loaded", G_CALLBACK(view_changed_cb), component_view);
g_object_set_data((GObject*)info, "folderview", view_widget);
g_object_set_data((GObject*)view_widget, "foldertree", tree_widget);
@@ -822,438 +291,6 @@ impl_createView (PortableServer_Servant servant,
return BONOBO_OBJREF(component_view);
}
-static CORBA_boolean
-impl_requestQuit(PortableServer_Servant servant, CORBA_Environment *ev)
-{
- /*MailComponent *mc = MAIL_COMPONENT(bonobo_object_from_servant(servant));*/
- CamelFolder *folder;
- guint32 unsent;
-
- if (!e_msg_composer_request_close_all())
- return FALSE;
-
- folder = mc_default_folders[MAIL_COMPONENT_FOLDER_OUTBOX].folder;
- if (folder != NULL
- && camel_session_is_online(session)
- && camel_object_get(folder, NULL, CAMEL_FOLDER_VISIBLE, &unsent, 0) == 0
- && unsent > 0
- && e_error_run(NULL, "mail:exit-unsaved", NULL) != GTK_RESPONSE_YES)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-mc_quit_sync_done(CamelStore *store, gpointer data)
-{
- MailComponent *mc = data;
-
- mc->priv->quit_count--;
-}
-
-static void
-mc_quit_sync(CamelStore *store, struct _store_info *si, MailComponent *mc)
-{
- mc->priv->quit_count++;
- mail_sync_store(store, mc->priv->quit_expunge, mc_quit_sync_done, mc);
-}
-
-static void
-mc_quit_delete (CamelStore *store, struct _store_info *si, MailComponent *mc)
-{
- CamelFolder *folder = camel_store_get_junk (store, NULL);
-
- if (folder) {
- GPtrArray *uids;
- gint i;
-
- uids = camel_folder_get_uids (folder);
- camel_folder_freeze(folder);
- for (i=0;i<uids->len;i++)
- camel_folder_set_message_flags(folder, uids->pdata[i], CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN);
- camel_folder_thaw(folder);
- camel_folder_free_uids (folder, uids);
- }
-}
-
-static CORBA_boolean
-impl_quit(PortableServer_Servant servant, CORBA_Environment *ev)
-{
- MailComponent *mc = MAIL_COMPONENT(bonobo_object_from_servant(servant));
-
- if (mc->priv->quit_state == -1)
- mc->priv->quit_state = MC_QUIT_START;
-
- mail_config_prune_proxies ();
- switch (mc->priv->quit_state) {
- case MC_QUIT_START: {
- gint now = time(NULL)/60/60/24, days;
- gboolean empty_junk;
-
- GConfClient *gconf = mail_config_get_gconf_client();
-
- camel_application_is_exiting = TRUE;
-
- mail_vfolder_shutdown();
-
- mc->priv->quit_expunge = gconf_client_get_bool(gconf, "/apps/evolution/mail/trash/empty_on_exit", NULL)
- && ((days = gconf_client_get_int(gconf, "/apps/evolution/mail/trash/empty_on_exit_days", NULL)) == 0
- || (days + gconf_client_get_int(gconf, "/apps/evolution/mail/trash/empty_date", NULL)) <= now);
-
- empty_junk = gconf_client_get_bool(gconf, "/apps/evolution/mail/junk/empty_on_exit", NULL)
- && ((days = gconf_client_get_int(gconf, "/apps/evolution/mail/junk/empty_on_exit_days", NULL)) == 0
- || (days + gconf_client_get_int(gconf, "/apps/evolution/mail/junk/empty_date", NULL)) <= now);
-
- if (empty_junk) {
- g_hash_table_foreach(mc->priv->store_hash, (GHFunc)mc_quit_delete, mc);
- gconf_client_set_int(gconf, "/apps/evolution/mail/junk/empty_date", now, NULL);
- }
-
- g_hash_table_foreach(mc->priv->store_hash, (GHFunc)mc_quit_sync, mc);
-
- if (mc->priv->quit_expunge)
- gconf_client_set_int(gconf, "/apps/evolution/mail/trash/empty_date", now, NULL);
-
- mc->priv->quit_state = MC_QUIT_SYNC;
- }
- /* Falls through */
- case MC_QUIT_SYNC:
- if (mc->priv->quit_count > 0 || mc->priv->mail_sync_in_progress > 0)
- return FALSE;
-
- mail_cancel_all();
- mc->priv->quit_state = MC_QUIT_THREADS;
-
- /* Falls through */
- case MC_QUIT_THREADS:
- /* should we keep cancelling? */
- if (mail_msg_active((guint)-1))
- return FALSE;
-
- mail_session_shutdown ();
- return TRUE;
- }
-
- return TRUE;
-}
-
-static GNOME_Evolution_CreatableItemTypeList *
-impl__get_userCreatableItems (PortableServer_Servant servant, CORBA_Environment *ev)
-{
- GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
-
- list->_length = 2;
- list->_maximum = list->_length;
- list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
-
- CORBA_sequence_set_release (list, FALSE);
-
- list->_buffer[0].id = (gchar *) "message";
- list->_buffer[0].description = _("New Mail Message");
- list->_buffer[0].menuDescription = (gchar *) C_("New", "_Mail Message");
- list->_buffer[0].tooltip = _("Compose a new mail message");
- list->_buffer[0].menuShortcut = 'm';
- list->_buffer[0].iconName = (gchar *) "mail-message-new";
- list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[1].id = (gchar *) "folder";
- list->_buffer[1].description = _("New Mail Folder");
- list->_buffer[1].menuDescription = (gchar *) C_("New", "Mail _Folder");
- list->_buffer[1].tooltip = _("Create a new mail folder");
- list->_buffer[1].menuShortcut = '\0';
- list->_buffer[1].iconName = (gchar *) "folder-new";
- list->_buffer[1].type = GNOME_Evolution_CREATABLE_FOLDER;
-
- return list;
-}
-
-static gint
-create_item(const gchar *type, EMFolderTreeModel *model, const gchar *uri, gpointer tree)
-{
- if (strcmp(type, "message") == 0) {
- if (!em_utils_check_user_can_send_mail(NULL))
- return 0;
-
- em_utils_compose_new_message(uri);
- } else if (strcmp(type, "folder") == 0) {
- em_folder_utils_create_folder (NULL, tree, NULL);
- } else
- return -1;
-
- return 0;
-}
-
-static void
-create_local_item_cb(EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data)
-{
- EMFolderTree *tree = data;
- gchar *uri = em_folder_tree_get_selected_uri(tree);
-
- create_item(item_type_name, em_folder_tree_get_model(tree), uri, (gpointer) tree);
- g_free(uri);
-}
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
- const CORBA_char *item_type_name,
- CORBA_Environment *ev)
-{
- MailComponent *mc = MAIL_COMPONENT(bonobo_object_from_servant(servant));
-
- if (create_item(item_type_name, mc->priv->model, NULL, NULL) == -1) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Component_UnknownType, NULL);
- }
-}
-
-static void
-handleuri_got_folder(gchar *uri, CamelFolder *folder, gpointer data)
-{
- CamelURL *url = data;
- EMMessageBrowser *emmb;
-
- if (folder != NULL) {
- const gchar *reply = camel_url_get_param(url, "reply");
- const gchar *forward = camel_url_get_param(url, "forward");
- gint mode;
-
- if (reply) {
-
- if (!strcmp(reply, "all"))
- mode = REPLY_MODE_ALL;
- else if (!strcmp(reply, "list"))
- mode = REPLY_MODE_LIST;
- else /* if "sender" or anything else */
- mode = REPLY_MODE_SENDER;
-
- em_utils_reply_to_message(folder, camel_url_get_param(url, "uid"), NULL, mode, NULL);
- } else if (forward) {
- GPtrArray *uids;
- const gchar * uid;
-
- uid = camel_url_get_param(url, "uid");
- if (uid == NULL)
- g_warning("Could not forward the message. UID is NULL.");
- else {
- uids = g_ptr_array_new();
- g_ptr_array_add(uids, g_strdup(uid));
-
- if (!strcmp(forward, "attached"))
- em_utils_forward_attached(folder, uids, uri);
- else if (!strcmp(forward, "inline"))
- em_utils_forward_inline(folder, uids, uri);
- else if (!strcmp(forward, "quoted"))
- em_utils_forward_quoted(folder, uids, uri);
- else { /* Just the default forward */
- em_utils_forward_messages(folder, uids, uri);
- }
- }
- } else {
- emmb = (EMMessageBrowser *)em_message_browser_window_new();
- /*message_list_set_threaded(((EMFolderView *)emmb)->list, emfv->list->threaded);*/
- /* FIXME: session needs to be passed easier than this */
- em_format_set_session((EMFormat *)((EMFolderView *)emmb)->preview, session);
- em_folder_view_set_folder((EMFolderView *)emmb, folder, uri);
- em_folder_view_set_message((EMFolderView *)emmb, camel_url_get_param(url, "uid"), FALSE);
- gtk_widget_show(emmb->window);
- }
- } else {
- g_warning("Couldn't open folder '%s'", uri);
- }
- camel_url_free(url);
-}
-
-static void
-impl_handleURI (PortableServer_Servant servant, const gchar *uri, CORBA_Environment *ev)
-{
- if (!strncmp (uri, "mailto:", 7)) {
- if (!em_utils_check_user_can_send_mail(NULL))
- return;
-
- em_utils_compose_new_message_with_mailto (uri, NULL);
- } else if (!strncmp(uri, "email:", 6)) {
- CamelURL *url = camel_url_new(uri, NULL);
-
- if (camel_url_get_param(url, "uid") != NULL) {
- gchar *curi = em_uri_to_camel(uri);
-
- mail_get_folder(curi, 0, handleuri_got_folder, url, mail_msg_unordered_push);
- g_free(curi);
- } else {
- g_warning("email uri's must include a uid parameter");
- camel_url_free(url);
- }
- }
-}
-
-static void
-impl_sendAndReceive (PortableServer_Servant servant, CORBA_Environment *ev)
-{
- em_utils_clear_get_password_canceled_accounts_flag ();
- mail_send_receive ();
-}
-
-static void
-impl_upgradeFromVersion (PortableServer_Servant servant, const short major, const short minor, const short revision, CORBA_Environment *ev)
-{
- MailComponent *component;
- CamelException ex;
-
- component = mail_component_peek ();
-
- camel_exception_init (&ex);
- if (em_migrate (e_get_user_data_dir (), major, minor, revision, &ex) == -1) {
- GNOME_Evolution_Component_UpgradeFailed *failedex;
-
- failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
- failedex->what = CORBA_string_dup(_("Failed upgrading Mail settings or folders."));
- failedex->why = CORBA_string_dup(ex.desc);
- CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
- }
-
- camel_exception_clear (&ex);
-}
-
-static void
-mc_sync_store_done (CamelStore *store, gpointer data)
-{
- MailComponent *mc = (MailComponent *) data;
-
- mc->priv->mail_sync_in_progress--;
-}
-
-static void
-mc_sync_store (gpointer key, gpointer value, gpointer user_data)
-{
- MailComponent *mc = (MailComponent *) user_data;
-
- mc->priv->mail_sync_in_progress++;
-
- if (!camel_application_is_exiting)
- mail_sync_store (CAMEL_STORE (key), FALSE, mc_sync_store_done, mc);
- else
- mc_sync_store_done (CAMEL_STORE (key), mc);
-}
-
-static gboolean
-call_mail_sync (gpointer user_data)
-{
- MailComponent *mc = (MailComponent *)user_data;
-
- if (camel_application_is_exiting)
- return FALSE;
-
- if (!mc->priv->mail_sync_in_progress && session && camel_session_is_online (session))
- mail_component_stores_foreach (mc, mc_sync_store, mc);
-
- return !camel_application_is_exiting;
-}
-
-struct _setline_data {
- GNOME_Evolution_Listener listener;
- CORBA_boolean status;
- gint pending;
-};
-
-static void
-setline_done(CamelStore *store, gpointer data)
-{
- struct _setline_data *sd = data;
-
- g_return_if_fail (sd->pending > 0);
-
- sd->pending--;
- if (sd->pending == 0) {
- CORBA_Environment ev = { NULL };
-
- GNOME_Evolution_Listener_complete(sd->listener, &ev);
- CORBA_exception_free(&ev);
- CORBA_Object_release(sd->listener, &ev);
- CORBA_exception_free(&ev);
- if (!sd->status)
- camel_session_set_online(session, sd->status);
- g_free(sd);
- }
-}
-
-static void
-setline_check(gpointer key, gpointer value, gpointer data)
-{
- CamelService *service = key;
- struct _setline_data *sd = data;
-
- if (CAMEL_IS_DISCO_STORE(service)
- || CAMEL_IS_OFFLINE_STORE(service)) {
- sd->pending++;
- mail_store_set_offline((CamelStore *)service, !sd->status, setline_done, sd);
- }
-}
-
-gint
-status_check (GNOME_Evolution_ShellState shell_state)
-{
- gint status = 0;
-
- switch (shell_state)
- {
- case GNOME_Evolution_USER_OFFLINE:
- status = OFFLINE;
- if (em_utils_prompt_user (NULL, "/apps/evolution/mail/prompts/quick_offline", "mail:ask-quick-offline", NULL))
- break;
- case GNOME_Evolution_FORCED_OFFLINE:
- /*Network is down so change network state on the camel session*/
- status = OFFLINE;
- /* Cancel all operations as they wont happen anyway cos Network is down*/
- mail_cancel_all ();
- camel_session_set_network_state (session, FALSE);
- break;
- case GNOME_Evolution_USER_ONLINE:
- camel_session_set_network_state (session, TRUE);
- status = ONLINE;
- }
-
- return status;
-}
-
-static void
-impl_setLineStatus(PortableServer_Servant servant, GNOME_Evolution_ShellState shell_state, GNOME_Evolution_Listener listener, CORBA_Environment *ev)
-{
- struct _setline_data *sd;
- gint status = status_check(shell_state);
-
- /* This will dis/enable further auto-mail-check action. */
- /* FIXME: If send/receive active, wait for it to finish? */
- if (status)
- camel_session_set_online(session, status);
-
- sd = g_malloc0(sizeof(*sd));
- sd->status = status;
- sd->listener = CORBA_Object_duplicate(listener, ev);
- if (ev->_major == CORBA_NO_EXCEPTION)
- mail_component_stores_foreach(mail_component_peek(), setline_check, sd);
- else
- CORBA_exception_free(ev);
-
- if (sd->pending == 0) {
- if (sd->listener) {
- CORBA_Object_release(sd->listener, ev);
- CORBA_exception_free(ev);
- }
-
- g_free(sd);
-
- if (!status)
- camel_session_set_online(session, status);
- GNOME_Evolution_Listener_complete(listener, ev);
- }
-}
-
-static void
-impl_mail_test(PortableServer_Servant servant, CORBA_Environment *ev)
-{
- printf("*** Testing mail interface!! ***\n");
-}
-
/* Initialization. */
static void
@@ -1268,32 +305,27 @@ mail_component_class_init (MailComponentClass *class)
parent_class = g_type_class_peek_parent (class);
- object_class->dispose = impl_dispose;
object_class->finalize = impl_finalize;
epv->createView = impl_createView;
- epv->requestQuit = impl_requestQuit;
- epv->quit = impl_quit;
- epv->_get_userCreatableItems = impl__get_userCreatableItems;
- epv->requestCreateItem = impl_requestCreateItem;
- epv->handleURI = impl_handleURI;
- epv->sendAndReceive = impl_sendAndReceive;
- epv->upgradeFromVersion = impl_upgradeFromVersion;
- epv->setLineStatus = impl_setLineStatus;
-
- mepv->test = impl_mail_test;
-
- /* Register attachment handler types. */
- e_attachment_handler_mail_get_type ();
-}
+// epv->quit = impl_quit;
+// epv->_get_userCreatableItems = impl__get_userCreatableItems;
+// epv->requestCreateItem = impl_requestCreateItem;
+// epv->handleURI = impl_handleURI;
+// epv->sendAndReceive = impl_sendAndReceive;
+// epv->upgradeFromVersion = impl_upgradeFromVersion;
+// epv->setLineStatus = impl_setLineStatus;
-static void
-store_hash_free (struct _store_info *si)
-{
- si->removed = 1;
- store_info_unref(si);
+// mepv->test = impl_mail_test;
}
+//static void
+//store_hash_free (struct _store_info *si)
+//{
+// si->removed = 1;
+// store_info_unref(si);
+//}
+
static void
mail_component_init (MailComponent *component)
{
@@ -1305,318 +337,42 @@ mail_component_init (MailComponent *component)
priv->lock = g_mutex_new();
priv->quit_state = -1;
- /* FIXME This is used as both a filename and URI path throughout
- * the mail code. Need to clean this up; maybe provide a
- * mail_component_get_base_uri() function. */
- priv->base_directory = g_build_filename (e_get_user_data_dir (), "mail", NULL);
-#ifdef G_OS_WIN32
- {
- gchar *p = priv->base_directory;
- while ((p = strchr(p, '\\')))
- *p++ = '/';
- }
-#endif
-
- if (g_mkdir_with_parents (e_get_user_data_dir (), 0777) == -1 && errno != EEXIST)
- abort ();
-
- priv->model = em_folder_tree_model_new (e_get_user_data_dir ());
+// /* FIXME This is used as both a filename and URI path throughout
+// * the mail code. Need to clean this up; maybe provide a
+// * mail_component_get_base_uri() function. */
+// priv->base_directory = g_build_filename (e_get_user_data_dir (), "mail", NULL);
+//#ifdef G_OS_WIN32
+// {
+// gchar *p = priv->base_directory;
+// while ((p = strchr(p, '\\')))
+// *p++ = '/';
+// }
+//#endif
+
+// if (g_mkdir_with_parents (e_get_user_data_dir (), 0777) == -1 && errno != EEXIST)
+// abort ();
+
+// priv->model = em_folder_tree_model_new (e_get_user_data_dir ());
priv->logger = e_logger_create ("mail");
priv->activity_handler = e_activity_handler_new ();
e_activity_handler_set_logger (priv->activity_handler, priv->logger);
e_activity_handler_set_error_flush_time (priv->activity_handler, mail_config_get_error_timeout ()*1000);
- mail_session_init (e_get_user_data_dir ());
-
- priv->async_event = mail_async_event_new();
- priv->store_hash = g_hash_table_new_full (
- NULL, NULL,
- (GDestroyNotify) NULL,
- (GDestroyNotify) store_hash_free);
-
- mail_autoreceive_init (session);
-
- priv->mail_sync_in_progress = 0;
- if (g_getenv("CAMEL_FLUSH_CHANGES"))
- priv->mail_sync_id = g_timeout_add_seconds (mail_config_get_sync_timeout (), call_mail_sync, component);
- else
- priv->mail_sync_id = 0;
-}
-
-/* Public API. */
-MailComponent *
-mail_component_peek (void)
-{
- static MailComponent *component = NULL;
-
- if (component == NULL)
- component = g_object_new(mail_component_get_type(), NULL);
-
- return component;
-}
-
-const gchar *
-mail_component_peek_base_directory (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- return component->priv->base_directory;
-}
-
-RuleContext *
-mail_component_peek_search_context (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- setup_search_context(component);
-
- return component->priv->search_context;
-}
+// mail_session_init (e_get_user_data_dir ());
-EActivityHandler *
-mail_component_peek_activity_handler (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- return component->priv->activity_handler;
-}
+// priv->async_event = mail_async_event_new();
+// priv->store_hash = g_hash_table_new_full (
+// NULL, NULL,
+// (GDestroyNotify) NULL,
+// (GDestroyNotify) store_hash_free);
-CamelSession *mail_component_peek_session(MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
+// mail_autoreceive_init (session);
- return session;
-}
-
-void
-mail_component_add_store (MailComponent *component, CamelStore *store, const gchar *name)
-{
- mc_add_store(component, store, name, NULL);
-}
-
-/**
- * mail_component_load_store_by_uri:
- * @component: mail component
- * @uri: uri of store
- * @name: name of store (used for display purposes)
- *
- * Return value: Pointer to the newly added CamelStore. The caller is supposed
- * to ref the object if it wants to store it.
- **/
-CamelStore *
-mail_component_load_store_by_uri (MailComponent *component, const gchar *uri, const gchar *name)
-{
- CamelException ex;
- CamelStore *store;
- CamelProvider *prov;
-
- MAIL_COMPONENT_DEFAULT(component);
-
- camel_exception_init (&ex);
-
- /* Load the service (don't connect!). Check its provider and
- * see if this belongs in the shell's folder list. If so, add
- * it.
- */
-
- prov = camel_provider_get(uri, &ex);
- if (prov == NULL) {
- /* EPFIXME: real error dialog */
- g_warning ("couldn't get service %s: %s\n", uri,
- camel_exception_get_description (&ex));
- camel_exception_clear (&ex);
- return NULL;
- }
-
- if (!(prov->flags & CAMEL_PROVIDER_IS_STORAGE))
- return NULL;
-
- store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex);
- if (store == NULL) {
- /* EPFIXME: real error dialog */
- g_warning ("couldn't get service %s: %s\n", uri,
- camel_exception_get_description (&ex));
- camel_exception_clear (&ex);
- return NULL;
- }
-
- mail_component_add_store(component, store, name);
- camel_object_unref (store);
-
- return store;
-}
-
-static void
-store_disconnect (CamelStore *store, gpointer event_data, gpointer user_data)
-{
- camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
- camel_object_unref (store);
-}
-
-void
-mail_component_remove_store (MailComponent *component, CamelStore *store)
-{
- MailComponentPrivate *priv;
-
- MAIL_COMPONENT_DEFAULT(component);
-
- priv = component->priv;
-
- /* Because the store_hash holds a reference to each store
- * used as a key in it, none of them will ever be gc'ed, meaning
- * any call to camel_session_get_{service,store} with the same
- * URL will always return the same object. So this works.
- */
-
- if (g_hash_table_lookup (priv->store_hash, store) == NULL)
- return;
-
- camel_object_ref (store);
- g_hash_table_remove (priv->store_hash, store);
-
- /* so i guess potentially we could have a race, add a store while one
- being removed. ?? */
- mail_note_store_remove (store);
-
- em_folder_tree_model_remove_store (priv->model, store);
-
- mail_async_event_emit (priv->async_event, MAIL_ASYNC_THREAD, (MailAsyncFunc) store_disconnect, store, NULL, NULL);
-}
-
-void
-mail_component_remove_store_by_uri (MailComponent *component, const gchar *uri)
-{
- CamelProvider *prov;
- CamelStore *store;
-
- MAIL_COMPONENT_DEFAULT(component);
-
- if (!(prov = camel_provider_get(uri, NULL)))
- return;
-
- if (!(prov->flags & CAMEL_PROVIDER_IS_STORAGE))
- return;
-
- store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, NULL);
- if (store != NULL) {
- mail_component_remove_store (component, store);
- camel_object_unref (store);
- }
-}
-
-gint
-mail_component_get_store_count (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- return g_hash_table_size (component->priv->store_hash);
-}
-
-/* need to map from internal struct to external api */
-struct _store_foreach_data {
- GHFunc func;
- gpointer data;
-};
-
-static void
-mc_stores_foreach(CamelStore *store, struct _store_info *si, struct _store_foreach_data *data)
-{
- data->func((gpointer)store, (gpointer)si->name, data->data);
-}
-
-void
-mail_component_stores_foreach (MailComponent *component, GHFunc func, gpointer user_data)
-{
- struct _store_foreach_data data = { func, user_data };
-
- MAIL_COMPONENT_DEFAULT(component);
-
- g_hash_table_foreach (component->priv->store_hash, (GHFunc)mc_stores_foreach, &data);
-}
-
-void
-mail_component_remove_folder (MailComponent *component, CamelStore *store, const gchar *path)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- /* FIXME: implement me. but first, am I really even needed? */
-}
-
-EMFolderTreeModel *
-mail_component_peek_tree_model (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- return component->priv->model;
-}
-
-CamelStore *
-mail_component_peek_local_store (MailComponent *mc)
-{
- MAIL_COMPONENT_DEFAULT (mc);
- mc_setup_local_store (mc);
-
- return mc->priv->local_store;
-}
-
-/**
- * mail_component_get_folder:
- * @mc:
- * @id:
- *
- * Get a standard/default folder by id. This call is thread-safe.
- *
- * Return value:
- **/
-CamelFolder *
-mail_component_get_folder(MailComponent *mc, enum _mail_component_folder_t id)
-{
- g_return_val_if_fail (id <= MAIL_COMPONENT_FOLDER_LOCAL_INBOX, NULL);
-
- MAIL_COMPONENT_DEFAULT(mc);
- mc_setup_local_store(mc);
-
- return mc_default_folders[id].folder;
-}
-
-/**
- * mail_component_get_folder_uri:
- * @mc:
- * @id:
- *
- * Get a standard/default folder's uri. This call is thread-safe.
- *
- * Return value:
- **/
-const gchar *
-mail_component_get_folder_uri(MailComponent *mc, enum _mail_component_folder_t id)
-{
- g_return_val_if_fail (id <= MAIL_COMPONENT_FOLDER_LOCAL_INBOX, NULL);
-
- MAIL_COMPONENT_DEFAULT(mc);
- mc_setup_local_store(mc);
-
- return mc_default_folders[id].uri;
-}
-
-/**
- * mail_indicate_new_mail
- * Indicates new mail in a shell window.
- * @param have_new_mail TRUE when have new mail, false otherwise.
- **/
-void
-mail_indicate_new_mail (gboolean have_new_mail)
-{
- const gchar *icon = NULL;
- MailComponent *mc = mail_component_peek ();
-
- g_return_if_fail (mc != NULL);
-
- if (have_new_mail)
- icon = "mail-unread";
-
- if (mc->priv->component_view)
- e_component_view_set_button_icon (mc->priv->component_view, icon);
+// priv->mail_sync_in_progress = 0;
+// if (g_getenv("CAMEL_FLUSH_CHANGES"))
+// priv->mail_sync_id = g_timeout_add_seconds (mail_config_get_sync_timeout (), call_mail_sync, component);
+// else
+// priv->mail_sync_id = 0;
}
void
@@ -1627,14 +383,3 @@ mail_component_show_logger (gpointer top)
eni_show_logger(logger, top, MAILER_ERROR_TIME_OUT_KEY, MAILER_ERROR_LEVEL_KEY);
}
-
-void
-mail_component_show_status_bar (gboolean show)
-{
- /*MailComponent *mc = mail_component_peek ();*/
-
- /* Nothing to do */
- return;
-}
-
-BONOBO_TYPE_FUNC_FULL (MailComponent, GNOME_Evolution_MailComponent, PARENT_TYPE, mail_component)
diff --git a/mail/mail-component.h b/mail/mail-component.h
index fee8599e7c..f69a3c2cff 100644
--- a/mail/mail-component.h
+++ b/mail/mail-component.h
@@ -72,8 +72,6 @@ const gchar *mail_component_peek_base_directory (MailComponent *compone
RuleContext *mail_component_peek_search_context (MailComponent *component);
EActivityHandler *mail_component_peek_activity_handler (MailComponent *component);
-CamelSession *mail_component_peek_session(MailComponent *);
-
void mail_component_add_store (MailComponent *component,
CamelStore *store,
const gchar *name);
diff --git a/mail/mail-config-factory.c b/mail/mail-config-factory.c
deleted file mode 100644
index 75442b27fb..0000000000
--- a/mail/mail-config-factory.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "em-account-prefs.h"
-#include "em-composer-prefs.h"
-#include "em-mailer-prefs.h"
-#include "em-network-prefs.h"
-
-#include "mail-config-factory.h"
-
-#define CONFIG_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Mail_ConfigControlFactory:" BASE_VERSION
-
-BonoboObject *
-mail_config_control_factory_cb (BonoboGenericFactory *factory, const gchar *component_id, gpointer user_data)
-{
- GNOME_Evolution_Shell shell = (GNOME_Evolution_Shell) user_data;
- EvolutionConfigControl *control;
- GtkWidget *prefs = NULL;
-
- if (!strcmp (component_id, EM_ACCOUNT_PREFS_CONTROL_ID)) {
- prefs = em_account_prefs_new (shell);
- } else if (!strcmp (component_id, EM_MAILER_PREFS_CONTROL_ID)) {
- prefs = em_mailer_prefs_new ();
- } else if (!strcmp (component_id, EM_COMPOSER_PREFS_CONTROL_ID)) {
- prefs = em_composer_prefs_new ();
- } else if (!strcmp (component_id, EM_NETWORK_PREFS_CONTROL_ID)) {
- prefs = em_network_prefs_new ();
- } else {
- g_return_val_if_reached(NULL);
- }
-
- gtk_widget_show_all (prefs);
-
- control = evolution_config_control_new (prefs);
-
- return BONOBO_OBJECT (control);
-}
diff --git a/mail/mail-config.c b/mail/mail-config.c
index d9a86f6452..1ac6892b74 100644
--- a/mail/mail-config.c
+++ b/mail/mail-config.c
@@ -37,10 +37,7 @@
#include <gtk/gtk.h>
#include <glib/gstdio.h>
-
-#ifndef G_OS_WIN32
-#include <sys/wait.h>
-#endif
+#include <glib/gi18n-lib.h>
#include <gtkhtml/gtkhtml.h>
#include <glade/glade.h>
@@ -48,19 +45,11 @@
#include <libxml/tree.h>
#include <libxml/parser.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-context.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <bonobo/bonobo-exception.h>
-
#include <libedataserver/e-data-server-util.h>
#include <e-util/e-util.h>
#include <misc/e-gui-utils.h>
-#include "e-util/e-util-labels.h"
-
-#include <libedataserver/e-account-list.h>
-#include <e-util/e-signature-list.h>
+#include "e-util/e-account-utils.h"
+#include "e-util/e-signature-utils.h"
#include <camel/camel-service.h>
#include <camel/camel-stream-mem.h>
@@ -70,22 +59,18 @@
#include <libedataserverui/e-passwords.h>
-#include "mail-component.h"
#include "mail-session.h"
#include "mail-config.h"
#include "mail-mt.h"
#include "mail-tools.h"
+#include "em-utils.h"
+#include "e-mail-local.h"
typedef struct {
GConfClient *gconf;
- gboolean corrupt;
-
gchar *gtkrc;
- EAccountList *accounts;
- ESignatureList *signatures;
-
GSList *labels;
gboolean address_compress;
@@ -110,18 +95,6 @@ extern gint camel_header_param_encode_filenames_in_rfc_2047;
static MailConfig *config = NULL;
static guint config_write_timeout = 0;
-void
-mail_config_save_accounts (void)
-{
- e_account_list_save (config->accounts);
-}
-
-void
-mail_config_save_signatures (void)
-{
- e_signature_list_save (config->signatures);
-}
-
static void
config_clear_mime_types (void)
{
@@ -215,33 +188,6 @@ config_write_style (void)
}
static void
-config_clear_labels (void)
-{
- if (!config)
- return;
-
- e_util_labels_free (config->labels);
- config->labels = NULL;
-}
-
-static void
-config_cache_labels (GConfClient *client)
-{
- if (!config)
- return;
-
- config->labels = e_util_labels_parse (client);
-}
-
-static void
-gconf_labels_changed (GConfClient *client, guint cnxn_id,
- GConfEntry *entry, gpointer user_data)
-{
- config_clear_labels ();
- config_cache_labels (client);
-}
-
-static void
gconf_style_changed (GConfClient *client, guint cnxn_id,
GConfEntry *entry, gpointer user_data)
{
@@ -368,9 +314,6 @@ mail_config_init (void)
mail_config_clear ();
- config->accounts = e_account_list_new (config->gconf);
- config->signatures = e_signature_list_new (config->gconf);
-
gtk_rc_parse (config->gtkrc);
/* Composer Configuration */
@@ -473,18 +416,6 @@ mail_config_init (void)
gconf_client_notify_add (
config->gconf, key, func, NULL, NULL, NULL);
- /* Label Configuration */
-
- gconf_client_add_dir (
- config->gconf, E_UTIL_LABELS_GCONF_KEY,
- GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
-
- gconf_client_notify_add (
- config->gconf, E_UTIL_LABELS_GCONF_KEY,
- gconf_labels_changed, NULL, NULL, NULL);
-
- config_cache_labels (config->gconf);
-
/* MIME Type Configuration */
gconf_client_add_dir (
@@ -549,28 +480,23 @@ mail_config_clear (void)
if (!config)
return;
- if (config->accounts) {
- g_object_unref (config->accounts);
- config->accounts = NULL;
- }
-
- if (config->signatures) {
- g_object_unref (config->signatures);
- config->signatures = NULL;
- }
-
- config_clear_labels ();
config_clear_mime_types ();
}
void
mail_config_write (void)
{
+ EAccountList *account_list;
+ ESignatureList *signature_list;
+
if (!config)
return;
- e_account_list_save (config->accounts);
- e_signature_list_save (config->signatures);
+ account_list = e_get_account_list ();
+ signature_list = e_get_signature_list ();
+
+ e_account_list_save (account_list);
+ e_signature_list_save (signature_list);
gconf_client_suggest_sync (config->gconf, NULL);
}
@@ -578,6 +504,7 @@ mail_config_write (void)
void
mail_config_write_on_exit (void)
{
+ EAccountList *account_list;
EAccount *account;
EIterator *iter;
@@ -591,7 +518,8 @@ mail_config_write_on_exit (void)
/* then we make sure the ones we want to remember are in the
session cache */
- iter = e_list_get_iterator ((EList *) config->accounts);
+ account_list = e_get_account_list ();
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
gchar *passwd;
@@ -620,7 +548,7 @@ mail_config_write_on_exit (void)
e_passwords_clear_passwords ("Mail");
/* then we remember them */
- iter = e_list_get_iterator ((EList *) config->accounts);
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
@@ -654,18 +582,6 @@ mail_config_get_gconf_client (void)
return config->gconf;
}
-gboolean
-mail_config_is_configured (void)
-{
- return e_list_length ((EList *) config->accounts) > 0;
-}
-
-gboolean
-mail_config_is_corrupt (void)
-{
- return config->corrupt;
-}
-
gint
mail_config_get_address_count (void)
{
@@ -733,74 +649,16 @@ mail_config_get_enable_magic_spacebar ()
return config->magic_spacebar;
}
-/**
- * mail_config_get_labels
- *
- * @return list of known labels, each member data is EUtilLabel structure.
- * Returned list should not be freed, neither data inside it.
- **/
-GSList *
-mail_config_get_labels (void)
-{
- return config->labels;
-}
-
const gchar **
mail_config_get_allowable_mime_types (void)
{
return (const gchar **) config->mime_types->pdata;
}
-gboolean
-mail_config_find_account (EAccount *account)
-{
- EAccount *acnt;
- EIterator *iter;
-
- iter = e_list_get_iterator ((EList *) config->accounts);
- while (e_iterator_is_valid (iter)) {
- acnt = (EAccount *) e_iterator_get (iter);
- if (acnt == account) {
- g_object_unref (iter);
- return TRUE;
- }
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-
- return FALSE;
-}
-
-EAccount *
-mail_config_get_default_account (void)
-{
- if (config == NULL)
- mail_config_init ();
-
- if (!config->accounts)
- return NULL;
-
- /* should probably return const */
- return (EAccount *)e_account_list_get_default(config->accounts);
-}
-
-EAccount *
-mail_config_get_account_by_name (const gchar *account_name)
-{
- return (EAccount *)e_account_list_find(config->accounts, E_ACCOUNT_FIND_NAME, account_name);
-}
-
-EAccount *
-mail_config_get_account_by_uid (const gchar *uid)
-{
- return (EAccount *) e_account_list_find (config->accounts, E_ACCOUNT_FIND_UID, uid);
-}
-
static EAccount *
mc_get_account_by (const gchar *given_url, const gchar * (get_url_string)(EAccount *account))
{
+ EAccountList *account_list;
EAccount *account = NULL;
EIterator *iter;
CamelURL *url;
@@ -815,7 +673,8 @@ mc_get_account_by (const gchar *given_url, const gchar * (get_url_string)(EAccou
provider = camel_provider_get (given_url, NULL);
g_return_val_if_fail (provider != NULL && provider->url_equal != NULL, NULL);
- iter = e_list_get_iterator ((EList *) config->accounts);
+ account_list = e_get_account_list ();
+ iter = e_list_get_iterator ((EList *) account_list);
while (account == NULL && e_iterator_is_valid (iter)) {
CamelURL *account_url;
const gchar *account_url_string;
@@ -877,77 +736,21 @@ mail_config_get_account_by_transport_url (const gchar *transport_url)
return mc_get_account_by (transport_url, get_transport_url_string);
}
-gint
-mail_config_has_proxies (EAccount *account)
-{
- return e_account_list_account_has_proxies (config->accounts, account);
-}
-
-void
-mail_config_remove_account_proxies (EAccount *account)
-{
- e_account_list_remove_account_proxies (config->accounts, account);
-}
-
-void
-mail_config_prune_proxies (void)
-{
- e_account_list_prune_proxies (config->accounts);
-}
-
-EAccountList *
-mail_config_get_accounts (void)
-{
- if (config == NULL)
- mail_config_init ();
-
- return config->accounts;
-}
-
-void
-mail_config_add_account (EAccount *account)
-{
- e_account_list_add(config->accounts, account);
- mail_config_save_accounts ();
-}
-
-void
-mail_config_remove_account (EAccount *account)
-{
- e_account_list_remove(config->accounts, account);
- mail_config_save_accounts ();
-}
-
-void
-mail_config_set_default_account (EAccount *account)
-{
- e_account_list_set_default(config->accounts, account);
-}
-
-EAccountIdentity *
-mail_config_get_default_identity (void)
-{
- EAccount *account;
-
- account = mail_config_get_default_account ();
- if (account)
- return account->id;
- else
- return NULL;
-}
-
EAccountService *
mail_config_get_default_transport (void)
{
+ EAccountList *account_list;
EAccount *account;
EIterator *iter;
- account = mail_config_get_default_account ();
+ account_list = e_get_account_list ();
+ account = e_get_default_account ();
+
if (account && account->enabled && account->transport && account->transport->url && account->transport->url[0])
return account->transport;
/* return the first account with a transport? */
- iter = e_list_get_iterator ((EList *) config->accounts);
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
@@ -968,17 +771,19 @@ mail_config_get_default_transport (void)
static gchar *
uri_to_evname (const gchar *uri, const gchar *prefix)
{
- const gchar *base_directory = mail_component_peek_base_directory (mail_component_peek ());
+ const gchar *data_dir;
gchar *safe;
gchar *tmp;
+ data_dir = em_utils_get_data_dir ();
+
safe = g_strdup (uri);
e_filename_make_safe (safe);
/* blah, easiest thing to do */
if (prefix[0] == '*')
- tmp = g_strdup_printf ("%s/%s%s.xml", base_directory, prefix + 1, safe);
+ tmp = g_strdup_printf ("%s/%s%s.xml", data_dir, prefix + 1, safe);
else
- tmp = g_strdup_printf ("%s/%s%s", base_directory, prefix, safe);
+ tmp = g_strdup_printf ("%s/%s%s", data_dir, prefix, safe);
g_free (safe);
return tmp;
}
@@ -986,6 +791,7 @@ uri_to_evname (const gchar *uri, const gchar *prefix)
void
mail_config_uri_renamed (GCompareFunc uri_cmp, const gchar *old, const gchar *new)
{
+ EAccountList *account_list;
EAccount *account;
EIterator *iter;
gint i, work = 0;
@@ -998,7 +804,8 @@ mail_config_uri_renamed (GCompareFunc uri_cmp, const gchar *old, const gchar *ne
"*views/custom_view-",
NULL };
- iter = e_list_get_iterator ((EList *) config->accounts);
+ account_list = e_get_account_list ();
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
@@ -1039,26 +846,33 @@ mail_config_uri_renamed (GCompareFunc uri_cmp, const gchar *old, const gchar *ne
void
mail_config_uri_deleted (GCompareFunc uri_cmp, const gchar *uri)
{
+ EAccountList *account_list;
EAccount *account;
EIterator *iter;
gint work = 0;
+ const gchar *local_drafts_folder_uri;
+ const gchar *local_sent_folder_uri;
+
/* assumes these can't be removed ... */
- const gchar *default_sent_folder_uri = mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT);
- const gchar *default_drafts_folder_uri = mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS);
+ local_drafts_folder_uri =
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS);
+ local_sent_folder_uri =
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_SENT);
- iter = e_list_get_iterator ((EList *) config->accounts);
+ account_list = e_get_account_list ();
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
if (account->sent_folder_uri && uri_cmp (account->sent_folder_uri, uri)) {
g_free (account->sent_folder_uri);
- account->sent_folder_uri = g_strdup (default_sent_folder_uri);
+ account->sent_folder_uri = g_strdup (local_sent_folder_uri);
work = 1;
}
if (account->drafts_folder_uri && uri_cmp (account->drafts_folder_uri, uri)) {
g_free (account->drafts_folder_uri);
- account->drafts_folder_uri = g_strdup (default_drafts_folder_uri);
+ account->drafts_folder_uri = g_strdup (local_drafts_folder_uri);
work = 1;
}
@@ -1091,123 +905,18 @@ gchar *
mail_config_folder_to_cachename (CamelFolder *folder, const gchar *prefix)
{
gchar *url, *basename, *filename;
- const gchar *evolution_dir;
-
- evolution_dir = mail_component_peek_base_directory (mail_component_peek ());
+ const gchar *config_dir;
+ config_dir = em_utils_get_config_dir ();
url = mail_config_folder_to_safe_url (folder);
basename = g_strdup_printf ("%s%s", prefix, url);
- filename = g_build_filename (evolution_dir, "config", basename, NULL);
+ filename = g_build_filename (config_dir, basename, NULL);
g_free (basename);
g_free (url);
return filename;
}
-ESignatureList *
-mail_config_get_signatures (void)
-{
- return config->signatures;
-}
-
-static gchar *
-get_new_signature_filename (void)
-{
- const gchar *base_directory;
- gchar *filename, *id;
- struct stat st;
- gint i;
-
- base_directory = e_get_user_data_dir ();
- filename = g_build_filename (base_directory, "signatures", NULL);
- if (g_lstat (filename, &st)) {
- if (errno == ENOENT) {
- if (g_mkdir (filename, 0700))
- g_warning ("Fatal problem creating %s directory.", filename);
- } else
- g_warning ("Fatal problem with %s directory.", filename);
- }
- g_free (filename);
-
- filename = g_malloc (strlen (base_directory) + sizeof ("/signatures/signature-") + 12);
- id = g_stpcpy (filename, base_directory);
- id = g_stpcpy (id, "/signatures/signature-");
-
- for (i = 0; i < (INT_MAX - 1); i++) {
- sprintf (id, "%d", i);
- if (g_lstat (filename, &st) == -1 && errno == ENOENT) {
- gint fd;
-
- fd = g_creat (filename, 0600);
- if (fd >= 0) {
- close (fd);
- return filename;
- }
- }
- }
-
- g_free (filename);
-
- return NULL;
-}
-
-ESignature *
-mail_config_signature_new (const gchar *filename, gboolean script, gboolean html)
-{
- ESignature *sig;
-
- sig = e_signature_new ();
- e_signature_set_name (sig, _("Unnamed"));
- e_signature_set_is_script (sig, script);
- e_signature_set_is_html (sig, html);
-
- if (filename == NULL) {
- gchar *new_filename;
-
- new_filename = get_new_signature_filename ();
- e_signature_set_filename (sig, new_filename);
- g_free (new_filename);
- } else
- e_signature_set_filename (sig, filename);
-
- return sig;
-}
-
-ESignature *
-mail_config_get_signature_by_uid (const gchar *uid)
-{
- return (ESignature *) e_signature_list_find (config->signatures, E_SIGNATURE_FIND_UID, uid);
-}
-
-ESignature *
-mail_config_get_signature_by_name (const gchar *name)
-{
- return (ESignature *) e_signature_list_find (config->signatures, E_SIGNATURE_FIND_NAME, name);
-}
-
-void
-mail_config_add_signature (ESignature *signature)
-{
- e_signature_list_add (config->signatures, signature);
- mail_config_save_signatures ();
-}
-
-void
-mail_config_remove_signature (ESignature *signature)
-{
- const gchar *filename;
- gboolean is_script;
-
- filename = e_signature_get_filename (signature);
- is_script = e_signature_get_is_script (signature);
-
- if (filename == NULL && !is_script)
- g_unlink (filename);
-
- e_signature_list_remove (config->signatures, signature);
- mail_config_save_signatures ();
-}
-
void
mail_config_reload_junk_headers (void)
{
@@ -1238,131 +947,3 @@ mail_config_get_lookup_book_local_only (void)
return config->book_lookup_local_only;
}
-
-gboolean
-mail_config_scripts_disabled (void)
-{
- if (config == NULL)
- mail_config_init ();
-
- return config->scripts_disabled;
-}
-
-gchar *
-mail_config_signature_run_script (const gchar *script)
-{
-#ifndef G_OS_WIN32
- gint result, status;
- gint in_fds[2];
- pid_t pid;
-
- if (mail_config_scripts_disabled ())
- return NULL;
-
- if (pipe (in_fds) == -1) {
- g_warning ("Failed to create pipe to '%s': %s", script, g_strerror (errno));
- return NULL;
- }
-
- if (!(pid = fork ())) {
- /* child process */
- gint maxfd, i;
-
- close (in_fds [0]);
- if (dup2 (in_fds[1], STDOUT_FILENO) < 0)
- _exit (255);
- close (in_fds [1]);
-
- setsid ();
-
- maxfd = sysconf (_SC_OPEN_MAX);
- for (i = 3; i < maxfd; i++) {
- if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)
- fcntl (i, F_SETFD, FD_CLOEXEC);
- }
-
- execlp("/bin/sh", "/bin/sh", "-c", script, NULL);
- g_warning ("Could not execute %s: %s\n", script, g_strerror (errno));
- _exit (255);
- } else if (pid < 0) {
- g_warning ("Failed to create create child process '%s': %s", script, g_strerror (errno));
- close (in_fds [0]);
- close (in_fds [1]);
- return NULL;
- } else {
- CamelStreamFilter *filtered_stream;
- CamelStreamMem *memstream;
- CamelMimeFilter *charenc;
- CamelStream *stream;
- GByteArray *buffer;
- gchar *charset;
- gchar *content;
-
- /* parent process */
- close (in_fds[1]);
-
- stream = camel_stream_fs_new_with_fd (in_fds[0]);
-
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- buffer = g_byte_array_new ();
- camel_stream_mem_set_byte_array (memstream, buffer);
-
- camel_stream_write_to_stream (stream, (CamelStream *) memstream);
- camel_object_unref (stream);
-
- /* signature scripts are supposed to generate UTF-8 content, but because users
- are known to not ever read the manual... we try to do our best if the
- content isn't valid UTF-8 by assuming that the content is in the user's
- preferred charset. */
- if (!g_utf8_validate ((gchar *)buffer->data, buffer->len, NULL)) {
- stream = (CamelStream *) memstream;
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (memstream, g_byte_array_new ());
-
- filtered_stream = camel_stream_filter_new_with_stream (stream);
- camel_object_unref (stream);
-
- charset = gconf_client_get_string (config->gconf, "/apps/evolution/mail/composer/charset", NULL);
- if (charset && *charset) {
- if ((charenc = (CamelMimeFilter *) camel_mime_filter_charset_new_convert (charset, "utf-8"))) {
- camel_stream_filter_add (filtered_stream, charenc);
- camel_object_unref (charenc);
- }
- }
- g_free (charset);
-
- camel_stream_write_to_stream ((CamelStream *) filtered_stream, (CamelStream *) memstream);
- camel_object_unref (filtered_stream);
- g_byte_array_free (buffer, TRUE);
-
- buffer = memstream->buffer;
- }
-
- camel_object_unref (memstream);
-
- g_byte_array_append (buffer, (const guchar *)"", 1);
- content = (gchar *)buffer->data;
- g_byte_array_free (buffer, FALSE);
-
- /* wait for the script process to terminate */
- result = waitpid (pid, &status, 0);
-
- if (result == -1 && errno == EINTR) {
- /* child process is hanging... */
- kill (pid, SIGTERM);
- sleep (1);
- result = waitpid (pid, &status, WNOHANG);
- if (result == 0) {
- /* ...still hanging, set phasers to KILL */
- kill (pid, SIGKILL);
- sleep (1);
- result = waitpid (pid, &status, WNOHANG);
- }
- }
-
- return content;
- }
-#else
- return NULL;
-#endif
-}
diff --git a/mail/mail-config.glade b/mail/mail-config.glade
index 75ed530f25..bc88e6e0b4 100644
--- a/mail/mail-config.glade
+++ b/mail/mail-config.glade
@@ -1,9938 +1,5575 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
+<?xml version="1.0"?>
<glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkWindow" id="account_druid">
- <property name="title" translatable="yes">Evolution Account Assistant</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GnomeDruid" id="druid">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="show_help">False</property>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="start_page">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_START</property>
- <property name="title" translatable="yes">Mail Configuration</property>
- <property name="text" translatable="yes">Welcome to the Evolution Mail Configuration Assistant.
-
-Click &quot;Forward&quot; to begin.</property>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="identity_page">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Identity</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid_identity_vbox">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="identity_help">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Please enter your name and email address below. The &quot;optional&quot; fields below do not need to be filled in, unless you wish to include this information in email you send.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="source_page">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Receiving Email</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid_source_vbox">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="extra_help">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Please configure the following account settings.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="transport_page">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Sending Email</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid_transport_vbox">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="transport_help">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Please enter information about the way you will send mail. If you are not sure, ask your system administrator or Internet Service Provider.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="management_page">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Account Management</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid_management_vbox">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="management_help">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Please enter a descriptive name for this account in the space below. This name will be used for display purposes only.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="finish_page">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_FINISH</property>
- <property name="title" translatable="yes">Done</property>
- <property name="text" translatable="yes">Congratulations, your mail configuration is complete.
-
-You are now ready to send and receive email
-using Evolution.
-
-Click &quot;Apply&quot; to save your settings.</property>
- </widget>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkWindow" id="account_editor">
- <property name="title" translatable="yes">Account Editor</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkNotebook" id="account_editor_notebook">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="show_tabs">True</property>
- <property name="show_border">True</property>
- <property name="tab_pos">GTK_POS_TOP</property>
- <property name="scrollable">False</property>
- <property name="enable_popup">False</property>
-
- <child>
- <widget class="GtkVBox" id="vboxIdentityBorder">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="management_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label470">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Account Information&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox172">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label568">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table12">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="account_vbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="management_description_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Type the name by which you would like to refer to this account.
-For example: &quot;Work&quot; or &quot;Personal&quot;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxIdentityName">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="management_name_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Name:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">management_name</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="management_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="identity_required_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label464">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Required Information&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox170">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label569">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table10">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkTable" id="identity_required_table">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkEntry" id="identity_address">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- <accessibility>
- <atkrelation target="identity_address_label" type="labelled-by"/>
- <atkrelation target="label464" type="labelled-by"/>
- </accessibility>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="identity_address_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Email _Address:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">identity_address</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="identity_full_name_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Full Nam_e:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">identity_full_name</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="identity_full_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- <accessibility>
- <atkrelation target="label464" type="labelled-by"/>
- <atkrelation target="identity_full_name_label" type="labelled-by"/>
- </accessibility>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="identity_optional_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label466">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Optional Information&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox171">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label570">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="identity_optional_table">
- <property name="visible">True</property>
- <property name="n_rows">4</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="sigLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Signat_ure:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">signature_dropdown</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox169">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="Custom" id="signature_dropdown">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_dropdown_new</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Mon, 06 Sep 2004 01:00:22 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="sigAddNew">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Add Ne_w Signature...</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="sigAddNewClicked"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="identity_organization">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- <accessibility>
- <atkrelation target="identity_organization_label" type="labelled-by"/>
- <atkrelation target="label466" type="labelled-by"/>
- </accessibility>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="identity_organization_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Or_ganization:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">identity_organization</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="identity_reply_to">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- <accessibility>
- <atkrelation target="label466" type="labelled-by"/>
- <atkrelation target="reply_to_label" type="labelled-by"/>
- </accessibility>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="reply_to_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Re_ply-To:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">identity_reply_to</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="management_default">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Make this my default account</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label31">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Identity</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxSourceBorder">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="source_vbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkTable" id="source_type_table">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="source_type_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Server _Type:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">source_type_dropdown</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label442">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Description:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="source_description">
- <property name="visible">True</property>
- <property name="label" translatable="yes">description</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="source_type_dropdown">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_dropdown_new</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Thu, 29 Jul 2004 05:31:24 GMT</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHSeparator" id="hseparator2">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="source_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label472">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Configuration&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox173">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label565">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table13">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkTable" id="table4">
- <property name="visible">True</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="source_user_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">User_name:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">source_user</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="source_user">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="source_path_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Path:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFileChooserButton" id="source_path_entry">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Mailbox location</property>
- <property name="action">GTK_FILE_CHOOSER_ACTION_OPEN</property>
- <property name="local_only">True</property>
- <property name="show_hidden">False</property>
- <property name="do_overwrite_confirmation">False</property>
- <property name="width_chars">-1</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox210">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkEntry" id="source_host">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="port_hint">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkImage" id="image12">
- <property name="visible">True</property>
- <property name="icon_size">4</property>
- <property name="icon_name">gtk-dialog-info</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="port_hint1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">If the server uses a non-standard port then specify the server address as &quot;server-name:port-number&quot;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox211">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="source_host_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Server:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">source_host</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="source_security_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label515">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Security&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">source_auth_dropdown</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox201">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label567">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox181">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="source_ssl_hbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="lblSourceUseSSL">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Use Secure Connection:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">source_use_ssl</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="source_use_ssl">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_ssl_selector_new</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Tue, 03 Aug 2004 07:22:52 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="source_ssl_disabled">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="stock">gtk-dialog-warning</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label514">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;SSL is not supported in this build of Evolution&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="source_auth_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label474">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;_Authentication Type&lt;/span&gt;</property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">source_auth_dropdown</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox174">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label566">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox179">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="hbox199">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="Custom" id="source_auth_dropdown">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_dropdown_new</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Thu, 29 Jul 2004 08:38:30 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="source_check_supported">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Ch_eck for Supported Types</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="source_remember_password">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Note: you will not be prompted for a password until you connect for the first time</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Re_member password</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label33">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Receiving Email</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxTransportBorder">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="transport_vbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkTable" id="transport_type_table">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="transport_type_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Server _Type:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">transport_type_dropdown</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label50">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Description:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="transport_type_dropdown">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_dropdown_new</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Thu, 29 Jul 2004 05:42:00 GMT</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="transport_description">
- <property name="visible">True</property>
- <property name="label" translatable="yes">description</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHSeparator" id="hseparator3">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="transport_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="transport_server_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label476">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Server Configuration&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox175">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label562">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table15">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox12">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkTable" id="table6">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox212">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkEntry" id="transport_host">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="port_hint">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkImage" id="image13">
- <property name="visible">True</property>
- <property name="icon_size">4</property>
- <property name="icon_name">gtk-dialog-info</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="port_hint1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">If the server uses a non-standard port then specify the server address as &quot;server-name:port-number&quot;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox213">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox247">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="transport_host_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Server:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">transport_host</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="transport_needs_auth">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Ser_ver requires authentication</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="transport_security_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label517">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Security&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox203">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label564">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox183">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="transport_ssl_hbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="lblTransportUseSSL">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Use Secure Connection:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">transport_use_ssl</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="transport_use_ssl">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_ssl_selector_new</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Tue, 03 Aug 2004 07:23:50 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="transport_ssl_disabled">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-dialog-warning</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="transport_ssl_disabled_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;SSL is not supported in this build of Evolution&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="transport_auth_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label478">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Authentication&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox176">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label563">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table16">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox61">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkTable" id="table31">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="transport_auth_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">T_ype:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">transport_auth_dropdown</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="transport_user_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">User_name:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">transport_user</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="transport_user">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox195">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="Custom" id="transport_auth_dropdown">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_dropdown_new</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Thu, 29 Jul 2004 08:37:13 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="transport_check_supported">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Ch_eck for Supported Types</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFixed" id="fixed5">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="transport_remember_password">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Remember _password</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label34">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Sending Mail</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxFoldersBorder">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="folders_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label482">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Sent and Draft Messages&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox177">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label560">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table17">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox184">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkTable" id="folders_table">
- <property name="visible">True</property>
- <property name="n_rows">3</property>
- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="drafts_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Drafts _Folder:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">drafts_button</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="sent_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Sent _Messages Folder:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">sent_button</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="sent_button">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_folder_selector_button_new</property>
- <property name="string1">Select Sent Folder</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Tue, 14 Dec 2004 17:07:09 GMT</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="drafts_button">
- <property name="visible">True</property>
- <property name="creation_function">em_account_editor_folder_selector_button_new</property>
- <property name="string1">Select Drafts Folder</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Tue, 14 Dec 2004 17:07:02 GMT</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFixed" id="fixed9">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFixed" id="fixed8">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox216">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="default_folders_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-revert-to-saved</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFixed" id="fixed12">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="frame2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label484">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Composing Messages&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox178">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label561">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table18">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkTable" id="table8">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="vbox186">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="always_cc">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Alway_s carbon-copy (cc) to:</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox210">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label522">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">12</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table32">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox187">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkEntry" id="cc_addrs">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox188">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="always_bcc">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Always _blind carbon-copy (bcc) to:</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox211">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label523">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">12</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table33">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox189">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkEntry" id="bcc_addrs">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox205">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label578">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Message Receipts&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox231">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label581">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox232">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label583">
- <property name="visible">True</property>
- <property name="label" translatable="yes">S_end message receipts:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">receipt_policy_dropdown</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkComboBox" id="receipt_policy_dropdown">
- <property name="visible">True</property>
- <property name="items" translatable="yes"></property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label35">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Defaults</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxSecurityBorder">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="pgp_frame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label486">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Pretty Good Privacy (PGP/GPG)&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox179">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label558">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table19">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vboxPGP">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="hbox63">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="pgp_key_id_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">PGP/GPG _Key ID:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">pgp_key</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="pgp_key">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="pgp_always_sign">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Al_ways sign outgoing messages when using this account</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="pgp_no_imip_sign">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Do not sign meeting requests (for Outlook compatibility)</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="pgp_encrypt_to_self">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Always encrypt to _myself when sending encrypted messages</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">True</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="pgp_always_trust">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Always _trust keys in my keyring when encrypting</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="smime_vbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label519">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Secure MIME (S/MIME)&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox206">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label559">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="smime_table">
- <property name="visible">True</property>
- <property name="n_rows">6</property>
- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkEntry" id="smime_sign_key">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="smime_encrypt_key">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="smime_encrypt_to_self">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Also encrypt to sel_f when sending encrypted messages</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">3</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="smime_encrypt_default">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Encrypt out_going messages (by default)</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">3</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="smime_sign_default">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Digitally sign o_utgoing messages (by default)</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHSeparator" id="hseparator3">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">3</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_padding">6</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label470">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Encry_ption certificate:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">smime_encrypt_key</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label469">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Sig_ning certificate:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">smime_sign_key</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox208">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkButton" id="smime_encrypt_key_select">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment28">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox175">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image3">
- <property name="visible">True</property>
- <property name="stock">gtk-open</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="button98">
- <property name="visible">True</property>
- <property name="label" translatable="yes">S_elect...</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="smime_encrypt_key_clear">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment35">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox230">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image10">
- <property name="visible">True</property>
- <property name="stock">gtk-clear</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label577">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Clea_r</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox209">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkButton" id="smime_sign_key_select">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment29">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox176">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image4">
- <property name="visible">True</property>
- <property name="stock">gtk-open</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label472">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Select...</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="smime_sign_key_clear">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment34">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox229">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image9">
- <property name="visible">True</property>
- <property name="stock">gtk-clear</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label576">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Cle_ar</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblSecurity">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Security</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkWindow" id="accounts_tab">
- <property name="title" translatable="yes">Email Accounts</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkHBox" id="toplevel">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="Custom" id="etableMailAccounts">
- <property name="visible">True</property>
- <property name="creation_function">em_account_prefs_treeview_new</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Wed, 29 Oct 2003 17:47:08 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxMailFunctions">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkVButtonBox" id="vbuttonboxMailAccounts">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_START</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkButton" id="cmdAccountAdd">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-add</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="cmdAccountEdit">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment33">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox224">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image8">
- <property name="visible">True</property>
- <property name="stock">gtk-properties</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label557">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Edit</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="cmdAccountDelete">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-delete</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="cmdAccountDefault">
- <property name="width_request">89</property>
- <property name="height_request">36</property>
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">De_fault</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkWindow" id="preferences_tab">
- <property name="title" translatable="yes">Mail Preferences</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkNotebook" id="preferences_toplevel">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="show_tabs">True</property>
- <property name="show_border">True</property>
- <property name="tab_pos">GTK_POS_TOP</property>
- <property name="scrollable">True</property>
- <property name="enable_popup">False</property>
-
- <child>
- <widget class="GtkVBox" id="vboxGeneral">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="FontsFrame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label492">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Message Fonts&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox182">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label540">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table22">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vboxMessageFonts">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="radFontUseSame">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Use the same fonts as other applications</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="tblScreen">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="lblScreenVariable">
- <property name="visible">True</property>
- <property name="label" translatable="yes">S_tandard Font:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">FontVariable</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFontButton" id="FontFixed">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="title" translatable="yes">Select HTML fixed width font</property>
- <property name="show_style">True</property>
- <property name="show_size">True</property>
- <property name="use_font">False</property>
- <property name="use_size">False</property>
- <property name="focus_on_click">True</property>
- <signal name="font_set" handler="changed"/>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFontButton" id="FontVariable">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="title" translatable="yes">Select HTML variable width font</property>
- <property name="show_style">True</property>
- <property name="show_size">True</property>
- <property name="use_font">False</property>
- <property name="use_size">False</property>
- <property name="focus_on_click">True</property>
- <signal name="font_set" handler="changed"/>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label444">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Fix_ed width Font:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">FontFixed</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="MessageDisplayFrame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label494">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Message Display&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox183">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label541">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table23">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vboxMessageDisplay">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="hboxReadTimeout">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkMarkTimeout">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Mark messages as read after</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkSpinButton" id="spinMarkTimeout">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="climb_rate">1</property>
- <property name="digits">1</property>
- <property name="numeric">True</property>
- <property name="update_policy">GTK_UPDATE_IF_VALID</property>
- <property name="snap_to_ticks">False</property>
- <property name="wrap">False</property>
- <property name="adjustment">1.5 0 10 1 1 0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblSeconds">
- <property name="visible">True</property>
- <property name="label" translatable="yes">seconds</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox234">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">4</property>
-
- <child>
- <widget class="GtkCheckButton" id="mlimit_checkbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Do not format messages when text si_ze exceeds</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkSpinButton" id="mlimit_spin">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="climb_rate">1</property>
- <property name="digits">0</property>
- <property name="numeric">False</property>
- <property name="update_policy">GTK_UPDATE_ALWAYS</property>
- <property name="snap_to_ticks">False</property>
- <property name="wrap">False</property>
- <property name="adjustment">0 0 30000 1 10 0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label585">
- <property name="visible">True</property>
- <property name="label" translatable="yes">KB</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox233">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="address_checkbox">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Shrink To / Cc / Bcc headers to </property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkSpinButton" id="address_spin">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="climb_rate">1</property>
- <property name="digits">0</property>
- <property name="numeric">False</property>
- <property name="update_policy">GTK_UPDATE_ALWAYS</property>
- <property name="snap_to_ticks">False</property>
- <property name="wrap">False</property>
- <property name="adjustment">5 1 100 1 10 0</property>
- </widget>
- <packing>
- <property name="padding">2</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label584">
- <property name="visible">True</property>
- <property name="label" translatable="yes">addresses</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">2</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="magic_spacebar_checkbox">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Enable Magic S_pacebar</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxHighlightColor">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkHighlightCitations">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Highlight _quotations with</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">True</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkColorButton" id="colorButtonHighlightCitations">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="use_alpha">False</property>
- <property name="title" translatable="yes">Pick a color</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblColor">
- <property name="visible">True</property>
- <property name="label" translatable="yes">color</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxDefaultCharset">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="lblDefaultCharset">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Default character e_ncoding:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">omenuCharset</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkOptionMenu" id="omenuCharset">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="history">0</property>
-
- <child internal-child="menu">
- <widget class="GtkMenu" id="convertwidget26">
- <property name="visible">True</property>
-
- <child>
- <widget class="GtkMenuItem" id="convertwidget27">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Baltic (ISO-8859-13)</property>
- <property name="use_underline">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="convertwidget28">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Baltic (ISO-8859-4)</property>
- <property name="use_underline">True</property>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxEnableSearchFolders">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkEnableSearchFolders">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Enable Sea_rch Folders</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">True</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblEnableSFRestart">
- <property name="visible">True</property>
- <property name="label" translatable="yes">(Note: Requires restart of the application)</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="DeleteMailFrame">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label496">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Delete Mail&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox184">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label542">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table24">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vboxDeletingMail">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="hbox220">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">4</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkEmptyTrashOnExit">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Empty trash folders on e_xit</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkComboBox" id="comboboxEmptyTrashDays">
- <property name="visible">True</property>
- <property name="items" translatable="yes">a
+ <requires lib="gnome"/>
+ <!-- interface-requires gnome 2298.56488 -->
+ <!-- interface-requires gtk+ 2.16 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <widget class="GtkWindow" id="account_editor">
+ <property name="title" translatable="yes">Account Editor</property>
+ <child>
+ <widget class="GtkNotebook" id="account_editor_notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">12</property>
+ <child>
+ <widget class="GtkVBox" id="vboxIdentityBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="management_frame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label470">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Account Information&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox172">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label568">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table12">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="account_vbox">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="management_description_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Type the name by which you would like to refer to this account.
+For example: "Work" or "Personal"</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxIdentityName">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="management_name_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">management_name</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="management_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="identity_required_frame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label464">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Required Information&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox170">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label569">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table10">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkTable" id="identity_required_table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="identity_address">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <atkrelation type="labelled-by" target="label464"/>
+ <atkrelation type="labelled-by" target="identity_address_label"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="identity_address_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Email _Address:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">identity_address</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="identity_full_name_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Full Nam_e:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">identity_full_name</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="identity_full_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <atkrelation type="labelled-by" target="identity_full_name_label"/>
+ <atkrelation type="labelled-by" target="label464"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="identity_optional_frame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label466">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Optional Information&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox171">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label570">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="identity_optional_table">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="sigLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Signat_ure:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">signature_dropdown</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox169">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="Custom" id="signature_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="sigAddNew">
+ <property name="label" translatable="yes">Add Ne_w Signature...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="sigAddNewClicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="identity_organization">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <atkrelation type="labelled-by" target="label466"/>
+ <atkrelation type="labelled-by" target="identity_organization_label"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="identity_organization_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Or_ganization:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">identity_organization</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="identity_reply_to">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <atkrelation type="labelled-by" target="reply_to_label"/>
+ <atkrelation type="labelled-by" target="label466"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="reply_to_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Re_ply-To:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">identity_reply_to</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="management_default">
+ <property name="label" translatable="yes">_Make this my default account</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label31">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Identity</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxSourceBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="source_vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkTable" id="source_type_table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="source_type_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Server _Type:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">source_type_dropdown</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label442">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Description:</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="source_description">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">description</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="source_type_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHSeparator" id="hseparator2">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="source_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label472">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Configuration&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox173">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label565">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table13">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkTable" id="table4">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="source_host_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Server:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">source_host</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="source_user_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">User_name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">source_user</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="source_host">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="source_user">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="source_path_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Path:</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFileChooserButton" id="source_path_entry">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Mailbox location</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="source_security_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label515">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Security&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="mnemonic_widget">source_auth_dropdown</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox201">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label567">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox181">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="source_ssl_hbox">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="lblSourceUseSSL">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Use Secure Connection:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">source_use_ssl</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="source_use_ssl">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_ssl_selector_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="source_ssl_disabled">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-warning</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label514">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;SSL is not supported in this build of Evolution&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="source_auth_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label474">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;_Authentication Type&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">source_auth_dropdown</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox174">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label566">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox179">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox199">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="Custom" id="source_auth_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="source_check_supported">
+ <property name="label" translatable="yes"> Ch_eck for Supported Types</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="source_remember_password">
+ <property name="label" translatable="yes">Re_member password</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Note: you will not be prompted for a password until you connect for the first time</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label33">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Receiving Email</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxTransportBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="transport_vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkTable" id="transport_type_table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="transport_type_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Server _Type:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">transport_type_dropdown</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label50">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Description:</property>
+ <property name="justify">right</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="transport_type_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="transport_description">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">description</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHSeparator" id="hseparator3">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="transport_frame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="transport_server_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label476">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Server Configuration&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox175">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label562">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table15">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox12">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkTable" id="table6">
+ <property name="visible">True</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="transport_host_label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Server:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">transport_host</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="transport_host">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="transport_needs_auth">
+ <property name="label" translatable="yes">Ser_ver requires authentication</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="transport_security_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label517">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Security&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox203">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label564">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox183">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="transport_ssl_hbox">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="lblTransportUseSSL">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Use Secure Connection:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">transport_use_ssl</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="transport_use_ssl">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_ssl_selector_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="transport_ssl_disabled">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-warning</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="transport_ssl_disabled_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;SSL is not supported in this build of Evolution&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="transport_auth_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label478">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Authentication&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox176">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label563">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table16">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox61">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkTable" id="table31">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="transport_auth_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">T_ype:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">transport_auth_dropdown</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="transport_user_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">User_name:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">transport_user</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="transport_user">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox195">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="Custom" id="transport_auth_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="transport_check_supported">
+ <property name="label" translatable="yes">Ch_eck for Supported Types</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFixed" id="fixed5">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="transport_remember_password">
+ <property name="label" translatable="yes">Remember _password</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label34">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sending Mail</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxFoldersBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="folders_frame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label482">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Sent and Draft Messages&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox177">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label560">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table17">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox184">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkTable" id="folders_table">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="drafts_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Drafts _Folder:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">drafts_button</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="sent_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Sent _Messages Folder:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">sent_button</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="sent_button">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_folder_selector_button_new</property>
+ <property name="string1">Select Sent Folder</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="drafts_button">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_folder_selector_button_new</property>
+ <property name="string1">Select Drafts Folder</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFixed" id="fixed9">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFixed" id="fixed8">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox216">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkButton" id="default_folders_button">
+ <property name="label">gtk-revert-to-saved</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFixed" id="fixed12">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="frame2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label484">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Composing Messages&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox178">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label561">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table18">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkTable" id="table8">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox186">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="always_cc">
+ <property name="label" translatable="yes">Alway_s carbon-copy (cc) to:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox210">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label522">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table32">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox187">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="cc_addrs">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox188">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="always_bcc">
+ <property name="label" translatable="yes">Always _blind carbon-copy (bcc) to:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox211">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label523">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table33">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox189">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="bcc_addrs">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox205">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label578">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Message Receipts&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox231">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label581">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox232">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label583">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">S_end message receipts:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">receipt_policy_dropdown</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="receipt_policy_dropdown">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label35">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Defaults</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxSecurityBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="pgp_frame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label486">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Pretty Good Privacy (PGP/GPG)&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox179">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label558">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table19">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxPGP">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox63">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="pgp_key_id_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">PGP/GPG _Key ID:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">pgp_key</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="pgp_key">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="pgp_always_sign">
+ <property name="label" translatable="yes">Al_ways sign outgoing messages when using this account</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="pgp_no_imip_sign">
+ <property name="label" translatable="yes">_Do not sign meeting requests (for Outlook compatibility)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="pgp_encrypt_to_self">
+ <property name="label" translatable="yes">Always encrypt to _myself when sending encrypted messages</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="pgp_always_trust">
+ <property name="label" translatable="yes">Always _trust keys in my keyring when encrypting</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="smime_vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label519">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Secure MIME (S/MIME)&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox206">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label559">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="smime_table">
+ <property name="visible">True</property>
+ <property name="n_rows">6</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="smime_sign_key">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="smime_encrypt_key">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="smime_encrypt_to_self">
+ <property name="label" translatable="yes">Also encrypt to sel_f when sending encrypted messages</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">3</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="smime_encrypt_default">
+ <property name="label" translatable="yes">Encrypt out_going messages (by default)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">3</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="smime_sign_default">
+ <property name="label" translatable="yes">Digitally sign o_utgoing messages (by default)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ <property name="y_padding">6</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Encry_ption certificate:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">smime_encrypt_key</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label469">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Sig_ning certificate:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">smime_sign_key</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox208">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkButton" id="smime_encrypt_key_select">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment28">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="stock">gtk-open</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="button98">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">S_elect...</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="smime_encrypt_key_clear">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment35">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox230">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image10">
+ <property name="visible">True</property>
+ <property name="stock">gtk-clear</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label577">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Clea_r</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox209">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkButton" id="smime_sign_key_select">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment29">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="stock">gtk-open</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Select...</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="smime_sign_key_clear">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment34">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox229">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image9">
+ <property name="visible">True</property>
+ <property name="stock">gtk-clear</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label576">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Cle_ar</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblSecurity">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Security</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="preferences_tab">
+ <property name="title" translatable="yes">Mail Preferences</property>
+ <child>
+ <widget class="GtkNotebook" id="preferences_toplevel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="scrollable">True</property>
+ <child>
+ <widget class="GtkVBox" id="vboxGeneral">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="FontsFrame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label492">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Message Fonts&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox182">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label540">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table22">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxMessageFonts">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="radFontUseSame">
+ <property name="label" translatable="yes">_Use the same fonts as other applications</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="tblScreen">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblScreenVariable">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">S_tandard Font:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">FontVariable</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFontButton" id="FontFixed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Select HTML fixed width font</property>
+ <signal name="font_set" handler="changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFontButton" id="FontVariable">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Select HTML variable width font</property>
+ <signal name="font_set" handler="changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label444">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Fix_ed width Font:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">FontFixed</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="MessageDisplayFrame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label494">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Message Display&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox183">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label541">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table23">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxMessageDisplay">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hboxReadTimeout">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkMarkTimeout">
+ <property name="label" translatable="yes">_Mark messages as read after</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spinMarkTimeout">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">1.5 0 10 1 1 0</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">1</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">if-valid</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblSeconds">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">seconds</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox234">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <widget class="GtkCheckButton" id="mlimit_checkbutton">
+ <property name="label" translatable="yes">Do not format messages when text si_ze exceeds</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="mlimit_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 30000 1 10 0</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label585">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">KB</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox233">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="address_checkbox">
+ <property name="label" translatable="yes">_Shrink To / Cc / Bcc headers to </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="address_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">5 1 100 1 10 0</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label584">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">addresses</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">2</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="magic_spacebar_checkbox">
+ <property name="label" translatable="yes">Enable Magic S_pacebar</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxHighlightColor">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkHighlightCitations">
+ <property name="label" translatable="yes">Highlight _quotations with</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkColorButton" id="colorButtonHighlightCitations">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Pick a color</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblColor">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">color</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxDefaultCharset">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblDefaultCharset">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Default character e_ncoding:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxEnableSearchFolders">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkEnableSearchFolders">
+ <property name="label" translatable="yes">Enable Sea_rch Folders</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblEnableSFRestart">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">(Note: Requires restart of the application)</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="DeleteMailFrame">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label496">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Delete Mail&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox184">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label542">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table24">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxDeletingMail">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox220">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkEmptyTrashOnExit">
+ <property name="label" translatable="yes">Empty trash folders on e_xit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="comboboxEmptyTrashDays">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">a
b</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkConfirmExpunge">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Confirm _when expunging a folder</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblGeneral">
- <property name="visible">True</property>
- <property name="label" translatable="yes">General</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxHtmlMail">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label530">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;General&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox215">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label538">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox173">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkShowAnimatedImages">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes" comments="If enabled, show animation; if disabled, only display a static image without any animation">_Show image animations</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkPromptWantHTML">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Prompt on sending HTML mail to contacts that do not want them</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxLoadingImages">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label500">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Loading Images&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox186">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label539">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox190">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkRadioButton" id="radImagesNever">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Never load images from the Internet</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="radImagesSometimes">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Load images in messages from contacts</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">radImagesNever</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="radImagesAlways">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Always load images from the Internet</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">radImagesNever</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblHtmlMail">
- <property name="visible">True</property>
- <property name="label" translatable="yes">HTML Messages</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="frameColours">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label502">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Labels&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox187">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label537">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox242">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox209">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow50">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="labelTree">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label589">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Note: Underscore in the label name is used as mnemonic identifier in menu.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox208">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkButton" id="labelAdd">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-add</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="labelEdit">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-edit</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="labelRemove">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-remove</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="padding">6</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblColours">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Labels</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxHeaderTab">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox206">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkHBox" id="hbox238">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label587">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Sender Photograph&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox206">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox239">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="photo_show">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Show the photograph of sender in the message preview</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox240">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="photo_local">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">S_earch for sender photograph only in local address books</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label524">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Displayed Message _Headers&lt;/span&gt;</property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">txtHeaders</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox212">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label536">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox199">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkEntry" id="txtHeaders">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow49">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="treeHeaders">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- <accessibility>
- <atkproperty name="AtkObject::accessible_name" translatable="yes">Mail Headers Table</atkproperty>
- </accessibility>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox200">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkButton" id="cmdHeadersAdd">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-add</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="cmdHeadersRemove">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-remove</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox210">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label591">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Date/Time Format&lt;/span&gt;</property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">txtHeaders</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox245">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label592">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">6</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="datetime_format_table">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">0</property>
- <property name="column_spacing">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblHeaders">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Headers</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox161">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox192">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label526">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;General&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table34">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="n_rows">9</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">3</property>
- <property name="column_spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox235">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label586">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Default junk plugin:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">default_junk_plugin</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">6</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="default_junk_plugin">
- <property name="visible">True</property>
- <property name="creation_function">create_combo_text_widget</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Fri, 23 Mar 2007 09:28:55 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkCheckIncomingMail">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Checks incoming mail messages to be Junk</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Check incoming _messages for junk</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_padding">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox236">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkImage" id="plugin_image">
- <property name="visible">True</property>
- <property name="icon_size">4</property>
- <property name="icon_name">gtk-info</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="plugin_status">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">8</property>
- <property name="bottom_attach">9</property>
- <property name="x_padding">15</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox237">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">4</property>
-
- <child>
- <widget class="GtkCheckButton" id="junk_empty_check">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Delete junk messages on e_xit</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkComboBox" id="junk_empty_combobox">
- <property name="visible">True</property>
- <property name="items" translatable="yes">a
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkConfirmExpunge">
+ <property name="label" translatable="yes">Confirm _when expunging a folder</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblGeneral">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">General</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxHtmlMail">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label530">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;General&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox215">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label538">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox173">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkShowAnimatedImages">
+ <property name="label" translatable="yes" comments="If enabled, show animation; if disabled, only display a static image without any animation">_Show image animations</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkPromptWantHTML">
+ <property name="label" translatable="yes">_Prompt on sending HTML mail to contacts that do not want them</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxLoadingImages">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label500">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Loading Images&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox186">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label539">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox190">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkRadioButton" id="radImagesNever">
+ <property name="label" translatable="yes">_Never load images from the Internet</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="radImagesSometimes">
+ <property name="label" translatable="yes">_Load images in messages from contacts</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radImagesNever</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="radImagesAlways">
+ <property name="label" translatable="yes">_Always load images from the Internet</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radImagesNever</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHtmlMail">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">HTML Messages</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="frameColours">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label502">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Labels&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="labels-alignment">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblColours">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Labels</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxHeaderTab">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox206">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <widget class="GtkHBox" id="hbox238">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label587">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Sender Photograph&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkHBox" id="hbox239">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="photo_show">
+ <property name="label" translatable="yes">_Show the photograph of sender in the message preview</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">10</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox240">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="photo_local">
+ <property name="label" translatable="yes">S_earch for sender photograph only in local address books</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">10</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label524">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Displayed Message _Headers&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtHeaders</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox212">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label536">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox199">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkEntry" id="txtHeaders">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow49">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <widget class="GtkTreeView" id="treeHeaders">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <accessibility>
+ <atkproperty name="AtkObject::accessible-name" translatable="yes">Mail Headers Table</atkproperty>
+ </accessibility>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox200">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkButton" id="cmdHeadersAdd">
+ <property name="label">gtk-add</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="cmdHeadersRemove">
+ <property name="label">gtk-remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox210">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkLabel" id="label591">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Date/Time Format&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtHeaders</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox245">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label592">
+ <property name="visible">True</property>
+ <property name="xpad">6</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="datetime_format_table">
+ <property name="visible">True</property>
+ <property name="n_columns">3</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHeaders">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Headers</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox161">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox192">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkLabel" id="label526">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;General&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table34">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="n_rows">9</property>
+ <property name="row_spacing">3</property>
+ <child>
+ <widget class="GtkHBox" id="hbox235">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label586">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Default junk plugin:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">default_junk_plugin</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">6</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="default_junk_plugin">
+ <property name="visible">True</property>
+ <property name="creation_function">create_combo_text_widget</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkCheckIncomingMail">
+ <property name="label" translatable="yes">Check incoming _messages for junk</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Checks incoming mail messages to be Junk</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="x_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox236">
+ <property name="visible">True</property>
+ <property name="spacing">3</property>
+ <child>
+ <widget class="GtkImage" id="plugin_image">
+ <property name="visible">True</property>
+ <property name="icon_name">gtk-info</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="plugin_status">
+ <property name="visible">True</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">8</property>
+ <property name="bottom_attach">9</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="x_padding">15</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox237">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <widget class="GtkCheckButton" id="junk_empty_check">
+ <property name="label" translatable="yes">Delete junk messages on e_xit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="junk_empty_combobox">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">a
b</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_padding">4</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="junk_header_check">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Check cu_stom headers for junk</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_padding">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox243">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow51">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="junk_header_tree">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVButtonBox" id="vbuttonbox26">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="junk_header_add">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-add</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="junk_header_remove">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-remove</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_padding">22</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="lookup_book">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Do not mar_k messages as junk if sender is in my address book</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_padding">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="junk_lookup_local_only">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Lookup in local address book only</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_padding">25</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox244">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkImage" id="image11">
- <property name="visible">True</property>
- <property name="stock">gtk-info</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label590">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Option is ignored if a match for custom junk headers is found.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox195">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label473">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Junk</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkWindow" id="composer_tab">
- <property name="title" translatable="yes">Message Composer</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkNotebook" id="composer_toplevel">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="show_tabs">True</property>
- <property name="show_border">True</property>
- <property name="tab_pos">GTK_POS_TOP</property>
- <property name="scrollable">False</property>
- <property name="enable_popup">False</property>
-
- <child>
- <widget class="GtkVBox" id="vboxGeneral">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">18</property>
-
- <child>
- <widget class="GtkVBox" id="frameBehavior">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label504">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Default Behavior&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox189">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label505">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">12</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table28">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vboxBehavior">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkSendHTML">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Format messages in _HTML</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkAutoSmileys">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Automatically insert _emoticon images</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkRequestReceipt">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Always request rea_d receipt</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkReplyStartBottom">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Start _typing at the bottom on replying</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkOutlookFilenames">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Encode file names in an Outlook/GMail way</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="tableForwardsReplies">
- <property name="visible">True</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="lblReplyStyle">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Reply style:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkAlignment" id="alignment25">
- <property name="visible">True</property>
- <property name="xalign">7.45058015283e-09</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hboxReplyStyle">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkComboBox" id="comboboxReplyStyle">
- <property name="visible">True</property>
- <property name="items" translatable="yes">Attachment
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="x_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="junk_header_check">
+ <property name="label" translatable="yes">Check cu_stom headers for junk</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="x_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox243">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow51">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <widget class="GtkTreeView" id="junk_header_tree">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox26">
+ <property name="visible">True</property>
+ <property name="layout_style">spread</property>
+ <child>
+ <widget class="GtkButton" id="junk_header_add">
+ <property name="label">gtk-add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="junk_header_remove">
+ <property name="label">gtk-remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_padding">22</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="lookup_book">
+ <property name="label" translatable="yes">Do not mar_k messages as junk if sender is in my address book</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="x_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="junk_lookup_local_only">
+ <property name="label" translatable="yes">_Lookup in local address book only</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="x_padding">25</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox244">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="image11">
+ <property name="visible">True</property>
+ <property name="stock">gtk-info</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label590">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Option is ignored if a match for custom junk headers is found.</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox195">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label473">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Junk</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="composer_tab">
+ <property name="title" translatable="yes">Message Composer</property>
+ <child>
+ <widget class="GtkNotebook" id="composer_toplevel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <widget class="GtkVBox" id="vboxGeneral">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">18</property>
+ <child>
+ <widget class="GtkVBox" id="frameBehavior">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label504">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Default Behavior&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox189">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label505">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table28">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxBehavior">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">8</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkSendHTML">
+ <property name="label" translatable="yes">Format messages in _HTML</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkAutoSmileys">
+ <property name="label" translatable="yes">Automatically insert _emoticon images</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkRequestReceipt">
+ <property name="label" translatable="yes">Always request rea_d receipt</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkReplyStartBottom">
+ <property name="label" translatable="yes">Start _typing at the bottom on replying</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkOutlookFilenames">
+ <property name="label" translatable="yes">Encode file names in an Outlook/GMail way</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="tableForwardsReplies">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblReplyStyle">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Reply style:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment25">
+ <property name="visible">True</property>
+ <property name="xalign">7.4505801528346183e-09</property>
+ <property name="xscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hboxReplyStyle">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkComboBox" id="comboboxReplyStyle">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Attachment
Inline (Outlook style)
Quoted
Do not quote</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxForwardStyle">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkComboBox" id="comboboxForwardStyle">
- <property name="visible">True</property>
- <property name="items" translatable="yes">Attachment
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxForwardStyle">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkComboBox" id="comboboxForwardStyle">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Attachment
Inline
Quoted</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkOptionMenu" id="omenuCharset1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="history">0</property>
-
- <child internal-child="menu">
- <widget class="GtkMenu" id="convertwidget41">
- <property name="visible">True</property>
-
- <child>
- <widget class="GtkMenuItem" id="convertwidget42">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Baltic (ISO-8859-13)</property>
- <property name="use_underline">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkMenuItem" id="convertwidget43">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Baltic (ISO-8859-4)</property>
- <property name="use_underline">True</property>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblForwardStyle">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Forward style:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblCharset">
- <property name="visible">True</property>
- <property name="label" translatable="yes">C_haracter set:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">omenuCharset1</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox241">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkVBox" id="vbox207">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkLabel" id="label588">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Top Posting Option&lt;/b&gt; (Not Recommended)</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.479999989271</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkTopSignature">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Keep Signature above the original message on replying</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label506">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Alerts&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox190">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label507">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">12</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table29">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vboxAlerts">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkPromptEmptySubject">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Prompt when sending messages with an empty subject line</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkPromptBccOnly">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Pr_ompt when sending messages with only Bcc recipients defined</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblGeneral">
- <property name="visible">True</property>
- <property name="label" translatable="yes">General</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxSignatures">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="vbox201">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label548">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Sig_natures&lt;/b&gt;</property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">listSignatures</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxSignatures">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label550">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label549">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow46">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="listSignatures">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- <accessibility>
- <atkproperty name="AtkObject::accessible_name" translatable="yes">Signatures Table</atkproperty>
- </accessibility>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxSignatureButtons">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkVButtonBox" id="vbuttonbox25">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_START</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkButton" id="cmdSignatureAdd">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-add</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="cmdSignatureAddScript">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="cmdSignatureAddScriptClicked"/>
-
- <child>
- <widget class="GtkAlignment" id="alignment32">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox223">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image7">
- <property name="visible">True</property>
- <property name="stock">gtk-execute</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label554">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Add _Script</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="cmdSignatureEdit">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment31">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox222">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image6">
- <property name="visible">True</property>
- <property name="stock">gtk-properties</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label553">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Edit</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="cmdSignatureDelete">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-remove</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox202">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label551">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Preview&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox162">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label552">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolled-sig">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblSignatures">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Signatures</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxSpellChecking">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkVBox" id="vbox196">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label534">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;_Languages&lt;/b&gt;</property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">listSpellCheckLanguage</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox218">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label555">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox197">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox178">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="hbox192">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="hboxLanguages">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow48">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="listSpellCheckLanguage">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- <accessibility>
- <atkproperty name="AtkObject::accessible_name" translatable="yes">Languages Table</atkproperty>
- </accessibility>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxImageAndHelp">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkImage" id="pixmapSpellInfo">
- <property name="visible">True</property>
- <property name="stock">gtk-dialog-info</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblSpellChecking">
- <property name="visible">True</property>
- <property name="label" translatable="yes">The list of languages here reflects only the languages for which you have a dictionary installed.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="frameSpellChecking">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label508">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Options&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox191">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label556">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxOptions">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkEnableSpellChecking">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Check spelling while I _type</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxSpellCheckColor">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="lblSpellCheckColor">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Color for _misspelled words:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">colorButtonSpellCheckColor</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkColorButton" id="colorButtonSpellCheckColor">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="use_alpha">False</property>
- <property name="title" translatable="yes">Pick a color</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label450">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Spell Checking</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkWindow" id="font_tab">
- <property name="title" translatable="yes">Font Properties</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkVBox" id="toplevel">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <placeholder/>
- </child>
-
- <child>
- <widget class="GtkVBox" id="frame4">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label512">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Printed Fonts&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox194">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label513">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">12</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="tblPrint">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="lblPrintVariable">
- <property name="visible">True</property>
- <property name="label" translatable="yes">V_ariable-width:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">print_variable</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblPrintFixed">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Fi_xed-width:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">print_fixed</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFontButton" id="print_fixed">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="title" translatable="yes">Select HTML fixed width font for printing</property>
- <property name="show_style">True</property>
- <property name="show_size">True</property>
- <property name="use_font">False</property>
- <property name="use_size">False</property>
- <property name="focus_on_click">True</property>
- <signal name="font_set" handler="changed"/>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFontButton" id="print_variable">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="title" translatable="yes">Select HTML variable width font for printing</property>
- <property name="show_style">True</property>
- <property name="show_size">True</property>
- <property name="use_font">False</property>
- <property name="use_size">False</property>
- <property name="focus_on_click">True</property>
- <signal name="font_set" handler="changed"/>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkDialog" id="add_script_signature">
- <property name="title" translatable="yes"></property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
- <property name="has_separator">False</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area1">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
-
- <child>
- <widget class="GtkButton" id="button_add_script_add">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">0</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment30">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox221">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkImage" id="image5">
- <property name="visible">True</property>
- <property name="stock">gtk-add</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label547">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Add Signature</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="button_add_script_cancel">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-cancel</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">0</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox160">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox_add_script_signature">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="hboxImageAndHelp">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkImage" id="pixmap1">
- <property name="visible">True</property>
- <property name="stock">gtk-dialog-info</property>
- <property name="icon_size">6</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label456">
- <property name="visible">True</property>
- <property name="label" translatable="yes">The output of this script will be used as your
-signature. The name you specify will be used for display purposes only.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="tblNameScript">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label459">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Name:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">entry_add_script_name</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label460">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Script:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">filechooserbutton_add_script</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="entry_add_script_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFileChooserButton" id="filechooserbutton_add_script">
- <property name="visible">True</property>
- <property name="title" translatable="yes"></property>
- <property name="action">GTK_FILE_CHOOSER_ACTION_OPEN</property>
- <property name="local_only">True</property>
- <property name="show_hidden">False</property>
- <property name="do_overwrite_confirmation">False</property>
- <property name="width_chars">-1</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkWindow" id="network_prefs_tab">
- <property name="visible">True</property>
- <property name="title" translatable="yes">window1</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkNotebook" id="network_preferences_toplevel">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="show_tabs">True</property>
- <property name="show_border">True</property>
- <property name="tab_pos">GTK_POS_TOP</property>
- <property name="scrollable">False</property>
- <property name="enable_popup">False</property>
-
- <child>
- <widget class="GtkVBox" id="vboxGeneral">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">18</property>
-
- <child>
- <widget class="GtkVBox" id="frameProxy">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label76">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Proxy Settings&lt;/span&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxProxy">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkRadioButton" id="rdoSysSettings">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Use system defaults</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="rdoNoProxy">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Direct connection to the Internet</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">rdoSysSettings</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="rdoManualProxy">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Manual proxy configuration:</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">rdoSysSettings</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkAlignment" id="alignment27">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">1</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">24</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox18">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkTable" id="table8">
- <property name="visible">True</property>
- <property name="n_rows">4</property>
- <property name="n_columns">4</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="lblHttpHost">
- <property name="visible">True</property>
- <property name="label" translatable="yes">H_TTP Proxy:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">txtHttpHost</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblHttpsHost">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Secure HTTP Proxy:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">txtHttpsHost</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblIgnoreHosts">
- <property name="visible">True</property>
- <property name="label" translatable="yes">No _Proxy for:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">txtIgnoreHosts</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="txtHttpHost">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="txtHttpsHost">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblHttpPort">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Port:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblHttpsPort">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Port:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkSpinButton" id="spnHttpPort">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="climb_rate">1</property>
- <property name="digits">0</property>
- <property name="numeric">False</property>
- <property name="update_policy">GTK_UPDATE_ALWAYS</property>
- <property name="snap_to_ticks">False</property>
- <property name="wrap">False</property>
- <property name="adjustment">0 0 65535 1 10 0</property>
- </widget>
- <packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkSpinButton" id="spnHttpsPort">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="climb_rate">1</property>
- <property name="digits">0</property>
- <property name="numeric">False</property>
- <property name="update_policy">GTK_UPDATE_ALWAYS</property>
- <property name="snap_to_ticks">False</property>
- <property name="wrap">False</property>
- <property name="adjustment">0 0 65535 1 10 0</property>
- </widget>
- <packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="txtIgnoreHosts">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">4</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkUseAuth">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Use Authe_ntication</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkAlignment" id="alignment26">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">1</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">24</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkTable" id="table11">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">3</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="lblAuthUser">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Us_ername:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">txtAuthUser</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblAuthPwd">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Pass_word:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">txtAuthPwd</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="txtAuthUser">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="txtAuthPwd">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">False</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblGeneral">
- <property name="visible">True</property>
- <property name="label" translatable="yes">General</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblForwardStyle">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Forward style:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblCharset">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">C_haracter set:</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxComposerCharset">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox241">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox207">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">8</property>
+ <child>
+ <widget class="GtkLabel" id="label588">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.47999998927116394</property>
+ <property name="label" translatable="yes">&lt;b&gt;Top Posting Option&lt;/b&gt; (Not Recommended)</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkTopSignature">
+ <property name="label" translatable="yes">_Keep Signature above the original message on replying</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label506">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Alerts&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox190">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkLabel" id="label507">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table29">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxAlerts">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkPromptEmptySubject">
+ <property name="label" translatable="yes">_Prompt when sending messages with an empty subject line</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkPromptBccOnly">
+ <property name="label" translatable="yes">Pr_ompt when sending messages with only Bcc recipients defined</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblGeneral">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">General</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxSignatures">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox201">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label548">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;Sig_natures&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignSignatures">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox202">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label551">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;Preview&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox162">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label552">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolled-sig">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblSignatures">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Signatures</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxSpellChecking">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox196">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label534">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;_Languages&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">listSpellCheckLanguage</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox218">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label555">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox197">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox178">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox192">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hboxLanguages">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow48">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <widget class="GtkTreeView" id="listSpellCheckLanguage">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <accessibility>
+ <atkproperty name="AtkObject::accessible-name" translatable="yes">Languages Table</atkproperty>
+ </accessibility>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxImageAndHelp">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="pixmapSpellInfo">
+ <property name="visible">True</property>
+ <property name="yalign">0</property>
+ <property name="stock">gtk-dialog-info</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblSpellChecking">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The list of languages here reflects only the languages for which you have a dictionary installed.</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="frameSpellChecking">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label508">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Options&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox191">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label556">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxOptions">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkEnableSpellChecking">
+ <property name="label" translatable="yes">Check spelling while I _type</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxSpellCheckColor">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblSpellCheckColor">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Color for _misspelled words:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">colorButtonSpellCheckColor</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkColorButton" id="colorButtonSpellCheckColor">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Pick a color</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label450">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Spell Checking</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="font_tab">
+ <property name="title" translatable="yes">Font Properties</property>
+ <child>
+ <widget class="GtkVBox" id="toplevel">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="frame4">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label512">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Printed Fonts&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox194">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label513">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="tblPrint">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblPrintVariable">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">V_ariable-width:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">print_variable</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblPrintFixed">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Fi_xed-width:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">print_fixed</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFontButton" id="print_fixed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Select HTML fixed width font for printing</property>
+ <signal name="font_set" handler="changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFontButton" id="print_variable">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Select HTML variable width font for printing</property>
+ <signal name="font_set" handler="changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkDialog" id="add_script_signature">
+ <property name="type_hint">normal</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox160">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkVBox" id="vbox_add_script_signature">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hboxImageAndHelp">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="pixmap1">
+ <property name="visible">True</property>
+ <property name="yalign">0</property>
+ <property name="stock">gtk-dialog-info</property>
+ <property name="icon-size">6</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label456">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The output of this script will be used as your
+signature. The name you specify will be used
+for display purposes only. </property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="tblNameScript">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label459">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">entry_add_script_name</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label460">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Script:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">filechooserbutton_add_script</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_add_script_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFileChooserButton" id="filechooserbutton_add_script">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <widget class="GtkButton" id="button_add_script_add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment30">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox221">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image5">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label547">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Add Signature</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_add_script_cancel">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="network_prefs_tab">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">window1</property>
+ <child>
+ <widget class="GtkNotebook" id="network_preferences_toplevel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <widget class="GtkVBox" id="vboxGeneral">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">18</property>
+ <child>
+ <widget class="GtkVBox" id="frameProxy">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label76">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Proxy Settings&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxProxy">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">8</property>
+ <child>
+ <widget class="GtkRadioButton" id="rdoSysSettings">
+ <property name="label" translatable="yes">_Use system defaults</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="rdoNoProxy">
+ <property name="label" translatable="yes">_Direct connection to the Internet</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">rdoSysSettings</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="rdoManualProxy">
+ <property name="label" translatable="yes">_Manual proxy configuration:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">rdoSysSettings</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment27">
+ <property name="visible">True</property>
+ <property name="left_padding">24</property>
+ <child>
+ <widget class="GtkVBox" id="vbox18">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkTable" id="table8">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblHttpHost">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">H_TTP Proxy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtHttpHost</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHttpsHost">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Secure HTTP Proxy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtHttpsHost</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblIgnoreHosts">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">No _Proxy for:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtIgnoreHosts</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtHttpHost">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtHttpsHost">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHttpPort">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Port:</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHttpsPort">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Port:</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spnHttpPort">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 65535 1 10 0</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spnHttpsPort">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 65535 1 10 0</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtIgnoreHosts">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkUseAuth">
+ <property name="label" translatable="yes">Use Authe_ntication</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment26">
+ <property name="visible">True</property>
+ <property name="left_padding">24</property>
+ <child>
+ <widget class="GtkTable" id="table11">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">3</property>
+ <child>
+ <widget class="GtkLabel" id="lblAuthUser">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Us_ername:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtAuthUser</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblAuthPwd">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Pass_word:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtAuthPwd</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtAuthUser">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtAuthPwd">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="visibility">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblGeneral">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">General</property>
+ </widget>
+ <packing>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
diff --git a/mail/mail-config.h b/mail/mail-config.h
index 80a82a2f83..cc5878456c 100644
--- a/mail/mail-config.h
+++ b/mail/mail-config.h
@@ -33,14 +33,6 @@
G_BEGIN_DECLS
-typedef struct _MailConfigSignature {
- gint id;
- gchar *name;
- gchar *filename;
- gchar *script;
- gboolean html;
-} MailConfigSignature;
-
typedef enum {
MAIL_CONFIG_HTTP_NEVER,
MAIL_CONFIG_HTTP_SOMETIMES,
@@ -83,53 +75,20 @@ void mail_config_write_on_exit (void);
GConfClient *mail_config_get_gconf_client (void);
/* General Accessor functions */
-gboolean mail_config_is_configured (void);
-gboolean mail_config_is_corrupt (void);
-
-GSList *mail_config_get_labels (void);
-
const gchar **mail_config_get_allowable_mime_types (void);
void mail_config_service_set_save_passwd (EAccountService *service, gboolean save_passwd);
/* accounts */
-gboolean mail_config_find_account (EAccount *account);
-EAccount *mail_config_get_default_account (void);
-EAccount *mail_config_get_account_by_name (const gchar *account_name);
-EAccount *mail_config_get_account_by_uid (const gchar *uid);
EAccount *mail_config_get_account_by_source_url (const gchar *url);
EAccount *mail_config_get_account_by_transport_url (const gchar *url);
-EAccountList *mail_config_get_accounts (void);
-void mail_config_add_account (EAccount *account);
-void mail_config_remove_account (EAccount *account);
-void mail_config_set_default_account (EAccount *account);
gint mail_config_get_address_count (void);
gint mail_config_get_message_limit (void);
gboolean mail_config_get_enable_magic_spacebar (void);
-void mail_config_remove_account_proxies (EAccount *account);
-void mail_config_prune_proxies (void);
-gint mail_config_has_proxies (EAccount *account);
-
-EAccountIdentity *mail_config_get_default_identity (void);
EAccountService *mail_config_get_default_transport (void);
-void mail_config_save_accounts (void);
-
-/* signatures */
-ESignature *mail_config_signature_new (const gchar *filename, gboolean script, gboolean html);
-ESignature *mail_config_get_signature_by_uid (const gchar *uid);
-ESignature *mail_config_get_signature_by_name (const gchar *name);
-
-ESignatureList *mail_config_get_signatures (void);
-void mail_config_add_signature (ESignature *signature);
-void mail_config_remove_signature (ESignature *signature);
-
-void mail_config_save_signatures (void);
-
-gchar *mail_config_signature_run_script (const gchar *script);
-
/* uri's got changed by the store, etc */
void mail_config_uri_renamed (GCompareFunc uri_cmp, const gchar *old, const gchar *new);
void mail_config_uri_deleted (GCompareFunc uri_cmp, const gchar *uri);
@@ -146,12 +105,8 @@ void mail_config_reload_junk_headers (void);
gboolean mail_config_get_lookup_book (void);
gboolean mail_config_get_lookup_book_local_only (void);
-gboolean mail_config_scripts_disabled (void);
-
GType evolution_mail_config_get_type (void);
-gboolean evolution_mail_config_factory_init (void);
-
G_END_DECLS
#endif /* MAIL_CONFIG_H */
diff --git a/mail/mail-crypto.c b/mail/mail-crypto.c
deleted file mode 100644
index f484e0a5d8..0000000000
--- a/mail/mail-crypto.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <camel/camel-gpg-context.h>
-#include <libedataserver/e-account.h>
-
-#include "mail-crypto.h"
-#include "mail-session.h"
-
-/**
- * mail_crypto_get_pgp_cipher_context:
- * @account: Account that will be using this context
- *
- * Constructs a new GnuPG cipher context with the appropriate
- * options set based on the account provided.
- **/
-CamelCipherContext *
-mail_crypto_get_pgp_cipher_context (EAccount *account)
-{
- CamelCipherContext *cipher;
-
- cipher = camel_gpg_context_new (session);
- if (account)
- camel_gpg_context_set_always_trust ((CamelGpgContext *) cipher, account->pgp_always_trust);
-
- return cipher;
-}
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index 50167b7f0a..d19e163001 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -37,9 +37,7 @@
#include <glib.h>
#include <glib/gstdio.h>
-#include <libgnome/gnome-sound.h>
#include <glib/gi18n.h>
-#include <bonobo/bonobo-exception.h>
#include <camel/camel-store.h>
#include <camel/camel-folder.h>
#include <camel/camel-vtrash-folder.h>
@@ -50,12 +48,12 @@
#include <libedataserver/e-data-server-util.h>
#include <libedataserver/e-msgport.h>
#include "e-util/e-util.h"
+#include "shell/e-shell.h"
#include "mail-mt.h"
#include "mail-folder-cache.h"
#include "mail-ops.h"
#include "mail-session.h"
-#include "mail-component.h"
#include "mail-tools.h"
/* For notifications of changes */
@@ -65,6 +63,10 @@
#include "em-folder-tree-model.h"
#include "em-event.h"
+#include "em-utils.h"
+
+#include "e-mail-local.h"
+#include "e-mail-store.h"
#define w(x)
#define d(x)
@@ -150,14 +152,14 @@ free_update(struct _folder_update *up)
}
static void
-real_flush_updates(gpointer o, gpointer event_data, gpointer data)
+real_flush_updates (void)
{
- struct _MailComponent *component;
- struct _EMFolderTreeModel *model;
+ EShell *shell;
+ EMFolderTreeModel *default_model;
struct _folder_update *up;
- component = mail_component_peek ();
- model = mail_component_peek_tree_model (component);
+ shell = e_shell_get_default ();
+ default_model = em_folder_tree_model_get_default ();
LOCK(info_lock);
while ((up = (struct _folder_update *)e_dlist_remhead(&updates))) {
@@ -186,17 +188,22 @@ real_flush_updates(gpointer o, gpointer event_data, gpointer data)
}
/* update unread counts */
- em_folder_tree_model_set_unread_count (model, up->store, up->full_name, up->unread);
+ em_folder_tree_model_set_unread_count (
+ default_model, up->store, up->full_name, up->unread);
if (up->uri) {
EMEvent *e = em_event_peek();
EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, up->new);
- t->is_inbox = em_folder_tree_model_is_type_inbox (model, up->store, up->full_name);
- t->name = em_folder_tree_model_get_folder_name (model, up->store, up->full_name);
+ t->is_inbox = em_folder_tree_model_is_type_inbox (
+ default_model, up->store, up->full_name);
+ t->name = em_folder_tree_model_get_folder_name (
+ default_model, up->store, up->full_name);
if (t->new > 0)
- mail_indicate_new_mail (TRUE);
+ e_shell_event (
+ shell, "mail-icon",
+ (gpointer) "mail-unread");
/** @Event: folder.changed
* @Title: Folder changed
@@ -208,6 +215,19 @@ real_flush_updates(gpointer o, gpointer event_data, gpointer data)
e_event_emit((EEvent *)e, "folder.changed", (EEventTarget *)t);
}
+ if (CAMEL_IS_VEE_STORE (up->store) && !up->remove) {
+ /* Normally the vfolder store takes care of the folder_opened event itself,
+ but we add folder to the noting system later, thus we do not know about
+ search folders to update them in a tree, thus ensure their changes will
+ be tracked correctly. */
+ CamelFolder *folder = camel_store_get_folder (up->store, up->full_name, 0, NULL);
+
+ if (folder) {
+ mail_note_folder (folder);
+ camel_object_unref (folder);
+ }
+ }
+
free_update(up);
LOCK(info_lock);
@@ -217,10 +237,13 @@ real_flush_updates(gpointer o, gpointer event_data, gpointer data)
}
static void
-flush_updates(void)
+flush_updates (void)
{
if (update_id == -1 && !e_dlist_empty(&updates))
- update_id = mail_async_event_emit(mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)real_flush_updates, NULL, NULL, NULL);
+ update_id = mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI,
+ (MailAsyncFunc) real_flush_updates,
+ NULL, NULL, NULL);
}
static void
@@ -289,20 +312,26 @@ update_1folder(struct _folder_info *mfi, gint new, CamelFolderInfo *info)
{
struct _folder_update *up;
CamelFolder *folder;
+ CamelFolder *local_drafts;
+ CamelFolder *local_outbox;
+ CamelFolder *local_sent;
gint unread = -1;
gint deleted;
+ local_drafts = e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ local_sent = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
+
folder = mfi->folder;
if (folder) {
d(printf("update 1 folder '%s'\n", folder->full_name));
if ((count_trash && (CAMEL_IS_VTRASH_FOLDER (folder)))
- || folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)
- || folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)
- || (count_sent && folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT))) {
+ || folder == local_drafts
+ || folder == local_outbox
+ || (count_sent && folder == local_sent)) {
d(printf(" total count\n"));
unread = camel_folder_get_message_count (folder);
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)
- || folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)) {
+ if (folder == local_drafts || folder == local_outbox) {
guint32 junked = 0;
if ((deleted = camel_folder_get_deleted_message_count (folder)) > 0)
@@ -395,6 +424,9 @@ folder_changed (CamelObject *o, gpointer event_data, gpointer user_data)
static time_t last_newmail = 0;
CamelFolderChangeInfo *changes = event_data;
CamelFolder *folder = (CamelFolder *)o;
+ CamelFolder *local_drafts;
+ CamelFolder *local_outbox;
+ CamelFolder *local_sent;
CamelStore *store = folder->parent_store;
CamelMessageInfo *info;
struct _store_info *si;
@@ -405,10 +437,14 @@ folder_changed (CamelObject *o, gpointer event_data, gpointer user_data)
d(printf("folder '%s' changed\n", folder->full_name));
+ local_drafts = e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ local_sent = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
+
if (!CAMEL_IS_VEE_FOLDER(folder)
- && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)
- && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)
- && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT)
+ && folder != local_drafts
+ && folder != local_outbox
+ && folder != local_sent
&& changes && (changes->uid_added->len > 0)) {
/* for each added message, check to see that it is
brand new, not junk and not already deleted */
@@ -596,6 +632,7 @@ rename_folders(struct _store_info *si, const gchar *oldbase, const gchar *newbas
gchar *old, *olduri, *oldfile, *newuri, *newfile;
struct _folder_info *mfi;
struct _folder_update *up;
+ const gchar *config_dir;
up = g_malloc0(sizeof(*up));
@@ -651,17 +688,18 @@ rename_folders(struct _store_info *si, const gchar *oldbase, const gchar *newbas
#endif
/* rename the meta-data we maintain ourselves */
+ config_dir = em_utils_get_config_dir ();
olduri = folder_to_url(si->store, old);
e_filename_make_safe(olduri);
newuri = folder_to_url(si->store, fi->full_name);
e_filename_make_safe(newuri);
- oldfile = g_strdup_printf("%s/config/custom_view-%s.xml", mail_component_peek_base_directory(NULL), olduri);
- newfile = g_strdup_printf("%s/config/custom_view-%s.xml", mail_component_peek_base_directory(NULL), newuri);
+ oldfile = g_strdup_printf("%s/custom_view-%s.xml", config_dir, olduri);
+ newfile = g_strdup_printf("%s/custom_view-%s.xml", config_dir, newuri);
g_rename(oldfile, newfile);
g_free(oldfile);
g_free(newfile);
- oldfile = g_strdup_printf("%s/config/current_view-%s.xml", mail_component_peek_base_directory(NULL), olduri);
- newfile = g_strdup_printf("%s/config/current_view-%s.xml", mail_component_peek_base_directory(NULL), newuri);
+ oldfile = g_strdup_printf("%s/current_view-%s.xml", config_dir, olduri);
+ newfile = g_strdup_printf("%s/current_view-%s.xml", config_dir, newuri);
g_rename(oldfile, newfile);
g_free(oldfile);
g_free(newfile);
@@ -1053,7 +1091,7 @@ mail_folder_cache_get_folder_info_flags (CamelFolder *folder, gint *flags)
if (stores == NULL)
return FALSE;
- fi.url = camel_url_new(uri, NULL);
+ fi.url = camel_url_new (uri, NULL);
LOCK(info_lock);
g_hash_table_foreach(stores, (GHFunc)storeinfo_find_folder_info, &fi);
diff --git a/mail/mail-mt.c b/mail/mail-mt.c
index 0032a21432..012bca16a6 100644
--- a/mail/mail-mt.c
+++ b/mail/mail-mt.c
@@ -34,14 +34,13 @@
#include <camel/camel-url.h>
#include <camel/camel-operation.h>
+#include "shell/e-shell.h"
#include "misc/e-gui-utils.h"
#include "e-util/e-error.h"
#include "e-util/e-icon-factory.h"
-
-#include "e-activity-handler.h"
+#include "widgets/misc/e-alert-activity.h"
#include "mail-config.h"
-#include "mail-component.h"
#include "mail-session.h"
#include "mail-mt.h"
@@ -65,7 +64,7 @@ static void mail_operation_status(CamelOperation *op, const gchar *what, gint pc
struct _MailMsgPrivate {
gint activity_state; /* sigh sigh sigh, we need to keep track of the state external to the
pointer itself for locking/race conditions */
- gint activity_id;
+ EActivity *activity;
GtkWidget *error;
gboolean cancelable;
};
@@ -140,19 +139,23 @@ mail_msg_new (MailMsgInfo *info)
}
static void
-end_event_callback (CamelObject *o, gpointer event_data, gpointer error)
+end_event_callback (CamelObject *o, EActivity *activity, gpointer error)
{
- MailComponent *component;
- EActivityHandler *activity_handler;
- guint activity_id = GPOINTER_TO_INT (event_data);
-
- component = mail_component_peek ();
- activity_handler = mail_component_peek_activity_handler (component);
- if (!error) {
- e_activity_handler_operation_finished (activity_handler, activity_id);
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ if (error == NULL) {
+ e_activity_complete (activity);
+ g_object_unref (activity);
} else {
- d(printf("Yahooooo, we got it nonintrusively\n"));
- e_activity_handler_operation_set_error (activity_handler, activity_id, error);
+ if (activity != NULL)
+ g_object_unref (activity);
+ activity = e_alert_activity_new_warning (error);
+ e_shell_backend_add_activity (shell_backend, activity);
+ g_object_unref (activity);
}
}
@@ -183,6 +186,9 @@ checkmem(gpointer p)
static void
mail_msg_free (MailMsg *mail_msg)
{
+ if (mail_msg->priv->activity != NULL)
+ g_object_unref (mail_msg->priv->activity);
+
if (mail_msg->cancel != NULL) {
camel_operation_mute (mail_msg->cancel);
camel_operation_unref (mail_msg->cancel);
@@ -209,7 +215,7 @@ void
mail_msg_unref (gpointer msg)
{
MailMsg *mail_msg = msg;
- gint activity_id;
+ EActivity *activity = NULL;
GtkWidget *error = NULL;
g_return_if_fail (mail_msg != NULL);
@@ -253,24 +259,21 @@ mail_msg_unref (gpointer msg)
MAIL_MT_UNLOCK(mail_msg_lock);
return;
} else {
- activity_id = mail_msg->priv->activity_id;
+ activity = mail_msg->priv->activity;
+ if (activity != NULL)
+ g_object_ref (activity);
error = mail_msg->priv->error;
- if (error && !activity_id) {
- e_activity_handler_make_error (mail_component_peek_activity_handler (mail_component_peek ()), "mail", E_LOG_ERROR, error);
- printf("Making error\n");
- }
-
}
MAIL_MT_UNLOCK(mail_msg_lock);
mail_msg_free (mail_msg);
- if (activity_id != 0)
+ if (activity != NULL)
mail_async_event_emit (
mail_async_event, MAIL_ASYNC_GUI,
(MailAsyncFunc) end_event_callback,
- NULL, GINT_TO_POINTER (activity_id), error);
+ NULL, activity, error);
}
/* hash table of ops->dialogue of active errors */
@@ -305,10 +308,8 @@ mail_msg_check_error (gpointer msg)
if (!camel_exception_is_set(&m->ex)
|| m->ex.id == CAMEL_EXCEPTION_USER_CANCEL
- || m->ex.id == CAMEL_EXCEPTION_FOLDER_INVALID_UID) {
- mail_component_show_status_bar (FALSE);
+ || m->ex.id == CAMEL_EXCEPTION_FOLDER_INVALID_UID)
return;
- }
if (active_errors == NULL)
active_errors = g_hash_table_new(NULL, NULL);
@@ -331,10 +332,9 @@ mail_msg_check_error (gpointer msg)
g_hash_table_insert(active_errors, m->info, gd);
g_signal_connect(gd, "response", G_CALLBACK(error_response), m->info);
g_signal_connect(gd, "destroy", G_CALLBACK(error_destroy), m->info);
- if (m->priv->cancelable) {
+ if (m->priv->cancelable)
m->priv->error = (GtkWidget *) gd;
- mail_component_show_status_bar (TRUE);
- } else
+ else
gtk_widget_show((GtkWidget *)gd);
}
@@ -486,7 +486,6 @@ mail_msg_idle_cb (void)
G_LOCK (idle_source_id);
idle_source_id = 0;
G_UNLOCK (idle_source_id);
- mail_component_show_status_bar (TRUE);
/* check the main loop queue */
while ((msg = g_async_queue_try_pop (main_loop_queue)) != NULL) {
if (msg->info->exec != NULL)
@@ -503,7 +502,6 @@ mail_msg_idle_cb (void)
mail_msg_check_error (msg);
mail_msg_unref (msg);
}
- mail_component_show_status_bar (FALSE);
return FALSE;
}
@@ -625,7 +623,6 @@ mail_msg_unordered_push (gpointer msg)
g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (10));
g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL);
- mail_component_show_status_bar (TRUE);
}
void
@@ -636,7 +633,6 @@ mail_msg_fast_ordered_push (gpointer msg)
g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (1));
g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL);
- mail_component_show_status_bar (TRUE);
}
void
@@ -647,7 +643,6 @@ mail_msg_slow_ordered_push (gpointer msg)
g_once (&once, (GThreadFunc) create_thread_pool, GINT_TO_POINTER (1));
g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL);
- mail_component_show_status_bar (TRUE);
}
gboolean
@@ -868,11 +863,9 @@ mail_call_main (mail_call_t type, MailMainFunc func, ...)
m->func = func;
G_VA_COPY(m->ap, ap);
- if (mail_in_main_thread ()) {
- mail_component_show_status_bar (TRUE);
+ if (mail_in_main_thread ())
do_call (m);
- mail_component_show_status_bar (FALSE);
- } else {
+ else {
mail_msg_ref (m);
m->done = e_flag_new ();
mail_msg_main_loop_push (m);
@@ -944,9 +937,17 @@ struct _op_status_msg {
};
static void
+op_cancelled_cb (EActivity *activity,
+ gpointer user_data)
+{
+ mail_msg_cancel (GPOINTER_TO_UINT (user_data));
+}
+
+static void
op_status_exec (struct _op_status_msg *m)
{
- EActivityHandler *activity_handler = mail_component_peek_activity_handler (mail_component_peek ());
+ EShell *shell;
+ EShellBackend *shell_backend;
MailMsg *msg;
MailMsgPrivate *data;
gchar *out, *p, *o, c;
@@ -954,6 +955,9 @@ op_status_exec (struct _op_status_msg *m)
g_return_if_fail (mail_in_main_thread ());
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
MAIL_MT_LOCK (mail_msg_lock);
msg = g_hash_table_lookup (mail_msg_active_table, m->data);
@@ -977,7 +981,7 @@ op_status_exec (struct _op_status_msg *m)
pc = m->pc;
- if (data->activity_id == 0) {
+ if (data->activity == NULL) {
gchar *what;
/* its being created/removed? well leave it be */
@@ -997,28 +1001,39 @@ op_status_exec (struct _op_status_msg *m)
what = g_strdup("");
}
- data->activity_id = e_activity_handler_cancelable_operation_started (activity_handler, "evolution-mail", what, TRUE, (void (*) (gpointer)) camel_operation_cancel, msg->cancel);
+ data->activity = e_activity_new (what);
+ e_activity_set_allow_cancel (data->activity, TRUE);
+ e_activity_set_percent (data->activity, 0.0);
+ e_shell_backend_add_activity (shell_backend, data->activity);
+
+ g_signal_connect (
+ data->activity, "cancelled",
+ G_CALLBACK (op_cancelled_cb),
+ GUINT_TO_POINTER (msg->seq));
g_free (what);
MAIL_MT_LOCK (mail_msg_lock);
if (data->activity_state == 3) {
- gint activity_id = data->activity_id;
+ EActivity *activity;
+
+ activity = g_object_ref (data->activity);
MAIL_MT_UNLOCK (mail_msg_lock);
mail_msg_free (msg);
- if (activity_id != 0)
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) end_event_callback,
- NULL, GINT_TO_POINTER (activity_id), NULL);
+ if (activity != 0)
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) end_event_callback,
+ NULL, activity, NULL);
} else {
data->activity_state = 2;
MAIL_MT_UNLOCK (mail_msg_lock);
}
return;
}
- } else if (data->activity_id != 0) {
+ } else if (data->activity != NULL) {
MAIL_MT_UNLOCK (mail_msg_lock);
- e_activity_handler_operation_progressing (activity_handler, data->activity_id, out, (double)(pc/100.0));
+ e_activity_set_percent (data->activity, pc / 100.0);
} else {
MAIL_MT_UNLOCK (mail_msg_lock);
}
@@ -1071,6 +1086,5 @@ set_stop (gint sensitive)
if (last == sensitive)
return;
- /*bonobo_ui_component_set_prop (uic, "/commands/MailStop", "sensitive", sensitive ? "1" : "0", NULL);*/
last = sensitive;
}
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 04d08cef13..74cf74aeca 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -57,11 +57,11 @@
#include <libedataserver/e-data-server-util.h>
#include "e-util/e-util.h"
+#include "e-util/e-account-utils.h"
#include "e-util/e-util-private.h"
#include "em-filter-rule.h"
#include "em-utils.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-mt.h"
#include "mail-ops.h"
@@ -69,10 +69,13 @@
#include "mail-tools.h"
#include "mail-vfolder.h"
+#include "e-mail-local.h"
+
#define w(x)
#define d(x)
-const gchar *x_mailer;
+/* XXX Make this a preprocessor definition. */
+const gchar *x_mailer = "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT;
/* used for both just filtering a folder + uid's, and for filtering a whole folder */
/* used both for fetching mail, and for filtering mail */
@@ -245,7 +248,7 @@ uid_cachename_hack (CamelStore *store)
{
CamelURL *url = CAMEL_SERVICE (store)->url;
gchar *encoded_url, *filename;
- const gchar *evolution_dir;
+ const gchar *data_dir;
encoded_url = g_strdup_printf ("%s%s%s@%s", url->user,
url->authmech ? ";auth=" : "",
@@ -253,8 +256,8 @@ uid_cachename_hack (CamelStore *store)
url->host);
e_filename_make_safe (encoded_url);
- evolution_dir = mail_component_peek_base_directory (mail_component_peek ());
- filename = g_build_filename (evolution_dir, "pop", encoded_url, "uid-cache", NULL);
+ data_dir = em_utils_get_data_dir ();
+ filename = g_build_filename (data_dir, "pop", encoded_url, "uid-cache", NULL);
g_free (encoded_url);
return filename;
@@ -275,9 +278,10 @@ fetch_mail_exec (struct _fetch_mail_msg *m)
if (m->cancel)
camel_operation_register (m->cancel);
- if ((fm->destination = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_LOCAL_INBOX)) == NULL)
+ fm->destination = e_mail_local_get_folder (E_MAIL_FOLDER_LOCAL_INBOX);
+ if (fm->destination == NULL)
goto fail;
- camel_object_ref(fm->destination);
+ camel_object_ref (fm->destination);
/* FIXME: this should support keep_on_server too, which would then perform a spool
access thingy, right? problem is matching raw messages to uid's etc. */
@@ -473,9 +477,9 @@ mail_send_message(CamelFolder *queue, const gchar *uid, const gchar *destination
gchar *name;
name = g_strstrip(g_strdup(tmp));
- if ((account = mail_config_get_account_by_uid(name))
+ if ((account = e_get_account_by_uid (name))
/* 'old' x-evolution-account stored the name, how silly */
- || (account = mail_config_get_account_by_name(name))) {
+ || (account = e_get_account_by_name (name))) {
if (account->transport && account->transport->url)
transport_url = g_strdup (account->transport->url);
@@ -579,7 +583,7 @@ mail_send_message(CamelFolder *queue, const gchar *uid, const gchar *destination
}
if (!folder) {
- folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT);
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
camel_object_ref(folder);
}
@@ -590,7 +594,7 @@ mail_send_message(CamelFolder *queue, const gchar *uid, const gchar *destination
if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
goto exit;
- sent_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT);
+ sent_folder = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
if (folder != sent_folder) {
const gchar *name;
@@ -685,13 +689,15 @@ report_status (struct _send_queue_msg *m, enum camel_filter_status_t status, gin
static void
send_queue_exec (struct _send_queue_msg *m)
{
- CamelFolder *sent_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT);
+ CamelFolder *sent_folder;
GPtrArray *uids, *send_uids = NULL;
CamelException ex;
gint i, j;
d(printf("sending queue\n"));
+ sent_folder = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
+
if (!(uids = camel_folder_get_uids (m->queue)))
return;
@@ -1267,7 +1273,8 @@ struct _get_quota_msg {
CamelFolder *folder;
CamelFolderQuotaInfo *quota;
- void (*done) (CamelFolder *folder, CamelFolderQuotaInfo *quota, gpointer data);
+ void (*done) (CamelFolder *folder, const gchar *folder_uri, CamelFolderQuotaInfo *quota, gpointer data);
+ gchar *folder_uri;
gpointer data;
};
@@ -1287,7 +1294,7 @@ static void
get_quota_done (struct _get_quota_msg *m)
{
if (m->done)
- m->done (m->folder, m->quota, m->data);
+ m->done (m->folder, m->folder_uri, m->quota, m->data);
}
static void
@@ -1297,6 +1304,7 @@ get_quota_free (struct _get_quota_msg *m)
camel_object_unref (m->folder);
if (m->quota)
camel_folder_quota_info_free (m->quota);
+ g_free (m->folder_uri);
}
static MailMsgInfo get_quota_info = {
@@ -1309,7 +1317,8 @@ static MailMsgInfo get_quota_info = {
gint
mail_get_folder_quota (CamelFolder *folder,
- void (*done)(CamelFolder *folder, CamelFolderQuotaInfo *quota, gpointer data),
+ const gchar *folder_uri,
+ void (*done)(CamelFolder *folder, const gchar *uri, CamelFolderQuotaInfo *quota, gpointer data),
gpointer data, MailMsgDispatchFunc dispatch)
{
struct _get_quota_msg *m;
@@ -1319,6 +1328,7 @@ mail_get_folder_quota (CamelFolder *folder,
m = mail_msg_new (&get_quota_info);
m->folder = folder;
+ m->folder_uri = g_strdup (folder_uri);
m->data = data;
m->done = done;
@@ -1747,15 +1757,15 @@ empty_trash_desc (struct _empty_trash_msg *m)
static void
empty_trash_exec (struct _empty_trash_msg *m)
{
- const gchar *evolution_dir;
+ const gchar *data_dir;
CamelFolder *trash;
gchar *uri;
if (m->account) {
trash = mail_tool_get_trash (m->account->source->url, FALSE, &m->base.ex);
} else {
- evolution_dir = mail_component_peek_base_directory (mail_component_peek ());
- uri = g_strdup_printf ("mbox:%s/local", evolution_dir);
+ data_dir = em_utils_get_data_dir ();
+ uri = g_strdup_printf ("mbox:%s/local", data_dir);
trash = mail_tool_get_trash (uri, TRUE, &m->base.ex);
g_free (uri);
}
diff --git a/mail/mail-ops.h b/mail/mail-ops.h
index 4bc1a9b47d..3233f03219 100644
--- a/mail/mail-ops.h
+++ b/mail/mail-ops.h
@@ -71,7 +71,8 @@ gint mail_get_folder (const gchar *uri, guint32 flags,
/* get quota information for a folder */
gint mail_get_folder_quota (CamelFolder *folder,
- void (*done)(CamelFolder *folder, CamelFolderQuotaInfo *quota, gpointer data),
+ const gchar *folder_uri,
+ void (*done)(CamelFolder *folder, const gchar *folder_uri, CamelFolderQuotaInfo *quota, gpointer data),
gpointer data, MailMsgDispatchFunc dispatch);
/* and for a store */
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index 04a5defa34..7f7c99724d 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -38,7 +38,6 @@
#include "camel/camel-store.h"
#include "mail-mt.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-session.h"
#include "mail-tools.h"
@@ -46,7 +45,12 @@
#include "mail-send-recv.h"
#include "mail-folder-cache.h"
#include "em-event.h"
-#include <e-util/gconf-bridge.h>
+
+#include "shell/e-shell.h"
+#include "e-util/e-account-utils.h"
+#include "e-util/gconf-bridge.h"
+
+#include "e-mail-local.h"
#define d(x)
@@ -160,7 +164,8 @@ setup_send_data(void)
g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) free_folder_info);
- data->inbox = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_LOCAL_INBOX);
+ data->inbox = e_mail_local_get_folder (
+ E_MAIL_FOLDER_LOCAL_INBOX);
camel_object_ref(data->inbox);
data->active = g_hash_table_new_full (
g_str_hash, g_str_equal,
@@ -360,7 +365,10 @@ get_receive_type(const gchar *url)
}
static struct _send_data *
-build_dialog (EAccountList *accounts, CamelFolder *outbox, const gchar *destination, gboolean show_dialog)
+build_dialog (GtkWindow *parent,
+ EAccountList *accounts,
+ CamelFolder *outbox,
+ const gchar *destination)
{
GtkDialog *gd;
GtkWidget *table;
@@ -380,7 +388,10 @@ build_dialog (EAccountList *accounts, CamelFolder *outbox, const gchar *destinat
EIterator *iter;
EMEventTargetSendReceive *target;
- gd = (GtkDialog *)(send_recv_dialog = gtk_dialog_new_with_buttons(_("Send & Receive Mail"), NULL, GTK_DIALOG_NO_SEPARATOR, NULL));
+ send_recv_dialog = gtk_dialog_new_with_buttons (
+ _("Send & Receive Mail"), parent,
+ GTK_DIALOG_NO_SEPARATOR, NULL);
+ gd = GTK_DIALOG (send_recv_dialog);
gtk_window_set_modal ((GtkWindow *) gd, FALSE);
gconf_bridge_bind_window_size (
@@ -611,7 +622,8 @@ build_dialog (EAccountList *accounts, CamelFolder *outbox, const gchar *destinat
}
gtk_widget_show_all (table);
- if (show_dialog)
+
+ if (parent != NULL)
gtk_widget_show (GTK_WIDGET (gd));
g_signal_connect (gd, "response", G_CALLBACK (dialog_response), data);
@@ -680,8 +692,12 @@ receive_done (const gchar *uri, gpointer data)
/* if we've been called to run again - run again */
if (info->type == SEND_SEND && info->state == SEND_ACTIVE && info->again) {
+ CamelFolder *local_outbox;
+
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+
info->again = 0;
- mail_send_queue (mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX),
+ mail_send_queue (local_outbox,
info->uri,
FILTER_SOURCE_OUTGOING,
info->cancel,
@@ -900,25 +916,27 @@ receive_update_got_store (gchar *uri, CamelStore *store, gpointer data)
struct _send_info *info = data;
if (store) {
- mail_note_store(store, info->cancel, receive_update_got_folderinfo, info);
+ mail_note_store(
+ store, info->cancel,
+ receive_update_got_folderinfo, info);
} else {
receive_done("", info);
}
}
GtkWidget *
-mail_send_receive_dialog (gboolean show_dialog)
+mail_send_receive (GtkWindow *parent)
{
- CamelFolder *outbox_folder;
+ CamelFolder *local_outbox;
struct _send_data *data;
EAccountList *accounts;
EAccount *account;
GList *scan;
if (send_recv_dialog != NULL) {
- if (show_dialog && GTK_WIDGET_REALIZED(send_recv_dialog)) {
- gdk_window_show(send_recv_dialog->window);
- gdk_window_raise(send_recv_dialog->window);
+ if (parent != NULL && GTK_WIDGET_REALIZED (send_recv_dialog)) {
+ gdk_window_show (send_recv_dialog->window);
+ gdk_window_raise (send_recv_dialog->window);
}
return send_recv_dialog;
}
@@ -926,14 +944,15 @@ mail_send_receive_dialog (gboolean show_dialog)
if (!camel_session_is_online (session))
return send_recv_dialog;
- account = mail_config_get_default_account ();
+ account = e_get_default_account ();
if (!account || !account->transport->url)
return send_recv_dialog;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
- outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
- data = build_dialog (accounts, outbox_folder, account->transport->url, show_dialog);
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ data = build_dialog (
+ parent, accounts, local_outbox, account->transport->url);
scan = data->infos;
while (scan) {
struct _send_info *info = scan->data;
@@ -949,7 +968,7 @@ mail_send_receive_dialog (gboolean show_dialog)
break;
case SEND_SEND:
/* todo, store the folder in info? */
- mail_send_queue(outbox_folder, info->uri,
+ mail_send_queue(local_outbox, info->uri,
FILTER_SOURCE_OUTGOING,
info->cancel,
receive_get_folder, info,
@@ -968,12 +987,6 @@ mail_send_receive_dialog (gboolean show_dialog)
return send_recv_dialog;
}
-GtkWidget *
-mail_send_receive ()
-{
- return mail_send_receive_dialog(TRUE);
-}
-
struct _auto_data {
EAccount *account;
gint period; /* in seconds */
@@ -1066,16 +1079,16 @@ auto_account_changed(EAccountList *eal, EAccount *ea, gpointer dummy)
}
static void
-auto_online(CamelObject *o, gpointer ed, gpointer d)
+auto_online (EShell *shell)
{
EIterator *iter;
EAccountList *accounts;
struct _auto_data *info;
- if (!GPOINTER_TO_INT(ed))
+ if (!e_shell_get_online (shell))
return;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
for (iter = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(iter);e_iterator_next(iter)) {
info = g_object_get_data((GObject *)e_iterator_get(iter), "mail-autoreceive");
if (info && info->timeout_id)
@@ -1086,15 +1099,20 @@ auto_online(CamelObject *o, gpointer ed, gpointer d)
/* call to setup initial, and after changes are made to the config */
/* FIXME: Need a cleanup funciton for when object is deactivated */
void
-mail_autoreceive_init (CamelSession *session)
+mail_autoreceive_init (EShellBackend *shell_backend,
+ CamelSession *session)
{
EAccountList *accounts;
EIterator *iter;
+ EShell *shell;
+
+ g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+ g_return_if_fail (CAMEL_IS_SESSION (session));
if (auto_active)
return;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
auto_active = g_hash_table_new(g_str_hash, g_str_equal);
g_signal_connect(accounts, "account-added", G_CALLBACK(auto_account_added), NULL);
@@ -1104,7 +1122,13 @@ mail_autoreceive_init (CamelSession *session)
for (iter = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(iter);e_iterator_next(iter))
auto_account_added(accounts, (EAccount *)e_iterator_get(iter), NULL);
- camel_object_hook_event (session, "online", auto_online, NULL);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ auto_online (shell);
+
+ g_signal_connect (
+ shell, "notify::online",
+ G_CALLBACK (auto_online), NULL);
}
/* we setup the download info's in a hashtable, if we later need to build the gui, we insert
@@ -1114,7 +1138,7 @@ mail_receive_uri (const gchar *uri, gboolean keep_on_server)
{
struct _send_info *info;
struct _send_data *data;
- CamelFolder *outbox_folder;
+ CamelFolder *local_outbox;
send_info_t type;
data = setup_send_data();
@@ -1159,8 +1183,8 @@ mail_receive_uri (const gchar *uri, gboolean keep_on_server)
break;
case SEND_SEND:
/* todo, store the folder in info? */
- outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
- mail_send_queue (outbox_folder, info->uri,
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ mail_send_queue (local_outbox, info->uri,
FILTER_SOURCE_OUTGOING,
info->cancel,
receive_get_folder, info,
@@ -1178,7 +1202,7 @@ mail_receive_uri (const gchar *uri, gboolean keep_on_server)
void
mail_send (void)
{
- CamelFolder *outbox_folder;
+ CamelFolder *local_outbox;
EAccountService *transport;
struct _send_info *info;
struct _send_data *data;
@@ -1221,8 +1245,8 @@ mail_send (void)
g_hash_table_insert (data->active, (gpointer) SEND_URI_KEY, info);
/* todo, store the folder in info? */
- outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
- mail_send_queue (outbox_folder, info->uri,
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ mail_send_queue (local_outbox, info->uri,
FILTER_SOURCE_OUTGOING,
info->cancel,
receive_get_folder, info,
diff --git a/mail/mail-send-recv.h b/mail/mail-send-recv.h
index 08ab233d13..2ba1f01aeb 100644
--- a/mail/mail-send-recv.h
+++ b/mail/mail-send-recv.h
@@ -25,12 +25,12 @@
#include <gtk/gtk.h>
#include <camel/camel-session.h>
+#include <shell/e-shell-backend.h>
G_BEGIN_DECLS
/* send/receive all uri's */
-GtkWidget * mail_send_receive (void);
-GtkWidget * mail_send_receive_dialog (gboolean show_dialog);
+GtkWidget * mail_send_receive (GtkWindow *parent);
/* receive a single uri */
void mail_receive_uri (const gchar *uri,
@@ -39,7 +39,8 @@ void mail_receive_uri (const gchar *uri,
void mail_send (void);
/* setup auto receive stuff */
-void mail_autoreceive_init (CamelSession *session);
+void mail_autoreceive_init (EShellBackend *shell_backend,
+ CamelSession *session);
G_END_DECLS
diff --git a/mail/mail-session.c b/mail/mail-session.c
index 7cc1a7e263..27fdaf9942 100644
--- a/mail/mail-session.c
+++ b/mail/mail-session.c
@@ -33,7 +33,7 @@
#include <gconf/gconf-client.h>
-#include <libgnome/gnome-sound.h>
+#include <canberra-gtk.h>
#include <libedataserverui/e-passwords.h>
#include <libedataserver/e-flag.h>
@@ -42,15 +42,16 @@
#include <camel/camel-filter-driver.h>
#include <camel/camel-i18n.h>
+#include "e-util/e-util.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
#include "e-account-combo-box.h"
+#include "shell/e-shell.h"
#include "em-composer-utils.h"
#include "em-filter-context.h"
#include "em-filter-rule.h"
#include "em-utils.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-mt.h"
#include "mail-ops.h"
@@ -82,6 +83,7 @@ typedef struct _MailSessionClass {
} MailSessionClass;
+static EShellBackend *session_shell_backend;
static CamelSessionClass *ms_parent_class;
static gchar *get_password(CamelSession *session, CamelService *service, const gchar *domain, const gchar *prompt, const gchar *item, guint32 flags, CamelException *ex);
@@ -460,7 +462,9 @@ static void
main_play_sound (CamelFilterDriver *driver, gchar *filename, gpointer user_data)
{
if (filename && *filename)
- gnome_sound_play (filename);
+ ca_context_play(ca_gtk_context_get(), 0,
+ CA_PROP_MEDIA_FILENAME, filename,
+ NULL);
else
gdk_beep ();
@@ -502,13 +506,15 @@ main_get_filter_driver (CamelSession *session, const gchar *type, CamelException
{
CamelFilterDriver *driver;
FilterRule *rule = NULL;
+ const gchar *data_dir;
gchar *user, *system;
GConfClient *gconf;
RuleContext *fc;
gconf = mail_config_get_gconf_client ();
- user = g_strdup_printf ("%s/filters.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = e_shell_backend_get_data_dir (session_shell_backend);
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
fc = (RuleContext *) em_filter_context_new ();
rule_context_load (fc, system, user);
@@ -701,12 +707,20 @@ mail_session_check_junk_notify (GConfClient *gconf, guint id, GConfEntry *entry,
}
void
-mail_session_init (const gchar *base_directory)
+mail_session_init (EShellBackend *shell_backend)
{
- gchar *camel_dir;
+ EShell *shell;
GConfClient *gconf;
+ gboolean online;
+ const gchar *data_dir;
- if (camel_init (base_directory, TRUE) != 0)
+ session_shell_backend = shell_backend;
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ online = e_shell_get_online (shell);
+
+ data_dir = e_get_user_data_dir ();
+ if (camel_init (data_dir, TRUE) != 0)
exit (0);
camel_provider_init();
@@ -715,8 +729,8 @@ mail_session_init (const gchar *base_directory)
e_account_combo_box_set_session (session); /* XXX Don't ask... */
e_account_writable(NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD); /* Init the EAccount Setup */
- camel_dir = g_strdup_printf ("%s/mail", base_directory);
- camel_session_construct (session, camel_dir);
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ camel_session_construct (session, data_dir);
gconf = mail_config_get_gconf_client ();
gconf_client_add_dir (gconf, "/apps/evolution/mail/junk", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
@@ -726,10 +740,8 @@ mail_session_init (const gchar *base_directory)
session, NULL, NULL);
session->junk_plugin = NULL;
- /* The shell will tell us to go online. */
- camel_session_set_online ((CamelSession *) session, FALSE);
+ camel_session_set_online ((CamelSession *) session, online);
mail_config_reload_junk_headers ();
- g_free (camel_dir);
}
void
@@ -772,13 +784,6 @@ mail_session_set_interactive (gboolean interactive)
}
void
-mail_session_forget_passwords (BonoboUIComponent *uih, gpointer user_data,
- const gchar *path)
-{
- e_passwords_forget_passwords ();
-}
-
-void
mail_session_flush_filter_log (void)
{
MailSession *ms = (MailSession *) session;
diff --git a/mail/mail-session.h b/mail/mail-session.h
index aa226222d7..b1274403c0 100644
--- a/mail/mail-session.h
+++ b/mail/mail-session.h
@@ -24,12 +24,12 @@
#define MAIL_SESSION_H
#include <glib.h>
-#include <bonobo/bonobo-ui-component.h>
#include <camel/camel-session.h>
+#include <shell/e-shell-backend.h>
G_BEGIN_DECLS
-void mail_session_init (const gchar *base_directory);
+void mail_session_init (EShellBackend *shell_backend);
void mail_session_shutdown (void);
gboolean mail_session_get_interactive (void);
void mail_session_set_interactive (gboolean interactive);
@@ -39,8 +39,6 @@ gboolean mail_session_accept_dialog (const gchar *prompt, const gchar *key,
gboolean async);
gchar *mail_session_get_password (const gchar *url);
void mail_session_add_password (const gchar *url, const gchar *passwd);
-void mail_session_forget_passwords (BonoboUIComponent *uih, gpointer user_data,
- const gchar *path);
void mail_session_remember_password (const gchar *url);
void mail_session_forget_password (const gchar *key);
@@ -56,4 +54,4 @@ extern CamelSession *session;
G_END_DECLS
-#endif /* ! MAIL_SESSION_H */
+#endif /* MAIL_SESSION_H */
diff --git a/mail/mail-tools.c b/mail/mail-tools.c
index d83aace1ea..a19c3dedb4 100644
--- a/mail/mail-tools.c
+++ b/mail/mail-tools.c
@@ -51,7 +51,6 @@
#include "em-utils.h"
#include "em-vfolder-context.h"
#include "em-vfolder-rule.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-folder-cache.h"
#include "mail-mt.h"
@@ -107,6 +106,7 @@ static gchar *
mail_tool_get_local_movemail_path (const guchar *uri, CamelException *ex)
{
guchar *safe_uri, *c;
+ const gchar *data_dir;
gchar *path, *full;
struct stat st;
@@ -115,7 +115,9 @@ mail_tool_get_local_movemail_path (const guchar *uri, CamelException *ex)
if (strchr("/:;=|%&#!*^()\\, ", *c) || !isprint((gint) *c))
*c = '_';
- path = g_strdup_printf("%s/spool", mail_component_peek_base_directory(NULL));
+ data_dir = em_utils_get_data_dir ();
+ path = g_build_filename (data_dir, "spool", NULL);
+
if (g_stat(path, &st) == -1 && g_mkdir_with_parents(path, 0777) == -1) {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Could not create spool directory `%s': %s"),
path, g_strerror(errno));
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index e995589fe2..96d60ab5f0 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -31,10 +31,11 @@
#include <camel/camel-vee-folder.h>
#include <camel/camel-vee-store.h>
#include <camel/camel-vtrash-folder.h>
+#include <libedataserver/e-account-list.h>
-#include "libedataserver/e-account-list.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
+#include "e-util/e-account-utils.h"
#include "em-folder-tree-model.h"
#include "em-utils.h"
@@ -42,7 +43,6 @@
#include "em-vfolder-editor.h"
#include "em-vfolder-rule.h"
#include "mail-autofilter.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-folder-cache.h"
#include "mail-mt.h"
@@ -50,6 +50,9 @@
#include "mail-tools.h"
#include "mail-vfolder.h"
+#include "e-mail-local.h"
+#include "e-mail-store.h"
+
#define d(x) /* (printf("%s:%s: ", G_STRLOC, G_STRFUNC), (x))*/
static EMVFolderContext *context; /* context remains open all time */
@@ -224,7 +227,7 @@ vfolder_adduri_desc (struct _adduri_msg *m)
else
uid = g_strdup_printf("%s@%s", url->user, url->host);
- account = e_account_list_find(mail_config_get_accounts(), E_ACCOUNT_FIND_UID, uid);
+ account = e_get_account_by_uid (uid);
g_free(uid);
if (account != NULL)
loc = account->name;
@@ -336,21 +339,28 @@ uri_is_ignore(CamelStore *store, const gchar *uri)
EAccountList *accounts;
EAccount *account;
EIterator *iter;
+ const gchar *local_drafts_uri;
+ const gchar *local_outbox_uri;
+ const gchar *local_sent_uri;
gint found = FALSE;
+ local_drafts_uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS);
+ local_outbox_uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_OUTBOX);
+ local_sent_uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_SENT);
+
d(printf("checking '%s' against:\n %s\n %s\n %s\n", uri,
- mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_OUTBOX),
- mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT),
- mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)));
+ local_outbox_uri,
+ local_sent_uri,
+ local_drafts_uri));
- found = camel_store_folder_uri_equal(store, mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_OUTBOX), uri)
- || camel_store_folder_uri_equal(store, mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT), uri)
- || camel_store_folder_uri_equal(store, mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS), uri);
+ found = camel_store_folder_uri_equal(store, local_outbox_uri, uri)
+ || camel_store_folder_uri_equal(store, local_sent_uri, uri)
+ || camel_store_folder_uri_equal(store, local_drafts_uri, uri);
if (found)
return found;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator ((EList *) accounts);
while (e_iterator_is_valid (iter)) {
gchar *curi;
@@ -591,13 +601,14 @@ done:
if (changed->str[0]) {
GtkWidget *dialog;
+ const gchar *data_dir;
gchar *user;
dialog = e_error_new(NULL, "mail:vfolder-updated", changed->str, uri, NULL);
em_utils_show_info_silent (dialog);
- user = g_strdup_printf ("%s/vfolders.xml",
- mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save ((RuleContext *) context, user);
g_free (user);
}
@@ -660,10 +671,12 @@ mail_vfolder_rename_uri(CamelStore *store, const gchar *cfrom, const gchar *cto)
UNLOCK();
if (changed) {
+ const gchar *data_dir;
gchar *user;
d(printf("Vfolders updated from renamed folder\n"));
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
}
@@ -784,21 +797,12 @@ static void context_rule_added(RuleContext *ctx, FilterRule *rule)
static void context_rule_removed(RuleContext *ctx, FilterRule *rule)
{
- gchar *path;
-
gpointer key, folder = NULL;
d(printf("rule removed; %s\n", rule->name));
/* TODO: remove from folder info cache? */
- /* FIXME: is this even necessary? if we remove the folder from
- * the CamelStore, the tree should pick it up auto-magically
- * because it listens to CamelStore events... */
- path = g_strdup_printf("/%s", rule->name);
- mail_component_remove_folder (mail_component_peek (), vfolder_store, path);
- g_free(path);
-
LOCK();
if (g_hash_table_lookup_extended (vfolder_hash, rule->name, &key, &folder)) {
g_hash_table_remove (vfolder_hash, key);
@@ -840,6 +844,8 @@ store_folder_deleted(CamelObject *o, gpointer event_data, gpointer data)
/* delete it from our list */
rule = rule_context_find_rule((RuleContext *)context, info->full_name, NULL);
if (rule) {
+ const gchar *data_dir;
+
/* We need to stop listening to removed events, otherwise we'll try and remove it again */
g_signal_handlers_disconnect_matched(context, G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA, 0,
0, NULL, context_rule_removed, context);
@@ -847,7 +853,8 @@ store_folder_deleted(CamelObject *o, gpointer event_data, gpointer data)
g_object_unref(rule);
g_signal_connect(context, "rule_removed", G_CALLBACK(context_rule_removed), context);
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
} else {
@@ -874,6 +881,8 @@ store_folder_renamed(CamelObject *o, gpointer event_data, gpointer data)
LOCK();
d(printf("Changing folder name in hash table to '%s'\n", info->new->full_name));
if (g_hash_table_lookup_extended (vfolder_hash, info->old_base, &key, &folder)) {
+ const gchar *data_dir;
+
g_hash_table_remove (vfolder_hash, key);
g_free (key);
g_hash_table_insert (vfolder_hash, g_strdup(info->new->full_name), folder);
@@ -890,7 +899,8 @@ store_folder_renamed(CamelObject *o, gpointer event_data, gpointer data)
filter_rule_set_name(rule, info->new->full_name);
g_signal_connect(rule, "changed", G_CALLBACK(rule_changed), folder);
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
@@ -907,6 +917,7 @@ vfolder_load_storage(void)
/* lock for loading storage, it is safe to call it more than once */
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+ const gchar *data_dir;
gchar *user, *storeuri;
FilterRule *rule;
gchar *xmlfile;
@@ -925,7 +936,8 @@ vfolder_load_storage(void)
pthread_mutex_unlock (&lock);
/* first, create the vfolder store, and set it up */
- storeuri = g_strdup_printf("vfolder:%s/vfolder", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ storeuri = g_strdup_printf("vfolder:%s/vfolder", data_dir);
vfolder_store = camel_session_get_store(session, storeuri, NULL);
if (vfolder_store == NULL) {
g_warning("Cannot open vfolder store - no vfolders available");
@@ -942,7 +954,7 @@ vfolder_load_storage(void)
d(printf("got store '%s' = %p\n", storeuri, vfolder_store));
/* load our rules */
- user = g_strdup_printf ("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
context = em_vfolder_context_new ();
xmlfile = g_build_filename (EVOLUTION_PRIVDATADIR, "vfoldertypes.xml", NULL);
@@ -957,7 +969,7 @@ vfolder_load_storage(void)
g_signal_connect(context, "rule_removed", G_CALLBACK(context_rule_removed), context);
/* load store to mail component */
- mail_component_load_store_by_uri (mail_component_peek (), storeuri, _("Search Folders"));
+ e_mail_store_add_by_uri (storeuri, _("Search Folders"));
/* and setup the rules we have */
rule = NULL;
@@ -981,66 +993,66 @@ vfolder_load_storage(void)
void
vfolder_revert(void)
{
+ const gchar *data_dir;
gchar *user;
d(printf("vfolder_revert\n"));
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_revert((RuleContext *)context, user);
g_free(user);
}
-static GtkWidget *vfolder_editor = NULL;
-
-static void
-em_vfolder_editor_response (GtkWidget *dialog, gint button, gpointer data)
+void
+vfolder_edit (EShellView *shell_view)
{
- gchar *user;
+ EShellBackend *shell_backend;
+ EShellWindow *shell_window;
+ GtkWidget *dialog;
+ const gchar *data_dir;
+ gchar *filename;
- user = g_strdup_printf ("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
-
- switch (button) {
- case GTK_RESPONSE_OK:
- rule_context_save((RuleContext *)context, user);
- break;
- default:
- rule_context_revert((RuleContext *)context, user);
- }
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
- vfolder_editor = NULL;
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
- gtk_widget_destroy(dialog);
-
- g_free (user);
-}
-
-void
-vfolder_edit (void)
-{
- if (vfolder_editor) {
- gdk_window_raise (GTK_WIDGET (vfolder_editor)->window);
- return;
- }
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ filename = g_build_filename (data_dir, "vfolders.xml", NULL);
/* ensures vfolder is running */
vfolder_load_storage ();
- vfolder_editor = GTK_WIDGET (em_vfolder_editor_new (context));
- gtk_window_set_title (GTK_WINDOW (vfolder_editor), _("Search Folders"));
- g_signal_connect(vfolder_editor, "response", G_CALLBACK(em_vfolder_editor_response), NULL);
+ dialog = em_vfolder_editor_new (context);
+ gtk_window_set_title (
+ GTK_WINDOW (dialog), _("Search Folders"));
+ gtk_window_set_transient_for (
+ GTK_WINDOW (dialog), GTK_WINDOW (shell_window));
+
+ switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
+ case GTK_RESPONSE_OK:
+ rule_context_save ((RuleContext *) context, filename);
+ break;
+ default:
+ rule_context_revert ((RuleContext *) context, filename);
+ break;
+ }
- gtk_widget_show (vfolder_editor);
+ gtk_widget_destroy (dialog);
}
static void
edit_rule_response(GtkWidget *w, gint button, gpointer data)
{
if (button == GTK_RESPONSE_OK) {
+ const gchar *data_dir;
gchar *user;
FilterRule *rule = g_object_get_data (G_OBJECT (w), "rule");
FilterRule *orig = g_object_get_data (G_OBJECT (w), "orig");
filter_rule_copy(orig, rule);
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
}
@@ -1097,6 +1109,7 @@ static void
new_rule_clicked(GtkWidget *w, gint button, gpointer data)
{
if (button == GTK_RESPONSE_OK) {
+ const gchar *data_dir;
gchar *user;
FilterRule *rule = g_object_get_data((GObject *)w, "rule");
@@ -1112,7 +1125,8 @@ new_rule_clicked(GtkWidget *w, gint button, gpointer data)
g_object_ref(rule);
rule_context_add_rule((RuleContext *)context, rule);
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
}
diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h
index 79374348ae..b3299ab834 100644
--- a/mail/mail-vfolder.h
+++ b/mail/mail-vfolder.h
@@ -28,11 +28,12 @@
#include <filter/filter-part.h>
#include <filter/filter-rule.h>
#include <mail/em-vfolder-rule.h>
+#include <shell/e-shell-view.h>
void vfolder_load_storage(void);
void vfolder_revert(void);
-void vfolder_edit (void);
+void vfolder_edit (EShellView *shell_view);
void vfolder_edit_rule(const gchar *name);
FilterPart *vfolder_create_part (const gchar *name);
FilterRule *vfolder_clone_rule (FilterRule *in);
diff --git a/mail/message-list.c b/mail/message-list.c
index 92c740bb9d..714768ef21 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -50,10 +50,12 @@
#include "e-util/e-profile-event.h"
#include "e-util/e-util-private.h"
#include "e-util/e-util.h"
-#include "e-util/e-util-labels.h"
#include "misc/e-gui-utils.h"
+#include "shell/e-shell.h"
+#include "shell/e-shell-settings.h"
+
#include "table/e-cell-checkbox.h"
#include "table/e-cell-hbox.h"
#include "table/e-cell-date.h"
@@ -67,7 +69,7 @@
#include "table/e-cell-vbox.h"
#include "table/e-cell-hbox.h"
-#include "em-popup.h"
+#include "e-mail-label-list-store.h"
#include "em-utils.h"
#include "mail-config.h"
#include "mail-mt.h"
@@ -97,6 +99,10 @@
#define d(x)
#define t(x)
+#define MESSAGE_LIST_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), MESSAGE_LIST_TYPE, MessageListPrivate))
+
struct _MLSelection {
GPtrArray *uids;
CamelFolder *folder;
@@ -106,6 +112,8 @@ struct _MLSelection {
struct _MessageListPrivate {
GtkWidget *invisible; /* 4 selection */
+ EShellBackend *shell_backend;
+
struct _MLSelection clipboard;
gboolean destroyed;
@@ -113,12 +121,17 @@ struct _MessageListPrivate {
gboolean any_row_changed; /* save state before regen list when this is set to true */
};
+enum {
+ PROP_0,
+ PROP_SHELL_BACKEND
+};
+
static struct {
const gchar *target;
GdkAtom atom;
guint32 actions;
} ml_drag_info[] = {
- { "x-uid-list", NULL, GDK_ACTION_ASK|GDK_ACTION_MOVE|GDK_ACTION_COPY },
+ { "x-uid-list", NULL, GDK_ACTION_MOVE|GDK_ACTION_COPY },
{ "message/rfc822", NULL, GDK_ACTION_COPY },
{ "text/uri-list", NULL, GDK_ACTION_COPY },
};
@@ -808,7 +821,7 @@ message_list_invert_selection (MessageList *message_list)
void
message_list_copy(MessageList *ml, gboolean cut)
{
- struct _MessageListPrivate *p = ml->priv;
+ MessageListPrivate *p = ml->priv;
GPtrArray *uids;
clear_selection(ml, &p->clipboard);
@@ -1220,53 +1233,124 @@ sanitize_recipients (const gchar *string)
}
static gint
-get_all_labels (CamelMessageInfo *msg_info, gchar **label_str, gboolean get_tags)
-{
+get_all_labels (MessageList *message_list,
+ CamelMessageInfo *msg_info,
+ gchar **label_str,
+ gboolean get_tags)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EMailLabelListStore *store;
+ GtkTreeIter iter;
GString *str;
+ const gchar *property_name;
const gchar *old_label;
+ gchar *new_label;
gint count = 0;
const CamelFlag *flag;
- GSList *labels;
- labels = mail_config_get_labels ();
+ shell_backend = message_list_get_shell_backend (message_list);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ property_name = "mail-label-list-store";
+ store = e_shell_settings_get_object (shell_settings, property_name);
+
str = g_string_new ("");
for (flag = camel_message_info_user_flags (msg_info); flag; flag = flag->next) {
- const gchar *name = e_util_labels_get_name (labels, flag->name);
+ gchar *item;
- if (name) {
- if (str->len)
- g_string_append (str, ", ");
+ if (!e_mail_label_list_store_lookup (store, flag->name, &iter))
+ continue;
- if (get_tags)
- name = flag->name;
+ if (get_tags)
+ item = e_mail_label_list_store_get_tag (store, &iter);
+ else
+ item = e_mail_label_list_store_get_name (store, &iter);
- g_string_append (str, name);
- count++;
- }
+ if (str->len)
+ g_string_append (str, ", ");
+
+ g_string_append (str, item);
+ count++;
+
+ g_free (item);
}
- old_label = e_util_labels_get_new_tag (camel_message_info_user_tag (msg_info, "label"));
+ old_label = camel_message_info_user_tag (msg_info, "label");
+ if (old_label == NULL)
+ goto exit;
+
+ /* Convert old-style labels ("<name>") to "$Label<name>". */
+ new_label = g_alloca (strlen (old_label) + 10);
+ g_stpcpy (g_stpcpy (new_label, "$Label"), old_label);
- if (old_label != NULL) {
- const gchar *name = NULL;
+ if (e_mail_label_list_store_lookup (store, new_label, &iter)) {
+ gchar *name = NULL;
if (str->len)
g_string_append (str, ", ");
if (!get_tags)
- name = e_util_labels_get_name (labels, old_label);
+ name = e_mail_label_list_store_get_name (store, &iter);
g_string_append (str, (get_tags || !name) ? old_label : name);
- ++count;
+ count++;
+
+ g_free (name);
}
+exit:
*label_str = g_string_free (str, FALSE);
+ g_object_unref (store);
+
return count;
}
static const gchar *
+get_label_color (MessageList *message_list,
+ const gchar *tag)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EMailLabelListStore *store;
+ GtkTreeIter iter;
+ GdkColor color;
+ const gchar *property_name;
+ const gchar *interned = NULL;
+ gchar *color_spec;
+
+ /* FIXME get_all_labels() should return an array of tree iterators,
+ * not strings. Now we just have to lookup the tag again. */
+
+ shell_backend = message_list_get_shell_backend (message_list);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ property_name = "mail-label-list-store";
+ store = e_shell_settings_get_object (shell_settings, property_name);
+
+ if (!e_mail_label_list_store_lookup (store, tag, &iter))
+ goto exit;
+
+ e_mail_label_list_store_get_color (store, &iter, &color);
+
+ /* XXX Hack to avoid returning an allocated string. */
+ color_spec = gdk_color_to_string (&color);
+ interned = g_intern_string (color_spec);
+ g_free (color_spec);
+
+exit:
+ g_object_unref (store);
+
+ return interned;
+}
+
+static const gchar *
get_trimmed_subject (CamelMessageInfo *info)
{
const gchar *subject;
@@ -1467,9 +1551,8 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, gint col, gpointer model_data
completed = camel_message_info_user_tag(msg_info, "completed-on");
followup = camel_message_info_user_tag(msg_info, "follow-up");
if (colour == NULL) {
- if ((n = get_all_labels (msg_info, &labels_string, TRUE)) == 1) {
-
- colour = e_util_labels_get_color_str (mail_config_get_labels (), labels_string);
+ if ((n = get_all_labels (message_list, msg_info, &labels_string, TRUE)) == 1) {
+ colour = get_label_color (message_list, labels_string);
} else if (camel_message_info_flags(msg_info) & CAMEL_MESSAGE_FLAGGED) {
/* FIXME: extract from the important.xpm somehow. */
colour = "#A7453E";
@@ -1548,7 +1631,7 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, gint col, gpointer model_data
cleansed_str = g_string_new ("");
- if (get_all_labels (msg_info, &str, FALSE)) {
+ if (get_all_labels (message_list, msg_info, &str, FALSE)) {
gint i;
for (i = 0; str[i] != '\0'; ++i) {
if (str[i] != '_') {
@@ -1950,7 +2033,7 @@ ml_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint ti
static gboolean
ml_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, MessageList *ml)
{
- struct _MessageListPrivate *p = ml->priv;
+ MessageListPrivate *p = ml->priv;
clear_selection(ml, &p->clipboard);
@@ -2079,48 +2162,6 @@ ml_drop_action(struct _drop_msg *m)
}
static void
-ml_drop_popup_copy(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _drop_msg *m = data;
-
- m->action = GDK_ACTION_COPY;
- ml_drop_action(m);
-}
-
-static void
-ml_drop_popup_move(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _drop_msg *m = data;
-
- m->action = GDK_ACTION_MOVE;
- ml_drop_action(m);
-}
-
-static void
-ml_drop_popup_cancel(EPopup *ep, EPopupItem *item, gpointer data)
-{
- struct _drop_msg *m = data;
-
- m->aborted = TRUE;
- mail_msg_unref(m);
-}
-
-static EPopupItem ml_drop_popup_menu[] = {
- { E_POPUP_ITEM, (gchar *) "00.emc.02", (gchar *) N_("_Copy"), ml_drop_popup_copy, NULL, (gchar *) "folder-copy", 0 },
- { E_POPUP_ITEM, (gchar *) "00.emc.03", (gchar *) N_("_Move"), ml_drop_popup_move, NULL, (gchar *) "folder-move", 0 },
- { E_POPUP_BAR, (gchar *) "10.emc" },
- { E_POPUP_ITEM, (gchar *) "99.emc.00", (gchar *) N_("Cancel _Drag"), ml_drop_popup_cancel, NULL, NULL, 0 },
-};
-
-static void
-ml_drop_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-
- /* FIXME: free data if no item was selected? */
-}
-
-static void
ml_tree_drag_data_received (ETree *tree, gint row, ETreePath path, gint col,
GdkDragContext *context, gint x, gint y,
GtkSelectionData *data, guint info,
@@ -2146,22 +2187,7 @@ ml_tree_drag_data_received (ETree *tree, gint row, ETreePath path, gint col,
memcpy(m->selection->data, data->data, data->length);
m->selection->length = data->length;
- if (context->action == GDK_ACTION_ASK) {
- EMPopup *emp;
- GSList *menus = NULL;
- GtkMenu *menu;
- gint i;
-
- emp = em_popup_new("org.gnome.mail.messagelist.popup.drop");
- for (i=0;i<sizeof(ml_drop_popup_menu)/sizeof(ml_drop_popup_menu[0]);i++)
- menus = g_slist_append(menus, &ml_drop_popup_menu[i]);
-
- e_popup_add_items((EPopup *)emp, menus, NULL, ml_drop_popup_free, m);
- menu = e_popup_create_menu_once((EPopup *)emp, NULL, 0);
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
- } else {
- ml_drop_action(m);
- }
+ ml_drop_action(m);
}
struct search_child_struct {
@@ -2222,8 +2248,6 @@ ml_tree_drag_motion(ETree *tree, GdkDragContext *context, gint x, gint y, guint
action = context->suggested_action;
if (action == GDK_ACTION_COPY && (actions & GDK_ACTION_MOVE))
action = GDK_ACTION_MOVE;
- else if (action == GDK_ACTION_ASK && (actions & (GDK_ACTION_MOVE|GDK_ACTION_COPY)) != (GDK_ACTION_MOVE|GDK_ACTION_COPY))
- action = GDK_ACTION_MOVE;
gdk_drag_status(context, action, time);
@@ -2245,13 +2269,25 @@ on_model_row_changed (ETableModel *model, gint row, MessageList *ml)
/*
* GObject::init
*/
+
+static void
+message_list_set_shell_backend (MessageList *message_list,
+ EShellBackend *shell_backend)
+{
+ g_return_if_fail (message_list->priv->shell_backend == NULL);
+
+ message_list->priv->shell_backend = g_object_ref (shell_backend);
+}
+
static void
message_list_init (MessageList *message_list)
{
- struct _MessageListPrivate *p;
+ MessageListPrivate *p;
GtkAdjustment *adjustment;
GdkAtom matom;
+ message_list->priv = MESSAGE_LIST_GET_PRIVATE (message_list);
+
adjustment = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, G_MAXDOUBLE, 0.0, 0.0, 0.0);
gtk_scrolled_window_set_vadjustment ((GtkScrolledWindow *) message_list, adjustment);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (message_list), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
@@ -2280,7 +2316,7 @@ message_list_init (MessageList *message_list)
message_list->regen_lock = g_mutex_new ();
/* TODO: Should this only get the selection if we're realised? */
- p = message_list->priv = g_malloc0(sizeof(*message_list->priv));
+ p = message_list->priv;
p->invisible = gtk_invisible_new();
p->destroyed = FALSE;
g_object_ref_sink(p->invisible);
@@ -2301,7 +2337,7 @@ static void
message_list_destroy(GtkObject *object)
{
MessageList *message_list = MESSAGE_LIST (object);
- struct _MessageListPrivate *p = message_list->priv;
+ MessageListPrivate *p = message_list->priv;
p->destroyed = TRUE;
@@ -2353,14 +2389,65 @@ message_list_destroy(GtkObject *object)
message_list->seen_id = 0;
}
+ /* Chain up to parent's destroy() method. */
GTK_OBJECT_CLASS (message_list_parent_class)->destroy(object);
}
static void
-message_list_finalise (GObject *object)
+message_list_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ message_list_set_shell_backend (
+ MESSAGE_LIST (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+message_list_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ g_value_set_object (
+ value, message_list_get_shell_backend (
+ MESSAGE_LIST (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+message_list_dispose (GObject *object)
+{
+ MessageListPrivate *priv;
+
+ priv = MESSAGE_LIST_GET_PRIVATE (object);
+
+ if (priv->shell_backend != NULL) {
+ g_object_unref (priv->shell_backend);
+ priv->shell_backend = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (message_list_parent_class)->dispose (object);
+}
+
+static void
+message_list_finalize (GObject *object)
{
MessageList *message_list = MESSAGE_LIST (object);
- struct _MessageListPrivate *p = message_list->priv;
+ MessageListPrivate *priv = message_list->priv;
g_hash_table_destroy (message_list->normalised_hash);
@@ -2390,10 +2477,9 @@ message_list_finalise (GObject *object)
g_free(message_list->folder_uri);
message_list->folder_uri = NULL;
- clear_selection(message_list, &p->clipboard);
-
- g_free(p);
+ clear_selection(message_list, &priv->clipboard);
+ /* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (message_list_parent_class)->finalize (object);
}
@@ -2401,17 +2487,36 @@ message_list_finalise (GObject *object)
* GObjectClass::init
*/
static void
-message_list_class_init (MessageListClass *message_list_class)
+message_list_class_init (MessageListClass *class)
{
- GObjectClass *object_class = (GObjectClass *) message_list_class;
- GtkObjectClass *gtkobject_class = (GtkObjectClass *) message_list_class;
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
gint i;
for (i=0;i<sizeof(ml_drag_info)/sizeof(ml_drag_info[0]);i++)
ml_drag_info[i].atom = gdk_atom_intern(ml_drag_info[i].target, FALSE);
- object_class->finalize = message_list_finalise;
- gtkobject_class->destroy = message_list_destroy;
+ g_type_class_add_private (class, sizeof (MessageListPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = message_list_set_property;
+ object_class->get_property = message_list_get_property;
+ object_class->dispose = message_list_dispose;
+ object_class->finalize = message_list_finalize;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = message_list_destroy;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_BACKEND,
+ g_param_spec_object (
+ "shell-backend",
+ _("Shell Backend"),
+ _("The mail shell backend"),
+ E_TYPE_SHELL_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
message_list_signals[MESSAGE_SELECTED] =
g_signal_new ("message_selected",
@@ -2541,14 +2646,14 @@ message_list_construct (MessageList *message_list)
e_tree_drag_source_set(message_list->tree, GDK_BUTTON1_MASK,
ml_drag_types, sizeof(ml_drag_types)/sizeof(ml_drag_types[0]),
- GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_ASK);
+ GDK_ACTION_MOVE|GDK_ACTION_COPY);
g_signal_connect(message_list->tree, "tree_drag_data_get",
G_CALLBACK(ml_tree_drag_data_get), message_list);
e_tree_drag_dest_set(message_list->tree, GTK_DEST_DEFAULT_ALL,
ml_drop_types, sizeof(ml_drop_types)/sizeof(ml_drop_types[0]),
- GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_ASK);
+ GDK_ACTION_MOVE|GDK_ACTION_COPY);
g_signal_connect(message_list->tree, "tree_drag_data_received",
G_CALLBACK(ml_tree_drag_data_received), message_list);
@@ -2563,19 +2668,30 @@ message_list_construct (MessageList *message_list)
* Returns a new message-list widget.
**/
GtkWidget *
-message_list_new (void)
+message_list_new (EShellBackend *shell_backend)
{
MessageList *message_list;
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+
message_list = MESSAGE_LIST (g_object_new(message_list_get_type (),
"hadjustment", NULL,
"vadjustment", NULL,
+ "shell-backend", shell_backend,
NULL));
message_list_construct (message_list);
return GTK_WIDGET (message_list);
}
+EShellBackend *
+message_list_get_shell_backend (MessageList *message_list)
+{
+ g_return_val_if_fail (IS_MESSAGE_LIST (message_list), NULL);
+
+ return message_list->priv->shell_backend;
+}
+
static void
clear_info(gchar *key, ETreePath *node, MessageList *ml)
{
@@ -4069,9 +4185,8 @@ regen_list_exec (struct _regen_list_msg *m)
if ((!is_deleted || (is_deleted && !m->hidedel)) && (!is_junk || (is_junk && !m->hidejunk)))
g_ptr_array_add (uids, (gpointer) camel_pstring_strdup (looking_for));
-
- camel_folder_free_message_info (m->folder, looking_info);
}
+
}
}
}
diff --git a/mail/message-list.h b/mail/message-list.h
index 259ec501dd..075c20afe3 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -29,6 +29,9 @@
#include <table/e-table-simple.h>
#include <table/e-tree-scrolled.h>
+#include <camel/camel-folder.h>
+#include <shell/e-shell-backend.h>
+
G_BEGIN_DECLS
#define MESSAGE_LIST_TYPE (message_list_get_type ())
@@ -83,11 +86,13 @@ enum {
#define ML_HIDE_SAME (2147483646)
typedef struct _MessageList MessageList;
+typedef struct _MessageListClass MessageListClass;
+typedef struct _MessageListPrivate MessageListPrivate;
struct _MessageList {
ETreeScrolled parent;
- struct _MessageListPrivate *priv;
+ MessageListPrivate *priv;
/* The table */
ETreeModel *model;
@@ -163,14 +168,14 @@ struct _MessageList {
struct _MailAsyncEvent *async_event;
};
-typedef struct {
+struct _MessageListClass {
ETreeScrolledClass parent_class;
/* signals - select a message */
void (*message_selected) (MessageList *ml, const gchar *uid);
void (*message_list_built) (MessageList *ml);
void (*message_list_scrolled) (MessageList *ml);
-} MessageListClass;
+};
typedef enum {
MESSAGE_LIST_SELECT_NEXT = 0,
@@ -180,7 +185,8 @@ typedef enum {
} MessageListSelectDirection;
GType message_list_get_type (void);
-GtkWidget *message_list_new (void);
+GtkWidget *message_list_new (EShellBackend *shell_backend);
+EShellBackend *message_list_get_shell_backend (MessageList *message_list);
void message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder, const gchar *uri, gboolean outgoing);
void message_list_freeze(MessageList *ml);
diff --git a/mail/message-tag-followup.c b/mail/message-tag-followup.c
index 9293205fb3..6ccd74459a 100644
--- a/mail/message-tag-followup.c
+++ b/mail/message-tag-followup.c
@@ -288,6 +288,11 @@ construct (MessageTagEditor *editor)
gtk_widget_reparent (widget, GTK_DIALOG (editor)->vbox);
gtk_box_set_child_packing (GTK_BOX (GTK_DIALOG (editor)->vbox), widget, TRUE, TRUE, 6, GTK_PACK_START);
+ widget = glade_xml_get_widget (gui, "pixmap");
+ gtk_image_set_from_icon_name (
+ GTK_IMAGE (widget), "stock_mail-flag-for-followup",
+ GTK_ICON_SIZE_DIALOG);
+
followup->message_list = GTK_TREE_VIEW (glade_xml_get_widget (gui, "message_list"));
model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
gtk_tree_view_set_model (followup->message_list, (GtkTreeModel *) model);
diff --git a/mail/searchtypes.xml b/mail/searchtypes.xml
index 63a52ca772..ba349993f7 100644
--- a/mail/searchtypes.xml
+++ b/mail/searchtypes.xml
@@ -329,7 +329,7 @@
</code>
</option>
</input>
- <input type="string" name="recipient"/>
+ <input type="address" name="recipient"/>
</part>
<part name="subject">
@@ -569,7 +569,7 @@
</option>
</input>
<input type="optionlist" name="versus">
- <dynamic func="e_util_labels_get_filter_options"/>
+ <dynamic func="e_mail_labels_get_filter_options"/>
</input>
</part>
@@ -764,29 +764,18 @@
</partset>
<ruleset>
+
<rule grouping="any" source="demand">
- <_title>Subject or Addresses contains</_title>
+ <_title>Subject or Sender contains</_title>
<partset>
<part name="subject">
<value name="subject-type" type="option" value="contains"/>
<value name="subject" type="string"/>
- </part>
+ </part>
<part name="sender">
<value name="sender-type" type="option" value="contains"/>
<value name="sender" type="string"/>
</part>
- <part name="to">
- <value name="recipient-type" type="option" value="contains"/>
- <value name="recipient" type="address"/>
- </part>
- <part name="to">
- <value name="recipient-type" type="option" value="contains"/>
- <value name="recipient" type="address"/>
- </part>
- <part name="to">
- <value name="recipient-type" type="option" value="contains"/>
- <value name="recipient" type="address"/>
- </part>
</partset>
<sources/>
</rule>
@@ -807,21 +796,6 @@
</rule>
<rule grouping="any" source="demand">
- <_title>Subject or Sender contains</_title>
- <partset>
- <part name="subject">
- <value name="subject-type" type="option" value="contains"/>
- <value name="subject" type="string"/>
- </part>
- <part name="sender">
- <value name="sender-type" type="option" value="contains"/>
- <value name="sender" type="string"/>
- </part>
- </partset>
- <sources/>
- </rule>
-
- <rule grouping="any" source="demand">
<_title>Recipients contain</_title>
<partset>
<part name="to">
diff --git a/mail/vfoldertypes.xml b/mail/vfoldertypes.xml
index 11ed7cc0af..9fd117b67d 100644
--- a/mail/vfoldertypes.xml
+++ b/mail/vfoldertypes.xml
@@ -569,7 +569,7 @@
</option>
</input>
<input type="optionlist" name="versus">
- <dynamic func="e_util_labels_get_filter_options"/>
+ <dynamic func="e_mail_labels_get_filter_options"/>
</input>
</part>
diff --git a/modules/Makefile.am b/modules/Makefile.am
new file mode 100644
index 0000000000..f792a4d9ee
--- /dev/null
+++ b/modules/Makefile.am
@@ -0,0 +1,11 @@
+if ENABLE_MONO
+MONO_DIR = plugin-mono
+endif
+
+if ENABLE_PYTHON
+PYTHON_DIR = plugin-python
+endif
+
+SUBDIRS = addressbook calendar mail plugin-lib $(MONO_DIR) $(PYTHON_DIR)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/component/Makefile.am b/modules/addressbook/Makefile.am
index 6e43acd60c..05b169841e 100644
--- a/addressbook/gui/component/Makefile.am
+++ b/modules/addressbook/Makefile.am
@@ -1,5 +1,5 @@
if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libevolution-mail-shared.la
+WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libevolution-mail.la
endif
AM_CPPFLAGS = \
@@ -8,12 +8,15 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/widgets \
-I$(top_srcdir)/shell \
-I$(top_builddir)/shell \
+ -I$(top_srcdir)/widgets/menus \
-I$(top_srcdir)/widgets/misc \
-I$(top_srcdir)/addressbook/util \
-I$(top_srcdir)/addressbook/gui/contact-editor \
-I$(top_srcdir)/addressbook/gui/contact-list-editor \
-I$(top_srcdir)/addressbook/gui/widgets \
-I$(top_srcdir)/a11y/addressbook \
+ -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
+ -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
-DEVOLUTION_UIDIR=\""$(evolutionuidir)"\" \
@@ -21,32 +24,43 @@ AM_CPPFLAGS = \
$(LDAP_CFLAGS) \
$(EVOLUTION_ADDRESSBOOK_CFLAGS)
-component_LTLIBRARIES = libevolution-addressbook.la
-
-libevolution_addressbook_la_SOURCES = \
- addressbook-component.c \
- addressbook-component.h \
- addressbook-config.c \
- addressbook-config.h \
- addressbook-migrate.c \
- addressbook-migrate.h \
- autocompletion-config.c \
- autocompletion-config.h \
- addressbook.c \
- addressbook.h \
- addressbook-view.c \
- addressbook-view.h \
- component-factory.c
-
-# $(top_builddir)/addressbook/printing/libecontactprint.la
+module_LTLIBRARIES = libevolution-module-addressbook.la
+
+libevolution_module_addressbook_la_SOURCES = \
+ evolution-module-addressbook.c \
+ addressbook-config.c \
+ addressbook-config.h \
+ autocompletion-config.c \
+ autocompletion-config.h \
+ eab-composer-util.c \
+ eab-composer-util.h \
+ e-book-config-hook.c \
+ e-book-config-hook.h \
+ e-book-shell-backend.c \
+ e-book-shell-backend.h \
+ e-book-shell-content.c \
+ e-book-shell-content.h \
+ e-book-shell-migrate.c \
+ e-book-shell-migrate.h \
+ e-book-shell-settings.c \
+ e-book-shell-settings.h \
+ e-book-shell-sidebar.c \
+ e-book-shell-sidebar.h \
+ e-book-shell-view.c \
+ e-book-shell-view.h \
+ e-book-shell-view-actions.c \
+ e-book-shell-view-actions.h \
+ e-book-shell-view-private.c \
+ e-book-shell-view-private.h
if ENABLE_SMIME
SMIME_LIB=$(top_builddir)/smime/gui/libevolution-smime.la
endif
-libevolution_addressbook_la_LIBADD = \
+libevolution_module_addressbook_la_LIBADD = \
$(SMIME_LIB) \
$(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/composer/libcomposer.la \
$(top_builddir)/addressbook/printing/libecontactprint.la \
$(top_builddir)/shell/libeshell.la \
$(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \
@@ -58,15 +72,13 @@ libevolution_addressbook_la_LIBADD = \
$(top_builddir)/widgets/table/libetable.la \
$(top_builddir)/widgets/text/libetext.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/widgets/misc/libefilterbar.la \
$(top_builddir)/widgets/menus/libmenus.la \
- $(top_builddir)/a11y/addressbook/libevolution-addressbook-a11y.la \
$(top_builddir)/addressbook/importers/libevolution-addressbook-importers.la \
- $(WIN32_BOOTSTRAP_LIBS) \
$(EVOLUTION_ADDRESSBOOK_LIBS) $(LDAP_LIBS)
-libevolution_addressbook_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+libevolution_module_addressbook_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED)
# GConf schemas
@@ -94,23 +106,14 @@ install-data-local:
fi
endif
-server_in_files = GNOME_Evolution_Addressbook.server.in.in
-server_DATA = $(server_in_files:.server.in.in=.server)
-@EVO_SERVER_RULE@
-@INTLTOOL_SERVER_RULE@
-
glade_DATA = \
ldap-config.glade
-BUILT_SOURCES = $(server_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
DISTCLEANFILES = $(schema_DATA)
EXTRA_DIST = \
$(glade_DATA) \
$(schema_in_files) \
- $(server_in_files) \
openldap-extract.h
dist-hook:
diff --git a/addressbook/gui/component/addressbook-config.c b/modules/addressbook/addressbook-config.c
index 248a9de9ea..901ee4353b 100644
--- a/addressbook/gui/component/addressbook-config.c
+++ b/modules/addressbook/addressbook-config.c
@@ -34,8 +34,6 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include <bonobo/bonobo-generic-factory.h>
-
#ifdef G_OS_WIN32
/* Include <windows.h> early and work around DATADIR lossage */
#define DATADIR crap_DATADIR
@@ -46,7 +44,6 @@
#include <glade/glade.h>
#include "addressbook.h"
-#include "addressbook-component.h"
#include "addressbook-config.h"
#include "e-util/e-error.h"
@@ -72,8 +69,6 @@
#define LDAPS_PORT_STRING "636"
#define GLADE_FILE_NAME "ldap-config.glade"
-#define CONFIG_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_ConfigControlFactory:" BASE_VERSION
-#define LDAP_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_LDAPStorage_ConfigControl:" BASE_VERSION
GtkWidget* supported_bases_create_table (gchar *name, gchar *string1, gchar *string2,
gint num1, gint num2);
@@ -96,7 +91,7 @@ struct _AddressbookSourceDialog {
GtkWidget *window;
- /* Source selection (druid only) */
+ /* Source selection (assistant only) */
ESourceList *source_list;
GSList *menu_source_groups;
diff --git a/addressbook/gui/component/addressbook-config.h b/modules/addressbook/addressbook-config.h
index 0cfcb95b56..26c1788e51 100644
--- a/addressbook/gui/component/addressbook-config.h
+++ b/modules/addressbook/addressbook-config.h
@@ -24,7 +24,8 @@
#ifndef __ADDRESSBOOK_CONFIG_H__
#define __ADDRESSBOOK_CONFIG_H__
-#include "evolution-config-control.h"
+#include <gtk/gtk.h>
+#include <libedataserver/e-source.h>
typedef enum {
ADDRESSBOOK_LDAP_AUTH_NONE,
diff --git a/addressbook/gui/component/apps_evolution_addressbook.schemas.in b/modules/addressbook/apps_evolution_addressbook.schemas.in
index 4a336409df..7ce3902c82 100644
--- a/addressbook/gui/component/apps_evolution_addressbook.schemas.in
+++ b/modules/addressbook/apps_evolution_addressbook.schemas.in
@@ -56,13 +56,47 @@
<!-- View state -->
<schema>
+ <key>/schemas/apps/evolution/addressbook/display/layout</key>
+ <applyto>/apps/evolution/addressbook/display/layout</applyto>
+ <owner>evolution-addressbook</owner>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short>Contact layout style</short>
+ <long>
+ The layout style determines where to place the preview pane
+ in relation to the contact list. "0" (Classic View) places
+ the preview pane below the contact list. "1" (Vertical View)
+ places the preview pane next to the contact list.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/addressbook/display/hpane_position</key>
+ <applyto>/apps/evolution/addressbook/display/hpane_position</applyto>
+ <owner>evolution-addressbook</owner>
+ <type>int</type>
+ <default>200</default>
+ <locale name="C">
+ <short>Contact preview pane position (horizontal)</short>
+ <long>
+ Position of the contact preview pane when oriented horizontally.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/evolution/addressbook/display/vpane_position</key>
<applyto>/apps/evolution/addressbook/display/vpane_position</applyto>
<owner>evolution-addressbook</owner>
<type>int</type>
+ <default>400</default>
<locale name="C">
- <short>Vertical pane position</short>
- <long>Position of the vertical pane, between the card and list views and the preview pane, in pixels.</long>
+ <short>Contact preview pane position (vertical)</short>
+ <long>
+ Position of the contact preview pane when oriented vertically.
+ </long>
</locale>
</schema>
diff --git a/modules/addressbook/autocompletion-config.c b/modules/addressbook/autocompletion-config.c
new file mode 100644
index 0000000000..ac6a7d1860
--- /dev/null
+++ b/modules/addressbook/autocompletion-config.c
@@ -0,0 +1,202 @@
+/*
+ * e-shell-config-autocompletion.h - Configuration page for addressbook autocompletion.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "autocompletion-config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserverui/e-source-selector.h>
+#include <libedataserverui/e-name-selector-entry.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/e-datetime-format.h"
+#include "widgets/misc/e-preferences-window.h"
+
+static void
+source_selection_changed_cb (ESourceSelector *source_selector)
+{
+ ESourceList *source_list;
+ GSList *selection;
+ GSList *l;
+ GSList *groups;
+
+ source_list = e_source_selector_get_source_list (source_selector);
+
+ /* first we clear all the completion flags from all sources */
+ for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) {
+ ESourceGroup *group = E_SOURCE_GROUP (groups->data);
+ GSList *sources;
+
+ for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) {
+ ESource *source = E_SOURCE (sources->data);
+
+ e_source_set_property (source, "completion", NULL);
+ }
+ }
+
+ /* then we loop over the selector's selection, setting the
+ property on those sources */
+ selection = e_source_selector_get_selection (source_selector);
+ for (l = selection; l; l = l->next) {
+ ESource *source = E_SOURCE (l->data);
+
+ e_source_set_property (source, "completion", "true");
+ }
+ e_source_selector_free_selection (selection);
+
+ /* XXX we should pop up a dialog if this fails */
+ e_source_list_sync (source_list, NULL);
+}
+
+static void
+initialize_selection (ESourceSelector *source_selector)
+{
+ ESourceList *source_list;
+ GSList *groups;
+
+ source_list = e_source_selector_get_source_list (source_selector);
+
+ for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) {
+ ESourceGroup *group = E_SOURCE_GROUP (groups->data);
+ GSList *sources;
+
+ for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) {
+ ESource *source = E_SOURCE (sources->data);
+ const gchar *completion;
+
+ completion = e_source_get_property (source, "completion");
+ if (completion && !g_ascii_strcasecmp (completion, "true"))
+ e_source_selector_select_source (source_selector, source);
+ }
+ }
+}
+
+static GtkWidget *
+add_section (GtkWidget *container,
+ const gchar *caption,
+ gboolean expand)
+{
+ GtkWidget *widget;
+ gchar *markup;
+
+ widget = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (container), widget, expand, expand, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ markup = g_markup_printf_escaped ("<b>%s</b>", caption);
+ widget = gtk_label_new (markup);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 12, 0);
+ gtk_box_pack_start (GTK_BOX (container), widget, expand, expand, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ return widget;
+}
+
+void
+autocompletion_config_init (EShell *shell)
+{
+ EShellSettings *shell_settings;
+ ESourceList *source_list;
+ GtkWidget *scrolled_window;
+ GtkWidget *source_selector;
+ GtkWidget *preferences_window;
+ GtkWidget *itembox;
+ GtkWidget *widget;
+ GtkWidget *vbox;
+
+ g_return_if_fail (E_IS_SHELL (shell));
+
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ source_list = e_source_list_new_for_gconf_default (
+ "/apps/evolution/addressbook/sources");
+
+ vbox = gtk_vbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+ gtk_widget_show (vbox);
+
+ itembox = add_section (vbox, _("Date/Time Format"), FALSE);
+
+ widget = gtk_table_new (1, 3, FALSE);
+ gtk_box_pack_start (GTK_BOX (itembox), widget, TRUE, TRUE, 0);
+ e_datetime_format_add_setup_widget (
+ widget, 0, "addressbook", "table",
+ DTFormatKindDateTime, _("Table column:"));
+ gtk_widget_show (widget);
+
+ itembox = add_section (vbox, _("Autocompletion"), TRUE);
+
+ widget = gtk_check_button_new_with_mnemonic (
+ _("Always _show address of the autocompleted contact"));
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "book-completion-show-address",
+ G_OBJECT (widget), "active");
+ gtk_box_pack_start (GTK_BOX (itembox), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+ gtk_widget_show (scrolled_window);
+
+ source_selector = e_source_selector_new (source_list);
+ g_signal_connect (
+ source_selector, "selection_changed",
+ G_CALLBACK (source_selection_changed_cb), NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), source_selector);
+ gtk_widget_show (source_selector);
+
+ gtk_box_pack_start (GTK_BOX (itembox), scrolled_window, TRUE, TRUE, 0);
+
+ initialize_selection (E_SOURCE_SELECTOR (source_selector));
+
+ preferences_window = e_shell_get_preferences_window (shell);
+
+ e_preferences_window_add_page (
+ E_PREFERENCES_WINDOW (preferences_window),
+ "contacts",
+ "preferences-autocompletion",
+ _("Contacts"),
+ vbox,
+ 200);
+}
diff --git a/addressbook/gui/component/autocompletion-config.h b/modules/addressbook/autocompletion-config.h
index 0690604bc7..5769bdce9d 100644
--- a/addressbook/gui/component/autocompletion-config.h
+++ b/modules/addressbook/autocompletion-config.h
@@ -25,8 +25,13 @@
#ifndef _AUTOCOMPLETION_CONFIG_H
#define _AUTOCOMPLETION_CONFIG_H
-#include "evolution-config-control.h"
+#include <glib.h>
+#include <shell/e-shell.h>
-EvolutionConfigControl* autocompletion_config_control_new (void);
+G_BEGIN_DECLS
+
+void autocompletion_config_init (EShell *shell);
+
+G_END_DECLS
#endif /* _AUTOCOMPLETION_CONFIG_H */
diff --git a/modules/addressbook/e-book-config-hook.c b/modules/addressbook/e-book-config-hook.c
new file mode 100644
index 0000000000..d8c03a5329
--- /dev/null
+++ b/modules/addressbook/e-book-config-hook.c
@@ -0,0 +1,67 @@
+/*
+ * e-book-config-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-config-hook.h"
+
+#include "e-util/e-config.h"
+#include "addressbook/gui/widgets/eab-config.h"
+
+static const EConfigHookTargetMask no_masks[] = {
+ { NULL }
+};
+
+static const EConfigHookTargetMap targets[] = {
+ { "source", EAB_CONFIG_TARGET_SOURCE, no_masks },
+ { NULL }
+};
+
+static void
+book_config_hook_class_init (EPluginHookClass *class)
+{
+ gint ii;
+
+ class->id = "org.gnome.evolution.addressbook.config:1.0";
+
+ for (ii = 0; targets[ii].type != NULL; ii++)
+ e_config_hook_class_add_target_map (
+ (EConfigHookClass *) class, &targets[ii]);
+}
+
+void
+e_book_config_hook_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EConfigHookClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) book_config_hook_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EConfigHook),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ NULL /* value_table */
+ };
+
+ g_type_module_register_type (
+ type_module, e_config_hook_get_type (),
+ "EBookConfigHook", &type_info, 0);
+}
diff --git a/mail/mail-crypto.h b/modules/addressbook/e-book-config-hook.h
index d4d5b7f504..a5d9e06457 100644
--- a/mail/mail-crypto.h
+++ b/modules/addressbook/e-book-config-hook.h
@@ -1,4 +1,6 @@
/*
+ * e-book-config-hook.h
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,21 +15,19 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef MAIL_CRYPTO_H
-#define MAIL_CRYPTO_H
+#ifndef E_BOOK_CONFIG_HOOK_H
+#define E_BOOK_CONFIG_HOOK_H
+
+#include <glib-object.h>
G_BEGIN_DECLS
-/* PGP/MIME convenience wrappers */
-CamelCipherContext *mail_crypto_get_pgp_cipher_context(EAccount *account);
+void e_book_config_hook_register_type (GTypeModule *type_module);
G_END_DECLS
-#endif /* ! MAIL_CRYPTO_H */
+#endif /* E_BOOK_CONFIG_HOOK_H */
diff --git a/modules/addressbook/e-book-shell-backend.c b/modules/addressbook/e-book-shell-backend.c
new file mode 100644
index 0000000000..f96cb0dd22
--- /dev/null
+++ b/modules/addressbook/e-book-shell-backend.c
@@ -0,0 +1,591 @@
+/*
+ * e-book-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-shell-backend.h"
+
+#include <config.h>
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libebook/e-book.h>
+#include <libedataserver/e-url.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+
+#include "shell/e-shell.h"
+#include "shell/e-shell-window.h"
+
+#include "e-util/e-import.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
+#include "addressbook/gui/contact-editor/e-contact-editor.h"
+#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
+#include "addressbook/importers/evolution-addressbook-importers.h"
+
+#include "addressbook-config.h"
+#include "autocompletion-config.h"
+
+#include "e-book-shell-migrate.h"
+#include "e-book-shell-settings.h"
+#include "e-book-shell-view.h"
+
+#ifdef ENABLE_SMIME
+#include "smime/gui/component.h"
+#include "smime/gui/certificate-manager.h"
+#endif
+
+#define E_BOOK_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_BOOK_SHELL_BACKEND, EBookShellBackendPrivate))
+
+#define LDAP_BASE_URI "ldap://"
+#define PERSONAL_RELATIVE_URI "system"
+
+struct _EBookShellBackendPrivate {
+ ESourceList *source_list;
+};
+
+enum {
+ PROP_0,
+ PROP_SOURCE_LIST
+};
+
+static gpointer parent_class;
+static GType book_shell_backend_type;
+
+static void
+book_shell_backend_ensure_sources (EShellBackend *shell_backend)
+{
+ /* XXX This is basically the same algorithm across all backends.
+ * Maybe we could somehow integrate this into EShellBackend? */
+
+ EBookShellBackendPrivate *priv;
+ ESourceGroup *on_this_computer;
+ ESourceGroup *on_ldap_servers;
+ ESource *personal;
+ GSList *groups, *iter;
+ const gchar *data_dir;
+ const gchar *name;
+ gchar *base_uri;
+ gchar *filename;
+
+ on_this_computer = NULL;
+ on_ldap_servers = NULL;
+ personal = NULL;
+
+ priv = E_BOOK_SHELL_BACKEND_GET_PRIVATE (shell_backend);
+
+ if (!e_book_get_addressbooks (&priv->source_list, NULL)) {
+ g_warning ("Could not get addressbook sources from GConf!");
+ return;
+ }
+
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ filename = g_build_filename (data_dir, "local", NULL);
+ base_uri = g_filename_to_uri (filename, NULL, NULL);
+ g_free (filename);
+
+ groups = e_source_list_peek_groups (priv->source_list);
+ for (iter = groups; iter != NULL; iter = iter->next) {
+ ESourceGroup *source_group = iter->data;
+ const gchar *group_base_uri;
+
+ group_base_uri = e_source_group_peek_base_uri (source_group);
+
+ /* Compare only "file://" part. If the user's home
+ * changes, we do not want to create another group. */
+ if (on_this_computer == NULL &&
+ strncmp (base_uri, group_base_uri, 7) == 0)
+ on_this_computer = source_group;
+
+ else if (on_ldap_servers == NULL &&
+ strcmp (LDAP_BASE_URI, group_base_uri) == 0)
+ on_ldap_servers = source_group;
+ }
+
+ name = _("On This Computer");
+
+ if (on_this_computer != NULL) {
+ GSList *sources;
+ const gchar *group_base_uri;
+
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (on_this_computer, name);
+
+ sources = e_source_group_peek_sources (on_this_computer);
+ group_base_uri = e_source_group_peek_base_uri (on_this_computer);
+
+ /* Make sure this group includes a "Personal" source. */
+ for (iter = sources; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+
+ if (strcmp (PERSONAL_RELATIVE_URI, relative_uri) != 0)
+ continue;
+
+ personal = source;
+ break;
+ }
+
+ /* Make sure we have the correct base URI. This can
+ * change when the user's home directory changes. */
+ if (strcmp (base_uri, group_base_uri) != 0) {
+ e_source_group_set_base_uri (
+ on_this_computer, base_uri);
+
+ /* XXX We shouldn't need this sync call here as
+ * set_base_uri() results in synching to GConf,
+ * but that happens in an idle loop and too late
+ * to prevent the user from seeing a "Cannot
+ * Open ... because of invalid URI" error. */
+ e_source_list_sync (priv->source_list, NULL);
+ }
+
+ } else {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, base_uri);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ }
+
+ name = _("Personal");
+
+ if (personal == NULL) {
+ ESource *source;
+
+ /* Create the default Personal address book. */
+ source = e_source_new (name, PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (on_this_computer, source, -1);
+ e_source_set_property (source, "completion", "true");
+ g_object_unref (source);
+ } else {
+ /* Force the source name to the current locale. */
+ e_source_set_name (personal, name);
+ }
+
+ name = _("On LDAP Servers");
+
+ if (on_ldap_servers == NULL) {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, LDAP_BASE_URI);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ } else {
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (on_ldap_servers, name);
+ }
+
+ g_free (base_uri);
+}
+
+static void
+book_shell_backend_init_importers (void)
+{
+ EImportClass *import_class;
+ EImportImporter *importer;
+
+ import_class = g_type_class_ref (e_import_get_type ());
+
+ importer = evolution_ldif_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+
+ importer = evolution_vcard_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+
+ importer = evolution_csv_outlook_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+
+ importer = evolution_csv_mozilla_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+
+ importer = evolution_csv_evolution_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+}
+
+static void
+book_shell_backend_new_contact_cb (EBook *book,
+ EBookStatus status,
+ gpointer user_data)
+{
+ EShell *shell;
+ EContact *contact;
+ EABEditor *editor;
+
+ /* XXX Handle errors better. */
+ if (status != E_BOOK_ERROR_OK)
+ return;
+
+ contact = e_contact_new ();
+ shell = E_SHELL (user_data);
+
+ editor = e_contact_editor_new (
+ shell, book, contact, TRUE, TRUE);
+
+ eab_editor_show (editor);
+
+ g_object_unref (contact);
+ g_object_unref (book);
+}
+
+static void
+book_shell_backend_new_contact_list_cb (EBook *book,
+ EBookStatus status,
+ gpointer user_data)
+{
+ EShell *shell;
+ EContact *contact;
+ EABEditor *editor;
+
+ /* XXX Handle errors better. */
+ if (status != E_BOOK_ERROR_OK)
+ return;
+
+ contact = e_contact_new ();
+ shell = E_SHELL (user_data);
+
+ editor = e_contact_list_editor_new (
+ shell, book, contact, TRUE, TRUE);
+
+ eab_editor_show (editor);
+
+ g_object_unref (contact);
+ g_object_unref (book);
+}
+
+static void
+action_contact_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ EBook *book = NULL;
+ GConfClient *client;
+ ESourceList *source_list;
+ const gchar *action_name;
+ const gchar *key;
+ gchar *uid;
+
+ /* This callback is used for both contacts and contact lists. */
+
+ if (!e_book_get_addressbooks (&source_list, NULL)) {
+ g_warning ("Could not get addressbook sources from GConf!");
+ return;
+ }
+
+ shell = e_shell_window_get_shell (shell_window);
+ client = e_shell_get_gconf_client (shell);
+ action_name = gtk_action_get_name (action);
+
+ key = "/apps/evolution/addressbook/display/primary_addressbook";
+ uid = gconf_client_get_string (client, key, NULL);
+
+ if (uid != NULL) {
+ ESource *source;
+
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ if (source != NULL)
+ book = e_book_new (source, NULL);
+ g_free (uid);
+ }
+
+ if (book == NULL)
+ book = e_book_new_default_addressbook (NULL);
+
+ if (strcmp (action_name, "contact-new") == 0)
+ e_book_async_open (
+ book, FALSE,
+ book_shell_backend_new_contact_cb, shell);
+
+ if (strcmp (action_name, "contact-list-new") == 0)
+ e_book_async_open (
+ book, FALSE,
+ book_shell_backend_new_contact_list_cb, shell);
+}
+
+static void
+action_address_book_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ addressbook_config_create_new_source (NULL);
+}
+
+static GtkActionEntry item_entries[] = {
+
+ { "contact-new",
+ "contact-new",
+ NC_("New", "_Contact"),
+ "<Shift><Control>c",
+ N_("Create a new contact"),
+ G_CALLBACK (action_contact_new_cb) },
+
+ { "contact-new-list",
+ "stock_contact-list",
+ N_("Contact _List"),
+ "<Shift><Control>l",
+ N_("Create a new contact list"),
+ G_CALLBACK (action_contact_new_cb) }
+};
+
+static GtkActionEntry source_entries[] = {
+
+ { "address-book-new",
+ "address-book-new",
+ NC_("New", "Address _Book"),
+ NULL,
+ N_("Create a new address book"),
+ G_CALLBACK (action_address_book_new_cb) }
+};
+
+static gboolean
+book_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
+ const gchar *uri)
+{
+ EUri *euri;
+ const gchar *cp;
+ gchar *source_uid = NULL;
+ gchar *contact_uid = NULL;
+
+ if (!g_str_has_prefix (uri, "contacts:"))
+ return FALSE;
+
+ euri = e_uri_new (uri);
+ cp = euri->query;
+
+ if (cp == NULL) {
+ e_uri_free (euri);
+ return FALSE;
+ }
+
+ while (*cp != '\0') {
+ gchar *header;
+ gchar *content;
+ gsize length;
+ gsize content_length;
+
+ length = strcspn (cp, "=&");
+
+ /* If it's malformed, give up. */
+ if (cp[length] != '=')
+ break;
+
+ header = (gchar *) cp;
+ header[length] = '\0';
+ cp += length + 1;
+
+ content_length = strcspn (cp, "&");
+ content = g_strndup (cp, content_length);
+
+ if (g_ascii_strcasecmp (header, "source-uid") == 0)
+ source_uid = g_strdup (content);
+
+ if (g_ascii_strcasecmp (header, "contact-uid") == 0)
+ contact_uid = g_strdup (content);
+
+ g_free (content);
+
+ cp += content_length;
+ if (*cp == '&') {
+ cp++;
+ if (strcmp (cp, "amp;"))
+ cp += 4;
+ }
+ }
+
+ /* FIXME */
+ /*addressbook_view_edit_contact (view, source_uid, contact_uid);*/
+
+ g_free (source_uid);
+ g_free (contact_uid);
+
+ e_uri_free (euri);
+
+ return TRUE;
+}
+
+static void
+book_shell_backend_window_created_cb (EShellBackend *shell_backend,
+ GtkWindow *window)
+{
+ const gchar *backend_name;
+
+ if (!E_IS_SHELL_WINDOW (window))
+ return;
+
+ backend_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ e_shell_window_register_new_item_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ item_entries, G_N_ELEMENTS (item_entries));
+
+ e_shell_window_register_new_source_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ source_entries, G_N_ELEMENTS (source_entries));
+}
+
+static void
+book_shell_backend_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SOURCE_LIST:
+ g_value_set_object (
+ value,
+ e_book_shell_backend_get_source_list (
+ E_BOOK_SHELL_BACKEND (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+book_shell_backend_dispose (GObject *object)
+{
+ EBookShellBackendPrivate *priv;
+
+ priv = E_BOOK_SHELL_BACKEND_GET_PRIVATE (object);
+
+ if (priv->source_list != NULL) {
+ g_object_unref (priv->source_list);
+ priv->source_list = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+book_shell_backend_constructed (GObject *object)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell_backend = E_SHELL_BACKEND (object);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ /* XXX Why is this here? Address books aren't the only
+ * things that use S/MIME. Maybe put it in EShell? */
+#ifdef ENABLE_SMIME
+ smime_component_init ();
+ certificate_manager_config_init (shell);
+#endif
+
+ book_shell_backend_init_importers ();
+ book_shell_backend_ensure_sources (shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "handle-uri",
+ G_CALLBACK (book_shell_backend_handle_uri_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "window-created",
+ G_CALLBACK (book_shell_backend_window_created_cb),
+ shell_backend);
+
+ /* Initialize settings before initializing preferences,
+ * since the preferences bind to the shell settings. */
+ e_book_shell_backend_init_settings (shell);
+ autocompletion_config_init (shell);
+}
+
+static void
+book_shell_backend_class_init (EBookShellBackendClass *class)
+{
+ GObjectClass *object_class;
+ EShellBackendClass *shell_backend_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EBookShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = book_shell_backend_get_property;
+ object_class->dispose = book_shell_backend_dispose;
+ object_class->constructed = book_shell_backend_constructed;
+
+ shell_backend_class = E_SHELL_BACKEND_CLASS (class);
+ shell_backend_class->shell_view_type = E_TYPE_BOOK_SHELL_VIEW;
+ shell_backend_class->name = "addressbook";
+ shell_backend_class->aliases = "contacts";
+ shell_backend_class->schemes = "";
+ shell_backend_class->sort_order = 300;
+ shell_backend_class->start = NULL;
+ shell_backend_class->migrate = e_book_shell_backend_migrate;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE_LIST,
+ g_param_spec_object (
+ "source-list",
+ _("Source List"),
+ _("The registry of address books"),
+ E_TYPE_SOURCE_LIST,
+ G_PARAM_READABLE));
+}
+
+static void
+book_shell_backend_init (EBookShellBackend *book_shell_backend)
+{
+ book_shell_backend->priv =
+ E_BOOK_SHELL_BACKEND_GET_PRIVATE (book_shell_backend);
+}
+
+GType
+e_book_shell_backend_get_type (void)
+{
+ return book_shell_backend_type;
+}
+
+void
+e_book_shell_backend_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EBookShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) book_shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EBookShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) book_shell_backend_init,
+ NULL /* value_table */
+ };
+
+ book_shell_backend_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_BACKEND,
+ "EBookShellBackend", &type_info, 0);
+}
+
+ESourceList *
+e_book_shell_backend_get_source_list (EBookShellBackend *book_shell_backend)
+{
+ g_return_val_if_fail (
+ E_IS_BOOK_SHELL_BACKEND (book_shell_backend), NULL);
+
+ return book_shell_backend->priv->source_list;
+}
diff --git a/modules/addressbook/e-book-shell-backend.h b/modules/addressbook/e-book-shell-backend.h
new file mode 100644
index 0000000000..c61e43b814
--- /dev/null
+++ b/modules/addressbook/e-book-shell-backend.h
@@ -0,0 +1,70 @@
+/*
+ * e-book-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_BOOK_SHELL_BACKEND_H
+#define E_BOOK_SHELL_BACKEND_H
+
+#include <shell/e-shell-backend.h>
+#include <libedataserver/e-source-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_SHELL_BACKEND \
+ (e_book_shell_backend_get_type ())
+#define E_BOOK_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_BOOK_SHELL_BACKEND, EBookShellBackend))
+#define E_BOOK_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_BOOK_SHELL_BACKEND, EBookShellBackendClass))
+#define E_IS_BOOK_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_BOOK_SHELL_BACKEND))
+#define E_IS_BOOK_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_BOOK_SHELL_BACKEND))
+#define E_BOOK_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_BOOK_SHELL_BACKEND, EBookShellBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookShellBackend EBookShellBackend;
+typedef struct _EBookShellBackendClass EBookShellBackendClass;
+typedef struct _EBookShellBackendPrivate EBookShellBackendPrivate;
+
+struct _EBookShellBackend {
+ EShellBackend parent;
+ EBookShellBackendPrivate *priv;
+};
+
+struct _EBookShellBackendClass {
+ EShellBackendClass parent_class;
+};
+
+GType e_book_shell_backend_get_type (void);
+void e_book_shell_backend_register_type
+ (GTypeModule *type_module);
+ESourceList * e_book_shell_backend_get_source_list
+ (EBookShellBackend *book_shell_backend);
+
+G_END_DECLS
+
+#endif /* E_BOOK_SHELL_BACKEND_H */
diff --git a/modules/addressbook/e-book-shell-content.c b/modules/addressbook/e-book-shell-content.c
new file mode 100644
index 0000000000..f138da3d00
--- /dev/null
+++ b/modules/addressbook/e-book-shell-content.c
@@ -0,0 +1,541 @@
+/*
+ * e-book-shell-content.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-shell-content.h"
+
+#include <glib/gi18n.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/gconf-bridge.h"
+#include "widgets/misc/e-paned.h"
+
+#define E_BOOK_SHELL_CONTENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_BOOK_SHELL_CONTENT, EBookShellContentPrivate))
+
+struct _EBookShellContentPrivate {
+ GtkWidget *paned;
+ GtkWidget *notebook;
+ GtkWidget *preview;
+
+ GtkOrientation orientation;
+
+ guint preview_visible : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_CURRENT_VIEW,
+ PROP_ORIENTATION,
+ PROP_PREVIEW_CONTACT,
+ PROP_PREVIEW_VISIBLE
+};
+
+static gpointer parent_class;
+static GType book_shell_content_type;
+
+static void
+book_shell_content_send_message_cb (EBookShellContent *book_shell_content,
+ EDestination *destination,
+ EABContactDisplay *display)
+{
+ GList node = { destination, NULL, NULL };
+
+ eab_send_as_to (&node);
+}
+
+static GtkOrientation
+book_shell_content_get_orientation (EBookShellContent *book_shell_content)
+{
+ return book_shell_content->priv->orientation;
+}
+
+static void
+book_shell_content_set_orientation (EBookShellContent *book_shell_content,
+ GtkOrientation orientation)
+{
+ book_shell_content->priv->orientation = orientation;
+
+ g_object_notify (G_OBJECT (book_shell_content), "orientation");
+}
+
+static void
+book_shell_content_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ e_book_shell_content_set_current_view (
+ E_BOOK_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_ORIENTATION:
+ book_shell_content_set_orientation (
+ E_BOOK_SHELL_CONTENT (object),
+ g_value_get_enum (value));
+ return;
+
+ case PROP_PREVIEW_CONTACT:
+ e_book_shell_content_set_preview_contact (
+ E_BOOK_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_PREVIEW_VISIBLE:
+ e_book_shell_content_set_preview_visible (
+ E_BOOK_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+book_shell_content_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ g_value_set_object (
+ value,
+ e_book_shell_content_get_current_view (
+ E_BOOK_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_ORIENTATION:
+ g_value_set_enum (
+ value,
+ book_shell_content_get_orientation (
+ E_BOOK_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_PREVIEW_CONTACT:
+ g_value_set_object (
+ value,
+ e_book_shell_content_get_preview_contact (
+ E_BOOK_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_PREVIEW_VISIBLE:
+ g_value_set_boolean (
+ value,
+ e_book_shell_content_get_preview_visible (
+ E_BOOK_SHELL_CONTENT (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+book_shell_content_dispose (GObject *object)
+{
+ EBookShellContentPrivate *priv;
+
+ priv = E_BOOK_SHELL_CONTENT_GET_PRIVATE (object);
+
+ if (priv->paned != NULL) {
+ g_object_unref (priv->paned);
+ priv->paned = NULL;
+ }
+
+ if (priv->notebook != NULL) {
+ g_object_unref (priv->notebook);
+ priv->notebook = NULL;
+ }
+
+ if (priv->preview != NULL) {
+ g_object_unref (priv->preview);
+ priv->preview = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+book_shell_content_constructed (GObject *object)
+{
+ EBookShellContentPrivate *priv;
+ GConfBridge *bridge;
+ GtkWidget *container;
+ GtkWidget *widget;
+ const gchar *key;
+
+ priv = E_BOOK_SHELL_CONTENT_GET_PRIVATE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ container = GTK_WIDGET (object);
+
+ widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->paned = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (object), "orientation",
+ G_OBJECT (widget), "orientation");
+
+ container = widget;
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
+ priv->notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (object), "preview-visible",
+ G_OBJECT (widget), "visible");
+
+ container = widget;
+
+ widget = eab_contact_display_new ();
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (widget),
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->preview = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ priv->preview, "send-message",
+ G_CALLBACK (book_shell_content_send_message_cb), object);
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/addressbook/display/hpane_position";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "hposition");
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/addressbook/display/vpane_position";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "vposition");
+}
+
+static guint32
+book_shell_content_check_state (EShellContent *shell_content)
+{
+ EBookShellContent *book_shell_content;
+ ESelectionModel *selection_model;
+ EAddressbookModel *model;
+ EAddressbookView *view;
+ guint32 state = 0;
+ gint n_contacts;
+ gint n_selected;
+
+ book_shell_content = E_BOOK_SHELL_CONTENT (shell_content);
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ model = e_addressbook_view_get_model (view);
+
+ selection_model = e_addressbook_view_get_selection_model (view);
+ n_contacts = (selection_model != NULL) ?
+ e_selection_model_row_count (selection_model) : 0;
+ n_selected = (selection_model != NULL) ?
+ e_selection_model_selected_count (selection_model) : 0;
+
+ /* FIXME Finish the rest of the flags. */
+ if (n_selected == 1)
+ state |= E_BOOK_SHELL_CONTENT_SELECTION_SINGLE;
+ if (n_selected > 1)
+ state |= E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE;
+ if (e_addressbook_model_can_stop (model))
+ state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY;
+ if (e_addressbook_model_get_editable (model))
+ state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE;
+ if (n_contacts == 0)
+ state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY;
+
+ return state;
+}
+
+static void
+book_shell_content_class_init (EBookShellContentClass *class)
+{
+ GObjectClass *object_class;
+ EShellContentClass *shell_content_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EBookShellContentPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = book_shell_content_set_property;
+ object_class->get_property = book_shell_content_get_property;
+ object_class->dispose = book_shell_content_dispose;
+ object_class->constructed = book_shell_content_constructed;
+
+ shell_content_class = E_SHELL_CONTENT_CLASS (class);
+ shell_content_class->check_state = book_shell_content_check_state;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CURRENT_VIEW,
+ g_param_spec_object (
+ "current-view",
+ _("Current View"),
+ _("The currently selected address book view"),
+ E_TYPE_ADDRESSBOOK_VIEW,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PREVIEW_CONTACT,
+ g_param_spec_object (
+ "preview-contact",
+ _("Previewed Contact"),
+ _("The contact being shown in the preview pane"),
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PREVIEW_VISIBLE,
+ g_param_spec_boolean (
+ "preview-visible",
+ _("Preview is Visible"),
+ _("Whether the preview pane is visible"),
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_override_property (
+ object_class, PROP_ORIENTATION, "orientation");
+}
+
+static void
+book_shell_content_init (EBookShellContent *book_shell_content)
+{
+ book_shell_content->priv =
+ E_BOOK_SHELL_CONTENT_GET_PRIVATE (book_shell_content);
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_book_shell_content_get_type (void)
+{
+ return book_shell_content_type;
+}
+
+void
+e_book_shell_content_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EBookShellContentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) book_shell_content_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EBookShellContent),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) book_shell_content_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo orientable_info = {
+ (GInterfaceInitFunc) NULL,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ book_shell_content_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_CONTENT,
+ "EBookShellContent", &type_info, 0);
+
+ g_type_module_add_interface (
+ type_module, book_shell_content_type,
+ GTK_TYPE_ORIENTABLE, &orientable_info);
+}
+
+GtkWidget *
+e_book_shell_content_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_BOOK_SHELL_CONTENT,
+ "shell-view", shell_view, NULL);
+}
+
+void
+e_book_shell_content_insert_view (EBookShellContent *book_shell_content,
+ EAddressbookView *addressbook_view)
+{
+ GtkNotebook *notebook;
+ GtkWidget *child;
+
+ g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content));
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (addressbook_view));
+
+ notebook = GTK_NOTEBOOK (book_shell_content->priv->notebook);
+ child = GTK_WIDGET (addressbook_view);
+ gtk_notebook_append_page (notebook, child, NULL);
+}
+
+void
+e_book_shell_content_remove_view (EBookShellContent *book_shell_content,
+ EAddressbookView *addressbook_view)
+{
+ GtkNotebook *notebook;
+ GtkWidget *child;
+ gint page_num;
+
+ g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content));
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (addressbook_view));
+
+ notebook = GTK_NOTEBOOK (book_shell_content->priv->notebook);
+ child = GTK_WIDGET (addressbook_view);
+ page_num = gtk_notebook_page_num (notebook, child);
+ g_return_if_fail (page_num >= 0);
+
+ gtk_notebook_remove_page (notebook, page_num);
+}
+
+EAddressbookView *
+e_book_shell_content_get_current_view (EBookShellContent *book_shell_content)
+{
+ GtkNotebook *notebook;
+ GtkWidget *widget;
+ gint page_num;
+
+ g_return_val_if_fail (
+ E_IS_BOOK_SHELL_CONTENT (book_shell_content), NULL);
+
+ notebook = GTK_NOTEBOOK (book_shell_content->priv->notebook);
+ page_num = gtk_notebook_get_current_page (notebook);
+ widget = gtk_notebook_get_nth_page (notebook, page_num);
+ g_return_val_if_fail (widget != NULL, NULL);
+
+ return E_ADDRESSBOOK_VIEW (widget);
+}
+
+void
+e_book_shell_content_set_current_view (EBookShellContent *book_shell_content,
+ EAddressbookView *addressbook_view)
+{
+ GtkNotebook *notebook;
+ GtkWidget *child;
+ gint page_num;
+
+ g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content));
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (addressbook_view));
+
+ notebook = GTK_NOTEBOOK (book_shell_content->priv->notebook);
+ child = GTK_WIDGET (addressbook_view);
+ page_num = gtk_notebook_page_num (notebook, child);
+ g_return_if_fail (page_num >= 0);
+
+ gtk_notebook_set_current_page (notebook, page_num);
+ g_object_notify (G_OBJECT (book_shell_content), "current-view");
+}
+
+EContact *
+e_book_shell_content_get_preview_contact (EBookShellContent *book_shell_content)
+{
+ EABContactDisplay *display;
+
+ g_return_val_if_fail (
+ E_IS_BOOK_SHELL_CONTENT (book_shell_content), NULL);
+
+ display = EAB_CONTACT_DISPLAY (book_shell_content->priv->preview);
+
+ return eab_contact_display_get_contact (display);
+}
+
+void
+e_book_shell_content_set_preview_contact (EBookShellContent *book_shell_content,
+ EContact *preview_contact)
+{
+ EABContactDisplay *display;
+
+ g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content));
+
+ display = EAB_CONTACT_DISPLAY (book_shell_content->priv->preview);
+
+ eab_contact_display_set_contact (display, preview_contact);
+ g_object_notify (G_OBJECT (book_shell_content), "preview-contact");
+}
+
+gboolean
+e_book_shell_content_get_preview_visible (EBookShellContent *book_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_BOOK_SHELL_CONTENT (book_shell_content), FALSE);
+
+ return book_shell_content->priv->preview_visible;
+}
+
+void
+e_book_shell_content_set_preview_visible (EBookShellContent *book_shell_content,
+ gboolean preview_visible)
+{
+ g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content));
+
+ book_shell_content->priv->preview_visible = preview_visible;
+
+ g_object_notify (G_OBJECT (book_shell_content), "preview-visible");
+}
+
+void
+e_book_shell_content_clipboard_copy (EBookShellContent *book_shell_content)
+{
+ EAddressbookView *addressbook_view;
+ GtkHTML *html;
+ gchar *selection;
+
+ g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content));
+
+ html = GTK_HTML (book_shell_content->priv->preview);
+ addressbook_view =
+ e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (addressbook_view != NULL);
+
+ if (!GTK_WIDGET_HAS_FOCUS (html)) {
+ e_addressbook_view_copy (addressbook_view);
+ return;
+ }
+
+ selection = gtk_html_get_selection_html (html, NULL);
+ if (selection != NULL)
+ gtk_html_copy (html);
+ g_free (selection);
+}
diff --git a/modules/addressbook/e-book-shell-content.h b/modules/addressbook/e-book-shell-content.h
new file mode 100644
index 0000000000..da78c01274
--- /dev/null
+++ b/modules/addressbook/e-book-shell-content.h
@@ -0,0 +1,110 @@
+/*
+ * e-book-shell-content.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_BOOK_SHELL_CONTENT_H
+#define E_BOOK_SHELL_CONTENT_H
+
+#include <libebook/e-contact.h>
+
+#include "shell/e-shell-content.h"
+#include "shell/e-shell-view.h"
+
+#include "addressbook/gui/widgets/e-addressbook-view.h"
+#include "eab-composer-util.h"
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_SHELL_CONTENT \
+ (e_book_shell_content_get_type ())
+#define E_BOOK_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_BOOK_SHELL_CONTENT, EBookShellContent))
+#define E_BOOK_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_BOOK_SHELL_CONTENT, EBookShellContentClass))
+#define E_IS_BOOK_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_BOOK_SHELL_CONTENT))
+#define E_IS_BOOK_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_BOOK_SHELL_CONTENT))
+#define E_BOOK_SHELL_CONTENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_BOOK_SHELL_CONTENT, EBookShellContentClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookShellContent EBookShellContent;
+typedef struct _EBookShellContentClass EBookShellContentClass;
+typedef struct _EBookShellContentPrivate EBookShellContentPrivate;
+
+enum {
+ E_BOOK_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0,
+ E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1,
+ E_BOOK_SHELL_CONTENT_SELECTION_HAS_EMAIL = 1 << 2,
+ E_BOOK_SHELL_CONTENT_SELECTION_IS_CONTACT_LIST = 1 << 3,
+ E_BOOK_SHELL_CONTENT_SELECTION_HAS_HTTP_URI = 1 << 4,
+ E_BOOK_SHELL_CONTENT_SELECTION_HAS_MAILTO_URI = 1 << 5,
+ E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY = 1 << 6,
+ E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE = 1 << 7,
+ E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY = 1 << 8
+};
+
+struct _EBookShellContent {
+ EShellContent parent;
+ EBookShellContentPrivate *priv;
+};
+
+struct _EBookShellContentClass {
+ EShellContentClass parent_class;
+};
+
+GType e_book_shell_content_get_type (void);
+void e_book_shell_content_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_book_shell_content_new(EShellView *shell_view);
+void e_book_shell_content_insert_view
+ (EBookShellContent *book_shell_content,
+ EAddressbookView *addressbook_view);
+void e_book_shell_content_remove_view
+ (EBookShellContent *book_shell_content,
+ EAddressbookView *addressbook_view);
+EAddressbookView *
+ e_book_shell_content_get_current_view
+ (EBookShellContent *book_shell_content);
+void e_book_shell_content_set_current_view
+ (EBookShellContent *book_shell_content,
+ EAddressbookView *addressbook_view);
+EContact * e_book_shell_content_get_preview_contact
+ (EBookShellContent *book_shell_content);
+void e_book_shell_content_set_preview_contact
+ (EBookShellContent *book_shell_content,
+ EContact *preview_contact);
+gboolean e_book_shell_content_get_preview_visible
+ (EBookShellContent *book_shell_content);
+void e_book_shell_content_set_preview_visible
+ (EBookShellContent *book_shell_content,
+ gboolean preview_visible);
+void e_book_shell_content_clipboard_copy
+ (EBookShellContent *book_shell_content);
+
+G_END_DECLS
+
+#endif /* E_BOOK_SHELL_CONTENT_H */
diff --git a/addressbook/gui/component/addressbook-migrate.c b/modules/addressbook/e-book-shell-migrate.c
index 424a39c730..c237f40d94 100644
--- a/addressbook/gui/component/addressbook-migrate.c
+++ b/modules/addressbook/e-book-shell-migrate.c
@@ -1,4 +1,6 @@
/*
+ * e-book-shell-backend-migrate.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -45,7 +47,7 @@
#include "e-util/e-xml-utils.h"
#include "e-util/e-folder-map.h"
-#include "addressbook-migrate.h"
+#include "e-book-shell-migrate.h"
/*#define SLOW_MIGRATION*/
@@ -57,7 +59,7 @@ typedef struct {
ESourceList *source_list;
- AddressbookComponent *component;
+ const gchar *data_dir;
GtkWidget *window;
GtkWidget *label;
@@ -449,14 +451,12 @@ create_groups (MigrationContext *context,
GSList *groups;
ESourceGroup *group;
gchar *base_uri, *base_uri_proto;
- const gchar *base_dir;
*on_this_computer = NULL;
*on_ldap_servers = NULL;
*personal_source = NULL;
- base_dir = addressbook_component_peek_base_directory (context->component);
- base_uri = g_build_filename (base_dir, "local", NULL);
+ base_uri = g_build_filename (context->data_dir, "local", NULL);
base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
@@ -743,12 +743,17 @@ get_source_by_name (ESourceList *source_list, const gchar *name)
static gboolean
migrate_completion_folders (MigrationContext *context)
{
- gchar *uris_xml = gconf_client_get_string (addressbook_component_peek_gconf_client (context->component),
- "/apps/evolution/addressbook/completion/uris",
- NULL);
+ GConfClient *client;
+ const gchar *key;
+ gchar *uris_xml;
printf ("trying to migrate completion folders\n");
+ client = gconf_client_get_default ();
+ key = "/apps/evolution/addressbook/completion/uris";
+ uris_xml = gconf_client_get_string (client, key, NULL);
+ g_object_unref (client);
+
if (uris_xml) {
xmlDoc *doc = xmlParseMemory (uris_xml, strlen (uris_xml));
xmlNode *root;
@@ -1075,17 +1080,20 @@ migrate_pilot_data (const gchar *old_path, const gchar *new_path)
g_dir_close (dir);
}
-static MigrationContext*
-migration_context_new (AddressbookComponent *component)
+static MigrationContext *
+migration_context_new (const gchar *data_dir)
{
MigrationContext *context = g_new (MigrationContext, 1);
/* set up the mapping from old uris to new uids */
- context->folder_uid_map = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free);
+ context->folder_uid_map = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
e_book_get_addressbooks (&context->source_list, NULL);
- context->component = component;
+ context->data_dir = data_dir;
return context;
}
@@ -1102,16 +1110,24 @@ migration_context_free (MigrationContext *context)
g_free (context);
}
-gint
-addressbook_migrate (AddressbookComponent *component, gint major, gint minor, gint revision, GError **err)
+gboolean
+e_book_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
{
ESourceGroup *on_this_computer;
ESourceGroup *on_ldap_servers;
ESource *personal_source;
- MigrationContext *context = migration_context_new (component);
+ MigrationContext *context;
gboolean need_dialog = FALSE;
+ const gchar *data_dir;
+
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), FALSE);
- printf ("addressbook_migrate (%d.%d.%d)\n", major, minor, revision);
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ context = migration_context_new (data_dir);
/* we call this unconditionally now - create_groups either
creates the groups/sources or it finds the necessary
@@ -1122,7 +1138,7 @@ addressbook_migrate (AddressbookComponent *component, gint major, gint minor, gi
if (major == 1
/* we only need the most recent upgrade point here.
further decomposition will happen below. */
- && (minor < 5 || (minor == 5 && revision <= 10)))
+ && (minor < 5 || (minor == 5 && micro <= 10)))
need_dialog = TRUE;
if (need_dialog)
@@ -1130,7 +1146,7 @@ addressbook_migrate (AddressbookComponent *component, gint major, gint minor, gi
if (major == 1) {
- if (minor < 5 || (minor == 5 && revision <= 2)) {
+ if (minor < 5 || (minor == 5 && micro <= 2)) {
/* initialize our dialog */
dialog_set_label (context,
_("The location and hierarchy of the Evolution contact "
@@ -1145,7 +1161,7 @@ addressbook_migrate (AddressbookComponent *component, gint major, gint minor, gi
migrate_completion_folders (context);
}
- if (minor < 5 || (minor == 5 && revision <= 7)) {
+ if (minor < 5 || (minor == 5 && micro <= 7)) {
dialog_set_label (context,
_("The format of mailing list contacts has changed.\n\n"
"Please be patient while Evolution migrates your "
@@ -1154,7 +1170,7 @@ addressbook_migrate (AddressbookComponent *component, gint major, gint minor, gi
migrate_contact_lists_for_local_folders (context, on_this_computer);
}
- if (minor < 5 || (minor == 5 && revision <= 8)) {
+ if (minor < 5 || (minor == 5 && micro <= 8)) {
dialog_set_label (context,
_("The way Evolution stores some phone numbers has changed.\n\n"
"Please be patient while Evolution migrates your "
@@ -1163,15 +1179,14 @@ addressbook_migrate (AddressbookComponent *component, gint major, gint minor, gi
migrate_company_phone_for_local_folders (context, on_this_computer);
}
- if (minor < 5 || (minor == 5 && revision <= 10)) {
+ if (minor < 5 || (minor == 5 && micro <= 10)) {
gchar *old_path, *new_path;
dialog_set_label (context, _("Evolution's Palm Sync changelog and map files have changed.\n\n"
"Please be patient while Evolution migrates your Pilot Sync data..."));
old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Contacts", NULL);
- new_path = g_build_filename (addressbook_component_peek_base_directory (component),
- "local", "system", NULL);
+ new_path = g_build_filename (data_dir, "local", "system", NULL);
migrate_pilot_data (old_path, new_path);
g_free (new_path);
g_free (old_path);
@@ -1183,7 +1198,7 @@ addressbook_migrate (AddressbookComponent *component, gint major, gint minor, gi
during one phase of development, as they take
precedent over relative uris (but aren't updated
when editing an ESource). */
- if (minor == 5 && revision <= 11) {
+ if (minor == 5 && micro <= 11) {
GSList *g;
for (g = e_source_list_peek_groups (context->source_list); g; g = g->next) {
ESourceGroup *group = g->data;
diff --git a/addressbook/gui/component/addressbook-migrate.h b/modules/addressbook/e-book-shell-migrate.h
index 0386d611e6..cb6128910a 100644
--- a/addressbook/gui/component/addressbook-migrate.h
+++ b/modules/addressbook/e-book-shell-migrate.h
@@ -1,4 +1,5 @@
/*
+ * e-book-shell-migrate.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,11 +22,20 @@
*
*/
-#ifndef _ADDRESSBOOK_MIGRATE_H_
-#define _ADDRESSBOOK_MIGRATE_H_
+#ifndef E_BOOK_SHELL_MIGRATE_H
+#define E_BOOK_SHELL_MIGRATE_H
-#include "addressbook-component.h"
+#include <glib.h>
+#include <shell/e-shell-backend.h>
-gint addressbook_migrate (AddressbookComponent *component, gint major, gint minor, gint revision, GError **err);
+G_BEGIN_DECLS
-#endif /* _ADDRESSBOOK_MIGRATE_H_ */
+gboolean e_book_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_BOOK_SHELL_MIGRATE_H */
diff --git a/modules/addressbook/e-book-shell-settings.c b/modules/addressbook/e-book-shell-settings.c
new file mode 100644
index 0000000000..7a9544d721
--- /dev/null
+++ b/modules/addressbook/e-book-shell-settings.c
@@ -0,0 +1,34 @@
+/*
+ * e-book-shell-settings.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-shell-settings.h"
+
+void
+e_book_shell_backend_init_settings (EShell *shell)
+{
+ EShellSettings *shell_settings;
+
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_settings_install_property_for_key (
+ "book-completion-show-address",
+ "/apps/evolution/addressbook/completion/show_address");
+}
diff --git a/modules/addressbook/e-book-shell-settings.h b/modules/addressbook/e-book-shell-settings.h
new file mode 100644
index 0000000000..9e05de41df
--- /dev/null
+++ b/modules/addressbook/e-book-shell-settings.h
@@ -0,0 +1,33 @@
+/*
+ * e-book-shell-settings.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_BOOK_SHELL_SETTINGS_H
+#define E_BOOK_SHELL_SETTINGS_H
+
+#include <shell/e-shell.h>
+
+G_BEGIN_DECLS
+
+void e_book_shell_backend_init_settings (EShell *shell);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_SETTINGS_H */
diff --git a/modules/addressbook/e-book-shell-sidebar.c b/modules/addressbook/e-book-shell-sidebar.c
new file mode 100644
index 0000000000..fc283e28d7
--- /dev/null
+++ b/modules/addressbook/e-book-shell-sidebar.c
@@ -0,0 +1,232 @@
+/*
+ * e-book-shell-sidebar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-shell-sidebar.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include "e-book-shell-view.h"
+#include "e-book-shell-backend.h"
+#include "e-addressbook-selector.h"
+
+#define E_BOOK_SHELL_SIDEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarPrivate))
+
+struct _EBookShellSidebarPrivate {
+ GtkWidget *selector;
+};
+
+enum {
+ PROP_0,
+ PROP_SELECTOR
+};
+
+static gpointer parent_class;
+static GType book_shell_sidebar_type;
+
+static void
+book_shell_sidebar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SELECTOR:
+ g_value_set_object (
+ value, e_book_shell_sidebar_get_selector (
+ E_BOOK_SHELL_SIDEBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+book_shell_sidebar_dispose (GObject *object)
+{
+ EBookShellSidebarPrivate *priv;
+
+ priv = E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ if (priv->selector != NULL) {
+ g_object_unref (priv->selector);
+ priv->selector = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+book_shell_sidebar_constructed (GObject *object)
+{
+ EBookShellSidebarPrivate *priv;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellSidebar *shell_sidebar;
+ ESourceList *source_list;
+ GtkContainer *container;
+ GtkWidget *widget;
+
+ priv = E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_sidebar = E_SHELL_SIDEBAR (object);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ source_list = e_book_shell_backend_get_source_list (
+ E_BOOK_SHELL_BACKEND (shell_backend));
+
+ container = GTK_CONTAINER (shell_sidebar);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_container_add (container, widget);
+ gtk_widget_show (widget);
+
+ container = GTK_CONTAINER (widget);
+
+ widget = e_addressbook_selector_new (source_list);
+ e_source_selector_show_selection (E_SOURCE_SELECTOR (widget), FALSE);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->selector = g_object_ref (widget);
+ gtk_widget_show (widget);
+}
+
+static guint32
+book_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+ EBookShellSidebar *book_shell_sidebar;
+ ESourceSelector *selector;
+ ESource *source;
+ gboolean is_system = FALSE;
+ guint32 state = 0;
+
+ book_shell_sidebar = E_BOOK_SHELL_SIDEBAR (shell_sidebar);
+ selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+
+ if (source != NULL) {
+ const gchar *uri;
+
+ uri = e_source_peek_relative_uri (source);
+ is_system = (uri == NULL || strcmp (uri, "system") == 0);
+ }
+
+ if (source != NULL)
+ state |= E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE;
+ if (is_system)
+ state |= E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM;
+
+ return state;
+}
+
+static void
+book_shell_sidebar_class_init (EBookShellSidebarClass *class)
+{
+ GObjectClass *object_class;
+ EShellSidebarClass *shell_sidebar_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EBookShellSidebarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = book_shell_sidebar_get_property;
+ object_class->dispose = book_shell_sidebar_dispose;
+ object_class->constructed = book_shell_sidebar_constructed;
+
+ shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
+ shell_sidebar_class->check_state = book_shell_sidebar_check_state;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTOR,
+ g_param_spec_object (
+ "selector",
+ _("Source Selector Widget"),
+ _("This widget displays groups of address books"),
+ E_TYPE_SOURCE_SELECTOR,
+ G_PARAM_READABLE));
+}
+
+static void
+book_shell_sidebar_init (EBookShellSidebar *book_shell_sidebar)
+{
+ book_shell_sidebar->priv =
+ E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (book_shell_sidebar);
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_book_shell_sidebar_get_type (void)
+{
+ return book_shell_sidebar_type;
+}
+
+void
+e_book_shell_sidebar_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EBookShellSidebarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) book_shell_sidebar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EBookShellSidebar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) book_shell_sidebar_init,
+ NULL /* value_table */
+ };
+
+ book_shell_sidebar_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_SIDEBAR,
+ "EBookShellSidebar", &type_info, 0);
+}
+
+GtkWidget *
+e_book_shell_sidebar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_BOOK_SHELL_SIDEBAR,
+ "shell-view", shell_view, NULL);
+}
+
+ESourceSelector *
+e_book_shell_sidebar_get_selector (EBookShellSidebar *book_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_BOOK_SHELL_SIDEBAR (book_shell_sidebar), NULL);
+
+ return E_SOURCE_SELECTOR (book_shell_sidebar->priv->selector);
+}
diff --git a/modules/addressbook/e-book-shell-sidebar.h b/modules/addressbook/e-book-shell-sidebar.h
new file mode 100644
index 0000000000..716523f971
--- /dev/null
+++ b/modules/addressbook/e-book-shell-sidebar.h
@@ -0,0 +1,79 @@
+/*
+ * e-book-shell-sidebar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_BOOK_SHELL_SIDEBAR_H
+#define E_BOOK_SHELL_SIDEBAR_H
+
+#include <libedataserverui/e-source-selector.h>
+
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_SHELL_SIDEBAR \
+ (e_book_shell_sidebar_get_type ())
+#define E_BOOK_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebar))
+#define E_BOOK_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarClass))
+#define E_IS_BOOK_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_BOOK_SHELL_SIDEBAR))
+#define E_IS_BOOK_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_BOOK_SHELL_SIDEBAR))
+#define E_BOOK_SHELL_SIDEBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookShellSidebar EBookShellSidebar;
+typedef struct _EBookShellSidebarClass EBookShellSidebarClass;
+typedef struct _EBookShellSidebarPrivate EBookShellSidebarPrivate;
+
+enum {
+ E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0,
+ E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM = 1 << 1
+};
+
+struct _EBookShellSidebar {
+ EShellSidebar parent;
+ EBookShellSidebarPrivate *priv;
+};
+
+struct _EBookShellSidebarClass {
+ EShellSidebarClass parent_class;
+};
+
+GType e_book_shell_sidebar_get_type (void);
+void e_book_shell_sidebar_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_book_shell_sidebar_new(EShellView *shell_view);
+ESourceSelector *
+ e_book_shell_sidebar_get_selector
+ (EBookShellSidebar *book_shell_sidebar);
+
+G_END_DECLS
+
+#endif /* E_BOOK_SHELL_SIDEBAR_H */
diff --git a/modules/addressbook/e-book-shell-view-actions.c b/modules/addressbook/e-book-shell-view-actions.c
new file mode 100644
index 0000000000..c2195e52de
--- /dev/null
+++ b/modules/addressbook/e-book-shell-view-actions.c
@@ -0,0 +1,1093 @@
+/*
+ * e-book-shell-view-actions.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-shell-view-private.h"
+
+#include <e-util/e-error.h>
+#include <e-util/e-util.h>
+#include <filter/filter-rule.h>
+
+#include <addressbook-config.h>
+
+static void
+action_address_book_copy_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_copy_to_folder (view, TRUE);
+}
+
+static void
+action_address_book_delete_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EBookShellBackend *book_shell_backend;
+ EBookShellSidebar *book_shell_sidebar;
+ ESource *source;
+ ESourceSelector *selector;
+ ESourceGroup *source_group;
+ ESourceList *source_list;
+ EBook *book;
+ gint response;
+ GError *error = NULL;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ book_shell_backend = book_shell_view->priv->book_shell_backend;
+ source_list = e_book_shell_backend_get_source_list (book_shell_backend);
+
+ book_shell_sidebar = book_shell_view->priv->book_shell_sidebar;
+ selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (source != NULL);
+
+ response = e_error_run (
+ GTK_WINDOW (shell_window),
+ "addressbook:ask-delete-addressbook",
+ e_source_peek_name (source));
+
+ if (response != GTK_RESPONSE_YES)
+ return;
+
+ book = e_book_new (source, &error);
+ if (error != NULL) {
+ g_warning ("Error removing addressbook: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (!e_book_remove (book, NULL)) {
+ e_error_run (
+ GTK_WINDOW (shell_window),
+ "addressbook:remove-addressbook", NULL);
+ g_object_unref (book);
+ return;
+ }
+
+ if (e_source_selector_source_is_selected (selector, source))
+ e_source_selector_unselect_source (selector, source);
+
+ source_group = e_source_peek_group (source);
+ e_source_group_remove_source (source_group, source);
+
+ e_source_list_sync (source_list, NULL);
+
+ g_object_unref (book);
+}
+
+static void
+action_address_book_move_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_move_to_folder (view, TRUE);
+}
+
+static void
+action_address_book_new_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ addressbook_config_create_new_source (GTK_WIDGET (shell_window));
+}
+
+static void
+action_address_book_properties_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EBookShellSidebar *book_shell_sidebar;
+ ESource *source;
+ ESourceSelector *selector;
+ EditorUidClosure *closure;
+ GHashTable *uid_to_editor;
+ const gchar *uid;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ book_shell_sidebar = book_shell_view->priv->book_shell_sidebar;
+ selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (source != NULL);
+
+ uid = e_source_peek_uid (source);
+ uid_to_editor = book_shell_view->priv->uid_to_editor;
+
+ closure = g_hash_table_lookup (uid_to_editor, uid);
+ if (closure == NULL) {
+ GtkWidget *editor;
+
+ editor = addressbook_config_edit_source (
+ GTK_WIDGET (shell_window), source);
+
+ closure = g_new (EditorUidClosure, 1);
+ closure->editor = editor;
+ closure->uid = g_strdup (uid);
+ closure->view = book_shell_view;
+
+ g_hash_table_insert (uid_to_editor, closure->uid, closure);
+
+ g_object_weak_ref (
+ G_OBJECT (closure->editor), (GWeakNotify)
+ e_book_shell_view_editor_weak_notify, closure);
+ }
+
+ gtk_window_present (GTK_WINDOW (closure->editor));
+}
+
+static void
+action_address_book_rename_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellSidebar *book_shell_sidebar;
+ ESourceSelector *selector;
+
+ book_shell_sidebar = book_shell_view->priv->book_shell_sidebar;
+ selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
+
+ e_source_selector_edit_primary_selection (selector);
+}
+
+static void
+action_address_book_save_as_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_save_as (view, TRUE);
+}
+
+static void
+action_address_book_stop_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_stop (view);
+}
+
+static void
+action_contact_clipboard_copy_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ e_book_shell_content_clipboard_copy (book_shell_content);
+}
+
+static void
+action_contact_clipboard_cut_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_cut (view);
+}
+
+static void
+action_contact_clipboard_paste_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_paste (view);
+}
+
+static void
+action_contact_copy_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_copy_to_folder (view, FALSE);
+}
+
+static void
+action_contact_delete_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_delete_selection (view, TRUE);
+}
+
+static void
+action_contact_forward_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+ GList *list, *iter;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ list = e_addressbook_view_get_selected (view);
+ g_return_if_fail (list != NULL);
+
+ /* Convert the list of contacts to a list of destinations. */
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EContact *contact = iter->data;
+ EDestination *destination;
+
+ destination = e_destination_new ();
+ e_destination_set_contact (destination, contact, 0);
+ g_object_unref (contact);
+
+ iter->data = destination;
+ }
+
+ eab_send_as_attachment (list);
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
+}
+
+static void
+action_contact_move_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_move_to_folder (view, FALSE);
+}
+
+static void
+action_contact_new_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ EContact *contact;
+ EABEditor *editor;
+ EBook *book;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
+ g_return_if_fail (book != NULL);
+
+ contact = e_contact_new ();
+ editor = e_contact_editor_new (shell, book, contact, TRUE, TRUE);
+ eab_editor_show (editor);
+ g_object_unref (contact);
+}
+
+static void
+action_contact_new_list_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ EContact *contact;
+ EABEditor *editor;
+ EBook *book;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
+ g_return_if_fail (book != NULL);
+
+ contact = e_contact_new ();
+ editor = e_contact_list_editor_new (shell, book, contact, TRUE, TRUE);
+ eab_editor_show (editor);
+ g_object_unref (contact);
+}
+
+static void
+action_contact_open_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_view (view);
+}
+
+static void
+action_contact_preview_cb (GtkToggleAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ gboolean visible;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ visible = gtk_toggle_action_get_active (action);
+ e_book_shell_content_set_preview_visible (book_shell_content, visible);
+}
+
+static void
+action_contact_print_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+ GtkPrintOperationAction print_action;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ e_addressbook_view_print (view, print_action);
+}
+
+static void
+action_contact_print_preview_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+ GtkPrintOperationAction print_action;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
+ e_addressbook_view_print (view, print_action);
+}
+
+static void
+action_contact_save_as_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_save_as (view, FALSE);
+}
+
+static void
+action_contact_search_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EBookShellView *book_shell_view)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *search_hint;
+
+ /* XXX Figure out a way to handle this in EShellContent
+ * instead of every shell view having to handle it.
+ * The problem is EShellContent does not know what
+ * the search option actions are for this view. It
+ * would have to dig up the popup menu and retrieve
+ * the action for each menu item. Seems messy. */
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ search_hint = gtk_action_get_label (GTK_ACTION (current));
+ e_shell_content_set_search_hint (shell_content, search_hint);
+}
+
+static void
+action_contact_select_all_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ e_addressbook_view_select_all (view);
+}
+
+static void
+action_contact_send_message_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+ GList *list, *iter;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ g_return_if_fail (view != NULL);
+
+ list = e_addressbook_view_get_selected (view);
+ g_return_if_fail (list != NULL);
+
+ /* Convert the list of contacts to a list of destinations. */
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EContact *contact = iter->data;
+ EDestination *destination;
+
+ destination = e_destination_new ();
+ e_destination_set_contact (destination, contact, 0);
+ g_object_unref (contact);
+
+ iter->data = destination;
+ }
+
+ eab_send_as_to (list);
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
+}
+
+static void
+action_contact_view_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ orientable = GTK_ORIENTABLE (book_shell_content);
+
+ switch (gtk_radio_action_get_current_value (action)) {
+ case 0:
+ orientation = GTK_ORIENTATION_VERTICAL;
+ break;
+ case 1:
+ orientation = GTK_ORIENTATION_HORIZONTAL;
+ break;
+ default:
+ g_return_if_reached ();
+ }
+
+ gtk_orientable_set_orientation (orientable, orientation);
+}
+
+static void
+action_gal_save_custom_view_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EShellView *shell_view;
+ EAddressbookView *address_view;
+ GalViewInstance *view_instance;
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with saving the custom view. */
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ address_view = e_book_shell_content_get_current_view (book_shell_content);
+ view_instance = e_addressbook_view_get_view_instance (address_view);
+ gal_view_instance_save_as (view_instance);
+}
+
+static void
+action_search_execute_cb (GtkAction *action,
+ EBookShellView *book_shell_view)
+{
+ EShellView *shell_view;
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with executing the search. */
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ e_book_shell_view_execute_search (book_shell_view);
+}
+
+static void
+action_search_filter_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EBookShellView *book_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+}
+
+static GtkActionEntry contact_entries[] = {
+
+ { "address-book-copy",
+ GTK_STOCK_COPY,
+ N_("Co_py All Contacts To..."),
+ NULL,
+ N_("Copy the contacts of the selected address book to another"),
+ G_CALLBACK (action_address_book_copy_cb) },
+
+ { "address-book-delete",
+ GTK_STOCK_DELETE,
+ N_("Del_ete Address Book"),
+ NULL,
+ N_("Delete the selected address book"),
+ G_CALLBACK (action_address_book_delete_cb) },
+
+ { "address-book-move",
+ "folder-move",
+ N_("Mo_ve All Contacts To..."),
+ NULL,
+ N_("Move the contacts of the selected address book to another"),
+ G_CALLBACK (action_address_book_move_cb) },
+
+ { "address-book-new",
+ "address-book-new",
+ N_("_New Address Book"),
+ NULL,
+ N_("Create a new address book"),
+ G_CALLBACK (action_address_book_new_cb) },
+
+ { "address-book-properties",
+ GTK_STOCK_PROPERTIES,
+ N_("Address _Book Properties"),
+ NULL,
+ N_("Show properties of the selected address book"),
+ G_CALLBACK (action_address_book_properties_cb) },
+
+ { "address-book-rename",
+ NULL,
+ N_("_Rename..."),
+ "F2",
+ N_("Rename the selected address book"),
+ G_CALLBACK (action_address_book_rename_cb) },
+
+ { "address-book-save-as",
+ GTK_STOCK_SAVE_AS,
+ N_("S_ave Address Book as vCard"),
+ NULL,
+ N_("Save the contacts of the selected address book as a vCard"),
+ G_CALLBACK (action_address_book_save_as_cb) },
+
+ { "address-book-stop",
+ GTK_STOCK_STOP,
+ NULL,
+ NULL,
+ N_("Stop loading"),
+ G_CALLBACK (action_address_book_stop_cb) },
+
+ { "contact-clipboard-copy",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy the selection"),
+ G_CALLBACK (action_contact_clipboard_copy_cb) },
+
+ { "contact-clipboard-cut",
+ GTK_STOCK_CUT,
+ NULL,
+ NULL,
+ N_("Cut the selection"),
+ G_CALLBACK (action_contact_clipboard_cut_cb) },
+
+ { "contact-clipboard-paste",
+ GTK_STOCK_PASTE,
+ NULL,
+ NULL,
+ N_("Paste the clipboard"),
+ G_CALLBACK (action_contact_clipboard_paste_cb) },
+
+ { "contact-copy",
+ NULL,
+ N_("_Copy Contact To..."),
+ "<Control><Shift>y",
+ N_("Copy selected contacts to another address book"),
+ G_CALLBACK (action_contact_copy_cb) },
+
+ { "contact-delete",
+ GTK_STOCK_DELETE,
+ N_("_Delete Contact"),
+ "<Control>d",
+ N_("Delete selected contacts"),
+ G_CALLBACK (action_contact_delete_cb) },
+
+ { "contact-forward",
+ "mail-forward",
+ N_("_Forward Contact..."),
+ NULL,
+ N_("Send selected contacts to another person"),
+ G_CALLBACK (action_contact_forward_cb) },
+
+ { "contact-move",
+ NULL,
+ N_("_Move Contact To..."),
+ "<Control><Shift>v",
+ N_("Move selected contacts to another address book"),
+ G_CALLBACK (action_contact_move_cb) },
+
+ { "contact-new",
+ "contact-new",
+ N_("_New Contact..."),
+ NULL,
+ N_("Create a new contact"),
+ G_CALLBACK (action_contact_new_cb) },
+
+ { "contact-new-list",
+ "stock_contact-list",
+ N_("New Contact _List..."),
+ NULL,
+ N_("Create a new contact list"),
+ G_CALLBACK (action_contact_new_list_cb) },
+
+ { "contact-open",
+ NULL,
+ N_("_Open"),
+ "<Control>o",
+ N_("View the current contact"),
+ G_CALLBACK (action_contact_open_cb) },
+
+ { "contact-save-as",
+ GTK_STOCK_SAVE_AS,
+ N_("Save as vCard..."),
+ NULL,
+ N_("Save selected contacts as a vCard"),
+ G_CALLBACK (action_contact_save_as_cb) },
+
+ { "contact-select-all",
+ GTK_STOCK_SELECT_ALL,
+ NULL,
+ NULL,
+ N_("Select all contacts"),
+ G_CALLBACK (action_contact_select_all_cb) },
+
+ { "contact-send-message",
+ "mail-message-new",
+ N_("_Send Message to Contact..."),
+ NULL,
+ N_("Send a message to the selected contacts"),
+ G_CALLBACK (action_contact_send_message_cb) },
+
+ /*** Menus ***/
+
+ { "contact-actions-menu",
+ NULL,
+ N_("_Actions"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "contact-preview-menu",
+ NULL,
+ N_("_Preview"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static EPopupActionEntry contact_popup_entries[] = {
+
+ { "address-book-popup-delete",
+ N_("_Delete"),
+ "address-book-delete" },
+
+ { "address-book-popup-properties",
+ N_("_Properties"),
+ "address-book-properties" },
+
+ { "address-book-popup-rename",
+ NULL,
+ "address-book-rename" },
+
+ { "address-book-popup-save-as",
+ N_("_Save as vCard..."),
+ "address-book-save-as" },
+
+ { "contact-popup-clipboard-copy",
+ NULL,
+ "contact-clipboard-copy" },
+
+ { "contact-popup-clipboard-cut",
+ NULL,
+ "contact-clipboard-cut" },
+
+ { "contact-popup-clipboard-paste",
+ NULL,
+ "contact-clipboard-paste" },
+
+ { "contact-popup-copy",
+ NULL,
+ "contact-copy" },
+
+ { "contact-popup-delete",
+ NULL,
+ "contact-delete" },
+
+ { "contact-popup-forward",
+ NULL,
+ "contact-forward" },
+
+ { "contact-popup-move",
+ NULL,
+ "contact-move" },
+
+ { "contact-popup-open",
+ NULL,
+ "contact-open" },
+
+ { "contact-popup-save-as",
+ NULL,
+ "contact-save-as" },
+
+ { "contact-popup-send-message",
+ NULL,
+ "contact-send-message" },
+};
+
+static GtkToggleActionEntry contact_toggle_entries[] = {
+
+ { "contact-preview",
+ NULL,
+ N_("Contact _Preview"),
+ "<Control>m",
+ N_("Show contact preview window"),
+ G_CALLBACK (action_contact_preview_cb),
+ TRUE }
+};
+
+static GtkRadioActionEntry contact_view_entries[] = {
+
+ /* This action represents the initial active contact view.
+ * It should not be visible in the UI, nor should it be
+ * possible to switch to it from another shell view. */
+ { "contact-view-initial",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ -1 },
+
+ { "contact-view-classic",
+ NULL,
+ N_("_Classic View"),
+ NULL,
+ N_("Show contact preview below the contact list"),
+ 0 },
+
+ { "contact-view-vertical",
+ NULL,
+ N_("_Vertical View"),
+ NULL,
+ N_("Show contact preview alongside the contact list"),
+ 1 }
+};
+
+static GtkRadioActionEntry contact_filter_entries[] = {
+
+ { "contact-filter-any-category",
+ NULL,
+ N_("Any Category"),
+ NULL,
+ NULL,
+ CONTACT_FILTER_ANY_CATEGORY },
+
+ { "contact-filter-unmatched",
+ NULL,
+ N_("Unmatched"),
+ NULL,
+ NULL,
+ CONTACT_FILTER_UNMATCHED }
+};
+
+static GtkRadioActionEntry contact_search_entries[] = {
+
+ { "contact-search-any-field-contains",
+ NULL,
+ N_("Any field contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CONTACT_SEARCH_ANY_FIELD_CONTAINS },
+
+ { "contact-search-email-begins-with",
+ NULL,
+ N_("Email begins with"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CONTACT_SEARCH_EMAIL_BEGINS_WITH },
+
+ { "contact-search-name-contains",
+ NULL,
+ N_("Name contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CONTACT_SEARCH_NAME_CONTAINS }
+};
+
+static GtkActionEntry lockdown_printing_entries[] = {
+
+ { "contact-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ "<Control>p",
+ N_("Print selected contacts"),
+ G_CALLBACK (action_contact_print_cb) },
+
+ { "contact-print-preview",
+ GTK_STOCK_PRINT_PREVIEW,
+ NULL,
+ NULL,
+ N_("Preview the contacts to be printed"),
+ G_CALLBACK (action_contact_print_preview_cb) }
+};
+
+static EPopupActionEntry lockdown_printing_popup_entries[] = {
+
+ { "contact-popup-print",
+ NULL,
+ "contact-print" }
+};
+
+void
+e_book_shell_view_actions_init (EBookShellView *book_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+ GConfBridge *bridge;
+ GtkAction *action;
+ GObject *object;
+ const gchar *key;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ /* Contact Actions */
+ action_group = ACTION_GROUP (CONTACTS);
+ gtk_action_group_add_actions (
+ action_group, contact_entries,
+ G_N_ELEMENTS (contact_entries), book_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, contact_popup_entries,
+ G_N_ELEMENTS (contact_popup_entries));
+ gtk_action_group_add_toggle_actions (
+ action_group, contact_toggle_entries,
+ G_N_ELEMENTS (contact_toggle_entries), book_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, contact_view_entries,
+ G_N_ELEMENTS (contact_view_entries), -1,
+ G_CALLBACK (action_contact_view_cb), book_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, contact_search_entries,
+ G_N_ELEMENTS (contact_search_entries),
+ CONTACT_SEARCH_NAME_CONTAINS,
+ G_CALLBACK (action_contact_search_cb), book_shell_view);
+
+ /* Lockdown Printing Actions */
+ action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
+ gtk_action_group_add_actions (
+ action_group, lockdown_printing_entries,
+ G_N_ELEMENTS (lockdown_printing_entries), book_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, lockdown_printing_popup_entries,
+ G_N_ELEMENTS (lockdown_printing_popup_entries));
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (ACTION (CONTACT_PREVIEW));
+ key = "/apps/evolution/addressbook/display/show_preview";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (CONTACT_VIEW_VERTICAL));
+ key = "/apps/evolution/addressbook/display/layout";
+ gconf_bridge_bind_property (bridge, key, object, "current-value");
+
+ /* Fine tuning. */
+
+ action = ACTION (CONTACT_DELETE);
+ g_object_set (action, "short-label", _("Delete"), NULL);
+
+ g_signal_connect (
+ ACTION (GAL_SAVE_CUSTOM_VIEW), "activate",
+ G_CALLBACK (action_gal_save_custom_view_cb), book_shell_view);
+
+ g_signal_connect (
+ ACTION (SEARCH_EXECUTE), "activate",
+ G_CALLBACK (action_search_execute_cb), book_shell_view);
+}
+
+void
+e_book_shell_view_update_search_filter (EBookShellView *book_shell_view)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+ GtkRadioAction *radio_action;
+ GList *list, *iter;
+ GSList *group;
+ gint ii;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action_group = ACTION_GROUP (CONTACTS_FILTER);
+ e_action_group_remove_all_actions (action_group);
+
+ /* Add the standard filter actions. */
+ gtk_action_group_add_radio_actions (
+ action_group, contact_filter_entries,
+ G_N_ELEMENTS (contact_filter_entries),
+ CONTACT_FILTER_ANY_CATEGORY,
+ G_CALLBACK (action_search_filter_cb),
+ book_shell_view);
+
+ /* Retrieve the radio group from an action we just added. */
+ list = gtk_action_group_list_actions (action_group);
+ radio_action = GTK_RADIO_ACTION (list->data);
+ group = gtk_radio_action_get_group (radio_action);
+ g_list_free (list);
+
+ /* Build the category actions. */
+
+ list = e_categories_get_list ();
+ for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) {
+ const gchar *category_name = iter->data;
+ const gchar *filename;
+ GtkAction *action;
+ gchar *action_name;
+
+ action_name = g_strdup_printf (
+ "contact-filter-category-%d", ii);
+ radio_action = gtk_radio_action_new (
+ action_name, category_name, NULL, NULL, ii);
+ g_free (action_name);
+
+ /* Convert the category icon file to a themed icon name. */
+ filename = e_categories_get_icon_file_for (category_name);
+ if (filename != NULL && *filename != '\0') {
+ gchar *basename;
+ gchar *cp;
+
+ basename = g_path_get_basename (filename);
+
+ /* Lose the file extension. */
+ if ((cp = strrchr (basename, '.')) != NULL)
+ *cp = '\0';
+
+ g_object_set (
+ radio_action, "icon-name", basename, NULL);
+
+ g_free (basename);
+ }
+
+ gtk_radio_action_set_group (radio_action, group);
+ group = gtk_radio_action_get_group (radio_action);
+
+ /* The action group takes ownership of the action. */
+ action = GTK_ACTION (radio_action);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (radio_action);
+ }
+ g_list_free (list);
+
+ /* Use any action in the group; doesn't matter which. */
+ e_shell_content_set_filter_action (shell_content, radio_action);
+
+ ii = CONTACT_FILTER_UNMATCHED;
+ e_shell_content_add_filter_separator_after (shell_content, ii);
+}
diff --git a/modules/addressbook/e-book-shell-view-actions.h b/modules/addressbook/e-book-shell-view-actions.h
new file mode 100644
index 0000000000..4c3a18bddf
--- /dev/null
+++ b/modules/addressbook/e-book-shell-view-actions.h
@@ -0,0 +1,95 @@
+/*
+ * e-book-shell-view-actions.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_BOOK_SHELL_VIEW_ACTIONS_H
+#define E_BOOK_SHELL_VIEW_ACTIONS_H
+
+#include <shell/e-shell-window-actions.h>
+
+/* Address Book Actions */
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "address-book-copy")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "address-book-delete")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_MOVE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "address-book-move")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_PROPERTIES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "address-book-properties")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_RENAME(window) \
+ E_SHELL_WINDOW_ACTION ((window), "address-book-rename")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_SAVE_AS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "address-book-save-as")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_STOP(window) \
+ E_SHELL_WINDOW_ACTION ((window), "address-book-stop")
+
+/* Contact Actions */
+#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-copy")
+#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_CUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-cut")
+#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_PASTE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-paste")
+#define E_SHELL_WINDOW_ACTION_CONTACT_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-copy")
+#define E_SHELL_WINDOW_ACTION_CONTACT_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-delete")
+#define E_SHELL_WINDOW_ACTION_CONTACT_FORWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-forward")
+#define E_SHELL_WINDOW_ACTION_CONTACT_MOVE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-move")
+#define E_SHELL_WINDOW_ACTION_CONTACT_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-new")
+#define E_SHELL_WINDOW_ACTION_CONTACT_NEW_LIST(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-new-list")
+#define E_SHELL_WINDOW_ACTION_CONTACT_OPEN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-open")
+#define E_SHELL_WINDOW_ACTION_CONTACT_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-preview")
+#define E_SHELL_WINDOW_ACTION_CONTACT_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-print")
+#define E_SHELL_WINDOW_ACTION_CONTACT_PRINT_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-print-preview")
+#define E_SHELL_WINDOW_ACTION_CONTACT_SAVE_AS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-save-as")
+#define E_SHELL_WINDOW_ACTION_CONTACT_SELECT_ALL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-select-all")
+#define E_SHELL_WINDOW_ACTION_CONTACT_SEND_MESSAGE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-send-message")
+#define E_SHELL_WINDOW_ACTION_CONTACT_VIEW_CLASSIC(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-view-classic")
+#define E_SHELL_WINDOW_ACTION_CONTACT_VIEW_VERTICAL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-view-vertical")
+
+/* Search Actions */
+#define E_SHELL_WINDOW_ACTION_CONTACT_SEARCH_ANY_FIELD_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-search-any-field-contains")
+#define E_SHELL_WINDOW_ACTION_CONTACT_SEARCH_EMAIL_BEGINS_WITH(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-search-email-begins-with")
+#define E_SHELL_WINDOW_ACTION_CONTACT_SEARCH_NAME_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contact-search-name-contains")
+
+/* Action Groups */
+#define E_SHELL_WINDOW_ACTION_GROUP_CONTACTS(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "contacts")
+#define E_SHELL_WINDOW_ACTION_GROUP_CONTACTS_FILTER(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "contacts-filter")
+
+#endif /* E_BOOK_SHELL_VIEW_ACTIONS_H */
diff --git a/modules/addressbook/e-book-shell-view-private.c b/modules/addressbook/e-book-shell-view-private.c
new file mode 100644
index 0000000000..6770800dbd
--- /dev/null
+++ b/modules/addressbook/e-book-shell-view-private.c
@@ -0,0 +1,634 @@
+/*
+ * e-book-shell-view-private.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-shell-view-private.h"
+
+#include "widgets/menus/gal-view-factory-etable.h"
+#include "addressbook/gui/widgets/gal-view-factory-minicard.h"
+
+#include "addressbook.h"
+
+static void
+open_contact (EBookShellView *book_shell_view,
+ EContact *contact,
+ gboolean is_new_contact,
+ EAddressbookView *view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EAddressbookModel *model;
+ EABEditor *editor;
+ EBook *book;
+ gboolean editable;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ model = e_addressbook_view_get_model (view);
+ book = e_addressbook_model_get_book (model);
+ editable = e_addressbook_model_get_editable (model);
+
+ if (e_contact_get (contact, E_CONTACT_IS_LIST))
+ editor = e_contact_list_editor_new (
+ shell, book, contact, is_new_contact, editable);
+ else
+ editor = e_contact_editor_new (
+ shell, book, contact, is_new_contact, editable);
+
+ eab_editor_show (editor);
+}
+
+static void
+popup_event (EBookShellView *book_shell_view,
+ GdkEventButton *event)
+{
+ EShellView *shell_view;
+ const gchar *widget_path;
+
+ widget_path = "/contact-popup";
+ shell_view = E_SHELL_VIEW (book_shell_view);
+
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+}
+
+static void
+book_shell_view_selection_change_foreach (gint row,
+ EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ EContact *contact;
+
+ /* XXX A "foreach" function is kind of a silly way to retrieve
+ * the one and only selected contact, but this is the only
+ * means that ESelectionModel provides. */
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ model = e_addressbook_view_get_model (view);
+ contact = e_addressbook_model_get_contact (model, row);
+
+ e_book_shell_content_set_preview_contact (book_shell_content, contact);
+ book_shell_view->priv->preview_index = row;
+}
+
+static void
+selection_change (EBookShellView *book_shell_view,
+ EAddressbookView *view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *current_view;
+ ESelectionModel *selection_model;
+ EShellView *shell_view;
+ gint n_selected;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ current_view = e_book_shell_content_get_current_view (book_shell_content);
+
+ if (view != current_view)
+ return;
+
+ e_shell_view_update_actions (shell_view);
+
+ selection_model = e_addressbook_view_get_selection_model (view);
+
+ n_selected = (selection_model != NULL) ?
+ e_selection_model_selected_count (selection_model) : 0;
+
+ if (n_selected == 1)
+ e_selection_model_foreach (
+ selection_model, (EForeachFunc)
+ book_shell_view_selection_change_foreach,
+ book_shell_view);
+ else {
+ e_book_shell_content_set_preview_contact (
+ book_shell_content, NULL);
+ book_shell_view->priv->preview_index = -1;
+ }
+}
+
+static void
+contact_changed (EBookShellView *book_shell_view,
+ gint index,
+ EAddressbookModel *model)
+{
+ EBookShellContent *book_shell_content;
+ EContact *contact;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+
+ contact = e_addressbook_model_contact_at (model, index);
+
+ if (book_shell_view->priv->preview_index != index)
+ return;
+
+ /* Re-render the same contact. */
+ e_book_shell_content_set_preview_contact (book_shell_content, contact);
+}
+
+static void
+contacts_removed (EBookShellView *book_shell_view,
+ GArray *removed_indices,
+ EAddressbookModel *model)
+{
+ EBookShellContent *book_shell_content;
+ EContact *preview_contact;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+
+ preview_contact =
+ e_book_shell_content_get_preview_contact (book_shell_content);
+
+ if (preview_contact == NULL)
+ return;
+
+ /* Is the displayed contact still in the model? */
+ if (e_addressbook_model_find (model, preview_contact) < 0)
+ return;
+
+ /* If not, clear the contact display. */
+ e_book_shell_content_set_preview_contact (book_shell_content, NULL);
+ book_shell_view->priv->preview_index = -1;
+}
+
+static void
+book_open_cb (EBook *book,
+ EBookStatus status,
+ gpointer user_data)
+{
+ EAddressbookView *view = user_data;
+ EAddressbookModel *model;
+ ESource *source;
+
+ source = e_book_get_source (book);
+ model = e_addressbook_view_get_model (view);
+
+ if (status == E_BOOK_ERROR_OK) {
+ e_addressbook_model_set_book (model, book);
+ e_addressbook_model_force_folder_bar_message (model);
+ } else if (status != E_BOOK_ERROR_CANCELLED)
+ eab_load_error_dialog (NULL /* XXX */, source, status);
+}
+
+static void
+book_shell_view_activate_selected_source (EBookShellView *book_shell_view,
+ ESourceSelector *selector)
+{
+ EShellView *shell_view;
+ EBookShellContent *book_shell_content;
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ ESource *source;
+ GalViewInstance *view_instance;
+ GHashTable *hash_table;
+ GtkWidget *widget;
+ const gchar *uid;
+ gchar *view_id;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ source = e_source_selector_peek_primary_selection (selector);
+
+ if (source == NULL)
+ return;
+
+ uid = e_source_peek_uid (source);
+ hash_table = book_shell_view->priv->uid_to_view;
+ widget = g_hash_table_lookup (hash_table, uid);
+
+ if (widget != NULL) {
+ EBook *book;
+
+ /* There is a view for this UID. Make sure the view
+ * actually contains an EBook. The absence of an EBook
+ * suggests a previous load failed, so try again. */
+ view = E_ADDRESSBOOK_VIEW (widget);
+ model = e_addressbook_view_get_model (view);
+ source = e_addressbook_view_get_source (view);
+
+ if (e_addressbook_model_get_book (model) == NULL) {
+ book = e_book_new (source, NULL);
+
+ if (book != NULL)
+ addressbook_load (book, book_open_cb, view);
+ }
+
+ } else {
+ EBook *book;
+
+ /* Create a view for this UID. */
+ widget = e_addressbook_view_new (shell_view, source);
+ gtk_widget_show (widget);
+
+ e_book_shell_content_insert_view (
+ book_shell_content,
+ E_ADDRESSBOOK_VIEW (widget));
+
+ g_hash_table_insert (
+ hash_table, g_strdup (uid),
+ g_object_ref (widget));
+
+ g_signal_connect_swapped (
+ widget, "open-contact",
+ G_CALLBACK (open_contact), book_shell_view);
+
+ g_signal_connect_swapped (
+ widget, "popup-event",
+ G_CALLBACK (popup_event), book_shell_view);
+
+ g_signal_connect_swapped (
+ widget, "command-state-change",
+ G_CALLBACK (e_shell_view_update_actions),
+ book_shell_view);
+
+ g_signal_connect_swapped (
+ widget, "selection-change",
+ G_CALLBACK (selection_change), book_shell_view);
+
+ book = e_book_new (source, NULL);
+ view = E_ADDRESSBOOK_VIEW (widget);
+
+ if (book != NULL)
+ addressbook_load (book, book_open_cb, view);
+
+ model = e_addressbook_view_get_model (view);
+
+ g_signal_connect_swapped (
+ model, "contact-changed",
+ G_CALLBACK (contact_changed), book_shell_view);
+
+ g_signal_connect_swapped (
+ model, "contacts-removed",
+ G_CALLBACK (contacts_removed), book_shell_view);
+ }
+
+ e_book_shell_content_set_current_view (
+ book_shell_content, E_ADDRESSBOOK_VIEW (widget));
+
+ /* XXX We have to keep the addressbook selector informed of the
+ * current view so it can move contacts via drag-and-drop. */
+ e_addressbook_selector_set_current_view (
+ E_ADDRESSBOOK_SELECTOR (selector),
+ E_ADDRESSBOOK_VIEW (widget));
+
+ view_instance = e_addressbook_view_get_view_instance (view);
+ view_id = gal_view_instance_get_current_view_id (view_instance);
+ e_shell_view_set_view_id (shell_view, view_id);
+ g_free (view_id);
+
+ e_addressbook_model_force_folder_bar_message (model);
+ selection_change (book_shell_view, view);
+}
+
+static gboolean
+book_shell_view_show_popup_menu (GdkEventButton *event,
+ EShellView *shell_view)
+{
+ const gchar *widget_path;
+
+ widget_path = "/address-book-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+
+ return TRUE;
+}
+
+static gboolean
+book_shell_view_selector_button_press_event_cb (EShellView *shell_view,
+ GdkEventButton *event)
+{
+ /* XXX Use ESourceSelector's "popup-event" signal instead. */
+
+ if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
+ return book_shell_view_show_popup_menu (event, shell_view);
+
+ return FALSE;
+}
+
+static gboolean
+book_shell_view_selector_popup_menu_cb (EShellView *shell_view)
+{
+ /* XXX Use ESourceSelector's "popup-event" signal instead. */
+
+ return book_shell_view_show_popup_menu (NULL, shell_view);
+}
+
+static gboolean
+book_shell_view_selector_key_press_event_cb (EShellView *shell_view,
+ GdkEventKey *event)
+{
+ EShellWindow *shell_window;
+
+ /* Needed for the ACTION() macro. */
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (event->keyval == GDK_Delete) {
+ gtk_action_activate (ACTION (ADDRESS_BOOK_DELETE));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+book_shell_view_load_view_collection (EShellViewClass *shell_view_class)
+{
+ GalViewCollection *collection;
+ GalViewFactory *factory;
+ ETableSpecification *spec;
+ const gchar *base_dir;
+ gchar *filename;
+
+ collection = shell_view_class->view_collection;
+
+ base_dir = EVOLUTION_ETSPECDIR;
+ spec = e_table_specification_new ();
+ filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL);
+ if (!e_table_specification_load_from_file (spec, filename))
+ g_critical ("Unable to load ETable specification file "
+ "for address book");
+ g_free (filename);
+
+ factory = gal_view_factory_etable_new (spec);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+ g_object_unref (spec);
+
+ factory = gal_view_factory_minicard_new ();
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+
+ gal_view_collection_load (collection);
+}
+
+static void
+book_shell_view_notify_view_id_cb (EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EAddressbookView *address_view;
+ GalViewInstance *view_instance;
+ const gchar *view_id;
+
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ address_view = e_book_shell_content_get_current_view (book_shell_content);
+ view_instance = e_addressbook_view_get_view_instance (address_view);
+ view_id = e_shell_view_get_view_id (E_SHELL_VIEW (book_shell_view));
+
+ /* A NULL view ID implies we're in a custom view. But you can
+ * only get to a custom view via the "Define Views" dialog, which
+ * would have already modified the view instance appropriately.
+ * Furthermore, there's no way to refer to a custom view by ID
+ * anyway, since custom views have no IDs. */
+ if (view_id == NULL)
+ return;
+
+ gal_view_instance_set_current_view_id (view_instance, view_id);
+}
+
+void
+e_book_shell_view_private_init (EBookShellView *book_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ EBookShellViewPrivate *priv = book_shell_view->priv;
+ GHashTable *uid_to_view;
+ GHashTable *uid_to_editor;
+
+ uid_to_view = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ uid_to_editor = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
+
+ priv->uid_to_view = uid_to_view;
+ priv->uid_to_editor = uid_to_editor;
+ priv->preview_index = -1;
+
+ if (!gal_view_collection_loaded (shell_view_class->view_collection))
+ book_shell_view_load_view_collection (shell_view_class);
+
+ g_signal_connect (
+ book_shell_view, "notify::view-id",
+ G_CALLBACK (book_shell_view_notify_view_id_cb), NULL);
+}
+
+void
+e_book_shell_view_private_constructed (EBookShellView *book_shell_view)
+{
+ EBookShellViewPrivate *priv = book_shell_view->priv;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellBackend *shell_backend;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ESourceSelector *selector;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ e_shell_window_add_action_group (shell_window, "contacts");
+ e_shell_window_add_action_group (shell_window, "contacts-filter");
+
+ /* Cache these to avoid lots of awkward casting. */
+ priv->book_shell_backend = g_object_ref (shell_backend);
+ priv->book_shell_content = g_object_ref (shell_content);
+ priv->book_shell_sidebar = g_object_ref (shell_sidebar);
+
+ selector = e_book_shell_sidebar_get_selector (
+ E_BOOK_SHELL_SIDEBAR (shell_sidebar));
+
+ g_signal_connect_swapped (
+ selector, "button-press-event",
+ G_CALLBACK (book_shell_view_selector_button_press_event_cb),
+ book_shell_view);
+
+ g_signal_connect_swapped (
+ selector, "key-press-event",
+ G_CALLBACK (book_shell_view_selector_key_press_event_cb),
+ book_shell_view);
+
+ g_signal_connect_swapped (
+ selector, "popup-menu",
+ G_CALLBACK (book_shell_view_selector_popup_menu_cb),
+ book_shell_view);
+
+ g_signal_connect_swapped (
+ selector, "primary-selection-changed",
+ G_CALLBACK (book_shell_view_activate_selected_source),
+ book_shell_view);
+
+ e_categories_register_change_listener (
+ G_CALLBACK (e_book_shell_view_update_search_filter),
+ book_shell_view);
+
+ e_book_shell_view_actions_init (book_shell_view);
+ book_shell_view_activate_selected_source (book_shell_view, selector);
+ e_book_shell_view_update_search_filter (book_shell_view);
+}
+
+void
+e_book_shell_view_private_dispose (EBookShellView *book_shell_view)
+{
+ EBookShellViewPrivate *priv = book_shell_view->priv;
+
+ DISPOSE (priv->book_shell_backend);
+ DISPOSE (priv->book_shell_content);
+ DISPOSE (priv->book_shell_sidebar);
+
+ g_hash_table_remove_all (priv->uid_to_view);
+ g_hash_table_remove_all (priv->uid_to_editor);
+}
+
+void
+e_book_shell_view_private_finalize (EBookShellView *book_shell_view)
+{
+ EBookShellViewPrivate *priv = book_shell_view->priv;
+
+ g_hash_table_destroy (priv->uid_to_view);
+ g_hash_table_destroy (priv->uid_to_editor);
+}
+
+void
+e_book_shell_view_execute_search (EBookShellView *book_shell_view)
+{
+ EBookShellContent *book_shell_content;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ GtkRadioAction *action;
+ GString *string;
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ FilterRule *rule;
+ const gchar *format;
+ const gchar *text;
+ gchar *query;
+ gchar *temp;
+ gint value;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ text = e_shell_content_get_search_text (shell_content);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action = GTK_RADIO_ACTION (ACTION (CONTACT_SEARCH_ANY_FIELD_CONTAINS));
+ value = gtk_radio_action_get_current_value (action);
+
+ if (text == NULL || *text == '\0') {
+ text = "";
+ value = CONTACT_SEARCH_ANY_FIELD_CONTAINS;
+ }
+
+ switch (value) {
+ case CONTACT_SEARCH_NAME_CONTAINS:
+ format = "(contains \"full_name\" %s)";
+ break;
+
+ case CONTACT_SEARCH_EMAIL_BEGINS_WITH:
+ format = "(beginswith \"email\" %s)";
+ break;
+
+ default:
+ text = "";
+ /* fall through */
+
+ case CONTACT_SEARCH_ANY_FIELD_CONTAINS:
+ format = "(contains \"x-evolution-any-field\" %s)";
+ break;
+ }
+
+ /* Build the query. */
+ string = g_string_new ("");
+ e_sexp_encode_string (string, text);
+ query = g_strdup_printf (format, string->str);
+ g_string_free (string, TRUE);
+
+ /* Apply selected filter. */
+ value = e_shell_content_get_filter_value (shell_content);
+ switch (value) {
+ case CONTACT_FILTER_ANY_CATEGORY:
+ break;
+
+ case CONTACT_FILTER_UNMATCHED:
+ temp = g_strdup_printf (
+ "(and (not (and (exists \"CATEGORIES\") "
+ "(not (is \"CATEGORIES\" \"\")))) %s)",
+ query);
+ g_free (query);
+ query = temp;
+ break;
+
+ default:
+ {
+ GList *categories;
+ const gchar *category_name;
+
+ categories = e_categories_get_list ();
+ category_name = g_list_nth_data (categories, value);
+ g_list_free (categories);
+
+ temp = g_strdup_printf (
+ "(and (is \"category_list\" \"%s\") %s)",
+ category_name, query);
+ g_free (query);
+ query = temp;
+ }
+ }
+
+ /* XXX This is wrong. We need to programmatically construct a
+ * FilterRule, tell it to build code, and pass the resulting
+ * expression string to EAddressbookModel. */
+ rule = filter_rule_new ();
+ e_shell_content_set_search_rule (shell_content, rule);
+ g_object_unref (rule);
+
+ /* Submit the query. */
+ book_shell_content = book_shell_view->priv->book_shell_content;
+ view = e_book_shell_content_get_current_view (book_shell_content);
+ model = e_addressbook_view_get_model (view);
+ e_addressbook_model_set_query (model, query);
+ g_free (query);
+
+ e_book_shell_content_set_preview_contact (book_shell_content, NULL);
+ book_shell_view->priv->preview_index = -1;
+}
+
+void
+e_book_shell_view_editor_weak_notify (EditorUidClosure *closure,
+ GObject *where_the_object_was)
+{
+ GHashTable *hash_table;
+
+ hash_table = closure->view->priv->uid_to_editor;
+ g_hash_table_remove (hash_table, closure->uid);
+}
diff --git a/modules/addressbook/e-book-shell-view-private.h b/modules/addressbook/e-book-shell-view-private.h
new file mode 100644
index 0000000000..b49677680f
--- /dev/null
+++ b/modules/addressbook/e-book-shell-view-private.h
@@ -0,0 +1,131 @@
+/*
+ * e-book-shell-view-private.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_BOOK_SHELL_VIEW_PRIVATE_H
+#define E_BOOK_SHELL_VIEW_PRIVATE_H
+
+#include "e-book-shell-view.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <libebook/e-book.h>
+#include <libedataserver/e-categories.h>
+#include <libedataserver/e-sexp.h>
+#include <libedataserverui/e-source-selector.h>
+
+#include "e-util/gconf-bridge.h"
+#include "shell/e-shell-content.h"
+#include "shell/e-shell-sidebar.h"
+#include "misc/e-popup-action.h"
+
+#include "addressbook/gui/contact-editor/e-contact-editor.h"
+#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
+#include "addressbook/gui/widgets/e-addressbook-view.h"
+#include "addressbook/gui/widgets/e-addressbook-selector.h"
+
+#include "e-book-shell-backend.h"
+#include "e-book-shell-content.h"
+#include "e-book-shell-sidebar.h"
+#include "e-book-shell-view-actions.h"
+
+#define E_BOOK_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_BOOK_SHELL_VIEW, EBookShellViewPrivate))
+
+/* Shorthand, requires a variable named "shell_window". */
+#define ACTION(name) \
+ (E_SHELL_WINDOW_ACTION_##name (shell_window))
+#define ACTION_GROUP(name) \
+ (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window))
+
+/* For use in dispose() methods. */
+#define DISPOSE(obj) \
+ G_STMT_START { \
+ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \
+ } G_STMT_END
+
+/* ETable Specifications */
+#define ETSPEC_FILENAME "e-addressbook-view.etspec"
+
+G_BEGIN_DECLS
+
+typedef struct _EditorUidClosure EditorUidClosure;
+
+struct _EditorUidClosure {
+ GtkWidget *editor;
+ gchar *uid;
+ EBookShellView *view;
+};
+
+/* List these in the order to be displayed.
+ * Positive values are reserved for categories. */
+enum {
+ CONTACT_FILTER_ANY_CATEGORY = -2,
+ CONTACT_FILTER_UNMATCHED = -1
+};
+
+/* List these in the order to be displayed. */
+enum {
+ CONTACT_SEARCH_NAME_CONTAINS,
+ CONTACT_SEARCH_EMAIL_BEGINS_WITH,
+ CONTACT_SEARCH_ANY_FIELD_CONTAINS
+};
+
+struct _EBookShellViewPrivate {
+
+ /* These are just for convenience. */
+ EBookShellBackend *book_shell_backend;
+ EBookShellContent *book_shell_content;
+ EBookShellSidebar *book_shell_sidebar;
+
+ GHashTable *uid_to_view;
+ GHashTable *uid_to_editor;
+
+ gint preview_index;
+};
+
+void e_book_shell_view_private_init
+ (EBookShellView *book_shell_view,
+ EShellViewClass *shell_view_class);
+void e_book_shell_view_private_constructed
+ (EBookShellView *book_shell_view);
+void e_book_shell_view_private_dispose
+ (EBookShellView *book_shell_view);
+void e_book_shell_view_private_finalize
+ (EBookShellView *book_shell_view);
+
+/* Private Utilities */
+
+void e_book_shell_view_actions_init
+ (EBookShellView *book_shell_view);
+void e_book_shell_view_execute_search
+ (EBookShellView *book_shell_view);
+void e_book_shell_view_editor_weak_notify
+ (EditorUidClosure *closure,
+ GObject *where_the_object_was);
+void e_book_shell_view_update_search_filter
+ (EBookShellView *book_shell_view);
+
+G_END_DECLS
+
+#endif /* E_BOOK_SHELL_VIEW_PRIVATE_H */
diff --git a/modules/addressbook/e-book-shell-view.c b/modules/addressbook/e-book-shell-view.c
new file mode 100644
index 0000000000..ea48bb534c
--- /dev/null
+++ b/modules/addressbook/e-book-shell-view.c
@@ -0,0 +1,318 @@
+/*
+ * e-book-shell-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-shell-view-private.h"
+
+static gpointer parent_class;
+static GType book_shell_view_type;
+
+static void
+book_shell_view_source_list_changed_cb (EBookShellView *book_shell_view,
+ ESourceList *source_list)
+{
+ EBookShellViewPrivate *priv = book_shell_view->priv;
+ EBookShellContent *book_shell_content;
+ EShellView *shell_view;
+ GList *keys, *iter;
+
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ book_shell_content = book_shell_view->priv->book_shell_content;
+
+ keys = g_hash_table_get_keys (priv->uid_to_view);
+ for (iter = keys; iter != NULL; iter = iter->next) {
+ gchar *uid = iter->data;
+ EAddressbookView *view;
+
+ /* If the source still exists, move on. */
+ if (e_source_list_peek_source_by_uid (source_list, uid))
+ continue;
+
+ /* Remove the view for the deleted source. */
+ view = g_hash_table_lookup (priv->uid_to_view, uid);
+ e_book_shell_content_remove_view (book_shell_content, view);
+ g_hash_table_remove (priv->uid_to_view, uid);
+ }
+ g_list_free (keys);
+
+ keys = g_hash_table_get_keys (priv->uid_to_editor);
+ for (iter = keys; iter != NULL; iter = iter->next) {
+ gchar *uid = iter->data;
+ EditorUidClosure *closure;
+
+ /* If the source still exists, move on. */
+ if (e_source_list_peek_source_by_uid (source_list, uid))
+ continue;
+
+ /* Remove the editor for the deleted source. */
+ closure = g_hash_table_lookup (priv->uid_to_editor, uid);
+ g_object_weak_unref (
+ G_OBJECT (closure->editor), (GWeakNotify)
+ e_book_shell_view_editor_weak_notify, closure);
+ gtk_widget_destroy (closure->editor);
+ g_hash_table_remove (priv->uid_to_editor, uid);
+ }
+ g_list_free (keys);
+
+ e_shell_view_update_actions (shell_view);
+}
+
+static void
+book_shell_view_dispose (GObject *object)
+{
+ EBookShellView *book_shell_view;
+
+ book_shell_view = E_BOOK_SHELL_VIEW (object);
+ e_book_shell_view_private_dispose (book_shell_view);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+book_shell_view_finalize (GObject *object)
+{
+ EBookShellView *book_shell_view;
+
+ book_shell_view = E_BOOK_SHELL_VIEW (object);
+ e_book_shell_view_private_finalize (book_shell_view);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+book_shell_view_constructed (GObject *object)
+{
+ EBookShellView *book_shell_view;
+ EBookShellBackend *book_shell_backend;
+ ESourceList *source_list;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ book_shell_view = E_BOOK_SHELL_VIEW (object);
+ e_book_shell_view_private_constructed (book_shell_view);
+
+ book_shell_backend = book_shell_view->priv->book_shell_backend;
+ source_list = e_book_shell_backend_get_source_list (book_shell_backend);
+
+ g_signal_connect_swapped (
+ source_list, "changed",
+ G_CALLBACK (book_shell_view_source_list_changed_cb),
+ book_shell_view);
+}
+
+static void
+book_shell_view_update_actions (EShellView *shell_view)
+{
+ EBookShellViewPrivate *priv;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ GtkAction *action;
+ const gchar *label;
+ gboolean sensitive;
+ guint32 state;
+
+ /* Be descriptive. */
+ gboolean any_contacts_selected;
+ gboolean has_primary_source;
+ gboolean multiple_contacts_selected;
+ gboolean primary_source_is_system;
+ gboolean single_contact_selected;
+ gboolean selection_is_contact_list;
+ gboolean selection_has_email;
+ gboolean source_is_busy;
+ gboolean source_is_editable;
+ gboolean source_is_empty;
+
+ priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ state = e_shell_content_check_state (shell_content);
+
+ single_contact_selected =
+ (state & E_BOOK_SHELL_CONTENT_SELECTION_SINGLE);
+ multiple_contacts_selected =
+ (state & E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE);
+ selection_has_email =
+ (state & E_BOOK_SHELL_CONTENT_SELECTION_HAS_EMAIL);
+ selection_is_contact_list =
+ (state & E_BOOK_SHELL_CONTENT_SELECTION_IS_CONTACT_LIST);
+ source_is_busy =
+ (state & E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY);
+ source_is_editable =
+ (state & E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE);
+ source_is_empty =
+ (state & E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY);
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ state = e_shell_sidebar_check_state (shell_sidebar);
+
+ has_primary_source =
+ (state & E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE);
+ primary_source_is_system =
+ (state & E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM);
+
+ any_contacts_selected =
+ (single_contact_selected || multiple_contacts_selected);
+
+ action = ACTION (ADDRESS_BOOK_DELETE);
+ sensitive = has_primary_source && !primary_source_is_system;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (ADDRESS_BOOK_RENAME);
+ sensitive = has_primary_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (ADDRESS_BOOK_STOP);
+ sensitive = source_is_busy;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_CLIPBOARD_COPY);
+ sensitive = any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_CLIPBOARD_CUT);
+ sensitive = source_is_editable && any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_CLIPBOARD_PASTE);
+ sensitive = source_is_editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_COPY);
+ sensitive = any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_DELETE);
+ sensitive = source_is_editable && any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_FORWARD);
+ sensitive = any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+ if (multiple_contacts_selected)
+ label = _("_Forward Contacts");
+ else
+ label = _("_Forward Contact");
+ g_object_set (action, "label", label, NULL);
+
+ action = ACTION (CONTACT_MOVE);
+ sensitive = source_is_editable && any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_OPEN);
+ sensitive = any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_PRINT);
+ sensitive = any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_PRINT_PREVIEW);
+ sensitive = any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_SAVE_AS);
+ sensitive = any_contacts_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_SELECT_ALL);
+ sensitive = !(source_is_empty);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CONTACT_SEND_MESSAGE);
+ sensitive = any_contacts_selected && selection_has_email;
+ gtk_action_set_sensitive (action, sensitive);
+ if (multiple_contacts_selected)
+ label = _("_Send Message to Contacts");
+ else if (selection_is_contact_list)
+ label = _("_Send Message to List");
+ else
+ label = _("_Send Message to Contact");
+ g_object_set (action, "label", label, NULL);
+}
+
+static void
+book_shell_view_class_init (EBookShellViewClass *class)
+{
+ GObjectClass *object_class;
+ EShellViewClass *shell_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EBookShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = book_shell_view_dispose;
+ object_class->finalize = book_shell_view_finalize;
+ object_class->constructed = book_shell_view_constructed;
+
+ shell_view_class = E_SHELL_VIEW_CLASS (class);
+ shell_view_class->label = _("Contacts");
+ shell_view_class->icon_name = "x-office-address-book";
+ shell_view_class->ui_definition = "evolution-contacts.ui";
+ shell_view_class->ui_manager_id = "org.gnome.evolution.contacts";
+ shell_view_class->search_options = "/contact-search-options";
+ shell_view_class->search_rules = "addresstypes.xml";
+ shell_view_class->new_shell_content = e_book_shell_content_new;
+ shell_view_class->new_shell_sidebar = e_book_shell_sidebar_new;
+ shell_view_class->update_actions = book_shell_view_update_actions;
+}
+
+static void
+book_shell_view_init (EBookShellView *book_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ book_shell_view->priv =
+ E_BOOK_SHELL_VIEW_GET_PRIVATE (book_shell_view);
+
+ e_book_shell_view_private_init (book_shell_view, shell_view_class);
+}
+
+GType
+e_book_shell_view_get_type (void)
+{
+ return book_shell_view_type;
+}
+
+void
+e_book_shell_view_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EBookShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) book_shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EBookShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) book_shell_view_init,
+ NULL /* value_table */
+ };
+
+ book_shell_view_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_VIEW,
+ "EBookShellView", &type_info, 0);
+}
diff --git a/modules/addressbook/e-book-shell-view.h b/modules/addressbook/e-book-shell-view.h
new file mode 100644
index 0000000000..33a0c8a75d
--- /dev/null
+++ b/modules/addressbook/e-book-shell-view.h
@@ -0,0 +1,66 @@
+/*
+ * e-book-shell-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_BOOK_SHELL_VIEW_H
+#define E_BOOK_SHELL_VIEW_H
+
+#include <shell/e-shell-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_SHELL_VIEW \
+ (e_book_shell_view_get_type ())
+#define E_BOOK_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_BOOK_SHELL_VIEW, EBookShellView))
+#define E_BOOK_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_BOOK_SHELL_VIEW, EBookShellViewClass))
+#define E_IS_BOOK_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_BOOK_SHELL_VIEW))
+#define E_IS_BOOK_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_BOOK_SHELL_VIEW))
+#define E_BOOK_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_BOOK_SHELL_VIEW, EBookShellViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookShellView EBookShellView;
+typedef struct _EBookShellViewClass EBookShellViewClass;
+typedef struct _EBookShellViewPrivate EBookShellViewPrivate;
+
+struct _EBookShellView {
+ EShellView parent;
+ EBookShellViewPrivate *priv;
+};
+
+struct _EBookShellViewClass {
+ EShellViewClass parent_class;
+};
+
+GType e_book_shell_view_get_type (void);
+void e_book_shell_view_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_BOOK_SHELL_VIEW_H */
diff --git a/modules/addressbook/eab-composer-util.c b/modules/addressbook/eab-composer-util.c
new file mode 100644
index 0000000000..6d45f13a94
--- /dev/null
+++ b/modules/addressbook/eab-composer-util.c
@@ -0,0 +1,197 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "eab-composer-util.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libebook/e-contact.h>
+#include <libebook/e-destination.h>
+
+#include "composer/e-msg-composer.h"
+#include "addressbook/util/eab-book-util.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
+
+void
+eab_send_as_to (GList *destinations)
+{
+ EMsgComposer *composer;
+ EComposerHeaderTable *table;
+ GPtrArray *to_array;
+ GPtrArray *bcc_array;
+
+ union {
+ gpointer *pdata;
+ EDestination **destinations;
+ } convert;
+
+ if (destinations == NULL)
+ return;
+
+ composer = e_msg_composer_new ();
+ table = e_msg_composer_get_header_table (composer);
+
+ to_array = g_ptr_array_new ();
+ bcc_array = g_ptr_array_new ();
+
+ /* Sort contacts into "To" and "Bcc" destinations. */
+ while (destinations != NULL) {
+ EDestination *destination = destinations->data;
+
+ if (e_destination_is_evolution_list (destination)) {
+ if (e_destination_list_show_addresses (destination))
+ g_ptr_array_add (to_array, destination);
+ else
+ g_ptr_array_add (bcc_array, destination);
+ } else
+ g_ptr_array_add (to_array, destination);
+
+ destinations = g_list_next (destinations);
+ }
+
+ /* Add sentinels to each array. */
+ g_ptr_array_add (to_array, NULL);
+ g_ptr_array_add (bcc_array, NULL);
+
+ /* XXX Acrobatics like this make me question whether NULL-terminated
+ * arrays are really the best argument type for passing a list of
+ * destinations to the header table. */
+
+ /* Add "To" destinations. */
+ convert.pdata = to_array->pdata;
+ e_composer_header_table_set_destinations_to (
+ table, convert.destinations);
+ g_ptr_array_free (to_array, FALSE);
+ e_destination_freev (convert.destinations);
+
+ /* Add "Bcc" destinations. */
+ convert.pdata = bcc_array->pdata;
+ e_composer_header_table_set_destinations_bcc (
+ table, convert.destinations);
+ g_ptr_array_free (bcc_array, FALSE);
+ e_destination_freev (convert.destinations);
+
+ gtk_widget_show (GTK_WIDGET (composer));
+}
+
+static const gchar *
+get_email (EContact *contact, EContactField field_id, gchar **to_free)
+{
+ gchar *name = NULL, *mail = NULL;
+ const gchar *value = e_contact_get_const (contact, field_id);
+
+ *to_free = NULL;
+
+ if (eab_parse_qp_email (value, &name, &mail)) {
+ *to_free = g_strdup_printf ("%s <%s>", name, mail);
+ value = *to_free;
+ }
+
+ g_free (name);
+ g_free (mail);
+
+ return value;
+}
+
+void
+eab_send_as_attachment (GList *destinations)
+{
+ EMsgComposer *composer;
+ EComposerHeaderTable *table;
+ CamelMimePart *attachment;
+ GList *contacts, *iter;
+ gchar *data;
+
+ if (destinations == NULL)
+ return;
+
+ composer = e_msg_composer_new ();
+ table = e_msg_composer_get_header_table (composer);
+
+ attachment = camel_mime_part_new ();
+
+ contacts = g_list_copy (destinations);
+ for (iter = contacts; iter != NULL; iter = iter->next)
+ iter->data = e_destination_get_contact (iter->data);
+ data = eab_contact_list_to_string (contacts);
+ g_list_free (contacts);
+
+ camel_mime_part_set_content (
+ attachment, data, strlen (data), "text/x-vcard");
+
+ if (destinations->next != NULL)
+ camel_mime_part_set_description (
+ attachment, _("Multiple vCards"));
+ else {
+ EContact *contact;
+ const gchar *file_as;
+ gchar *description;
+
+ contact = e_destination_get_contact (destinations->data);
+ file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ description = g_strdup_printf (_("vCard for %s"), file_as);
+ camel_mime_part_set_description (attachment, description);
+ g_free (description);
+ }
+
+ camel_mime_part_set_disposition (attachment, "attachment");
+
+ e_msg_composer_attach (composer, attachment);
+ camel_object_unref (attachment);
+
+ if (destinations->next != NULL)
+ e_composer_header_table_set_subject (
+ table, _("Contact information"));
+ else {
+ EContact *contact;
+ gchar *tempstr;
+ const gchar *tempstr2;
+ gchar *tempfree = NULL;
+
+ contact = e_destination_get_contact (destinations->data);
+ tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (!tempstr2 || !*tempstr2)
+ tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+ if (!tempstr2 || !*tempstr2)
+ tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG);
+ if (!tempstr2 || !*tempstr2) {
+ g_free (tempfree);
+ tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree);
+ }
+ if (!tempstr2 || !*tempstr2) {
+ g_free (tempfree);
+ tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree);
+ }
+ if (!tempstr2 || !*tempstr2) {
+ g_free (tempfree);
+ tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree);
+ }
+
+ if (!tempstr2 || !*tempstr2)
+ tempstr = g_strdup_printf (_("Contact information"));
+ else
+ tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2);
+
+ e_composer_header_table_set_subject (table, tempstr);
+
+ g_free (tempstr);
+ g_free (tempfree);
+ }
+
+ gtk_widget_show (GTK_WIDGET (composer));
+}
diff --git a/modules/addressbook/eab-composer-util.h b/modules/addressbook/eab-composer-util.h
new file mode 100644
index 0000000000..4aec23074d
--- /dev/null
+++ b/modules/addressbook/eab-composer-util.h
@@ -0,0 +1,31 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef EAB_COMPOSER_UTIL_H
+#define EAB_COMPOSER_UTIL_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void eab_send_as_to (GList *destinations);
+void eab_send_as_attachment (GList *destinations);
+
+G_END_DECLS
+
+#endif /* EAB_COMPOSER_UTIL_H */
diff --git a/shell/evolution-component.c b/modules/addressbook/evolution-module-addressbook.c
index 49824c9545..73b3634b91 100644
--- a/shell/evolution-component.c
+++ b/modules/addressbook/evolution-module-addressbook.c
@@ -1,4 +1,6 @@
/*
+ * evolution-module-addressbook.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,36 +15,35 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-component.h"
+#include "e-book-config-hook.h"
-#define PARENT_TYPE bonobo_object_get_type ()
+#include "e-book-shell-backend.h"
+#include "e-book-shell-content.h"
+#include "e-book-shell-sidebar.h"
+#include "e-book-shell-view.h"
-static BonoboObjectClass *parent_class = NULL;
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
-/* Evolution.Component */
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
-/* Initialization */
+ e_book_config_hook_register_type (type_module);
-static void
-evolution_component_class_init (EvolutionComponentClass *klass)
-{
- parent_class = g_type_class_peek_parent (klass);
+ e_book_shell_backend_register_type (type_module);
+ e_book_shell_content_register_type (type_module);
+ e_book_shell_sidebar_register_type (type_module);
+ e_book_shell_view_register_type (type_module);
}
-static void
-evolution_component_init(EvolutionComponent *emf, EvolutionComponentClass *klass)
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
{
}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionComponent, GNOME_Evolution_Component, PARENT_TYPE, evolution_component)
diff --git a/addressbook/gui/component/ldap-config.glade b/modules/addressbook/ldap-config.glade
index f87cf84b14..f87cf84b14 100644
--- a/addressbook/gui/component/ldap-config.glade
+++ b/modules/addressbook/ldap-config.glade
diff --git a/addressbook/gui/component/openldap-extract.h b/modules/addressbook/openldap-extract.h
index 29175fb494..29175fb494 100644
--- a/addressbook/gui/component/openldap-extract.h
+++ b/modules/addressbook/openldap-extract.h
diff --git a/modules/calendar/Makefile.am b/modules/calendar/Makefile.am
new file mode 100644
index 0000000000..490d42a05e
--- /dev/null
+++ b/modules/calendar/Makefile.am
@@ -0,0 +1,84 @@
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"calendar-modules\" \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
+ $(EVOLUTION_CALENDAR_CFLAGS)
+
+module_LTLIBRARIES = \
+ libevolution-module-calendar.la
+
+libevolution_module_calendar_la_SOURCES = \
+ evolution-module-calendar.c \
+ e-cal-attachment-handler.c \
+ e-cal-attachment-handler.h \
+ e-cal-config-hook.c \
+ e-cal-config-hook.h \
+ e-cal-event-hook.c \
+ e-cal-event-hook.h \
+ e-cal-shell-backend.c \
+ e-cal-shell-backend.h \
+ e-cal-shell-content.c \
+ e-cal-shell-content.h \
+ e-cal-shell-migrate.c \
+ e-cal-shell-migrate.h \
+ e-cal-shell-settings.c \
+ e-cal-shell-settings.h \
+ e-cal-shell-sidebar.c \
+ e-cal-shell-sidebar.h \
+ e-cal-shell-view.c \
+ e-cal-shell-view.h \
+ e-cal-shell-view-actions.c \
+ e-cal-shell-view-actions.h \
+ e-cal-shell-view-memopad.c \
+ e-cal-shell-view-private.c \
+ e-cal-shell-view-private.h \
+ e-cal-shell-view-taskpad.c \
+ e-memo-shell-backend.c \
+ e-memo-shell-backend.h \
+ e-memo-shell-content.c \
+ e-memo-shell-content.h \
+ e-memo-shell-migrate.c \
+ e-memo-shell-migrate.h \
+ e-memo-shell-sidebar.c \
+ e-memo-shell-sidebar.h \
+ e-memo-shell-view.c \
+ e-memo-shell-view.h \
+ e-memo-shell-view-actions.c \
+ e-memo-shell-view-actions.h \
+ e-memo-shell-view-private.c \
+ e-memo-shell-view-private.h \
+ e-task-shell-backend.c \
+ e-task-shell-backend.h \
+ e-task-shell-content.c \
+ e-task-shell-content.h \
+ e-task-shell-migrate.c \
+ e-task-shell-migrate.h \
+ e-task-shell-sidebar.c \
+ e-task-shell-sidebar.h \
+ e-task-shell-view.c \
+ e-task-shell-view.h \
+ e-task-shell-view-actions.c \
+ e-task-shell-view-actions.h \
+ e-task-shell-view-private.c \
+ e-task-shell-view-private.h
+
+libevolution_module_calendar_la_LIBADD = \
+ $(top_builddir)/shell/libeshell.la \
+ $(top_builddir)/calendar/gui/libevolution-calendar.la \
+ $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/filter/libfilter.la \
+ $(top_builddir)/widgets/menus/libmenus.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/widgets/table/libetable.la \
+ $(CAMEL_LIBS) \
+ $(EVOLUTION_CALENDAR_LIBS)
+
+libevolution_module_calendar_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/calendar/gui/e-attachment-handler-calendar.c b/modules/calendar/e-cal-attachment-handler.c
index 601d1f5e3c..dd95cc5d08 100644
--- a/calendar/gui/e-attachment-handler-calendar.c
+++ b/modules/calendar/e-cal-attachment-handler.c
@@ -1,5 +1,5 @@
/*
- * e-attachment-handler-calendar.c
+ * e-cal-attachment-handler.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,7 @@
*
*/
-#include "e-attachment-handler-calendar.h"
+#include "e-cal-attachment-handler.h"
#include <glib/gi18n.h>
#include <libical/ical.h>
@@ -29,13 +29,13 @@
#include "calendar/common/authentication.h"
-#define E_ATTACHMENT_HANDLER_CALENDAR_GET_PRIVATE(obj) \
+#define E_CAL_ATTACHMENT_HANDLER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_CALENDAR, EAttachmentHandlerCalendarPrivate))
+ ((obj), E_TYPE_CAL_ATTACHMENT_HANDLER, ECalAttachmentHandlerPrivate))
typedef struct _ImportContext ImportContext;
-struct _EAttachmentHandlerCalendarPrivate {
+struct _ECalAttachmentHandlerPrivate {
gint placeholder;
};
@@ -46,6 +46,7 @@ struct _ImportContext {
};
static gpointer parent_class;
+static GType cal_attachment_handler_type;
static const gchar *ui =
"<ui>"
@@ -388,7 +389,7 @@ static GtkActionEntry standard_entries[] = {
};
static void
-attachment_handler_calendar_update_actions (EAttachmentView *view)
+cal_attachment_handler_update_actions (EAttachmentView *view)
{
EAttachment *attachment;
GtkAction *action;
@@ -431,7 +432,7 @@ exit:
}
static void
-attachment_handler_calendar_constructed (GObject *object)
+cal_attachment_handler_constructed (GObject *object)
{
EAttachmentHandler *handler;
EAttachmentView *view;
@@ -461,51 +462,51 @@ attachment_handler_calendar_constructed (GObject *object)
g_signal_connect (
view, "update_actions",
- G_CALLBACK (attachment_handler_calendar_update_actions),
+ G_CALLBACK (cal_attachment_handler_update_actions),
NULL);
}
static void
-attachment_handler_calendar_class_init (EAttachmentHandlerCalendarClass *class)
+cal_attachment_handler_class_init (ECalAttachmentHandlerClass *class)
{
GObjectClass *object_class;
parent_class = g_type_class_peek_parent (class);
- g_type_class_add_private (class, sizeof (EAttachmentHandlerCalendarPrivate));
+ g_type_class_add_private (class, sizeof (ECalAttachmentHandlerPrivate));
object_class = G_OBJECT_CLASS (class);
- object_class->constructed = attachment_handler_calendar_constructed;
+ object_class->constructed = cal_attachment_handler_constructed;
}
static void
-attachment_handler_calendar_init (EAttachmentHandlerCalendar *handler)
+cal_attachment_handler_init (ECalAttachmentHandler *handler)
{
- handler->priv = E_ATTACHMENT_HANDLER_CALENDAR_GET_PRIVATE (handler);
+ handler->priv = E_CAL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
}
GType
-e_attachment_handler_calendar_get_type (void)
+e_cal_attachment_handler_get_type (void)
{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EAttachmentHandlerCalendarClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) attachment_handler_calendar_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EAttachmentHandlerCalendar),
- 0, /* n_preallocs */
- (GInstanceInitFunc) attachment_handler_calendar_init,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- E_TYPE_ATTACHMENT_HANDLER,
- "EAttachmentHandlerCalendar", &type_info, 0);
- }
+ return cal_attachment_handler_type;
+}
- return type;
+void
+e_cal_attachment_handler_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (ECalAttachmentHandlerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_attachment_handler_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalAttachmentHandler),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) cal_attachment_handler_init,
+ NULL /* value_table */
+ };
+
+ cal_attachment_handler_type = g_type_module_register_type (
+ type_module, E_TYPE_ATTACHMENT_HANDLER,
+ "ECalAttachmentHandler", &type_info, 0);
}
diff --git a/modules/calendar/e-cal-attachment-handler.h b/modules/calendar/e-cal-attachment-handler.h
new file mode 100644
index 0000000000..b792fbf765
--- /dev/null
+++ b/modules/calendar/e-cal-attachment-handler.h
@@ -0,0 +1,67 @@
+/*
+ * e-cal-attachment-handler.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_ATTACHMENT_HANDLER_H
+#define E_CAL_ATTACHMENT_HANDLER_H
+
+#include <misc/e-attachment-handler.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CAL_ATTACHMENT_HANDLER \
+ (e_cal_attachment_handler_get_type ())
+#define E_CAL_ATTACHMENT_HANDLER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_ATTACHMENT_HANDLER, ECalAttachmentHandler))
+#define E_CAL_ATTACHMENT_HANDLER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_ATTACHMENT_HANDLER, ECalAttachmentHandlerClass))
+#define E_IS_CAL_ATTACHMENT_HANDLER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_ATTACHMENT_HANDLER))
+#define E_IS_CAL_ATTACHMENT_HANDLER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_ATTACHMENT_HANDLER))
+#define E_CAL_ATTACHMENT_HANDLER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_ATTACHMENT_HANDLER, ECalAttachmentHandlerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalAttachmentHandler ECalAttachmentHandler;
+typedef struct _ECalAttachmentHandlerClass ECalAttachmentHandlerClass;
+typedef struct _ECalAttachmentHandlerPrivate ECalAttachmentHandlerPrivate;
+
+struct _ECalAttachmentHandler {
+ EAttachmentHandler parent;
+ ECalAttachmentHandlerPrivate *priv;
+};
+
+struct _ECalAttachmentHandlerClass {
+ EAttachmentHandlerClass parent_class;
+};
+
+GType e_cal_attachment_handler_get_type (void);
+void e_cal_attachment_handler_register_type
+ (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_CAL_ATTACHMENT_HANDLER_H */
diff --git a/modules/calendar/e-cal-config-hook.c b/modules/calendar/e-cal-config-hook.c
new file mode 100644
index 0000000000..4a0522460c
--- /dev/null
+++ b/modules/calendar/e-cal-config-hook.c
@@ -0,0 +1,68 @@
+/*
+ * e-cal-config-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-config-hook.h"
+
+#include "e-util/e-config.h"
+#include "calendar/gui/e-cal-config.h"
+
+static const EConfigHookTargetMask no_masks[] = {
+ { NULL }
+};
+
+static const EConfigHookTargetMap targets[] = {
+ { "source", EC_CONFIG_TARGET_SOURCE, no_masks },
+ { "prefs", EC_CONFIG_TARGET_PREFS, no_masks },
+ { NULL }
+};
+
+static void
+cal_config_hook_class_init (EPluginHookClass *class)
+{
+ gint ii;
+
+ class->id = "org.gnome.evolution.calendar.config:1.0";
+
+ for (ii = 0; targets[ii].type != NULL; ii++)
+ e_config_hook_class_add_target_map (
+ (EConfigHookClass *) class, &targets[ii]);
+}
+
+void
+e_cal_config_hook_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EConfigHookClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_config_hook_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EConfigHook),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ NULL /* value_table */
+ };
+
+ g_type_module_register_type (
+ type_module, e_config_hook_get_type (),
+ "ECalConfigHook", &type_info, 0);
+}
diff --git a/calendar/gui/control-factory.h b/modules/calendar/e-cal-config-hook.h
index c79d70b5ba..a22ec56bbc 100644
--- a/calendar/gui/control-factory.h
+++ b/modules/calendar/e-cal-config-hook.h
@@ -1,4 +1,5 @@
/*
+ * e-cal-config-hook.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,18 +15,19 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _CONTROL_FACTORY_H_
-#define _CONTROL_FACTORY_H_
+#ifndef E_CAL_CONFIG_HOOK_H
+#define E_CAL_CONFIG_HOOK_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
-#include <bonobo/bonobo-control.h>
+void e_cal_config_hook_register_type (GTypeModule *type_module);
-BonoboControl *control_factory_new_control (void);
+G_END_DECLS
-#endif /* _CONTROL_FACTORY_H_ */
+#endif /* E_CAL_CONFIG_HOOK_H */
diff --git a/modules/calendar/e-cal-event-hook.c b/modules/calendar/e-cal-event-hook.c
new file mode 100644
index 0000000000..b263727107
--- /dev/null
+++ b/modules/calendar/e-cal-event-hook.c
@@ -0,0 +1,72 @@
+/*
+ * e-cal-event-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-event-hook.h"
+
+#include "e-util/e-event.h"
+#include "calendar/gui/e-cal-event.h"
+
+static const EEventHookTargetMask masks[] = {
+ { "migration", E_CAL_EVENT_MODULE_MIGRATION },
+ { NULL }
+};
+
+static const EEventHookTargetMap targets[] = {
+ { "module", E_CAL_EVENT_TARGET_BACKEND, masks },
+ { NULL }
+};
+
+static void
+cal_event_hook_class_init (EPluginHookClass *class)
+{
+ EEventHookClass *event_hook_class;
+ gint ii;
+
+ event_hook_class = (EEventHookClass *) class;
+ event_hook_class->event = (EEvent *) e_cal_event_peek ();
+
+ class->id = "org.gnome.evolution.calendar.events:1.0";
+
+ for (ii = 0; targets[ii].type != NULL; ii++)
+ e_event_hook_class_add_target_map (
+ (EEventHookClass *) class, &targets[ii]);
+}
+
+void
+e_cal_event_hook_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EEventHookClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_event_hook_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EEventHook),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ NULL /* value_table */
+ };
+
+ g_type_module_register_type (
+ type_module, e_event_hook_get_type (),
+ "ECalEventHook", &type_info, 0);
+}
diff --git a/modules/calendar/e-cal-event-hook.h b/modules/calendar/e-cal-event-hook.h
new file mode 100644
index 0000000000..9dde31f900
--- /dev/null
+++ b/modules/calendar/e-cal-event-hook.h
@@ -0,0 +1,33 @@
+/*
+ * e-cal-event-hook.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_EVENT_HOOK_H
+#define E_CAL_EVENT_HOOK_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_cal_event_hook_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_CAL_EVENT_HOOK_H */
diff --git a/modules/calendar/e-cal-shell-backend.c b/modules/calendar/e-cal-shell-backend.c
new file mode 100644
index 0000000000..5149574323
--- /dev/null
+++ b/modules/calendar/e-cal-shell-backend.c
@@ -0,0 +1,854 @@
+/*
+ * e-cal-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-backend.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libecal/e-cal.h>
+#include <libecal/e-cal-time-util.h>
+#include <libedataserver/e-url.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+
+#include "e-util/e-import.h"
+#include "shell/e-shell.h"
+#include "shell/e-shell-backend.h"
+#include "shell/e-shell-window.h"
+#include "widgets/misc/e-preferences-window.h"
+
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/dialogs/cal-prefs-dialog.h"
+#include "calendar/gui/dialogs/calendar-setup.h"
+#include "calendar/gui/dialogs/event-editor.h"
+#include "calendar/importers/evolution-calendar-importer.h"
+
+#include "e-cal-shell-migrate.h"
+#include "e-cal-shell-settings.h"
+#include "e-cal-shell-view.h"
+
+#define E_CAL_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CAL_SHELL_BACKEND, ECalShellBackendPrivate))
+
+#define CONTACTS_BASE_URI "contacts://"
+#define WEATHER_BASE_URI "weather://"
+#define WEB_BASE_URI "webcal://"
+#define PERSONAL_RELATIVE_URI "system"
+
+struct _ECalShellBackendPrivate {
+ ESourceList *source_list;
+};
+
+enum {
+ PROP_0,
+ PROP_SOURCE_LIST
+};
+
+static gpointer parent_class;
+static GType cal_shell_backend_type;
+
+static void
+cal_shell_backend_ensure_sources (EShellBackend *shell_backend)
+{
+ /* XXX This is basically the same algorithm across all backends.
+ * Maybe we could somehow integrate this into EShellBackend? */
+
+ ECalShellBackendPrivate *priv;
+ ESourceGroup *on_this_computer;
+ ESourceGroup *on_the_web;
+ ESourceGroup *contacts;
+ ESourceGroup *weather;
+ ESource *birthdays;
+ ESource *personal;
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GSList *groups, *iter;
+ const gchar *data_dir;
+ const gchar *name;
+ gchar *base_uri;
+ gchar *filename;
+ gchar *property;
+
+ on_this_computer = NULL;
+ on_the_web = NULL;
+ contacts = NULL;
+ weather = NULL;
+ birthdays = NULL;
+ personal = NULL;
+
+ priv = E_CAL_SHELL_BACKEND_GET_PRIVATE (shell_backend);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ if (!e_cal_get_sources (&priv->source_list, E_CAL_SOURCE_TYPE_EVENT, NULL)) {
+ g_warning ("Could not get calendar sources from GConf!");
+ return;
+ }
+
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ filename = g_build_filename (data_dir, "local", NULL);
+ base_uri = g_filename_to_uri (filename, NULL, NULL);
+ g_free (filename);
+
+ groups = e_source_list_peek_groups (priv->source_list);
+ for (iter = groups; iter != NULL; iter = iter->next) {
+ ESourceGroup *source_group = iter->data;
+ const gchar *group_base_uri;
+
+ group_base_uri = e_source_group_peek_base_uri (source_group);
+
+ /* Compare only "file://" part. if the user's home
+ * changes, we do not want to create another group. */
+ if (on_this_computer == NULL &&
+ strncmp (base_uri, group_base_uri, 7) == 0)
+ on_this_computer = source_group;
+
+ else if (on_the_web == NULL &&
+ strcmp (WEB_BASE_URI, group_base_uri) == 0)
+ on_the_web = source_group;
+
+ else if (contacts == NULL &&
+ strcmp (CONTACTS_BASE_URI, group_base_uri) == 0)
+ contacts = source_group;
+
+ else if (weather == NULL &&
+ strcmp (WEATHER_BASE_URI, group_base_uri) == 0)
+ weather = source_group;
+ }
+
+ name = _("On This Computer");
+
+ if (on_this_computer != NULL) {
+ GSList *sources;
+ const gchar *group_base_uri;
+
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (on_this_computer, name);
+
+ sources = e_source_group_peek_sources (on_this_computer);
+ group_base_uri = e_source_group_peek_base_uri (on_this_computer);
+
+ /* Make sure this group includes a "Personal" source. */
+ for (iter = sources; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+
+ if (strcmp (PERSONAL_RELATIVE_URI, relative_uri) != 0)
+ continue;
+
+ personal = source;
+ break;
+ }
+
+ /* Make sure we have the correct base URI. This can
+ * change when the user's home directory changes. */
+ if (strcmp (base_uri, group_base_uri) != 0) {
+ e_source_group_set_base_uri (
+ on_this_computer, base_uri);
+
+ /* XXX We shouldn't need this sync call here as
+ * set_base_uri() results in synching to GConf,
+ * but that happens in an idle loop and too late
+ * to prevent the user from seeing a "Cannot
+ * Open ... because of invalid URI" error. */
+ e_source_list_sync (priv->source_list, NULL);
+ }
+
+ } else {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, base_uri);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ }
+
+ name = _("Personal");
+
+ if (personal == NULL) {
+ ESource *source;
+ GSList *selected;
+ gchar *primary;
+
+ source = e_source_new (name, PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (on_this_computer, source, -1);
+ g_object_unref (source);
+
+ primary = e_shell_settings_get_string (
+ shell_settings, "cal-primary-calendar");
+
+ selected = calendar_config_get_calendars_selected ();
+
+ if (primary == NULL && selected == NULL) {
+ const gchar *uid;
+
+ uid = e_source_peek_uid (source);
+ selected = g_slist_prepend (NULL, g_strdup (uid));
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-calendar", uid);
+ calendar_config_set_calendars_selected (selected);
+ }
+
+ g_slist_foreach (selected, (GFunc) g_free, NULL);
+ g_slist_free (selected);
+ g_free (primary);
+ } else {
+ /* Force the source name to the current locale. */
+ e_source_set_name (personal, name);
+ }
+
+ name = _("On The Web");
+
+ if (on_the_web == NULL) {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, WEB_BASE_URI);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ } else {
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (on_the_web, name);
+ }
+
+ name = _("Contacts");
+
+ if (contacts != NULL) {
+ GSList *sources;
+
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (contacts, name);
+
+ sources = e_source_group_peek_sources (contacts);
+
+ if (sources != NULL) {
+ GSList *trash;
+
+ /* There is only one source under Contacts. */
+ birthdays = E_SOURCE (sources->data);
+ sources = g_slist_next (sources);
+
+ /* Delete any other sources in this group.
+ * Earlier versions allowed you to create
+ * additional sources under Contacts. */
+ trash = g_slist_copy (sources);
+ while (trash != NULL) {
+ ESource *source = trash->data;
+ e_source_group_remove_source (contacts, source);
+ trash = g_slist_delete_link (trash, trash);
+ }
+
+ }
+ } else {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, CONTACTS_BASE_URI);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+
+ /* This is now a borrowed reference. */
+ contacts = source_group;
+ }
+
+ /* XXX e_source_group_get_property() returns a newly-allocated
+ * string when it could just as easily return a const string.
+ * Unfortunately, fixing that would break the API. */
+ property = e_source_group_get_property (contacts, "create_source");
+ if (property == NULL)
+ e_source_group_set_property (contacts, "create_source", "no");
+ g_free (property);
+
+ name = _("Birthdays & Anniversaries");
+
+ if (birthdays == NULL) {
+ ESource *source;
+ const gchar *name;
+
+ name = _("Birthdays & Anniversaries");
+ source = e_source_new (name, "/");
+ e_source_group_add_source (contacts, source, -1);
+ g_object_unref (source);
+
+ /* This is now a borrowed reference. */
+ birthdays = source;
+ } else {
+ /* Force the source name to the current locale. */
+ e_source_set_name (birthdays, name);
+ }
+
+ if (e_source_get_property (birthdays, "delete") == NULL)
+ e_source_set_property (birthdays, "delete", "no");
+
+ if (e_source_peek_color_spec (birthdays) == NULL)
+ e_source_set_color_spec (birthdays, "#DDBECE");
+
+ name = _("Weather");
+
+ if (weather == NULL) {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, WEATHER_BASE_URI);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ } else {
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (weather, name);
+ }
+
+ g_free (base_uri);
+}
+
+static void
+cal_shell_backend_event_new_cb (ECal *cal,
+ ECalendarStatus status,
+ EShell *shell)
+{
+ ECalComponent *comp;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+
+ /* XXX Handle errors better. */
+ if (status != E_CALENDAR_STATUS_OK)
+ return;
+
+ flags |= COMP_EDITOR_NEW_ITEM;
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = event_editor_new (cal, shell, flags);
+ comp = cal_comp_event_new_with_current_time (cal, FALSE);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (cal);
+}
+
+static void
+cal_shell_backend_event_all_day_new_cb (ECal *cal,
+ ECalendarStatus status,
+ EShell *shell)
+{
+ ECalComponent *comp;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+
+ /* XXX Handle errors better. */
+ if (status != E_CALENDAR_STATUS_OK)
+ return;
+
+ flags |= COMP_EDITOR_NEW_ITEM;
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = event_editor_new (cal, shell, flags);
+ comp = cal_comp_event_new_with_current_time (cal, TRUE);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (cal);
+}
+
+static void
+cal_shell_backend_event_meeting_new_cb (ECal *cal,
+ ECalendarStatus status,
+ EShell *shell)
+{
+ ECalComponent *comp;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+
+ /* XXX Handle errors better. */
+ if (status != E_CALENDAR_STATUS_OK)
+ return;
+
+ flags |= COMP_EDITOR_NEW_ITEM;
+ flags |= COMP_EDITOR_USER_ORG;
+ flags |= COMP_EDITOR_MEETING;
+
+ editor = event_editor_new (cal, shell, flags);
+ comp = cal_comp_event_new_with_current_time (cal, FALSE);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (cal);
+}
+
+static void
+action_event_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ ECal *cal = NULL;
+ ECalSourceType source_type;
+ ESourceList *source_list;
+ EShellSettings *shell_settings;
+ EShell *shell;
+ const gchar *action_name;
+ gchar *uid;
+
+ /* This callback is used for both appointments and meetings. */
+
+ source_type = E_CAL_SOURCE_TYPE_EVENT;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ if (!e_cal_get_sources (&source_list, source_type, NULL)) {
+ g_warning ("Could not get calendar sources from GConf!");
+ return;
+ }
+
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-calendar");
+
+ if (uid != NULL) {
+ ESource *source;
+
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ if (source != NULL)
+ cal = auth_new_cal_from_source (source, source_type);
+ g_free (uid);
+ }
+
+ if (cal == NULL)
+ cal = auth_new_cal_from_default (source_type);
+
+ g_return_if_fail (cal != NULL);
+
+ /* Connect the appropriate signal handler. */
+ action_name = gtk_action_get_name (action);
+ if (strcmp (action_name, "event-all-day-new") == 0)
+ g_signal_connect (
+ cal, "cal-opened",
+ G_CALLBACK (cal_shell_backend_event_all_day_new_cb),
+ shell);
+ else if (strcmp (action_name, "event-meeting-new") == 0)
+ g_signal_connect (
+ cal, "cal-opened",
+ G_CALLBACK (cal_shell_backend_event_meeting_new_cb),
+ shell);
+ else
+ g_signal_connect (
+ cal, "cal-opened",
+ G_CALLBACK (cal_shell_backend_event_new_cb),
+ shell);
+
+ e_cal_open_async (cal, FALSE);
+}
+
+static void
+action_calendar_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ calendar_setup_new_calendar (GTK_WINDOW (shell_window));
+}
+
+static GtkActionEntry item_entries[] = {
+
+ { "event-new",
+ "appointment-new",
+ NC_("New", "_Appointment"),
+ "<Shift><Control>a",
+ N_("Create a new appointment"),
+ G_CALLBACK (action_event_new_cb) },
+
+ { "event-all-day-new",
+ "stock_new-24h-appointment",
+ NC_("New", "All Day A_ppointment"),
+ NULL,
+ N_("Create a new all-day appointment"),
+ G_CALLBACK (action_event_new_cb) },
+
+ { "event-meeting-new",
+ "stock_new-meeting",
+ NC_("New", "M_eeting"),
+ "<Shift><Control>e",
+ N_("Create a new meeting request"),
+ G_CALLBACK (action_event_new_cb) }
+};
+
+static GtkActionEntry source_entries[] = {
+
+ { "calendar-new",
+ "x-office-calendar",
+ NC_("New", "Cale_ndar"),
+ NULL,
+ N_("Create a new calendar"),
+ G_CALLBACK (action_calendar_new_cb) }
+};
+
+static void
+cal_shell_backend_init_importers (void)
+{
+ EImportClass *import_class;
+ EImportImporter *importer;
+
+ import_class = g_type_class_ref (e_import_get_type ());
+
+ importer = gnome_calendar_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+
+ importer = ical_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+
+ importer = vcal_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+}
+
+static void
+cal_shell_backend_init_preferences (EShell *shell)
+{
+ GtkWidget *preferences_window;
+
+ preferences_window = e_shell_get_preferences_window (shell);
+
+ e_preferences_window_add_page (
+ E_PREFERENCES_WINDOW (preferences_window),
+ "calendar-and-tasks",
+ "preferences-calendar-and-tasks",
+ _("Calendar and Tasks"),
+ calendar_prefs_dialog_new (shell),
+ 600);
+}
+
+static gboolean
+cal_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
+ const gchar *uri)
+{
+ EShell *shell;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+ ECal *client;
+ ECalComponent *comp;
+ ESource *source;
+ ESourceList *source_list;
+ ECalSourceType source_type;
+ EUri *euri;
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+ const gchar *cp;
+ gchar *source_uid = NULL;
+ gchar *comp_uid = NULL;
+ gchar *comp_rid = NULL;
+ time_t startdate = -1;
+ time_t enddate = -1;
+ gboolean handled = FALSE;
+ GError *error = NULL;
+
+ source_type = E_CAL_SOURCE_TYPE_EVENT;
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ if (strncmp (uri, "calendar:", 9) != 0)
+ return FALSE;
+
+ euri = e_uri_new (uri);
+ cp = euri->query;
+ if (cp == NULL)
+ goto exit;
+
+ while (*cp != '\0') {
+ gchar *header;
+ gchar *content;
+ gsize header_len;
+ gsize content_len;
+
+ header_len = strcspn (cp, "=&");
+
+ /* It it's malformed, give up. */
+ if (cp[header_len] != '=')
+ break;
+
+ header = (gchar *) cp;
+ header[header_len] = '\0';
+ cp += header_len + 1;
+
+ content_len = strcspn (cp, "&");
+
+ content = g_strndup (cp, content_len);
+ if (g_ascii_strcasecmp (header, "startdate") == 0)
+ startdate = time_from_isodate (content);
+ else if (g_ascii_strcasecmp (header, "enddate") == 0)
+ enddate = time_from_isodate (content);
+ else if (g_ascii_strcasecmp (header, "source-uid") == 0)
+ source_uid = g_strdup (content);
+ else if (g_ascii_strcasecmp (header, "comp-uid") == 0)
+ comp_uid = g_strdup (content);
+ else if (g_ascii_strcasecmp (header, "comp-rid") == 0)
+ comp_rid = g_strdup (content);
+ g_free (content);
+
+ cp += content_len;
+ if (*cp == '&') {
+ cp++;
+ if (strcmp (cp, "amp;") == 0)
+ cp += 4;
+ }
+ }
+
+ if (source_uid == NULL || comp_uid == NULL)
+ goto exit;
+
+ /* URI is valid, so consider it handled. Whether
+ * we successfully open it is another matter... */
+ handled = TRUE;
+
+ if (!e_cal_get_sources (&source_list, source_type, NULL)) {
+ g_printerr ("Could not get calendar sources from GConf!\n");
+ goto exit;
+ }
+
+ source = e_source_list_peek_source_by_uid (source_list, source_uid);
+ if (source == NULL) {
+ g_printerr ("No source for UID `%s'\n", source_uid);
+ g_object_unref (source_list);
+ goto exit;
+ }
+
+ client = auth_new_cal_from_source (source, source_type);
+ if (client == NULL || !e_cal_open (client, TRUE, &error)) {
+ g_printerr ("%s\n", error->message);
+ g_object_unref (source_list);
+ g_error_free (error);
+ goto exit;
+ }
+
+ /* XXX Copied from e_cal_shell_view_open_event().
+ * Clearly a new utility function is needed. */
+
+ editor = comp_editor_find_instance (comp_uid);
+
+ if (editor != NULL)
+ goto present;
+
+ if (!e_cal_get_object (client, comp_uid, comp_rid, &icalcomp, &error)) {
+ g_printerr ("%s\n", error->message);
+ g_object_unref (source_list);
+ g_error_free (error);
+ goto exit;
+ }
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+
+ icalprop = icalcomponent_get_first_property (
+ icalcomp, ICAL_ATTENDEE_PROPERTY);
+ if (icalprop != NULL)
+ flags |= COMP_EDITOR_MEETING;
+
+ if (itip_organizer_is_user (comp, client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ if (itip_sentby_is_user (comp, client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ if (!e_cal_component_has_attendees (comp))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = event_editor_new (client, shell, flags);
+ comp_editor_edit_comp (editor, comp);
+
+ g_object_unref (comp);
+
+present:
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (source_list);
+ g_object_unref (client);
+
+exit:
+ g_free (source_uid);
+ g_free (comp_uid);
+ g_free (comp_rid);
+
+ e_uri_free (euri);
+
+ return handled;
+}
+
+static void
+cal_shell_backend_window_created_cb (EShellBackend *shell_backend,
+ GtkWindow *window)
+{
+ const gchar *backend_name;
+
+ if (!E_IS_SHELL_WINDOW (window))
+ return;
+
+ backend_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ e_shell_window_register_new_item_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ item_entries, G_N_ELEMENTS (item_entries));
+
+ e_shell_window_register_new_source_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ source_entries, G_N_ELEMENTS (source_entries));
+}
+
+static void
+cal_shell_backend_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SOURCE_LIST:
+ g_value_set_object (
+ value,
+ e_cal_shell_backend_get_source_list (
+ E_CAL_SHELL_BACKEND (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cal_shell_backend_dispose (GObject *object)
+{
+ ECalShellBackendPrivate *priv;
+
+ priv = E_CAL_SHELL_BACKEND_GET_PRIVATE (object);
+
+ if (priv->source_list != NULL) {
+ g_object_unref (priv->source_list);
+ priv->source_list = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+cal_shell_backend_constructed (GObject *object)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell_backend = E_SHELL_BACKEND (object);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ cal_shell_backend_ensure_sources (shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "handle-uri",
+ G_CALLBACK (cal_shell_backend_handle_uri_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "window-created",
+ G_CALLBACK (cal_shell_backend_window_created_cb),
+ shell_backend);
+
+ cal_shell_backend_init_importers ();
+
+ /* Initialize settings before initializing preferences,
+ * since the preferences bind to the shell settings. */
+ e_cal_shell_backend_init_settings (shell);
+ cal_shell_backend_init_preferences (shell);
+}
+
+static void
+cal_shell_backend_class_init (ECalShellBackendClass *class)
+{
+ GObjectClass *object_class;
+ EShellBackendClass *shell_backend_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECalShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = cal_shell_backend_get_property;
+ object_class->dispose = cal_shell_backend_dispose;
+ object_class->constructed = cal_shell_backend_constructed;
+
+ shell_backend_class = E_SHELL_BACKEND_CLASS (class);
+ shell_backend_class->shell_view_type = E_TYPE_CAL_SHELL_VIEW;
+ shell_backend_class->name = "calendar";
+ shell_backend_class->aliases = "";
+ shell_backend_class->schemes = "calendar";
+ shell_backend_class->sort_order = 400;
+ shell_backend_class->start = NULL;
+ shell_backend_class->migrate = e_cal_shell_backend_migrate;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE_LIST,
+ g_param_spec_object (
+ "source-list",
+ _("Source List"),
+ _("The registry of calendars"),
+ E_TYPE_SOURCE_LIST,
+ G_PARAM_READABLE));
+}
+
+static void
+cal_shell_backend_init (ECalShellBackend *cal_shell_backend)
+{
+ cal_shell_backend->priv =
+ E_CAL_SHELL_BACKEND_GET_PRIVATE (cal_shell_backend);
+}
+
+GType
+e_cal_shell_backend_get_type (void)
+{
+ return cal_shell_backend_type;
+}
+
+void
+e_cal_shell_backend_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (ECalShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) cal_shell_backend_init,
+ NULL /* value_table */
+ };
+
+ cal_shell_backend_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_BACKEND,
+ "ECalShellBackend", &type_info, 0);
+}
+
+ESourceList *
+e_cal_shell_backend_get_source_list (ECalShellBackend *cal_shell_backend)
+{
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_BACKEND (cal_shell_backend), NULL);
+
+ return cal_shell_backend->priv->source_list;
+}
diff --git a/modules/calendar/e-cal-shell-backend.h b/modules/calendar/e-cal-shell-backend.h
new file mode 100644
index 0000000000..497e200490
--- /dev/null
+++ b/modules/calendar/e-cal-shell-backend.h
@@ -0,0 +1,70 @@
+/*
+ * e-cal-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_BACKEND_H
+#define E_CAL_SHELL_BACKEND_H
+
+#include <shell/e-shell-backend.h>
+#include <libedataserver/e-source-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CAL_SHELL_BACKEND \
+ (e_cal_shell_backend_get_type ())
+#define E_CAL_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_SHELL_BACKEND, ECalShellBackend))
+#define E_CAL_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_SHELL_BACKEND, ECalShellBackendClass))
+#define E_IS_CAL_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_SHELL_BACKEND))
+#define E_IS_CAL_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_SHELL_BACKEND))
+#define E_CAL_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_SHELL_BACKEND, ECalShellBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalShellBackend ECalShellBackend;
+typedef struct _ECalShellBackendClass ECalShellBackendClass;
+typedef struct _ECalShellBackendPrivate ECalShellBackendPrivate;
+
+struct _ECalShellBackend {
+ EShellBackend parent;
+ ECalShellBackendPrivate *priv;
+};
+
+struct _ECalShellBackendClass {
+ EShellBackendClass parent_class;
+};
+
+GType e_cal_shell_backend_get_type (void);
+void e_cal_shell_backend_register_type
+ (GTypeModule *type_module);
+ESourceList * e_cal_shell_backend_get_source_list
+ (ECalShellBackend *cal_shell_backend);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_BACKEND_H */
diff --git a/modules/calendar/e-cal-shell-content.c b/modules/calendar/e-cal-shell-content.c
new file mode 100644
index 0000000000..e199f0524d
--- /dev/null
+++ b/modules/calendar/e-cal-shell-content.c
@@ -0,0 +1,768 @@
+/*
+ * e-cal-shell-content.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-content.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/gconf-bridge.h"
+#include "widgets/menus/gal-view-etable.h"
+#include "widgets/misc/e-paned.h"
+
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/calendar-view.h"
+#include "calendar/gui/e-cal-list-view.h"
+#include "calendar/gui/e-cal-model-calendar.h"
+#include "calendar/gui/e-calendar-table.h"
+#include "calendar/gui/e-calendar-view.h"
+#include "calendar/gui/e-day-view.h"
+#include "calendar/gui/e-week-view.h"
+
+#define E_CAL_SHELL_CONTENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CAL_SHELL_CONTENT, ECalShellContentPrivate))
+
+struct _ECalShellContentPrivate {
+ GtkWidget *hpaned;
+ GtkWidget *notebook;
+ GtkWidget *vpaned;
+
+ GtkWidget *calendar;
+ GtkWidget *task_table;
+ GtkWidget *memo_table;
+
+ GalViewInstance *view_instance;
+
+ guint paned_binding_id;
+};
+
+enum {
+ PROP_0
+};
+
+/* Used to indicate who has the focus within the calendar view. */
+typedef enum {
+ FOCUS_CALENDAR,
+ FOCUS_MEMO_TABLE,
+ FOCUS_TASK_TABLE,
+ FOCUS_OTHER
+} FocusLocation;
+
+static gpointer parent_class;
+static GType cal_shell_content_type;
+
+static void
+cal_shell_content_display_view_cb (ECalShellContent *cal_shell_content,
+ GalView *gal_view)
+{
+ GnomeCalendar *calendar;
+ GnomeCalendarViewType view_type;
+
+ /* XXX This is confusing: we have CalendarView and ECalendarView.
+ * ECalendarView is an abstract base class for calendar view
+ * widgets (day view, week view, etc). CalendarView is a
+ * simple GalView subclass that represents a calendar view. */
+
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ if (GAL_IS_VIEW_ETABLE (gal_view)) {
+ ECalendarView *calendar_view;
+ ETable *table;
+
+ view_type = GNOME_CAL_LIST_VIEW;
+ calendar_view = gnome_calendar_get_calendar_view (
+ calendar, view_type);
+ table = e_table_scrolled_get_table (
+ E_CAL_LIST_VIEW (calendar_view)->table_scrolled);
+ gal_view_etable_attach_table (
+ GAL_VIEW_ETABLE (gal_view), table);
+ } else {
+ view_type = calendar_view_get_view_type (
+ CALENDAR_VIEW (gal_view));
+ }
+
+ gnome_calendar_display_view (calendar, view_type);
+}
+
+static void
+cal_shell_content_notify_view_id_cb (ECalShellContent *cal_shell_content)
+{
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ GConfBridge *bridge;
+ GtkWidget *paned;
+ guint binding_id;
+ const gchar *key;
+ const gchar *view_id;
+
+ bridge = gconf_bridge_get ();
+ paned = cal_shell_content->priv->hpaned;
+ binding_id = cal_shell_content->priv->paned_binding_id;
+
+ shell_content = E_SHELL_CONTENT (cal_shell_content);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ view_id = e_shell_view_get_view_id (shell_view);
+
+ if (binding_id > 0)
+ gconf_bridge_unbind (bridge, binding_id);
+
+ if (view_id != NULL && strcmp (view_id, "Month_View") == 0)
+ key = "/apps/evolution/calendar/display/month_hpane_position";
+ else
+ key = "/apps/evolution/calendar/display/hpane_position";
+
+ binding_id = gconf_bridge_bind_property_delayed (
+ bridge, key, G_OBJECT (paned), "hposition");
+
+ cal_shell_content->priv->paned_binding_id = binding_id;
+}
+
+static FocusLocation
+cal_shell_content_get_focus_location (ECalShellContent *cal_shell_content)
+{
+ GtkWidget *widget;
+ GnomeCalendar *calendar;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ ECalendarTable *task_table;
+ EMemoTable *memo_table;
+ ETable *table;
+
+ calendar = GNOME_CALENDAR (cal_shell_content->priv->calendar);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ memo_table = E_MEMO_TABLE (cal_shell_content->priv->memo_table);
+ task_table = E_CALENDAR_TABLE (cal_shell_content->priv->task_table);
+
+ table = e_memo_table_get_table (memo_table);
+ if (GTK_WIDGET_HAS_FOCUS (table->table_canvas))
+ return FOCUS_MEMO_TABLE;
+
+ table = e_calendar_table_get_table (task_table);
+ if (GTK_WIDGET_HAS_FOCUS (table->table_canvas))
+ return FOCUS_TASK_TABLE;
+
+ if (E_IS_DAY_VIEW (calendar_view)) {
+ EDayView *day_view = E_DAY_VIEW (calendar_view);
+
+ if (GTK_WIDGET_HAS_FOCUS (day_view->top_canvas))
+ return FOCUS_CALENDAR;
+
+ if (GNOME_CANVAS (day_view->top_canvas)->focused_item != NULL)
+ return FOCUS_CALENDAR;
+
+ if (GTK_WIDGET_HAS_FOCUS (day_view->main_canvas))
+ return FOCUS_CALENDAR;
+
+ if (GNOME_CANVAS (day_view->main_canvas)->focused_item != NULL)
+ return FOCUS_CALENDAR;
+
+ if (GTK_WIDGET_HAS_FOCUS (day_view))
+ return FOCUS_CALENDAR;
+
+ } else if (E_IS_WEEK_VIEW (calendar_view)) {
+ EWeekView *week_view = E_WEEK_VIEW (calendar_view);
+
+ if (GTK_WIDGET_HAS_FOCUS (week_view->main_canvas))
+ return FOCUS_CALENDAR;
+
+ if (GNOME_CANVAS (week_view->main_canvas)->focused_item != NULL)
+ return FOCUS_CALENDAR;
+
+ if (GTK_WIDGET_HAS_FOCUS (week_view))
+ return FOCUS_CALENDAR;
+
+ } else if (E_IS_CAL_LIST_VIEW (calendar_view)) {
+ ECalListView *list_view = E_CAL_LIST_VIEW (widget);
+
+ table = e_table_scrolled_get_table (list_view->table_scrolled);
+ if (GTK_WIDGET_HAS_FOCUS (table))
+ return FOCUS_CALENDAR;
+
+ if (GTK_WIDGET_HAS_FOCUS (list_view))
+ return FOCUS_CALENDAR;
+ }
+
+ return FOCUS_OTHER;
+}
+
+static void
+cal_shell_content_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cal_shell_content_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cal_shell_content_dispose (GObject *object)
+{
+ ECalShellContentPrivate *priv;
+
+ priv = E_CAL_SHELL_CONTENT_GET_PRIVATE (object);
+
+ if (priv->hpaned != NULL) {
+ g_object_unref (priv->hpaned);
+ priv->hpaned = NULL;
+ }
+
+ if (priv->notebook != NULL) {
+ g_object_unref (priv->notebook);
+ priv->notebook = NULL;
+ }
+
+ if (priv->vpaned != NULL) {
+ g_object_unref (priv->vpaned);
+ priv->vpaned = NULL;
+ }
+
+ if (priv->calendar != NULL) {
+ g_object_unref (priv->calendar);
+ priv->calendar = NULL;
+ }
+
+ if (priv->task_table != NULL) {
+ g_object_unref (priv->task_table);
+ priv->task_table = NULL;
+ }
+
+ if (priv->memo_table != NULL) {
+ g_object_unref (priv->memo_table);
+ priv->memo_table = NULL;
+ }
+
+ if (priv->view_instance != NULL) {
+ g_object_unref (priv->view_instance);
+ priv->view_instance = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+cal_shell_content_finalize (GObject *object)
+{
+ ECalShellContentPrivate *priv;
+
+ priv = E_CAL_SHELL_CONTENT_GET_PRIVATE (object);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+cal_shell_content_constructed (GObject *object)
+{
+ ECalShellContentPrivate *priv;
+ ECalendarView *calendar_view;
+ ECalModel *memo_model;
+ ECalModel *task_model;
+ EShell *shell;
+ EShellContent *shell_content;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *foreign_content;
+ EShellView *foreign_view;
+ GnomeCalendar *calendar;
+ GalViewInstance *view_instance;
+ GConfBridge *bridge;
+ GtkWidget *container;
+ GtkWidget *widget;
+ const gchar *config_dir;
+ const gchar *key;
+ gchar *filename;
+ gchar *markup;
+ gint ii;
+
+ priv = E_CAL_SHELL_CONTENT_GET_PRIVATE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_content = E_SHELL_CONTENT (object);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ config_dir = e_shell_backend_get_config_dir (shell_backend);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ /* We borrow the memopad and taskpad models from the memo
+ * and task views, loading the views if necessary. */
+
+ foreign_view = e_shell_window_get_shell_view (shell_window, "memos");
+ foreign_content = e_shell_view_get_shell_content (foreign_view);
+ g_object_get (foreign_content, "model", &memo_model, NULL);
+
+ foreign_view = e_shell_window_get_shell_view (shell_window, "tasks");
+ foreign_content = e_shell_view_get_shell_content (foreign_view);
+ g_object_get (foreign_content, "model", &task_model, NULL);
+
+ /* Build content widgets. */
+
+ container = GTK_WIDGET (object);
+
+ widget = e_paned_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->hpaned = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = priv->hpaned;
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
+ priv->notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* FIXME Need to deal with saving and restoring the position.
+ * Month view has its own position. */
+ widget = gtk_vpaned_new ();
+ gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, TRUE);
+ priv->vpaned = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = priv->notebook;
+
+ /* Add views in the order defined by GnomeCalendarViewType, such
+ * that the notebook page number corresponds to the view type. */
+
+ /* XXX GnomeCalendar is a widget, but we don't pack it.
+ * Maybe it should just be a GObject instead? */
+ priv->calendar = gnome_calendar_new (shell_settings);
+ g_object_ref_sink (priv->calendar);
+ calendar = GNOME_CALENDAR (priv->calendar);
+
+ for (ii = 0; ii < GNOME_CAL_LAST_VIEW; ii++) {
+ calendar_view = gnome_calendar_get_calendar_view (calendar, ii);
+
+ gtk_notebook_append_page (
+ GTK_NOTEBOOK (container),
+ GTK_WIDGET (calendar_view), NULL);
+ gtk_widget_show (GTK_WIDGET (calendar_view));
+ }
+
+ e_binding_new (
+ G_OBJECT (priv->calendar), "view",
+ G_OBJECT (priv->notebook), "page");
+
+ container = priv->vpaned;
+
+ widget = gtk_vbox_new (FALSE, 0);
+ gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, TRUE);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ markup = g_strdup_printf ("<b>%s</b>", _("Tasks"));
+ gtk_label_set_markup (GTK_LABEL (widget), markup);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ widget = e_calendar_table_new (shell_view, task_model);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->task_table = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ filename = g_build_filename (config_dir, "TaskPad", NULL);
+ e_calendar_table_load_state (E_CALENDAR_TABLE (widget), filename);
+ g_free (filename);
+
+ container = priv->vpaned;
+
+ widget = gtk_vbox_new (FALSE, 0);
+ gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, TRUE);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_label_new (NULL);
+ markup = g_strdup_printf ("<b>%s</b>", _("Memos"));
+ gtk_label_set_markup (GTK_LABEL (widget), markup);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ widget = e_memo_table_new (shell_view, memo_model);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->memo_table = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ filename = g_build_filename (config_dir, "MemoPad", NULL);
+ e_memo_table_load_state (E_MEMO_TABLE (widget), filename);
+ g_free (filename);
+
+ /* Load the view instance. */
+
+ view_instance = e_shell_view_new_view_instance (shell_view, NULL);
+ g_signal_connect_swapped (
+ view_instance, "display-view",
+ G_CALLBACK (cal_shell_content_display_view_cb),
+ object);
+ /* XXX Actually, don't load the view instance just yet.
+ * The GtkWidget::map() callback below explains why. */
+ priv->view_instance = view_instance;
+
+ g_signal_connect_swapped (
+ shell_view, "notify::view-id",
+ G_CALLBACK (cal_shell_content_notify_view_id_cb),
+ object);
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (priv->vpaned);
+ key = "/apps/evolution/calendar/display/vpane_position";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "position");
+
+ g_object_unref (memo_model);
+ g_object_unref (task_model);
+}
+
+static void
+cal_shell_content_map (GtkWidget *widget)
+{
+ ECalShellContentPrivate *priv;
+
+ /* XXX Delay loading the GalViewInstance until after ECalShellView
+ * has a chance to install the sidebar's date navigator into
+ * GnomeCalendar, since loading the GalViewInstance triggers a
+ * callback in GnomeCalendar that requires the date navigator.
+ * Ordinarily we would do this at the end of constructed(), but
+ * that's too soon in this case. (This feels kind of kludgy.) */
+ priv = E_CAL_SHELL_CONTENT_GET_PRIVATE (widget);
+ gal_view_instance_load (priv->view_instance);
+
+ /* Chain up to parent's map() method. */
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+}
+
+static void
+cal_shell_content_class_init (ECalShellContentClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECalShellContentPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = cal_shell_content_set_property;
+ object_class->get_property = cal_shell_content_get_property;
+ object_class->dispose = cal_shell_content_dispose;
+ object_class->finalize = cal_shell_content_finalize;
+ object_class->constructed = cal_shell_content_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->map = cal_shell_content_map;
+}
+
+static void
+cal_shell_content_init (ECalShellContent *cal_shell_content)
+{
+ cal_shell_content->priv =
+ E_CAL_SHELL_CONTENT_GET_PRIVATE (cal_shell_content);
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_cal_shell_content_get_type (void)
+{
+ return cal_shell_content_type;
+}
+
+void
+e_cal_shell_content_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (ECalShellContentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_shell_content_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalShellContent),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) cal_shell_content_init,
+ NULL /* value_table */
+ };
+
+ cal_shell_content_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_CONTENT,
+ "ECalShellContent", &type_info, 0);
+}
+
+GtkWidget *
+e_cal_shell_content_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_CAL_SHELL_CONTENT,
+ "shell-view", shell_view, NULL);
+}
+
+ECalModel *
+e_cal_shell_content_get_model (ECalShellContent *cal_shell_content)
+{
+ GnomeCalendar *calendar;
+
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
+
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ return gnome_calendar_get_model (calendar);
+}
+
+GnomeCalendar *
+e_cal_shell_content_get_calendar (ECalShellContent *cal_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
+
+ return GNOME_CALENDAR (cal_shell_content->priv->calendar);
+}
+
+EMemoTable *
+e_cal_shell_content_get_memo_table (ECalShellContent *cal_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
+
+ return E_MEMO_TABLE (cal_shell_content->priv->memo_table);
+}
+
+ECalendarTable *
+e_cal_shell_content_get_task_table (ECalShellContent *cal_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
+
+ return E_CALENDAR_TABLE (cal_shell_content->priv->task_table);
+}
+
+GalViewInstance *
+e_cal_shell_content_get_view_instance (ECalShellContent *cal_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
+
+ return cal_shell_content->priv->view_instance;
+}
+
+void
+e_cal_shell_content_copy_clipboard (ECalShellContent *cal_shell_content)
+{
+ GnomeCalendar *calendar;
+ EMemoTable *memo_table;
+ ECalendarTable *task_table;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+
+ g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
+
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ switch (cal_shell_content_get_focus_location (cal_shell_content)) {
+ case FOCUS_CALENDAR:
+ e_calendar_view_copy_clipboard (calendar_view);
+ break;
+
+ case FOCUS_MEMO_TABLE:
+ e_memo_table_copy_clipboard (memo_table);
+ break;
+
+ case FOCUS_TASK_TABLE:
+ e_calendar_table_copy_clipboard (task_table);
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+}
+
+void
+e_cal_shell_content_cut_clipboard (ECalShellContent *cal_shell_content)
+{
+ GnomeCalendar *calendar;
+ EMemoTable *memo_table;
+ ECalendarTable *task_table;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+
+ g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
+
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ switch (cal_shell_content_get_focus_location (cal_shell_content)) {
+ case FOCUS_CALENDAR:
+ e_calendar_view_cut_clipboard (calendar_view);
+ break;
+
+ case FOCUS_MEMO_TABLE:
+ e_memo_table_copy_clipboard (memo_table);
+ break;
+
+ case FOCUS_TASK_TABLE:
+ e_calendar_table_copy_clipboard (task_table);
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+}
+
+void
+e_cal_shell_content_paste_clipboard (ECalShellContent *cal_shell_content)
+{
+ GnomeCalendar *calendar;
+ EMemoTable *memo_table;
+ ECalendarTable *task_table;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+
+ g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
+
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ switch (cal_shell_content_get_focus_location (cal_shell_content)) {
+ case FOCUS_CALENDAR:
+ e_calendar_view_paste_clipboard (calendar_view);
+ break;
+
+ case FOCUS_MEMO_TABLE:
+ e_memo_table_copy_clipboard (memo_table);
+ break;
+
+ case FOCUS_TASK_TABLE:
+ e_calendar_table_copy_clipboard (task_table);
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+}
+
+void
+e_cal_shell_content_delete_selection (ECalShellContent *cal_shell_content)
+{
+ GnomeCalendar *calendar;
+ EMemoTable *memo_table;
+ ECalendarTable *task_table;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+
+ g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
+
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ switch (cal_shell_content_get_focus_location (cal_shell_content)) {
+ case FOCUS_CALENDAR:
+ e_calendar_view_delete_selected_events (calendar_view);
+ break;
+
+ case FOCUS_MEMO_TABLE:
+ e_memo_table_delete_selected (memo_table);
+ break;
+
+ case FOCUS_TASK_TABLE:
+ e_calendar_table_delete_selected (task_table);
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+}
+
+void
+e_cal_shell_content_delete_selected_occurrence (ECalShellContent *cal_shell_content)
+{
+ GnomeCalendar *calendar;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ FocusLocation focus;
+
+ g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
+
+ focus = cal_shell_content_get_focus_location (cal_shell_content);
+ if (focus != FOCUS_CALENDAR)
+ return;
+
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ e_calendar_view_delete_selected_occurrence (calendar_view);
+}
diff --git a/modules/calendar/e-cal-shell-content.h b/modules/calendar/e-cal-shell-content.h
new file mode 100644
index 0000000000..3db7d33260
--- /dev/null
+++ b/modules/calendar/e-cal-shell-content.h
@@ -0,0 +1,108 @@
+/*
+ * e-cal-shell-content.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_CONTENT_H
+#define E_CAL_SHELL_CONTENT_H
+
+#include <shell/e-shell-content.h>
+#include <shell/e-shell-view.h>
+
+#include <calendar/gui/e-memo-table.h>
+#include <calendar/gui/gnome-cal.h>
+#include <menus/gal-view-instance.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CAL_SHELL_CONTENT \
+ (e_cal_shell_content_get_type ())
+#define E_CAL_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_SHELL_CONTENT, ECalShellContent))
+#define E_CAL_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_SHELL_CONTENT, ECalShellContentClass))
+#define E_IS_CAL_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_SHELL_CONTENT))
+#define E_IS_CAL_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_SHELL_CONTENT))
+#define E_CAL_SHELL_CONTENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_SHELL_CONTENT, ECalShellContentClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalShellContent ECalShellContent;
+typedef struct _ECalShellContentClass ECalShellContentClass;
+typedef struct _ECalShellContentPrivate ECalShellContentPrivate;
+
+enum {
+ E_CAL_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0,
+ E_CAL_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1,
+ E_CAL_SHELL_CONTENT_SELECTION_IS_ASSIGNABLE = 1 << 2,
+ E_CAL_SHELL_CONTENT_SELECTION_IS_COMPLETE = 1 << 3,
+ E_CAL_SHELL_CONTENT_SELECTION_IS_EDITABLE = 1 << 4,
+ E_CAL_SHELL_CONTENT_SELECTION_IS_MEETING = 1 << 5,
+ E_CAL_SHELL_CONTENT_SELECTION_IS_ORGANIZER = 1 << 6,
+ E_CAL_SHELL_CONTENT_SELECTION_IS_RECURRING = 1 << 7,
+ E_CAL_SHELL_CONTENT_SELECTION_CAN_ACCEPT = 1 << 8,
+ E_CAL_SHELL_CONTENT_SELECTION_CAN_DELEGATE = 1 << 9,
+ E_CAL_SHELL_CONTENT_SELECTION_CAN_SAVE = 1 << 10
+};
+
+struct _ECalShellContent {
+ EShellContent parent;
+ ECalShellContentPrivate *priv;
+};
+
+struct _ECalShellContentClass {
+ EShellContentClass parent_class;
+};
+
+GType e_cal_shell_content_get_type (void);
+void e_cal_shell_content_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_cal_shell_content_new (EShellView *shell_view);
+ECalModel * e_cal_shell_content_get_model
+ (ECalShellContent *cal_shell_content);
+GnomeCalendar * e_cal_shell_content_get_calendar
+ (ECalShellContent *cal_shell_content);
+EMemoTable * e_cal_shell_content_get_memo_table
+ (ECalShellContent *cal_shell_content);
+ECalendarTable *e_cal_shell_content_get_task_table
+ (ECalShellContent *cal_shell_content);
+GalViewInstance *
+ e_cal_shell_content_get_view_instance
+ (ECalShellContent *cal_shell_content);
+void e_cal_shell_content_copy_clipboard
+ (ECalShellContent *cal_shell_content);
+void e_cal_shell_content_cut_clipboard
+ (ECalShellContent *cal_shell_content);
+void e_cal_shell_content_paste_clipboard
+ (ECalShellContent *cal_shell_content);
+void e_cal_shell_content_delete_selection
+ (ECalShellContent *cal_shell_content);
+void e_cal_shell_content_delete_selected_occurrence
+ (ECalShellContent *cal_shell_content);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_CONTENT_H */
diff --git a/calendar/gui/migration.c b/modules/calendar/e-cal-shell-migrate.c
index 1597b96ebc..5ec9c99bf3 100644
--- a/calendar/gui/migration.c
+++ b/modules/calendar/e-cal-shell-migrate.c
@@ -1,4 +1,6 @@
/*
+ * e-cal-shell-backend-migrate.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,14 +15,11 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Rodrigo Moya <rodrigo@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#include <config.h>
+#include "e-cal-shell-migrate.h"
#include <string.h>
#include <sys/types.h>
@@ -29,32 +28,26 @@
#include <fcntl.h>
#include <errno.h>
-#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
-
-#include <libecal/e-cal.h>
-
#include <libebackend/e-dbhash.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+#include <libedataserver/e-source-list.h>
#include <libedataserver/e-xml-hash-utils.h>
-#include <libedataserver/e-xml-utils.h>
-#include <libedataserver/e-account-list.h>
-#include <camel/camel-url.h>
#include "e-util/e-bconf-map.h"
#include "e-util/e-folder-map.h"
#include "e-util/e-util-private.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/calendar-config-keys.h"
+#include "calendar/gui/e-cal-event.h"
+#include "shell/e-shell.h"
-#include "calendar-config-keys.h"
-#include "calendar-config.h"
-#include "e-cal-event.h"
-#include "migration.h"
-
-#ifndef G_OS_WIN32
-
-/* No previous versions have been available on Win32, so don't
- * bother with upgrade support from 1.x on Win32.
- */
+#define WEBCAL_BASE_URI "webcal://"
+#define CONTACTS_BASE_URI "contacts://"
+#define BAD_CONTACTS_BASE_URI "contact://"
+#define PERSONAL_RELATIVE_URI "system"
static e_gconf_map_t calendar_display_map[] = {
/* /Calendar/Display */
@@ -77,22 +70,6 @@ static e_gconf_map_t calendar_display_map[] = {
{ NULL },
};
-static e_gconf_map_t calendar_tasks_map[] = {
- /* /Calendar/Tasks */
- { "HideCompletedTasks", "calendar/tasks/hide_completed", E_GCONF_MAP_BOOL },
- { "HideCompletedTasksUnits", "calendar/tasks/hide_completed_units", E_GCONF_MAP_STRING },
- { "HideCompletedTasksValue", "calendar/tasks/hide_completed_value", E_GCONF_MAP_INT },
- { NULL },
-};
-
-static e_gconf_map_t calendar_tasks_colours_map[] = {
- /* /Calendar/Tasks/Colors */
- { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING },
- { "TasksOverDue", "calendar/tasks/colors/overdue", E_GCONF_MAP_STRING },
- { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING },
- { NULL },
-};
-
static e_gconf_map_t calendar_other_map[] = {
/* /Calendar/Other */
{ "ConfirmDelete", "calendar/prompts/confirm_delete", E_GCONF_MAP_BOOL },
@@ -127,20 +104,18 @@ static e_gconf_map_list_t calendar_remap_list[] = {
{ NULL },
};
-static e_gconf_map_list_t task_remap_list[] = {
-
- { "/Calendar/Tasks", calendar_tasks_map },
- { "/Calendar/Tasks/Colors", calendar_tasks_colours_map },
-
- { NULL },
-};
-
static GtkWidget *window;
static GtkLabel *label;
static GtkProgressBar *progress;
+#ifndef G_OS_WIN32
+
+/* No previous versions have been available on Win32, so don't
+ * bother with upgrade support from 1.x on Win32.
+ */
+
static void
-setup_progress_dialog (gboolean tasks)
+setup_progress_dialog (void)
{
GtkWidget *vbox, *hbox, *w;
@@ -153,14 +128,9 @@ setup_progress_dialog (gboolean tasks)
gtk_widget_show (vbox);
gtk_container_add ((GtkContainer *) window, vbox);
- if (tasks)
- w = gtk_label_new (_("The location and hierarchy of the Evolution task "
- "folders has changed since Evolution 1.x.\n\nPlease be "
- "patient while Evolution migrates your folders..."));
- else
- w = gtk_label_new (_("The location and hierarchy of the Evolution calendar "
- "folders has changed since Evolution 1.x.\n\nPlease be "
- "patient while Evolution migrates your folders..."));
+ w = gtk_label_new (_("The location and hierarchy of the Evolution calendar "
+ "folders has changed since Evolution 1.x.\n\nPlease be "
+ "patient while Evolution migrates your folders..."));
gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
gtk_widget_show (w);
@@ -316,7 +286,7 @@ migrate_ical_folder_to_source (gchar *old_path, ESource *new_source, ECalSourceT
ECal *old_ecal = NULL, *new_ecal = NULL;
ESource *old_source;
ESourceGroup *group;
- gchar *old_uri = g_filename_to_uri (old_path, NULL, NULL);
+ gchar *old_uri = g_strdup_printf ("file://%s", old_path);
GError *error = NULL;
gboolean retval = FALSE;
@@ -379,11 +349,126 @@ migrate_ical_folder (gchar *old_path, ESourceGroup *dest_group, gchar *source_na
#endif /* !G_OS_WIN32 */
-#define WEBCAL_BASE_URI "webcal://"
-#define CONTACTS_BASE_URI "contacts://"
-#define BAD_CONTACTS_BASE_URI "contact://"
-#define PERSONAL_RELATIVE_URI "system"
-#define GROUPWISE_BASE_URI "groupwise://"
+#ifndef G_OS_WIN32
+
+static void
+migrate_pilot_db_key (const gchar *key, gpointer user_data)
+{
+ EXmlHash *xmlhash = user_data;
+
+ e_xmlhash_add (xmlhash, key, "");
+}
+
+static void
+migrate_pilot_data (const gchar *component, const gchar *conduit, const gchar *old_path, const gchar *new_path)
+{
+ gchar *changelog, *map;
+ const gchar *dent;
+ const gchar *ext;
+ gchar *filename;
+ GDir *dir;
+
+ if (!(dir = g_dir_open (old_path, 0, NULL)))
+ return;
+
+ map = g_alloca (12 + strlen (conduit));
+ sprintf (map, "pilot-map-%s-", conduit);
+
+ changelog = g_alloca (24 + strlen (conduit));
+ sprintf (changelog, "pilot-sync-evolution-%s-", conduit);
+
+ while ((dent = g_dir_read_name (dir))) {
+ if (!strncmp (dent, map, strlen (map)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) {
+ /* pilot map file - src and dest file formats are identical */
+ guchar inbuf[4096];
+ gsize nread, nwritten;
+ gint fd0, fd1;
+ gssize n;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ g_free (filename);
+ filename = g_build_filename (new_path, dent, NULL);
+ if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) {
+ g_free (filename);
+ close (fd0);
+ continue;
+ }
+
+ do {
+ do {
+ n = read (fd0, inbuf, sizeof (inbuf));
+ } while (n == -1 && errno == EINTR);
+
+ if (n < 1)
+ break;
+
+ nread = n;
+ nwritten = 0;
+ do {
+ do {
+ n = write (fd1, inbuf + nwritten, nread - nwritten);
+ } while (n == -1 && errno == EINTR);
+
+ if (n > 0)
+ nwritten += n;
+ } while (nwritten < nread && n != -1);
+
+ if (n == -1)
+ break;
+ } while (1);
+
+ if (n != -1)
+ n = fsync (fd1);
+
+ if (n == -1) {
+ g_warning ("Failed to migrate %s: %s", dent, strerror (errno));
+ g_unlink (filename);
+ }
+
+ close (fd0);
+ close (fd1);
+ g_free (filename);
+ } else if (!strncmp (dent, changelog, strlen (changelog)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) {
+ /* src and dest formats differ, src format is db3 while dest format is xml */
+ EXmlHash *xmlhash;
+ EDbHash *dbhash;
+ struct stat st;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if (g_stat (filename, &st) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ dbhash = e_dbhash_new (filename);
+ g_free (filename);
+
+ filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent);
+ if (g_stat (filename, &st) != -1)
+ g_unlink (filename);
+ xmlhash = e_xmlhash_new (filename);
+ g_free (filename);
+
+ e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash);
+
+ e_dbhash_destroy (dbhash);
+
+ e_xmlhash_write (xmlhash);
+ e_xmlhash_destroy (xmlhash);
+ }
+ }
+
+ g_dir_close (dir);
+}
+
+#endif
static ESourceGroup *
create_calendar_contact_source (ESourceList *source_list)
@@ -406,13 +491,15 @@ create_calendar_contact_source (ESourceList *source_list)
}
static void
-create_calendar_sources (CalendarComponent *component,
- ESourceList *source_list,
+create_calendar_sources (EShellBackend *shell_backend,
+ ESourceList *source_list,
ESourceGroup **on_this_computer,
ESource **personal_source,
ESourceGroup **on_the_web,
ESourceGroup **contacts)
{
+ EShell *shell;
+ EShellSettings *shell_settings;
GSList *groups;
ESourceGroup *group;
gchar *base_uri, *base_uri_proto;
@@ -423,7 +510,10 @@ create_calendar_sources (CalendarComponent *component,
*contacts = NULL;
*personal_source = NULL;
- base_dir = calendar_component_peek_base_directory (component);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ base_dir = e_shell_backend_get_config_dir (shell_backend);
base_uri = g_build_filename (base_dir, "local", NULL);
base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
@@ -478,16 +568,21 @@ create_calendar_sources (CalendarComponent *component,
}
if (!*personal_source) {
- gchar *primary_calendar = calendar_config_get_primary_calendar ();
+ gchar *primary_calendar;
/* Create the default Person calendar */
ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
e_source_group_add_source (*on_this_computer, source, -1);
+ primary_calendar = e_shell_settings_get_string (
+ shell_settings, "cal-primary-calendar");
+
if (!primary_calendar && !calendar_config_get_calendars_selected ()) {
GSList selected;
- calendar_config_set_primary_calendar (e_source_peek_uid (source));
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-calendar",
+ e_source_peek_uid (source));
selected.data = (gpointer)e_source_peek_uid (source);
selected.next = NULL;
@@ -517,233 +612,28 @@ create_calendar_sources (CalendarComponent *component,
g_free (base_uri);
}
-static void
-create_task_sources (TasksComponent *component,
- ESourceList *source_list,
- ESourceGroup **on_this_computer,
- ESourceGroup **on_the_web,
- ESource **personal_source)
-{
- GSList *groups;
- ESourceGroup *group;
- gchar *base_uri, *base_uri_proto;
- const gchar *base_dir;
-
- *on_this_computer = NULL;
- *on_the_web = NULL;
- *personal_source = NULL;
-
- base_dir = tasks_component_peek_base_directory (component);
- base_uri = g_build_filename (base_dir, "local", NULL);
-
- base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
-
- groups = e_source_list_peek_groups (source_list);
- if (groups) {
- /* groups are already there, we need to search for things... */
- GSList *g;
-
- for (g = groups; g; g = g->next) {
-
- group = E_SOURCE_GROUP (g->data);
-
- if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
- *on_this_computer = g_object_ref (group);
- else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
- *on_the_web = g_object_ref (group);
- }
- }
-
- if (*on_this_computer) {
- /* make sure "Personal" shows up as a source under
- this group */
- GSList *sources = e_source_group_peek_sources (*on_this_computer);
- GSList *s;
- for (s = sources; s; s = s->next) {
- ESource *source = E_SOURCE (s->data);
- const gchar *relative_uri;
-
- relative_uri = e_source_peek_relative_uri (source);
- if (relative_uri == NULL)
- continue;
- if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
- *personal_source = g_object_ref (source);
- break;
- }
- }
- } else {
- /* create the local source group */
- group = e_source_group_new (_("On This Computer"), base_uri_proto);
- e_source_list_add_group (source_list, group, -1);
-
- *on_this_computer = group;
- }
-
- if (!*personal_source) {
- /* Create the default Person task list */
- ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
- e_source_group_add_source (*on_this_computer, source, -1);
-
- if (!calendar_config_get_primary_tasks () && !calendar_config_get_tasks_selected ()) {
- GSList selected;
-
- calendar_config_set_primary_tasks (e_source_peek_uid (source));
-
- selected.data = (gpointer)e_source_peek_uid (source);
- selected.next = NULL;
- calendar_config_set_tasks_selected (&selected);
- }
-
- e_source_set_color_spec (source, "#BECEDD");
- *personal_source = source;
- }
-
- if (!*on_the_web) {
- /* Create the Webcal source group */
- group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
- e_source_list_add_group (source_list, group, -1);
-
- *on_the_web = group;
- }
-
- g_free (base_uri_proto);
- g_free (base_uri);
-}
-
-#ifndef G_OS_WIN32
-
-static void
-migrate_pilot_db_key (const gchar *key, gpointer user_data)
-{
- EXmlHash *xmlhash = user_data;
-
- e_xmlhash_add (xmlhash, key, "");
-}
-
-static void
-migrate_pilot_data (const gchar *component, const gchar *conduit, const gchar *old_path, const gchar *new_path)
-{
- gchar *changelog, *map;
- const gchar *dent;
- const gchar *ext;
- gchar *filename;
- GDir *dir;
-
- if (!(dir = g_dir_open (old_path, 0, NULL)))
- return;
-
- map = g_alloca (12 + strlen (conduit));
- sprintf (map, "pilot-map-%s-", conduit);
-
- changelog = g_alloca (24 + strlen (conduit));
- sprintf (changelog, "pilot-sync-evolution-%s-", conduit);
-
- while ((dent = g_dir_read_name (dir))) {
- if (!strncmp (dent, map, strlen (map)) &&
- ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) {
- /* pilot map file - src and dest file formats are identical */
- guchar inbuf[4096];
- gsize nread, nwritten;
- gint fd0, fd1;
- gssize n;
-
- filename = g_build_filename (old_path, dent, NULL);
- if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) {
- g_free (filename);
- continue;
- }
-
- g_free (filename);
- filename = g_build_filename (new_path, dent, NULL);
- if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) {
- g_free (filename);
- close (fd0);
- continue;
- }
-
- do {
- do {
- n = read (fd0, inbuf, sizeof (inbuf));
- } while (n == -1 && errno == EINTR);
-
- if (n < 1)
- break;
-
- nread = n;
- nwritten = 0;
- do {
- do {
- n = write (fd1, inbuf + nwritten, nread - nwritten);
- } while (n == -1 && errno == EINTR);
-
- if (n > 0)
- nwritten += n;
- } while (nwritten < nread && n != -1);
-
- if (n == -1)
- break;
- } while (1);
-
- if (n != -1)
- n = fsync (fd1);
-
- if (n == -1) {
- g_warning ("Failed to migrate %s: %s", dent, g_strerror (errno));
- g_unlink (filename);
- }
-
- close (fd0);
- close (fd1);
- g_free (filename);
- } else if (!strncmp (dent, changelog, strlen (changelog)) &&
- ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) {
- /* src and dest formats differ, src format is db3 while dest format is xml */
- EXmlHash *xmlhash;
- EDbHash *dbhash;
- struct stat st;
-
- filename = g_build_filename (old_path, dent, NULL);
- if (g_stat (filename, &st) == -1) {
- g_free (filename);
- continue;
- }
-
- dbhash = e_dbhash_new (filename);
- g_free (filename);
-
- filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent);
- if (g_stat (filename, &st) != -1)
- g_unlink (filename);
- xmlhash = e_xmlhash_new (filename);
- g_free (filename);
-
- e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash);
-
- e_dbhash_destroy (dbhash);
-
- e_xmlhash_write (xmlhash);
- e_xmlhash_destroy (xmlhash);
- }
- }
-
- g_dir_close (dir);
-}
-
-#endif
-
gboolean
-migrate_calendars (CalendarComponent *component, gint major, gint minor, gint revision, GError **err)
+e_cal_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
{
ESourceGroup *on_this_computer = NULL, *on_the_web = NULL, *contacts = NULL;
ESource *personal_source = NULL;
+ ESourceList *source_list;
ECalEvent *ece;
- ECalEventTargetComponent *target;
+ ECalEventTargetBackend *target;
gboolean retval = FALSE;
+ g_object_get (shell_backend, "source-list", &source_list, NULL);
+
/* we call this unconditionally now - create_groups either
creates the groups/sources or it finds the necessary
groups/sources. */
- create_calendar_sources (component, calendar_component_peek_source_list (component), &on_this_computer, &personal_source, &on_the_web, &contacts);
+ create_calendar_sources (
+ shell_backend, source_list, &on_this_computer,
+ &personal_source, &on_the_web, &contacts);
#ifndef G_OS_WIN32
if (major == 1) {
@@ -771,7 +661,7 @@ migrate_calendars (CalendarComponent *component, gint major, gint minor, gint re
if (res != 0) {
/* FIXME: set proper domain/code */
- g_set_error(err, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb"));
+ g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb"));
goto fail;
}
}
@@ -780,7 +670,7 @@ migrate_calendars (CalendarComponent *component, gint major, gint minor, gint re
GSList *migration_dirs, *l;
gchar *path, *local_cal_folder;
- setup_progress_dialog (FALSE);
+ setup_progress_dialog ();
path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
migration_dirs = e_folder_map_local_folders (path, "calendar");
@@ -800,7 +690,7 @@ migrate_calendars (CalendarComponent *component, gint major, gint minor, gint re
if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_EVENT)) {
/* FIXME: domain/code */
- g_set_error(err, 0, 0, _("Unable to migrate calendar `%s'"), source_name);
+ g_set_error(error, 0, 0, _("Unable to migrate calendar `%s'"), source_name);
g_free(source_name);
goto fail;
}
@@ -813,7 +703,7 @@ migrate_calendars (CalendarComponent *component, gint major, gint minor, gint re
dialog_close ();
}
- if (minor <= 4 || (minor == 5 && revision < 5)) {
+ if (minor <= 4 || (minor == 5 && micro < 5)) {
GConfClient *gconf;
GConfValue *gconf_val;
gint i;
@@ -839,11 +729,11 @@ migrate_calendars (CalendarComponent *component, gint major, gint minor, gint re
g_object_unref (gconf);
}
- if (minor < 5 || (minor == 5 && revision <= 10)) {
+ if (minor < 5 || (minor == 5 && micro <= 10)) {
gchar *old_path, *new_path;
old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Calendar", NULL);
- new_path = g_build_filename (calendar_component_peek_base_directory (component),
+ new_path = g_build_filename (e_shell_backend_get_config_dir (shell_backend),
"local", "system", NULL);
migrate_pilot_data ("calendar", "calendar", old_path, new_path);
g_free (new_path);
@@ -856,9 +746,9 @@ migrate_calendars (CalendarComponent *component, gint major, gint minor, gint re
during one phase of development, as they take
precedent over relative uris (but aren't updated
when editing an ESource). */
- if (minor == 5 && revision <= 11) {
+ if (minor == 5 && micro <= 11) {
GSList *g;
- for (g = e_source_list_peek_groups (calendar_component_peek_source_list (component)); g; g = g->next) {
+ for (g = e_source_list_peek_groups (source_list); g; g = g->next) {
ESourceGroup *group = g->data;
GSList *s;
@@ -872,7 +762,7 @@ migrate_calendars (CalendarComponent *component, gint major, gint minor, gint re
}
#endif /* !G_OS_WIN32 */
- e_source_list_sync (calendar_component_peek_source_list (component), NULL);
+ e_source_list_sync (source_list, NULL);
/** @Event: component.migration
* @Title: Migration step in component initialization
@@ -885,8 +775,8 @@ migrate_calendars (CalendarComponent *component, gint major, gint minor, gint re
*/
/* Fire off migration event */
ece = e_cal_event_peek ();
- target = e_cal_event_target_new_component (ece, calendar_component_peek (), 0);
- e_event_emit ((EEvent *) ece, "component.migration", (EEventTarget *) target);
+ target = e_cal_event_target_new_module (ece, shell_backend, source_list, 0);
+ e_event_emit ((EEvent *) ece, "module.migration", (EEventTarget *) target);
retval = TRUE;
fail:
@@ -902,342 +792,3 @@ fail:
return retval;
}
-gboolean
-migrate_tasks (TasksComponent *component, gint major, gint minor, gint revision, GError **err)
-{
- ESourceGroup *on_this_computer = NULL;
- ESourceGroup *on_the_web = NULL;
- ESource *personal_source = NULL;
- gboolean retval = FALSE;
-
- /* we call this unconditionally now - create_groups either
- creates the groups/sources or it finds the necessary
- groups/sources. */
- create_task_sources (component, tasks_component_peek_source_list (component), &on_this_computer, &on_the_web, &personal_source);
-
-#ifndef G_OS_WIN32
- if (major == 1) {
- xmlDocPtr config_doc = NULL;
- gchar *conf_file;
-
- conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL);
- if (g_file_test (conf_file, G_FILE_TEST_IS_REGULAR))
- config_doc = e_xml_parse_file (conf_file);
- g_free (conf_file);
-
- if (config_doc && minor <= 2) {
- GConfClient *gconf;
- gint res = 0;
-
- /* move bonobo config to gconf */
- gconf = gconf_client_get_default ();
-
- res = e_bconf_import (gconf, config_doc, task_remap_list);
-
- g_object_unref (gconf);
-
- xmlFreeDoc(config_doc);
-
- if (res != 0) {
- g_set_error(err, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb"));
- goto fail;
- }
- }
-
- if (minor <= 4) {
- GSList *migration_dirs, *l;
- gchar *path, *local_task_folder;
-
- setup_progress_dialog (TRUE);
-
- path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
- migration_dirs = e_folder_map_local_folders (path, "tasks");
- local_task_folder = g_build_filename (path, "Tasks", NULL);
- g_free (path);
-
- if (personal_source)
- migrate_ical_folder_to_source (local_task_folder, personal_source, E_CAL_SOURCE_TYPE_TODO);
-
- for (l = migration_dirs; l; l = l->next) {
- gchar *source_name;
-
- if (personal_source && !strcmp ((gchar *)l->data, local_task_folder))
- continue;
-
- source_name = get_source_name (on_this_computer, (gchar *)l->data);
-
- if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_TODO)) {
- /* FIXME: domain/code */
- g_set_error(err, 0, 0, _("Unable to migrate tasks `%s'"), source_name);
- g_free(source_name);
- goto fail;
- }
-
- g_free (source_name);
- }
-
- g_free (local_task_folder);
-
- dialog_close ();
- }
-
- if (minor < 5 || (minor == 5 && revision <= 10)) {
- gchar *old_path, *new_path;
-
- old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Tasks", NULL);
- new_path = g_build_filename (tasks_component_peek_base_directory (component),
- "local", "system", NULL);
- migrate_pilot_data ("tasks", "todo", old_path, new_path);
- g_free (new_path);
- g_free (old_path);
- }
-
- /* we only need to do this next step if people ran
- older versions of 1.5. We need to clear out the
- absolute URI's that were assigned to ESources
- during one phase of development, as they take
- precedent over relative uris (but aren't updated
- when editing an ESource). */
- if (minor == 5 && revision <= 11) {
- GSList *g;
- for (g = e_source_list_peek_groups (tasks_component_peek_source_list (component)); g; g = g->next) {
- ESourceGroup *group = g->data;
- GSList *s;
-
- for (s = e_source_group_peek_sources (group); s; s = s->next) {
- ESource *source = s->data;
- e_source_set_absolute_uri (source, NULL);
- }
- }
- }
- }
-#endif /* !G_OS_WIN32 */
- e_source_list_sync (tasks_component_peek_source_list (component), NULL);
- retval = TRUE;
-fail:
- if (on_this_computer)
- g_object_unref (on_this_computer);
- if (on_the_web)
- g_object_unref (on_the_web);
- if (personal_source)
- g_object_unref (personal_source);
-
- return retval;
-}
-
-/********************************************************************************************************
- *
- * MEMOS
- *
- ********************************************************************************************************/
-
-static void
-create_memo_sources (MemosComponent *component,
- ESourceList *source_list,
- ESourceGroup **on_this_computer,
- ESourceGroup **on_the_web,
- ESource **personal_source)
-{
- GSList *groups;
- ESourceGroup *group;
- gchar *base_uri, *base_uri_proto;
- const gchar *base_dir;
-
- *on_this_computer = NULL;
- *on_the_web = NULL;
- *personal_source = NULL;
-
- base_dir = memos_component_peek_base_directory (component);
- base_uri = g_build_filename (base_dir, "local", NULL);
-
- base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
-
- groups = e_source_list_peek_groups (source_list);
- if (groups) {
- /* groups are already there, we need to search for things... */
- GSList *g;
-
- for (g = groups; g; g = g->next) {
-
- group = E_SOURCE_GROUP (g->data);
-
- if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
- *on_this_computer = g_object_ref (group);
- else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
- *on_the_web = g_object_ref (group);
- }
- }
-
- if (*on_this_computer) {
- /* make sure "Personal" shows up as a source under
- this group */
- GSList *sources = e_source_group_peek_sources (*on_this_computer);
- GSList *s;
- for (s = sources; s; s = s->next) {
- ESource *source = E_SOURCE (s->data);
- const gchar *relative_uri;
-
- relative_uri = e_source_peek_relative_uri (source);
- if (relative_uri == NULL)
- continue;
- if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
- *personal_source = g_object_ref (source);
- break;
- }
- }
- } else {
- /* create the local source group */
- group = e_source_group_new (_("On This Computer"), base_uri_proto);
- e_source_list_add_group (source_list, group, -1);
-
- *on_this_computer = group;
- }
-
- if (!*personal_source) {
- /* Create the default Person task list */
- ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
- e_source_group_add_source (*on_this_computer, source, -1);
-
- if (!calendar_config_get_primary_memos () && !calendar_config_get_memos_selected ()) {
- GSList selected;
-
- calendar_config_set_primary_memos (e_source_peek_uid (source));
-
- selected.data = (gpointer)e_source_peek_uid (source);
- selected.next = NULL;
- calendar_config_set_memos_selected (&selected);
- }
-
- e_source_set_color_spec (source, "#BECEDD");
- *personal_source = source;
- }
-
- if (!*on_the_web) {
- /* Create the Webcal source group */
- group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
- e_source_list_add_group (source_list, group, -1);
-
- *on_the_web = group;
- }
-
- g_free (base_uri_proto);
- g_free (base_uri);
-}
-
-static gboolean
-is_groupwise_account (EAccount *account)
-{
- if (account->source->url != NULL) {
- return g_str_has_prefix (account->source->url, GROUPWISE_BASE_URI);
- } else {
- return FALSE;
- }
-}
-
-static void
-add_gw_esource (ESourceList *source_list, const gchar *group_name, const gchar *source_name, CamelURL *url, GConfClient *client)
-{
- ESourceGroup *group;
- ESource *source;
- GSList *ids, *temp;
- GError *error = NULL;
- gchar *relative_uri;
- const gchar *soap_port;
- const gchar * use_ssl;
- const gchar *poa_address;
- const gchar *offline_sync;
-
- poa_address = url->host;
- if (!poa_address || strlen (poa_address) ==0)
- return;
- soap_port = camel_url_get_param (url, "soap_port");
-
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7191";
-
- use_ssl = camel_url_get_param (url, "use_ssl");
- offline_sync = camel_url_get_param (url, "offline_sync");
-
- group = e_source_group_new (group_name, GROUPWISE_BASE_URI);
- if (!e_source_list_add_group (source_list, group, -1))
- return;
- relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
-
- source = e_source_new (source_name, relative_uri);
- e_source_set_property (source, "auth", "1");
- e_source_set_property (source, "username", url->user);
- e_source_set_property (source, "port", camel_url_get_param (url, "soap_port"));
- e_source_set_property (source, "auth-domain", "Groupwise");
- e_source_set_property (source, "use_ssl", use_ssl);
- e_source_set_property (source, "offline_sync", offline_sync ? "1" : "0" );
-
- e_source_set_color_spec (source, "#EEBC60");
- e_source_group_add_source (group, source, -1);
-
- ids = gconf_client_get_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, &error);
- if ( error != NULL ) {
- g_warning("%s (%s) %s\n", G_STRLOC, G_STRFUNC, error->message);
- g_error_free(error);
- }
- ids = g_slist_append (ids, g_strdup (e_source_peek_uid (source)));
- gconf_client_set_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, ids, NULL);
- temp = ids;
- for (; temp != NULL; temp = g_slist_next (temp))
- g_free (temp->data);
-
- g_slist_free (ids);
- g_object_unref (source);
- g_object_unref (group);
- g_free (relative_uri);
-}
-
-gboolean
-migrate_memos (MemosComponent *component, gint major, gint minor, gint revision, struct _GError **err)
-{
- ESourceGroup *on_this_computer = NULL;
- ESourceGroup *on_the_web = NULL;
- ESource *personal_source = NULL;
- ESourceList *source_list = NULL;
- gboolean retval = FALSE;
-
- source_list = memos_component_peek_source_list (component);
-
- /* we call this unconditionally now - create_groups either
- creates the groups/sources or it finds the necessary
- groups/sources. */
- create_memo_sources (component, source_list, &on_this_computer, &on_the_web, &personal_source);
-
- /* Migration for Gw accounts between versions < 2.8 */
- if (major == 2 && minor < 8) {
- EAccountList *al;
- EAccount *a;
- CamelURL *url;
- EIterator *it;
- GConfClient *gconf_client = gconf_client_get_default ();
- al = e_account_list_new (gconf_client);
- for (it = e_list_get_iterator((EList *)al);
- e_iterator_is_valid(it);
- e_iterator_next(it)) {
- a = (EAccount *) e_iterator_get(it);
- if (!a->enabled || !is_groupwise_account (a))
- continue;
- url = camel_url_new (a->source->url, NULL);
- add_gw_esource (source_list, a->name, _("Notes"), url, gconf_client);
- camel_url_free (url);
- }
- g_object_unref (al);
- g_object_unref (gconf_client);
- }
-
- e_source_list_sync (source_list, NULL);
- retval = TRUE;
-
- if (on_this_computer)
- g_object_unref (on_this_computer);
- if (on_the_web)
- g_object_unref (on_the_web);
- if (personal_source)
- g_object_unref (personal_source);
-
- return retval;
-}
diff --git a/modules/calendar/e-cal-shell-migrate.h b/modules/calendar/e-cal-shell-migrate.h
new file mode 100644
index 0000000000..359ca5ea22
--- /dev/null
+++ b/modules/calendar/e-cal-shell-migrate.h
@@ -0,0 +1,38 @@
+/*
+ * e-cal-shell-backend-migrate.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_BACKEND_MIGRATE_H
+#define E_CAL_SHELL_BACKEND_MIGRATE_H
+
+#include <glib.h>
+#include <shell/e-shell-backend.h>
+
+G_BEGIN_DECLS
+
+gboolean e_cal_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_BACKEND_MIGRATE_H */
diff --git a/modules/calendar/e-cal-shell-settings.c b/modules/calendar/e-cal-shell-settings.c
new file mode 100644
index 0000000000..4e6939c892
--- /dev/null
+++ b/modules/calendar/e-cal-shell-settings.c
@@ -0,0 +1,742 @@
+/*
+ * e-cal-shell-settings.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-settings.h"
+
+#include <gconf/gconf-client.h>
+#include <libecal/e-cal-util.h>
+
+#include "e-util/e-binding.h"
+
+static gboolean
+transform_string_to_icaltimezone (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ EShellSettings *shell_settings;
+ gboolean use_system_timezone;
+ const gchar *location = NULL;
+ icaltimezone *timezone = NULL;
+
+ shell_settings = E_SHELL_SETTINGS (user_data);
+
+ use_system_timezone = e_shell_settings_get_boolean (
+ shell_settings, "cal-use-system-timezone");
+
+ if (use_system_timezone)
+ timezone = e_cal_util_get_system_timezone ();
+ else
+ location = g_value_get_string (src_value);
+
+ if (location != NULL && *location != '\0')
+ timezone = icaltimezone_get_builtin_timezone (location);
+
+ if (timezone == NULL)
+ timezone = icaltimezone_get_utc_timezone ();
+
+ g_value_set_pointer (dst_value, timezone);
+
+ return TRUE;
+}
+
+static gboolean
+transform_icaltimezone_to_string (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ const gchar *location = NULL;
+ icaltimezone *timezone;
+
+ timezone = g_value_get_pointer (src_value);
+
+ if (timezone != NULL)
+ location = icaltimezone_get_location (timezone);
+
+ if (location == NULL)
+ location = "UTC";
+
+ g_value_set_string (dst_value, location);
+
+ return TRUE;
+}
+
+static gboolean
+transform_weekdays_gconf_to_evolution (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ GDateWeekday weekday;
+
+ /* XXX At some point, Evolution changed its weekday numbering
+ * from 0 = Sunday to 0 = Monday, but did not migrate the
+ * "week_start_day" key. Both enumerations are of course
+ * different from GDateWeekday. We should have saved the
+ * weekday as a string instead. */
+
+ /* This is purposefully verbose for better readability. */
+
+ /* GConf numbering */
+ switch (g_value_get_int (src_value)) {
+ case 0:
+ weekday = G_DATE_SUNDAY;
+ break;
+ case 1:
+ weekday = G_DATE_MONDAY;
+ break;
+ case 2:
+ weekday = G_DATE_TUESDAY;
+ break;
+ case 3:
+ weekday = G_DATE_WEDNESDAY;
+ break;
+ case 4:
+ weekday = G_DATE_THURSDAY;
+ break;
+ case 5:
+ weekday = G_DATE_FRIDAY;
+ break;
+ case 6:
+ weekday = G_DATE_SATURDAY;
+ break;
+ default:
+ return FALSE;
+ }
+
+ /* Evolution numbering */
+ switch (weekday) {
+ case G_DATE_MONDAY:
+ g_value_set_int (dst_value, 0);
+ break;
+ case G_DATE_TUESDAY:
+ g_value_set_int (dst_value, 1);
+ break;
+ case G_DATE_WEDNESDAY:
+ g_value_set_int (dst_value, 2);
+ break;
+ case G_DATE_THURSDAY:
+ g_value_set_int (dst_value, 3);
+ break;
+ case G_DATE_FRIDAY:
+ g_value_set_int (dst_value, 4);
+ break;
+ case G_DATE_SATURDAY:
+ g_value_set_int (dst_value, 5);
+ break;
+ case G_DATE_SUNDAY:
+ g_value_set_int (dst_value, 6);
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+transform_weekdays_evolution_to_gconf (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ GDateWeekday weekday;
+
+ /* XXX At some point, Evolution changed its weekday numbering
+ * from 0 = Sunday to 0 = Monday, but did not migrate the
+ * "week_start_day" key. Both enumerations are of course
+ * different from GDateWeekday. We should have saved the
+ * weekday as a string instead. */
+
+ /* This is purposefully verbose for better readability. */
+
+ /* GConf numbering */
+ switch (g_value_get_int (src_value)) {
+ case 0:
+ weekday = G_DATE_MONDAY;
+ break;
+ case 1:
+ weekday = G_DATE_TUESDAY;
+ break;
+ case 2:
+ weekday = G_DATE_WEDNESDAY;
+ break;
+ case 3:
+ weekday = G_DATE_THURSDAY;
+ break;
+ case 4:
+ weekday = G_DATE_FRIDAY;
+ break;
+ case 5:
+ weekday = G_DATE_SATURDAY;
+ break;
+ case 6:
+ weekday = G_DATE_SUNDAY;
+ break;
+ default:
+ return FALSE;
+ }
+
+ /* Evolution numbering */
+ switch (weekday) {
+ case G_DATE_MONDAY:
+ g_value_set_int (dst_value, 1);
+ break;
+ case G_DATE_TUESDAY:
+ g_value_set_int (dst_value, 2);
+ break;
+ case G_DATE_WEDNESDAY:
+ g_value_set_int (dst_value, 3);
+ break;
+ case G_DATE_THURSDAY:
+ g_value_set_int (dst_value, 4);
+ break;
+ case G_DATE_FRIDAY:
+ g_value_set_int (dst_value, 5);
+ break;
+ case G_DATE_SATURDAY:
+ g_value_set_int (dst_value, 6);
+ break;
+ case G_DATE_SUNDAY:
+ g_value_set_int (dst_value, 0);
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Working day flags */
+enum {
+ WORKING_DAY_SUNDAY = 1 << 0,
+ WORKING_DAY_MONDAY = 1 << 1,
+ WORKING_DAY_TUESDAY = 1 << 2,
+ WORKING_DAY_WEDNESDAY = 1 << 3,
+ WORKING_DAY_THURSDAY = 1 << 4,
+ WORKING_DAY_FRIDAY = 1 << 5,
+ WORKING_DAY_SATURDAY = 1 << 6
+};
+
+static gboolean
+transform_working_days_bitset_to_sunday (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gint bitset;
+ gboolean working_day;
+
+ bitset = g_value_get_int (src_value);
+ working_day = ((bitset & WORKING_DAY_SUNDAY) != 0);
+ g_value_set_boolean (dst_value, working_day);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_sunday_to_bitset (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ EShellSettings *shell_settings;
+ gint bitset, bit;
+
+ shell_settings = E_SHELL_SETTINGS (user_data);
+
+ bitset = e_shell_settings_get_int (
+ shell_settings, "cal-working-days-bitset");
+
+ bit = g_value_get_boolean (src_value) ? WORKING_DAY_SUNDAY : 0;
+ g_value_set_int (dst_value, (bitset & ~WORKING_DAY_SUNDAY) | bit);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_bitset_to_monday (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gint bitset;
+ gboolean working_day;
+
+ bitset = g_value_get_int (src_value);
+ working_day = ((bitset & WORKING_DAY_MONDAY) != 0);
+ g_value_set_boolean (dst_value, working_day);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_monday_to_bitset (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ EShellSettings *shell_settings;
+ gint bitset, bit;
+
+ shell_settings = E_SHELL_SETTINGS (user_data);
+
+ bitset = e_shell_settings_get_int (
+ shell_settings, "cal-working-days-bitset");
+
+ bit = g_value_get_boolean (src_value) ? WORKING_DAY_MONDAY : 0;
+ g_value_set_int (dst_value, (bitset & ~WORKING_DAY_MONDAY) | bit);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_bitset_to_tuesday (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gint bitset;
+ gboolean working_day;
+
+ bitset = g_value_get_int (src_value);
+ working_day = ((bitset & WORKING_DAY_TUESDAY) != 0);
+ g_value_set_boolean (dst_value, working_day);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_tuesday_to_bitset (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ EShellSettings *shell_settings;
+ gint bitset, bit;
+
+ shell_settings = E_SHELL_SETTINGS (user_data);
+
+ bitset = e_shell_settings_get_int (
+ shell_settings, "cal-working-days-bitset");
+
+ bit = g_value_get_boolean (src_value) ? WORKING_DAY_TUESDAY : 0;
+ g_value_set_int (dst_value, (bitset & ~WORKING_DAY_TUESDAY) | bit);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_bitset_to_wednesday (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gint bitset;
+ gboolean working_day;
+
+ bitset = g_value_get_int (src_value);
+ working_day = ((bitset & WORKING_DAY_WEDNESDAY) != 0);
+ g_value_set_boolean (dst_value, working_day);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_wednesday_to_bitset (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ EShellSettings *shell_settings;
+ gint bitset, bit;
+
+ shell_settings = E_SHELL_SETTINGS (user_data);
+
+ bitset = e_shell_settings_get_int (
+ shell_settings, "cal-working-days-bitset");
+
+ bit = g_value_get_boolean (src_value) ? WORKING_DAY_WEDNESDAY : 0;
+ g_value_set_int (dst_value, (bitset & ~WORKING_DAY_WEDNESDAY) | bit);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_bitset_to_thursday (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gint bitset;
+ gboolean working_day;
+
+ bitset = g_value_get_int (src_value);
+ working_day = ((bitset & WORKING_DAY_THURSDAY) != 0);
+ g_value_set_boolean (dst_value, working_day);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_thursday_to_bitset (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ EShellSettings *shell_settings;
+ gint bitset, bit;
+
+ shell_settings = E_SHELL_SETTINGS (user_data);
+
+ bitset = e_shell_settings_get_int (
+ shell_settings, "cal-working-days-bitset");
+
+ bit = g_value_get_boolean (src_value) ? WORKING_DAY_THURSDAY : 0;
+ g_value_set_int (dst_value, (bitset & ~WORKING_DAY_THURSDAY) | bit);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_bitset_to_friday (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gint bitset;
+ gboolean working_day;
+
+ bitset = g_value_get_int (src_value);
+ working_day = ((bitset & WORKING_DAY_FRIDAY) != 0);
+ g_value_set_boolean (dst_value, working_day);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_friday_to_bitset (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ EShellSettings *shell_settings;
+ gint bitset, bit;
+
+ shell_settings = E_SHELL_SETTINGS (user_data);
+
+ bitset = e_shell_settings_get_int (
+ shell_settings, "cal-working-days-bitset");
+
+ bit = g_value_get_boolean (src_value) ? WORKING_DAY_FRIDAY : 0;
+ g_value_set_int (dst_value, (bitset & ~WORKING_DAY_FRIDAY) | bit);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_bitset_to_saturday (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gint bitset;
+ gboolean working_day;
+
+ bitset = g_value_get_int (src_value);
+ working_day = ((bitset & WORKING_DAY_SATURDAY) != 0);
+ g_value_set_boolean (dst_value, working_day);
+
+ return TRUE;
+}
+
+static gboolean
+transform_working_days_saturday_to_bitset (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ EShellSettings *shell_settings;
+ gint bitset, bit;
+
+ shell_settings = E_SHELL_SETTINGS (user_data);
+
+ bitset = e_shell_settings_get_int (
+ shell_settings, "cal-working-days-bitset");
+
+ bit = g_value_get_boolean (src_value) ? WORKING_DAY_SATURDAY : 0;
+ g_value_set_int (dst_value, (bitset & ~WORKING_DAY_SATURDAY) | bit);
+
+ return TRUE;
+}
+
+void
+e_cal_shell_backend_init_settings (EShell *shell)
+{
+ EShellSettings *shell_settings;
+
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_settings_install_property_for_key (
+ "cal-compress-weekend",
+ "/apps/evolution/calendar/display/compress_weekend");
+
+ e_shell_settings_install_property_for_key (
+ "cal-confirm-delete",
+ "/apps/evolution/calendar/prompts/confirm_delete");
+
+ e_shell_settings_install_property_for_key (
+ "cal-confirm-purge",
+ "/apps/evolution/calendar/prompts/confirm_purge");
+
+ e_shell_settings_install_property_for_key (
+ "cal-day-view-show-week-numbers",
+ "/apps/evolution/calendar/display/day_view_show_week_number");
+
+ e_shell_settings_install_property_for_key (
+ "cal-free-busy-template",
+ "/apps/evolution/calendar/publish/template");
+
+ e_shell_settings_install_property_for_key (
+ "cal-hide-completed-tasks",
+ "/apps/evolution/calendar/tasks/hide_completed");
+
+ e_shell_settings_install_property_for_key (
+ "cal-hide-completed-tasks-units",
+ "/apps/evolution/calendar/tasks/hide_completed_units");
+
+ e_shell_settings_install_property_for_key (
+ "cal-hide-completed-tasks-value",
+ "/apps/evolution/calendar/tasks/hide_completed_value");
+
+ e_shell_settings_install_property_for_key (
+ "cal-marcus-bains-day-view-color",
+ "/apps/evolution/calendar/display/marcus_bains_color_dayview");
+
+ e_shell_settings_install_property_for_key (
+ "cal-marcus-bains-time-bar-color",
+ "/apps/evolution/calendar/display/marcus_bains_color_timebar");
+
+ e_shell_settings_install_property_for_key (
+ "cal-marcus-bains-show-line",
+ "/apps/evolution/calendar/display/marcus_bains_line");
+
+ e_shell_settings_install_property_for_key (
+ "cal-primary-calendar",
+ "/apps/evolution/calendar/display/primary_calendar");
+
+ e_shell_settings_install_property_for_key (
+ "cal-primary-memo-list",
+ "/apps/evolution/calendar/memos/primary_memos");
+
+ e_shell_settings_install_property_for_key (
+ "cal-primary-task-list",
+ "/apps/evolution/calendar/tasks/primary_tasks");
+
+ e_shell_settings_install_property_for_key (
+ "cal-show-event-end-times",
+ "/apps/evolution/calendar/display/show_event_end");
+
+ e_shell_settings_install_property_for_key (
+ "cal-show-week-numbers",
+ "/apps/evolution/calendar/date_navigator/show_week_numbers");
+
+ e_shell_settings_install_property_for_key (
+ "cal-tasks-color-due-today",
+ "/apps/evolution/calendar/tasks/colors/due_today");
+
+ e_shell_settings_install_property_for_key (
+ "cal-tasks-color-overdue",
+ "/apps/evolution/calendar/tasks/colors/overdue");
+
+ e_shell_settings_install_property_for_key (
+ "cal-time-divisions",
+ "/apps/evolution/calendar/display/time_divisions");
+
+ /* Do not bind to this. Use "cal-timezone" instead. */
+ e_shell_settings_install_property_for_key (
+ "cal-timezone-string",
+ "/apps/evolution/calendar/display/timezone");
+
+ e_shell_settings_install_property_for_key (
+ "cal-use-24-hour-format",
+ "/apps/evolution/calendar/display/use_24hour_format");
+
+ e_shell_settings_install_property_for_key (
+ "cal-use-system-timezone",
+ "/apps/evolution/calendar/display/use_system_timezone");
+
+ /* Do not bind to this. Use "cal-week-start-day" instead. */
+ e_shell_settings_install_property_for_key (
+ "cal-week-start-day-gconf",
+ "/apps/evolution/calendar/display/week_start_day");
+
+ e_shell_settings_install_property_for_key (
+ "cal-work-day-end-hour",
+ "/apps/evolution/calendar/display/day_end_hour");
+
+ e_shell_settings_install_property_for_key (
+ "cal-work-day-end-minute",
+ "/apps/evolution/calendar/display/day_end_minute");
+
+ e_shell_settings_install_property_for_key (
+ "cal-work-day-start-hour",
+ "/apps/evolution/calendar/display/day_start_hour");
+
+ e_shell_settings_install_property_for_key (
+ "cal-work-day-start-minute",
+ "/apps/evolution/calendar/display/day_start_minute");
+
+ e_shell_settings_install_property_for_key (
+ "cal-working-days-bitset",
+ "/apps/evolution/calendar/display/working_days");
+
+ /* These properties use transform functions to convert
+ * GConf values to forms more useful to Evolution. We
+ * have to use separate properties because GConfBridge
+ * does not support transform functions. Much of this
+ * is backward-compatibility cruft for poorly designed
+ * GConf schemas. */
+
+ e_shell_settings_install_property (
+ g_param_spec_pointer (
+ "cal-timezone",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-timezone-string",
+ G_OBJECT (shell_settings), "cal-timezone",
+ transform_string_to_icaltimezone,
+ transform_icaltimezone_to_string,
+ (GDestroyNotify) g_object_unref,
+ g_object_ref (shell_settings));
+
+ e_shell_settings_install_property (
+ g_param_spec_int (
+ "cal-week-start-day",
+ NULL,
+ NULL,
+ 0, /* Monday */
+ 6, /* Sunday */
+ 0,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-week-start-day-gconf",
+ G_OBJECT (shell_settings), "cal-week-start-day",
+ transform_weekdays_gconf_to_evolution,
+ transform_weekdays_evolution_to_gconf,
+ (GDestroyNotify) NULL, NULL);
+
+ /* XXX These are my favorite. Storing a bit array in GConf
+ * instead of separate boolean keys. Brilliant move. */
+
+ e_shell_settings_install_property (
+ g_param_spec_boolean (
+ "cal-working-days-sunday",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-working-days-bitset",
+ G_OBJECT (shell_settings), "cal-working-days-sunday",
+ transform_working_days_bitset_to_sunday,
+ transform_working_days_sunday_to_bitset,
+ (GDestroyNotify) NULL, shell_settings);
+
+ e_shell_settings_install_property (
+ g_param_spec_boolean (
+ "cal-working-days-monday",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-working-days-bitset",
+ G_OBJECT (shell_settings), "cal-working-days-monday",
+ transform_working_days_bitset_to_monday,
+ transform_working_days_monday_to_bitset,
+ (GDestroyNotify) NULL, shell_settings);
+
+ e_shell_settings_install_property (
+ g_param_spec_boolean (
+ "cal-working-days-tuesday",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-working-days-bitset",
+ G_OBJECT (shell_settings), "cal-working-days-tuesday",
+ transform_working_days_bitset_to_tuesday,
+ transform_working_days_tuesday_to_bitset,
+ (GDestroyNotify) NULL, shell_settings);
+
+ e_shell_settings_install_property (
+ g_param_spec_boolean (
+ "cal-working-days-wednesday",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-working-days-bitset",
+ G_OBJECT (shell_settings), "cal-working-days-wednesday",
+ transform_working_days_bitset_to_wednesday,
+ transform_working_days_wednesday_to_bitset,
+ (GDestroyNotify) NULL, shell_settings);
+
+ e_shell_settings_install_property (
+ g_param_spec_boolean (
+ "cal-working-days-thursday",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-working-days-bitset",
+ G_OBJECT (shell_settings), "cal-working-days-thursday",
+ transform_working_days_bitset_to_thursday,
+ transform_working_days_thursday_to_bitset,
+ (GDestroyNotify) NULL, shell_settings);
+
+ e_shell_settings_install_property (
+ g_param_spec_boolean (
+ "cal-working-days-friday",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-working-days-bitset",
+ G_OBJECT (shell_settings), "cal-working-days-friday",
+ transform_working_days_bitset_to_friday,
+ transform_working_days_friday_to_bitset,
+ (GDestroyNotify) NULL, shell_settings);
+
+ e_shell_settings_install_property (
+ g_param_spec_boolean (
+ "cal-working-days-saturday",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "cal-working-days-bitset",
+ G_OBJECT (shell_settings), "cal-working-days-saturday",
+ transform_working_days_bitset_to_saturday,
+ transform_working_days_saturday_to_bitset,
+ (GDestroyNotify) g_object_unref,
+ g_object_ref (shell_settings));
+}
diff --git a/modules/calendar/e-cal-shell-settings.h b/modules/calendar/e-cal-shell-settings.h
new file mode 100644
index 0000000000..5f7293bbed
--- /dev/null
+++ b/modules/calendar/e-cal-shell-settings.h
@@ -0,0 +1,33 @@
+/*
+ * e-cal-shell-settings.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_SETTINGS_H
+#define E_CAL_SHELL_SETTINGS_H
+
+#include <shell/e-shell.h>
+
+G_BEGIN_DECLS
+
+void e_cal_shell_backend_init_settings (EShell *shell);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_SETTINGS_H */
diff --git a/modules/calendar/e-cal-shell-sidebar.c b/modules/calendar/e-cal-shell-sidebar.c
new file mode 100644
index 0000000000..05b3a47d72
--- /dev/null
+++ b/modules/calendar/e-cal-shell-sidebar.c
@@ -0,0 +1,757 @@
+/*
+ * e-cal-shell-sidebar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-sidebar.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-error.h"
+#include "e-util/e-binding.h"
+#include "e-util/gconf-bridge.h"
+#include "widgets/misc/e-paned.h"
+
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/e-calendar-selector.h"
+#include "calendar/gui/misc.h"
+
+#include "e-cal-shell-backend.h"
+#include "e-cal-shell-view.h"
+
+#define E_CAL_SHELL_SIDEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CAL_SHELL_SIDEBAR, ECalShellSidebarPrivate))
+
+struct _ECalShellSidebarPrivate {
+ GtkWidget *paned;
+ GtkWidget *selector;
+ GtkWidget *date_navigator;
+
+ /* UID -> Client */
+ GHashTable *client_table;
+};
+
+enum {
+ PROP_0,
+ PROP_DATE_NAVIGATOR,
+ PROP_SELECTOR
+};
+
+enum {
+ CLIENT_ADDED,
+ CLIENT_REMOVED,
+ STATUS_MESSAGE,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+static GType cal_shell_sidebar_type;
+
+static void
+cal_shell_sidebar_emit_client_added (ECalShellSidebar *cal_shell_sidebar,
+ ECal *client)
+{
+ guint signal_id = signals[CLIENT_ADDED];
+
+ g_signal_emit (cal_shell_sidebar, signal_id, 0, client);
+}
+
+static void
+cal_shell_sidebar_emit_client_removed (ECalShellSidebar *cal_shell_sidebar,
+ ECal *client)
+{
+ guint signal_id = signals[CLIENT_REMOVED];
+
+ g_signal_emit (cal_shell_sidebar, signal_id, 0, client);
+}
+
+static void
+cal_shell_sidebar_emit_status_message (ECalShellSidebar *cal_shell_sidebar,
+ const gchar *status_message)
+{
+ guint signal_id = signals[STATUS_MESSAGE];
+
+ g_signal_emit (cal_shell_sidebar, signal_id, 0, status_message);
+}
+
+static void
+cal_shell_sidebar_backend_died_cb (ECalShellSidebar *cal_shell_sidebar,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ GHashTable *client_table;
+ ESource *source;
+ const gchar *uid;
+
+ client_table = cal_shell_sidebar->priv->client_table;
+
+ shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ source = e_cal_get_source (client);
+ uid = e_source_peek_uid (source);
+
+ g_object_ref (source);
+
+ g_hash_table_remove (client_table, uid);
+ cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL);
+
+ e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:calendar-crashed", NULL);
+
+ g_object_unref (source);
+}
+
+static void
+cal_shell_sidebar_backend_error_cb (ECalShellSidebar *cal_shell_sidebar,
+ const gchar *message,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ GtkWidget *dialog;
+ const gchar *uri;
+ gchar *uri_no_passwd;
+
+ shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ uri = e_cal_get_uri (client);
+ uri_no_passwd = get_uri_without_password (uri);
+
+ dialog = gtk_message_dialog_new (
+ GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ _("Error on %s\n%s"),
+ uri_no_passwd, message);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ g_free (uri_no_passwd);
+}
+
+static void
+cal_shell_sidebar_client_opened_cb (ECalShellSidebar *cal_shell_sidebar,
+ ECalendarStatus status,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ ESource *source;
+
+ source = e_cal_get_source (client);
+
+ shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED ||
+ status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
+ auth_cal_forget_password (client);
+
+ switch (status) {
+ case E_CALENDAR_STATUS_OK:
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ cal_shell_sidebar_client_opened_cb, NULL);
+
+ cal_shell_sidebar_emit_status_message (
+ cal_shell_sidebar, _("Loading calendars"));
+ cal_shell_sidebar_emit_client_added (
+ cal_shell_sidebar, client);
+ cal_shell_sidebar_emit_status_message (
+ cal_shell_sidebar, NULL);
+ break;
+
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
+ e_cal_open_async (client, FALSE);
+ break;
+
+ case E_CALENDAR_STATUS_BUSY:
+ break;
+
+ case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
+ e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:prompt-no-contents-offline-calendar",
+ NULL);
+ break;
+
+ default:
+ cal_shell_sidebar_emit_client_removed (
+ cal_shell_sidebar, client);
+ break;
+ }
+}
+
+static void
+cal_shell_sidebar_row_changed_cb (ECalShellSidebar *cal_shell_sidebar,
+ GtkTreePath *tree_path,
+ GtkTreeIter *tree_iter,
+ GtkTreeModel *tree_model)
+{
+ ESourceSelector *selector;
+ ESource *source;
+
+ /* XXX ESourceSelector's underlying tree store has only one
+ * column: ESource objects. While we're not supposed to
+ * know this, listening for "row-changed" signals from
+ * the model is easier to deal with than the selector's
+ * "selection-changed" signal, which doesn't tell you
+ * _which_ row changed. */
+
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+ gtk_tree_model_get (tree_model, tree_iter, 0, &source, -1);
+
+ /* XXX This signal gets emitted a lot while the model is being
+ * rebuilt, during which time we won't get a valid ESource.
+ * ESourceSelector should probably block this signal while
+ * rebuilding the model, but we'll be forgiving and not
+ * emit a warning. */
+ if (!E_IS_SOURCE (source))
+ return;
+
+ if (e_source_selector_source_is_selected (selector, source))
+ e_cal_shell_sidebar_add_source (cal_shell_sidebar, source);
+ else
+ e_cal_shell_sidebar_remove_source (cal_shell_sidebar, source);
+}
+
+static void
+cal_shell_sidebar_selection_changed_cb (ECalShellSidebar *cal_shell_sidebar,
+ ESourceSelector *selector)
+{
+ GSList *list, *iter;
+
+ /* This signal is emitted less frequently than "row-changed",
+ * especially when the model is being rebuilt. So we'll take
+ * it easy on poor GConf. */
+
+ list = e_source_selector_get_selection (selector);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+
+ iter->data = (gpointer) e_source_peek_uid (source);
+ g_object_unref (source);
+ }
+
+ calendar_config_set_calendars_selected (list);
+
+ g_slist_free (list);
+}
+
+static void
+cal_shell_sidebar_primary_selection_changed_cb (ECalShellSidebar *cal_shell_sidebar,
+ ESourceSelector *selector)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESource *source;
+
+ /* XXX ESourceSelector needs a "primary-selection-uid" property
+ * so we can just bind the property with GConfBridge. */
+
+ source = e_source_selector_peek_primary_selection (selector);
+ if (source == NULL)
+ return;
+
+ shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-calendar",
+ e_source_peek_uid (source));
+}
+
+static void
+cal_shell_sidebar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_DATE_NAVIGATOR:
+ g_value_set_object (
+ value, e_cal_shell_sidebar_get_date_navigator (
+ E_CAL_SHELL_SIDEBAR (object)));
+ return;
+
+ case PROP_SELECTOR:
+ g_value_set_object (
+ value, e_cal_shell_sidebar_get_selector (
+ E_CAL_SHELL_SIDEBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cal_shell_sidebar_dispose (GObject *object)
+{
+ ECalShellSidebarPrivate *priv;
+
+ priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ if (priv->paned != NULL) {
+ g_object_unref (priv->paned);
+ priv->paned = NULL;
+ }
+
+ if (priv->selector != NULL) {
+ g_object_unref (priv->selector);
+ priv->selector = NULL;
+ }
+
+ if (priv->date_navigator != NULL) {
+ g_object_unref (priv->date_navigator);
+ priv->date_navigator = NULL;
+ }
+
+ g_hash_table_remove_all (priv->client_table);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+cal_shell_sidebar_finalize (GObject *object)
+{
+ ECalShellSidebarPrivate *priv;
+
+ priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->client_table);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+cal_shell_sidebar_constructed (GObject *object)
+{
+ ECalShellSidebarPrivate *priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESourceSelector *selector;
+ ESourceList *source_list;
+ ESource *source;
+ ECalendarItem *calitem;
+ GConfBridge *bridge;
+ GtkTreeModel *model;
+ GtkWidget *container;
+ GtkWidget *widget;
+ AtkObject *a11y;
+ GSList *list, *iter;
+ const gchar *key;
+ gchar *uid;
+
+ priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_sidebar = E_SHELL_SIDEBAR (object);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ source_list = e_cal_shell_backend_get_source_list (
+ E_CAL_SHELL_BACKEND (shell_backend));
+
+ container = GTK_WIDGET (shell_sidebar);
+
+ widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->paned = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, TRUE);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_calendar_selector_new (source_list);
+ e_source_selector_set_select_new (E_SOURCE_SELECTOR (widget), TRUE);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ a11y = gtk_widget_get_accessible (widget);
+ atk_object_set_name (a11y, _("Calendar Selector"));
+ priv->selector = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = priv->paned;
+
+ widget = e_calendar_new ();
+ calitem = E_CALENDAR (widget)->calitem;
+ e_calendar_item_set_days_start_week_sel (calitem, 9);
+ e_calendar_item_set_max_days_sel (calitem, 42);
+ gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, TRUE);
+ priv->date_navigator = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-show-week-numbers",
+ G_OBJECT (calitem), "show-week-numbers");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "cal-week-start-day",
+ G_OBJECT (calitem), "week-start-day");
+
+ /* Restore the selector state from the last session. */
+
+ selector = E_SOURCE_SELECTOR (priv->selector);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector));
+
+ g_signal_connect_swapped (
+ model, "row-changed",
+ G_CALLBACK (cal_shell_sidebar_row_changed_cb),
+ object);
+
+ source = NULL;
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-calendar");
+ if (uid != NULL)
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ if (source == NULL)
+ source = e_source_list_peek_source_any (source_list);
+ if (source != NULL)
+ e_source_selector_set_primary_selection (selector, source);
+ g_free (uid);
+
+ list = calendar_config_get_calendars_selected ();
+ for (iter = list; iter != NULL; iter = iter->next) {
+ uid = iter->data;
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ g_free (uid);
+
+ if (source == NULL)
+ continue;
+
+ e_source_selector_select_source (selector, source);
+ }
+ g_slist_free (list);
+
+ /* Listen for subsequent changes to the selector. */
+
+ g_signal_connect_swapped (
+ selector, "selection-changed",
+ G_CALLBACK (cal_shell_sidebar_selection_changed_cb),
+ object);
+
+ g_signal_connect_swapped (
+ selector, "primary-selection-changed",
+ G_CALLBACK (cal_shell_sidebar_primary_selection_changed_cb),
+ object);
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/calendar/display/date_navigator_vpane_position";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "vposition");
+}
+
+static void
+cal_shell_sidebar_client_removed (ECalShellSidebar *cal_shell_sidebar,
+ ECal *client)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ESource *source;
+ const gchar *uid;
+
+ client_table = cal_shell_sidebar->priv->client_table;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, cal_shell_sidebar);
+
+ source = e_cal_get_source (client);
+ e_source_selector_unselect_source (selector, source);
+
+ uid = e_source_peek_uid (source);
+ g_hash_table_remove (client_table, uid);
+
+ cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL);
+}
+
+static void
+cal_shell_sidebar_class_init (ECalShellSidebarClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECalShellSidebarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = cal_shell_sidebar_get_property;
+ object_class->dispose = cal_shell_sidebar_dispose;
+ object_class->finalize = cal_shell_sidebar_finalize;
+ object_class->constructed = cal_shell_sidebar_constructed;
+
+ class->client_removed = cal_shell_sidebar_client_removed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_DATE_NAVIGATOR,
+ g_param_spec_object (
+ "date-navigator",
+ _("Date Navigator Widget"),
+ _("This widget displays a miniature calendar"),
+ E_TYPE_CALENDAR,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTOR,
+ g_param_spec_object (
+ "selector",
+ _("Source Selector Widget"),
+ _("This widget displays groups of calendars"),
+ E_TYPE_SOURCE_SELECTOR,
+ G_PARAM_READABLE));
+
+ signals[CLIENT_ADDED] = g_signal_new (
+ "client-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ECalShellSidebarClass, client_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CAL);
+
+ signals[CLIENT_REMOVED] = g_signal_new (
+ "client-removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ECalShellSidebarClass, client_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CAL);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status-message",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ECalShellSidebarClass, status_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+}
+
+static void
+cal_shell_sidebar_init (ECalShellSidebar *cal_shell_sidebar)
+{
+ GHashTable *client_table;
+
+ client_table = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ cal_shell_sidebar->priv =
+ E_CAL_SHELL_SIDEBAR_GET_PRIVATE (cal_shell_sidebar);
+
+ cal_shell_sidebar->priv->client_table = client_table;
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_cal_shell_sidebar_get_type (void)
+{
+ return cal_shell_sidebar_type;
+}
+
+void
+e_cal_shell_sidebar_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (ECalShellSidebarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_shell_sidebar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalShellSidebar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) cal_shell_sidebar_init,
+ NULL /* value_table */
+ };
+
+ cal_shell_sidebar_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_SIDEBAR,
+ "ECalShellSidebar", &type_info, 0);
+}
+
+GtkWidget *
+e_cal_shell_sidebar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_CAL_SHELL_SIDEBAR,
+ "shell-view", shell_view, NULL);
+}
+
+GList *
+e_cal_shell_sidebar_get_clients (ECalShellSidebar *cal_shell_sidebar)
+{
+ GHashTable *client_table;
+
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar), NULL);
+
+ client_table = cal_shell_sidebar->priv->client_table;
+
+ return g_hash_table_get_values (client_table);
+}
+
+ECalendar *
+e_cal_shell_sidebar_get_date_navigator (ECalShellSidebar *cal_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar), NULL);
+
+ return E_CALENDAR (cal_shell_sidebar->priv->date_navigator);
+}
+
+ESourceSelector *
+e_cal_shell_sidebar_get_selector (ECalShellSidebar *cal_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar), NULL);
+
+ return E_SOURCE_SELECTOR (cal_shell_sidebar->priv->selector);
+}
+
+void
+e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_shell_sidebar,
+ ESource *source)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+ const gchar *uri;
+ gchar *message;
+
+ g_return_if_fail (E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar));
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ client_table = cal_shell_sidebar->priv->client_table;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (client != NULL)
+ return;
+
+ client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT);
+ g_return_if_fail (client != NULL);
+
+ g_signal_connect_swapped (
+ client, "backend-died",
+ G_CALLBACK (cal_shell_sidebar_backend_died_cb),
+ cal_shell_sidebar);
+
+ g_signal_connect_swapped (
+ client, "backend-error",
+ G_CALLBACK (cal_shell_sidebar_backend_error_cb),
+ cal_shell_sidebar);
+
+ g_hash_table_insert (client_table, g_strdup (uid), client);
+ e_source_selector_select_source (selector, source);
+
+ uri = e_cal_get_uri (client);
+ message = g_strdup_printf (_("Opening calendar at %s"), uri);
+ cal_shell_sidebar_emit_status_message (cal_shell_sidebar, message);
+ g_free (message);
+
+ g_signal_connect_swapped (
+ client, "cal-opened",
+ G_CALLBACK (cal_shell_sidebar_client_opened_cb),
+ cal_shell_sidebar);
+
+ e_cal_open_async (client, FALSE);
+}
+
+void
+e_cal_shell_sidebar_remove_source (ECalShellSidebar *cal_shell_sidebar,
+ ESource *source)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar));
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ client_table = cal_shell_sidebar->priv->client_table;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (client == NULL)
+ return;
+
+ cal_shell_sidebar_emit_client_removed (cal_shell_sidebar, client);
+}
diff --git a/modules/calendar/e-cal-shell-sidebar.h b/modules/calendar/e-cal-shell-sidebar.h
new file mode 100644
index 0000000000..3b7c0fd3b3
--- /dev/null
+++ b/modules/calendar/e-cal-shell-sidebar.h
@@ -0,0 +1,101 @@
+/*
+ * e-cal-shell-sidebar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_SIDEBAR_H
+#define E_CAL_SHELL_SIDEBAR_H
+
+#include <libecal/e-cal.h>
+#include <libedataserverui/e-source-selector.h>
+
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+#include <misc/e-calendar.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CAL_SHELL_SIDEBAR \
+ (e_cal_shell_sidebar_get_type ())
+#define E_CAL_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_SHELL_SIDEBAR, ECalShellSidebar))
+#define E_CAL_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_SHELL_SIDEBAR, ECalShellSidebarClass))
+#define E_IS_CAL_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_SHELL_SIDEBAR))
+#define E_IS_CAL_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_SHELL_SIDEBAR))
+#define E_CAL_SHELL_SIDEBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_SHELL_SIDEBAR, ECalShellSidebarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalShellSidebar ECalShellSidebar;
+typedef struct _ECalShellSidebarClass ECalShellSidebarClass;
+typedef struct _ECalShellSidebarPrivate ECalShellSidebarPrivate;
+
+enum {
+ E_CAL_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0,
+ E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_EMPTY = 1 << 1,
+ E_CAL_SHELL_SIDEBAR_SOURCE_CAN_GO_OFFLINE = 1 << 2,
+ E_CAL_SHELL_SIDEBAR_SOURCE_CAN_DELETE = 1 << 3
+};
+
+struct _ECalShellSidebar {
+ EShellSidebar parent;
+ ECalShellSidebarPrivate *priv;
+};
+
+struct _ECalShellSidebarClass {
+ EShellSidebarClass parent_class;
+
+ /* Signals */
+ void (*client_added) (ECalShellSidebar *cal_shell_sidebar,
+ ECal *client);
+ void (*client_removed) (ECalShellSidebar *cal_shell_sidebar,
+ ECal *client);
+ void (*status_message) (ECalShellSidebar *cal_shell_sidebar,
+ const gchar *status_message);
+};
+
+GType e_cal_shell_sidebar_get_type (void);
+void e_cal_shell_sidebar_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_cal_shell_sidebar_new (EShellView *shell_view);
+GList * e_cal_shell_sidebar_get_clients
+ (ECalShellSidebar *cal_shell_sidebar);
+ECalendar * e_cal_shell_sidebar_get_date_navigator
+ (ECalShellSidebar *cal_shell_sidebar);
+ESourceSelector *
+ e_cal_shell_sidebar_get_selector
+ (ECalShellSidebar *cal_shell_sidebar);
+void e_cal_shell_sidebar_add_source
+ (ECalShellSidebar *cal_shell_sidebar,
+ ESource *source);
+void e_cal_shell_sidebar_remove_source
+ (ECalShellSidebar *cal_shell_sidebar,
+ ESource *source);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_SIDEBAR_H */
diff --git a/modules/calendar/e-cal-shell-view-actions.c b/modules/calendar/e-cal-shell-view-actions.c
new file mode 100644
index 0000000000..b36c94b8d1
--- /dev/null
+++ b/modules/calendar/e-cal-shell-view-actions.c
@@ -0,0 +1,1792 @@
+/*
+ * e-cal-shell-view-actions.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-view-private.h"
+
+static void
+action_calendar_copy_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellSidebar *cal_shell_sidebar;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ ESourceSelector *selector;
+ ESource *source;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ copy_source_dialog (
+ GTK_WINDOW (shell_window),
+ source, E_CAL_SOURCE_TYPE_EVENT);
+}
+
+static void
+action_calendar_delete_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalShellSidebar *cal_shell_sidebar;
+ EShellBackend *shell_backend;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ ECalendarView *calendar_view;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalModel *model;
+ ECal *client;
+ ESourceSelector *selector;
+ ESourceGroup *source_group;
+ ESourceList *source_list;
+ ESource *source;
+ gint response;
+ gchar *uri;
+ GError *error = NULL;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+ model = e_calendar_view_get_model (calendar_view);
+
+ cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ /* Ask for confirmation. */
+ response = e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:prompt-delete-calendar",
+ e_source_peek_name (source));
+ if (response != GTK_RESPONSE_YES)
+ return;
+
+ uri = e_source_get_uri (source);
+ client = e_cal_model_get_client_for_uri (model, uri);
+ if (client == NULL)
+ client = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_EVENT);
+ g_free (uri);
+
+ g_return_if_fail (client != NULL);
+
+ if (!e_cal_remove (client, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (e_source_selector_source_is_selected (selector, source)) {
+ e_cal_shell_sidebar_remove_source (
+ cal_shell_sidebar, source);
+ e_source_selector_unselect_source (selector, source);
+ }
+
+ source_group = e_source_peek_group (source);
+ e_source_group_remove_source (source_group, source);
+
+ source_list = e_cal_shell_backend_get_source_list (
+ E_CAL_SHELL_BACKEND (shell_backend));
+ if (!e_source_list_sync (source_list, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+action_calendar_go_back_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ gnome_calendar_previous (calendar);
+}
+
+static void
+action_calendar_go_forward_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ gnome_calendar_next (calendar);
+}
+
+static void
+action_calendar_go_today_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ gnome_calendar_goto_today (calendar);
+}
+
+static void
+action_calendar_jump_to_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ goto_dialog (calendar);
+}
+
+static void
+action_calendar_new_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ calendar_setup_new_calendar (GTK_WINDOW (shell_window));
+}
+
+static void
+action_calendar_print_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *view;
+ GtkPrintOperationAction print_action;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ view = gnome_calendar_get_calendar_view (calendar, view_type);
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+
+ if (E_IS_CAL_LIST_VIEW (view)) {
+ ECalListView *list_view;
+ ETable *table;
+
+ list_view = E_CAL_LIST_VIEW (view);
+ table = e_table_scrolled_get_table (list_view->table_scrolled);
+ print_table (table, _("Print"), _("Calendar"), print_action);
+ } else {
+ time_t start;
+
+ gnome_calendar_get_current_time_range (calendar, &start, NULL);
+ print_calendar (calendar, print_action, start);
+ }
+}
+
+static void
+action_calendar_print_preview_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *view;
+ GtkPrintOperationAction print_action;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ view = gnome_calendar_get_calendar_view (calendar, view_type);
+ print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
+
+ if (E_IS_CAL_LIST_VIEW (view)) {
+ ECalListView *list_view;
+ ETable *table;
+
+ list_view = E_CAL_LIST_VIEW (view);
+ table = e_table_scrolled_get_table (list_view->table_scrolled);
+ print_table (table, _("Print"), _("Calendar"), print_action);
+ } else {
+ time_t start;
+
+ gnome_calendar_get_current_time_range (calendar, &start, NULL);
+ print_calendar (calendar, print_action, start);
+ }
+}
+
+static void
+action_calendar_properties_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellSidebar *cal_shell_sidebar;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ESource *source;
+ ESourceSelector *selector;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ /* XXX Does this -really- need a source group parameter? */
+ calendar_setup_edit_calendar (
+ GTK_WINDOW (shell_window), source,
+ e_source_peek_group (source));
+}
+
+static void
+action_calendar_purge_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+ GtkSpinButton *spin_button;
+ GtkWidget *container;
+ GtkWidget *dialog;
+ GtkWidget *widget;
+ gint days;
+ time_t tt;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ dialog = gtk_message_dialog_new (
+ GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK_CANCEL,
+ _("This operation will permanently erase all events older "
+ "than the selected amount of time. If you continue, you "
+ "will not be able to recover these events."));
+
+ gtk_dialog_set_default_response (
+ GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ widget = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, FALSE, 6);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ /* Translators: This is the first part of the sentence:
+ * "Purge events older than <<spin-button>> days" */
+ widget = gtk_label_new (_("Purge events older than"));
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, FALSE, 6);
+ gtk_widget_show (widget);
+
+ widget = gtk_spin_button_new_with_range (0.0, 1000.0, 1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), 60.0);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 6);
+ gtk_widget_show (widget);
+
+ spin_button = GTK_SPIN_BUTTON (widget);
+
+ /* Translators: This is the last part of the sentence:
+ * "Purge events older than <<spin-button>> days" */
+ widget = gtk_label_new (_("days"));
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, FALSE, 6);
+ gtk_widget_show (widget);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ days = gtk_spin_button_get_value_as_int (spin_button);
+
+ tt = time (NULL);
+ tt -= (days * (24 * 3600));
+
+ gnome_calendar_purge (calendar, tt);
+
+exit:
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_calendar_rename_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellSidebar *cal_shell_sidebar;
+ ESourceSelector *selector;
+
+ cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+
+ e_source_selector_edit_primary_selection (selector);
+}
+
+static void
+action_calendar_search_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *search_hint;
+
+ /* XXX Figure out a way to handle this in EShellContent
+ * instead of every shell view having to handle it.
+ * The problem is EShellContent does not know what
+ * the search option actions are for this view. It
+ * would have to dig up the popup menu and retrieve
+ * the action for each menu item. Seems messy. */
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ search_hint = gtk_action_get_label (GTK_ACTION (current));
+ e_shell_content_set_search_hint (shell_content, search_hint);
+}
+
+static void
+action_calendar_select_one_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellSidebar *cal_shell_sidebar;
+ ESourceSelector *selector;
+ ESource *primary;
+ GSList *list, *iter;
+
+ /* XXX ESourceSelector should provide a function for this. */
+
+ cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+ primary = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (primary != NULL);
+
+ list = e_source_selector_get_selection (selector);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+
+ if (source == primary)
+ continue;
+
+ e_source_selector_unselect_source (selector, source);
+ }
+ e_source_selector_free_selection (list);
+
+ e_source_selector_select_source (selector, primary);
+}
+
+static void
+action_calendar_view_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ GnomeCalendarViewType view_type;
+ const gchar *view_id;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ view_type = gtk_radio_action_get_current_value (action);
+
+ switch (view_type) {
+ case GNOME_CAL_DAY_VIEW:
+ view_id = "Day_View";
+ break;
+
+ case GNOME_CAL_WORK_WEEK_VIEW:
+ view_id = "Work_Week_View";
+ break;
+
+ case GNOME_CAL_WEEK_VIEW:
+ view_id = "Week_View";
+ break;
+
+ case GNOME_CAL_MONTH_VIEW:
+ view_id = "Month_View";
+ break;
+
+ case GNOME_CAL_LIST_VIEW:
+ view_id = "List_View";
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+
+ e_shell_view_set_view_id (shell_view, view_id);
+}
+
+static void
+action_event_all_day_new_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ GnomeCalendar *calendar;
+
+ /* These are just for readability. */
+ gboolean all_day = TRUE;
+ gboolean meeting = FALSE;
+ gboolean no_past_date = FALSE;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ e_calendar_view_new_appointment_full (
+ calendar_view, all_day, meeting, no_past_date);
+}
+
+static void
+action_event_clipboard_copy_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ e_cal_shell_content_copy_clipboard (cal_shell_content);
+}
+
+static void
+action_event_clipboard_cut_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ e_cal_shell_content_cut_clipboard (cal_shell_content);
+}
+
+static void
+action_event_clipboard_paste_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ e_cal_shell_content_paste_clipboard (cal_shell_content);
+}
+
+static void
+action_event_copy_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *calendar_view;
+ ESource *destination_source = NULL;
+ ECal *destination_client = NULL;
+ GList *selected, *iter;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (selected != NULL);
+
+ /* Get a destination source from the user. */
+ destination_source = select_source_dialog (
+ GTK_WINDOW (shell_window), E_CAL_SOURCE_TYPE_EVENT);
+ if (destination_source == NULL)
+ return;
+
+ /* Open the destination calendar. */
+ destination_client = auth_new_cal_from_source (
+ destination_source, E_CAL_SOURCE_TYPE_EVENT);
+ if (destination_client == NULL)
+ goto exit;
+ if (!e_cal_open (destination_client, FALSE, NULL))
+ goto exit;
+
+ e_cal_shell_view_set_status_message (
+ cal_shell_view, _("Copying Items"), -1.0);
+
+ for (iter = selected; iter != NULL; iter = iter->next) {
+ ECalendarViewEvent *event = iter->data;
+ gboolean remove = FALSE;
+
+ e_cal_shell_view_transfer_item_to (
+ cal_shell_view, event, destination_client, remove);
+ }
+
+ e_cal_shell_view_set_status_message (cal_shell_view, NULL, -1.0);
+
+exit:
+ if (destination_client != NULL)
+ g_object_unref (destination_client);
+ if (destination_source != NULL)
+ g_object_unref (destination_source);
+ g_list_free (selected);
+}
+
+static void
+action_event_delegate_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *calendar_view;
+ ECalendarViewEvent *event;
+ ECalComponent *component;
+ ECal *client;
+ GList *selected;
+ icalcomponent *clone;
+ icalproperty *property;
+ gboolean found = FALSE;
+ gchar *attendee;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (g_list_length (selected) == 1);
+
+ event = selected->data;
+ client = event->comp_data->client;
+ clone = icalcomponent_new_clone (event->comp_data->icalcomp);
+
+ /* Set the attendee status for the delegate. */
+
+ component = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ component, icalcomponent_new_clone (clone));
+
+ attendee = itip_get_comp_attendee (component, client);
+ property = icalcomponent_get_first_property (
+ clone, ICAL_ATTENDEE_PROPERTY);
+
+ while (property != NULL) {
+ const gchar *candidate;
+
+ candidate = icalproperty_get_attendee (property);
+ candidate = itip_strip_mailto (candidate);
+
+ if (g_ascii_strcasecmp (candidate, attendee) == 0) {
+ icalparameter *parameter;
+
+ parameter = icalparameter_new_role (
+ ICAL_ROLE_NONPARTICIPANT);
+ icalproperty_set_parameter (property, parameter);
+
+ parameter = icalparameter_new_partstat (
+ ICAL_PARTSTAT_DELEGATED);
+ icalproperty_set_parameter (property, parameter);
+
+ found = TRUE;
+ break;
+ }
+
+ property = icalcomponent_get_next_property (
+ clone, ICAL_ATTENDEE_PROPERTY);
+ }
+
+ /* If the attendee is not already in the component, add it. */
+ if (!found) {
+ icalparameter *parameter;
+ gchar *address;
+
+ address = g_strdup_printf ("MAILTO:%s", attendee);
+
+ property = icalproperty_new_attendee (address);
+ icalcomponent_add_property (clone, property);
+
+ parameter = icalparameter_new_role (ICAL_ROLE_NONPARTICIPANT);
+ icalproperty_add_parameter (property, parameter);
+
+ parameter = icalparameter_new_cutype (ICAL_CUTYPE_INDIVIDUAL);
+ icalproperty_add_parameter (property, parameter);
+
+ parameter = icalparameter_new_rsvp (ICAL_RSVP_TRUE);
+ icalproperty_add_parameter (property, parameter);
+
+ g_free (address);
+ }
+
+ g_free (attendee);
+ g_object_unref (component);
+
+ e_calendar_view_open_event_with_flags (
+ calendar_view, event->comp_data->client, clone,
+ COMP_EDITOR_MEETING | COMP_EDITOR_DELEGATE);
+
+ icalcomponent_free (clone);
+ g_list_free (selected);
+}
+
+static void
+action_event_delete_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ e_cal_shell_content_delete_selection (cal_shell_content);
+}
+
+static void
+action_event_delete_occurrence_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ e_cal_shell_content_delete_selected_occurrence (cal_shell_content);
+}
+
+static void
+action_event_delete_occurrence_all_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+
+ /* XXX Same as "event-delete". */
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ e_cal_shell_content_delete_selection (cal_shell_content);
+}
+
+static void
+action_event_forward_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ GnomeCalendar *calendar;
+ ECalendarViewEvent *event;
+ ECalComponent *component;
+ ECal *client;
+ icalcomponent *icalcomp;
+ GList *selected;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (g_list_length (selected) == 1);
+
+ event = selected->data;
+ client = event->comp_data->client;
+ icalcomp = event->comp_data->icalcomp;
+
+ component = e_cal_component_new ();
+
+ e_cal_component_set_icalcomponent (
+ component, icalcomponent_new_clone (icalcomp));
+ itip_send_comp (
+ E_CAL_COMPONENT_METHOD_PUBLISH,
+ component, client, NULL, NULL, NULL, TRUE, FALSE);
+
+ g_object_unref (component);
+
+ g_list_free (selected);
+}
+
+static void
+action_event_meeting_new_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ GnomeCalendar *calendar;
+
+ /* These are just for readability. */
+ gboolean all_day = FALSE;
+ gboolean meeting = TRUE;
+ gboolean no_past_date = FALSE;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ e_calendar_view_new_appointment_full (
+ calendar_view, all_day, meeting, no_past_date);
+}
+
+static void
+action_event_move_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *calendar_view;
+ ESource *destination_source = NULL;
+ ECal *destination_client = NULL;
+ GList *selected, *iter;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (selected != NULL);
+
+ /* Get a destination source from the user. */
+ destination_source = select_source_dialog (
+ GTK_WINDOW (shell_window), E_CAL_SOURCE_TYPE_EVENT);
+ if (destination_source == NULL)
+ return;
+
+ /* Open the destination calendar. */
+ destination_client = auth_new_cal_from_source (
+ destination_source, E_CAL_SOURCE_TYPE_EVENT);
+ if (destination_client == NULL)
+ goto exit;
+ if (!e_cal_open (destination_client, FALSE, NULL))
+ goto exit;
+
+ e_cal_shell_view_set_status_message (
+ cal_shell_view, _("Moving Items"), -1.0);
+
+ for (iter = selected; iter != NULL; iter = iter->next) {
+ ECalendarViewEvent *event = iter->data;
+ gboolean remove = TRUE;
+
+ e_cal_shell_view_transfer_item_to (
+ cal_shell_view, event, destination_client, remove);
+ }
+
+ e_cal_shell_view_set_status_message (cal_shell_view, NULL, -1.0);
+
+exit:
+ if (destination_client != NULL)
+ g_object_unref (destination_client);
+ if (destination_source != NULL)
+ g_object_unref (destination_source);
+ g_list_free (selected);
+}
+
+static void
+action_event_new_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ GnomeCalendar *calendar;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ e_calendar_view_new_appointment (calendar_view);
+}
+
+static void
+action_event_occurrence_movable_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalModel *model;
+ ECalendarView *calendar_view;
+ ECalendarViewEvent *event;
+ ECalComponent *exception_component;
+ ECalComponent *recurring_component;
+ ECalComponentDateTime date;
+ ECalComponentId *id;
+ ECal *client;
+ icalcomponent *icalcomp;
+ icaltimetype itt;
+ icaltimezone *timezone;
+ GList *selected;
+ gchar *uid;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ model = e_calendar_view_get_model (calendar_view);
+ timezone = e_cal_model_get_timezone (model);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (g_list_length (selected) == 1);
+
+ event = selected->data;
+ client = event->comp_data->client;
+ icalcomp = event->comp_data->icalcomp;
+
+ /* For the recurring object, we add an exception
+ * to get rid of the instance. */
+
+ recurring_component = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ recurring_component, icalcomponent_new_clone (icalcomp));
+ id = e_cal_component_get_id (recurring_component);
+
+ /* For the unrecurred instance, we duplicate the original object,
+ * create a new UID for it, get rid of the recurrence rules, and
+ * set the start and end times to the instance times. */
+
+ exception_component = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ exception_component, icalcomponent_new_clone (icalcomp));
+
+ uid = e_cal_component_gen_uid ();
+ e_cal_component_set_uid (exception_component, uid);
+ g_free (uid);
+
+ e_cal_component_set_recurid (exception_component, NULL);
+ e_cal_component_set_rdate_list (exception_component, NULL);
+ e_cal_component_set_rrule_list (exception_component, NULL);
+ e_cal_component_set_exdate_list (exception_component, NULL);
+ e_cal_component_set_exrule_list (exception_component, NULL);
+
+ date.value = &itt;
+ date.tzid = icaltimezone_get_tzid (timezone);
+ *date.value = icaltime_from_timet_with_zone (
+ event->comp_data->instance_start, FALSE, timezone);
+ cal_comp_set_dtstart_with_oldzone (client, exception_component, &date);
+ *date.value = icaltime_from_timet_with_zone (
+ event->comp_data->instance_end, FALSE, timezone);
+ cal_comp_set_dtstart_with_oldzone (client, exception_component, &date);
+ e_cal_component_commit_sequence (exception_component);
+
+ /* Now update both ECalComponents. Note that we do this last
+ * since at present the updates happend synchronously so our
+ * event may disappear. */
+
+ e_cal_remove_object_with_mod (
+ client, id->uid, id->rid, CALOBJ_MOD_THIS, NULL);
+
+ e_cal_component_free_id (id);
+ g_object_unref (recurring_component);
+
+ icalcomp = e_cal_component_get_icalcomponent (exception_component);
+ if (e_cal_create_object (client, icalcomp, &uid, NULL))
+ g_free (uid);
+
+ g_object_unref (exception_component);
+
+ g_list_free (selected);
+}
+
+static void
+action_event_open_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *view;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ e_calendar_view_open_event (view);
+}
+
+static void
+action_event_print_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *calendar_view;
+ ECalendarViewEvent *event;
+ ECalComponent *component;
+ ECal *client;
+ icalcomponent *icalcomp;
+ GList *selected;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (g_list_length (selected) == 1);
+
+ event = selected->data;
+ client = event->comp_data->client;
+ icalcomp = event->comp_data->icalcomp;
+
+ component = e_cal_component_new ();
+
+ e_cal_component_set_icalcomponent (
+ component, icalcomponent_new_clone (icalcomp));
+ print_comp (
+ component, client, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
+
+ g_object_unref (component);
+
+ g_list_free (selected);
+}
+
+static void
+action_event_reply_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ GnomeCalendar *calendar;
+ ECalendarViewEvent *event;
+ ECalComponent *component;
+ ECal *client;
+ icalcomponent *icalcomp;
+ GList *selected;
+ gboolean reply_all = FALSE;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (g_list_length (selected) == 1);
+
+ event = selected->data;
+ client = event->comp_data->client;
+ icalcomp = event->comp_data->icalcomp;
+
+ component = e_cal_component_new ();
+
+ e_cal_component_set_icalcomponent (
+ component, icalcomponent_new_clone (icalcomp));
+ reply_to_calendar_comp (
+ E_CAL_COMPONENT_METHOD_REPLY,
+ component, client, reply_all, NULL, NULL);
+
+ g_object_unref (component);
+
+ g_list_free (selected);
+}
+
+static void
+action_event_reply_all_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ GnomeCalendar *calendar;
+ ECalendarViewEvent *event;
+ ECalComponent *component;
+ ECal *client;
+ icalcomponent *icalcomp;
+ GList *selected;
+ gboolean reply_all = TRUE;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (g_list_length (selected) == 1);
+
+ event = selected->data;
+ client = event->comp_data->client;
+ icalcomp = event->comp_data->icalcomp;
+
+ component = e_cal_component_new ();
+
+ e_cal_component_set_icalcomponent (
+ component, icalcomponent_new_clone (icalcomp));
+ reply_to_calendar_comp (
+ E_CAL_COMPONENT_METHOD_REPLY,
+ component, client, reply_all, NULL, NULL);
+
+ g_object_unref (component);
+
+ g_list_free (selected);
+}
+
+static void
+action_event_save_as_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *calendar_view;
+ ECalendarViewEvent *event;
+ ECal *client;
+ icalcomponent *icalcomp;
+ GList *selected;
+ gchar *filename = NULL;
+ gchar *string = NULL;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (g_list_length (selected) == 1);
+
+ event = selected->data;
+ client = event->comp_data->client;
+ icalcomp = event->comp_data->icalcomp;
+
+ filename = e_file_dialog_save (_("Save As..."), NULL);
+ if (filename == NULL)
+ goto exit;
+
+ string = e_cal_get_component_as_string (client, icalcomp);
+ if (string == NULL) {
+ g_warning ("Could not convert item to a string");
+ goto exit;
+ }
+
+ e_write_file_uri (filename, string);
+
+exit:
+ g_free (filename);
+ g_free (string);
+
+ g_list_free (selected);
+}
+
+static void
+action_event_schedule_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *calendar_view;
+ ECalendarViewEvent *event;
+ ECal *client;
+ icalcomponent *icalcomp;
+ GList *selected;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ selected = e_calendar_view_get_selected_events (calendar_view);
+ g_return_if_fail (g_list_length (selected) == 1);
+
+ event = selected->data;
+ client = event->comp_data->client;
+ icalcomp = event->comp_data->icalcomp;
+
+ e_calendar_view_edit_appointment (
+ calendar_view, client, icalcomp, TRUE);
+
+ g_list_free (selected);
+}
+
+static void
+action_gal_save_custom_view_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EShellView *shell_view;
+ GalViewInstance *view_instance;
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with saving the custom view. */
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ view_instance = e_cal_shell_content_get_view_instance (cal_shell_content);
+ gal_view_instance_save_as (view_instance);
+}
+
+static void
+action_search_execute_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with executing the search. */
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ e_cal_shell_view_execute_search (cal_shell_view);
+}
+
+static void
+action_search_filter_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+}
+
+static GtkActionEntry calendar_entries[] = {
+
+ { "calendar-copy",
+ GTK_STOCK_COPY,
+ N_("_Copy..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_copy_cb) },
+
+ { "calendar-delete",
+ GTK_STOCK_DELETE,
+ NULL,
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_delete_cb) },
+
+ { "calendar-go-back",
+ GTK_STOCK_GO_BACK,
+ N_("Previous"),
+ NULL,
+ N_("Go Back"),
+ G_CALLBACK (action_calendar_go_back_cb) },
+
+ { "calendar-go-forward",
+ GTK_STOCK_GO_FORWARD,
+ N_("Next"),
+ NULL,
+ N_("Go Forward"),
+ G_CALLBACK (action_calendar_go_forward_cb) },
+
+ { "calendar-go-today",
+ "go-today",
+ N_("Select _Today"),
+ "<Control>t",
+ N_("Select today"),
+ G_CALLBACK (action_calendar_go_today_cb) },
+
+ { "calendar-jump-to",
+ GTK_STOCK_JUMP_TO,
+ N_("Select _Date"),
+ "<Control>g",
+ N_("Select a specific date"),
+ G_CALLBACK (action_calendar_jump_to_cb) },
+
+ { "calendar-new",
+ "x-office-calendar",
+ N_("_New Calendar"),
+ NULL,
+ N_("Create a new calendar"),
+ G_CALLBACK (action_calendar_new_cb) },
+
+ { "calendar-properties",
+ GTK_STOCK_PROPERTIES,
+ NULL,
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_properties_cb) },
+
+ { "calendar-purge",
+ NULL,
+ N_("Purg_e"),
+ "<Control>e",
+ N_("Purge old appointments and meetings"),
+ G_CALLBACK (action_calendar_purge_cb) },
+
+ { "calendar-rename",
+ NULL,
+ N_("_Rename..."),
+ "F2",
+ N_("Rename the selected calendar"),
+ G_CALLBACK (action_calendar_rename_cb) },
+
+ { "calendar-select-one",
+ "stock_check-filled",
+ N_("Show _Only This Calendar"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_select_one_cb) },
+
+ { "event-clipboard-copy",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy the selection"),
+ G_CALLBACK (action_event_clipboard_copy_cb) },
+
+ { "event-clipboard-cut",
+ GTK_STOCK_CUT,
+ NULL,
+ NULL,
+ N_("Cut the selection"),
+ G_CALLBACK (action_event_clipboard_cut_cb) },
+
+ { "event-clipboard-paste",
+ GTK_STOCK_PASTE,
+ NULL,
+ NULL,
+ N_("Paste the clipboard"),
+ G_CALLBACK (action_event_clipboard_paste_cb) },
+
+ { "event-copy",
+ NULL,
+ N_("Cop_y to Calendar..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_copy_cb) },
+
+ { "event-delegate",
+ NULL,
+ N_("_Delegate Meeting..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_delegate_cb) },
+
+ { "event-delete",
+ GTK_STOCK_DELETE,
+ NULL,
+ NULL,
+ N_("Delete the appointment"),
+ G_CALLBACK (action_event_delete_cb) },
+
+ { "event-delete-occurrence",
+ GTK_STOCK_DELETE,
+ N_("Delete This _Occurrence"),
+ NULL,
+ N_("Delete this occurrence"),
+ G_CALLBACK (action_event_delete_occurrence_cb) },
+
+ { "event-delete-occurrence-all",
+ GTK_STOCK_DELETE,
+ N_("Delete _All Occurrences"),
+ NULL,
+ N_("Delete all occurrences"),
+ G_CALLBACK (action_event_delete_occurrence_all_cb) },
+
+ { "event-all-day-new",
+ NULL,
+ N_("New All Day _Event..."),
+ NULL,
+ N_("Create a new all day event"),
+ G_CALLBACK (action_event_all_day_new_cb) },
+
+ { "event-forward",
+ "mail-forward",
+ N_("_Forward as iCalendar..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_forward_cb) },
+
+ { "event-meeting-new",
+ NULL,
+ N_("New _Meeting..."),
+ NULL,
+ N_("Create a new meeting"),
+ G_CALLBACK (action_event_meeting_new_cb) },
+
+ { "event-move",
+ NULL,
+ N_("Mo_ve to Calendar..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_move_cb) },
+
+ { "event-new",
+ NULL,
+ N_("New _Appointment..."),
+ NULL,
+ N_("Create a new appointment"),
+ G_CALLBACK (action_event_new_cb) },
+
+ { "event-occurrence-movable",
+ NULL,
+ N_("Make this Occurrence _Movable"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_occurrence_movable_cb) },
+
+ { "event-open",
+ NULL,
+ N_("_Open Appointment"),
+ "<Control>o",
+ N_("View the current appointment"),
+ G_CALLBACK (action_event_open_cb) },
+
+ { "event-reply",
+ "mail-reply-sender",
+ N_("_Reply"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_reply_cb) },
+
+ { "event-reply-all",
+ "mail-reply-all",
+ N_("Reply to _All"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_reply_all_cb) },
+
+ { "event-save-as",
+ GTK_STOCK_SAVE_AS,
+ NULL,
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_save_as_cb) },
+
+ { "event-schedule",
+ NULL,
+ N_("_Schedule Meeting..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_schedule_cb) },
+
+ /*** Menus ***/
+
+ { "calendar-actions-menu",
+ NULL,
+ N_("_Actions"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static EPopupActionEntry calendar_popup_entries[] = {
+
+ /* FIXME No equivalent main menu items for the any of the calendar
+ * popup menu items and for many of the event popup menu items.
+ * This is an accessibility issue. */
+
+ { "calendar-popup-copy",
+ NULL,
+ "calendar-copy" },
+
+ { "calendar-popup-delete",
+ NULL,
+ "calendar-delete" },
+
+ { "calendar-popup-go-today",
+ NULL,
+ "calendar-go-today" },
+
+ { "calendar-popup-jump-to",
+ NULL,
+ "calendar-jump-to" },
+
+ { "calendar-popup-properties",
+ NULL,
+ "calendar-properties" },
+
+ { "calendar-popup-rename",
+ NULL,
+ "calendar-rename" },
+
+ { "calendar-popup-select-one",
+ NULL,
+ "calendar-select-one" },
+
+ { "event-popup-clipboard-copy",
+ NULL,
+ "event-clipboard-copy" },
+
+ { "event-popup-clipboard-cut",
+ NULL,
+ "event-clipboard-cut" },
+
+ { "event-popup-clipboard-paste",
+ NULL,
+ "event-clipboard-paste" },
+
+ { "event-popup-copy",
+ NULL,
+ "event-copy" },
+
+ { "event-popup-delegate",
+ NULL,
+ "event-delegate" },
+
+ { "event-popup-delete",
+ NULL,
+ "event-delete" },
+
+ { "event-popup-delete-occurrence",
+ NULL,
+ "event-delete-occurrence" },
+
+ { "event-popup-delete-occurrence-all",
+ NULL,
+ "event-delete-occurrence-all" },
+
+ { "event-popup-forward",
+ NULL,
+ "event-forward" },
+
+ { "event-popup-move",
+ NULL,
+ "event-move" },
+
+ { "event-popup-occurrence-movable",
+ NULL,
+ "event-occurrence-movable" },
+
+ { "event-popup-open",
+ NULL,
+ "event-open" },
+
+ { "event-popup-reply",
+ NULL,
+ "event-reply" },
+
+ { "event-popup-reply-all",
+ NULL,
+ "event-reply-all" },
+
+ { "event-popup-save-as",
+ NULL,
+ "event-save-as" },
+
+ { "event-popup-schedule",
+ NULL,
+ "event-schedule" }
+};
+
+static GtkRadioActionEntry calendar_view_entries[] = {
+
+ { "calendar-view-day",
+ "view-calendar-day",
+ N_("Day"),
+ NULL,
+ N_("Show one day"),
+ GNOME_CAL_DAY_VIEW },
+
+ { "calendar-view-list",
+ "view-calendar-list",
+ N_("List"),
+ NULL,
+ N_("Show as list"),
+ GNOME_CAL_LIST_VIEW },
+
+ { "calendar-view-month",
+ "view-calendar-month",
+ N_("Month"),
+ NULL,
+ N_("Show one month"),
+ GNOME_CAL_MONTH_VIEW },
+
+ { "calendar-view-week",
+ "view-calendar-week",
+ N_("Week"),
+ NULL,
+ N_("Show one week"),
+ GNOME_CAL_WEEK_VIEW },
+
+ { "calendar-view-workweek",
+ "view-calendar-workweek",
+ N_("Work Week"),
+ NULL,
+ N_("Show one work week"),
+ GNOME_CAL_WORK_WEEK_VIEW }
+};
+
+static GtkRadioActionEntry calendar_filter_entries[] = {
+
+ { "calendar-filter-active-appointments",
+ NULL,
+ N_("Active Appointements"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CALENDAR_FILTER_ACTIVE_APPOINTMENTS },
+
+ { "calendar-filter-any-category",
+ NULL,
+ N_("Any Category"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CALENDAR_FILTER_ANY_CATEGORY },
+
+ { "calendar-filter-next-7-days-appointments",
+ NULL,
+ N_("Next 7 Days' Appointments"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS },
+
+ { "calendar-filter-unmatched",
+ NULL,
+ N_("Unmatched"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CALENDAR_FILTER_UNMATCHED }
+};
+
+static GtkRadioActionEntry calendar_search_entries[] = {
+
+ { "calendar-search-any-field-contains",
+ NULL,
+ N_("Any field contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CALENDAR_SEARCH_ANY_FIELD_CONTAINS },
+
+ { "calendar-search-description-contains",
+ NULL,
+ N_("Description contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CALENDAR_SEARCH_DESCRIPTION_CONTAINS },
+
+ { "calendar-search-summary-contains",
+ NULL,
+ N_("Summary contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ CALENDAR_SEARCH_SUMMARY_CONTAINS }
+};
+
+static GtkActionEntry lockdown_printing_entries[] = {
+
+ { "calendar-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ "<Control>p",
+ N_("Print this calendar"),
+ G_CALLBACK (action_calendar_print_cb) },
+
+ { "calendar-print-preview",
+ GTK_STOCK_PRINT_PREVIEW,
+ NULL,
+ NULL,
+ N_("Preview the calendar to be printed"),
+ G_CALLBACK (action_calendar_print_preview_cb) },
+
+ { "event-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_event_print_cb) }
+};
+
+static EPopupActionEntry lockdown_printing_popup_entries[] = {
+
+ { "event-popup-print",
+ NULL,
+ "event-print" }
+};
+
+void
+e_cal_shell_view_actions_init (ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+ GtkAction *action;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ /* Calendar Actions */
+ action_group = ACTION_GROUP (CALENDAR);
+ gtk_action_group_add_actions (
+ action_group, calendar_entries,
+ G_N_ELEMENTS (calendar_entries), cal_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, calendar_popup_entries,
+ G_N_ELEMENTS (calendar_popup_entries));
+ gtk_action_group_add_radio_actions (
+ action_group, calendar_view_entries,
+ G_N_ELEMENTS (calendar_view_entries), GNOME_CAL_DAY_VIEW,
+ G_CALLBACK (action_calendar_view_cb), cal_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, calendar_search_entries,
+ G_N_ELEMENTS (calendar_search_entries),
+ CALENDAR_SEARCH_SUMMARY_CONTAINS,
+ G_CALLBACK (action_calendar_search_cb), cal_shell_view);
+
+ /* Lockdown Printing Actions */
+ action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
+ gtk_action_group_add_actions (
+ action_group, lockdown_printing_entries,
+ G_N_ELEMENTS (lockdown_printing_entries), cal_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, lockdown_printing_popup_entries,
+ G_N_ELEMENTS (lockdown_printing_popup_entries));
+
+ /* Fine tuning. */
+
+ action = ACTION (CALENDAR_GO_TODAY);
+ g_object_set (action, "short-label", _("Today"), NULL);
+
+ action = ACTION (CALENDAR_JUMP_TO);
+ g_object_set (action, "short-label", _("Go To"), NULL);
+
+ action = ACTION (CALENDAR_VIEW_DAY);
+ g_object_set (action, "is-important", TRUE, NULL);
+
+ action = ACTION (CALENDAR_VIEW_LIST);
+ g_object_set (action, "is-important", TRUE, NULL);
+
+ action = ACTION (CALENDAR_VIEW_MONTH);
+ g_object_set (action, "is-important", TRUE, NULL);
+
+ action = ACTION (CALENDAR_VIEW_WEEK);
+ g_object_set (action, "is-important", TRUE, NULL);
+
+ action = ACTION (CALENDAR_VIEW_WORKWEEK);
+ g_object_set (action, "is-important", TRUE, NULL);
+
+ action = ACTION (EVENT_DELETE);
+ g_object_set (action, "short-label", _("Delete"), NULL);
+
+ g_signal_connect (
+ ACTION (GAL_SAVE_CUSTOM_VIEW), "activate",
+ G_CALLBACK (action_gal_save_custom_view_cb), cal_shell_view);
+
+ g_signal_connect (
+ ACTION (SEARCH_EXECUTE), "activate",
+ G_CALLBACK (action_search_execute_cb), cal_shell_view);
+
+ /* Initialize the memo and task pad actions. */
+ e_cal_shell_view_memopad_actions_init (cal_shell_view);
+ e_cal_shell_view_taskpad_actions_init (cal_shell_view);
+}
+
+void
+e_cal_shell_view_update_search_filter (ECalShellView *cal_shell_view)
+{
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GtkActionGroup *action_group;
+ GtkRadioAction *radio_action;
+ GList *list, *iter;
+ GSList *group;
+ gint ii;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action_group = ACTION_GROUP (CALENDAR_FILTER);
+ e_action_group_remove_all_actions (action_group);
+
+ /* Add the standard filter actions. */
+ gtk_action_group_add_radio_actions (
+ action_group, calendar_filter_entries,
+ G_N_ELEMENTS (calendar_filter_entries),
+ CALENDAR_FILTER_ANY_CATEGORY,
+ G_CALLBACK (action_search_filter_cb),
+ cal_shell_view);
+
+ /* Retrieve the radio group from an action we just added. */
+ list = gtk_action_group_list_actions (action_group);
+ radio_action = GTK_RADIO_ACTION (list->data);
+ group = gtk_radio_action_get_group (radio_action);
+ g_list_free (list);
+
+ /* Build the category actions. */
+
+ list = e_categories_get_list ();
+ for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) {
+ const gchar *category_name = iter->data;
+ const gchar *filename;
+ GtkAction *action;
+ gchar *action_name;
+
+ action_name = g_strdup_printf (
+ "calendar-filter-category-%d", ii);
+ radio_action = gtk_radio_action_new (
+ action_name, category_name, NULL, NULL, ii);
+ g_free (action_name);
+
+ /* Convert the category icon file to a themed icon name. */
+ filename = e_categories_get_icon_file_for (category_name);
+ if (filename != NULL && *filename != '\0') {
+ gchar *basename;
+ gchar *cp;
+
+ basename = g_path_get_basename (filename);
+
+ /* Lose the file extension. */
+ if ((cp = strrchr (basename, '.')) != NULL)
+ *cp = '\0';
+
+ g_object_set (
+ radio_action, "icon-name", basename, NULL);
+
+ g_free (basename);
+ }
+
+ gtk_radio_action_set_group (radio_action, group);
+ group = gtk_radio_action_get_group (radio_action);
+
+ /* The action group takes ownership of the action. */
+ action = GTK_ACTION (radio_action);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (radio_action);
+ }
+ g_list_free (list);
+
+ /* Use any action in the group; doesn't matter which. */
+ e_shell_content_set_filter_action (shell_content, radio_action);
+
+ ii = CALENDAR_FILTER_UNMATCHED;
+ e_shell_content_add_filter_separator_after (shell_content, ii);
+
+ ii = CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS;
+ e_shell_content_add_filter_separator_after (shell_content, ii);
+}
diff --git a/modules/calendar/e-cal-shell-view-actions.h b/modules/calendar/e-cal-shell-view-actions.h
new file mode 100644
index 0000000000..b02906f179
--- /dev/null
+++ b/modules/calendar/e-cal-shell-view-actions.h
@@ -0,0 +1,153 @@
+/*
+ * e-cal-shell-view-actions.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_VIEW_ACTIONS_H
+#define E_CAL_SHELL_VIEW_ACTIONS_H
+
+#include <shell/e-shell-window-actions.h>
+
+/* Calendar Actions */
+#define E_SHELL_WINDOW_ACTION_CALENDAR_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-copy")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-delete")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_GO_BACK(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-go-back")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_GO_FORWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-go-forward")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_GO_TODAY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-go-today")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_JUMP_TO(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-jump-to")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-new")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-print")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_PRINT_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-print-preview")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_PROPERTIES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-properties")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_PURGE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-purge")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_RENAME(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-rename")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_SELECT_ONE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-select-one")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_DAY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-view-day")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_LIST(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-view-list")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_MONTH(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-view-month")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_WEEK(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-view-week")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_WORKWEEK(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-view-workweek")
+
+/* Event Actions */
+#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "event-clipboard-copy")
+#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_CUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "event-clipboard-cut")
+#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_PASTE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "event-clipboard-paste")
+#define E_SHELL_WINDOW_ACTION_EVENT_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "event-delete")
+#define E_SHELL_WINDOW_ACTION_EVENT_DELETE_OCCURRENCE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "event-delete-occurrence")
+#define E_SHELL_WINDOW_ACTION_EVENT_DELETE_OCCURRENCE_ALL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "event-delete-occurrence-all")
+#define E_SHELL_WINDOW_ACTION_EVENT_OPEN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "event-open")
+
+/* Memo Pad Actions */
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-copy")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_CUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-cut")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_PASTE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-paste")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-delete")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_FORWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-forward")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-new")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_OPEN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-open")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_OPEN_URL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-open-url")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-print")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_SAVE_AS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-save-as")
+
+/* Task Pad Actions */
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_ASSIGN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-assign")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-copy")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_CUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-cut")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_PASTE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-paste")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-delete")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_FORWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-forward")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_MARK_COMPLETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-mark-complete")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_MARK_INCOMPLETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-mark-incomplete")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-new")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_OPEN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-open")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_OPEN_URL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-open-url")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-print")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_SAVE_AS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-save-as")
+
+/* Calendar Query Actions */
+#define E_SHELL_WINDOW_ACTION_CALENDAR_FILTER_ACTIVE_APPOINTMENTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-filter-active-appointments")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_FILTER_ANY_CATEGORY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-filter-any-category")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-filter-next-7-days-appointments")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_FILTER_UNMATCHED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-filter-unmatched")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_SEARCH_ANY_FIELD_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-search-any-field-contains")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_SEARCH_DESCRIPTION_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-search-description-contains")
+#define E_SHELL_WINDOW_ACTION_CALENDAR_SEARCH_SUMMARY_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "calendar-search-summary-contains")
+
+/* Action Groups */
+#define E_SHELL_WINDOW_ACTION_GROUP_CALENDAR(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "calendar")
+#define E_SHELL_WINDOW_ACTION_GROUP_CALENDAR_FILTER(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "calendar-filter")
+
+#endif /* E_CAL_SHELL_VIEW_ACTIONS_H */
diff --git a/modules/calendar/e-cal-shell-view-memopad.c b/modules/calendar/e-cal-shell-view-memopad.c
new file mode 100644
index 0000000000..1c4e863345
--- /dev/null
+++ b/modules/calendar/e-cal-shell-view-memopad.c
@@ -0,0 +1,526 @@
+/*
+ * e-cal-shell-view-memopad.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-view-private.h"
+
+/* Much of this file is based on e-memo-shell-view-actions.c. */
+
+static void
+action_calendar_memopad_clipboard_copy_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ e_memo_table_copy_clipboard (memo_table);
+}
+
+static void
+action_calendar_memopad_clipboard_cut_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ e_memo_table_cut_clipboard (memo_table);
+}
+
+static void
+action_calendar_memopad_clipboard_paste_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ e_memo_table_paste_clipboard (memo_table);
+}
+
+static void
+action_calendar_memopad_delete_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ e_cal_shell_view_memopad_set_status_message (
+ cal_shell_view, _("Deleting selected memos..."), -1.0);
+ e_memo_table_delete_selected (memo_table);
+ e_cal_shell_view_memopad_set_status_message (
+ cal_shell_view, NULL, -1.0);
+}
+
+static void
+action_calendar_memopad_forward_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ GSList *list;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only forward the first selected memo. */
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+ itip_send_comp (
+ E_CAL_COMPONENT_METHOD_PUBLISH, comp,
+ comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
+ g_object_unref (comp);
+}
+
+static void
+action_calendar_memopad_new_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECal *client;
+ ECalComponent *comp;
+ CompEditor *editor;
+ GSList *list;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ client = comp_data->client;
+ editor = memo_editor_new (client, shell, COMP_EDITOR_NEW_ITEM);
+ comp = cal_comp_memo_new_with_defaults (client);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (client);
+}
+
+static void
+action_calendar_memopad_open_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only open the first selected memo. */
+ e_cal_shell_view_memopad_open_memo (cal_shell_view, comp_data);
+}
+
+static void
+action_calendar_memopad_open_url_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ icalproperty *prop;
+ const gchar *uri;
+ GSList *list;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only open the URI of the first selected memo. */
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_URL_PROPERTY);
+ g_return_if_fail (prop == NULL);
+
+ uri = icalproperty_get_url (prop);
+ e_show_uri (GTK_WINDOW (shell_window), uri);
+}
+
+static void
+action_calendar_memopad_print_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ GtkPrintOperationAction print_action;
+ GSList *list;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only print the first selected memo. */
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ e_cal_component_set_icalcomponent (comp, clone);
+ print_comp (comp, comp_data->client, print_action);
+ g_object_unref (comp);
+}
+
+static void
+action_calendar_memopad_save_as_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+ gchar *filename;
+ gchar *string;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ filename = e_file_dialog_save (_("Save as..."), NULL);
+ if (filename == NULL)
+ return;
+
+ /* XXX We only save the first selected memo. */
+ string = e_cal_get_component_as_string (
+ comp_data->client, comp_data->icalcomp);
+ if (string == NULL) {
+ g_warning ("Could not convert memo to a string.");
+ return;
+ }
+
+ e_write_file_uri (filename, string);
+
+ g_free (filename);
+ g_free (string);
+}
+
+static GtkActionEntry calendar_memopad_entries[] = {
+
+ { "calendar-memopad-clipboard-copy",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy selected memo"),
+ G_CALLBACK (action_calendar_memopad_clipboard_copy_cb) },
+
+ { "calendar-memopad-clipboard-cut",
+ GTK_STOCK_CUT,
+ NULL,
+ NULL,
+ N_("Cut selected memo"),
+ G_CALLBACK (action_calendar_memopad_clipboard_cut_cb) },
+
+ { "calendar-memopad-clipboard-paste",
+ GTK_STOCK_PASTE,
+ NULL,
+ NULL,
+ N_("Paste memo from the clipboard"),
+ G_CALLBACK (action_calendar_memopad_clipboard_paste_cb) },
+
+ { "calendar-memopad-delete",
+ GTK_STOCK_DELETE,
+ N_("_Delete Memo"),
+ NULL,
+ N_("Delete selected memos"),
+ G_CALLBACK (action_calendar_memopad_delete_cb) },
+
+ { "calendar-memopad-forward",
+ "mail-forward",
+ N_("_Forward as iCalendar..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_memopad_forward_cb) },
+
+ { "calendar-memopad-new",
+ "stock_insert-note",
+ N_("New _Memo"),
+ NULL,
+ N_("Create a new memo"),
+ G_CALLBACK (action_calendar_memopad_new_cb) },
+
+ { "calendar-memopad-open",
+ GTK_STOCK_OPEN,
+ N_("_Open Memo"),
+ NULL,
+ N_("View the selected memo"),
+ G_CALLBACK (action_calendar_memopad_open_cb) },
+
+ { "calendar-memopad-open-url",
+ "applications-internet",
+ N_("Open _Web Page"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_memopad_open_url_cb) },
+
+ { "calendar-memopad-save-as",
+ GTK_STOCK_SAVE_AS,
+ NULL,
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_memopad_save_as_cb) }
+};
+
+static GtkActionEntry lockdown_printing_entries[] = {
+
+ { "calendar-memopad-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ NULL,
+ N_("Print the selected memo"),
+ G_CALLBACK (action_calendar_memopad_print_cb) }
+};
+
+void
+e_cal_shell_view_memopad_actions_init (ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ /* Calendar Actions */
+ action_group = ACTION_GROUP (CALENDAR);
+ gtk_action_group_add_actions (
+ action_group, calendar_memopad_entries,
+ G_N_ELEMENTS (calendar_memopad_entries), cal_shell_view);
+
+ /* Lockdown Printing Actions */
+ action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
+ gtk_action_group_add_actions (
+ action_group, lockdown_printing_entries,
+ G_N_ELEMENTS (lockdown_printing_entries), cal_shell_view);
+}
+
+void
+e_cal_shell_view_memopad_actions_update (ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ EMemoTable *memo_table;
+ ETable *table;
+ GtkAction *action;
+ GSList *list, *iter;
+ const gchar *label;
+ gboolean editable = TRUE;
+ gboolean has_url = FALSE;
+ gboolean sensitive;
+ gint n_selected;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+
+ table = e_memo_table_get_table (memo_table);
+ n_selected = e_table_selected_count (table);
+
+ list = e_memo_table_get_selected (memo_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ icalproperty *prop;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ editable &= !read_only;
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_URL_PROPERTY);
+ has_url |= (prop != NULL);
+ }
+ g_slist_free (list);
+
+ action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_COPY);
+ sensitive = (n_selected > 0);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_CUT);
+ sensitive = (n_selected > 0) && editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_PASTE);
+ sensitive = editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_MEMOPAD_DELETE);
+ sensitive = (n_selected > 0) && editable;
+ gtk_action_set_sensitive (action, sensitive);
+ label = ngettext ("Delete Memo", "Delete Memos", n_selected);
+ g_object_set (action, "label", label, NULL);
+
+ action = ACTION (CALENDAR_MEMOPAD_FORWARD);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_MEMOPAD_OPEN);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_MEMOPAD_OPEN_URL);
+ sensitive = (n_selected == 1) && has_url;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_MEMOPAD_PRINT);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_MEMOPAD_SAVE_AS);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+}
+
+void
+e_cal_shell_view_memopad_open_memo (ECalShellView *cal_shell_view,
+ ECalModelComponent *comp_data)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
+ g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data));
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ editor = comp_editor_find_instance (uid);
+
+ if (editor != NULL)
+ goto exit;
+
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+
+ if (e_cal_component_has_organizer (comp))
+ flags |= COMP_EDITOR_IS_SHARED;
+
+ if (itip_organizer_is_user (comp, comp_data->client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = memo_editor_new (comp_data->client, shell, flags);
+ comp_editor_edit_comp (editor, comp);
+
+ g_object_unref (comp);
+
+exit:
+ gtk_window_present (GTK_WINDOW (editor));
+}
+
+void
+e_cal_shell_view_memopad_set_status_message (ECalShellView *cal_shell_view,
+ const gchar *status_message,
+ gdouble percent)
+{
+ EActivity *activity;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+
+ g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ activity = cal_shell_view->priv->memopad_activity;
+
+ if (status_message == NULL || *status_message == '\0') {
+ if (activity != NULL) {
+ e_activity_complete (activity);
+ g_object_unref (activity);
+ activity = NULL;
+ }
+
+ } else if (activity == NULL) {
+ activity = e_activity_new (status_message);
+ e_activity_set_percent (activity, percent);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ } else {
+ e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
+ }
+
+ cal_shell_view->priv->memopad_activity = activity;
+}
diff --git a/modules/calendar/e-cal-shell-view-private.c b/modules/calendar/e-cal-shell-view-private.c
new file mode 100644
index 0000000000..1b9c8d367a
--- /dev/null
+++ b/modules/calendar/e-cal-shell-view-private.c
@@ -0,0 +1,1098 @@
+/*
+ * e-cal-shell-view-private.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-view-private.h"
+
+#include "calendar/gui/calendar-view-factory.h"
+#include "widgets/menus/gal-view-factory-etable.h"
+
+static void
+cal_shell_view_process_completed_tasks (ECalShellView *cal_shell_view,
+ gboolean config_changed)
+{
+#if 0
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ e_calendar_table_process_completed_tasks (
+ task_table, clients, config_changed);
+#endif
+}
+
+static struct tm
+cal_shell_view_get_current_time (ECalendarItem *calitem,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ struct icaltimetype tt;
+ icaltimezone *timezone;
+ ECalModel *model;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ model = e_cal_shell_content_get_model (cal_shell_content);
+ timezone = e_cal_model_get_timezone (model);
+
+ tt = icaltime_from_timet_with_zone (time (NULL), FALSE, timezone);
+
+ return icaltimetype_to_tm (&tt);
+}
+
+static void
+cal_shell_view_date_navigator_date_range_changed_cb (ECalShellView *cal_shell_view,
+ ECalendarItem *calitem)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ gnome_calendar_update_query (calendar);
+}
+
+static void
+cal_shell_view_date_navigator_selection_changed_cb (ECalShellView *cal_shell_view,
+ ECalendarItem *calitem)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendarViewType switch_to;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalModel *model;
+ GDate start_date, end_date;
+ GDate new_start_date, new_end_date;
+ icaltimetype tt;
+ icaltimezone *timezone;
+ time_t start, end, new_time;
+ gboolean starts_on_week_start_day;
+ gint new_days_shown;
+ gint week_start_day;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ model = gnome_calendar_get_model (calendar);
+ view_type = gnome_calendar_get_view (calendar);
+ switch_to = view_type;
+
+ timezone = e_cal_model_get_timezone (model);
+ week_start_day = e_cal_model_get_week_start_day (model);
+ e_cal_model_get_time_range (model, &start, &end);
+
+ time_to_gdate_with_zone (&start_date, start, timezone);
+ time_to_gdate_with_zone (&end_date, end, timezone);
+
+ if (view_type == GNOME_CAL_MONTH_VIEW) {
+ EWeekView *week_view;
+ ECalendarView *calendar_view;
+ gboolean multi_week_view;
+ gboolean compress_weekend;
+
+ calendar_view = gnome_calendar_get_calendar_view (
+ calendar, GNOME_CAL_MONTH_VIEW);
+
+ week_view = E_WEEK_VIEW (calendar_view);
+ multi_week_view = e_week_view_get_multi_week_view (week_view);
+ compress_weekend = e_week_view_get_compress_weekend (week_view);
+
+ if (week_start_day == 0 && (!multi_week_view || compress_weekend))
+ g_date_add_days (&start_date, 1);
+ }
+
+ g_date_subtract_days (&end_date, 1);
+
+ e_calendar_item_get_selection (
+ calitem, &new_start_date, &new_end_date);
+
+ /* If the selection hasn't changed, just return. */
+ if (g_date_compare (&start_date, &new_start_date) == 0 &&
+ g_date_compare (&end_date, &new_end_date) == 0)
+ return;
+
+ new_days_shown =
+ g_date_get_julian (&new_end_date) -
+ g_date_get_julian (&new_start_date) + 1;
+
+ /* If a complete week is selected we show the week view.
+ * Note that if weekends are compressed and the week start
+ * day is set to Sunday, we don't actually show complete
+ * weeks in the week view, so this may need tweaking. */
+ starts_on_week_start_day =
+ (g_date_get_weekday (&new_start_date) % 7 == week_start_day);
+
+ /* Update selection to be in the new time range. */
+ tt = icaltime_null_time ();
+ tt.year = g_date_get_year (&new_start_date);
+ tt.month = g_date_get_month (&new_start_date);
+ tt.day = g_date_get_day (&new_start_date);
+ new_time = icaltime_as_timet_with_zone (tt, timezone);
+
+ /* Switch views as appropriate, and change the number of
+ * days or weeks shown. */
+ if (new_days_shown > 9) {
+ if (view_type != GNOME_CAL_LIST_VIEW) {
+ ECalendarView *calendar_view;
+
+ calendar_view = gnome_calendar_get_calendar_view (
+ calendar, GNOME_CAL_MONTH_VIEW);
+ e_week_view_set_weeks_shown (
+ E_WEEK_VIEW (calendar_view),
+ (new_days_shown + 6) / 7);
+ switch_to = GNOME_CAL_MONTH_VIEW;
+ }
+ } else if (new_days_shown == 7 && starts_on_week_start_day)
+ switch_to = GNOME_CAL_WEEK_VIEW;
+ else {
+ ECalendarView *calendar_view;
+
+ calendar_view = gnome_calendar_get_calendar_view (
+ calendar, GNOME_CAL_DAY_VIEW);
+ e_day_view_set_days_shown (
+ E_DAY_VIEW (calendar_view), new_days_shown);
+
+ if (new_days_shown != 5 || !starts_on_week_start_day)
+ switch_to = GNOME_CAL_DAY_VIEW;
+
+ else if (view_type != GNOME_CAL_WORK_WEEK_VIEW)
+ switch_to = GNOME_CAL_DAY_VIEW;
+ }
+
+ /* Make the views display things properly. */
+ gnome_calendar_update_view_times (calendar, new_time);
+ gnome_calendar_set_view (calendar, switch_to);
+ gnome_calendar_set_range_selected (calendar, TRUE);
+
+ gnome_calendar_notify_dates_shown_changed (calendar);
+}
+
+static void
+cal_shell_view_date_navigator_scroll_event_cb (ECalShellView *cal_shell_view,
+ GdkEventScroll *event,
+ ECalendar *date_navigator)
+{
+ ECalendarItem *calitem;
+ GDate start_date, end_date;
+
+ calitem = date_navigator->calitem;
+ if (!e_calendar_item_get_selection (calitem, &start_date, &end_date))
+ return;
+
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ g_date_subtract_months (&start_date, 1);
+ g_date_subtract_months (&end_date, 1);
+ break;
+
+ case GDK_SCROLL_DOWN:
+ g_date_add_months (&start_date, 1);
+ g_date_add_months (&end_date, 1);
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+
+ /* XXX Does ECalendarItem emit a signal for this? If so, maybe
+ * we could move this handler into ECalShellSidebar. */
+ e_calendar_item_set_selection (calitem, &start_date, &end_date);
+
+ cal_shell_view_date_navigator_date_range_changed_cb (
+ cal_shell_view, calitem);
+}
+
+static void
+cal_shell_view_popup_event_cb (EShellView *shell_view,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/calendar-event-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+}
+
+static gboolean
+cal_shell_view_selector_popup_event_cb (EShellView *shell_view,
+ ESource *primary_source,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/calendar-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+
+ return TRUE;
+}
+
+static void
+cal_shell_view_selector_client_added_cb (ECalShellView *cal_shell_view,
+ ECal *client)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+ ECalModel *model;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ model = gnome_calendar_get_model (calendar);
+
+ e_cal_model_add_client (model, client);
+}
+
+static void
+cal_shell_view_selector_client_removed_cb (ECalShellView *cal_shell_view,
+ ECal *client)
+{
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+ ECalModel *model;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ model = gnome_calendar_get_model (calendar);
+
+ e_cal_model_remove_client (model, client);
+}
+
+static void
+cal_shell_view_memopad_popup_event_cb (EShellView *shell_view,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/calendar-memopad-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+}
+
+static void
+cal_shell_view_taskpad_popup_event_cb (EShellView *shell_view,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/calendar-taskpad-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+}
+
+static void
+cal_shell_view_user_created_cb (ECalShellView *cal_shell_view,
+ ECalendarView *calendar_view)
+{
+ ECalShellSidebar *cal_shell_sidebar;
+ ECalModel *model;
+ ECal *client;
+ ESource *source;
+
+ model = e_calendar_view_get_model (calendar_view);
+ client = e_cal_model_get_default_client (model);
+ source = e_cal_get_source (client);
+
+ cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar;
+ e_cal_shell_sidebar_add_source (cal_shell_sidebar, source);
+
+ e_cal_model_add_client (model, client);
+}
+
+static void
+cal_shell_view_load_view_collection (EShellViewClass *shell_view_class)
+{
+ GalViewCollection *collection;
+ GalViewFactory *factory;
+ ETableSpecification *spec;
+ const gchar *base_dir;
+ gchar *filename;
+
+ collection = shell_view_class->view_collection;
+
+ base_dir = EVOLUTION_ETSPECDIR;
+ spec = e_table_specification_new ();
+ filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL);
+ if (!e_table_specification_load_from_file (spec, filename))
+ g_critical ("Unable to load ETable specification file "
+ "for calendars");
+ g_free (filename);
+
+ factory = calendar_view_factory_new (GNOME_CAL_DAY_VIEW);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+
+ factory = calendar_view_factory_new (GNOME_CAL_WORK_WEEK_VIEW);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+
+ factory = calendar_view_factory_new (GNOME_CAL_WEEK_VIEW);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+
+ factory = calendar_view_factory_new (GNOME_CAL_MONTH_VIEW);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+
+ factory = gal_view_factory_etable_new (spec);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+ g_object_unref (spec);
+
+ gal_view_collection_load (collection);
+}
+
+static void
+cal_shell_view_notify_view_id_cb (ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ GalViewInstance *view_instance;
+ const gchar *view_id;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ view_instance =
+ e_cal_shell_content_get_view_instance (cal_shell_content);
+ view_id = e_shell_view_get_view_id (E_SHELL_VIEW (cal_shell_view));
+
+ /* A NULL view ID implies we're in a custom view. But you can
+ * only get to a custom view via the "Define Views" dialog, which
+ * would have already modified the view instance appropriately.
+ * Furthermore, there's no way to refer to a custom view by ID
+ * anyway, since custom views have no IDs. */
+ if (view_id == NULL)
+ return;
+
+ gal_view_instance_set_current_view_id (view_instance, view_id);
+}
+
+void
+e_cal_shell_view_private_init (ECalShellView *cal_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ if (!gal_view_collection_loaded (shell_view_class->view_collection))
+ cal_shell_view_load_view_collection (shell_view_class);
+
+ g_signal_connect (
+ cal_shell_view, "notify::view-id",
+ G_CALLBACK (cal_shell_view_notify_view_id_cb), NULL);
+}
+
+void
+e_cal_shell_view_private_constructed (ECalShellView *cal_shell_view)
+{
+ ECalShellViewPrivate *priv = cal_shell_view->priv;
+ ECalShellContent *cal_shell_content;
+ ECalShellSidebar *cal_shell_sidebar;
+ EShellBackend *shell_backend;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GnomeCalendar *calendar;
+ ECalendar *date_navigator;
+ EMemoTable *memo_table;
+ ECalendarTable *task_table;
+ ESourceSelector *selector;
+ ECalModel *model;
+ gint ii;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ e_shell_window_add_action_group (shell_window, "calendar");
+ e_shell_window_add_action_group (shell_window, "calendar-filter");
+
+ /* Cache these to avoid lots of awkward casting. */
+ priv->cal_shell_backend = g_object_ref (shell_backend);
+ priv->cal_shell_content = g_object_ref (shell_content);
+ priv->cal_shell_sidebar = g_object_ref (shell_sidebar);
+
+ cal_shell_content = E_CAL_SHELL_CONTENT (shell_content);
+ model = e_cal_shell_content_get_model (cal_shell_content);
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ cal_shell_sidebar = E_CAL_SHELL_SIDEBAR (shell_sidebar);
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+ date_navigator = e_cal_shell_sidebar_get_date_navigator (cal_shell_sidebar);
+
+ /* Give GnomeCalendar a handle to the date navigator. */
+ gnome_calendar_set_date_navigator (calendar, date_navigator);
+
+ e_calendar_item_set_get_time_callback (
+ date_navigator->calitem, (ECalendarItemGetTimeCallback)
+ cal_shell_view_get_current_time, cal_shell_view, NULL);
+
+ for (ii = 0; ii < GNOME_CAL_LAST_VIEW; ii++) {
+ ECalendarView *calendar_view;
+
+ calendar_view =
+ gnome_calendar_get_calendar_view (calendar, ii);
+
+ g_signal_connect_swapped (
+ calendar_view, "popup-event",
+ G_CALLBACK (cal_shell_view_popup_event_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ calendar_view, "user-created",
+ G_CALLBACK (cal_shell_view_user_created_cb),
+ cal_shell_view);
+ }
+
+ g_signal_connect_swapped (
+ calendar, "dates-shown-changed",
+ G_CALLBACK (e_cal_shell_view_update_sidebar),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ model, "notify::timezone",
+ G_CALLBACK (e_cal_shell_view_update_timezone),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ date_navigator, "scroll-event",
+ G_CALLBACK (cal_shell_view_date_navigator_scroll_event_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ date_navigator->calitem, "date-range-changed",
+ G_CALLBACK (cal_shell_view_date_navigator_date_range_changed_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ date_navigator->calitem, "selection-changed",
+ G_CALLBACK (cal_shell_view_date_navigator_selection_changed_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ selector, "popup-event",
+ G_CALLBACK (cal_shell_view_selector_popup_event_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ cal_shell_sidebar, "client-added",
+ G_CALLBACK (cal_shell_view_selector_client_added_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ cal_shell_sidebar, "client-removed",
+ G_CALLBACK (cal_shell_view_selector_client_removed_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ memo_table, "popup-event",
+ G_CALLBACK (cal_shell_view_memopad_popup_event_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ memo_table, "status-message",
+ G_CALLBACK (e_cal_shell_view_memopad_set_status_message),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ task_table, "popup-event",
+ G_CALLBACK (cal_shell_view_taskpad_popup_event_cb),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ task_table, "status-message",
+ G_CALLBACK (e_cal_shell_view_taskpad_set_status_message),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ e_memo_table_get_table (memo_table), "selection-change",
+ G_CALLBACK (e_cal_shell_view_memopad_actions_update),
+ cal_shell_view);
+
+ g_signal_connect_swapped (
+ e_calendar_table_get_table (task_table), "selection-change",
+ G_CALLBACK (e_cal_shell_view_taskpad_actions_update),
+ cal_shell_view);
+
+ e_categories_register_change_listener (
+ G_CALLBACK (e_cal_shell_view_update_search_filter),
+ cal_shell_view);
+
+ e_cal_shell_view_actions_init (cal_shell_view);
+ e_cal_shell_view_update_sidebar (cal_shell_view);
+ e_cal_shell_view_update_search_filter (cal_shell_view);
+ e_cal_shell_view_update_timezone (cal_shell_view);
+
+ /* Keep the toolbar view buttons in sync with the calendar. */
+ e_mutual_binding_new (
+ G_OBJECT (calendar), "view",
+ G_OBJECT (ACTION (CALENDAR_VIEW_DAY)), "current-value");
+}
+
+void
+e_cal_shell_view_private_dispose (ECalShellView *cal_shell_view)
+{
+ ECalShellViewPrivate *priv = cal_shell_view->priv;
+
+ DISPOSE (priv->cal_shell_backend);
+ DISPOSE (priv->cal_shell_content);
+ DISPOSE (priv->cal_shell_sidebar);
+
+ if (priv->calendar_activity != NULL) {
+ /* XXX Activity is not cancellable. */
+ e_activity_complete (priv->calendar_activity);
+ g_object_unref (priv->calendar_activity);
+ priv->calendar_activity = NULL;
+ }
+
+ if (priv->memopad_activity != NULL) {
+ /* XXX Activity is not cancellable. */
+ e_activity_complete (priv->memopad_activity);
+ g_object_unref (priv->memopad_activity);
+ priv->memopad_activity = NULL;
+ }
+
+ if (priv->taskpad_activity != NULL) {
+ /* XXX Activity is not cancellable. */
+ e_activity_complete (priv->taskpad_activity);
+ g_object_unref (priv->taskpad_activity);
+ priv->taskpad_activity = NULL;
+ }
+}
+
+void
+e_cal_shell_view_private_finalize (ECalShellView *cal_shell_view)
+{
+ /* XXX Nothing to do? */
+}
+
+void
+e_cal_shell_view_execute_search (ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalShellSidebar *cal_shell_sidebar;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ GnomeCalendar *calendar;
+ ECalendar *date_navigator;
+ GtkRadioAction *action;
+ GString *string;
+ FilterRule *rule;
+ const gchar *format;
+ const gchar *text;
+ time_t start_range;
+ time_t end_range;
+ gboolean range_search;
+ gchar *start, *end;
+ gchar *query;
+ gchar *temp;
+ gint value;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ text = e_shell_content_get_search_text (shell_content);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action = GTK_RADIO_ACTION (ACTION (CALENDAR_SEARCH_ANY_FIELD_CONTAINS));
+ value = gtk_radio_action_get_current_value (action);
+
+ if (text == NULL || *text == '\0') {
+ text = "";
+ value = CALENDAR_SEARCH_SUMMARY_CONTAINS;
+ }
+
+ switch (value) {
+ default:
+ text = "";
+ /* fall through */
+
+ case CALENDAR_SEARCH_SUMMARY_CONTAINS:
+ format = "(contains? \"summary\" %s)";
+ break;
+
+ case CALENDAR_SEARCH_DESCRIPTION_CONTAINS:
+ format = "(contains? \"description\" %s)";
+ break;
+
+ case CALENDAR_SEARCH_ANY_FIELD_CONTAINS:
+ format = "(contains? \"any\" %s)";
+ break;
+ }
+
+ /* Build the query. */
+ string = g_string_new ("");
+ e_sexp_encode_string (string, text);
+ query = g_strdup_printf (format, string->str);
+ g_string_free (string, TRUE);
+
+ range_search = FALSE;
+ start_range = end_range = 0;
+
+ /* Apply selected filter. */
+ value = e_shell_content_get_filter_value (shell_content);
+ switch (value) {
+ case CALENDAR_FILTER_ANY_CATEGORY:
+ break;
+
+ case CALENDAR_FILTER_UNMATCHED:
+ temp = g_strdup_printf (
+ "(and (has-categories? #f) %s)", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case CALENDAR_FILTER_ACTIVE_APPOINTMENTS:
+ /* Show a year's worth of appointments. */
+ start_range = time (NULL);
+ end_range = time_add_day (start_range, 365);
+ start = isodate_from_time_t (start_range);
+ end = isodate_from_time_t (end_range);
+
+ temp = g_strdup_printf (
+ "(and %s (occur-in-time-range? "
+ "(make-time \"%s\") (make-time \"%s\")))",
+ query, start, end);
+ g_free (query);
+ query = temp;
+
+ range_search = TRUE;
+ break;
+
+ case CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS:
+ start_range = time (NULL);
+ end_range = time_add_day (start_range, 7);
+ start = isodate_from_time_t (start_range);
+ end = isodate_from_time_t (end_range);
+
+ temp = g_strdup_printf (
+ "(and %s (occur-in-time-range? "
+ "(make-time \"%s\") (make-time \"%s\")))",
+ query, start, end);
+ g_free (query);
+ query = temp;
+
+ range_search = TRUE;
+ break;
+
+ default:
+ {
+ GList *categories;
+ const gchar *category_name;
+
+ categories = e_categories_get_list ();
+ category_name = g_list_nth_data (categories, value);
+ g_list_free (categories);
+
+ temp = g_strdup_printf (
+ "(and (has-categories? \"%s\") %s)",
+ category_name, query);
+ g_free (query);
+ query = temp;
+ break;
+ }
+ }
+
+ /* XXX This is wrong. We need to programmatically construct a
+ * FilterRule, tell it to build code, and pass the resulting
+ * expressing string to ECalModel. */
+ rule = filter_rule_new ();
+ e_shell_content_set_search_rule (shell_content, rule);
+ g_object_unref (rule);
+
+ cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar;
+ date_navigator = e_cal_shell_sidebar_get_date_navigator (cal_shell_sidebar);
+
+ if (range_search) {
+ /* Switch to list view and hide the date navigator. */
+ action = GTK_RADIO_ACTION (ACTION (CALENDAR_VIEW_LIST));
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
+ gtk_widget_hide (GTK_WIDGET (date_navigator));
+ } else {
+ /* Ensure the date navigator is visible. */
+ gtk_widget_show (GTK_WIDGET (date_navigator));
+ }
+
+ /* Submit the query. */
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ gnome_calendar_set_search_query (
+ calendar, query, range_search, start_range, end_range);
+ g_free (query);
+}
+
+void
+e_cal_shell_view_open_event (ECalShellView *cal_shell_view,
+ ECalModelComponent *comp_data)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ icalproperty *prop;
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
+ g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data));
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ editor = comp_editor_find_instance (uid);
+
+ if (editor != NULL)
+ goto exit;
+
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY);
+ if (prop != NULL)
+ flags |= COMP_EDITOR_MEETING;
+
+ if (itip_organizer_is_user (comp, comp_data->client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ if (itip_sentby_is_user (comp, comp_data->client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ if (!e_cal_component_has_attendees (comp))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = event_editor_new (comp_data->client, shell, flags);
+ comp_editor_edit_comp (editor, comp);
+
+ g_object_unref (comp);
+
+exit:
+ gtk_window_present (GTK_WINDOW (editor));
+}
+
+void
+e_cal_shell_view_set_status_message (ECalShellView *cal_shell_view,
+ const gchar *status_message,
+ gdouble percent)
+{
+ EActivity *activity;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+
+ g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ activity = cal_shell_view->priv->calendar_activity;
+
+ if (status_message == NULL || *status_message == '\0') {
+ if (activity != NULL) {
+ e_activity_complete (activity);
+ g_object_unref (activity);
+ activity = NULL;
+ }
+
+ } else if (activity == NULL) {
+ activity = e_activity_new (status_message);
+ e_activity_set_percent (activity, percent);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ } else {
+ e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
+ }
+
+ cal_shell_view->priv->calendar_activity = activity;
+}
+
+void
+e_cal_shell_view_transfer_item_to (ECalShellView *cal_shell_view,
+ ECalendarViewEvent *event,
+ ECal *destination_client,
+ gboolean remove)
+{
+ icalcomponent *icalcomp;
+ icalcomponent *icalcomp_clone;
+ icalcomponent *icalcomp_event;
+ gboolean success;
+ const gchar *uid;
+
+ /* XXX This function should be split up into
+ * smaller, more understandable pieces. */
+
+ g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (E_IS_CAL (destination_client));
+
+ icalcomp_event = event->comp_data->icalcomp;
+ uid = icalcomponent_get_uid (icalcomp_event);
+
+ /* Put the new object into the destination calendar. */
+
+ success = e_cal_get_object (
+ destination_client, uid, NULL, &icalcomp, NULL);
+
+ if (success) {
+ icalcomponent_free (icalcomp);
+ success = e_cal_modify_object (
+ destination_client, icalcomp_event,
+ CALOBJ_MOD_ALL, NULL);
+ if (!success)
+ return;
+ } else {
+ icalproperty *icalprop;
+ gchar *new_uid;
+
+ if (e_cal_util_component_is_instance (icalcomp_event)) {
+ success = e_cal_get_object (
+ event->comp_data->client,
+ uid, NULL, &icalcomp, NULL);
+ if (success) {
+ /* Use master object when working
+ * with a recurring event ... */
+ icalcomp_clone =
+ icalcomponent_new_clone (icalcomp);
+ icalcomponent_free (icalcomp);
+ } else {
+ /* ... or remove the recurrence ID ... */
+ icalcomp_clone =
+ icalcomponent_new_clone (icalcomp_event);
+ if (e_cal_util_component_has_recurrences (icalcomp_clone)) {
+ /* ... for non-detached instances,
+ * to make it a master object. */
+ icalprop = icalcomponent_get_first_property (
+ icalcomp_clone, ICAL_RECURRENCEID_PROPERTY);
+ if (icalprop != NULL)
+ icalcomponent_remove_property (
+ icalcomp_clone, icalprop);
+ }
+ }
+ } else
+ icalcomp_clone =
+ icalcomponent_new_clone (icalcomp_event);
+
+ icalprop = icalproperty_new_x ("1");
+ icalproperty_set_x_name (icalprop, "X-EVOLUTION-MOVE-CALENDAR");
+ icalcomponent_add_property (icalcomp_clone, icalprop);
+
+ if (!remove) {
+ /* Change the UID to avoid problems with
+ * duplicated UIDs. */
+ new_uid = e_cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp_clone, new_uid);
+ g_free (new_uid);
+ }
+
+ new_uid = NULL;
+ success = e_cal_create_object (
+ destination_client, icalcomp_clone, &new_uid, NULL);
+ if (!success) {
+ icalcomponent_free (icalcomp_clone);
+ return;
+ }
+
+ icalcomponent_free (icalcomp_clone);
+ g_free (new_uid);
+ }
+
+ if (remove) {
+ ECal *source_client = event->comp_data->client;
+
+ /* Remove the item from the source calendar. */
+ if (e_cal_util_component_is_instance (icalcomp_event) ||
+ e_cal_util_component_has_recurrences (icalcomp_event)) {
+ icaltimetype icaltime;
+ gchar *rid;
+
+ icaltime =
+ icalcomponent_get_recurrenceid (icalcomp_event);
+ if (!icaltime_is_null_time (icaltime))
+ rid = icaltime_as_ical_string_r (icaltime);
+ else
+ rid = NULL;
+ e_cal_remove_object_with_mod (
+ source_client, uid, rid, CALOBJ_MOD_ALL, NULL);
+ g_free (rid);
+ } else
+ e_cal_remove_object (source_client, uid, NULL);
+ }
+}
+
+void
+e_cal_shell_view_update_sidebar (ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ ECalShellContent *cal_shell_content;
+ GnomeCalendar *calendar;
+ GnomeCalendarViewType view_type;
+ ECalendarView *calendar_view;
+ ECalModel *model;
+ time_t start_time, end_time;
+ struct tm start_tm, end_tm;
+ struct icaltimetype start_tt, end_tt;
+ icaltimezone *timezone;
+ gchar buffer[512];
+ gchar end_buffer[512];
+
+ g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+
+ model = gnome_calendar_get_model (calendar);
+ timezone = e_cal_model_get_timezone (model);
+
+ view_type = gnome_calendar_get_view (calendar);
+ calendar_view = gnome_calendar_get_calendar_view (calendar, view_type);
+
+ e_calendar_view_get_visible_time_range (
+ calendar_view, &start_time, &end_time);
+
+ start_tt = icaltime_from_timet_with_zone (start_time, FALSE, timezone);
+ start_tm.tm_year = start_tt.year - 1900;
+ start_tm.tm_mon = start_tt.month - 1;
+ start_tm.tm_mday = start_tt.day;
+ start_tm.tm_hour = start_tt.hour;
+ start_tm.tm_min = start_tt.minute;
+ start_tm.tm_sec = start_tt.second;
+ start_tm.tm_isdst = -1;
+ start_tm.tm_wday = time_day_of_week (
+ start_tt.day, start_tt.month - 1, start_tt.year);
+
+ /* Subtract one from end_time so we don't get an extra day. */
+ end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, timezone);
+ end_tm.tm_year = end_tt.year - 1900;
+ end_tm.tm_mon = end_tt.month - 1;
+ end_tm.tm_mday = end_tt.day;
+ end_tm.tm_hour = end_tt.hour;
+ end_tm.tm_min = end_tt.minute;
+ end_tm.tm_sec = end_tt.second;
+ end_tm.tm_isdst = -1;
+ end_tm.tm_wday = time_day_of_week (
+ end_tt.day, end_tt.month - 1, end_tt.year);
+
+ switch (view_type) {
+ case GNOME_CAL_DAY_VIEW:
+ case GNOME_CAL_WORK_WEEK_VIEW:
+ case GNOME_CAL_WEEK_VIEW:
+ if (start_tm.tm_year == end_tm.tm_year &&
+ start_tm.tm_mon == end_tm.tm_mon &&
+ start_tm.tm_mday == end_tm.tm_mday) {
+ e_utf8_strftime (
+ buffer, sizeof (buffer),
+ _("%A %d %b %Y"), &start_tm);
+ } else if (start_tm.tm_year == end_tm.tm_year) {
+ e_utf8_strftime (
+ buffer, sizeof (buffer),
+ _("%a %d %b"), &start_tm);
+ e_utf8_strftime (
+ end_buffer, sizeof (end_buffer),
+ _("%a %d %b %Y"), &end_tm);
+ strcat (buffer, " - ");
+ strcat (buffer, end_buffer);
+ } else {
+ e_utf8_strftime (
+ buffer, sizeof (buffer),
+ _("%a %d %b %Y"), &start_tm);
+ e_utf8_strftime (
+ end_buffer, sizeof (end_buffer),
+ _("%a %d %b %Y"), &end_tm);
+ strcat (buffer, " - ");
+ strcat (buffer, end_buffer);
+ }
+ break;
+
+ case GNOME_CAL_MONTH_VIEW:
+ case GNOME_CAL_LIST_VIEW:
+ if (start_tm.tm_year == end_tm.tm_year) {
+ if (start_tm.tm_mon == end_tm.tm_mon) {
+ e_utf8_strftime (
+ buffer,
+ sizeof (buffer),
+ "%d", &start_tm);
+ e_utf8_strftime (
+ end_buffer,
+ sizeof (end_buffer),
+ _("%d %b %Y"), &end_tm);
+ strcat (buffer, " - ");
+ strcat (buffer, end_buffer);
+ } else {
+ e_utf8_strftime (
+ buffer,
+ sizeof (buffer),
+ _("%d %b"), &start_tm);
+ e_utf8_strftime (
+ end_buffer,
+ sizeof (end_buffer),
+ _("%d %b %Y"), &end_tm);
+ strcat (buffer, " - ");
+ strcat (buffer, end_buffer);
+ }
+ } else {
+ e_utf8_strftime (
+ buffer, sizeof (buffer),
+ _("%d %b %Y"), &start_tm);
+ e_utf8_strftime (
+ end_buffer, sizeof (end_buffer),
+ _("%d %b %Y"), &end_tm);
+ strcat (buffer, " - ");
+ strcat (buffer, end_buffer);
+ }
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+
+ e_shell_sidebar_set_secondary_text (shell_sidebar, buffer);
+}
+
+void
+e_cal_shell_view_update_timezone (ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalShellSidebar *cal_shell_sidebar;
+ icaltimezone *timezone;
+ ECalModel *model;
+ GList *clients, *iter;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ model = e_cal_shell_content_get_model (cal_shell_content);
+ timezone = e_cal_model_get_timezone (model);
+
+ cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar;
+ clients = e_cal_shell_sidebar_get_clients (cal_shell_sidebar);
+
+ for (iter = clients; iter != NULL; iter = iter->next) {
+ ECal *client = iter->data;
+
+ if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
+ e_cal_set_default_timezone (client, timezone, NULL);
+ }
+
+ g_list_free (clients);
+}
diff --git a/modules/calendar/e-cal-shell-view-private.h b/modules/calendar/e-cal-shell-view-private.h
new file mode 100644
index 0000000000..690031198e
--- /dev/null
+++ b/modules/calendar/e-cal-shell-view-private.h
@@ -0,0 +1,180 @@
+/*
+ * e-cal-shell-view-private.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_VIEW_PRIVATE_H
+#define E_CAL_SHELL_VIEW_PRIVATE_H
+
+#include "e-cal-shell-view.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libecal/e-cal-time-util.h>
+#include <libedataserver/e-categories.h>
+#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-sexp.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/e-dialog-utils.h"
+#include "e-util/e-error.h"
+#include "e-util/e-util.h"
+#include "widgets/misc/e-popup-action.h"
+
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/e-cal-list-view.h"
+#include "calendar/gui/e-cal-model-tasks.h"
+#include "calendar/gui/e-calendar-view.h"
+#include "calendar/gui/e-day-view.h"
+#include "calendar/gui/e-week-view.h"
+#include "calendar/gui/gnome-cal.h"
+#include "calendar/gui/goto.h"
+#include "calendar/gui/print.h"
+#include "calendar/gui/dialogs/calendar-setup.h"
+#include "calendar/gui/dialogs/copy-source-dialog.h"
+#include "calendar/gui/dialogs/event-editor.h"
+#include "calendar/gui/dialogs/memo-editor.h"
+#include "calendar/gui/dialogs/select-source-dialog.h"
+#include "calendar/gui/dialogs/task-editor.h"
+
+#include "e-cal-shell-backend.h"
+#include "e-cal-shell-content.h"
+#include "e-cal-shell-sidebar.h"
+#include "e-cal-shell-view-actions.h"
+
+#define E_CAL_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CAL_SHELL_VIEW, ECalShellViewPrivate))
+
+/* Shorthand, requires a variable named "shell_window". */
+#define ACTION(name) \
+ (E_SHELL_WINDOW_ACTION_##name (shell_window))
+#define ACTION_GROUP(name) \
+ (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window))
+
+/* For use in dispose() methods. */
+#define DISPOSE(obj) \
+ G_STMT_START { \
+ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \
+ } G_STMT_END
+
+/* ETable Specifications */
+#define ETSPEC_FILENAME "e-calendar-table.etspec"
+
+G_BEGIN_DECLS
+
+/* Filter items are displayed in ascending order.
+ * Non-negative values are reserved for categories. */
+enum {
+ CALENDAR_FILTER_ANY_CATEGORY = -4,
+ CALENDAR_FILTER_UNMATCHED = -3,
+ CALENDAR_FILTER_ACTIVE_APPOINTMENTS = -2,
+ CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS = -1
+};
+
+/* Search items are displayed in ascending order. */
+enum {
+ CALENDAR_SEARCH_SUMMARY_CONTAINS,
+ CALENDAR_SEARCH_DESCRIPTION_CONTAINS,
+ CALENDAR_SEARCH_ANY_FIELD_CONTAINS
+};
+
+struct _ECalShellViewPrivate {
+
+ /* These are just for convenience. */
+ ECalShellBackend *cal_shell_backend;
+ ECalShellContent *cal_shell_content;
+ ECalShellSidebar *cal_shell_sidebar;
+
+ /* The last time explicitly selected by the user. */
+ time_t base_view_time;
+
+ EActivity *calendar_activity;
+ EActivity *memopad_activity;
+ EActivity *taskpad_activity;
+};
+
+void e_cal_shell_view_private_init
+ (ECalShellView *cal_shell_view,
+ EShellViewClass *shell_view_class);
+void e_cal_shell_view_private_constructed
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_private_dispose
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_private_finalize
+ (ECalShellView *cal_shell_view);
+
+/* Private Utilities */
+
+void e_cal_shell_view_actions_init
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_execute_search
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_open_event
+ (ECalShellView *cal_shell_view,
+ ECalModelComponent *comp_data);
+void e_cal_shell_view_set_status_message
+ (ECalShellView *cal_shell_view,
+ const gchar *status_message,
+ gdouble percent);
+void e_cal_shell_view_transfer_item_to
+ (ECalShellView *cal_shell_view,
+ ECalendarViewEvent *event,
+ ECal *destination_client,
+ gboolean remove);
+void e_cal_shell_view_update_sidebar
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_update_search_filter
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_update_timezone
+ (ECalShellView *cal_shell_view);
+
+/* Memo Pad Utilities */
+
+void e_cal_shell_view_memopad_actions_init
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_memopad_actions_update
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_memopad_open_memo
+ (ECalShellView *cal_shell_view,
+ ECalModelComponent *comp_data);
+void e_cal_shell_view_memopad_set_status_message
+ (ECalShellView *cal_shell_view,
+ const gchar *status_message,
+ gdouble percent);
+
+/* Task Pad Utilities */
+
+void e_cal_shell_view_taskpad_actions_init
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_taskpad_actions_update
+ (ECalShellView *cal_shell_view);
+void e_cal_shell_view_taskpad_open_task
+ (ECalShellView *cal_shell_view,
+ ECalModelComponent *comp_data);
+void e_cal_shell_view_taskpad_set_status_message
+ (ECalShellView *cal_shell_view,
+ const gchar *status_message,
+ gdouble percent);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_VIEW_PRIVATE_H */
diff --git a/modules/calendar/e-cal-shell-view-taskpad.c b/modules/calendar/e-cal-shell-view-taskpad.c
new file mode 100644
index 0000000000..965ec47c49
--- /dev/null
+++ b/modules/calendar/e-cal-shell-view-taskpad.c
@@ -0,0 +1,654 @@
+/*
+ * e-cal-shell-view-taskpad.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-view-private.h"
+
+/* Much of this file is based on e-task-shell-view-actions.c. */
+
+static void
+action_calendar_taskpad_assign_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only open the first selected task. */
+ e_cal_shell_view_taskpad_open_task (cal_shell_view, comp_data);
+
+ /* FIXME Need to actually assign the task. */
+}
+
+static void
+action_calendar_taskpad_clipboard_copy_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ e_calendar_table_copy_clipboard (task_table);
+}
+
+static void
+action_calendar_taskpad_clipboard_cut_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ e_calendar_table_cut_clipboard (task_table);
+}
+
+static void
+action_calendar_taskpad_clipboard_paste_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ e_calendar_table_paste_clipboard (task_table);
+}
+
+static void
+action_calendar_taskpad_delete_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ e_cal_shell_view_taskpad_set_status_message (
+ cal_shell_view, _("Deleting selected tasks..."), -1.0);
+ e_calendar_table_delete_selected (task_table);
+ e_cal_shell_view_taskpad_set_status_message (
+ cal_shell_view, NULL, -1.0);
+}
+
+static void
+action_calendar_taskpad_forward_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ GSList *list;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only forward the first selected task. */
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+ itip_send_comp (
+ E_CAL_COMPONENT_METHOD_PUBLISH, comp,
+ comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
+ g_object_unref (comp);
+}
+
+static void
+action_calendar_taskpad_mark_complete_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModel *model;
+ GSList *list, *iter;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+ list = e_calendar_table_get_selected (task_table);
+ model = e_calendar_table_get_model (task_table);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ e_cal_model_tasks_mark_comp_complete (
+ E_CAL_MODEL_TASKS (model), comp_data);
+ }
+
+ g_slist_free (list);
+}
+
+static void
+action_calendar_taskpad_mark_incomplete_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModel *model;
+ GSList *list, *iter;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+ list = e_calendar_table_get_selected (task_table);
+ model = e_calendar_table_get_model (task_table);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ e_cal_model_tasks_mark_comp_incomplete (
+ E_CAL_MODEL_TASKS (model), comp_data);
+ }
+
+ g_slist_free (list);
+}
+
+static void
+action_calendar_taskpad_new_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ ECal *client;
+ ECalComponent *comp;
+ CompEditor *editor;
+ GSList *list;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ client = comp_data->client;
+ editor = task_editor_new (client, shell, COMP_EDITOR_NEW_ITEM);
+ comp = cal_comp_task_new_with_defaults (client);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (client);
+}
+
+static void
+action_calendar_taskpad_open_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only open the first selected task. */
+ e_cal_shell_view_taskpad_open_task (cal_shell_view, comp_data);
+}
+
+static void
+action_calendar_taskpad_open_url_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ icalproperty *prop;
+ const gchar *uri;
+ GSList *list;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+
+ /* XXX We only open the URI of the first selected task. */
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_URL_PROPERTY);
+ g_return_if_fail (prop == NULL);
+
+ uri = icalproperty_get_url (prop);
+ e_show_uri (GTK_WINDOW (shell_window), uri);
+}
+
+static void
+action_calendar_taskpad_print_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ GtkPrintOperationAction print_action;
+ GSList *list;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only print the first selected task. */
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ e_cal_component_set_icalcomponent (comp, clone);
+ print_comp (comp, comp_data->client, print_action);
+ g_object_unref (comp);
+}
+
+static void
+action_calendar_taskpad_save_as_cb (GtkAction *action,
+ ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+ gchar *filename;
+ gchar *string;
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ filename = e_file_dialog_save (_("Save as..."), NULL);
+ if (filename == NULL)
+ return;
+
+ string = e_cal_get_component_as_string (
+ comp_data->client, comp_data->icalcomp);
+ if (string == NULL) {
+ g_warning ("Could not convert task to a string");
+ return;
+ }
+
+ e_write_file_uri (filename, string);
+
+ g_free (filename);
+ g_free (string);
+}
+
+static GtkActionEntry calendar_taskpad_entries[] = {
+
+ { "calendar-taskpad-assign",
+ NULL,
+ N_("_Assign Task"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_taskpad_assign_cb) },
+
+ { "calendar-taskpad-clipboard-copy",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy selected tasks"),
+ G_CALLBACK (action_calendar_taskpad_clipboard_copy_cb) },
+
+ { "calendar-taskpad-clipboard-cut",
+ GTK_STOCK_CUT,
+ NULL,
+ NULL,
+ N_("Cut selected tasks"),
+ G_CALLBACK (action_calendar_taskpad_clipboard_cut_cb) },
+
+ { "calendar-taskpad-clipboard-paste",
+ GTK_STOCK_PASTE,
+ NULL,
+ NULL,
+ N_("Paste tasks from the clipboard"),
+ G_CALLBACK (action_calendar_taskpad_clipboard_paste_cb) },
+
+ { "calendar-taskpad-delete",
+ GTK_STOCK_DELETE,
+ N_("_Delete Task"),
+ NULL,
+ N_("Delete selected tasks"),
+ G_CALLBACK (action_calendar_taskpad_delete_cb) },
+
+ { "calendar-taskpad-forward",
+ "mail-forward",
+ N_("_Forward as iCalendar..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_taskpad_forward_cb) },
+
+ { "calendar-taskpad-mark-complete",
+ NULL,
+ N_("_Mark as Complete"),
+ NULL,
+ N_("Mark selected tasks as complete"),
+ G_CALLBACK (action_calendar_taskpad_mark_complete_cb) },
+
+ { "calendar-taskpad-mark-incomplete",
+ NULL,
+ N_("_Mar_k as Incomplete"),
+ NULL,
+ N_("Mark selected tasks as incomplete"),
+ G_CALLBACK (action_calendar_taskpad_mark_incomplete_cb) },
+
+ { "calendar-taskpad-new",
+ "stock_task",
+ N_("New _Task"),
+ NULL,
+ N_("Create a new task"),
+ G_CALLBACK (action_calendar_taskpad_new_cb) },
+
+ { "calendar-taskpad-open",
+ GTK_STOCK_OPEN,
+ N_("_Open Task"),
+ NULL,
+ N_("View the selected task"),
+ G_CALLBACK (action_calendar_taskpad_open_cb) },
+
+ { "calendar-taskpad-open-url",
+ "applications-internet",
+ N_("Open _Web Page"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_taskpad_open_url_cb) },
+
+ { "calendar-taskpad-save-as",
+ GTK_STOCK_SAVE_AS,
+ N_("_Save as iCalendar..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_calendar_taskpad_save_as_cb) }
+};
+
+static GtkActionEntry lockdown_printing_entries[] = {
+
+ { "calendar-taskpad-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ NULL,
+ N_("Print the selected task"),
+ G_CALLBACK (action_calendar_taskpad_print_cb) }
+};
+
+void
+e_cal_shell_view_taskpad_actions_init (ECalShellView *cal_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ /* Calendar Actions */
+ action_group = ACTION_GROUP (CALENDAR);
+ gtk_action_group_add_actions (
+ action_group, calendar_taskpad_entries,
+ G_N_ELEMENTS (calendar_taskpad_entries), cal_shell_view);
+
+ /* Lockdown Printing Actions */
+ action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
+ gtk_action_group_add_actions (
+ action_group, lockdown_printing_entries,
+ G_N_ELEMENTS (lockdown_printing_entries), cal_shell_view);
+}
+
+void
+e_cal_shell_view_taskpad_actions_update (ECalShellView *cal_shell_view)
+{
+ ECalShellContent *cal_shell_content;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ ECalendarTable *task_table;
+ ETable *table;
+ GtkAction *action;
+ GSList *list, *iter;
+ const gchar *label;
+ gboolean assignable = TRUE;
+ gboolean editable = TRUE;
+ gboolean has_url = FALSE;
+ gboolean sensitive;
+ gint n_selected;
+ gint n_complete = 0;
+ gint n_incomplete = 0;
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_content = cal_shell_view->priv->cal_shell_content;
+ task_table = e_cal_shell_content_get_task_table (cal_shell_content);
+
+ table = e_calendar_table_get_table (task_table);
+ n_selected = e_table_selected_count (table);
+
+ list = e_calendar_table_get_selected (task_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ icalproperty *prop;
+ const gchar *cap;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ editable &= !read_only;
+
+ cap = CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT;
+ if (e_cal_get_static_capability (comp_data->client, cap))
+ assignable = FALSE;
+
+ cap = CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK;
+ if (e_cal_get_static_capability (comp_data->client, cap))
+ assignable = FALSE;
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_URL_PROPERTY);
+ has_url |= (prop != NULL);
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
+ if (prop != NULL)
+ n_complete++;
+ else
+ n_incomplete++;
+ }
+ g_slist_free (list);
+
+ action = ACTION (CALENDAR_TASKPAD_ASSIGN);
+ sensitive = (n_selected == 1) && editable && assignable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_COPY);
+ sensitive = (n_selected > 0);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_CUT);
+ sensitive = (n_selected > 0) && editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_PASTE);
+ sensitive = editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_DELETE);
+ sensitive = (n_selected > 0) && editable;
+ gtk_action_set_sensitive (action, sensitive);
+ label = ngettext ("Delete Task", "Delete Tasks", n_selected);
+ g_object_set (action, "label", label, NULL);
+
+ action = ACTION (CALENDAR_TASKPAD_FORWARD);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_MARK_COMPLETE);
+ sensitive = (n_selected > 0) && editable && (n_incomplete > 0);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_MARK_INCOMPLETE);
+ sensitive = (n_selected > 0) && editable && (n_complete > 0);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_OPEN);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_OPEN_URL);
+ sensitive = (n_selected == 1) && has_url;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_PRINT);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_TASKPAD_SAVE_AS);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+}
+
+void
+e_cal_shell_view_taskpad_open_task (ECalShellView *cal_shell_view,
+ ECalModelComponent *comp_data)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ icalproperty *prop;
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
+ g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data));
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ editor = comp_editor_find_instance (uid);
+
+ if (editor != NULL)
+ goto exit;
+
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY);
+ if (prop != NULL)
+ flags |= COMP_EDITOR_IS_ASSIGNED;
+
+ if (itip_organizer_is_user (comp, comp_data->client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ if (!e_cal_component_has_attendees (comp))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = task_editor_new (comp_data->client, shell, flags);
+ comp_editor_edit_comp (editor, comp);
+
+ g_object_ref (comp);
+
+ if (flags & COMP_EDITOR_IS_ASSIGNED)
+ task_editor_show_assignment (TASK_EDITOR (editor));
+
+exit:
+ gtk_window_present (GTK_WINDOW (editor));
+}
+
+void
+e_cal_shell_view_taskpad_set_status_message (ECalShellView *cal_shell_view,
+ const gchar *status_message,
+ gdouble percent)
+{
+ EActivity *activity;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+
+ g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view));
+
+ shell_view = E_SHELL_VIEW (cal_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ activity = cal_shell_view->priv->taskpad_activity;
+
+ if (status_message == NULL || *status_message == '\0') {
+ if (activity != NULL) {
+ e_activity_complete (activity);
+ g_object_unref (activity);
+ activity = NULL;
+ }
+
+ } else if (activity == NULL) {
+ activity = e_activity_new (status_message);
+ e_activity_set_percent (activity, percent);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ } else {
+ e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
+ }
+
+ cal_shell_view->priv->taskpad_activity = activity;
+}
diff --git a/modules/calendar/e-cal-shell-view.c b/modules/calendar/e-cal-shell-view.c
new file mode 100644
index 0000000000..d9d21799b9
--- /dev/null
+++ b/modules/calendar/e-cal-shell-view.c
@@ -0,0 +1,219 @@
+/*
+ * e-cal-shell-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-shell-view-private.h"
+
+static gpointer parent_class;
+static GType cal_shell_view_type;
+
+static void
+cal_shell_view_dispose (GObject *object)
+{
+ e_cal_shell_view_private_dispose (E_CAL_SHELL_VIEW (object));
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+cal_shell_view_finalize (GObject *object)
+{
+ e_cal_shell_view_private_finalize (E_CAL_SHELL_VIEW (object));
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+cal_shell_view_constructed (GObject *object)
+{
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ e_cal_shell_view_private_constructed (E_CAL_SHELL_VIEW (object));
+}
+
+static void
+cal_shell_view_update_actions (EShellView *shell_view)
+{
+#if 0
+ ECalShellViewPrivate *priv;
+ ECalShellContent *cal_shell_content;
+ ECalShellSidebar *cal_shell_sidebar;
+ EShellWindow *shell_window;
+ GnomeCalendarViewType view_type;
+ GnomeCalendar *calendar;
+ ECalendarView *view;
+ ECalModel *model;
+ ESourceSelector *selector;
+ ESource *source;
+ GtkAction *action;
+ GList *list, *iter;
+ const gchar *uri = NULL;
+ gboolean user_created_source;
+ gboolean editable = TRUE;
+ gboolean recurring = FALSE;
+ gboolean sensitive;
+ gint n_selected;
+
+ priv = E_CAL_SHELL_VIEW_GET_PRIVATE (shell_view);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ cal_shell_content = priv->cal_shell_content;
+ calendar = e_cal_shell_content_get_calendar (cal_shell_content);
+ view_type = gnome_calendar_get_view (calendar);
+ view = gnome_calendar_get_calendar_view (calendar, view_type);
+ model = e_calendar_view_get_model (view);
+
+ cal_shell_sidebar = priv->cal_shell_sidebar;
+ selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+
+ list = e_calendar_view_get_selected_events (view);
+ n_selected = g_list_length (list);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ editable &= !read_only;
+
+ if (e_cal_util_component_has_recurrences (comp_data->icalcomp))
+ recurring |= TRUE;
+ else if (e_cal_util_component_is_instance (comp_data->icalcomp))
+ recurring |= TRUE;
+ }
+
+ source = e_source_selector_peek_primary_selection (selector);
+ if (source != NULL)
+ uri = e_source_peek_relative_uri (source);
+ user_created_source = (uri != NULL && strcmp (uri, "system") != 0);
+
+ action = ACTION (CALENDAR_COPY);
+ sensitive = (source != NULL);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_DELETE);
+ sensitive = user_created_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_PROPERTIES);
+ sensitive = (source != NULL);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (CALENDAR_RENAME);
+ sensitive = has_primary_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (EVENT_CLIPBOARD_COPY);
+ sensitive = (n_selected > 0);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (EVENT_CLIPBOARD_CUT);
+ sensitive = (n_selected > 0) && editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (EVENT_CLIPBOARD_PASTE);
+ sensitive = editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (EVENT_DELETE);
+ sensitive = (n_selected > 0) && editable && !recurring;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (EVENT_DELETE_OCCURRENCE);
+ sensitive = (n_selected > 0) && editable && recurring;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (EVENT_DELETE_OCCURRENCE_ALL);
+ sensitive = (n_selected > 0) && editable && recurring;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (EVENT_OPEN);
+ sensitive = (n_selected == 1);
+ gtk_action_set_sensitive (action, sensitive);
+#endif
+}
+
+static void
+cal_shell_view_class_init (ECalShellViewClass *class,
+ GTypeModule *type_module)
+{
+ GObjectClass *object_class;
+ EShellViewClass *shell_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECalShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = cal_shell_view_dispose;
+ object_class->finalize = cal_shell_view_finalize;
+ object_class->constructed = cal_shell_view_constructed;
+
+ shell_view_class = E_SHELL_VIEW_CLASS (class);
+ shell_view_class->label = _("Calendar");
+ shell_view_class->icon_name = "x-office-calendar";
+ shell_view_class->ui_definition = "evolution-calendars.ui";
+ shell_view_class->ui_manager_id = "org.gnome.evolution.calendars";
+ shell_view_class->search_options = "/calendar-search-options";
+ shell_view_class->search_rules = "caltypes.xml";
+ shell_view_class->new_shell_content = e_cal_shell_content_new;
+ shell_view_class->new_shell_sidebar = e_cal_shell_sidebar_new;
+ shell_view_class->update_actions = cal_shell_view_update_actions;
+}
+
+static void
+cal_shell_view_init (ECalShellView *cal_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ cal_shell_view->priv =
+ E_CAL_SHELL_VIEW_GET_PRIVATE (cal_shell_view);
+
+ e_cal_shell_view_private_init (cal_shell_view, shell_view_class);
+}
+
+GType
+e_cal_shell_view_get_type (void)
+{
+ return cal_shell_view_type;
+}
+
+void
+e_cal_shell_view_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (ECalShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ type_module,
+ sizeof (ECalShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) cal_shell_view_init,
+ NULL /* value_table */
+ };
+
+ cal_shell_view_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_VIEW,
+ "ECalShellView", &type_info, 0);
+}
diff --git a/modules/calendar/e-cal-shell-view.h b/modules/calendar/e-cal-shell-view.h
new file mode 100644
index 0000000000..0cd7382012
--- /dev/null
+++ b/modules/calendar/e-cal-shell-view.h
@@ -0,0 +1,66 @@
+/*
+ * e-cal-shell-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_SHELL_VIEW_H
+#define E_CAL_SHELL_VIEW_H
+
+#include <shell/e-shell-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CAL_SHELL_VIEW \
+ (e_cal_shell_view_get_type ())
+#define E_CAL_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CAL_SHELL_VIEW, ECalShellView))
+#define E_CAL_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CAL_SHELL_VIEW, ECalShellViewClass))
+#define E_IS_CAL_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CAL_SHELL_VIEW))
+#define E_IS_CAL_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CAL_SHELL_VIEW))
+#define E_CAL_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CAL_SHELL_VIEW, ECalShellViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalShellView ECalShellView;
+typedef struct _ECalShellViewClass ECalShellViewClass;
+typedef struct _ECalShellViewPrivate ECalShellViewPrivate;
+
+struct _ECalShellView {
+ EShellView parent;
+ ECalShellViewPrivate *priv;
+};
+
+struct _ECalShellViewClass {
+ EShellViewClass parent_class;
+};
+
+GType e_cal_shell_view_get_type (void);
+void e_cal_shell_view_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_CAL_SHELL_VIEW_H */
diff --git a/modules/calendar/e-memo-shell-backend.c b/modules/calendar/e-memo-shell-backend.c
new file mode 100644
index 0000000000..6c6a36491c
--- /dev/null
+++ b/modules/calendar/e-memo-shell-backend.c
@@ -0,0 +1,653 @@
+/*
+ * e-memo-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-memo-shell-backend.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libecal/e-cal.h>
+#include <libedataserver/e-url.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-source-group.h>
+
+#include "shell/e-shell.h"
+#include "shell/e-shell-backend.h"
+#include "shell/e-shell-window.h"
+
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/dialogs/calendar-setup.h"
+#include "calendar/gui/dialogs/memo-editor.h"
+
+#include "e-memo-shell-migrate.h"
+#include "e-memo-shell-view.h"
+
+#define E_MEMO_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEMO_SHELL_BACKEND, EMemoShellBackendPrivate))
+
+#define WEB_BASE_URI "webcal://"
+#define PERSONAL_RELATIVE_URI "system"
+
+struct _EMemoShellBackendPrivate {
+ ESourceList *source_list;
+};
+
+enum {
+ PROP_0,
+ PROP_SOURCE_LIST
+};
+
+static gpointer parent_class;
+static GType memo_shell_backend_type;
+
+static void
+memo_shell_backend_ensure_sources (EShellBackend *shell_backend)
+{
+ /* XXX This is basically the same algorithm across all modules.
+ * Maybe we could somehow integrate this into EShellBackend? */
+
+ EMemoShellBackendPrivate *priv;
+ ESourceGroup *on_this_computer;
+ ESourceGroup *on_the_web;
+ ESource *personal;
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GSList *groups, *iter;
+ const gchar *data_dir;
+ const gchar *name;
+ gchar *base_uri;
+ gchar *filename;
+
+ on_this_computer = NULL;
+ on_the_web = NULL;
+ personal = NULL;
+
+ priv = E_MEMO_SHELL_BACKEND_GET_PRIVATE (shell_backend);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ if (!e_cal_get_sources (&priv->source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL)) {
+ g_warning ("Could not get memo sources from GConf!");
+ return;
+ }
+
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ filename = g_build_filename (data_dir, "local", NULL);
+ base_uri = g_filename_to_uri (filename, NULL, NULL);
+ g_free (filename);
+
+ groups = e_source_list_peek_groups (priv->source_list);
+ for (iter = groups; iter != NULL; iter = iter->next) {
+ ESourceGroup *source_group = iter->data;
+ const gchar *group_base_uri;
+
+ group_base_uri = e_source_group_peek_base_uri (source_group);
+
+ /* Compare only "file://" part. If the user's home
+ * changes, we do not want to create another group. */
+ if (on_this_computer == NULL &&
+ strncmp (base_uri, group_base_uri, 7) == 0)
+ on_this_computer = source_group;
+
+ else if (on_the_web == NULL &&
+ strcmp (WEB_BASE_URI, group_base_uri) == 0)
+ on_the_web = source_group;
+ }
+
+ name = _("On This Computer");
+
+ if (on_this_computer != NULL) {
+ GSList *sources;
+ const gchar *group_base_uri;
+
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (on_this_computer, name);
+
+ sources = e_source_group_peek_sources (on_this_computer);
+ group_base_uri = e_source_group_peek_base_uri (on_this_computer);
+
+ /* Make sure this group includes a "Personal" source. */
+ for (iter = sources; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+
+ if (strcmp (PERSONAL_RELATIVE_URI, relative_uri) != 0)
+ continue;
+
+ personal = source;
+ break;
+ }
+
+ /* Make sure we have the correct base URI. This can
+ * change when the user's home directory changes. */
+ if (strcmp (base_uri, group_base_uri) != 0) {
+ e_source_group_set_base_uri (
+ on_this_computer, base_uri);
+
+ /* XXX We shouldn't need this sync call here as
+ * set_base_uri() results in synching to GConf,
+ * but that happens in an idle loop and too late
+ * to prevent the user from seeing a "Cannot
+ * Open ... because of invalid URI" error. */
+ e_source_list_sync (priv->source_list, NULL);
+ }
+
+ } else {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, base_uri);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ }
+
+ name = _("Personal");
+
+ if (personal == NULL) {
+ ESource *source;
+ GSList *selected;
+ gchar *primary;
+
+ source = e_source_new (name, PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (on_this_computer, source, -1);
+ g_object_unref (source);
+
+ primary = e_shell_settings_get_string (
+ shell_settings, "cal-primary-memo-list");
+
+ selected = calendar_config_get_memos_selected ();
+
+ if (primary == NULL && selected == NULL) {
+ const gchar *uid;
+
+ uid = e_source_peek_uid (source);
+ selected = g_slist_prepend (NULL, g_strdup (uid));
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-memo-list", uid);
+ calendar_config_set_memos_selected (selected);
+ }
+
+ g_slist_foreach (selected, (GFunc) g_free, NULL);
+ g_slist_free (selected);
+ g_free (primary);
+ } else {
+ /* Force the source name to the current locale. */
+ e_source_set_name (personal, name);
+ }
+
+ name = _("On The Web");
+
+ if (on_the_web == NULL) {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, WEB_BASE_URI);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ } else {
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (on_the_web, name);
+ }
+
+ g_free (base_uri);
+}
+
+static void
+memo_shell_backend_memo_new_cb (ECal *cal,
+ ECalendarStatus status,
+ EShell *shell)
+{
+ ECalComponent *comp;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+
+ /* XXX Handle errors better. */
+ if (status != E_CALENDAR_STATUS_OK)
+ return;
+
+ flags |= COMP_EDITOR_NEW_ITEM;
+
+ editor = memo_editor_new (cal, shell, flags);
+ comp = cal_comp_memo_new_with_defaults (cal);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (cal);
+}
+
+static void
+memo_shell_backend_memo_shared_new_cb (ECal *cal,
+ ECalendarStatus status,
+ EShell *shell)
+{
+ ECalComponent *comp;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+
+ /* XXX Handle errors better. */
+ if (status != E_CALENDAR_STATUS_OK)
+ return;
+
+ flags |= COMP_EDITOR_NEW_ITEM;
+ flags |= COMP_EDITOR_IS_SHARED;
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = memo_editor_new (cal, shell, flags);
+ comp = cal_comp_memo_new_with_defaults (cal);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (cal);
+}
+
+static void
+action_memo_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ ECal *cal = NULL;
+ ECalSourceType source_type;
+ ESourceList *source_list;
+ EShellSettings *shell_settings;
+ EShell *shell;
+ const gchar *action_name;
+ gchar *uid;
+
+ /* This callback is used for both memos and shared memos. */
+
+ source_type = E_CAL_SOURCE_TYPE_JOURNAL;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ if (!e_cal_get_sources (&source_list, source_type, NULL)) {
+ g_warning ("Could not get memo sources from GConf!");
+ return;
+ }
+
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-memo-list");
+
+ if (uid != NULL) {
+ ESource *source;
+
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ if (source != NULL)
+ cal = auth_new_cal_from_source (source, source_type);
+ g_free (uid);
+ }
+
+ if (cal == NULL)
+ cal = auth_new_cal_from_default (source_type);
+
+ g_return_if_fail (cal != NULL);
+
+ /* Connect the appropriate signal handler. */
+ action_name = gtk_action_get_name (action);
+ if (strcmp (action_name, "memo-shared-new") == 0)
+ g_signal_connect (
+ cal, "cal-opened",
+ G_CALLBACK (memo_shell_backend_memo_shared_new_cb),
+ shell);
+ else
+ g_signal_connect (
+ cal, "cal-opened",
+ G_CALLBACK (memo_shell_backend_memo_new_cb),
+ shell);
+
+ e_cal_open_async (cal, FALSE);
+}
+
+static void
+action_memo_list_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ calendar_setup_new_memo_list (GTK_WINDOW (shell_window));
+}
+
+static GtkActionEntry item_entries[] = {
+
+ { "memo-new",
+ "stock_insert-note",
+ NC_("New", "Mem_o"),
+ "<Shift><Control>o",
+ N_("Create a new memo"),
+ G_CALLBACK (action_memo_new_cb) },
+
+ { "memo-shared-new",
+ "stock_insert-note",
+ N_("_Shared Memo"),
+ "<Shift><Control>h",
+ N_("Create a new shared memo"),
+ G_CALLBACK (action_memo_new_cb) }
+};
+
+static GtkActionEntry source_entries[] = {
+
+ { "memo-list-new",
+ "stock_notes",
+ NC_("New", "Memo Li_st"),
+ NULL,
+ N_("Create a new memo list"),
+ G_CALLBACK (action_memo_list_new_cb) }
+};
+
+static gboolean
+memo_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
+ const gchar *uri)
+{
+ EShell *shell;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+ ECal *client;
+ ECalComponent *comp;
+ ESource *source;
+ ESourceList *source_list;
+ ECalSourceType source_type;
+ EUri *euri;
+ icalcomponent *icalcomp;
+ const gchar *cp;
+ gchar *source_uid = NULL;
+ gchar *comp_uid = NULL;
+ gchar *comp_rid = NULL;
+ gboolean handled = FALSE;
+ GError *error = NULL;
+
+ source_type = E_CAL_SOURCE_TYPE_JOURNAL;
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ if (strncmp (uri, "memo:", 5) != 0)
+ return FALSE;
+
+ euri = e_uri_new (uri);
+ cp = euri->query;
+ if (cp == NULL)
+ goto exit;
+
+ while (*cp != '\0') {
+ gchar *header;
+ gchar *content;
+ gsize header_len;
+ gsize content_len;
+
+ header_len = strcspn (cp, "=&");
+
+ /* If it's malformed, give up. */
+ if (cp[header_len] != '=')
+ break;
+
+ header = (gchar *) cp;
+ header[header_len] = '\0';
+ cp += header_len + 1;
+
+ content_len = strcspn (cp, "&");
+
+ content = g_strndup (cp, content_len);
+ if (g_ascii_strcasecmp (header, "source-uid") == 0)
+ source_uid = g_strdup (content);
+ else if (g_ascii_strcasecmp (header, "comp-uid") == 0)
+ comp_uid = g_strdup (content);
+ else if (g_ascii_strcasecmp (header, "comp-rid") == 0)
+ comp_rid = g_strdup (content);
+ g_free (content);
+
+ cp += content_len;
+ if (*cp == '&') {
+ cp++;
+ if (strcmp (cp, "amp;") == 0)
+ cp += 4;
+ }
+ }
+
+ if (source_uid == NULL || comp_uid == NULL)
+ goto exit;
+
+ /* URI is valid, so consider it handled. Whether
+ * we successfully open it is another matter... */
+ handled = TRUE;
+
+ if (!e_cal_get_sources (&source_list, source_type, NULL)) {
+ g_printerr ("Could not get memo sources from GConf!\n");
+ goto exit;
+ }
+
+ source = e_source_list_peek_source_by_uid (source_list, source_uid);
+ if (source == NULL) {
+ g_printerr ("No source for UID `%s'\n", source_uid);
+ g_object_unref (source_list);
+ goto exit;
+ }
+
+ client = auth_new_cal_from_source (source, source_type);
+ if (client == NULL || !e_cal_open (client, TRUE, &error)) {
+ g_printerr ("%s\n", error->message);
+ g_object_unref (source_list);
+ g_error_free (error);
+ goto exit;
+ }
+
+ /* XXX Copied from e_memo_shell_view_open_memo().
+ * Clearly a new utility function is needed. */
+
+ editor = comp_editor_find_instance (comp_uid);
+
+ if (editor != NULL)
+ goto present;
+
+ if (!e_cal_get_object (client, comp_uid, comp_rid, &icalcomp, &error)) {
+ g_printerr ("%s\n", error->message);
+ g_object_unref (source_list);
+ g_error_free (error);
+ goto exit;
+ }
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+
+ if (e_cal_component_has_organizer (comp))
+ flags |= COMP_EDITOR_IS_SHARED;
+
+ if (itip_organizer_is_user (comp, client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = memo_editor_new (client, shell, flags);
+ comp_editor_edit_comp (editor, comp);
+
+ g_object_unref (comp);
+
+present:
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (source_list);
+ g_object_unref (client);
+
+exit:
+ g_free (source_uid);
+ g_free (comp_uid);
+ g_free (comp_rid);
+
+ e_uri_free (euri);
+
+ return handled;
+}
+
+static void
+memo_shell_backend_window_created_cb (EShellBackend *shell_backend,
+ GtkWindow *window)
+{
+ const gchar *module_name;
+
+ if (!E_IS_SHELL_WINDOW (window))
+ return;
+
+ module_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ e_shell_window_register_new_item_actions (
+ E_SHELL_WINDOW (window), module_name,
+ item_entries, G_N_ELEMENTS (item_entries));
+
+ e_shell_window_register_new_source_actions (
+ E_SHELL_WINDOW (window), module_name,
+ source_entries, G_N_ELEMENTS (source_entries));
+}
+
+static void
+memo_shell_backend_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SOURCE_LIST:
+ g_value_set_object (
+ value,
+ e_memo_shell_backend_get_source_list (
+ E_MEMO_SHELL_BACKEND (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+memo_shell_backend_dispose (GObject *object)
+{
+ EMemoShellBackendPrivate *priv;
+
+ priv = E_MEMO_SHELL_BACKEND_GET_PRIVATE (object);
+
+ if (priv->source_list != NULL) {
+ g_object_unref (priv->source_list);
+ priv->source_list = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+memo_shell_backend_constructed (GObject *object)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell_backend = E_SHELL_BACKEND (object);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ memo_shell_backend_ensure_sources (shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "handle-uri",
+ G_CALLBACK (memo_shell_backend_handle_uri_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "window-created",
+ G_CALLBACK (memo_shell_backend_window_created_cb),
+ shell_backend);
+}
+
+static void
+memo_shell_backend_class_init (EMemoShellBackendClass *class)
+{
+ GObjectClass *object_class;
+ EShellBackendClass *shell_backend_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMemoShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = memo_shell_backend_get_property;
+ object_class->dispose = memo_shell_backend_dispose;
+ object_class->constructed = memo_shell_backend_constructed;
+
+ shell_backend_class = E_SHELL_BACKEND_CLASS (class);
+ shell_backend_class->shell_view_type = E_TYPE_MEMO_SHELL_VIEW;
+ shell_backend_class->name = "memos";
+ shell_backend_class->aliases = "";
+ shell_backend_class->schemes = "memo";
+ shell_backend_class->sort_order = 500;
+ shell_backend_class->start = NULL;
+ shell_backend_class->migrate = e_memo_shell_backend_migrate;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE_LIST,
+ g_param_spec_object (
+ "source-list",
+ _("Source List"),
+ _("The registry of memo lists"),
+ E_TYPE_SOURCE_LIST,
+ G_PARAM_READABLE));
+}
+
+static void
+memo_shell_backend_init (EMemoShellBackend *memo_shell_backend)
+{
+ memo_shell_backend->priv =
+ E_MEMO_SHELL_BACKEND_GET_PRIVATE (memo_shell_backend);
+}
+
+GType
+e_memo_shell_backend_get_type (void)
+{
+ return memo_shell_backend_type;
+}
+
+void
+e_memo_shell_backend_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EMemoShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) memo_shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMemoShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) memo_shell_backend_init,
+ NULL /* value_table */
+ };
+
+ memo_shell_backend_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_BACKEND,
+ "EMemoShellBackend", &type_info, 0);
+}
+
+ESourceList *
+e_memo_shell_backend_get_source_list (EMemoShellBackend *memo_shell_backend)
+{
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_BACKEND (memo_shell_backend), NULL);
+
+ return memo_shell_backend->priv->source_list;
+}
diff --git a/modules/calendar/e-memo-shell-backend.h b/modules/calendar/e-memo-shell-backend.h
new file mode 100644
index 0000000000..37fe41a784
--- /dev/null
+++ b/modules/calendar/e-memo-shell-backend.h
@@ -0,0 +1,70 @@
+/*
+ * e-memo-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MEMO_SHELL_BACKEND_H
+#define E_MEMO_SHELL_BACKEND_H
+
+#include <shell/e-shell-backend.h>
+#include <libedataserver/e-source-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MEMO_SHELL_BACKEND \
+ (e_memo_shell_backend_get_type ())
+#define E_MEMO_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEMO_SHELL_BACKEND, EMemoShellBackend))
+#define E_MEMO_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEMO_SHELL_BACKEND, EMemoShellBackendClass))
+#define E_IS_MEMO_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEMO_SHELL_BACKEND))
+#define E_IS_MEMO_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MEMO_SHELL_BACKEND))
+#define E_MEMO_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEMO_SHELL_BACKEND, EMemoShellBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMemoShellBackend EMemoShellBackend;
+typedef struct _EMemoShellBackendClass EMemoShellBackendClass;
+typedef struct _EMemoShellBackendPrivate EMemoShellBackendPrivate;
+
+struct _EMemoShellBackend {
+ EShellBackend parent;
+ EMemoShellBackendPrivate *priv;
+};
+
+struct _EMemoShellBackendClass {
+ EShellBackendClass parent_class;
+};
+
+GType e_memo_shell_backend_get_type (void);
+void e_memo_shell_backend_register_type
+ (GTypeModule *type_module);
+ESourceList * e_memo_shell_backend_get_source_list
+ (EMemoShellBackend *memo_shell_backend);
+
+G_END_DECLS
+
+#endif /* E_MEMO_SHELL_BACKEND_H */
diff --git a/modules/calendar/e-memo-shell-content.c b/modules/calendar/e-memo-shell-content.c
new file mode 100644
index 0000000000..2f4e436056
--- /dev/null
+++ b/modules/calendar/e-memo-shell-content.c
@@ -0,0 +1,721 @@
+/*
+ * e-memo-shell-content.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-memo-shell-content.h"
+
+#include <glib/gi18n.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/gconf-bridge.h"
+#include "widgets/menus/gal-view-etable.h"
+#include "widgets/misc/e-paned.h"
+
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/e-cal-model-memos.h"
+#include "calendar/gui/e-memo-table.h"
+
+#define E_MEMO_SHELL_CONTENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEMO_SHELL_CONTENT, EMemoShellContentPrivate))
+
+#define E_MEMO_TABLE_DEFAULT_STATE \
+ "<?xml version=\"1.0\"?>" \
+ "<ETableState>" \
+ " <column source=\"1\"/>" \
+ " <column source=\"0\"/>" \
+ " <column source=\"2\"/>" \
+ " <grouping/>" \
+ "</ETableState>"
+
+struct _EMemoShellContentPrivate {
+ GtkWidget *paned;
+ GtkWidget *memo_table;
+ GtkWidget *memo_preview;
+
+ ECalModel *memo_model;
+ GalViewInstance *view_instance;
+ GtkOrientation orientation;
+
+ gchar *current_uid;
+
+ guint preview_visible : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_MODEL,
+ PROP_ORIENTATION,
+ PROP_PREVIEW_VISIBLE
+};
+
+enum {
+ TARGET_VCALENDAR
+};
+
+static GtkTargetEntry drag_types[] = {
+ { (gchar *) "text/calendar", 0, TARGET_VCALENDAR },
+ { (gchar *) "text/x-calendar", 0, TARGET_VCALENDAR }
+};
+
+static gpointer parent_class;
+static GType memo_shell_content_type;
+
+static void
+memo_shell_content_display_view_cb (EMemoShellContent *memo_shell_content,
+ GalView *gal_view)
+{
+ EMemoTable *memo_table;
+ ETable *table;
+
+ if (!GAL_IS_VIEW_ETABLE (gal_view))
+ return;
+
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ table = e_memo_table_get_table (memo_table);
+
+ gal_view_etable_attach_table (GAL_VIEW_ETABLE (gal_view), table);
+}
+
+static void
+memo_shell_content_table_foreach_cb (gint model_row,
+ gpointer user_data)
+{
+ ECalModelComponent *comp_data;
+ icalcomponent *clone;
+ icalcomponent *vcal;
+ gchar *string;
+
+ struct {
+ ECalModel *model;
+ GSList *list;
+ } *foreach_data = user_data;
+
+ comp_data = e_cal_model_get_component_at (
+ foreach_data->model, model_row);
+
+ vcal = e_cal_util_new_top_level ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
+ icalcomponent_add_component (vcal, clone);
+
+ /* String is owned by libical; do not free. */
+ string = icalcomponent_as_ical_string (vcal);
+ if (string != NULL) {
+ ESource *source;
+ const gchar *source_uid;
+
+ source = e_cal_get_source (comp_data->client);
+ source_uid = e_source_peek_uid (source);
+
+ foreach_data->list = g_slist_prepend (
+ foreach_data->list,
+ g_strdup_printf ("%s\n%s", source_uid, string));
+ }
+
+ icalcomponent_free (vcal);
+}
+
+static void
+memo_shell_content_table_drag_data_get_cb (EMemoShellContent *memo_shell_content,
+ gint row,
+ gint col,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
+{
+ EMemoTable *memo_table;
+ ETable *table;
+
+ struct {
+ ECalModel *model;
+ GSList *list;
+ } foreach_data;
+
+ if (info != TARGET_VCALENDAR)
+ return;
+
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ table = e_memo_table_get_table (memo_table);
+
+ foreach_data.model = e_memo_table_get_model (memo_table);
+ foreach_data.list = NULL;
+
+ e_table_selected_row_foreach (
+ table, memo_shell_content_table_foreach_cb,
+ &foreach_data);
+
+ if (foreach_data.list != NULL) {
+ cal_comp_selection_set_string_list (
+ selection_data, foreach_data.list);
+ g_slist_foreach (foreach_data.list, (GFunc) g_free, NULL);
+ g_slist_free (foreach_data.list);
+ }
+}
+
+static void
+memo_shell_content_table_drag_data_delete_cb (EMemoShellContent *memo_shell_content,
+ gint row,
+ gint col,
+ GdkDragContext *context)
+{
+ /* Moved components are deleted from source immediately when moved,
+ * because some of them can be part of destination source, and we
+ * don't want to delete not-moved memos. There is no such information
+ * which event has been moved and which not, so skip this method. */
+}
+
+static void
+memo_shell_content_cursor_change_cb (EMemoShellContent *memo_shell_content,
+ gint row,
+ ETable *table)
+{
+ ECalComponentPreview *memo_preview;
+ EMemoTable *memo_table;
+ ECalModel *memo_model;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ const gchar *uid;
+
+ memo_model = e_memo_shell_content_get_memo_model (memo_shell_content);
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content);
+
+ if (e_table_selected_count (table) != 1) {
+ e_cal_component_preview_clear (memo_preview);
+ return;
+ }
+
+ row = e_table_get_cursor_row (table);
+ comp_data = e_cal_model_get_component_at (memo_model, row);
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (comp_data->icalcomp));
+ e_cal_component_preview_display (
+ memo_preview, comp_data->client, comp);
+
+ e_cal_component_get_uid (comp, &uid);
+ g_free (memo_shell_content->priv->current_uid);
+ memo_shell_content->priv->current_uid = g_strdup (uid);
+
+ g_object_unref (comp);
+}
+
+static void
+memo_shell_content_selection_change_cb (EMemoShellContent *memo_shell_content,
+ ETable *table)
+{
+ ECalComponentPreview *memo_preview;
+
+ memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content);
+
+ /* XXX Old code emits a "selection-changed" signal here. */
+
+ if (e_table_selected_count (table) != 1)
+ e_cal_component_preview_clear (memo_preview);
+}
+
+static void
+memo_shell_content_model_row_changed_cb (EMemoShellContent *memo_shell_content,
+ gint row,
+ ETableModel *model)
+{
+ ECalModelComponent *comp_data;
+ EMemoTable *memo_table;
+ ETable *table;
+ const gchar *current_uid;
+ const gchar *uid;
+
+ current_uid = memo_shell_content->priv->current_uid;
+ if (current_uid == NULL)
+ return;
+
+ comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
+ if (comp_data == NULL)
+ return;
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ if (g_strcmp0 (uid, current_uid) != 0)
+ return;
+
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ table = e_memo_table_get_table (memo_table);
+
+ memo_shell_content_cursor_change_cb (memo_shell_content, 0, table);
+}
+
+static GtkOrientation
+memo_shell_content_get_orientation (EMemoShellContent *memo_shell_content)
+{
+ return memo_shell_content->priv->orientation;
+}
+
+static void
+memo_shell_content_set_orientation (EMemoShellContent *memo_shell_content,
+ GtkOrientation orientation)
+{
+ memo_shell_content->priv->orientation = orientation;
+
+ g_object_notify (G_OBJECT (memo_shell_content), "orientation");
+}
+
+static void
+memo_shell_content_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ORIENTATION:
+ memo_shell_content_set_orientation (
+ E_MEMO_SHELL_CONTENT (object),
+ g_value_get_enum (value));
+ return;
+
+ case PROP_PREVIEW_VISIBLE:
+ e_memo_shell_content_set_preview_visible (
+ E_MEMO_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+memo_shell_content_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (
+ value,
+ e_memo_shell_content_get_memo_model (
+ E_MEMO_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_ORIENTATION:
+ g_value_set_enum (
+ value,
+ memo_shell_content_get_orientation (
+ E_MEMO_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_PREVIEW_VISIBLE:
+ g_value_set_boolean (
+ value,
+ e_memo_shell_content_get_preview_visible (
+ E_MEMO_SHELL_CONTENT (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+memo_shell_content_dispose (GObject *object)
+{
+ EMemoShellContentPrivate *priv;
+
+ priv = E_MEMO_SHELL_CONTENT_GET_PRIVATE (object);
+
+ if (priv->paned != NULL) {
+ g_object_unref (priv->paned);
+ priv->paned = NULL;
+ }
+
+ if (priv->memo_table != NULL) {
+ g_object_unref (priv->memo_table);
+ priv->memo_table = NULL;
+ }
+
+ if (priv->memo_preview != NULL) {
+ g_object_unref (priv->memo_preview);
+ priv->memo_preview = NULL;
+ }
+
+ if (priv->memo_model != NULL) {
+ g_object_unref (priv->memo_model);
+ priv->memo_model = NULL;
+ }
+
+ if (priv->view_instance != NULL) {
+ g_object_unref (priv->view_instance);
+ priv->view_instance = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+memo_shell_content_finalize (GObject *object)
+{
+ EMemoShellContentPrivate *priv;
+
+ priv = E_MEMO_SHELL_CONTENT_GET_PRIVATE (object);
+
+ g_free (priv->current_uid);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+memo_shell_content_constructed (GObject *object)
+{
+ EMemoShellContentPrivate *priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellSettings *shell_settings;
+ EShellBackend *shell_backend;
+ EShellContent *shell_content;
+ GalViewInstance *view_instance;
+ icaltimezone *timezone;
+ ETable *table;
+ GConfBridge *bridge;
+ GtkWidget *container;
+ GtkWidget *widget;
+ const gchar *key;
+
+ priv = E_MEMO_SHELL_CONTENT_GET_PRIVATE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_content = E_SHELL_CONTENT (object);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ priv->memo_model = e_cal_model_memos_new (shell_settings);
+
+ timezone = e_shell_settings_get_pointer (
+ shell_settings, "cal-timezone");
+
+ /* Build content widgets. */
+
+ container = GTK_WIDGET (object);
+
+ widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->paned = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (object), "orientation",
+ G_OBJECT (widget), "orientation");
+
+ container = widget;
+
+ widget = e_memo_table_new (shell_view, priv->memo_model);
+ gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
+ priv->memo_table = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (object), "preview-visible",
+ G_OBJECT (widget), "visible");
+
+ container = widget;
+
+ widget = e_cal_component_preview_new ();
+ e_cal_component_preview_set_default_timezone (
+ E_CAL_COMPONENT_PREVIEW (widget), timezone);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->memo_preview = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Configure the memo table. */
+
+ widget = E_MEMO_TABLE (priv->memo_table)->etable;
+ table = e_table_scrolled_get_table (E_TABLE_SCROLLED (widget));
+
+ e_table_set_state (table, E_MEMO_TABLE_DEFAULT_STATE);
+
+ e_table_drag_source_set (
+ table, GDK_BUTTON1_MASK,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_ASK);
+
+ g_signal_connect_swapped (
+ table, "table-drag-data-get",
+ G_CALLBACK (memo_shell_content_table_drag_data_get_cb),
+ object);
+
+ g_signal_connect_swapped (
+ table, "table-drag-data-delete",
+ G_CALLBACK (memo_shell_content_table_drag_data_delete_cb),
+ object);
+
+ g_signal_connect_swapped (
+ table, "cursor-change",
+ G_CALLBACK (memo_shell_content_cursor_change_cb),
+ object);
+
+ g_signal_connect_swapped (
+ table, "selection-change",
+ G_CALLBACK (memo_shell_content_selection_change_cb),
+ object);
+
+ g_signal_connect_swapped (
+ priv->memo_model, "model-row-changed",
+ G_CALLBACK (memo_shell_content_model_row_changed_cb),
+ object);
+
+ /* Load the view instance. */
+
+ view_instance = e_shell_view_new_view_instance (shell_view, NULL);
+ g_signal_connect_swapped (
+ view_instance, "display-view",
+ G_CALLBACK (memo_shell_content_display_view_cb),
+ object);
+ gal_view_instance_load (view_instance);
+ priv->view_instance = view_instance;
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/calendar/display/memo_hpane_position";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "hposition");
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/calendar/display/memo_vpane_position";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "vposition");
+}
+
+static guint32
+memo_shell_content_check_state (EShellContent *shell_content)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ETable *table;
+ GSList *list, *iter;
+ gboolean editable = TRUE;
+ gboolean has_url = FALSE;
+ gint n_selected;
+ guint32 state = 0;
+
+ memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content);
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ table = e_memo_table_get_table (memo_table);
+ n_selected = e_table_selected_count (table);
+
+ list = e_memo_table_get_selected (memo_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ icalproperty *prop;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ editable &= !read_only;
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_URL_PROPERTY);
+ has_url |= (prop != NULL);
+ }
+ g_slist_free (list);
+
+ if (n_selected == 1)
+ state |= E_MEMO_SHELL_CONTENT_SELECTION_SINGLE;
+ if (n_selected > 1)
+ state |= E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE;
+ if (editable)
+ state |= E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT;
+ if (has_url)
+ state |= E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL;
+
+ return state;
+}
+
+static void
+memo_shell_content_class_init (EMemoShellContentClass *class)
+{
+ GObjectClass *object_class;
+ EShellContentClass *shell_content_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMemoShellContentPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = memo_shell_content_set_property;
+ object_class->get_property = memo_shell_content_get_property;
+ object_class->dispose = memo_shell_content_dispose;
+ object_class->finalize = memo_shell_content_finalize;
+ object_class->constructed = memo_shell_content_constructed;
+
+ shell_content_class = E_SHELL_CONTENT_CLASS (class);
+ shell_content_class->check_state = memo_shell_content_check_state;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ _("Model"),
+ _("The memo table model"),
+ E_TYPE_CAL_MODEL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PREVIEW_VISIBLE,
+ g_param_spec_boolean (
+ "preview-visible",
+ _("Preview is Visible"),
+ _("Whether the preview pane is visible"),
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_override_property (
+ object_class, PROP_ORIENTATION, "orientation");
+}
+
+static void
+memo_shell_content_init (EMemoShellContent *memo_shell_content)
+{
+ memo_shell_content->priv =
+ E_MEMO_SHELL_CONTENT_GET_PRIVATE (memo_shell_content);
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_memo_shell_content_get_type (void)
+{
+ return memo_shell_content_type;
+}
+
+void
+e_memo_shell_content_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EMemoShellContentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) memo_shell_content_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMemoShellContent),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) memo_shell_content_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo orientable_info = {
+ (GInterfaceInitFunc) NULL,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ memo_shell_content_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_CONTENT,
+ "EMemoShellContent", &type_info, 0);
+
+ g_type_module_add_interface (
+ type_module, memo_shell_content_type,
+ GTK_TYPE_ORIENTABLE, &orientable_info);
+}
+
+GtkWidget *
+e_memo_shell_content_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_MEMO_SHELL_CONTENT,
+ "shell-view", shell_view, NULL);
+}
+
+ECalModel *
+e_memo_shell_content_get_memo_model (EMemoShellContent *memo_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_CONTENT (memo_shell_content), NULL);
+
+ return memo_shell_content->priv->memo_model;
+}
+
+ECalComponentPreview *
+e_memo_shell_content_get_memo_preview (EMemoShellContent *memo_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_CONTENT (memo_shell_content), NULL);
+
+ return E_CAL_COMPONENT_PREVIEW (
+ memo_shell_content->priv->memo_preview);
+}
+
+EMemoTable *
+e_memo_shell_content_get_memo_table (EMemoShellContent *memo_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_CONTENT (memo_shell_content), NULL);
+
+ return E_MEMO_TABLE (memo_shell_content->priv->memo_table);
+}
+
+gboolean
+e_memo_shell_content_get_preview_visible (EMemoShellContent *memo_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_CONTENT (memo_shell_content), FALSE);
+
+ return memo_shell_content->priv->preview_visible;
+}
+
+void
+e_memo_shell_content_set_preview_visible (EMemoShellContent *memo_shell_content,
+ gboolean preview_visible)
+{
+ g_return_if_fail (E_IS_MEMO_SHELL_CONTENT (memo_shell_content));
+
+ memo_shell_content->priv->preview_visible = preview_visible;
+
+ g_object_notify (G_OBJECT (memo_shell_content), "preview-visible");
+}
+
+GalViewInstance *
+e_memo_shell_content_get_view_instance (EMemoShellContent *memo_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_CONTENT (memo_shell_content), NULL);
+
+ return memo_shell_content->priv->view_instance;
+}
diff --git a/modules/calendar/e-memo-shell-content.h b/modules/calendar/e-memo-shell-content.h
new file mode 100644
index 0000000000..ae2710e148
--- /dev/null
+++ b/modules/calendar/e-memo-shell-content.h
@@ -0,0 +1,96 @@
+/*
+ * e-memo-shell-content.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MEMO_SHELL_CONTENT_H
+#define E_MEMO_SHELL_CONTENT_H
+
+#include <shell/e-shell-content.h>
+#include <shell/e-shell-view.h>
+
+#include <calendar/gui/e-memo-table.h>
+#include <calendar/gui/e-cal-component-preview.h>
+
+#include <menus/gal-view-instance.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MEMO_SHELL_CONTENT \
+ (e_memo_shell_content_get_type ())
+#define E_MEMO_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEMO_SHELL_CONTENT, EMemoShellContent))
+#define E_MEMO_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEMO_SHELL_CONTENT, EMemoShellContentClass))
+#define E_IS_MEMO_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEMO_SHELL_CONTENT))
+#define E_IS_MEMO_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MEMO_SHELL_CONTENT))
+#define E_MEMO_SHELL_CONTENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEMO_SHELL_CONTENT, EMemoShellContentClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMemoShellContent EMemoShellContent;
+typedef struct _EMemoShellContentClass EMemoShellContentClass;
+typedef struct _EMemoShellContentPrivate EMemoShellContentPrivate;
+
+enum {
+ E_MEMO_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0,
+ E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1,
+ E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT = 1 << 2,
+ E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL = 1 << 3
+};
+
+struct _EMemoShellContent {
+ EShellContent parent;
+ EMemoShellContentPrivate *priv;
+};
+
+struct _EMemoShellContentClass {
+ EShellContentClass parent_class;
+};
+
+GType e_memo_shell_content_get_type (void);
+void e_memo_shell_content_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_memo_shell_content_new(EShellView *shell_view);
+ECalModel * e_memo_shell_content_get_memo_model
+ (EMemoShellContent *memo_shell_conent);
+ECalComponentPreview *
+ e_memo_shell_content_get_memo_preview
+ (EMemoShellContent *memo_shell_content);
+EMemoTable * e_memo_shell_content_get_memo_table
+ (EMemoShellContent *memo_shell_content);
+gboolean e_memo_shell_content_get_preview_visible
+ (EMemoShellContent *memo_shell_content);
+void e_memo_shell_content_set_preview_visible
+ (EMemoShellContent *memo_shell_content,
+ gboolean preview_visible);
+GalViewInstance *
+ e_memo_shell_content_get_view_instance
+ (EMemoShellContent *memo_shell_content);
+
+G_END_DECLS
+
+#endif /* E_MEMO_SHELL_CONTENT_H */
diff --git a/modules/calendar/e-memo-shell-migrate.c b/modules/calendar/e-memo-shell-migrate.c
new file mode 100644
index 0000000000..3bcf3156a5
--- /dev/null
+++ b/modules/calendar/e-memo-shell-migrate.c
@@ -0,0 +1,268 @@
+/*
+ * e-memo-shell-migrate.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-memo-shell-migrate.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <camel/camel-url.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+#include <libedataserver/e-source-list.h>
+
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/calendar-config-keys.h"
+#include "shell/e-shell.h"
+
+#define WEBCAL_BASE_URI "webcal://"
+#define PERSONAL_RELATIVE_URI "system"
+#define GROUPWISE_BASE_URI "groupwise://"
+
+static void
+create_memo_sources (EShellBackend *shell_backend,
+ ESourceList *source_list,
+ ESourceGroup **on_this_computer,
+ ESourceGroup **on_the_web,
+ ESource **personal_source)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GSList *groups;
+ ESourceGroup *group;
+ gchar *base_uri, *base_uri_proto;
+ const gchar *base_dir;
+
+ *on_this_computer = NULL;
+ *on_the_web = NULL;
+ *personal_source = NULL;
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ base_dir = e_shell_backend_get_config_dir (shell_backend);
+ base_uri = g_build_filename (base_dir, "local", NULL);
+
+ base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
+
+ groups = e_source_list_peek_groups (source_list);
+ if (groups) {
+ /* groups are already there, we need to search for things... */
+ GSList *g;
+
+ for (g = groups; g; g = g->next) {
+
+ group = E_SOURCE_GROUP (g->data);
+
+ if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
+ *on_this_computer = g_object_ref (group);
+ else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
+ *on_the_web = g_object_ref (group);
+ }
+ }
+
+ if (*on_this_computer) {
+ /* make sure "Personal" shows up as a source under
+ this group */
+ GSList *sources = e_source_group_peek_sources (*on_this_computer);
+ GSList *s;
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+ if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
+ *personal_source = g_object_ref (source);
+ break;
+ }
+ }
+ } else {
+ /* create the local source group */
+ group = e_source_group_new (_("On This Computer"), base_uri_proto);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_this_computer = group;
+ }
+
+ if (!*personal_source) {
+ gchar *primary_memo_list;
+
+ /* Create the default Person memo list */
+ ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (*on_this_computer, source, -1);
+
+ primary_memo_list = e_shell_settings_get_string (
+ shell_settings, "cal-primary-memo-list");
+
+ if (!primary_memo_list && !calendar_config_get_memos_selected ()) {
+ GSList selected;
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-memo-list",
+ e_source_peek_uid (source));
+
+ selected.data = (gpointer)e_source_peek_uid (source);
+ selected.next = NULL;
+ calendar_config_set_memos_selected (&selected);
+ }
+
+ e_source_set_color_spec (source, "#BECEDD");
+ *personal_source = source;
+ }
+
+ if (!*on_the_web) {
+ /* Create the Webcal source group */
+ group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_the_web = group;
+ }
+
+ g_free (base_uri_proto);
+ g_free (base_uri);
+}
+
+static gboolean
+is_groupwise_account (EAccount *account)
+{
+ if (account->source->url != NULL) {
+ return g_str_has_prefix (account->source->url, GROUPWISE_BASE_URI);
+ } else {
+ return FALSE;
+ }
+}
+
+static void
+add_gw_esource (ESourceList *source_list, const gchar *group_name, const gchar *source_name, CamelURL *url, GConfClient *client)
+{
+ ESourceGroup *group;
+ ESource *source;
+ GSList *ids, *temp;
+ GError *error = NULL;
+ gchar *relative_uri;
+ const gchar *soap_port;
+ const gchar * use_ssl;
+ const gchar *poa_address;
+ const gchar *offline_sync;
+
+ poa_address = url->host;
+ if (!poa_address || strlen (poa_address) ==0)
+ return;
+ soap_port = camel_url_get_param (url, "soap_port");
+
+ if (!soap_port || strlen (soap_port) == 0)
+ soap_port = "7191";
+
+ use_ssl = camel_url_get_param (url, "use_ssl");
+ offline_sync = camel_url_get_param (url, "offline_sync");
+
+ group = e_source_group_new (group_name, GROUPWISE_BASE_URI);
+ if (!e_source_list_add_group (source_list, group, -1))
+ return;
+ relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
+
+ source = e_source_new (source_name, relative_uri);
+ e_source_set_property (source, "auth", "1");
+ e_source_set_property (source, "username", url->user);
+ e_source_set_property (source, "port", camel_url_get_param (url, "soap_port"));
+ e_source_set_property (source, "auth-domain", "Groupwise");
+ e_source_set_property (source, "use_ssl", use_ssl);
+ e_source_set_property (source, "offline_sync", offline_sync ? "1" : "0" );
+
+ e_source_set_color_spec (source, "#EEBC60");
+ e_source_group_add_source (group, source, -1);
+
+ ids = gconf_client_get_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, &error);
+ if ( error != NULL ) {
+ g_warning("%s (%s) %s\n", G_STRLOC, G_STRFUNC, error->message);
+ g_error_free(error);
+ }
+ ids = g_slist_append (ids, g_strdup (e_source_peek_uid (source)));
+ gconf_client_set_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, ids, NULL);
+ temp = ids;
+ for (; temp != NULL; temp = g_slist_next (temp))
+ g_free (temp->data);
+
+ g_slist_free (ids);
+ g_object_unref (source);
+ g_object_unref (group);
+ g_free (relative_uri);
+}
+
+gboolean
+e_memo_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint revision,
+ GError **error)
+{
+ ESourceGroup *on_this_computer = NULL;
+ ESourceGroup *on_the_web = NULL;
+ ESource *personal_source = NULL;
+ ESourceList *source_list = NULL;
+ gboolean retval = FALSE;
+
+ g_object_get (shell_backend, "source-list", &source_list, NULL);
+
+ /* we call this unconditionally now - create_groups either
+ creates the groups/sources or it finds the necessary
+ groups/sources. */
+ create_memo_sources (
+ shell_backend, source_list, &on_this_computer,
+ &on_the_web, &personal_source);
+
+ /* Migration for Gw accounts between versions < 2.8 */
+ if (major == 2 && minor < 8) {
+ EAccountList *al;
+ EAccount *a;
+ CamelURL *url;
+ EIterator *it;
+ GConfClient *gconf_client = gconf_client_get_default ();
+ al = e_account_list_new (gconf_client);
+ for (it = e_list_get_iterator((EList *)al);
+ e_iterator_is_valid(it);
+ e_iterator_next(it)) {
+ a = (EAccount *) e_iterator_get(it);
+ if (!a->enabled || !is_groupwise_account (a))
+ continue;
+ url = camel_url_new (a->source->url, NULL);
+ add_gw_esource (source_list, a->name, _("Notes"), url, gconf_client);
+ camel_url_free (url);
+ }
+ g_object_unref (al);
+ g_object_unref (gconf_client);
+ }
+
+ e_source_list_sync (source_list, NULL);
+ retval = TRUE;
+
+ if (on_this_computer)
+ g_object_unref (on_this_computer);
+ if (on_the_web)
+ g_object_unref (on_the_web);
+ if (personal_source)
+ g_object_unref (personal_source);
+
+ return retval;
+}
diff --git a/modules/calendar/e-memo-shell-migrate.h b/modules/calendar/e-memo-shell-migrate.h
new file mode 100644
index 0000000000..ba163c6950
--- /dev/null
+++ b/modules/calendar/e-memo-shell-migrate.h
@@ -0,0 +1,38 @@
+/*
+ * e-memo-shell-backend-migrate.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MEMO_SHELL_BACKEND_MIGRATE_H
+#define E_MEMO_SHELL_BACKEND_MIGRATE_H
+
+#include <glib.h>
+#include <shell/e-shell-backend.h>
+
+G_BEGIN_DECLS
+
+gboolean e_memo_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_MEMO_SHELL_BACKEND_MIGRATE_H */
diff --git a/modules/calendar/e-memo-shell-sidebar.c b/modules/calendar/e-memo-shell-sidebar.c
new file mode 100644
index 0000000000..33a2226c00
--- /dev/null
+++ b/modules/calendar/e-memo-shell-sidebar.c
@@ -0,0 +1,716 @@
+/*
+ * e-memo-shell-sidebar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-memo-shell-sidebar.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libecal/e-cal.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/e-error.h"
+#include "e-util/e-util.h"
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/e-memo-list-selector.h"
+#include "calendar/gui/misc.h"
+
+#include "e-memo-shell-view.h"
+#include "e-memo-shell-backend.h"
+
+#define E_MEMO_SHELL_SIDEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEMO_SHELL_SIDEBAR, EMemoShellSidebarPrivate))
+
+struct _EMemoShellSidebarPrivate {
+ GtkWidget *selector;
+ icaltimezone *timezone;
+
+ /* UID -> Client */
+ GHashTable *client_table;
+};
+
+enum {
+ PROP_0,
+ PROP_SELECTOR
+};
+
+enum {
+ CLIENT_ADDED,
+ CLIENT_REMOVED,
+ STATUS_MESSAGE,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+static GType memo_shell_sidebar_type;
+
+static void
+memo_shell_sidebar_emit_client_added (EMemoShellSidebar *memo_shell_sidebar,
+ ECal *client)
+{
+ guint signal_id = signals[CLIENT_ADDED];
+
+ g_signal_emit (memo_shell_sidebar, signal_id, 0, client);
+}
+
+static void
+memo_shell_sidebar_emit_client_removed (EMemoShellSidebar *memo_shell_sidebar,
+ ECal *client)
+{
+ guint signal_id = signals[CLIENT_REMOVED];
+
+ g_signal_emit (memo_shell_sidebar, signal_id, 0, client);
+}
+
+static void
+memo_shell_sidebar_emit_status_message (EMemoShellSidebar *memo_shell_sidebar,
+ const gchar *status_message)
+{
+ guint signal_id = signals[STATUS_MESSAGE];
+
+ g_signal_emit (memo_shell_sidebar, signal_id, 0, status_message, -1.0);
+}
+
+static void
+memo_shell_sidebar_backend_died_cb (EMemoShellSidebar *memo_shell_sidebar,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ GHashTable *client_table;
+ ESource *source;
+ const gchar *uid;
+
+ client_table = memo_shell_sidebar->priv->client_table;
+
+ shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ source = e_cal_get_source (client);
+ uid = e_source_peek_uid (source);
+
+ g_object_ref (source);
+
+ g_hash_table_remove (client_table, uid);
+ memo_shell_sidebar_emit_status_message (memo_shell_sidebar, NULL);
+
+ e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:memos-crashed", NULL);
+
+ g_object_unref (source);
+}
+
+static void
+memo_shell_sidebar_backend_error_cb (EMemoShellSidebar *memo_shell_sidebar,
+ const gchar *message,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ GtkWidget *dialog;
+ const gchar *uri;
+ gchar *uri_no_passwd;
+
+ shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ uri = e_cal_get_uri (client);
+ uri_no_passwd = get_uri_without_password (uri);
+
+ dialog = gtk_message_dialog_new (
+ GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ _("Error on %s\n%s"),
+ uri_no_passwd, message);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ g_free (uri_no_passwd);
+}
+
+static void
+memo_shell_sidebar_client_opened_cb (EMemoShellSidebar *memo_shell_sidebar,
+ ECalendarStatus status,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ ESource *source;
+
+ source = e_cal_get_source (client);
+
+ shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED ||
+ status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
+ auth_cal_forget_password (client);
+
+ switch (status) {
+ case E_CALENDAR_STATUS_OK:
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ memo_shell_sidebar_client_opened_cb, NULL);
+
+ memo_shell_sidebar_emit_status_message (
+ memo_shell_sidebar, _("Loading memos"));
+ memo_shell_sidebar_emit_client_added (
+ memo_shell_sidebar, client);
+ memo_shell_sidebar_emit_status_message (
+ memo_shell_sidebar, NULL);
+ break;
+
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
+ e_cal_open_async (client, FALSE);
+ break;
+
+ case E_CALENDAR_STATUS_BUSY:
+ break;
+
+ case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
+ e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:prompt-no-contents-offline-memos",
+ NULL);
+ break;
+
+ default:
+ memo_shell_sidebar_emit_client_removed (
+ memo_shell_sidebar, client);
+ break;
+ }
+}
+
+static void
+memo_shell_sidebar_row_changed_cb (EMemoShellSidebar *memo_shell_sidebar,
+ GtkTreePath *tree_path,
+ GtkTreeIter *tree_iter,
+ GtkTreeModel *tree_model)
+{
+ ESourceSelector *selector;
+ ESource *source;
+
+ /* XXX ESourceSelector's underlying tree store has only one
+ * column: ESource objects. While we're not supposed to
+ * know this, listening for "row-changed" signals from
+ * the model is easier to deal with than the selector's
+ * "selection-changed" signal, which doesn't tell you
+ * _which_ row changed. */
+
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+ gtk_tree_model_get (tree_model, tree_iter, 0, &source, -1);
+
+ /* XXX This signal gets emitted a lot while the model is being
+ * rebuilt, during which time we won't get a valid ESource.
+ * ESourceSelector should probably block this signal while
+ * rebuilding the model, but we'll be forgiving and not
+ * emit a warning. */
+ if (!E_IS_SOURCE (source))
+ return;
+
+ if (e_source_selector_source_is_selected (selector, source))
+ e_memo_shell_sidebar_add_source (memo_shell_sidebar, source);
+ else
+ e_memo_shell_sidebar_remove_source (memo_shell_sidebar, source);
+}
+
+static void
+memo_shell_sidebar_selection_changed_cb (EMemoShellSidebar *memo_shell_sidebar,
+ ESourceSelector *selector)
+{
+ GSList *list, *iter;
+
+ /* This signal is emitted less frequently than "row-changed",
+ * especially when the model is being rebuilt. So we'll take
+ * it easy on poor GConf. */
+
+ list = e_source_selector_get_selection (selector);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+
+ iter->data = (gpointer) e_source_peek_uid (source);
+ g_object_unref (source);
+ }
+
+ calendar_config_set_memos_selected (list);
+
+ g_slist_free (list);
+}
+
+static void
+memo_shell_sidebar_primary_selection_changed_cb (EMemoShellSidebar *memo_shell_sidebar,
+ ESourceSelector *selector)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESource *source;
+
+ /* XXX ESourceSelector needs a "primary-selection-uid" property
+ * so we can just bind the property with GConfBridge. */
+
+ source = e_source_selector_peek_primary_selection (selector);
+ if (source == NULL)
+ return;
+
+ shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-memo-list",
+ e_source_peek_uid (source));
+}
+
+static void
+memo_shell_sidebar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SELECTOR:
+ g_value_set_object (
+ value, e_memo_shell_sidebar_get_selector (
+ E_MEMO_SHELL_SIDEBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+memo_shell_sidebar_dispose (GObject *object)
+{
+ EMemoShellSidebarPrivate *priv;
+
+ priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ if (priv->selector != NULL) {
+ g_object_unref (priv->selector);
+ priv->selector = NULL;
+ }
+
+ g_hash_table_remove_all (priv->client_table);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+memo_shell_sidebar_finalize (GObject *object)
+{
+ EMemoShellSidebarPrivate *priv;
+
+ priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->client_table);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+memo_shell_sidebar_constructed (GObject *object)
+{
+ EMemoShellSidebarPrivate *priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESourceSelector *selector;
+ ESourceList *source_list;
+ ESource *source;
+ GtkContainer *container;
+ GtkTreeModel *model;
+ GtkWidget *widget;
+ AtkObject *a11y;
+ GSList *list, *iter;
+ gchar *uid;
+
+ priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_sidebar = E_SHELL_SIDEBAR (object);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ source_list = e_memo_shell_backend_get_source_list (
+ E_MEMO_SHELL_BACKEND (shell_backend));
+
+ container = GTK_CONTAINER (shell_sidebar);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_container_add (container, widget);
+ gtk_widget_show (widget);
+
+ container = GTK_CONTAINER (widget);
+
+ widget = e_memo_list_selector_new (source_list);
+ e_source_selector_set_select_new (E_SOURCE_SELECTOR (widget), TRUE);
+ gtk_container_add (container, widget);
+ a11y = gtk_widget_get_accessible (widget);
+ atk_object_set_name (a11y, _("Memo List Selector"));
+ priv->selector = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Restore the selector state from the last session. */
+
+ selector = E_SOURCE_SELECTOR (priv->selector);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ model, "row-changed",
+ G_CALLBACK (memo_shell_sidebar_row_changed_cb),
+ object);
+
+ source = NULL;
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-memo-list");
+ if (uid != NULL)
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ if (source == NULL)
+ source = e_source_list_peek_source_any (source_list);
+ if (source != NULL)
+ e_source_selector_set_primary_selection (selector, source);
+ g_free (uid);
+
+ list = calendar_config_get_memos_selected ();
+ for (iter = list; iter != NULL; iter = iter->next) {
+ uid = iter->data;
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ g_free (uid);
+
+ if (source == NULL)
+ continue;
+
+ e_source_selector_select_source (selector, source);
+ }
+ g_slist_free (list);
+
+ /* Listen for subsequent changes to the selector. */
+
+ g_signal_connect_swapped (
+ widget, "selection-changed",
+ G_CALLBACK (memo_shell_sidebar_selection_changed_cb),
+ object);
+
+ g_signal_connect_swapped (
+ widget, "primary-selection-changed",
+ G_CALLBACK (memo_shell_sidebar_primary_selection_changed_cb),
+ object);
+}
+
+static guint32
+memo_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+ EMemoShellSidebar *memo_shell_sidebar;
+ ESourceSelector *selector;
+ ESource *source;
+ gboolean is_system = FALSE;
+ guint32 state = 0;
+
+ memo_shell_sidebar = E_MEMO_SHELL_SIDEBAR (shell_sidebar);
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+
+ if (source != NULL) {
+ const gchar *uri;
+
+ uri = e_source_peek_relative_uri (source);
+ is_system = (uri == NULL || strcmp (uri, "system") == 0);
+ }
+
+ if (source != NULL)
+ state |= E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE;
+ if (is_system)
+ state |= E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM;
+
+ return state;
+}
+
+static void
+memo_shell_sidebar_client_removed (EMemoShellSidebar *memo_shell_sidebar,
+ ECal *client)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ESource *source;
+ const gchar *uid;
+
+ client_table = memo_shell_sidebar->priv->client_table;
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, memo_shell_sidebar);
+
+ source = e_cal_get_source (client);
+ e_source_selector_unselect_source (selector, source);
+
+ uid = e_source_peek_uid (source);
+ g_hash_table_remove (client_table, uid);
+
+ memo_shell_sidebar_emit_status_message (memo_shell_sidebar, NULL);
+}
+
+static void
+memo_shell_sidebar_class_init (EMemoShellSidebarClass *class)
+{
+ GObjectClass *object_class;
+ EShellSidebarClass *shell_sidebar_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMemoShellSidebarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = memo_shell_sidebar_get_property;
+ object_class->dispose = memo_shell_sidebar_dispose;
+ object_class->finalize = memo_shell_sidebar_finalize;
+ object_class->constructed = memo_shell_sidebar_constructed;
+
+ shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
+ shell_sidebar_class->check_state = memo_shell_sidebar_check_state;
+
+ class->client_removed = memo_shell_sidebar_client_removed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTOR,
+ g_param_spec_object (
+ "selector",
+ _("Source Selector Widget"),
+ _("This widget displays groups of memo lists"),
+ E_TYPE_SOURCE_SELECTOR,
+ G_PARAM_READABLE));
+
+ signals[CLIENT_ADDED] = g_signal_new (
+ "client-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMemoShellSidebarClass, client_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CAL);
+
+ signals[CLIENT_REMOVED] = g_signal_new (
+ "client-removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMemoShellSidebarClass, client_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CAL);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status-message",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMemoShellSidebarClass, status_message),
+ NULL, NULL,
+ e_marshal_VOID__STRING_DOUBLE,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_DOUBLE);
+}
+
+static void
+memo_shell_sidebar_init (EMemoShellSidebar *memo_shell_sidebar)
+{
+ GHashTable *client_table;
+
+ client_table = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ memo_shell_sidebar->priv =
+ E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (memo_shell_sidebar);
+
+ memo_shell_sidebar->priv->client_table = client_table;
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_memo_shell_sidebar_get_type (void)
+{
+ return memo_shell_sidebar_type;
+}
+
+void
+e_memo_shell_sidebar_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EMemoShellSidebarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) memo_shell_sidebar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMemoShellSidebar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) memo_shell_sidebar_init,
+ NULL /* value_table */
+ };
+
+ memo_shell_sidebar_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_SIDEBAR,
+ "EMemoShellSidebar", &type_info, 0);
+}
+
+GtkWidget *
+e_memo_shell_sidebar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_MEMO_SHELL_SIDEBAR,
+ "shell-view", shell_view, NULL);
+}
+
+GList *
+e_memo_shell_sidebar_get_clients (EMemoShellSidebar *memo_shell_sidebar)
+{
+ GHashTable *client_table;
+
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar), NULL);
+
+ client_table = memo_shell_sidebar->priv->client_table;
+
+ return g_hash_table_get_values (client_table);
+}
+
+ESourceSelector *
+e_memo_shell_sidebar_get_selector (EMemoShellSidebar *memo_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar), NULL);
+
+ return E_SOURCE_SELECTOR (memo_shell_sidebar->priv->selector);
+}
+
+void
+e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar,
+ ESource *source)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+ const gchar *uri;
+ gchar *message;
+
+ g_return_if_fail (E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar));
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ client_table = memo_shell_sidebar->priv->client_table;
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (client != NULL)
+ return;
+
+ client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+ g_return_if_fail (client != NULL);
+
+ g_signal_connect_swapped (
+ client, "backend-died",
+ G_CALLBACK (memo_shell_sidebar_backend_died_cb),
+ memo_shell_sidebar);
+
+ g_signal_connect_swapped (
+ client, "backend-error",
+ G_CALLBACK (memo_shell_sidebar_backend_error_cb),
+ memo_shell_sidebar);
+
+ g_hash_table_insert (client_table, g_strdup (uid), client);
+ e_source_selector_select_source (selector, source);
+
+ uri = e_cal_get_uri (client);
+ message = g_strdup_printf (_("Opening memos at %s"), uri);
+ memo_shell_sidebar_emit_status_message (memo_shell_sidebar, message);
+ g_free (message);
+
+ g_signal_connect_swapped (
+ client, "cal-opened",
+ G_CALLBACK (memo_shell_sidebar_client_opened_cb),
+ memo_shell_sidebar);
+
+ e_cal_open_async (client, FALSE);
+}
+
+void
+e_memo_shell_sidebar_remove_source (EMemoShellSidebar *memo_shell_sidebar,
+ ESource *source)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar));
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ client_table = memo_shell_sidebar->priv->client_table;
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (client == NULL)
+ return;
+
+ memo_shell_sidebar_emit_client_removed (memo_shell_sidebar, client);
+}
diff --git a/modules/calendar/e-memo-shell-sidebar.h b/modules/calendar/e-memo-shell-sidebar.h
new file mode 100644
index 0000000000..068d7436bc
--- /dev/null
+++ b/modules/calendar/e-memo-shell-sidebar.h
@@ -0,0 +1,97 @@
+/*
+ * e-memo-shell-sidebar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MEMO_SHELL_SIDEBAR_H
+#define E_MEMO_SHELL_SIDEBAR_H
+
+#include <libecal/e-cal.h>
+#include <libedataserverui/e-source-selector.h>
+
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MEMO_SHELL_SIDEBAR \
+ (e_memo_shell_sidebar_get_type ())
+#define E_MEMO_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEMO_SHELL_SIDEBAR, EMemoShellSidebar))
+#define E_MEMO_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEMO_SHELL_SIDEBAR, EMemoShellSidebarClass))
+#define E_IS_MEMO_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEMO_SHELL_SIDEBAR))
+#define E_IS_MEMO_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MEMO_SHELL_SIDEBAR))
+#define E_MEMO_SHELL_SIDEBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEMO_SHELL_SIDEBAR, EMemoShellSidebarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMemoShellSidebar EMemoShellSidebar;
+typedef struct _EMemoShellSidebarClass EMemoShellSidebarClass;
+typedef struct _EMemoShellSidebarPrivate EMemoShellSidebarPrivate;
+
+enum {
+ E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0,
+ E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM = 1 << 1
+};
+
+struct _EMemoShellSidebar {
+ EShellSidebar parent;
+ EMemoShellSidebarPrivate *priv;
+};
+
+struct _EMemoShellSidebarClass {
+ EShellSidebarClass parent_class;
+
+ /* Signals */
+ void (*client_added) (EMemoShellSidebar *memo_shell_sidebar,
+ ECal *client);
+ void (*client_removed) (EMemoShellSidebar *memo_shell_sidebar,
+ ECal *client);
+ void (*status_message) (EMemoShellSidebar *memo_shell_sidebar,
+ const gchar *status_message,
+ gdouble percent);
+};
+
+GType e_memo_shell_sidebar_get_type (void);
+void e_memo_shell_sidebar_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_memo_shell_sidebar_new(EShellView *shell_view);
+GList * e_memo_shell_sidebar_get_clients
+ (EMemoShellSidebar *memo_shell_sidebar);
+ESourceSelector *
+ e_memo_shell_sidebar_get_selector
+ (EMemoShellSidebar *memo_shell_sidebar);
+void e_memo_shell_sidebar_add_source
+ (EMemoShellSidebar *memo_shell_sidebar,
+ ESource *source);
+void e_memo_shell_sidebar_remove_source
+ (EMemoShellSidebar *memo_shell_sidebar,
+ ESource *source);
+
+G_END_DECLS
+
+#endif /* E_MEMO_SHELL_SIDEBAR_H */
diff --git a/modules/calendar/e-memo-shell-view-actions.c b/modules/calendar/e-memo-shell-view-actions.c
new file mode 100644
index 0000000000..0161eeb198
--- /dev/null
+++ b/modules/calendar/e-memo-shell-view-actions.c
@@ -0,0 +1,1019 @@
+/*
+ * e-memo-shell-view-actions.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-memo-shell-view-private.h"
+
+static void
+action_gal_save_custom_view_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EShellView *shell_view;
+ GalViewInstance *view_instance;
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with saving the custom view. */
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ view_instance = e_memo_shell_content_get_view_instance (memo_shell_content);
+ gal_view_instance_save_as (view_instance);
+}
+
+static void
+action_memo_clipboard_copy_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ e_memo_table_copy_clipboard (memo_table);
+}
+
+static void
+action_memo_clipboard_cut_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ e_memo_table_cut_clipboard (memo_table);
+}
+
+static void
+action_memo_clipboard_paste_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ e_memo_table_paste_clipboard (memo_table);
+}
+
+static void
+action_memo_delete_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ ECalComponentPreview *memo_preview;
+ EMemoTable *memo_table;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content);
+
+ e_memo_shell_view_set_status_message (
+ memo_shell_view, _("Deleting selected memos..."), -1.0);
+ e_memo_table_delete_selected (memo_table);
+ e_memo_shell_view_set_status_message (memo_shell_view, NULL, -1.0);
+
+ e_cal_component_preview_clear (memo_preview);
+}
+
+static void
+action_memo_forward_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ GSList *list;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only forward the first selected memo. */
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+ itip_send_comp (
+ E_CAL_COMPONENT_METHOD_PUBLISH, comp,
+ comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
+ g_object_unref (comp);
+}
+
+static void
+action_memo_list_copy_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellSidebar *memo_shell_sidebar;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ ESourceSelector *selector;
+ ESource *source;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ copy_source_dialog (
+ GTK_WINDOW (shell_window),
+ source, E_CAL_SOURCE_TYPE_JOURNAL);
+}
+
+static void
+action_memo_list_delete_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellBackend *memo_shell_backend;
+ EMemoShellContent *memo_shell_content;
+ EMemoShellSidebar *memo_shell_sidebar;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ EMemoTable *memo_table;
+ ECal *client;
+ ECalModel *model;
+ ESourceSelector *selector;
+ ESourceGroup *source_group;
+ ESourceList *source_list;
+ ESource *source;
+ gint response;
+ gchar *uri;
+ GError *error = NULL;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ memo_shell_backend = memo_shell_view->priv->memo_shell_backend;
+ source_list = e_memo_shell_backend_get_source_list (memo_shell_backend);
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ model = e_memo_table_get_model (memo_table);
+
+ memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ /* Ask for confirmation. */
+ response = e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:prompt-delete-memo-list",
+ e_source_peek_name (source));
+ if (response != GTK_RESPONSE_YES)
+ return;
+
+ uri = e_source_get_uri (source);
+ client = e_cal_model_get_client_for_uri (model, uri);
+ if (client == NULL)
+ client = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_JOURNAL);
+ g_free (uri);
+
+ g_return_if_fail (client != NULL);
+
+ if (!e_cal_remove (client, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (e_source_selector_source_is_selected (selector, source)) {
+ e_memo_shell_sidebar_remove_source (
+ memo_shell_sidebar, source);
+ e_source_selector_unselect_source (selector, source);
+ }
+
+ source_group = e_source_peek_group (source);
+ e_source_group_remove_source (source_group, source);
+
+ if (!e_source_list_sync (source_list, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+action_memo_list_new_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ calendar_setup_new_memo_list (GTK_WINDOW (shell_window));
+}
+
+static void
+action_memo_list_print_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ETable *table;
+ GtkPrintOperationAction print_action;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ table = e_memo_table_get_table (memo_table);
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ print_table (table, _("Print Memos"), _("Memos"), print_action);
+}
+
+static void
+action_memo_list_print_preview_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ETable *table;
+ GtkPrintOperationAction print_action;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ table = e_memo_table_get_table (memo_table);
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
+ print_table (table, _("Print Memos"), _("Memos"), print_action);
+}
+
+static void
+action_memo_list_properties_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellSidebar *memo_shell_sidebar;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ESource *source;
+ ESourceSelector *selector;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ calendar_setup_edit_memo_list (GTK_WINDOW (shell_window), source);
+}
+
+static void
+action_memo_list_rename_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellSidebar *memo_shell_sidebar;
+ ESourceSelector *selector;
+
+ memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+
+ e_source_selector_edit_primary_selection (selector);
+}
+
+static void
+action_memo_list_select_one_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellSidebar *memo_shell_sidebar;
+ ESourceSelector *selector;
+ ESource *primary;
+ GSList *list, *iter;
+
+ /* XXX ESourceSelector should provide a function for this. */
+
+ memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+ primary = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (primary != NULL);
+
+ list = e_source_selector_get_selection (selector);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+
+ if (source == primary)
+ continue;
+
+ e_source_selector_unselect_source (selector, source);
+ }
+ e_source_selector_free_selection (list);
+
+ e_source_selector_select_source (selector, primary);
+}
+
+static void
+action_memo_new_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECal *client;
+ ECalComponent *comp;
+ CompEditor *editor;
+ GSList *list;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ client = comp_data->client;
+ editor = memo_editor_new (client, shell, COMP_EDITOR_NEW_ITEM);
+ comp = cal_comp_memo_new_with_defaults (client);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (client);
+}
+
+static void
+action_memo_open_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only open the first selected memo. */
+ e_memo_shell_view_open_memo (memo_shell_view, comp_data);
+}
+
+static void
+action_memo_open_url_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ icalproperty *prop;
+ const gchar *uri;
+ GSList *list;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only open the URI of the first selected memo. */
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_URL_PROPERTY);
+ g_return_if_fail (prop == NULL);
+
+ uri = icalproperty_get_url (prop);
+ e_show_uri (GTK_WINDOW (shell_window), uri);
+}
+
+static void
+action_memo_preview_cb (GtkToggleAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ gboolean visible;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ visible = gtk_toggle_action_get_active (action);
+ e_memo_shell_content_set_preview_visible (memo_shell_content, visible);
+}
+
+static void
+action_memo_print_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ GtkPrintOperationAction print_action;
+ GSList *list;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only print the first selected memo. */
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ e_cal_component_set_icalcomponent (comp, clone);
+ print_comp (comp, comp_data->client, print_action);
+ g_object_unref (comp);
+}
+
+static void
+action_memo_save_as_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+ gchar *filename;
+ gchar *string;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ list = e_memo_table_get_selected (memo_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ filename = e_file_dialog_save (_("Save as..."), NULL);
+ if (filename == NULL)
+ return;
+
+ /* XXX We only save the first selected memo. */
+ string = e_cal_get_component_as_string (
+ comp_data->client, comp_data->icalcomp);
+ if (string == NULL) {
+ g_warning ("Could not convert memo to a string");
+ return;
+ }
+
+ e_write_file_uri (filename, string);
+
+ g_free (filename);
+ g_free (string);
+}
+
+static void
+action_memo_search_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMemoShellView *memo_shell_view)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *search_hint;
+
+ /* XXX Figure out a way to handle this in EShellContent
+ * instead of every shell view having to handle it.
+ * The problem is EShellContent does not know what
+ * the search option actions are for this view. It
+ * would have to dig up the popup menu and retrieve
+ * the action for each menu item. Seems messy. */
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ search_hint = gtk_action_get_label (GTK_ACTION (current));
+ e_shell_content_set_search_hint (shell_content, search_hint);
+}
+
+static void
+action_memo_view_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ orientable = GTK_ORIENTABLE (memo_shell_content);
+
+ switch (gtk_radio_action_get_current_value (action)) {
+ case 0:
+ orientation = GTK_ORIENTATION_VERTICAL;
+ break;
+ case 1:
+ orientation = GTK_ORIENTATION_HORIZONTAL;
+ break;
+ default:
+ g_return_if_reached ();
+ }
+
+ gtk_orientable_set_orientation (orientable, orientation);
+}
+
+static void
+action_search_execute_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EShellView *shell_view;
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with executing the search. */
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ e_memo_shell_view_execute_search (memo_shell_view);
+}
+
+static void
+action_search_filter_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMemoShellView *memo_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+}
+
+static GtkActionEntry memo_entries[] = {
+
+ { "memo-clipboard-copy",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy selected memo"),
+ G_CALLBACK (action_memo_clipboard_copy_cb) },
+
+ { "memo-clipboard-cut",
+ GTK_STOCK_CUT,
+ NULL,
+ NULL,
+ N_("Cut selected memo"),
+ G_CALLBACK (action_memo_clipboard_cut_cb) },
+
+ { "memo-clipboard-paste",
+ GTK_STOCK_PASTE,
+ NULL,
+ NULL,
+ N_("Paste memo from the clipboard"),
+ G_CALLBACK (action_memo_clipboard_paste_cb) },
+
+ { "memo-delete",
+ GTK_STOCK_DELETE,
+ N_("_Delete Memo"),
+ NULL,
+ N_("Delete selected memos"),
+ G_CALLBACK (action_memo_delete_cb) },
+
+ { "memo-forward",
+ "mail-forward",
+ N_("_Forward as iCalendar..."),
+ "<Control>f",
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_memo_forward_cb) },
+
+ { "memo-list-copy",
+ GTK_STOCK_COPY,
+ N_("_Copy..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_memo_list_copy_cb) },
+
+ { "memo-list-delete",
+ GTK_STOCK_DELETE,
+ N_("_Delete"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_memo_list_delete_cb) },
+
+ { "memo-list-new",
+ "stock_notes",
+ N_("_New Memo List"),
+ NULL,
+ N_("Create a new memo list"),
+ G_CALLBACK (action_memo_list_new_cb) },
+
+ { "memo-list-properties",
+ GTK_STOCK_PROPERTIES,
+ NULL,
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_memo_list_properties_cb) },
+
+ { "memo-list-rename",
+ NULL,
+ N_("_Rename..."),
+ "F2",
+ N_("Rename the selected memo list"),
+ G_CALLBACK (action_memo_list_rename_cb) },
+
+ { "memo-list-select-one",
+ "stock_check-filled",
+ N_("Show _Only This Memo List"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_memo_list_select_one_cb) },
+
+ { "memo-new",
+ "stock_insert-note",
+ N_("New _Memo"),
+ NULL,
+ N_("Create a new memo"),
+ G_CALLBACK (action_memo_new_cb) },
+
+ { "memo-open",
+ GTK_STOCK_OPEN,
+ N_("_Open Memo"),
+ "<Control>o",
+ N_("View the selected memo"),
+ G_CALLBACK (action_memo_open_cb) },
+
+ { "memo-open-url",
+ "applications-internet",
+ N_("Open _Web Page"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_memo_open_url_cb) },
+
+ { "memo-save-as",
+ GTK_STOCK_SAVE_AS,
+ N_("_Save as iCalendar..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_memo_save_as_cb) },
+
+ /*** Menus ***/
+
+ { "memo-preview-menu",
+ NULL,
+ N_("_Preview"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static EPopupActionEntry memo_popup_entries[] = {
+
+ { "memo-list-popup-copy",
+ NULL,
+ "memo-list-copy" },
+
+ { "memo-list-popup-delete",
+ NULL,
+ "memo-list-delete" },
+
+ { "memo-list-popup-properties",
+ NULL,
+ "memo-list-properties" },
+
+ { "memo-list-popup-rename",
+ NULL,
+ "memo-list-rename" },
+
+ { "memo-list-popup-select-one",
+ NULL,
+ "memo-list-select-one" },
+
+ { "memo-popup-clipboard-copy",
+ NULL,
+ "memo-clipboard-copy" },
+
+ { "memo-popup-clipboard-cut",
+ NULL,
+ "memo-clipboard-cut" },
+
+ { "memo-popup-clipboard-paste",
+ NULL,
+ "memo-clipboard-paste" },
+
+ { "memo-popup-delete",
+ NULL,
+ "memo-delete" },
+
+ { "memo-popup-forward",
+ NULL,
+ "memo-forward" },
+
+ { "memo-popup-open",
+ NULL,
+ "memo-open" },
+
+ { "memo-popup-open-url",
+ NULL,
+ "memo-open-url" },
+
+ { "memo-popup-save-as",
+ NULL,
+ "memo-save-as" }
+};
+
+static GtkToggleActionEntry memo_toggle_entries[] = {
+
+ { "memo-preview",
+ NULL,
+ N_("Memo _Preview"),
+ "<Control>m",
+ N_("Show memo preview pane"),
+ G_CALLBACK (action_memo_preview_cb),
+ TRUE }
+};
+
+static GtkRadioActionEntry memo_view_entries[] = {
+
+ /* This action represents the initial active memo view.
+ * It should not be visible in the UI, nor should it be
+ * possible to switch to it from another shell view. */
+ { "memo-view-initial",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ -1 },
+
+ { "memo-view-classic",
+ NULL,
+ N_("_Classic View"),
+ NULL,
+ N_("Show memo preview below the memo list"),
+ 0 },
+
+ { "memo-view-vertical",
+ NULL,
+ N_("_Vertical View"),
+ NULL,
+ N_("Show memo preview alongside the memo list"),
+ 1 }
+};
+
+static GtkRadioActionEntry memo_filter_entries[] = {
+
+ { "memo-filter-any-category",
+ NULL,
+ N_("Any Category"),
+ NULL,
+ NULL,
+ MEMO_FILTER_ANY_CATEGORY },
+
+ { "memo-filter-unmatched",
+ NULL,
+ N_("Unmatched"),
+ NULL,
+ NULL,
+ MEMO_FILTER_UNMATCHED }
+};
+
+static GtkRadioActionEntry memo_search_entries[] = {
+
+ { "memo-search-any-field-contains",
+ NULL,
+ N_("Any field contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MEMO_SEARCH_ANY_FIELD_CONTAINS },
+
+ { "memo-search-description-contains",
+ NULL,
+ N_("Description contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MEMO_SEARCH_DESCRIPTION_CONTAINS },
+
+ { "memo-search-summary-contains",
+ NULL,
+ N_("Summary contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MEMO_SEARCH_SUMMARY_CONTAINS }
+};
+
+static GtkActionEntry lockdown_printing_entries[] = {
+
+ { "memo-list-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ "<Control>p",
+ N_("Print the list of memos"),
+ G_CALLBACK (action_memo_list_print_cb) },
+
+ { "memo-list-print-preview",
+ GTK_STOCK_PRINT_PREVIEW,
+ NULL,
+ NULL,
+ N_("Preview the list of memos to be printed"),
+ G_CALLBACK (action_memo_list_print_preview_cb) },
+
+ { "memo-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ NULL,
+ N_("Print the selected memo"),
+ G_CALLBACK (action_memo_print_cb) }
+};
+
+static EPopupActionEntry lockdown_printing_popup_entries[] = {
+
+ { "memo-popup-print",
+ NULL,
+ "memo-print" }
+};
+
+void
+e_memo_shell_view_actions_init (EMemoShellView *memo_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+ GConfBridge *bridge;
+ GtkAction *action;
+ GObject *object;
+ const gchar *key;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ /* Memo Actions */
+ action_group = ACTION_GROUP (MEMOS);
+ gtk_action_group_add_actions (
+ action_group, memo_entries,
+ G_N_ELEMENTS (memo_entries), memo_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, memo_popup_entries,
+ G_N_ELEMENTS (memo_popup_entries));
+ gtk_action_group_add_toggle_actions (
+ action_group, memo_toggle_entries,
+ G_N_ELEMENTS (memo_toggle_entries), memo_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, memo_view_entries,
+ G_N_ELEMENTS (memo_view_entries), -1,
+ G_CALLBACK (action_memo_view_cb), memo_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, memo_search_entries,
+ G_N_ELEMENTS (memo_search_entries),
+ MEMO_SEARCH_SUMMARY_CONTAINS,
+ G_CALLBACK (action_memo_search_cb), memo_shell_view);
+
+ /* Lockdown Printing Actions */
+ action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
+ gtk_action_group_add_actions (
+ action_group, lockdown_printing_entries,
+ G_N_ELEMENTS (lockdown_printing_entries), memo_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, lockdown_printing_popup_entries,
+ G_N_ELEMENTS (lockdown_printing_popup_entries));
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (ACTION (MEMO_PREVIEW));
+ key = "/apps/evolution/calendar/display/show_memo_preview";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (MEMO_VIEW_VERTICAL));
+ key = "/apps/evolution/calendar/display/memo_layout";
+ gconf_bridge_bind_property (bridge, key, object, "current-value");
+
+ /* Fine tuning. */
+
+ action = ACTION (MEMO_DELETE);
+ g_object_set (action, "short-label", _("Delete"), NULL);
+
+ g_signal_connect (
+ ACTION (GAL_SAVE_CUSTOM_VIEW), "activate",
+ G_CALLBACK (action_gal_save_custom_view_cb), memo_shell_view);
+
+ g_signal_connect (
+ ACTION (SEARCH_EXECUTE), "activate",
+ G_CALLBACK (action_search_execute_cb), memo_shell_view);
+}
+
+void
+e_memo_shell_view_update_search_filter (EMemoShellView *memo_shell_view)
+{
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GtkActionGroup *action_group;
+ GtkRadioAction *radio_action;
+ GList *list, *iter;
+ GSList *group;
+ gint ii;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action_group = ACTION_GROUP (MEMOS_FILTER);
+ e_action_group_remove_all_actions (action_group);
+
+ /* Add the standard filter actions. */
+ gtk_action_group_add_radio_actions (
+ action_group, memo_filter_entries,
+ G_N_ELEMENTS (memo_filter_entries),
+ MEMO_FILTER_ANY_CATEGORY,
+ G_CALLBACK (action_search_filter_cb),
+ memo_shell_view);
+
+ /* Retrieve the radio group from an action we just added. */
+ list = gtk_action_group_list_actions (action_group);
+ radio_action = GTK_RADIO_ACTION (list->data);
+ group = gtk_radio_action_get_group (radio_action);
+ g_list_free (list);
+
+ /* Build the category actions. */
+
+ list = e_categories_get_list ();
+ for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) {
+ const gchar *category_name = iter->data;
+ const gchar *filename;
+ GtkAction *action;
+ gchar *action_name;
+
+ action_name = g_strdup_printf (
+ "memo-filter-category-%d", ii);
+ radio_action = gtk_radio_action_new (
+ action_name, category_name, NULL, NULL, ii);
+ g_free (action_name);
+
+ /* Convert the category icon file to a themed icon name. */
+ filename = e_categories_get_icon_file_for (category_name);
+ if (filename != NULL && *filename != '\0') {
+ gchar *basename;
+ gchar *cp;
+
+ basename = g_path_get_basename (filename);
+
+ /* Lose the file extension. */
+ if ((cp = strrchr (basename, '.')) != NULL)
+ *cp = '\0';
+
+ g_object_set (
+ radio_action, "icon-name", basename, NULL);
+
+ g_free (basename);
+ }
+
+ gtk_radio_action_set_group (radio_action, group);
+ group = gtk_radio_action_get_group (radio_action);
+
+ /* The action group takes ownership of the action. */
+ action = GTK_ACTION (radio_action);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (radio_action);
+ }
+ g_list_free (list);
+
+ /* Use any action in the group; doesn't matter which. */
+ e_shell_content_set_filter_action (shell_content, radio_action);
+
+ ii = MEMO_FILTER_UNMATCHED;
+ e_shell_content_add_filter_separator_after (shell_content, ii);
+}
diff --git a/modules/calendar/e-memo-shell-view-actions.h b/modules/calendar/e-memo-shell-view-actions.h
new file mode 100644
index 0000000000..d43d0239d9
--- /dev/null
+++ b/modules/calendar/e-memo-shell-view-actions.h
@@ -0,0 +1,91 @@
+/*
+ * e-memo-shell-view-actions.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MEMO_SHELL_VIEW_ACTIONS_H
+#define E_MEMO_SHELL_VIEW_ACTIONS_H
+
+#include <shell/e-shell-window-actions.h>
+
+/* Memo Actions */
+#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-copy")
+#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_CUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-cut")
+#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_PASTE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-paste")
+#define E_SHELL_WINDOW_ACTION_MEMO_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-delete")
+#define E_SHELL_WINDOW_ACTION_MEMO_FORWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-forward")
+#define E_SHELL_WINDOW_ACTION_MEMO_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-new")
+#define E_SHELL_WINDOW_ACTION_MEMO_OPEN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-open")
+#define E_SHELL_WINDOW_ACTION_MEMO_OPEN_URL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-open-url")
+#define E_SHELL_WINDOW_ACTION_MEMO_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-preview")
+#define E_SHELL_WINDOW_ACTION_MEMO_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-print")
+#define E_SHELL_WINDOW_ACTION_MEMO_SAVE_AS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-save-as")
+#define E_SHELL_WINDOW_ACTION_MEMO_VIEW_CLASSIC(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-view-classic")
+#define E_SHELL_WINDOW_ACTION_MEMO_VIEW_VERTICAL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-view-vertical")
+
+/* Memo List Actions */
+#define E_SHELL_WINDOW_ACTION_MEMO_LIST_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-list-copy")
+#define E_SHELL_WINDOW_ACTION_MEMO_LIST_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-list-delete")
+#define E_SHELL_WINDOW_ACTION_MEMO_LIST_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-list-new")
+#define E_SHELL_WINDOW_ACTION_MEMO_LIST_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-list-print")
+#define E_SHELL_WINDOW_ACTION_MEMO_LIST_PRINT_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-list-print-preview")
+#define E_SHELL_WINDOW_ACTION_MEMO_LIST_PROPERTIES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-list-properties")
+#define E_SHELL_WINDOW_ACTION_MEMO_LIST_RENAME(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-list-rename")
+#define E_SHELL_WINDOW_ACTION_MEMO_LIST_SELECT_ONE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-list-select-one")
+
+/* Memo Query Actions */
+#define E_SHELL_WINDOW_ACTION_MEMO_FILTER_ANY_CATEGORY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-filter-any-category")
+#define E_SHELL_WINDOW_ACTION_MEMO_FILTER_UNMATCHED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-filter-unmatched")
+#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_ANY_FIELD_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-search-any-field-contains")
+#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_DESCRIPTION_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-search-description-contains")
+#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_SUMMARY_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-search-summary-contains")
+
+/* Action Groups */
+#define E_SHELL_WINDOW_ACTION_GROUP_MEMOS(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "memos")
+#define E_SHELL_WINDOW_ACTION_GROUP_MEMOS_FILTER(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "memos-filter")
+
+#endif /* E_MEMO_SHELL_VIEW_ACTIONS_H */
diff --git a/modules/calendar/e-memo-shell-view-private.c b/modules/calendar/e-memo-shell-view-private.c
new file mode 100644
index 0000000000..da321d5c19
--- /dev/null
+++ b/modules/calendar/e-memo-shell-view-private.c
@@ -0,0 +1,561 @@
+/*
+ * e-memo-shell-view-private.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-memo-shell-view-private.h"
+
+#include "widgets/menus/gal-view-factory-etable.h"
+
+static void
+memo_shell_view_table_popup_event_cb (EShellView *shell_view,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/memo-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+}
+
+static void
+memo_shell_view_table_user_created_cb (EMemoShellView *memo_shell_view,
+ EMemoTable *memo_table)
+{
+ EMemoShellSidebar *memo_shell_sidebar;
+ ECalModel *model;
+ ECal *client;
+ ESource *source;
+
+ /* This is the "Click to Add" handler. */
+
+ model = e_memo_table_get_model (memo_table);
+ client = e_cal_model_get_default_client (model);
+ source = e_cal_get_source (client);
+
+ memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
+ e_memo_shell_sidebar_add_source (memo_shell_sidebar, source);
+
+ e_cal_model_add_client (model, client);
+}
+
+static void
+memo_shell_view_selector_client_added_cb (EMemoShellView *memo_shell_view,
+ ECal *client)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ECalModel *model;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ model = e_memo_table_get_model (memo_table);
+
+ e_cal_model_add_client (model, client);
+ e_memo_shell_view_update_timezone (memo_shell_view);
+}
+
+static void
+memo_shell_view_selector_client_removed_cb (EMemoShellView *memo_shell_view,
+ ECal *client)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoTable *memo_table;
+ ECalModel *model;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ model = e_memo_table_get_model (memo_table);
+
+ e_cal_model_remove_client (model, client);
+}
+
+static gboolean
+memo_shell_view_selector_popup_event_cb (EShellView *shell_view,
+ ESource *primary_source,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/memo-list-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+
+ return TRUE;
+}
+
+static void
+memo_shell_view_load_view_collection (EShellViewClass *shell_view_class)
+{
+ GalViewCollection *collection;
+ GalViewFactory *factory;
+ ETableSpecification *spec;
+ const gchar *base_dir;
+ gchar *filename;
+
+ collection = shell_view_class->view_collection;
+
+ base_dir = EVOLUTION_ETSPECDIR;
+ spec = e_table_specification_new ();
+ filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL);
+ if (!e_table_specification_load_from_file (spec, filename))
+ g_critical ("Unable to load ETable specification file "
+ "for memos");
+ g_free (filename);
+
+ factory = gal_view_factory_etable_new (spec);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+ g_object_unref (spec);
+
+ gal_view_collection_load (collection);
+}
+
+static void
+memo_shell_view_notify_view_id_cb (EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ GalViewInstance *view_instance;
+ const gchar *view_id;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ view_instance =
+ e_memo_shell_content_get_view_instance (memo_shell_content);
+ view_id = e_shell_view_get_view_id (E_SHELL_VIEW (memo_shell_view));
+
+ /* A NULL view ID implies we're in a custom view. But you can
+ * only get to a custom view via the "Define Views" dialog, which
+ * would have already modified the view instance appropriately.
+ * Furthermore, there's no way to refer to a custom view by ID
+ * anyway, since custom views have no IDs. */
+ if (view_id == NULL)
+ return;
+
+ gal_view_instance_set_current_view_id (view_instance, view_id);
+}
+
+void
+e_memo_shell_view_private_init (EMemoShellView *memo_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ if (!gal_view_collection_loaded (shell_view_class->view_collection))
+ memo_shell_view_load_view_collection (shell_view_class);
+
+ g_signal_connect (
+ memo_shell_view, "notify::view-id",
+ G_CALLBACK (memo_shell_view_notify_view_id_cb), NULL);
+}
+
+void
+e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view)
+{
+ EMemoShellViewPrivate *priv = memo_shell_view->priv;
+ EMemoShellContent *memo_shell_content;
+ EMemoShellSidebar *memo_shell_sidebar;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ EMemoTable *memo_table;
+ ECalModel *model;
+ ETable *table;
+ ESourceSelector *selector;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ e_shell_window_add_action_group (shell_window, "memos");
+ e_shell_window_add_action_group (shell_window, "memos-filter");
+
+ /* Cache these to avoid lots of awkward casting. */
+ priv->memo_shell_backend = g_object_ref (shell_backend);
+ priv->memo_shell_content = g_object_ref (shell_content);
+ priv->memo_shell_sidebar = g_object_ref (shell_sidebar);
+
+ memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content);
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ model = e_memo_table_get_model (memo_table);
+ table = e_memo_table_get_table (memo_table);
+
+ memo_shell_sidebar = E_MEMO_SHELL_SIDEBAR (shell_sidebar);
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+
+ g_signal_connect_swapped (
+ model, "notify::timezone",
+ G_CALLBACK (e_memo_shell_view_update_timezone),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ memo_table, "open-component",
+ G_CALLBACK (e_memo_shell_view_open_memo),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ memo_table, "popup-event",
+ G_CALLBACK (memo_shell_view_table_popup_event_cb),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ memo_table, "status-message",
+ G_CALLBACK (e_memo_shell_view_set_status_message),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ memo_table, "user-created",
+ G_CALLBACK (memo_shell_view_table_user_created_cb),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ model, "model-changed",
+ G_CALLBACK (e_memo_shell_view_update_sidebar),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ model, "model-rows-deleted",
+ G_CALLBACK (e_memo_shell_view_update_sidebar),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ model, "model-rows-inserted",
+ G_CALLBACK (e_memo_shell_view_update_sidebar),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ table, "selection-change",
+ G_CALLBACK (e_memo_shell_view_update_sidebar),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ memo_shell_sidebar, "client-added",
+ G_CALLBACK (memo_shell_view_selector_client_added_cb),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ memo_shell_sidebar, "client-removed",
+ G_CALLBACK (memo_shell_view_selector_client_removed_cb),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ memo_shell_sidebar, "status-message",
+ G_CALLBACK (e_memo_shell_view_set_status_message),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ selector, "popup-event",
+ G_CALLBACK (memo_shell_view_selector_popup_event_cb),
+ memo_shell_view);
+
+ g_signal_connect_swapped (
+ selector, "primary-selection-changed",
+ G_CALLBACK (e_shell_view_update_actions),
+ memo_shell_view);
+
+ e_categories_register_change_listener (
+ G_CALLBACK (e_memo_shell_view_update_search_filter),
+ memo_shell_view);
+
+ e_memo_shell_view_actions_init (memo_shell_view);
+ e_memo_shell_view_update_sidebar (memo_shell_view);
+ e_memo_shell_view_update_search_filter (memo_shell_view);
+ e_memo_shell_view_update_timezone (memo_shell_view);
+
+ e_memo_shell_view_execute_search (memo_shell_view);
+}
+
+void
+e_memo_shell_view_private_dispose (EMemoShellView *memo_shell_view)
+{
+ EMemoShellViewPrivate *priv = memo_shell_view->priv;
+
+ DISPOSE (priv->memo_shell_backend);
+ DISPOSE (priv->memo_shell_content);
+ DISPOSE (priv->memo_shell_sidebar);
+
+ if (memo_shell_view->priv->activity != NULL) {
+ /* XXX Activity is not cancellable. */
+ e_activity_complete (memo_shell_view->priv->activity);
+ g_object_unref (memo_shell_view->priv->activity);
+ memo_shell_view->priv->activity = NULL;
+ }
+}
+
+void
+e_memo_shell_view_private_finalize (EMemoShellView *memo_shell_view)
+{
+ /* XXX Nothing to do? */
+}
+
+void
+e_memo_shell_view_execute_search (EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ GtkRadioAction *action;
+ GString *string;
+ ECalComponentPreview *memo_preview;
+ EMemoTable *memo_table;
+ ECalModel *model;
+ FilterRule *rule;
+ const gchar *format;
+ const gchar *text;
+ gchar *query;
+ gchar *temp;
+ gint value;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ text = e_shell_content_get_search_text (shell_content);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action = GTK_RADIO_ACTION (ACTION (MEMO_SEARCH_ANY_FIELD_CONTAINS));
+ value = gtk_radio_action_get_current_value (action);
+
+ if (text == NULL || *text == '\0') {
+ text = "";
+ value = MEMO_SEARCH_SUMMARY_CONTAINS;
+ }
+
+ switch (value) {
+ default:
+ text = "";
+ /* fall through */
+
+ case MEMO_SEARCH_SUMMARY_CONTAINS:
+ format = "(contains? \"summary\" %s)";
+ break;
+
+ case MEMO_SEARCH_DESCRIPTION_CONTAINS:
+ format = "(contains? \"description\" %s)";
+ break;
+
+ case MEMO_SEARCH_ANY_FIELD_CONTAINS:
+ format = "(contains? \"any\" %s)";
+ break;
+ }
+
+ /* Build the query. */
+ string = g_string_new ("");
+ e_sexp_encode_string (string, text);
+ query = g_strdup_printf (format, string->str);
+ g_string_free (string, TRUE);
+
+ /* Apply selected filter. */
+ value = e_shell_content_get_filter_value (shell_content);
+ switch (value) {
+ case MEMO_FILTER_ANY_CATEGORY:
+ break;
+
+ case MEMO_FILTER_UNMATCHED:
+ temp = g_strdup_printf (
+ "(and (has-categories? #f) %s", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ default:
+ {
+ GList *categories;
+ const gchar *category_name;
+
+ categories = e_categories_get_list ();
+ category_name = g_list_nth_data (categories, value);
+ g_list_free (categories);
+
+ temp = g_strdup_printf (
+ "(and (has-categories? \"%s\") %s)",
+ category_name, query);
+ g_free (query);
+ query = temp;
+ }
+ }
+
+ /* XXX This is wrong. We need to programmatically construct a
+ * FilterRule, tell it to build code, and pass the resulting
+ * expression string to ECalModel. */
+ rule = filter_rule_new ();
+ e_shell_content_set_search_rule (shell_content, rule);
+ g_object_unref (rule);
+
+ /* Submit the query. */
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ model = e_memo_table_get_model (memo_table);
+ e_cal_model_set_search_query (model, query);
+ g_free (query);
+
+ memo_preview =
+ e_memo_shell_content_get_memo_preview (memo_shell_content);
+ e_cal_component_preview_clear (memo_preview);
+}
+
+void
+e_memo_shell_view_open_memo (EMemoShellView *memo_shell_view,
+ ECalModelComponent *comp_data)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_MEMO_SHELL_VIEW (memo_shell_view));
+ g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data));
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ editor = comp_editor_find_instance (uid);
+
+ if (editor != NULL)
+ goto exit;
+
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+
+ if (e_cal_component_has_organizer (comp))
+ flags |= COMP_EDITOR_IS_SHARED;
+
+ if (itip_organizer_is_user (comp, comp_data->client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = memo_editor_new (comp_data->client, shell, flags);
+ comp_editor_edit_comp (editor, comp);
+
+ g_object_unref (comp);
+
+exit:
+ gtk_window_present (GTK_WINDOW (editor));
+}
+
+void
+e_memo_shell_view_set_status_message (EMemoShellView *memo_shell_view,
+ const gchar *status_message,
+ gdouble percent)
+{
+ EActivity *activity;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+
+ g_return_if_fail (E_IS_MEMO_SHELL_VIEW (memo_shell_view));
+
+ activity = memo_shell_view->priv->activity;
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ if (status_message == NULL || *status_message == '\0') {
+ if (activity != NULL) {
+ e_activity_complete (activity);
+ g_object_unref (activity);
+ activity = NULL;
+ }
+
+ } else if (activity == NULL) {
+ activity = e_activity_new (status_message);
+ e_activity_set_percent (activity, percent);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ } else {
+ e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
+ }
+
+ memo_shell_view->priv->activity = activity;
+}
+
+void
+e_memo_shell_view_update_sidebar (EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ EMemoTable *memo_table;
+ ECalModel *model;
+ ETable *table;
+ GString *string;
+ const gchar *format;
+ gint n_rows;
+ gint n_selected;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+ model = e_memo_table_get_model (memo_table);
+ table = e_memo_table_get_table (memo_table);
+
+ n_rows = e_table_model_row_count (E_TABLE_MODEL (model));
+ n_selected = e_table_selected_count (table);
+
+ string = g_string_sized_new (64);
+
+ format = ngettext ("%d memo", "%d memos", n_rows);
+ g_string_append_printf (string, format, n_rows);
+
+ if (n_selected > 0) {
+ format = _("%d selected");
+ g_string_append_len (string, ", ", 2);
+ g_string_append_printf (string, format, n_selected);
+ }
+
+ e_shell_sidebar_set_secondary_text (shell_sidebar, string->str);
+
+ g_string_free (string, TRUE);
+}
+
+void
+e_memo_shell_view_update_timezone (EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EMemoShellSidebar *memo_shell_sidebar;
+ ECalComponentPreview *memo_preview;
+ icaltimezone *timezone;
+ ECalModel *model;
+ GList *clients, *iter;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content);
+ model = e_memo_shell_content_get_memo_model (memo_shell_content);
+ timezone = e_cal_model_get_timezone (model);
+
+ memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
+ clients = e_memo_shell_sidebar_get_clients (memo_shell_sidebar);
+
+ for (iter = clients; iter != NULL; iter = iter->next) {
+ ECal *client = iter->data;
+
+ if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
+ e_cal_set_default_timezone (client, timezone, NULL);
+ }
+
+ e_cal_component_preview_set_default_timezone (memo_preview, timezone);
+
+ g_list_free (clients);
+}
diff --git a/modules/calendar/e-memo-shell-view-private.h b/modules/calendar/e-memo-shell-view-private.h
new file mode 100644
index 0000000000..c7ece91f68
--- /dev/null
+++ b/modules/calendar/e-memo-shell-view-private.h
@@ -0,0 +1,128 @@
+/*
+ * e-memo-shell-view-private.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MEMO_SHELL_VIEW_PRIVATE_H
+#define E_MEMO_SHELL_VIEW_PRIVATE_H
+
+#include "e-memo-shell-view.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libedataserver/e-categories.h>
+#include <libedataserver/e-sexp.h>
+
+#include "e-util/e-dialog-utils.h"
+#include "e-util/e-error.h"
+#include "e-util/e-util.h"
+#include "e-util/gconf-bridge.h"
+#include "widgets/misc/e-popup-action.h"
+
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/e-cal-component-preview.h"
+#include "calendar/gui/e-calendar-selector.h"
+#include "calendar/gui/print.h"
+#include "calendar/gui/dialogs/calendar-setup.h"
+#include "calendar/gui/dialogs/copy-source-dialog.h"
+#include "calendar/gui/dialogs/memo-editor.h"
+
+#include "e-memo-shell-backend.h"
+#include "e-memo-shell-content.h"
+#include "e-memo-shell-sidebar.h"
+#include "e-memo-shell-view-actions.h"
+
+#define E_MEMO_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MEMO_SHELL_VIEW, EMemoShellViewPrivate))
+
+/* Shorthand, requires a variable named "shell_window". */
+#define ACTION(name) \
+ (E_SHELL_WINDOW_ACTION_##name (shell_window))
+#define ACTION_GROUP(name) \
+ (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window))
+
+/* For use in dispose() methods. */
+#define DISPOSE(obj) \
+ G_STMT_START { \
+ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \
+ } G_STMT_END
+
+/* ETable Specifications */
+#define ETSPEC_FILENAME "e-memo-table.etspec"
+
+G_BEGIN_DECLS
+
+/* Filter items are displayed in ascending order.
+ * Non-negative values are reserved for categories. */
+enum {
+ MEMO_FILTER_ANY_CATEGORY = -2,
+ MEMO_FILTER_UNMATCHED = -1
+};
+
+/* Search items are displayed in ascending order. */
+enum {
+ MEMO_SEARCH_SUMMARY_CONTAINS,
+ MEMO_SEARCH_DESCRIPTION_CONTAINS,
+ MEMO_SEARCH_ANY_FIELD_CONTAINS
+};
+
+struct _EMemoShellViewPrivate {
+
+ /* These are just for convenience. */
+ EMemoShellBackend *memo_shell_backend;
+ EMemoShellContent *memo_shell_content;
+ EMemoShellSidebar *memo_shell_sidebar;
+
+ EActivity *activity;
+};
+
+void e_memo_shell_view_private_init
+ (EMemoShellView *memo_shell_view,
+ EShellViewClass *shell_view_class);
+void e_memo_shell_view_private_constructed
+ (EMemoShellView *memo_shell_view);
+void e_memo_shell_view_private_dispose
+ (EMemoShellView *memo_shell_view);
+void e_memo_shell_view_private_finalize
+ (EMemoShellView *memo_shell_view);
+
+/* Private Utilities */
+
+void e_memo_shell_view_actions_init
+ (EMemoShellView *memo_shell_view);
+void e_memo_shell_view_execute_search
+ (EMemoShellView *memo_shell_view);
+void e_memo_shell_view_open_memo
+ (EMemoShellView *memo_shell_view,
+ ECalModelComponent *comp_data);
+void e_memo_shell_view_set_status_message
+ (EMemoShellView *memo_shell_view,
+ const gchar *status_message,
+ gdouble percent);
+void e_memo_shell_view_update_sidebar
+ (EMemoShellView *memo_shell_view);
+void e_memo_shell_view_update_search_filter
+ (EMemoShellView *memo_shell_view);
+void e_memo_shell_view_update_timezone
+ (EMemoShellView *memo_shell_view);
+
+G_END_DECLS
+
+#endif /* E_MEMO_SHELL_VIEW_PRIVATE_H */
diff --git a/modules/calendar/e-memo-shell-view.c b/modules/calendar/e-memo-shell-view.c
new file mode 100644
index 0000000000..e2964b061c
--- /dev/null
+++ b/modules/calendar/e-memo-shell-view.c
@@ -0,0 +1,222 @@
+/*
+ * e-memo-shell-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-memo-shell-view-private.h"
+
+static gpointer parent_class;
+static GType memo_shell_view_type;
+
+static void
+memo_shell_view_dispose (GObject *object)
+{
+ e_memo_shell_view_private_dispose (E_MEMO_SHELL_VIEW (object));
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+memo_shell_view_finalize (GObject *object)
+{
+ e_memo_shell_view_private_finalize (E_MEMO_SHELL_VIEW (object));
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+memo_shell_view_constructed (GObject *object)
+{
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ e_memo_shell_view_private_constructed (E_MEMO_SHELL_VIEW (object));
+}
+
+static void
+memo_shell_view_update_actions (EShellView *shell_view)
+{
+ EMemoShellViewPrivate *priv;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ GtkAction *action;
+ const gchar *label;
+ gboolean sensitive;
+ guint32 state;
+
+ /* Be descriptive. */
+ gboolean any_memos_selected;
+ gboolean has_primary_source;
+ gboolean multiple_memos_selected;
+ gboolean primary_source_is_system;
+ gboolean selection_has_url;
+ gboolean single_memo_selected;
+ gboolean sources_are_editable;
+
+ priv = E_MEMO_SHELL_VIEW_GET_PRIVATE (shell_view);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ state = e_shell_content_check_state (shell_content);
+
+ single_memo_selected =
+ (state & E_MEMO_SHELL_CONTENT_SELECTION_SINGLE);
+ multiple_memos_selected =
+ (state & E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE);
+ sources_are_editable =
+ (state & E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT);
+ selection_has_url =
+ (state & E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL);
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ state = e_shell_sidebar_check_state (shell_sidebar);
+
+ has_primary_source =
+ (state & E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE);
+ primary_source_is_system =
+ (state & E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM);
+
+ any_memos_selected =
+ (single_memo_selected || multiple_memos_selected);
+
+ action = ACTION (MEMO_CLIPBOARD_COPY);
+ sensitive = any_memos_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_CLIPBOARD_CUT);
+ sensitive = any_memos_selected && sources_are_editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_CLIPBOARD_PASTE);
+ sensitive = sources_are_editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_DELETE);
+ sensitive = any_memos_selected && sources_are_editable;
+ gtk_action_set_sensitive (action, sensitive);
+ if (multiple_memos_selected)
+ label = _("Delete Memos");
+ else
+ label = _("Delete Memo");
+ g_object_set (action, "label", label, NULL);
+
+ action = ACTION (MEMO_FORWARD);
+ sensitive = single_memo_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_LIST_COPY);
+ sensitive = has_primary_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_LIST_DELETE);
+ sensitive = has_primary_source && !primary_source_is_system;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_LIST_PROPERTIES);
+ sensitive = has_primary_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_LIST_RENAME);
+ sensitive = has_primary_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_OPEN);
+ sensitive = single_memo_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_OPEN_URL);
+ sensitive = single_memo_selected && selection_has_url;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_PRINT);
+ sensitive = single_memo_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MEMO_SAVE_AS);
+ sensitive = single_memo_selected;
+ gtk_action_set_sensitive (action, sensitive);
+}
+
+static void
+memo_shell_view_class_init (EMemoShellViewClass *class,
+ GTypeModule *type_module)
+{
+ GObjectClass *object_class;
+ EShellViewClass *shell_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMemoShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = memo_shell_view_dispose;
+ object_class->finalize = memo_shell_view_finalize;
+ object_class->constructed = memo_shell_view_constructed;
+
+ shell_view_class = E_SHELL_VIEW_CLASS (class);
+ shell_view_class->label = _("Memos");
+ shell_view_class->icon_name = "evolution-memos";
+ shell_view_class->ui_definition = "evolution-memos.ui";
+ shell_view_class->ui_manager_id = "org.gnome.evolution.memos";
+ shell_view_class->search_options = "/memo-search-options";
+ shell_view_class->search_rules = "memotypes.xml";
+ shell_view_class->new_shell_content = e_memo_shell_content_new;
+ shell_view_class->new_shell_sidebar = e_memo_shell_sidebar_new;
+ shell_view_class->update_actions = memo_shell_view_update_actions;
+}
+
+static void
+memo_shell_view_init (EMemoShellView *memo_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ memo_shell_view->priv =
+ E_MEMO_SHELL_VIEW_GET_PRIVATE (memo_shell_view);
+
+ e_memo_shell_view_private_init (memo_shell_view, shell_view_class);
+}
+
+GType
+e_memo_shell_view_get_type (void)
+{
+ return memo_shell_view_type;
+}
+
+void
+e_memo_shell_view_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EMemoShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) memo_shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ type_module,
+ sizeof (EMemoShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) memo_shell_view_init,
+ NULL /* value_table */
+ };
+
+ memo_shell_view_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_VIEW,
+ "EMemoShellView", &type_info, 0);
+}
diff --git a/modules/calendar/e-memo-shell-view.h b/modules/calendar/e-memo-shell-view.h
new file mode 100644
index 0000000000..686ae734c9
--- /dev/null
+++ b/modules/calendar/e-memo-shell-view.h
@@ -0,0 +1,67 @@
+/*
+ * e-memo-shell-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MEMO_SHELL_VIEW_H
+#define E_MEMO_SHELL_VIEW_H
+
+#include <shell/e-shell-view.h>
+#include <libedataserver/e-source-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MEMO_SHELL_VIEW \
+ (e_memo_shell_view_get_type ())
+#define E_MEMO_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MEMO_SHELL_VIEW, EMemoShellView))
+#define E_MEMO_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MEMO_SHELL_VIEW, EMemoShellViewClass))
+#define E_IS_MEMO_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MEMO_SHELL_VIEW))
+#define E_IS_MEMO_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MEMO_SHELL_VIEW))
+#define E_MEMO_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MEMO_SHELL_VIEW, EMemoShellViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMemoShellView EMemoShellView;
+typedef struct _EMemoShellViewClass EMemoShellViewClass;
+typedef struct _EMemoShellViewPrivate EMemoShellViewPrivate;
+
+struct _EMemoShellView {
+ EShellView parent;
+ EMemoShellViewPrivate *priv;
+};
+
+struct _EMemoShellViewClass {
+ EShellViewClass parent_class;
+};
+
+GType e_memo_shell_view_get_type (void);
+void e_memo_shell_view_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MEMO_SHELL_VIEW_H */
diff --git a/modules/calendar/e-task-shell-backend.c b/modules/calendar/e-task-shell-backend.c
new file mode 100644
index 0000000000..59a87e653c
--- /dev/null
+++ b/modules/calendar/e-task-shell-backend.c
@@ -0,0 +1,661 @@
+/*
+ * e-task-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-task-shell-backend.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libecal/e-cal.h>
+#include <libedataserver/e-url.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-source-group.h>
+
+#include "shell/e-shell.h"
+#include "shell/e-shell-backend.h"
+#include "shell/e-shell-window.h"
+
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/dialogs/calendar-setup.h"
+#include "calendar/gui/dialogs/task-editor.h"
+
+#include "e-task-shell-content.h"
+#include "e-task-shell-migrate.h"
+#include "e-task-shell-sidebar.h"
+#include "e-task-shell-view.h"
+
+#define E_TASK_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TASK_SHELL_BACKEND, ETaskShellBackendPrivate))
+
+#define WEB_BASE_URI "webcal://"
+#define PERSONAL_RELATIVE_URI "system"
+
+struct _ETaskShellBackendPrivate {
+ ESourceList *source_list;
+};
+
+enum {
+ PROP_0,
+ PROP_SOURCE_LIST
+};
+
+static gpointer parent_class;
+static GType task_shell_backend_type;
+
+static void
+task_shell_backend_ensure_sources (EShellBackend *shell_backend)
+{
+ /* XXX This is basically the same algorithm across all modules.
+ * Maybe we could somehow integrate this into EShellBackend? */
+
+ ETaskShellBackendPrivate *priv;
+ ESourceGroup *on_this_computer;
+ ESourceGroup *on_the_web;
+ ESource *personal;
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GSList *groups, *iter;
+ const gchar *data_dir;
+ const gchar *name;
+ gchar *base_uri;
+ gchar *filename;
+
+ on_this_computer = NULL;
+ on_the_web = NULL;
+ personal = NULL;
+
+ priv = E_TASK_SHELL_BACKEND_GET_PRIVATE (shell_backend);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ if (!e_cal_get_sources (&priv->source_list, E_CAL_SOURCE_TYPE_TODO, NULL)) {
+ g_warning ("Could not get task sources from GConf!");
+ return;
+ }
+
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ filename = g_build_filename (data_dir, "local", NULL);
+ base_uri = g_filename_to_uri (filename, NULL, NULL);
+ g_free (filename);
+
+ groups = e_source_list_peek_groups (priv->source_list);
+ for (iter = groups; iter != NULL; iter = iter->next) {
+ ESourceGroup *source_group = iter->data;
+ const gchar *group_base_uri;
+
+ group_base_uri = e_source_group_peek_base_uri (source_group);
+
+ /* Compare only "file://" part. If the user's home
+ * changes, we do not want to create another group. */
+ if (on_this_computer == NULL &&
+ strncmp (base_uri, group_base_uri, 7) == 0)
+ on_this_computer = source_group;
+
+ else if (on_the_web == NULL &&
+ strcmp (WEB_BASE_URI, group_base_uri) == 0)
+ on_the_web = source_group;
+ }
+
+ name = _("On This Computer");
+
+ if (on_this_computer != NULL) {
+ GSList *sources;
+ const gchar *group_base_uri;
+
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (on_this_computer, name);
+
+ sources = e_source_group_peek_sources (on_this_computer);
+ group_base_uri = e_source_group_peek_base_uri (on_this_computer);
+
+ /* Make sure this group includes a "Personal" source. */
+ for (iter = sources; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+
+ if (strcmp (PERSONAL_RELATIVE_URI, relative_uri) != 0)
+ continue;
+
+ personal = source;
+ break;
+ }
+
+ /* Make sure we have the correct base URI. This can
+ * change when the user's home directory changes. */
+ if (strcmp (base_uri, group_base_uri) != 0) {
+ e_source_group_set_base_uri (
+ on_this_computer, base_uri);
+
+ /* XXX We shouldn't need this sync call here as
+ * set_base_uri() results in synching to GConf,
+ * but that happens in an idle loop and too late
+ * to prevent the user from seeing a "Cannot
+ * Open ... because of invalid URI" error. */
+ e_source_list_sync (priv->source_list, NULL);
+ }
+
+ } else {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, base_uri);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ }
+
+ name = _("Personal");
+
+ if (personal == NULL) {
+ ESource *source;
+ GSList *selected;
+ gchar *primary;
+
+ source = e_source_new (name, PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (on_this_computer, source, -1);
+ g_object_unref (source);
+
+ primary = e_shell_settings_get_string (
+ shell_settings, "cal-primary-task-list");
+
+ selected = calendar_config_get_tasks_selected ();
+
+ if (primary == NULL && selected == NULL) {
+ const gchar *uid;
+
+ uid = e_source_peek_uid (source);
+ selected = g_slist_prepend (NULL, g_strdup (uid));
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-task-list", uid);
+ calendar_config_set_tasks_selected (selected);
+ }
+
+ g_slist_foreach (selected, (GFunc) g_free, NULL);
+ g_slist_free (selected);
+ g_free (primary);
+ } else {
+ /* Force the source name to the current locale. */
+ e_source_set_name (personal, name);
+ }
+
+ name = _("On The Web");
+
+ if (on_the_web == NULL) {
+ ESourceGroup *source_group;
+
+ source_group = e_source_group_new (name, WEB_BASE_URI);
+ e_source_list_add_group (priv->source_list, source_group, -1);
+ g_object_unref (source_group);
+ } else {
+ /* Force the group name to the current locale. */
+ e_source_group_set_name (on_the_web, name);
+ }
+
+ g_free (base_uri);
+}
+
+static void
+task_shell_backend_task_new_cb (ECal *cal,
+ ECalendarStatus status,
+ EShell *shell)
+{
+ ECalComponent *comp;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+
+ /* XXX Handle errors better. */
+ if (status != E_CALENDAR_STATUS_OK)
+ return;
+
+ flags |= COMP_EDITOR_NEW_ITEM;
+
+ editor = task_editor_new (cal, shell, flags);
+ comp = cal_comp_task_new_with_defaults (cal);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (cal);
+}
+
+static void
+task_shell_backend_task_assigned_new_cb (ECal *cal,
+ ECalendarStatus status,
+ EShell *shell)
+{
+ ECalComponent *comp;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+
+ /* XXX Handle errors better. */
+ if (status != E_CALENDAR_STATUS_OK)
+ return;
+
+ flags |= COMP_EDITOR_NEW_ITEM;
+ flags |= COMP_EDITOR_IS_ASSIGNED;
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = task_editor_new (cal, shell, flags);
+ comp = cal_comp_task_new_with_defaults (cal);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (cal);
+}
+
+static void
+action_task_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ ECal *cal = NULL;
+ ECalSourceType source_type;
+ ESourceList *source_list;
+ EShellSettings *shell_settings;
+ EShell *shell;
+ const gchar *action_name;
+ gchar *uid;
+
+ /* This callback is used for both tasks and assigned tasks. */
+
+ source_type = E_CAL_SOURCE_TYPE_TODO;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ if (!e_cal_get_sources (&source_list, source_type, NULL)) {
+ g_warning ("Could not get task sources from GConf!");
+ return;
+ }
+
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-task-list");
+
+ if (uid != NULL) {
+ ESource *source;
+
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ if (source != NULL)
+ cal = auth_new_cal_from_source (source, source_type);
+ g_free (uid);
+ }
+
+ if (cal == NULL)
+ cal = auth_new_cal_from_default (source_type);
+
+ g_return_if_fail (cal != NULL);
+
+ /* Connect the appropriate signal handler. */
+ action_name = gtk_action_get_name (action);
+ if (strcmp (action_name, "task-assigned-new") == 0)
+ g_signal_connect (
+ cal, "cal-opened",
+ G_CALLBACK (task_shell_backend_task_assigned_new_cb),
+ shell);
+ else
+ g_signal_connect (
+ cal, "cal-opened",
+ G_CALLBACK (task_shell_backend_task_new_cb),
+ shell);
+
+ e_cal_open_async (cal, FALSE);
+}
+
+static void
+action_task_list_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ calendar_setup_new_task_list (GTK_WINDOW (shell_window));
+}
+
+static GtkActionEntry item_entries[] = {
+
+ { "task-new",
+ "stock_task",
+ NC_("New", "_Task"),
+ "<Shift><Control>t",
+ N_("Create a new task"),
+ G_CALLBACK (action_task_new_cb) },
+
+ { "task-assigned-new",
+ "stock_task",
+ N_("Assigne_d Task"),
+ NULL,
+ N_("Create a new assigned task"),
+ G_CALLBACK (action_task_new_cb) }
+};
+
+static GtkActionEntry source_entries[] = {
+
+ { "task-list-new",
+ "stock_todo",
+ NC_("New", "Tas_k List"),
+ NULL,
+ N_("Create a new task list"),
+ G_CALLBACK (action_task_list_new_cb) }
+};
+
+static gboolean
+task_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
+ const gchar *uri)
+{
+ EShell *shell;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+ ECal *client;
+ ECalComponent *comp;
+ ESource *source;
+ ESourceList *source_list;
+ ECalSourceType source_type;
+ EUri *euri;
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+ const gchar *cp;
+ gchar *source_uid = NULL;
+ gchar *comp_uid = NULL;
+ gchar *comp_rid = NULL;
+ gboolean handled = FALSE;
+ GError *error = NULL;
+
+ source_type = E_CAL_SOURCE_TYPE_TODO;
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ if (strncmp (uri, "task:", 5) != 0)
+ return FALSE;
+
+ euri = e_uri_new (uri);
+ cp = euri->query;
+ if (cp == NULL)
+ goto exit;
+
+ while (*cp != '\0') {
+ gchar *header;
+ gchar *content;
+ gsize header_len;
+ gsize content_len;
+
+ header_len = strcspn (cp, "=&");
+
+ /* If it's malformed, give up. */
+ if (cp[header_len] != '=')
+ break;
+
+ header = (gchar *) cp;
+ header[header_len] = '\0';
+ cp += header_len + 1;
+
+ content_len = strcspn (cp, "&");
+
+ content = g_strndup (cp, content_len);
+ if (g_ascii_strcasecmp (header, "source-uid") == 0)
+ source_uid = g_strdup (content);
+ else if (g_ascii_strcasecmp (header, "comp-uid") == 0)
+ comp_uid = g_strdup (content);
+ else if (g_ascii_strcasecmp (header, "comp-rid") == 0)
+ comp_rid = g_strdup (content);
+ g_free (content);
+
+ cp += content_len;
+ if (*cp == '&') {
+ cp++;
+ if (strcmp (cp, "amp;") == 0)
+ cp += 4;
+ }
+ }
+
+ if (source_uid == NULL || comp_uid == NULL)
+ goto exit;
+
+ /* URI is valid, so consider it handled. Whether
+ * we successfully open it is another matter... */
+ handled = TRUE;
+
+ if (!e_cal_get_sources (&source_list, source_type, NULL)) {
+ g_printerr ("Could not get task sources from GConf!\n");
+ goto exit;
+ }
+
+ source = e_source_list_peek_source_by_uid (source_list, source_uid);
+ if (source == NULL) {
+ g_printerr ("No source for UID `%s'\n", source_uid);
+ g_object_unref (source_list);
+ goto exit;
+ }
+
+ client = auth_new_cal_from_source (source, source_type);
+ if (client == NULL || !e_cal_open (client, TRUE, &error)) {
+ g_printerr ("%s\n", error->message);
+ g_object_unref (source_list);
+ g_error_free (error);
+ goto exit;
+ }
+
+ /* XXX Copied from e_task_shell_view_open_task().
+ * Clearly a new utility function is needed. */
+
+ editor = comp_editor_find_instance (comp_uid);
+
+ if (editor != NULL)
+ goto present;
+
+ if (!e_cal_get_object (client, comp_uid, comp_rid, &icalcomp, &error)) {
+ g_printerr ("%s\n", error->message);
+ g_object_unref (source_list);
+ g_error_free (error);
+ goto exit;
+ }
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+
+ icalprop = icalcomponent_get_first_property (
+ icalcomp, ICAL_ATTENDEE_PROPERTY);
+ if (icalprop != NULL)
+ flags |= COMP_EDITOR_IS_ASSIGNED;
+
+ if (itip_organizer_is_user (comp, client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ if (!e_cal_component_has_attendees (comp))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = task_editor_new (client, shell, flags);
+ comp_editor_edit_comp (editor, comp);
+
+ g_object_unref (comp);
+
+present:
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (source_list);
+ g_object_unref (client);
+
+exit:
+ g_free (source_uid);
+ g_free (comp_uid);
+ g_free (comp_rid);
+
+ e_uri_free (euri);
+
+ return handled;
+}
+
+static void
+task_shell_backend_window_created_cb (EShellBackend *shell_backend,
+ GtkWindow *window)
+{
+ const gchar *module_name;
+
+ if (!E_IS_SHELL_WINDOW (window))
+ return;
+
+ module_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ e_shell_window_register_new_item_actions (
+ E_SHELL_WINDOW (window), module_name,
+ item_entries, G_N_ELEMENTS (item_entries));
+
+ e_shell_window_register_new_source_actions (
+ E_SHELL_WINDOW (window), module_name,
+ source_entries, G_N_ELEMENTS (source_entries));
+}
+
+static void
+task_shell_backend_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SOURCE_LIST:
+ g_value_set_object (
+ value,
+ e_task_shell_backend_get_source_list (
+ E_TASK_SHELL_BACKEND (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+task_shell_backend_dispose (GObject *object)
+{
+ ETaskShellBackendPrivate *priv;
+
+ priv = E_TASK_SHELL_BACKEND_GET_PRIVATE (object);
+
+ if (priv->source_list != NULL) {
+ g_object_unref (priv->source_list);
+ priv->source_list = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+task_shell_backend_constructed (GObject *object)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell_backend = E_SHELL_BACKEND (object);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ task_shell_backend_ensure_sources (shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "handle-uri",
+ G_CALLBACK (task_shell_backend_handle_uri_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "window-created",
+ G_CALLBACK (task_shell_backend_window_created_cb),
+ shell_backend);
+}
+
+static void
+task_shell_backend_class_init (ETaskShellBackendClass *class)
+{
+ GObjectClass *object_class;
+ EShellBackendClass *shell_backend_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETaskShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = task_shell_backend_get_property;
+ object_class->dispose = task_shell_backend_dispose;
+ object_class->constructed = task_shell_backend_constructed;
+
+ shell_backend_class = E_SHELL_BACKEND_CLASS (class);
+ shell_backend_class->shell_view_type = E_TYPE_TASK_SHELL_VIEW;
+ shell_backend_class->name = "tasks";
+ shell_backend_class->aliases = "";
+ shell_backend_class->schemes = "task";
+ shell_backend_class->sort_order = 600;
+ shell_backend_class->start = NULL;
+ shell_backend_class->migrate = e_task_shell_backend_migrate;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE_LIST,
+ g_param_spec_object (
+ "source-list",
+ _("Source List"),
+ _("The registry of task lists"),
+ E_TYPE_SOURCE_LIST,
+ G_PARAM_READABLE));
+}
+
+static void
+task_shell_backend_init (ETaskShellBackend *task_shell_backend)
+{
+ task_shell_backend->priv =
+ E_TASK_SHELL_BACKEND_GET_PRIVATE (task_shell_backend);
+}
+
+GType
+e_task_shell_backend_get_type (void)
+{
+ return task_shell_backend_type;
+}
+
+void
+e_task_shell_backend_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (ETaskShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) task_shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ETaskShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) task_shell_backend_init,
+ NULL /* value_table */
+ };
+
+ task_shell_backend_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_BACKEND,
+ "ETaskShellBackend", &type_info, 0);
+}
+
+ESourceList *
+e_task_shell_backend_get_source_list (ETaskShellBackend *task_shell_backend)
+{
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_BACKEND (task_shell_backend), NULL);
+
+ return task_shell_backend->priv->source_list;
+}
diff --git a/modules/calendar/e-task-shell-backend.h b/modules/calendar/e-task-shell-backend.h
new file mode 100644
index 0000000000..63b157ad85
--- /dev/null
+++ b/modules/calendar/e-task-shell-backend.h
@@ -0,0 +1,70 @@
+/*
+ * e-task-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TASK_SHELL_BACKEND_H
+#define E_TASK_SHELL_BACKEND_H
+
+#include <shell/e-shell-backend.h>
+#include <libedataserver/e-source-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TASK_SHELL_BACKEND \
+ (e_task_shell_backend_get_type ())
+#define E_TASK_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TASK_SHELL_BACKEND, ETaskShellBackend))
+#define E_TASK_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TASK_SHELL_BACKEND, ETaskShellBackendClass))
+#define E_IS_TASK_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TASK_SHELL_BACKEND))
+#define E_IS_TASK_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TASK_SHELL_BACKEND))
+#define E_TASK_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TASK_SHELL_BACKEND, ETaskShellBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETaskShellBackend ETaskShellBackend;
+typedef struct _ETaskShellBackendClass ETaskShellBackendClass;
+typedef struct _ETaskShellBackendPrivate ETaskShellBackendPrivate;
+
+struct _ETaskShellBackend {
+ EShellBackend parent;
+ ETaskShellBackendPrivate *priv;
+};
+
+struct _ETaskShellBackendClass {
+ EShellBackendClass parent_class;
+};
+
+GType e_task_shell_backend_get_type (void);
+void e_task_shell_backend_register_type
+ (GTypeModule *type_module);
+ESourceList * e_task_shell_backend_get_source_list
+ (ETaskShellBackend *task_shell_backend);
+
+G_END_DECLS
+
+#endif /* E_TASK_SHELL_BACKEND_H */
diff --git a/modules/calendar/e-task-shell-content.c b/modules/calendar/e-task-shell-content.c
new file mode 100644
index 0000000000..a095003978
--- /dev/null
+++ b/modules/calendar/e-task-shell-content.c
@@ -0,0 +1,744 @@
+/*
+ * e-task-shell-content.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-task-shell-content.h"
+
+#include <glib/gi18n.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/gconf-bridge.h"
+#include "widgets/menus/gal-view-etable.h"
+#include "widgets/misc/e-paned.h"
+
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/e-cal-model-tasks.h"
+#include "calendar/gui/e-calendar-table.h"
+
+#define E_TASK_SHELL_CONTENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TASK_SHELL_CONTENT, ETaskShellContentPrivate))
+
+#define E_CALENDAR_TABLE_DEFAULT_STATE \
+ "<?xml version=\"1.0\"?>" \
+ "<ETableState>" \
+ " <column source=\"13\"/>" \
+ " <column source=\"14\"/>" \
+ " <column source=\"9\"/>" \
+ " <column source=\"5\"/>" \
+ " <grouping/>" \
+ "</ETableState>"
+
+struct _ETaskShellContentPrivate {
+ GtkWidget *paned;
+ GtkWidget *task_table;
+ GtkWidget *task_preview;
+
+ ECalModel *task_model;
+ GalViewInstance *view_instance;
+ GtkOrientation orientation;
+
+ gchar *current_uid;
+
+ guint preview_visible : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_MODEL,
+ PROP_ORIENTATION,
+ PROP_PREVIEW_VISIBLE
+};
+
+enum {
+ TARGET_VCALENDAR
+};
+
+static GtkTargetEntry drag_types[] = {
+ { (gchar *) "text/calendar", 0, TARGET_VCALENDAR },
+ { (gchar *) "text/x-calendar", 0, TARGET_VCALENDAR }
+};
+
+static gpointer parent_class;
+static GType task_shell_content_type;
+
+static void
+task_shell_content_display_view_cb (ETaskShellContent *task_shell_content,
+ GalView *gal_view)
+{
+ ECalendarTable *task_table;
+ ETable *table;
+
+ if (!GAL_IS_VIEW_ETABLE (gal_view))
+ return;
+
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ table = e_calendar_table_get_table (task_table);
+
+ gal_view_etable_attach_table (GAL_VIEW_ETABLE (gal_view), table);
+}
+
+static void
+task_shell_content_table_foreach_cb (gint model_row,
+ gpointer user_data)
+{
+ ECalModelComponent *comp_data;
+ icalcomponent *clone;
+ icalcomponent *vcal;
+ gchar *string;
+
+ struct {
+ ECalModel *model;
+ GSList *list;
+ } *foreach_data = user_data;
+
+ comp_data = e_cal_model_get_component_at (
+ foreach_data->model, model_row);
+
+ vcal = e_cal_util_new_top_level ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
+ icalcomponent_add_component (vcal, clone);
+
+ /* String is owned by libical; do not free. */
+ string = icalcomponent_as_ical_string (vcal);
+ if (string != NULL) {
+ ESource *source;
+ const gchar *source_uid;
+
+ source = e_cal_get_source (comp_data->client);
+ source_uid = e_source_peek_uid (source);
+
+ foreach_data->list = g_slist_prepend (
+ foreach_data->list,
+ g_strdup_printf ("%s\n%s", source_uid, string));
+ }
+
+ icalcomponent_free (vcal);
+}
+
+static void
+task_shell_content_table_drag_data_get_cb (ETaskShellContent *task_shell_content,
+ gint row,
+ gint col,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
+{
+ ECalendarTable *task_table;
+ ETable *table;
+
+ struct {
+ ECalModel *model;
+ GSList *list;
+ } foreach_data;
+
+ if (info != TARGET_VCALENDAR)
+ return;
+
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ table = e_calendar_table_get_table (task_table);
+
+ foreach_data.model = e_calendar_table_get_model (task_table);
+ foreach_data.list = NULL;
+
+ e_table_selected_row_foreach (
+ table, task_shell_content_table_foreach_cb,
+ &foreach_data);
+
+ if (foreach_data.list != NULL) {
+ cal_comp_selection_set_string_list (
+ selection_data, foreach_data.list);
+ g_slist_foreach (foreach_data.list, (GFunc) g_free, NULL);
+ g_slist_free (foreach_data.list);
+ }
+}
+
+static void
+task_shell_content_table_drag_data_delete_cb (ETaskShellContent *task_shell_content,
+ gint row,
+ gint col,
+ GdkDragContext *context)
+{
+ /* Moved components are deleted from source immediately when moved,
+ * because some of them can be part of destination source, and we
+ * don't want to delete not-moved tasks. There is no such information
+ * which event has been moved and which not, so skip this method. */
+}
+
+static void
+task_shell_content_cursor_change_cb (ETaskShellContent *task_shell_content,
+ gint row,
+ ETable *table)
+{
+ ECalComponentPreview *task_preview;
+ ECalendarTable *task_table;
+ ECalModel *task_model;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ const gchar *uid;
+
+ task_model = e_task_shell_content_get_task_model (task_shell_content);
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ task_preview = e_task_shell_content_get_task_preview (task_shell_content);
+
+ if (e_table_selected_count (table) != 1) {
+ e_cal_component_preview_clear (task_preview);
+ return;
+ }
+
+ row = e_table_get_cursor_row (table);
+ comp_data = e_cal_model_get_component_at (task_model, row);
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (comp_data->icalcomp));
+ e_cal_component_preview_display (
+ task_preview, comp_data->client, comp);
+
+ e_cal_component_get_uid (comp, &uid);
+ g_free (task_shell_content->priv->current_uid);
+ task_shell_content->priv->current_uid = g_strdup (uid);
+
+ g_object_unref (comp);
+}
+
+static void
+task_shell_content_selection_change_cb (ETaskShellContent *task_shell_content,
+ ETable *table)
+{
+ ECalComponentPreview *task_preview;
+
+ task_preview = e_task_shell_content_get_task_preview (task_shell_content);
+
+ if (e_table_selected_count (table) != 1)
+ e_cal_component_preview_clear (task_preview);
+}
+
+static void
+task_shell_content_model_row_changed_cb (ETaskShellContent *task_shell_content,
+ gint row,
+ ETableModel *model)
+{
+ ECalModelComponent *comp_data;
+ ECalendarTable *task_table;
+ ETable *table;
+ const gchar *current_uid;
+ const gchar *uid;
+
+ current_uid = task_shell_content->priv->current_uid;
+ if (current_uid == NULL)
+ return;
+
+ comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
+ if (comp_data == NULL)
+ return;
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ if (g_strcmp0 (uid, current_uid) != 0)
+ return;
+
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ table = e_calendar_table_get_table (task_table);
+
+ task_shell_content_cursor_change_cb (task_shell_content, 0, table);
+}
+
+static GtkOrientation
+task_shell_content_get_orientation (ETaskShellContent *task_shell_content)
+{
+ return task_shell_content->priv->orientation;
+}
+
+static void
+task_shell_content_set_orientation (ETaskShellContent *task_shell_content,
+ GtkOrientation orientation)
+{
+ task_shell_content->priv->orientation = orientation;
+
+ g_object_notify (G_OBJECT (task_shell_content), "orientation");
+}
+
+static void
+task_shell_content_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ORIENTATION:
+ task_shell_content_set_orientation (
+ E_TASK_SHELL_CONTENT (object),
+ g_value_get_enum (value));
+ return;
+
+ case PROP_PREVIEW_VISIBLE:
+ e_task_shell_content_set_preview_visible (
+ E_TASK_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+task_shell_content_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (
+ value,
+ e_task_shell_content_get_task_model (
+ E_TASK_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_ORIENTATION:
+ g_value_set_enum (
+ value,
+ task_shell_content_get_orientation (
+ E_TASK_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_PREVIEW_VISIBLE:
+ g_value_set_boolean (
+ value,
+ e_task_shell_content_get_preview_visible (
+ E_TASK_SHELL_CONTENT (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+task_shell_content_dispose (GObject *object)
+{
+ ETaskShellContentPrivate *priv;
+
+ priv = E_TASK_SHELL_CONTENT_GET_PRIVATE (object);
+
+ if (priv->paned != NULL) {
+ g_object_unref (priv->paned);
+ priv->paned = NULL;
+ }
+
+ if (priv->task_table != NULL) {
+ g_object_unref (priv->task_table);
+ priv->task_table = NULL;
+ }
+
+ if (priv->task_preview != NULL) {
+ g_object_unref (priv->task_preview);
+ priv->task_preview = NULL;
+ }
+
+ if (priv->task_model != NULL) {
+ g_object_unref (priv->task_model);
+ priv->task_model = NULL;
+ }
+
+ if (priv->view_instance != NULL) {
+ g_object_unref (priv->view_instance);
+ priv->view_instance = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+task_shell_content_finalize (GObject *object)
+{
+ ETaskShellContentPrivate *priv;
+
+ priv = E_TASK_SHELL_CONTENT_GET_PRIVATE (object);
+
+ g_free (priv->current_uid);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+task_shell_content_constructed (GObject *object)
+{
+ ETaskShellContentPrivate *priv;
+ EShell *shell;
+ EShellSettings *shell_settings;
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GalViewInstance *view_instance;
+ icaltimezone *timezone;
+ ETable *table;
+ GConfBridge *bridge;
+ GtkWidget *container;
+ GtkWidget *widget;
+ const gchar *key;
+
+ priv = E_TASK_SHELL_CONTENT_GET_PRIVATE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_content = E_SHELL_CONTENT (object);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ priv->task_model = e_cal_model_tasks_new (shell_settings);
+
+ timezone = e_shell_settings_get_pointer (
+ shell_settings, "cal-timezone");
+
+ /* Build content widgets. */
+
+ container = GTK_WIDGET (object);
+
+ widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->paned = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (object), "orientation",
+ G_OBJECT (widget), "orientation");
+
+ container = widget;
+
+ widget = e_calendar_table_new (shell_view, priv->task_model);
+ gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
+ priv->task_table = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (object), "preview-visible",
+ G_OBJECT (widget), "visible");
+
+ container = widget;
+
+ widget = e_cal_component_preview_new ();
+ e_cal_component_preview_set_default_timezone (
+ E_CAL_COMPONENT_PREVIEW (widget), timezone);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->task_preview = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Configure the task table. */
+
+ widget = E_CALENDAR_TABLE (priv->task_table)->etable;
+ table = e_table_scrolled_get_table (E_TABLE_SCROLLED (widget));
+
+ e_table_set_state (table, E_CALENDAR_TABLE_DEFAULT_STATE);
+
+ e_table_drag_source_set (
+ table, GDK_BUTTON1_MASK,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_ASK);
+
+ g_signal_connect_swapped (
+ table, "table-drag-data-get",
+ G_CALLBACK (task_shell_content_table_drag_data_get_cb),
+ object);
+
+ g_signal_connect_swapped (
+ table, "table-drag-data-delete",
+ G_CALLBACK (task_shell_content_table_drag_data_delete_cb),
+ object);
+
+ g_signal_connect_swapped (
+ table, "cursor-change",
+ G_CALLBACK (task_shell_content_cursor_change_cb),
+ object);
+
+ g_signal_connect_swapped (
+ table, "selection-change",
+ G_CALLBACK (task_shell_content_selection_change_cb),
+ object);
+
+ g_signal_connect_swapped (
+ priv->task_model, "model-row-changed",
+ G_CALLBACK (task_shell_content_model_row_changed_cb),
+ object);
+
+ /* Load the view instance. */
+
+ view_instance = e_shell_view_new_view_instance (shell_view, NULL);
+ g_signal_connect_swapped (
+ view_instance, "display-view",
+ G_CALLBACK (task_shell_content_display_view_cb),
+ object);
+ gal_view_instance_load (view_instance);
+ priv->view_instance = view_instance;
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/calendar/display/task_hpane_position";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "hposition");
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/calendar/display/task_vpane_position";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "vposition");
+}
+
+static guint32
+task_shell_content_check_state (EShellContent *shell_content)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ETable *table;
+ GSList *list, *iter;
+ gboolean assignable = TRUE;
+ gboolean editable = TRUE;
+ gboolean has_url = FALSE;
+ gint n_selected;
+ gint n_complete = 0;
+ gint n_incomplete = 0;
+ guint32 state = 0;
+
+ task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ table = e_calendar_table_get_table (task_table);
+ n_selected = e_table_selected_count (table);
+
+ list = e_calendar_table_get_selected (task_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ icalproperty *prop;
+ const gchar *cap;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ editable &= !read_only;
+
+ cap = CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT;
+ if (e_cal_get_static_capability (comp_data->client, cap))
+ assignable = FALSE;
+
+ cap = CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK;
+ if (e_cal_get_static_capability (comp_data->client, cap))
+ assignable = FALSE;
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_URL_PROPERTY);
+ has_url |= (prop != NULL);
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
+ if (prop != NULL)
+ n_complete++;
+ else
+ n_incomplete++;
+ }
+ g_slist_free (list);
+
+ if (n_selected == 1)
+ state |= E_TASK_SHELL_CONTENT_SELECTION_SINGLE;
+ if (n_selected > 1)
+ state |= E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE;
+ if (assignable)
+ state |= E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN;
+ if (editable)
+ state |= E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT;
+ if (n_complete > 0)
+ state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE;
+ if (n_incomplete > 0)
+ state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE;
+ if (has_url)
+ state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_URL;
+
+ return state;
+}
+
+static void
+task_shell_content_class_init (ETaskShellContentClass *class)
+{
+ GObjectClass *object_class;
+ EShellContentClass *shell_content_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETaskShellContentPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = task_shell_content_set_property;
+ object_class->get_property = task_shell_content_get_property;
+ object_class->dispose = task_shell_content_dispose;
+ object_class->finalize = task_shell_content_finalize;
+ object_class->constructed = task_shell_content_constructed;
+
+ shell_content_class = E_SHELL_CONTENT_CLASS (class);
+ shell_content_class->check_state = task_shell_content_check_state;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ _("Model"),
+ _("The task table model"),
+ E_TYPE_CAL_MODEL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PREVIEW_VISIBLE,
+ g_param_spec_boolean (
+ "preview-visible",
+ _("Preview is Visible"),
+ _("Whether the preview pane is visible"),
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_override_property (
+ object_class, PROP_ORIENTATION, "orientation");
+}
+
+static void
+task_shell_content_init (ETaskShellContent *task_shell_content)
+{
+ task_shell_content->priv =
+ E_TASK_SHELL_CONTENT_GET_PRIVATE (task_shell_content);
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_task_shell_content_get_type (void)
+{
+ return task_shell_content_type;
+}
+
+void
+e_task_shell_content_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (ETaskShellContentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) task_shell_content_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ETaskShellContent),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) task_shell_content_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo orientable_info = {
+ (GInterfaceInitFunc) NULL,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ task_shell_content_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_CONTENT,
+ "ETaskShellContent", &type_info, 0);
+
+ g_type_module_add_interface (
+ type_module, task_shell_content_type,
+ GTK_TYPE_ORIENTABLE, &orientable_info);
+}
+
+GtkWidget *
+e_task_shell_content_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_TASK_SHELL_CONTENT,
+ "shell-view", shell_view, NULL);
+}
+
+ECalModel *
+e_task_shell_content_get_task_model (ETaskShellContent *task_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_CONTENT (task_shell_content), NULL);
+
+ return task_shell_content->priv->task_model;
+}
+
+ECalComponentPreview *
+e_task_shell_content_get_task_preview (ETaskShellContent *task_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_CONTENT (task_shell_content), NULL);
+
+ return E_CAL_COMPONENT_PREVIEW (
+ task_shell_content->priv->task_preview);
+}
+
+ECalendarTable *
+e_task_shell_content_get_task_table (ETaskShellContent *task_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_CONTENT (task_shell_content), NULL);
+
+ return E_CALENDAR_TABLE (task_shell_content->priv->task_table);
+}
+
+gboolean
+e_task_shell_content_get_preview_visible (ETaskShellContent *task_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_CONTENT (task_shell_content), FALSE);
+
+ return task_shell_content->priv->preview_visible;
+}
+
+void
+e_task_shell_content_set_preview_visible (ETaskShellContent *task_shell_content,
+ gboolean preview_visible)
+{
+ g_return_if_fail (E_IS_TASK_SHELL_CONTENT (task_shell_content));
+
+ task_shell_content->priv->preview_visible = preview_visible;
+
+ g_object_notify (G_OBJECT (task_shell_content), "preview-visible");
+}
+
+GalViewInstance *
+e_task_shell_content_get_view_instance (ETaskShellContent *task_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_CONTENT (task_shell_content), NULL);
+
+ return task_shell_content->priv->view_instance;
+}
diff --git a/modules/calendar/e-task-shell-content.h b/modules/calendar/e-task-shell-content.h
new file mode 100644
index 0000000000..f5d4fc9665
--- /dev/null
+++ b/modules/calendar/e-task-shell-content.h
@@ -0,0 +1,100 @@
+/*
+ * e-task-shell-content.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TASK_SHELL_CONTENT_H
+#define E_TASK_SHELL_CONTENT_H
+
+#include <shell/e-shell-content.h>
+#include <shell/e-shell-view.h>
+
+#include <calendar/gui/e-cal-model.h>
+#include <calendar/gui/e-calendar-table.h>
+#include <calendar/gui/e-cal-component-preview.h>
+
+#include <menus/gal-view-instance.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TASK_SHELL_CONTENT \
+ (e_task_shell_content_get_type ())
+#define E_TASK_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TASK_SHELL_CONTENT, ETaskShellContent))
+#define E_TASK_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TASK_SHELL_CONTENT, ETaskShellContentClass))
+#define E_IS_TASK_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TASK_SHELL_CONTENT))
+#define E_IS_TASK_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TASK_SHELL_CONTENT))
+#define E_TASK_SHELL_CONTENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TASK_SHELL_CONTENT, ETaskShellContentClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETaskShellContent ETaskShellContent;
+typedef struct _ETaskShellContentClass ETaskShellContentClass;
+typedef struct _ETaskShellContentPrivate ETaskShellContentPrivate;
+
+enum {
+ E_TASK_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0,
+ E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1,
+ E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN = 1 << 2,
+ E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT = 1 << 3,
+ E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE = 1 << 4,
+ E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE = 1 << 5,
+ E_TASK_SHELL_CONTENT_SELECTION_HAS_URL = 1 << 6
+};
+
+struct _ETaskShellContent {
+ EShellContent parent;
+ ETaskShellContentPrivate *priv;
+};
+
+struct _ETaskShellContentClass {
+ EShellContentClass parent_class;
+};
+
+GType e_task_shell_content_get_type (void);
+void e_task_shell_content_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_task_shell_content_new(EShellView *shell_view);
+ECalModel * e_task_shell_content_get_task_model
+ (ETaskShellContent *task_shell_content);
+ECalComponentPreview *
+ e_task_shell_content_get_task_preview
+ (ETaskShellContent *task_shell_content);
+ECalendarTable *e_task_shell_content_get_task_table
+ (ETaskShellContent *task_shell_content);
+gboolean e_task_shell_content_get_preview_visible
+ (ETaskShellContent *task_shell_content);
+void e_task_shell_content_set_preview_visible
+ (ETaskShellContent *task_shell_content,
+ gboolean preview_visible);
+GalViewInstance *
+ e_task_shell_content_get_view_instance
+ (ETaskShellContent *task_shell_content);
+
+G_END_DECLS
+
+#endif /* E_TASK_SHELL_CONTENT_H */
diff --git a/modules/calendar/e-task-shell-migrate.c b/modules/calendar/e-task-shell-migrate.c
new file mode 100644
index 0000000000..799298f5a7
--- /dev/null
+++ b/modules/calendar/e-task-shell-migrate.c
@@ -0,0 +1,675 @@
+/*
+ * e-task-shell-backend-migrate.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-task-shell-migrate.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <libebackend/e-dbhash.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-xml-hash-utils.h>
+#include <libedataserver/e-xml-utils.h>
+
+#include "e-util/e-bconf-map.h"
+#include "e-util/e-folder-map.h"
+#include "e-util/e-util-private.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/calendar-config-keys.h"
+#include "shell/e-shell.h"
+
+#define WEBCAL_BASE_URI "webcal://"
+#define PERSONAL_RELATIVE_URI "system"
+
+static e_gconf_map_t calendar_tasks_map[] = {
+ /* /Calendar/Tasks */
+ { "HideCompletedTasks", "calendar/tasks/hide_completed", E_GCONF_MAP_BOOL },
+ { "HideCompletedTasksUnits", "calendar/tasks/hide_completed_units", E_GCONF_MAP_STRING },
+ { "HideCompletedTasksValue", "calendar/tasks/hide_completed_value", E_GCONF_MAP_INT },
+ { NULL },
+};
+
+static e_gconf_map_t calendar_tasks_colours_map[] = {
+ /* /Calendar/Tasks/Colors */
+ { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING },
+ { "TasksOverDue", "calendar/tasks/colors/overdue", E_GCONF_MAP_STRING },
+ { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING },
+ { NULL },
+};
+
+static e_gconf_map_list_t task_remap_list[] = {
+
+ { "/Calendar/Tasks", calendar_tasks_map },
+ { "/Calendar/Tasks/Colors", calendar_tasks_colours_map },
+
+ { NULL },
+};
+
+static GtkWidget *window;
+static GtkLabel *label;
+static GtkProgressBar *progress;
+
+#ifndef G_OS_WIN32
+
+/* No previous versions have been available on Win32, so don't
+ * bother with upgrade support from 1.x on Win32.
+ */
+
+static void
+setup_progress_dialog (void)
+{
+ GtkWidget *vbox, *hbox, *w;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title ((GtkWindow *) window, _("Migrating..."));
+ gtk_window_set_modal ((GtkWindow *) window, TRUE);
+ gtk_container_set_border_width ((GtkContainer *) window, 6);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
+ gtk_container_add ((GtkContainer *) window, vbox);
+
+ w = gtk_label_new (_("The location and hierarchy of the Evolution task "
+ "folders has changed since Evolution 1.x.\n\nPlease be "
+ "patient while Evolution migrates your folders..."));
+
+ gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
+ gtk_widget_show (w);
+ gtk_box_pack_start ((GtkBox *) vbox, w, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_widget_show (hbox);
+ gtk_box_pack_start ((GtkBox *) vbox, hbox, TRUE, TRUE, 0);
+
+ label = (GtkLabel *) gtk_label_new ("");
+ gtk_widget_show ((GtkWidget *) label);
+ gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) label, TRUE, TRUE, 0);
+
+ progress = (GtkProgressBar *) gtk_progress_bar_new ();
+ gtk_widget_show ((GtkWidget *) progress);
+ gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) progress, TRUE, TRUE, 0);
+
+ gtk_widget_show (window);
+}
+
+static void
+dialog_close (void)
+{
+ gtk_widget_destroy ((GtkWidget *) window);
+}
+
+static void
+dialog_set_folder_name (const gchar *folder_name)
+{
+ gchar *text;
+
+ text = g_strdup_printf (_("Migrating '%s':"), folder_name);
+ gtk_label_set_text (label, text);
+ g_free (text);
+
+ gtk_progress_bar_set_fraction (progress, 0.0);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+}
+
+static void
+dialog_set_progress (double percent)
+{
+ gchar text[5];
+
+ snprintf (text, sizeof (text), "%d%%", (gint) (percent * 100.0f));
+
+ gtk_progress_bar_set_fraction (progress, percent);
+ gtk_progress_bar_set_text (progress, text);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+}
+
+static gboolean
+check_for_conflict (ESourceGroup *group, gchar *name)
+{
+ GSList *sources;
+ GSList *s;
+
+ sources = e_source_group_peek_sources (group);
+
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+
+ if (!strcmp (e_source_peek_name (source), name))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gchar *
+get_source_name (ESourceGroup *group, const gchar *path)
+{
+ gchar **p = g_strsplit (path, "/", 0);
+ gint i, j, starting_index;
+ gint num_elements;
+ gboolean conflict;
+ GString *s = g_string_new (NULL);
+
+ for (i = 0; p[i]; i ++);
+
+ num_elements = i;
+ i--;
+
+ /* p[i] is now the last path element */
+
+ /* check if it conflicts */
+ starting_index = i;
+ do {
+ for (j = starting_index; j < num_elements; j += 2) {
+ if (j != starting_index)
+ g_string_append_c (s, '_');
+ g_string_append (s, p[j]);
+ }
+
+ conflict = check_for_conflict (group, s->str);
+
+ /* if there was a conflict back up 2 levels (skipping the /subfolder/ element) */
+ if (conflict)
+ starting_index -= 2;
+
+ /* we always break out if we can't go any further,
+ regardless of whether or not we conflict. */
+ if (starting_index < 0)
+ break;
+
+ } while (conflict);
+ g_strfreev (p);
+
+ return g_string_free (s, FALSE);
+}
+
+static gboolean
+migrate_ical (ECal *old_ecal, ECal *new_ecal)
+{
+ GList *l, *objects;
+ gint num_added = 0;
+ gint num_objects;
+ gboolean retval = TRUE;
+
+ /* both ecals are loaded, start the actual migration */
+ if (!e_cal_get_object_list (old_ecal, "#t", &objects, NULL))
+ return FALSE;
+
+ num_objects = g_list_length (objects);
+ for (l = objects; l; l = l->next) {
+ icalcomponent *ical_comp = l->data;
+ GError *error = NULL;
+
+ if (!e_cal_create_object (new_ecal, ical_comp, NULL, &error)) {
+ g_warning ("Migration of object failed: %s", error->message);
+ retval = FALSE;
+ }
+
+ g_clear_error (&error);
+
+ num_added ++;
+ dialog_set_progress ((double)num_added / num_objects);
+ }
+
+ g_list_foreach (objects, (GFunc) icalcomponent_free, NULL);
+ g_list_free (objects);
+
+ return retval;
+}
+
+static gboolean
+migrate_ical_folder_to_source (gchar *old_path, ESource *new_source, ECalSourceType type)
+{
+ ECal *old_ecal = NULL, *new_ecal = NULL;
+ ESource *old_source;
+ ESourceGroup *group;
+ gchar *old_uri = g_strdup_printf ("file://%s", old_path);
+ GError *error = NULL;
+ gboolean retval = FALSE;
+
+ group = e_source_group_new ("", old_uri);
+ old_source = e_source_new ("", "");
+ e_source_group_add_source (group, old_source, -1);
+
+ dialog_set_folder_name (e_source_peek_name (new_source));
+
+ if (!(old_ecal = e_cal_new (old_source, type))) {
+ g_warning ("could not find a backend for '%s'", e_source_get_uri (old_source));
+ goto finish;
+ }
+ if (!e_cal_open (old_ecal, FALSE, &error)) {
+ g_warning ("failed to load source ecal for migration: '%s' (%s)", error->message,
+ e_source_get_uri (old_source));
+ goto finish;
+ }
+
+ if (!(new_ecal = e_cal_new (new_source, type))) {
+ g_warning ("could not find a backend for '%s'", e_source_get_uri (new_source));
+ goto finish;
+ }
+ if (!e_cal_open (new_ecal, FALSE, &error)) {
+ g_warning ("failed to load destination ecal for migration: '%s' (%s)", error->message,
+ e_source_get_uri (new_source));
+ goto finish;
+ }
+
+ retval = migrate_ical (old_ecal, new_ecal);
+
+finish:
+ g_clear_error (&error);
+ if (old_ecal)
+ g_object_unref (old_ecal);
+ g_object_unref (group);
+ if (new_ecal)
+ g_object_unref (new_ecal);
+ g_free (old_uri);
+
+ return retval;
+}
+
+static gboolean
+migrate_ical_folder (gchar *old_path, ESourceGroup *dest_group, gchar *source_name, ECalSourceType type)
+{
+ ESource *new_source;
+ gboolean retval;
+
+ new_source = e_source_new (source_name, source_name);
+ e_source_set_relative_uri (new_source, e_source_peek_uid (new_source));
+ e_source_group_add_source (dest_group, new_source, -1);
+
+ retval = migrate_ical_folder_to_source (old_path, new_source, type);
+
+ g_object_unref (new_source);
+
+ return retval;
+}
+
+#endif /* !G_OS_WIN32 */
+
+#ifndef G_OS_WIN32
+
+static void
+migrate_pilot_db_key (const gchar *key, gpointer user_data)
+{
+ EXmlHash *xmlhash = user_data;
+
+ e_xmlhash_add (xmlhash, key, "");
+}
+
+static void
+migrate_pilot_data (const gchar *component, const gchar *conduit, const gchar *old_path, const gchar *new_path)
+{
+ gchar *changelog, *map;
+ const gchar *dent;
+ const gchar *ext;
+ gchar *filename;
+ GDir *dir;
+
+ if (!(dir = g_dir_open (old_path, 0, NULL)))
+ return;
+
+ map = g_alloca (12 + strlen (conduit));
+ sprintf (map, "pilot-map-%s-", conduit);
+
+ changelog = g_alloca (24 + strlen (conduit));
+ sprintf (changelog, "pilot-sync-evolution-%s-", conduit);
+
+ while ((dent = g_dir_read_name (dir))) {
+ if (!strncmp (dent, map, strlen (map)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) {
+ /* pilot map file - src and dest file formats are identical */
+ guchar inbuf[4096];
+ gsize nread, nwritten;
+ gint fd0, fd1;
+ gssize n;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ g_free (filename);
+ filename = g_build_filename (new_path, dent, NULL);
+ if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) {
+ g_free (filename);
+ close (fd0);
+ continue;
+ }
+
+ do {
+ do {
+ n = read (fd0, inbuf, sizeof (inbuf));
+ } while (n == -1 && errno == EINTR);
+
+ if (n < 1)
+ break;
+
+ nread = n;
+ nwritten = 0;
+ do {
+ do {
+ n = write (fd1, inbuf + nwritten, nread - nwritten);
+ } while (n == -1 && errno == EINTR);
+
+ if (n > 0)
+ nwritten += n;
+ } while (nwritten < nread && n != -1);
+
+ if (n == -1)
+ break;
+ } while (1);
+
+ if (n != -1)
+ n = fsync (fd1);
+
+ if (n == -1) {
+ g_warning ("Failed to migrate %s: %s", dent, strerror (errno));
+ g_unlink (filename);
+ }
+
+ close (fd0);
+ close (fd1);
+ g_free (filename);
+ } else if (!strncmp (dent, changelog, strlen (changelog)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) {
+ /* src and dest formats differ, src format is db3 while dest format is xml */
+ EXmlHash *xmlhash;
+ EDbHash *dbhash;
+ struct stat st;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if (g_stat (filename, &st) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ dbhash = e_dbhash_new (filename);
+ g_free (filename);
+
+ filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent);
+ if (g_stat (filename, &st) != -1)
+ g_unlink (filename);
+ xmlhash = e_xmlhash_new (filename);
+ g_free (filename);
+
+ e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash);
+
+ e_dbhash_destroy (dbhash);
+
+ e_xmlhash_write (xmlhash);
+ e_xmlhash_destroy (xmlhash);
+ }
+ }
+
+ g_dir_close (dir);
+}
+
+#endif
+
+static void
+create_task_sources (EShellBackend *shell_backend,
+ ESourceList *source_list,
+ ESourceGroup **on_this_computer,
+ ESourceGroup **on_the_web,
+ ESource **personal_source)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GSList *groups;
+ ESourceGroup *group;
+ gchar *base_uri, *base_uri_proto;
+ const gchar *base_dir;
+
+ *on_this_computer = NULL;
+ *on_the_web = NULL;
+ *personal_source = NULL;
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ base_dir = e_shell_backend_get_config_dir (shell_backend);
+ base_uri = g_build_filename (base_dir, "local", NULL);
+
+ base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
+
+ groups = e_source_list_peek_groups (source_list);
+ if (groups) {
+ /* groups are already there, we need to search for things... */
+ GSList *g;
+
+ for (g = groups; g; g = g->next) {
+
+ group = E_SOURCE_GROUP (g->data);
+
+ if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
+ *on_this_computer = g_object_ref (group);
+ else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
+ *on_the_web = g_object_ref (group);
+ }
+ }
+
+ if (*on_this_computer) {
+ /* make sure "Personal" shows up as a source under
+ this group */
+ GSList *sources = e_source_group_peek_sources (*on_this_computer);
+ GSList *s;
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+ if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
+ *personal_source = g_object_ref (source);
+ break;
+ }
+ }
+ } else {
+ /* create the local source group */
+ group = e_source_group_new (_("On This Computer"), base_uri_proto);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_this_computer = group;
+ }
+
+ if (!*personal_source) {
+ gchar *primary_task_list;
+
+ /* Create the default Person task list */
+ ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (*on_this_computer, source, -1);
+
+ primary_task_list = e_shell_settings_get_string (
+ shell_settings, "cal-primary-task-list");
+
+ if (!primary_task_list && !calendar_config_get_tasks_selected ()) {
+ GSList selected;
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-task-list",
+ e_source_peek_uid (source));
+
+ selected.data = (gpointer)e_source_peek_uid (source);
+ selected.next = NULL;
+ calendar_config_set_tasks_selected (&selected);
+ }
+
+ e_source_set_color_spec (source, "#BECEDD");
+ *personal_source = source;
+ }
+
+ if (!*on_the_web) {
+ /* Create the Webcal source group */
+ group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_the_web = group;
+ }
+
+ g_free (base_uri_proto);
+ g_free (base_uri);
+}
+
+gboolean
+e_task_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ ESourceGroup *on_this_computer = NULL;
+ ESourceGroup *on_the_web = NULL;
+ ESource *personal_source = NULL;
+ ESourceList *source_list;
+ gboolean retval = FALSE;
+
+ g_object_get (shell_backend, "source-list", &source_list, NULL);
+
+ /* we call this unconditionally now - create_groups either
+ creates the groups/sources or it finds the necessary
+ groups/sources. */
+ create_task_sources (
+ shell_backend, source_list, &on_this_computer,
+ &on_the_web, &personal_source);
+
+#ifndef G_OS_WIN32
+ if (major == 1) {
+ xmlDocPtr config_doc = NULL;
+ gchar *conf_file;
+
+ conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL);
+ if (g_file_test (conf_file, G_FILE_TEST_IS_REGULAR))
+ config_doc = e_xml_parse_file (conf_file);
+ g_free (conf_file);
+
+ if (config_doc && minor <= 2) {
+ GConfClient *gconf;
+ gint res = 0;
+
+ /* move bonobo config to gconf */
+ gconf = gconf_client_get_default ();
+
+ res = e_bconf_import (gconf, config_doc, task_remap_list);
+
+ g_object_unref (gconf);
+
+ xmlFreeDoc(config_doc);
+
+ if (res != 0) {
+ g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb"));
+ goto fail;
+ }
+ }
+
+ if (minor <= 4) {
+ GSList *migration_dirs, *l;
+ gchar *path, *local_task_folder;
+
+ setup_progress_dialog ();
+
+ path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
+ migration_dirs = e_folder_map_local_folders (path, "tasks");
+ local_task_folder = g_build_filename (path, "Tasks", NULL);
+ g_free (path);
+
+ if (personal_source)
+ migrate_ical_folder_to_source (local_task_folder, personal_source, E_CAL_SOURCE_TYPE_TODO);
+
+ for (l = migration_dirs; l; l = l->next) {
+ gchar *source_name;
+
+ if (personal_source && !strcmp ((gchar *)l->data, local_task_folder))
+ continue;
+
+ source_name = get_source_name (on_this_computer, (gchar *)l->data);
+
+ if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_TODO)) {
+ /* FIXME: domain/code */
+ g_set_error(error, 0, 0, _("Unable to migrate tasks `%s'"), source_name);
+ g_free(source_name);
+ goto fail;
+ }
+
+ g_free (source_name);
+ }
+
+ g_free (local_task_folder);
+
+ dialog_close ();
+ }
+
+ if (minor < 5 || (minor == 5 && micro <= 10)) {
+ gchar *old_path, *new_path;
+
+ old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Tasks", NULL);
+ new_path = g_build_filename (e_shell_backend_get_config_dir (shell_backend),
+ "local", "system", NULL);
+ migrate_pilot_data ("tasks", "todo", old_path, new_path);
+ g_free (new_path);
+ g_free (old_path);
+ }
+
+ /* we only need to do this next step if people ran
+ older versions of 1.5. We need to clear out the
+ absolute URI's that were assigned to ESources
+ during one phase of development, as they take
+ precedent over relative uris (but aren't updated
+ when editing an ESource). */
+ if (minor == 5 && micro <= 11) {
+ GSList *g;
+ for (g = e_source_list_peek_groups (source_list); g; g = g->next) {
+ ESourceGroup *group = g->data;
+ GSList *s;
+
+ for (s = e_source_group_peek_sources (group); s; s = s->next) {
+ ESource *source = s->data;
+ e_source_set_absolute_uri (source, NULL);
+ }
+ }
+ }
+ }
+#endif /* !G_OS_WIN32 */
+ e_source_list_sync (source_list, NULL);
+ retval = TRUE;
+fail:
+ if (on_this_computer)
+ g_object_unref (on_this_computer);
+ if (on_the_web)
+ g_object_unref (on_the_web);
+ if (personal_source)
+ g_object_unref (personal_source);
+
+ return retval;
+}
diff --git a/modules/calendar/e-task-shell-migrate.h b/modules/calendar/e-task-shell-migrate.h
new file mode 100644
index 0000000000..4cb91c9f4a
--- /dev/null
+++ b/modules/calendar/e-task-shell-migrate.h
@@ -0,0 +1,38 @@
+/*
+ * e-task-shell-backend-migrate.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TASK_SHELL_BACKEND_MIGRATE_H
+#define E_TASK_SHELL_BACKEND_MIGRATE_H
+
+#include <glib.h>
+#include <shell/e-shell-backend.h>
+
+G_BEGIN_DECLS
+
+gboolean e_task_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_TASK_SHELL_BACKEND_MIGRATE_H */
diff --git a/modules/calendar/e-task-shell-sidebar.c b/modules/calendar/e-task-shell-sidebar.c
new file mode 100644
index 0000000000..6bd7700fcf
--- /dev/null
+++ b/modules/calendar/e-task-shell-sidebar.c
@@ -0,0 +1,714 @@
+/*
+ * e-task-shell-sidebar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-task-shell-sidebar.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libecal/e-cal.h>
+
+#include "e-util/e-error.h"
+#include "e-util/e-util.h"
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/e-task-list-selector.h"
+#include "calendar/gui/misc.h"
+
+#include "e-task-shell-backend.h"
+#include "e-task-shell-view.h"
+
+#define E_TASK_SHELL_SIDEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TASK_SHELL_SIDEBAR, ETaskShellSidebarPrivate))
+
+struct _ETaskShellSidebarPrivate {
+ GtkWidget *selector;
+
+ /* UID -> Client */
+ GHashTable *client_table;
+};
+
+enum {
+ PROP_0,
+ PROP_SELECTOR
+};
+
+enum {
+ CLIENT_ADDED,
+ CLIENT_REMOVED,
+ STATUS_MESSAGE,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+static GType task_shell_sidebar_type;
+
+static void
+task_shell_sidebar_emit_client_added (ETaskShellSidebar *task_shell_sidebar,
+ ECal *client)
+{
+ guint signal_id = signals[CLIENT_ADDED];
+
+ g_signal_emit (task_shell_sidebar, signal_id, 0, client);
+}
+
+static void
+task_shell_sidebar_emit_client_removed (ETaskShellSidebar *task_shell_sidebar,
+ ECal *client)
+{
+ guint signal_id = signals[CLIENT_REMOVED];
+
+ g_signal_emit (task_shell_sidebar, signal_id, 0, client);
+}
+
+static void
+task_shell_sidebar_emit_status_message (ETaskShellSidebar *task_shell_sidebar,
+ const gchar *status_message)
+{
+ guint signal_id = signals[STATUS_MESSAGE];
+
+ g_signal_emit (task_shell_sidebar, signal_id, 0, status_message, -1.0);
+}
+
+static void
+task_shell_sidebar_backend_died_cb (ETaskShellSidebar *task_shell_sidebar,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ GHashTable *client_table;
+ ESource *source;
+ const gchar *uid;
+
+ client_table = task_shell_sidebar->priv->client_table;
+
+ shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ source = e_cal_get_source (client);
+ uid = e_source_peek_uid (source);
+
+ g_object_ref (source);
+
+ g_hash_table_remove (client_table, uid);
+ task_shell_sidebar_emit_status_message (task_shell_sidebar, NULL);
+
+ e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:tasks-crashed", NULL);
+
+ g_object_unref (source);
+}
+
+static void
+task_shell_sidebar_backend_error_cb (ETaskShellSidebar *task_shell_sidebar,
+ const gchar *message,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ GtkWidget *dialog;
+ const gchar *uri;
+ gchar *uri_no_passwd;
+
+ shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ uri = e_cal_get_uri (client);
+ uri_no_passwd = get_uri_without_password (uri);
+
+ dialog = gtk_message_dialog_new (
+ GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ _("Error on %s\n%s"),
+ uri_no_passwd, message);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ g_free (uri_no_passwd);
+}
+
+static void
+task_shell_sidebar_client_opened_cb (ETaskShellSidebar *task_shell_sidebar,
+ ECalendarStatus status,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ ESource *source;
+
+ source = e_cal_get_source (client);
+
+ shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED ||
+ status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
+ auth_cal_forget_password (client);
+
+ switch (status) {
+ case E_CALENDAR_STATUS_OK:
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ task_shell_sidebar_client_opened_cb, NULL);
+
+ task_shell_sidebar_emit_status_message (
+ task_shell_sidebar, _("Loading tasks"));
+ task_shell_sidebar_emit_client_added (
+ task_shell_sidebar, client);
+ task_shell_sidebar_emit_status_message (
+ task_shell_sidebar, NULL);
+ break;
+
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
+ e_cal_open_async (client, FALSE);
+ break;
+
+ case E_CALENDAR_STATUS_BUSY:
+ break;
+
+ case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
+ e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:prompt-no-contents-offline-tasks",
+ NULL);
+ break;
+
+ default:
+ task_shell_sidebar_emit_client_removed (
+ task_shell_sidebar, client);
+ break;
+ }
+}
+
+static void
+task_shell_sidebar_row_changed_cb (ETaskShellSidebar *task_shell_sidebar,
+ GtkTreePath *tree_path,
+ GtkTreeIter *tree_iter,
+ GtkTreeModel *tree_model)
+{
+ ESourceSelector *selector;
+ ESource *source;
+
+ /* XXX ESourceSelector's underlying tree store has only one
+ * column: ESource objects. While we're not supposed to
+ * know this, listening for "row-changed" signals from
+ * the model is easier to deal with than the selector's
+ * "selection-changed" signal, which doesn't tell you
+ * _which_ row changed. */
+
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+ gtk_tree_model_get (tree_model, tree_iter, 0, &source, -1);
+
+ /* XXX This signal gets emitted a lot while the model is being
+ * rebuilt, during which time we won't get a valid ESource.
+ * ESourceSelector should probably block this signal while
+ * rebuilding the model, but we'll be forgiving and not
+ * emit a warning. */
+ if (!E_IS_SOURCE (source))
+ return;
+
+ if (e_source_selector_source_is_selected (selector, source))
+ e_task_shell_sidebar_add_source (task_shell_sidebar, source);
+ else
+ e_task_shell_sidebar_remove_source (task_shell_sidebar, source);
+}
+
+static void
+task_shell_sidebar_selection_changed_cb (ETaskShellSidebar *task_shell_sidebar,
+ ESourceSelector *selector)
+{
+ GSList *list, *iter;
+
+ /* This signal is emitted less frequently than "row-changed",
+ * especially when the model is being rebuilt. So we'll take
+ * it easy on poor GConf. */
+
+ list = e_source_selector_get_selection (selector);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+
+ iter->data = (gpointer) e_source_peek_uid (source);
+ g_object_unref (source);
+ }
+
+ calendar_config_set_tasks_selected (list);
+
+ g_slist_free (list);
+}
+
+static void
+task_shell_sidebar_primary_selection_changed_cb (ETaskShellSidebar *task_shell_sidebar,
+ ESourceSelector *selector)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESource *source;
+
+ /* XXX ESourceSelector needs a "primary-selection-uid" property
+ * so we can just bind the property with GConfBridge. */
+
+ source = e_source_selector_peek_primary_selection (selector);
+ if (source == NULL)
+ return;
+
+ shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-task-list",
+ e_source_peek_uid (source));
+}
+
+static void
+task_shell_sidebar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SELECTOR:
+ g_value_set_object (
+ value, e_task_shell_sidebar_get_selector (
+ E_TASK_SHELL_SIDEBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+task_shell_sidebar_dispose (GObject *object)
+{
+ ETaskShellSidebarPrivate *priv;
+
+ priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ if (priv->selector != NULL) {
+ g_object_unref (priv->selector);
+ priv->selector = NULL;
+ }
+
+ g_hash_table_remove_all (priv->client_table);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+task_shell_sidebar_finalize (GObject *object)
+{
+ ETaskShellSidebarPrivate *priv;
+
+ priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->client_table);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+task_shell_sidebar_constructed (GObject *object)
+{
+ ETaskShellSidebarPrivate *priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESourceSelector *selector;
+ ESourceList *source_list;
+ ESource *source;
+ GtkContainer *container;
+ GtkTreeModel *model;
+ GtkWidget *widget;
+ AtkObject *a11y;
+ GSList *list, *iter;
+ gchar *uid;
+
+ priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_sidebar = E_SHELL_SIDEBAR (object);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ source_list = e_task_shell_backend_get_source_list (
+ E_TASK_SHELL_BACKEND (shell_backend));
+
+ container = GTK_CONTAINER (shell_sidebar);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_container_add (container, widget);
+ gtk_widget_show (widget);
+
+ container = GTK_CONTAINER (widget);
+
+ widget = e_task_list_selector_new (source_list);
+ e_source_selector_set_select_new (E_SOURCE_SELECTOR (widget), TRUE);
+ gtk_container_add (container, widget);
+ a11y = gtk_widget_get_accessible (widget);
+ atk_object_set_name (a11y, _("Task List Selector"));
+ priv->selector = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Restore the selector state from the last session. */
+
+ selector = E_SOURCE_SELECTOR (priv->selector);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ model, "row-changed",
+ G_CALLBACK (task_shell_sidebar_row_changed_cb),
+ object);
+
+ source = NULL;
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-task-list");
+ if (uid != NULL)
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ if (source == NULL)
+ source = e_source_list_peek_source_any (source_list);
+ if (source != NULL)
+ e_source_selector_set_primary_selection (selector, source);
+ g_free (uid);
+
+ list = calendar_config_get_tasks_selected ();
+ for (iter = list; iter != NULL; iter = iter->next) {
+ uid = iter->data;
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ g_free (uid);
+
+ if (source == NULL)
+ continue;
+
+ e_source_selector_select_source (selector, source);
+ }
+ g_slist_free (list);
+
+ /* Listen for subsequent changes to the selector. */
+
+ g_signal_connect_swapped (
+ widget, "selection-changed",
+ G_CALLBACK (task_shell_sidebar_selection_changed_cb),
+ object);
+
+ g_signal_connect_swapped (
+ widget, "primary-selection-changed",
+ G_CALLBACK (task_shell_sidebar_primary_selection_changed_cb),
+ object);
+}
+
+static guint32
+task_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+ ETaskShellSidebar *task_shell_sidebar;
+ ESourceSelector *selector;
+ ESource *source;
+ gboolean is_system = FALSE;
+ guint32 state = 0;
+
+ task_shell_sidebar = E_TASK_SHELL_SIDEBAR (shell_sidebar);
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+
+ if (source != NULL) {
+ const gchar *uri;
+
+ uri = e_source_peek_relative_uri (source);
+ is_system = (uri == NULL || strcmp (uri, "system") == 0);
+ }
+
+ if (source != NULL)
+ state |= E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE;
+ if (is_system)
+ state |= E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM;
+
+ return state;
+}
+
+static void
+task_shell_sidebar_client_removed (ETaskShellSidebar *task_shell_sidebar,
+ ECal *client)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ESource *source;
+ const gchar *uid;
+
+ client_table = task_shell_sidebar->priv->client_table;
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_DATA, 0, 0,
+ NULL, NULL, task_shell_sidebar);
+
+ source = e_cal_get_source (client);
+ e_source_selector_unselect_source (selector, source);
+
+ uid = e_source_peek_uid (source);
+ g_hash_table_remove (client_table, uid);
+
+ task_shell_sidebar_emit_status_message (task_shell_sidebar, NULL);
+}
+
+static void
+task_shell_sidebar_class_init (ETaskShellSidebarClass *class)
+{
+ GObjectClass *object_class;
+ EShellSidebarClass *shell_sidebar_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETaskShellSidebarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = task_shell_sidebar_get_property;
+ object_class->dispose = task_shell_sidebar_dispose;
+ object_class->finalize = task_shell_sidebar_finalize;
+ object_class->constructed = task_shell_sidebar_constructed;
+
+ shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
+ shell_sidebar_class->check_state = task_shell_sidebar_check_state;
+
+ class->client_removed = task_shell_sidebar_client_removed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTOR,
+ g_param_spec_object (
+ "selector",
+ _("Source Selector Widget"),
+ _("This widget displays groups of task lists"),
+ E_TYPE_SOURCE_SELECTOR,
+ G_PARAM_READABLE));
+
+ signals[CLIENT_ADDED] = g_signal_new (
+ "client-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ETaskShellSidebarClass, client_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CAL);
+
+ signals[CLIENT_REMOVED] = g_signal_new (
+ "client-removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ETaskShellSidebarClass, client_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CAL);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status-message",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ETaskShellSidebarClass, status_message),
+ NULL, NULL,
+ e_marshal_VOID__STRING_DOUBLE,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_DOUBLE);
+}
+
+static void
+task_shell_sidebar_init (ETaskShellSidebar *task_shell_sidebar)
+{
+ GHashTable *client_table;
+
+ client_table = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ task_shell_sidebar->priv =
+ E_TASK_SHELL_SIDEBAR_GET_PRIVATE (task_shell_sidebar);
+
+ task_shell_sidebar->priv->client_table = client_table;
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_task_shell_sidebar_get_type (void)
+{
+ return task_shell_sidebar_type;
+}
+
+void
+e_task_shell_sidebar_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (ETaskShellSidebarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) task_shell_sidebar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ETaskShellSidebar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) task_shell_sidebar_init,
+ NULL /* value_table */
+ };
+
+ task_shell_sidebar_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_SIDEBAR,
+ "ETaskShellSidebar", &type_info, 0);
+}
+
+GtkWidget *
+e_task_shell_sidebar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_TASK_SHELL_SIDEBAR,
+ "shell-view", shell_view, NULL);
+}
+
+GList *
+e_task_shell_sidebar_get_clients (ETaskShellSidebar *task_shell_sidebar)
+{
+ GHashTable *client_table;
+
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar), NULL);
+
+ client_table = task_shell_sidebar->priv->client_table;
+
+ return g_hash_table_get_values (client_table);
+}
+
+ESourceSelector *
+e_task_shell_sidebar_get_selector (ETaskShellSidebar *task_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar), NULL);
+
+ return E_SOURCE_SELECTOR (task_shell_sidebar->priv->selector);
+}
+
+void
+e_task_shell_sidebar_add_source (ETaskShellSidebar *task_shell_sidebar,
+ ESource *source)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+ const gchar *uri;
+ gchar *message;
+
+ g_return_if_fail (E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar));
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ client_table = task_shell_sidebar->priv->client_table;
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (client != NULL)
+ return;
+
+ client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
+ g_return_if_fail (client != NULL);
+
+ g_signal_connect_swapped (
+ client, "backend-died",
+ G_CALLBACK (task_shell_sidebar_backend_died_cb),
+ task_shell_sidebar);
+
+ g_signal_connect_swapped (
+ client, "backend-error",
+ G_CALLBACK (task_shell_sidebar_backend_error_cb),
+ task_shell_sidebar);
+
+ g_hash_table_insert (client_table, g_strdup (uid), client);
+ e_source_selector_select_source (selector, source);
+
+ uri = e_cal_get_uri (client);
+ message = g_strdup_printf (_("Opening tasks at %s"), uri);
+ task_shell_sidebar_emit_status_message (task_shell_sidebar, message);
+ g_free (message);
+
+ g_signal_connect_swapped (
+ client, "cal-opened",
+ G_CALLBACK (task_shell_sidebar_client_opened_cb),
+ task_shell_sidebar);
+
+ e_cal_open_async (client, FALSE);
+}
+
+void
+e_task_shell_sidebar_remove_source (ETaskShellSidebar *task_shell_sidebar,
+ ESource *source)
+{
+ ESourceSelector *selector;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar));
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ client_table = task_shell_sidebar->priv->client_table;
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (client == NULL)
+ return;
+
+ task_shell_sidebar_emit_client_removed (task_shell_sidebar, client);
+}
diff --git a/modules/calendar/e-task-shell-sidebar.h b/modules/calendar/e-task-shell-sidebar.h
new file mode 100644
index 0000000000..5d4c74fe11
--- /dev/null
+++ b/modules/calendar/e-task-shell-sidebar.h
@@ -0,0 +1,97 @@
+/*
+ * e-task-shell-sidebar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TASK_SHELL_SIDEBAR_H
+#define E_TASK_SHELL_SIDEBAR_H
+
+#include <libecal/e-cal.h>
+#include <libedataserverui/e-source-selector.h>
+
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TASK_SHELL_SIDEBAR \
+ (e_task_shell_sidebar_get_type ())
+#define E_TASK_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TASK_SHELL_SIDEBAR, ETaskShellSidebar))
+#define E_TASK_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TASK_SHELL_SIDEBAR, ETaskShellSidebarClass))
+#define E_IS_TASK_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TASK_SHELL_SIDEBAR))
+#define E_IS_TASK_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TASK_SHELL_SIDEBAR))
+#define E_TASK_SHELL_SIDEBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TASK_SHELL_SIDEBAR, ETaskShellSidebarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETaskShellSidebar ETaskShellSidebar;
+typedef struct _ETaskShellSidebarClass ETaskShellSidebarClass;
+typedef struct _ETaskShellSidebarPrivate ETaskShellSidebarPrivate;
+
+enum {
+ E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0,
+ E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM = 1 << 1
+};
+
+struct _ETaskShellSidebar {
+ EShellSidebar parent;
+ ETaskShellSidebarPrivate *priv;
+};
+
+struct _ETaskShellSidebarClass {
+ EShellSidebarClass parent_class;
+
+ /* Signals */
+ void (*client_added) (ETaskShellSidebar *task_shell_sidebar,
+ ECal *client);
+ void (*client_removed) (ETaskShellSidebar *task_shell_sidebar,
+ ECal *client);
+ void (*status_message) (ETaskShellSidebar *task_shell_sidebar,
+ const gchar *status_message,
+ gdouble percent);
+};
+
+GType e_task_shell_sidebar_get_type (void);
+void e_task_shell_sidebar_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_task_shell_sidebar_new(EShellView *shell_view);
+GList * e_task_shell_sidebar_get_clients
+ (ETaskShellSidebar *task_shell_sidebar);
+ESourceSelector *
+ e_task_shell_sidebar_get_selector
+ (ETaskShellSidebar *task_shell_sidebar);
+void e_task_shell_sidebar_add_source
+ (ETaskShellSidebar *task_shell_sidebar,
+ ESource *source);
+void e_task_shell_sidebar_remove_source
+ (ETaskShellSidebar *task_shell_sidebar,
+ ESource *source);
+
+G_END_DECLS
+
+#endif /* E_TASK_SHELL_SIDEBAR_H */
diff --git a/modules/calendar/e-task-shell-view-actions.c b/modules/calendar/e-task-shell-view-actions.c
new file mode 100644
index 0000000000..d4fb94c2e5
--- /dev/null
+++ b/modules/calendar/e-task-shell-view-actions.c
@@ -0,0 +1,1222 @@
+/*
+ * e-task-shell-view-actions.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-task-shell-view-private.h"
+
+static void
+action_gal_save_custom_view_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ EShellView *shell_view;
+ GalViewInstance *view_instance;
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with saving the custom view. */
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ view_instance = e_task_shell_content_get_view_instance (task_shell_content);
+ gal_view_instance_save_as (view_instance);
+}
+
+static void
+action_search_execute_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ EShellView *shell_view;
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with executing the search. */
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ e_task_shell_view_execute_search (task_shell_view);
+}
+
+static void
+action_search_filter_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ ETaskShellView *task_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+}
+
+static void
+action_task_assign_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only open the first selected task. */
+ e_task_shell_view_open_task (task_shell_view, comp_data);
+
+ /* FIXME Need to actually assign the task. */
+}
+
+static void
+action_task_clipboard_copy_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ e_calendar_table_copy_clipboard (task_table);
+}
+
+static void
+action_task_clipboard_cut_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ e_calendar_table_cut_clipboard (task_table);
+}
+
+static void
+action_task_clipboard_paste_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ e_calendar_table_paste_clipboard (task_table);
+}
+
+static void
+action_task_delete_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalComponentPreview *task_preview;
+ ECalendarTable *task_table;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ task_preview = e_task_shell_content_get_task_preview (task_shell_content);
+
+ e_task_shell_view_set_status_message (
+ task_shell_view, _("Deleting selected tasks..."), -1.0);
+ e_calendar_table_delete_selected (task_table);
+ e_task_shell_view_set_status_message (task_shell_view, NULL, -1.0);
+
+ e_cal_component_preview_clear (task_preview);
+}
+
+static void
+action_task_forward_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ GSList *list;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only forward the first selected task. */
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+ itip_send_comp (
+ E_CAL_COMPONENT_METHOD_PUBLISH, comp,
+ comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
+ g_object_unref (comp);
+}
+
+static void
+action_task_list_copy_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellSidebar *task_shell_sidebar;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ ESourceSelector *selector;
+ ESource *source;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ copy_source_dialog (
+ GTK_WINDOW (shell_window),
+ source, E_CAL_SOURCE_TYPE_TODO);
+}
+
+static void
+action_task_list_delete_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellBackend *task_shell_backend;
+ ETaskShellContent *task_shell_content;
+ ETaskShellSidebar *task_shell_sidebar;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ ECalendarTable *task_table;
+ ECal *client;
+ ECalModel *model;
+ ESourceSelector *selector;
+ ESourceGroup *source_group;
+ ESourceList *source_list;
+ ESource *source;
+ gint response;
+ gchar *uri;
+ GError *error = NULL;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ task_shell_backend = task_shell_view->priv->task_shell_backend;
+ source_list = e_task_shell_backend_get_source_list (task_shell_backend);
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ model = e_calendar_table_get_model (task_table);
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ /* Ask for confirmation. */
+ response = e_error_run (
+ GTK_WINDOW (shell_window),
+ "calendar:prompt-delete-task-list",
+ e_source_peek_name (source));
+ if (response != GTK_RESPONSE_YES)
+ return;
+
+ uri = e_source_get_uri (source);
+ client = e_cal_model_get_client_for_uri (model, uri);
+ if (client == NULL)
+ client = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_JOURNAL);
+ g_free (uri);
+
+ g_return_if_fail (client != NULL);
+
+ if (!e_cal_remove (client, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (e_source_selector_source_is_selected (selector, source)) {
+ e_task_shell_sidebar_remove_source (
+ task_shell_sidebar, source);
+ e_source_selector_unselect_source (selector, source);
+ }
+
+ source_group = e_source_peek_group (source);
+ e_source_group_remove_source (source_group, source);
+
+ if (!e_source_list_sync (source_list, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+action_task_list_new_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ calendar_setup_new_task_list (GTK_WINDOW (shell_window));
+}
+
+static void
+action_task_list_print_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ETable *table;
+ GtkPrintOperationAction print_action;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ table = e_calendar_table_get_table (task_table);
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ print_table (table, _("Print Tasks"), _("Tasks"), print_action);
+}
+
+static void
+action_task_list_print_preview_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ETable *table;
+ GtkPrintOperationAction print_action;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ table = e_calendar_table_get_table (task_table);
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
+ print_table (table, _("Print Tasks"), _("Tasks"), print_action);
+}
+
+static void
+action_task_list_properties_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellSidebar *task_shell_sidebar;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ESource *source;
+ ESourceSelector *selector;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ calendar_setup_edit_task_list (GTK_WINDOW (shell_window), source);
+}
+
+static void
+action_task_list_rename_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellSidebar *task_shell_sidebar;
+ ESourceSelector *selector;
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+
+ e_source_selector_edit_primary_selection (selector);
+}
+
+static void
+action_task_list_select_one_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellSidebar *task_shell_sidebar;
+ ESourceSelector *selector;
+ ESource *primary;
+ GSList *list, *iter;
+
+ /* XXX ESourceSelector should provide a function for this. */
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+ primary = e_source_selector_peek_primary_selection (selector);
+ g_return_if_fail (primary != NULL);
+
+ list = e_source_selector_get_selection (selector);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+
+ if (source == primary)
+ continue;
+
+ e_source_selector_unselect_source (selector, source);
+ }
+ e_source_selector_free_selection (list);
+
+ e_source_selector_select_source (selector, primary);
+}
+
+static void
+action_task_mark_complete_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModel *model;
+ GSList *list, *iter;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ list = e_calendar_table_get_selected (task_table);
+ model = e_calendar_table_get_model (task_table);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ e_cal_model_tasks_mark_comp_complete (
+ E_CAL_MODEL_TASKS (model), comp_data);
+ }
+
+ g_slist_free (list);
+}
+
+static void
+action_task_mark_incomplete_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModel *model;
+ GSList *list, *iter;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ list = e_calendar_table_get_selected (task_table);
+ model = e_calendar_table_get_model (task_table);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ e_cal_model_tasks_mark_comp_incomplete (
+ E_CAL_MODEL_TASKS (model), comp_data);
+ }
+
+ g_slist_free (list);
+}
+
+static void
+action_task_new_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ ECal *client;
+ ECalComponent *comp;
+ CompEditor *editor;
+ GSList *list;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ client = comp_data->client;
+ editor = task_editor_new (client, shell, COMP_EDITOR_NEW_ITEM);
+ comp = cal_comp_task_new_with_defaults (client);
+ comp_editor_edit_comp (editor, comp);
+
+ gtk_window_present (GTK_WINDOW (editor));
+
+ g_object_unref (comp);
+ g_object_unref (client);
+}
+
+static void
+action_task_open_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only open the first selected task. */
+ e_task_shell_view_open_task (task_shell_view, comp_data);
+}
+
+static void
+action_task_open_url_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ icalproperty *prop;
+ const gchar *uri;
+ GSList *list;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+
+ /* XXX We only open the URI of the first selected task. */
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_URL_PROPERTY);
+ g_return_if_fail (prop == NULL);
+
+ uri = icalproperty_get_url (prop);
+ e_show_uri (GTK_WINDOW (shell_window), uri);
+}
+
+static void
+action_task_preview_cb (GtkToggleAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ gboolean visible;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ visible = gtk_toggle_action_get_active (action);
+ e_task_shell_content_set_preview_visible (task_shell_content, visible);
+}
+
+static void
+action_task_print_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ GtkPrintOperationAction print_action;
+ GSList *list;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ /* XXX We only print the first selected task. */
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ e_cal_component_set_icalcomponent (comp, clone);
+ print_comp (comp, comp_data->client, print_action);
+ g_object_unref (comp);
+}
+
+static void
+action_task_purge_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkWidget *dialog;
+ GtkWidget *widget;
+ gboolean active;
+ gint response;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (!e_task_shell_view_get_confirm_purge (task_shell_view))
+ goto purge;
+
+ /* XXX This needs reworked. The dialog looks like ass. */
+
+ dialog = gtk_message_dialog_new (
+ GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_YES_NO,
+ "%s", _("This operation will permanently erase all tasks "
+ "marked as completed. If you continue, you will not be able "
+ "to recover these tasks.\n\nReally erase these tasks?"));
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO);
+
+ widget = gtk_check_button_new_with_label (_("Do not ask me again"));
+ gtk_box_pack_start (
+ GTK_BOX (GTK_DIALOG (dialog)->vbox), widget, TRUE, TRUE, 6);
+ gtk_widget_show (widget);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ gtk_widget_destroy (dialog);
+
+ if (response != GTK_RESPONSE_YES)
+ return;
+
+ if (active)
+ e_task_shell_view_set_confirm_purge (task_shell_view, FALSE);
+
+purge:
+
+ /* FIXME KILL-BONOBO */
+ ;
+}
+
+static void
+action_task_save_as_cb (GtkAction *action,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModelComponent *comp_data;
+ GSList *list;
+ gchar *filename;
+ gchar *string;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ list = e_calendar_table_get_selected (task_table);
+ g_return_if_fail (list != NULL);
+ comp_data = list->data;
+ g_slist_free (list);
+
+ filename = e_file_dialog_save (_("Save as..."), NULL);
+ if (filename == NULL)
+ return;
+
+ string = e_cal_get_component_as_string (
+ comp_data->client, comp_data->icalcomp);
+ if (string == NULL) {
+ g_warning ("Could not convert task to a string");
+ return;
+ }
+
+ e_write_file_uri (filename, string);
+
+ g_free (filename);
+ g_free (string);
+}
+
+static void
+action_task_search_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ ETaskShellView *task_shell_view)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *search_hint;
+
+ /* XXX Figure out a way to handle this in EShellContent
+ * instead of every shell view having to handle it.
+ * The problem is EShellContent does not know what
+ * the search option actions are for this view. It
+ * would have to dig up the popup menu and retrieve
+ * the action for each menu item. Seems messy. */
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ search_hint = gtk_action_get_label (GTK_ACTION (current));
+ e_shell_content_set_search_hint (shell_content, search_hint);
+}
+
+static void
+action_task_view_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ orientable = GTK_ORIENTABLE (task_shell_content);
+
+ switch (gtk_radio_action_get_current_value (action)) {
+ case 0:
+ orientation = GTK_ORIENTATION_VERTICAL;
+ break;
+ case 1:
+ orientation = GTK_ORIENTATION_HORIZONTAL;
+ break;
+ default:
+ g_return_if_reached ();
+ }
+
+ gtk_orientable_set_orientation (orientable, orientation);
+}
+
+static GtkActionEntry task_entries[] = {
+
+ { "task-assign",
+ NULL,
+ N_("_Assign Task"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_task_assign_cb) },
+
+ { "task-clipboard-copy",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy selected tasks"),
+ G_CALLBACK (action_task_clipboard_copy_cb) },
+
+ { "task-clipboard-cut",
+ GTK_STOCK_CUT,
+ NULL,
+ NULL,
+ N_("Cut selected tasks"),
+ G_CALLBACK (action_task_clipboard_cut_cb) },
+
+ { "task-clipboard-paste",
+ GTK_STOCK_PASTE,
+ NULL,
+ NULL,
+ N_("Paste tasks from the clipboard"),
+ G_CALLBACK (action_task_clipboard_paste_cb) },
+
+ { "task-delete",
+ GTK_STOCK_DELETE,
+ N_("_Delete Task"),
+ NULL,
+ N_("Delete selected tasks"),
+ G_CALLBACK (action_task_delete_cb) },
+
+ { "task-forward",
+ "mail-forward",
+ N_("_Forward as iCalendar..."),
+ "<Control>f",
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_task_forward_cb) },
+
+ { "task-list-copy",
+ GTK_STOCK_COPY,
+ N_("Copy..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_task_list_copy_cb) },
+
+ { "task-list-delete",
+ GTK_STOCK_DELETE,
+ N_("_Delete"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_task_list_delete_cb) },
+
+ { "task-list-new",
+ "stock_todo",
+ N_("_New Task List"),
+ NULL,
+ N_("Create a new task list"),
+ G_CALLBACK (action_task_list_new_cb) },
+
+ { "task-list-properties",
+ GTK_STOCK_PROPERTIES,
+ NULL,
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_task_list_properties_cb) },
+
+ { "task-list-rename",
+ NULL,
+ N_("_Rename..."),
+ "F2",
+ N_("Rename the selected task list"),
+ G_CALLBACK (action_task_list_rename_cb) },
+
+ { "task-list-select-one",
+ "stock_check-filled",
+ N_("Show _Only This Task List"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_task_list_select_one_cb) },
+
+ { "task-mark-complete",
+ NULL,
+ N_("_Mark as Complete"),
+ "<Control>k",
+ N_("Mark selected tasks as complete"),
+ G_CALLBACK (action_task_mark_complete_cb) },
+
+ { "task-mark-incomplete",
+ NULL,
+ N_("Mar_k as Incomplete"),
+ NULL,
+ N_("Mark selected tasks as incomplete"),
+ G_CALLBACK (action_task_mark_incomplete_cb) },
+
+ { "task-new",
+ "stock_task",
+ N_("New _Task"),
+ NULL,
+ N_("Create a new task"),
+ G_CALLBACK (action_task_new_cb) },
+
+ { "task-open",
+ GTK_STOCK_OPEN,
+ N_("_Open Task"),
+ "<Control>o",
+ N_("View the selected task"),
+ G_CALLBACK (action_task_open_cb) },
+
+ { "task-open-url",
+ "applications-internet",
+ N_("Open _Web Page"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_task_open_url_cb) },
+
+ { "task-purge",
+ NULL,
+ N_("Purg_e"),
+ "<Control>e",
+ N_("Delete completed tasks"),
+ G_CALLBACK (action_task_purge_cb) },
+
+ { "task-save-as",
+ GTK_STOCK_SAVE_AS,
+ N_("_Save as iCalendar..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_task_save_as_cb) },
+
+ /*** Menus ***/
+
+ { "task-actions-menu",
+ NULL,
+ N_("_Actions"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "task-preview-menu",
+ NULL,
+ N_("_Preview"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static EPopupActionEntry task_popup_entries[] = {
+
+ { "task-list-popup-copy",
+ NULL,
+ "task-list-copy" },
+
+ { "task-list-popup-delete",
+ NULL,
+ "task-list-delete" },
+
+ { "task-list-popup-properties",
+ NULL,
+ "task-list-properties" },
+
+ { "task-list-popup-rename",
+ NULL,
+ "task-list-rename" },
+
+ { "task-list-popup-select-one",
+ NULL,
+ "task-list-select-one" },
+
+ { "task-popup-assign",
+ NULL,
+ "task-assign" },
+
+ { "task-popup-clipboard-copy",
+ NULL,
+ "task-clipboard-copy" },
+
+ { "task-popup-clipboard-cut",
+ NULL,
+ "task-clipboard-cut" },
+
+ { "task-popup-clipboard-paste",
+ NULL,
+ "task-clipboard-paste" },
+
+ { "task-popup-delete",
+ NULL,
+ "task-delete" },
+
+ { "task-popup-forward",
+ NULL,
+ "task-forward" },
+
+ { "task-popup-mark-complete",
+ NULL,
+ "task-mark-complete" },
+
+ { "task-popup-mark-incomplete",
+ NULL,
+ "task-mark-incomplete" },
+
+ { "task-popup-open",
+ NULL,
+ "task-open" },
+
+ { "task-popup-open-url",
+ NULL,
+ "task-open-url" },
+
+ { "task-popup-save-as",
+ NULL,
+ "task-save-as" },
+};
+
+static GtkToggleActionEntry task_toggle_entries[] = {
+
+ { "task-preview",
+ NULL,
+ N_("Task _Preview"),
+ "<Control>m",
+ N_("Show task preview pane"),
+ G_CALLBACK (action_task_preview_cb),
+ TRUE }
+};
+
+static GtkRadioActionEntry task_view_entries[] = {
+
+ /* This action represents the inital active memo view.
+ * It should not be visible in the UI, nor should it be
+ * possible to switch to it from another shell view. */
+ { "task-view-initial",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ -1 },
+
+ { "task-view-classic",
+ NULL,
+ N_("_Classic View"),
+ NULL,
+ N_("Show task preview below the task list"),
+ 0 },
+
+ { "task-view-vertical",
+ NULL,
+ N_("_Vertical View"),
+ NULL,
+ N_("Show task preview alongside the task list"),
+ 1 }
+};
+
+static GtkRadioActionEntry task_filter_entries[] = {
+
+ { "task-filter-active-tasks",
+ NULL,
+ N_("Active Tasks"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_FILTER_ACTIVE_TASKS },
+
+ { "task-filter-any-category",
+ NULL,
+ N_("Any Category"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_FILTER_ANY_CATEGORY },
+
+ { "task-filter-completed-tasks",
+ NULL,
+ N_("Completed Tasks"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_FILTER_COMPLETED_TASKS },
+
+ { "task-filter-next-7-days-tasks",
+ NULL,
+ N_("Next 7 Days' Tasks"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_FILTER_NEXT_7_DAYS_TASKS },
+
+ { "task-filter-overdue-tasks",
+ NULL,
+ N_("Overdue Tasks"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_FILTER_OVERDUE_TASKS },
+
+ { "task-filter-tasks-with-attachments",
+ NULL,
+ N_("Tasks with Attachments"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_FILTER_TASKS_WITH_ATTACHMENTS },
+
+ { "task-filter-unmatched",
+ NULL,
+ N_("Unmatched"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_FILTER_UNMATCHED }
+};
+
+static GtkRadioActionEntry task_search_entries[] = {
+
+ { "task-search-any-field-contains",
+ NULL,
+ N_("Any field contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_SEARCH_ANY_FIELD_CONTAINS },
+
+ { "task-search-description-contains",
+ NULL,
+ N_("Description contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_SEARCH_DESCRIPTION_CONTAINS },
+
+ { "task-search-summary-contains",
+ NULL,
+ N_("Summary contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ TASK_SEARCH_SUMMARY_CONTAINS }
+};
+
+static GtkActionEntry lockdown_printing_entries[] = {
+
+ { "task-list-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ "<Control>p",
+ N_("Print the list of tasks"),
+ G_CALLBACK (action_task_list_print_cb) },
+
+ { "task-list-print-preview",
+ GTK_STOCK_PRINT_PREVIEW,
+ NULL,
+ NULL,
+ N_("Preview the list of tasks to be printed"),
+ G_CALLBACK (action_task_list_print_preview_cb) },
+
+ { "task-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ NULL,
+ N_("Print the selected task"),
+ G_CALLBACK (action_task_print_cb) }
+};
+
+static EPopupActionEntry lockdown_printing_popup_entries[] = {
+
+ { "task-popup-print",
+ NULL,
+ "task-print" }
+};
+
+void
+e_task_shell_view_actions_init (ETaskShellView *task_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+ GConfBridge *bridge;
+ GtkAction *action;
+ GObject *object;
+ const gchar *key;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ /* Task Actions */
+ action_group = ACTION_GROUP (TASKS);
+ gtk_action_group_add_actions (
+ action_group, task_entries,
+ G_N_ELEMENTS (task_entries), task_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, task_popup_entries,
+ G_N_ELEMENTS (task_popup_entries));
+ gtk_action_group_add_toggle_actions (
+ action_group, task_toggle_entries,
+ G_N_ELEMENTS (task_toggle_entries), task_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, task_view_entries,
+ G_N_ELEMENTS (task_view_entries), -1,
+ G_CALLBACK (action_task_view_cb), task_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, task_search_entries,
+ G_N_ELEMENTS (task_search_entries),
+ TASK_SEARCH_SUMMARY_CONTAINS,
+ G_CALLBACK (action_task_search_cb), task_shell_view);
+
+ /* Lockdown Printing Actions */
+ action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
+ gtk_action_group_add_actions (
+ action_group, lockdown_printing_entries,
+ G_N_ELEMENTS (lockdown_printing_entries), task_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, lockdown_printing_popup_entries,
+ G_N_ELEMENTS (lockdown_printing_popup_entries));
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (ACTION (TASK_PREVIEW));
+ key = "/apps/evolution/calendar/display/show_task_preview";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (TASK_VIEW_VERTICAL));
+ key = "/apps/evolution/calendar/display/task_layout";
+ gconf_bridge_bind_property (bridge, key, object, "current-value");
+
+ /* Fine tuning. */
+
+ action = ACTION (TASK_DELETE);
+ g_object_set (action, "short-label", _("Delete"), NULL);
+
+ g_signal_connect (
+ ACTION (GAL_SAVE_CUSTOM_VIEW), "activate",
+ G_CALLBACK (action_gal_save_custom_view_cb), task_shell_view);
+
+ g_signal_connect (
+ ACTION (SEARCH_EXECUTE), "activate",
+ G_CALLBACK (action_search_execute_cb), task_shell_view);
+}
+
+void
+e_task_shell_view_update_search_filter (ETaskShellView *task_shell_view)
+{
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GtkActionGroup *action_group;
+ GtkRadioAction *radio_action;
+ GList *list, *iter;
+ GSList *group;
+ gint ii;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action_group = ACTION_GROUP (TASKS_FILTER);
+ e_action_group_remove_all_actions (action_group);
+
+ /* Add the standard filter actions. */
+ gtk_action_group_add_radio_actions (
+ action_group, task_filter_entries,
+ G_N_ELEMENTS (task_filter_entries),
+ TASK_FILTER_ANY_CATEGORY,
+ G_CALLBACK (action_search_filter_cb),
+ task_shell_view);
+
+ /* Retrieve the radio group from an action we just added. */
+ list = gtk_action_group_list_actions (action_group);
+ radio_action = GTK_RADIO_ACTION (list->data);
+ group = gtk_radio_action_get_group (radio_action);
+ g_list_free (list);
+
+ /* Build the category actions. */
+
+ list = e_categories_get_list ();
+ for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) {
+ const gchar *category_name = iter->data;
+ const gchar *filename;
+ GtkAction *action;
+ gchar *action_name;
+
+ action_name = g_strdup_printf (
+ "task-filter-category-%d", ii);
+ radio_action = gtk_radio_action_new (
+ action_name, category_name, NULL, NULL, ii);
+ g_free (action_name);
+
+ /* Convert the category icon file to a themed icon name. */
+ filename = e_categories_get_icon_file_for (category_name);
+ if (filename != NULL && *filename != '\0') {
+ gchar *basename;
+ gchar *cp;
+
+ basename = g_path_get_basename (filename);
+
+ /* Lose the file extension. */
+ if ((cp = strrchr (basename, '.')) != NULL)
+ *cp = '\0';
+
+ g_object_set (
+ radio_action, "icon-name", basename, NULL);
+
+ g_free (basename);
+ }
+
+ gtk_radio_action_set_group (radio_action, group);
+ group = gtk_radio_action_get_group (radio_action);
+
+ /* The action group takes ownership of the action. */
+ action = GTK_ACTION (radio_action);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (radio_action);
+ }
+ g_list_free (list);
+
+ /* Use any action in the group; doesn't matter which. */
+ e_shell_content_set_filter_action (shell_content, radio_action);
+
+ ii = TASK_FILTER_UNMATCHED;
+ e_shell_content_add_filter_separator_after (shell_content, ii);
+
+ ii = TASK_FILTER_TASKS_WITH_ATTACHMENTS;
+ e_shell_content_add_filter_separator_after (shell_content, ii);
+}
diff --git a/modules/calendar/e-task-shell-view-actions.h b/modules/calendar/e-task-shell-view-actions.h
new file mode 100644
index 0000000000..daa70c36da
--- /dev/null
+++ b/modules/calendar/e-task-shell-view-actions.h
@@ -0,0 +1,109 @@
+/*
+ * e-task-shell-view-actions.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TASK_SHELL_VIEW_ACTIONS_H
+#define E_TASK_SHELL_VIEW_ACTIONS_H
+
+#include <shell/e-shell-window-actions.h>
+
+/* Task Actions */
+#define E_SHELL_WINDOW_ACTION_TASK_ASSIGN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-assign")
+#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-clipboard-copy")
+#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_CUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-clipboard-cut")
+#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_PASTE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-clipboard-paste")
+#define E_SHELL_WINDOW_ACTION_TASK_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-delete")
+#define E_SHELL_WINDOW_ACTION_TASK_FORWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-forward")
+#define E_SHELL_WINDOW_ACTION_TASK_MARK_COMPLETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-mark-complete")
+#define E_SHELL_WINDOW_ACTION_TASK_MARK_INCOMPLETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-mark-incomplete")
+#define E_SHELL_WINDOW_ACTION_TASK_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-new")
+#define E_SHELL_WINDOW_ACTION_TASK_OPEN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-open")
+#define E_SHELL_WINDOW_ACTION_TASK_OPEN_URL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-open-url")
+#define E_SHELL_WINDOW_ACTION_TASK_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-preview")
+#define E_SHELL_WINDOW_ACTION_TASK_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-print")
+#define E_SHELL_WINDOW_ACTION_TASK_PURGE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-purge")
+#define E_SHELL_WINDOW_ACTION_TASK_SAVE_AS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-save-as")
+#define E_SHELL_WINDOW_ACTION_TASK_VIEW_CLASSIC(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-view-classic")
+#define E_SHELL_WINDOW_ACTION_TASK_VIEW_VERTICAL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-view-vertical")
+
+/* Task List Actions */
+#define E_SHELL_WINDOW_ACTION_TASK_LIST_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-list-copy")
+#define E_SHELL_WINDOW_ACTION_TASK_LIST_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-list-delete")
+#define E_SHELL_WINDOW_ACTION_TASK_LIST_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-list-new")
+#define E_SHELL_WINDOW_ACTION_TASK_LIST_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-list-print")
+#define E_SHELL_WINDOW_ACTION_TASK_LIST_PRINT_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-list-print-preview")
+#define E_SHELL_WINDOW_ACTION_TASK_LIST_PROPERTIES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-list-properties")
+#define E_SHELL_WINDOW_ACTION_TASK_LIST_RENAME(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-list-rename")
+#define E_SHELL_WINDOW_ACTION_TASK_LIST_SELECT_ONE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-list-select-one")
+
+/* Task Query Actions */
+#define E_SHELL_WINDOW_ACTION_TASK_FILTER_ACTIVE_TASKS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-filter-active-tasks")
+#define E_SHELL_WINDOW_ACTION_TASK_FILTER_ANY_CATEGORY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-filter-any-category")
+#define E_SHELL_WINDOW_ACTION_TASK_FILTER_COMPLETED_TASKS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-filter-completed-tasks")
+#define E_SHELL_WINDOW_ACTION_TASK_FILTER_NEXT_7_DAYS_TASKS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-filter-next-7-days-tasks")
+#define E_SHELL_WINDOW_ACTION_TASK_FILTER_OVERDUE_TASKS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-filter-overdue-tasks")
+#define E_SHELL_WINDOW_ACTION_TASK_FILTER_TASKS_WITH_ATTACHMENTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-filter-tasks-with-attachments")
+#define E_SHELL_WINDOW_ACTION_TASK_FILTER_UNMATCHED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-filter-unmatched")
+#define E_SHELL_WINDOW_ACTION_TASK_SEARCH_ANY_FIELD_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-search-any-field-contains")
+#define E_SHELL_WINDOW_ACTION_TASK_SEARCH_DESCRIPTION_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-search-description-contains")
+#define E_SHELL_WINDOW_ACTION_TASK_SEARCH_SUMMARY_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "task-search-summary-contains")
+
+/* Action Groups */
+#define E_SHELL_WINDOW_ACTION_GROUP_TASKS(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "tasks")
+#define E_SHELL_WINDOW_ACTION_GROUP_TASKS_FILTER(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "tasks-filter")
+
+#endif /* E_TASK_SHELL_VIEW_ACTIONS_H */
diff --git a/modules/calendar/e-task-shell-view-private.c b/modules/calendar/e-task-shell-view-private.c
new file mode 100644
index 0000000000..a0ca5ee978
--- /dev/null
+++ b/modules/calendar/e-task-shell-view-private.c
@@ -0,0 +1,726 @@
+/*
+ * e-task-shell-view-private.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-task-shell-view-private.h"
+
+#include "widgets/menus/gal-view-factory-etable.h"
+
+static void
+task_shell_view_process_completed_tasks (ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ETaskShellSidebar *task_shell_sidebar;
+ ECalendarTable *task_table;
+ GList *clients;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ clients = e_task_shell_sidebar_get_clients (task_shell_sidebar);
+
+ e_calendar_table_process_completed_tasks (task_table, clients, TRUE);
+
+ /* Search query takes whether to show completed tasks into account,
+ * so if the preference has changed we need to update the query. */
+ e_task_shell_view_execute_search (task_shell_view);
+
+ g_list_free (clients);
+}
+
+static void
+task_shell_view_table_popup_event_cb (EShellView *shell_view,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/task-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+}
+
+static void
+task_shell_view_table_user_created_cb (ETaskShellView *task_shell_view,
+ ECalendarTable *task_table)
+{
+ ETaskShellSidebar *task_shell_sidebar;
+ ECalModel *model;
+ ECal *client;
+ ESource *source;
+
+ /* This is the "Click to Add" handler. */
+
+ model = e_calendar_table_get_model (task_table);
+ client = e_cal_model_get_default_client (model);
+ source = e_cal_get_source (client);
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ e_task_shell_sidebar_add_source (task_shell_sidebar, source);
+
+ e_cal_model_add_client (model, client);
+}
+
+static void
+task_shell_view_selector_client_added_cb (ETaskShellView *task_shell_view,
+ ECal *client)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModel *model;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ model = e_calendar_table_get_model (task_table);
+
+ e_cal_model_add_client (model, client);
+ e_task_shell_view_update_timezone (task_shell_view);
+}
+
+static void
+task_shell_view_selector_client_removed_cb (ETaskShellView *task_shell_view,
+ ECal *client)
+{
+ ETaskShellContent *task_shell_content;
+ ECalendarTable *task_table;
+ ECalModel *model;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ model = e_calendar_table_get_model (task_table);
+
+ e_cal_model_remove_client (model, client);
+}
+
+static gboolean
+task_shell_view_selector_popup_event_cb (EShellView *shell_view,
+ ESource *primary_source,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/task-list-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+
+ return TRUE;
+}
+
+static gboolean
+task_shell_view_update_timeout_cb (ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ETaskShellSidebar *task_shell_sidebar;
+ ECalendarTable *task_table;
+ ECalModel *model;
+ GList *clients;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ model = e_calendar_table_get_model (task_table);
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ clients = e_task_shell_sidebar_get_clients (task_shell_sidebar);
+
+ e_calendar_table_process_completed_tasks (task_table, clients, FALSE);
+ e_cal_model_tasks_update_due_tasks (E_CAL_MODEL_TASKS (model));
+
+ g_list_free (clients);
+
+ return TRUE;
+}
+
+static void
+task_shell_view_load_view_collection (EShellViewClass *shell_view_class)
+{
+ GalViewCollection *collection;
+ GalViewFactory *factory;
+ ETableSpecification *spec;
+ const gchar *base_dir;
+ gchar *filename;
+
+ collection = shell_view_class->view_collection;
+
+ base_dir = EVOLUTION_ETSPECDIR;
+ spec = e_table_specification_new ();
+ filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL);
+ if (!e_table_specification_load_from_file (spec, filename))
+ g_critical ("Unable to load ETable specification file "
+ "for tasks");
+ g_free (filename);
+
+ factory = gal_view_factory_etable_new (spec);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+ g_object_unref (spec);
+
+ gal_view_collection_load (collection);
+}
+
+static void
+task_shell_view_notify_view_id_cb (ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ GalViewInstance *view_instance;
+ const gchar *view_id;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ view_instance =
+ e_task_shell_content_get_view_instance (task_shell_content);
+ view_id = e_shell_view_get_view_id (E_SHELL_VIEW (task_shell_view));
+
+ /* A NULL view ID implies we're in a custom view. But you can
+ * only get to a custom view via the "Define Views" dialog, which
+ * would have already modified the view instance appropriately.
+ * Furthermore, there's no way to refer to a custom view by ID
+ * anyway, since custom views have no IDs. */
+ if (view_id == NULL)
+ return;
+
+ gal_view_instance_set_current_view_id (view_instance, view_id);
+}
+
+void
+e_task_shell_view_private_init (ETaskShellView *task_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ if (!gal_view_collection_loaded (shell_view_class->view_collection))
+ task_shell_view_load_view_collection (shell_view_class);
+
+ g_signal_connect (
+ task_shell_view, "notify::view-id",
+ G_CALLBACK (task_shell_view_notify_view_id_cb), NULL);
+}
+
+void
+e_task_shell_view_private_constructed (ETaskShellView *task_shell_view)
+{
+ ETaskShellViewPrivate *priv = task_shell_view->priv;
+ ETaskShellContent *task_shell_content;
+ ETaskShellSidebar *task_shell_sidebar;
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellContent *shell_content;
+ EShellSettings *shell_settings;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ ECalendarTable *task_table;
+ ECalModel *model;
+ ETable *table;
+ ESourceSelector *selector;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_window_add_action_group (shell_window, "tasks");
+ e_shell_window_add_action_group (shell_window, "tasks-filter");
+
+ /* Cache these to avoid lots of awkward casting. */
+ priv->task_shell_backend = g_object_ref (shell_backend);
+ priv->task_shell_content = g_object_ref (shell_content);
+ priv->task_shell_sidebar = g_object_ref (shell_sidebar);
+
+ task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ model = e_calendar_table_get_model (task_table);
+ table = e_calendar_table_get_table (task_table);
+
+ task_shell_sidebar = E_TASK_SHELL_SIDEBAR (shell_sidebar);
+ selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+
+ g_signal_connect_swapped (
+ model, "notify::timezone",
+ G_CALLBACK (e_task_shell_view_update_timezone),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ task_table, "open-component",
+ G_CALLBACK (e_task_shell_view_open_task),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ task_table, "popup-event",
+ G_CALLBACK (task_shell_view_table_popup_event_cb),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ task_table, "status-message",
+ G_CALLBACK (e_task_shell_view_set_status_message),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ task_table, "user-created",
+ G_CALLBACK (task_shell_view_table_user_created_cb),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ model, "model-changed",
+ G_CALLBACK (e_task_shell_view_update_sidebar),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ model, "model-rows-deleted",
+ G_CALLBACK (e_task_shell_view_update_sidebar),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ model, "model-rows-inserted",
+ G_CALLBACK (e_task_shell_view_update_sidebar),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ table, "selection-change",
+ G_CALLBACK (e_task_shell_view_update_sidebar),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ task_shell_sidebar, "client-added",
+ G_CALLBACK (task_shell_view_selector_client_added_cb),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ task_shell_sidebar, "client-removed",
+ G_CALLBACK (task_shell_view_selector_client_removed_cb),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ task_shell_sidebar, "status-message",
+ G_CALLBACK (e_task_shell_view_set_status_message),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ selector, "popup-event",
+ G_CALLBACK (task_shell_view_selector_popup_event_cb),
+ task_shell_view);
+
+ g_signal_connect_swapped (
+ selector, "primary-selection-changed",
+ G_CALLBACK (e_shell_view_update_actions),
+ task_shell_view);
+
+ e_categories_register_change_listener (
+ G_CALLBACK (e_task_shell_view_update_search_filter),
+ task_shell_view);
+
+ task_shell_view_update_timeout_cb (task_shell_view);
+ priv->update_timeout = g_timeout_add_full (
+ G_PRIORITY_LOW, 60000, (GSourceFunc)
+ task_shell_view_update_timeout_cb,
+ task_shell_view, NULL);
+
+ /* Listen for configuration changes. */
+
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "cal-confirm-purge",
+ G_OBJECT (task_shell_view), "confirm-purge");
+
+ /* Hide Completed Tasks (enable/units/value) */
+ g_signal_connect_swapped (
+ shell_settings, "notify::cal-hide-completed-tasks",
+ G_CALLBACK (task_shell_view_process_completed_tasks),
+ task_shell_view);
+ g_signal_connect_swapped (
+ shell_settings, "notify::cal-hide-completed-tasks-units",
+ G_CALLBACK (task_shell_view_process_completed_tasks),
+ task_shell_view);
+ g_signal_connect_swapped (
+ shell_settings, "notify::cal-hide-completed-tasks-value",
+ G_CALLBACK (task_shell_view_process_completed_tasks),
+ task_shell_view);
+
+ e_task_shell_view_actions_init (task_shell_view);
+ e_task_shell_view_update_sidebar (task_shell_view);
+ e_task_shell_view_update_search_filter (task_shell_view);
+ e_task_shell_view_update_timezone (task_shell_view);
+
+ e_task_shell_view_execute_search (task_shell_view);
+}
+
+void
+e_task_shell_view_private_dispose (ETaskShellView *task_shell_view)
+{
+ ETaskShellViewPrivate *priv = task_shell_view->priv;
+
+ DISPOSE (priv->task_shell_backend);
+ DISPOSE (priv->task_shell_content);
+ DISPOSE (priv->task_shell_sidebar);
+
+ if (task_shell_view->priv->activity != NULL) {
+ /* XXX Activity is no cancellable. */
+ e_activity_complete (task_shell_view->priv->activity);
+ g_object_unref (task_shell_view->priv->activity);
+ task_shell_view->priv->activity = NULL;
+ }
+
+ if (priv->update_timeout > 0) {
+ g_source_remove (priv->update_timeout);
+ priv->update_timeout = 0;
+ }
+}
+
+void
+e_task_shell_view_private_finalize (ETaskShellView *task_shell_view)
+{
+ /* XXX Nothing to do? */
+}
+
+void
+e_task_shell_view_execute_search (ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ GtkRadioAction *action;
+ GString *string;
+ ECalComponentPreview *task_preview;
+ ECalendarTable *task_table;
+ ECalModel *model;
+ FilterRule *rule;
+ const gchar *format;
+ const gchar *text;
+ time_t start_range;
+ time_t end_range;
+ gchar *start, *end;
+ gchar *query;
+ gchar *temp;
+ gint value;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ text = e_shell_content_get_search_text (shell_content);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action = GTK_RADIO_ACTION (ACTION (TASK_SEARCH_ANY_FIELD_CONTAINS));
+ value = gtk_radio_action_get_current_value (action);
+
+ if (text == NULL || *text == '\0') {
+ text = "";
+ value = TASK_SEARCH_SUMMARY_CONTAINS;
+ }
+
+ switch (value) {
+ default:
+ text = "";
+ /* fall through */
+
+ case TASK_SEARCH_SUMMARY_CONTAINS:
+ format = "(contains? \"summary\" %s)";
+ break;
+
+ case TASK_SEARCH_DESCRIPTION_CONTAINS:
+ format = "(contains? \"description\" %s)";
+ break;
+
+ case TASK_SEARCH_ANY_FIELD_CONTAINS:
+ format = "(contains? \"any\" %s)";
+ break;
+ }
+
+ /* Build the query. */
+ string = g_string_new ("");
+ e_sexp_encode_string (string, text);
+ query = g_strdup_printf (format, string->str);
+ g_string_free (string, TRUE);
+
+ /* Apply selected filter. */
+ value = e_shell_content_get_filter_value (shell_content);
+ switch (value) {
+ case TASK_FILTER_ANY_CATEGORY:
+ break;
+
+ case TASK_FILTER_UNMATCHED:
+ temp = g_strdup_printf (
+ "(and (has-categories? #f) %s)", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case TASK_FILTER_NEXT_7_DAYS_TASKS:
+ start_range = time (NULL);
+ end_range = time_add_day (start_range, 7);
+ start = isodate_from_time_t (start_range);
+ end = isodate_from_time_t (end_range);
+
+ temp = g_strdup_printf (
+ "(and %s (due-in-time-range? "
+ "(make-time \"%s\") (make-time \"%s\")))",
+ query, start, end);
+ g_free (query);
+ query = temp;
+ break;
+
+ case TASK_FILTER_ACTIVE_TASKS:
+ start_range = time (NULL);
+ end_range = time_add_day (start_range, 365);
+ start = isodate_from_time_t (start_range);
+ end = isodate_from_time_t (end_range);
+
+ temp = g_strdup_printf (
+ "(and %s (due-in-time-range? "
+ "(make-time \"%s\") (make-time \"%s\")) "
+ "(not (is-completed?)))",
+ query, start, end);
+ g_free (query);
+ query = temp;
+ break;
+
+ case TASK_FILTER_OVERDUE_TASKS:
+ start_range = 0;
+ end_range = time (NULL);
+ start = isodate_from_time_t (start_range);
+ end = isodate_from_time_t (end_range);
+
+ temp = g_strdup_printf (
+ "(and %s (due-in-time-range? "
+ "(make-time \"%s\") (make-time \"%s\")) "
+ "(not (is-completed?)))",
+ query, start, end);
+ g_free (query);
+ query = temp;
+ break;
+
+ case TASK_FILTER_COMPLETED_TASKS:
+ temp = g_strdup_printf (
+ "(and (is-completed?) %s)", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case TASK_FILTER_TASKS_WITH_ATTACHMENTS:
+ temp = g_strdup_printf (
+ "(and (has-attachments?) %s)", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ default:
+ {
+ GList *categories;
+ const gchar *category_name;
+
+ categories = e_categories_get_list ();
+ category_name = g_list_nth_data (categories, value);
+ g_list_free (categories);
+
+ temp = g_strdup_printf (
+ "(and (has-categories? \"%s\") %s)",
+ category_name, query);
+ g_free (query);
+ query = temp;
+ break;
+ }
+ }
+
+ /* Honor the user's preference to hide completed tasks. */
+ temp = calendar_config_get_hide_completed_tasks_sexp (FALSE);
+ if (temp != NULL) {
+ gchar *temp2;
+
+ temp2 = g_strdup_printf ("(and %s %s)", temp, query);
+ g_free (query);
+ g_free (temp);
+ query = temp2;
+ }
+
+ /* XXX This is wrong. We need to programmatically construct a
+ * FilterRule, tell it to build code, and pass the resulting
+ * expression string to ECalModel. */
+ rule = filter_rule_new ();
+ e_shell_content_set_search_rule (shell_content, rule);
+ g_object_unref (rule);
+
+ /* Submit the query. */
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+ model = e_calendar_table_get_model (task_table);
+ e_cal_model_set_search_query (model, query);
+ g_free (query);
+
+ task_preview =
+ e_task_shell_content_get_task_preview (task_shell_content);
+ e_cal_component_preview_clear (task_preview);
+}
+
+void
+e_task_shell_view_open_task (ETaskShellView *task_shell_view,
+ ECalModelComponent *comp_data)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ CompEditor *editor;
+ CompEditorFlags flags = 0;
+ ECalComponent *comp;
+ icalcomponent *clone;
+ icalproperty *prop;
+ const gchar *uid;
+
+ g_return_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view));
+ g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data));
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ editor = comp_editor_find_instance (uid);
+
+ if (editor != NULL)
+ goto exit;
+
+ comp = e_cal_component_new ();
+ clone = icalcomponent_new_clone (comp_data->icalcomp);
+ e_cal_component_set_icalcomponent (comp, clone);
+
+ prop = icalcomponent_get_first_property (
+ comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY);
+ if (prop != NULL)
+ flags |= COMP_EDITOR_IS_ASSIGNED;
+
+ if (itip_organizer_is_user (comp, comp_data->client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ if (!e_cal_component_has_attendees (comp))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ editor = task_editor_new (comp_data->client, shell, flags);
+ comp_editor_edit_comp (editor, comp);
+
+ g_object_ref (comp);
+
+ if (flags & COMP_EDITOR_IS_ASSIGNED)
+ task_editor_show_assignment (TASK_EDITOR (editor));
+
+exit:
+ gtk_window_present (GTK_WINDOW (editor));
+}
+
+void
+e_task_shell_view_set_status_message (ETaskShellView *task_shell_view,
+ const gchar *status_message,
+ gdouble percent)
+{
+ EActivity *activity;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+
+ g_return_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view));
+
+ activity = task_shell_view->priv->activity;
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ if (status_message == NULL || *status_message == '\0') {
+ if (activity != NULL) {
+ e_activity_complete (activity);
+ g_object_unref (activity);
+ activity = NULL;
+ }
+
+ } else if (activity == NULL) {
+ activity = e_activity_new (status_message);
+ e_activity_set_percent (activity, percent);
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ } else {
+ e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
+ }
+
+ task_shell_view->priv->activity = activity;
+}
+
+void
+e_task_shell_view_update_sidebar (ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ ECalendarTable *task_table;
+ ECalModel *model;
+ ETable *table;
+ GString *string;
+ const gchar *format;
+ gint n_rows;
+ gint n_selected;
+
+ shell_view = E_SHELL_VIEW (task_shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+ model = e_calendar_table_get_model (task_table);
+ table = e_calendar_table_get_table (task_table);
+
+ n_rows = e_table_model_row_count (E_TABLE_MODEL (model));
+ n_selected = e_table_selected_count (table);
+
+ string = g_string_sized_new (64);
+
+ format = ngettext ("%d task", "%d tasks", n_rows);
+ g_string_append_printf (string, format, n_rows);
+
+ if (n_selected > 0) {
+ format = _("%d selected");
+ g_string_append_len (string, ", ", 2);
+ g_string_append_printf (string, format, n_selected);
+ }
+
+ e_shell_sidebar_set_secondary_text (shell_sidebar, string->str);
+
+ g_string_free (string, TRUE);
+}
+
+void
+e_task_shell_view_update_timezone (ETaskShellView *task_shell_view)
+{
+ ETaskShellContent *task_shell_content;
+ ETaskShellSidebar *task_shell_sidebar;
+ ECalComponentPreview *task_preview;
+ icaltimezone *timezone;
+ ECalModel *model;
+ GList *clients, *iter;
+
+ task_shell_content = task_shell_view->priv->task_shell_content;
+ task_preview = e_task_shell_content_get_task_preview (task_shell_content);
+ model = e_task_shell_content_get_task_model (task_shell_content);
+ timezone = e_cal_model_get_timezone (model);
+
+ task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
+ clients = e_task_shell_sidebar_get_clients (task_shell_sidebar);
+
+ for (iter = clients; iter != NULL; iter = iter->next) {
+ ECal *client = iter->data;
+
+ if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
+ e_cal_set_default_timezone (client, timezone, NULL);
+ }
+
+ e_cal_component_preview_set_default_timezone (task_preview, timezone);
+
+ g_list_free (clients);
+}
diff --git a/modules/calendar/e-task-shell-view-private.h b/modules/calendar/e-task-shell-view-private.h
new file mode 100644
index 0000000000..e612069bed
--- /dev/null
+++ b/modules/calendar/e-task-shell-view-private.h
@@ -0,0 +1,141 @@
+/*
+ * e-task-shell-view-private.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TASK_SHELL_VIEW_PRIVATE_H
+#define E_TASK_SHELL_VIEW_PRIVATE_H
+
+#include "e-task-shell-view.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <libecal/e-cal-time-util.h>
+#include <libedataserver/e-categories.h>
+#include <libedataserver/e-sexp.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/e-dialog-utils.h"
+#include "e-util/e-error.h"
+#include "e-util/e-util.h"
+#include "e-util/gconf-bridge.h"
+#include "widgets/misc/e-popup-action.h"
+
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/e-cal-component-preview.h"
+#include "calendar/gui/e-cal-model-tasks.h"
+#include "calendar/gui/e-calendar-selector.h"
+#include "calendar/gui/print.h"
+#include "calendar/gui/dialogs/calendar-setup.h"
+#include "calendar/gui/dialogs/copy-source-dialog.h"
+#include "calendar/gui/dialogs/task-editor.h"
+
+#include "e-task-shell-backend.h"
+#include "e-task-shell-content.h"
+#include "e-task-shell-sidebar.h"
+#include "e-task-shell-view-actions.h"
+
+#define E_TASK_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TASK_SHELL_VIEW, ETaskShellViewPrivate))
+
+/* Shorthand, requires a variable named "shell_window". */
+#define ACTION(name) \
+ (E_SHELL_WINDOW_ACTION_##name (shell_window))
+#define ACTION_GROUP(name) \
+ (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window))
+
+/* For use in dispose() methods. */
+#define DISPOSE(obj) \
+ G_STMT_START { \
+ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \
+ } G_STMT_END
+
+/* ETable Specifications */
+#define ETSPEC_FILENAME "e-calendar-table.etspec"
+
+G_BEGIN_DECLS
+
+/* Filter items are displayed in ascending order.
+ * Non-negative values are reserved for categories. */
+enum {
+ TASK_FILTER_ANY_CATEGORY = -7,
+ TASK_FILTER_UNMATCHED = -6,
+ TASK_FILTER_NEXT_7_DAYS_TASKS = -5,
+ TASK_FILTER_ACTIVE_TASKS = -4,
+ TASK_FILTER_OVERDUE_TASKS = -3,
+ TASK_FILTER_COMPLETED_TASKS = -2,
+ TASK_FILTER_TASKS_WITH_ATTACHMENTS = -1
+};
+
+/* Search items are displayed in ascending order. */
+enum {
+ TASK_SEARCH_SUMMARY_CONTAINS,
+ TASK_SEARCH_DESCRIPTION_CONTAINS,
+ TASK_SEARCH_ANY_FIELD_CONTAINS
+};
+
+struct _ETaskShellViewPrivate {
+
+ /* These are just for convenience. */
+ ETaskShellBackend *task_shell_backend;
+ ETaskShellContent *task_shell_content;
+ ETaskShellSidebar *task_shell_sidebar;
+
+ EActivity *activity;
+ guint update_timeout;
+
+ guint confirm_purge : 1;
+};
+
+void e_task_shell_view_private_init
+ (ETaskShellView *task_shell_view,
+ EShellViewClass *shell_view_class);
+void e_task_shell_view_private_constructed
+ (ETaskShellView *task_shell_view);
+void e_task_shell_view_private_dispose
+ (ETaskShellView *task_shell_view);
+void e_task_shell_view_private_finalize
+ (ETaskShellView *task_shell_view);
+
+/* Private Utilities */
+
+void e_task_shell_view_actions_init
+ (ETaskShellView *task_shell_view);
+void e_task_shell_view_execute_search
+ (ETaskShellView *task_shell_view);
+void e_task_shell_view_open_task
+ (ETaskShellView *task_shell_view,
+ ECalModelComponent *comp_data);
+void e_task_shell_view_set_status_message
+ (ETaskShellView *task_shell_view,
+ const gchar *status_message,
+ gdouble percent);
+void e_task_shell_view_update_sidebar
+ (ETaskShellView *task_shell_view);
+void e_task_shell_view_update_search_filter
+ (ETaskShellView *task_shell_view);
+void e_task_shell_view_update_timezone
+ (ETaskShellView *task_shell_view);
+
+G_END_DECLS
+
+#endif /* E_TASK_SHELL_VIEW_PRIVATE_H */
diff --git a/modules/calendar/e-task-shell-view.c b/modules/calendar/e-task-shell-view.c
new file mode 100644
index 0000000000..b1298eaa29
--- /dev/null
+++ b/modules/calendar/e-task-shell-view.c
@@ -0,0 +1,325 @@
+/*
+ * e-task-shell-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-task-shell-view-private.h"
+
+enum {
+ PROP_0,
+ PROP_CONFIRM_PURGE
+};
+
+static gpointer parent_class;
+static GType task_shell_view_type;
+
+static void
+task_shell_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CONFIRM_PURGE:
+ e_task_shell_view_set_confirm_purge (
+ E_TASK_SHELL_VIEW (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+task_shell_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CONFIRM_PURGE:
+ g_value_set_boolean (
+ value, e_task_shell_view_get_confirm_purge (
+ E_TASK_SHELL_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+task_shell_view_dispose (GObject *object)
+{
+ e_task_shell_view_private_dispose (E_TASK_SHELL_VIEW (object));
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+task_shell_view_finalize (GObject *object)
+{
+ e_task_shell_view_private_finalize (E_TASK_SHELL_VIEW (object));
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+task_shell_view_constructed (GObject *object)
+{
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ e_task_shell_view_private_constructed (E_TASK_SHELL_VIEW (object));
+}
+
+static void
+task_shell_view_update_actions (EShellView *shell_view)
+{
+ ETaskShellViewPrivate *priv;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ GtkAction *action;
+ const gchar *label;
+ gboolean sensitive;
+ guint32 state;
+
+ /* Be descriptive. */
+ gboolean any_tasks_selected;
+ gboolean has_primary_source;
+ gboolean multiple_tasks_selected;
+ gboolean primary_source_is_system;
+ gboolean selection_has_url;
+ gboolean selection_is_assignable;
+ gboolean single_task_selected;
+ gboolean some_tasks_complete;
+ gboolean some_tasks_incomplete;
+ gboolean sources_are_editable;
+
+ priv = E_TASK_SHELL_VIEW_GET_PRIVATE (shell_view);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ state = e_shell_content_check_state (shell_content);
+
+ single_task_selected =
+ (state & E_TASK_SHELL_CONTENT_SELECTION_SINGLE);
+ multiple_tasks_selected =
+ (state & E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE);
+ selection_is_assignable =
+ (state & E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN);
+ sources_are_editable =
+ (state & E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT);
+ some_tasks_complete =
+ (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE);
+ some_tasks_incomplete =
+ (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE);
+ selection_has_url =
+ (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_URL);
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ state = e_shell_sidebar_check_state (shell_sidebar);
+
+ has_primary_source =
+ (state & E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE);
+ primary_source_is_system =
+ (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM);
+
+ any_tasks_selected =
+ (single_task_selected || multiple_tasks_selected);
+
+ action = ACTION (TASK_ASSIGN);
+ sensitive =
+ single_task_selected && sources_are_editable &&
+ selection_is_assignable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_CLIPBOARD_COPY);
+ sensitive = any_tasks_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_CLIPBOARD_CUT);
+ sensitive = any_tasks_selected && sources_are_editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_CLIPBOARD_PASTE);
+ sensitive = sources_are_editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_DELETE);
+ sensitive = any_tasks_selected && sources_are_editable;
+ gtk_action_set_sensitive (action, sensitive);
+ if (multiple_tasks_selected)
+ label = _("Delete Tasks");
+ else
+ label = _("Delete Task");
+ g_object_set (action, "label", label, NULL);
+
+ action = ACTION (TASK_FORWARD);
+ sensitive = single_task_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_LIST_COPY);
+ sensitive = has_primary_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_LIST_DELETE);
+ sensitive = has_primary_source && !primary_source_is_system;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_LIST_PROPERTIES);
+ sensitive = has_primary_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_LIST_RENAME);
+ sensitive = has_primary_source;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_MARK_COMPLETE);
+ sensitive =
+ any_tasks_selected &&
+ sources_are_editable &&
+ some_tasks_incomplete;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_MARK_INCOMPLETE);
+ sensitive =
+ any_tasks_selected &&
+ sources_are_editable &&
+ some_tasks_complete;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_OPEN);
+ sensitive = single_task_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_OPEN_URL);
+ sensitive = single_task_selected && selection_has_url;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_PRINT);
+ sensitive = single_task_selected;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_PURGE);
+ sensitive = sources_are_editable;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (TASK_SAVE_AS);
+ sensitive = single_task_selected;
+ gtk_action_set_sensitive (action, sensitive);
+}
+
+static void
+task_shell_view_class_init (ETaskShellViewClass *class,
+ GTypeModule *type_module)
+{
+ GObjectClass *object_class;
+ EShellViewClass *shell_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETaskShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = task_shell_view_set_property;
+ object_class->get_property = task_shell_view_get_property;
+ object_class->dispose = task_shell_view_dispose;
+ object_class->finalize = task_shell_view_finalize;
+ object_class->constructed = task_shell_view_constructed;
+
+ shell_view_class = E_SHELL_VIEW_CLASS (class);
+ shell_view_class->label = _("Tasks");
+ shell_view_class->icon_name = "evolution-tasks";
+ shell_view_class->ui_definition = "evolution-tasks.ui";
+ shell_view_class->ui_manager_id = "org.gnome.evolution.tasks";
+ shell_view_class->search_options = "/task-search-options";
+ shell_view_class->search_rules = "tasktypes.xml";
+ shell_view_class->new_shell_content = e_task_shell_content_new;
+ shell_view_class->new_shell_sidebar = e_task_shell_sidebar_new;
+ shell_view_class->update_actions = task_shell_view_update_actions;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONFIRM_PURGE,
+ g_param_spec_boolean (
+ "confirm-purge",
+ "Confirm Purge",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+}
+
+static void
+task_shell_view_init (ETaskShellView *task_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ task_shell_view->priv =
+ E_TASK_SHELL_VIEW_GET_PRIVATE (task_shell_view);
+
+ e_task_shell_view_private_init (task_shell_view, shell_view_class);
+}
+
+GType
+e_task_shell_view_get_type (void)
+{
+ return task_shell_view_type;
+}
+
+void
+e_task_shell_view_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (ETaskShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) task_shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ type_module,
+ sizeof (ETaskShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) task_shell_view_init,
+ NULL /* value_table */
+ };
+
+ task_shell_view_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_VIEW,
+ "ETaskShellView", &type_info, 0);
+}
+
+gboolean
+e_task_shell_view_get_confirm_purge (ETaskShellView *task_shell_view)
+{
+ g_return_val_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view), FALSE);
+
+ return task_shell_view->priv->confirm_purge;
+}
+
+void
+e_task_shell_view_set_confirm_purge (ETaskShellView *task_shell_view,
+ gboolean confirm_purge)
+{
+ g_return_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view));
+
+ task_shell_view->priv->confirm_purge = confirm_purge;
+
+ g_object_notify (G_OBJECT (task_shell_view), "confirm-purge");
+}
diff --git a/modules/calendar/e-task-shell-view.h b/modules/calendar/e-task-shell-view.h
new file mode 100644
index 0000000000..853d90cac1
--- /dev/null
+++ b/modules/calendar/e-task-shell-view.h
@@ -0,0 +1,72 @@
+/*
+ * e-task-shell-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TASK_SHELL_VIEW_H
+#define E_TASK_SHELL_VIEW_H
+
+#include <shell/e-shell-view.h>
+#include <libedataserver/e-source-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TASK_SHELL_VIEW \
+ (e_task_shell_view_get_type ())
+#define E_TASK_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TASK_SHELL_VIEW, ETaskShellView))
+#define E_TASK_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TASK_SHELL_VIEW, ETaskShellViewClass))
+#define E_IS_TASK_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TASK_SHELL_VIEW))
+#define E_IS_TASK_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TASK_SHELL_VIEW))
+#define E_TASK_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TASK_SHELL_VIEW, ETaskShellViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETaskShellView ETaskShellView;
+typedef struct _ETaskShellViewClass ETaskShellViewClass;
+typedef struct _ETaskShellViewPrivate ETaskShellViewPrivate;
+
+struct _ETaskShellView {
+ EShellView parent;
+ ETaskShellViewPrivate *priv;
+};
+
+struct _ETaskShellViewClass {
+ EShellViewClass parent_class;
+};
+
+GType e_task_shell_view_get_type (void);
+void e_task_shell_view_register_type (GTypeModule *type_module);
+gboolean e_task_shell_view_get_confirm_purge
+ (ETaskShellView *task_shell_view);
+void e_task_shell_view_set_confirm_purge
+ (ETaskShellView *task_shell_view,
+ gboolean confirm_purge);
+
+G_END_DECLS
+
+#endif /* E_TASK_SHELL_VIEW_H */
diff --git a/modules/calendar/evolution-module-calendar.c b/modules/calendar/evolution-module-calendar.c
new file mode 100644
index 0000000000..f72e8a97e4
--- /dev/null
+++ b/modules/calendar/evolution-module-calendar.c
@@ -0,0 +1,75 @@
+/*
+ * evolution-module-calendar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-attachment-handler.h"
+
+#include "e-cal-config-hook.h"
+#include "e-cal-event-hook.h"
+
+#include "e-cal-shell-backend.h"
+#include "e-cal-shell-content.h"
+#include "e-cal-shell-sidebar.h"
+#include "e-cal-shell-view.h"
+
+#include "e-memo-shell-backend.h"
+#include "e-memo-shell-content.h"
+#include "e-memo-shell-sidebar.h"
+#include "e-memo-shell-view.h"
+
+#include "e-task-shell-backend.h"
+#include "e-task-shell-content.h"
+#include "e-task-shell-sidebar.h"
+#include "e-task-shell-view.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
+
+ e_cal_attachment_handler_register_type (type_module);
+
+ e_cal_config_hook_register_type (type_module);
+ e_cal_event_hook_register_type (type_module);
+
+ e_cal_shell_backend_register_type (type_module);
+ e_cal_shell_content_register_type (type_module);
+ e_cal_shell_sidebar_register_type (type_module);
+ e_cal_shell_view_register_type (type_module);
+
+ e_memo_shell_backend_register_type (type_module);
+ e_memo_shell_content_register_type (type_module);
+ e_memo_shell_sidebar_register_type (type_module);
+ e_memo_shell_view_register_type (type_module);
+
+ e_task_shell_backend_register_type (type_module);
+ e_task_shell_content_register_type (type_module);
+ e_task_shell_sidebar_register_type (type_module);
+ e_task_shell_view_register_type (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/modules/mail/Makefile.am b/modules/mail/Makefile.am
new file mode 100644
index 0000000000..462161843c
--- /dev/null
+++ b/modules/mail/Makefile.am
@@ -0,0 +1,60 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/mail \
+ -I$(top_srcdir)/widgets \
+ $(EVOLUTION_MAIL_CFLAGS) \
+ -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
+ -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ -DG_LOG_DOMAIN=\"evolution-module-mail\"
+
+module_LTLIBRARIES = libevolution-module-mail.la
+
+libevolution_module_mail_la_SOURCES = \
+ evolution-module-mail.c \
+ e-mail-attachment-handler.c \
+ e-mail-attachment-handler.h \
+ e-mail-config-hook.c \
+ e-mail-config-hook.h \
+ e-mail-event-hook.c \
+ e-mail-event-hook.h \
+ e-mail-junk-hook.c \
+ e-mail-junk-hook.h \
+ e-mail-shell-backend.c \
+ e-mail-shell-backend.h \
+ e-mail-shell-content.c \
+ e-mail-shell-content.h \
+ e-mail-shell-migrate.c \
+ e-mail-shell-migrate.h \
+ e-mail-shell-settings.c \
+ e-mail-shell-settings.h \
+ e-mail-shell-sidebar.c \
+ e-mail-shell-sidebar.h \
+ e-mail-shell-view.c \
+ e-mail-shell-view.h \
+ e-mail-shell-view-actions.c \
+ e-mail-shell-view-actions.h \
+ e-mail-shell-view-private.c \
+ e-mail-shell-view-private.h \
+ em-account-prefs.c \
+ em-account-prefs.h \
+ em-composer-prefs.c \
+ em-composer-prefs.h \
+ em-mailer-prefs.c \
+ em-mailer-prefs.h \
+ em-network-prefs.c \
+ em-network-prefs.h
+
+libevolution_module_mail_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/shell/libeshell.la \
+ $(top_builddir)/composer/libcomposer.la \
+ $(top_builddir)/widgets/table/libetable.la \
+ $(top_builddir)/widgets/text/libetext.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/mail/importers/libevolution-mail-importers.la
+
+libevolution_module_mail_la_LDFLAGS = \
+ -avoid-version -module $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/mail/e-attachment-handler-mail.c b/modules/mail/e-mail-attachment-handler.c
index c17c97d8ca..91fe5d3e5f 100644
--- a/mail/e-attachment-handler-mail.c
+++ b/modules/mail/e-mail-attachment-handler.c
@@ -1,5 +1,5 @@
/*
- * e-attachment-handler-mail.c
+ * e-mail-attachment-handler.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,7 @@
*
*/
-#include "e-attachment-handler-mail.h"
+#include "e-mail-attachment-handler.h"
#include <glib/gi18n.h>
#include <camel/camel-folder.h>
@@ -29,15 +29,16 @@
#include "mail/em-composer-utils.h"
#include "mail/mail-tools.h"
-#define E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE(obj) \
+#define E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailPrivate))
+ ((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandlerPrivate))
-struct _EAttachmentHandlerMailPrivate {
+struct _EMailAttachmentHandlerPrivate {
gint placeholder;
};
static gpointer parent_class;
+static GType mail_attachment_handler_type;
static const gchar *ui =
"<ui>"
@@ -57,7 +58,7 @@ static GtkTargetEntry target_table[] = {
};
static void
-attachment_handler_mail_forward (GtkAction *action,
+mail_attachment_handler_forward (GtkAction *action,
EAttachmentView *view)
{
EAttachment *attachment;
@@ -79,7 +80,7 @@ attachment_handler_mail_forward (GtkAction *action,
}
static void
-attachment_handler_mail_reply_all (GtkAction *action,
+mail_attachment_handler_reply_all (GtkAction *action,
EAttachmentView *view)
{
EAttachment *attachment;
@@ -103,7 +104,7 @@ attachment_handler_mail_reply_all (GtkAction *action,
}
static void
-attachment_handler_mail_reply_sender (GtkAction *action,
+mail_attachment_handler_reply_sender (GtkAction *action,
EAttachmentView *view)
{
EAttachment *attachment;
@@ -133,25 +134,25 @@ static GtkActionEntry standard_entries[] = {
N_("_Forward"),
NULL,
NULL, /* XXX Add a tooltip! */
- G_CALLBACK (attachment_handler_mail_forward) },
+ G_CALLBACK (mail_attachment_handler_forward) },
{ "mail-reply-all",
"mail-reply-all",
N_("Reply to _All"),
NULL,
NULL, /* XXX Add a tooltip! */
- G_CALLBACK (attachment_handler_mail_reply_all) },
+ G_CALLBACK (mail_attachment_handler_reply_all) },
{ "mail-reply-sender",
"mail-reply-sender",
N_("_Reply to Sender"),
NULL,
NULL, /* XXX Add a tooltip! */
- G_CALLBACK (attachment_handler_mail_reply_sender) }
+ G_CALLBACK (mail_attachment_handler_reply_sender) }
};
static void
-attachment_handler_mail_message_rfc822 (EAttachmentView *view,
+mail_attachment_handler_message_rfc822 (EAttachmentView *view,
GdkDragContext *drag_context,
gint x,
gint y,
@@ -213,7 +214,7 @@ exit:
}
static void
-attachment_handler_mail_x_uid_list (EAttachmentView *view,
+mail_attachment_handler_x_uid_list (EAttachmentView *view,
GdkDragContext *drag_context,
gint x,
gint y,
@@ -380,7 +381,7 @@ exit:
}
static void
-attachment_handler_mail_update_actions (EAttachmentView *view)
+mail_attachment_handler_update_actions (EAttachmentView *view)
{
EAttachment *attachment;
CamelMimePart *mime_part;
@@ -413,7 +414,7 @@ exit:
}
static void
-attachment_handler_mail_constructed (GObject *object)
+mail_attachment_handler_constructed (GObject *object)
{
EAttachmentHandler *handler;
EAttachmentView *view;
@@ -443,28 +444,28 @@ attachment_handler_mail_constructed (GObject *object)
g_signal_connect (
view, "update-actions",
- G_CALLBACK (attachment_handler_mail_update_actions),
+ G_CALLBACK (mail_attachment_handler_update_actions),
NULL);
g_signal_connect (
view, "drag-data-received",
- G_CALLBACK (attachment_handler_mail_message_rfc822),
+ G_CALLBACK (mail_attachment_handler_message_rfc822),
NULL);
g_signal_connect (
view, "drag-data-received",
- G_CALLBACK (attachment_handler_mail_x_uid_list),
+ G_CALLBACK (mail_attachment_handler_x_uid_list),
NULL);
}
static GdkDragAction
-attachment_handler_mail_get_drag_actions (EAttachmentHandler *handler)
+mail_attachment_handler_get_drag_actions (EAttachmentHandler *handler)
{
return GDK_ACTION_COPY;
}
static const GtkTargetEntry *
-attachment_handler_mail_get_target_table (EAttachmentHandler *handler,
+mail_attachment_handler_get_target_table (EAttachmentHandler *handler,
guint *n_targets)
{
if (n_targets != NULL)
@@ -474,51 +475,51 @@ attachment_handler_mail_get_target_table (EAttachmentHandler *handler,
}
static void
-attachment_handler_mail_class_init (EAttachmentHandlerMailClass *class)
+mail_attachment_handler_class_init (EMailAttachmentHandlerClass *class)
{
GObjectClass *object_class;
EAttachmentHandlerClass *handler_class;
parent_class = g_type_class_peek_parent (class);
- g_type_class_add_private (class, sizeof (EAttachmentHandlerMailPrivate));
+ g_type_class_add_private (class, sizeof (EMailAttachmentHandlerPrivate));
object_class = G_OBJECT_CLASS (class);
- object_class->constructed = attachment_handler_mail_constructed;
+ object_class->constructed = mail_attachment_handler_constructed;
handler_class = E_ATTACHMENT_HANDLER_CLASS (class);
- handler_class->get_drag_actions = attachment_handler_mail_get_drag_actions;
- handler_class->get_target_table = attachment_handler_mail_get_target_table;
+ handler_class->get_drag_actions = mail_attachment_handler_get_drag_actions;
+ handler_class->get_target_table = mail_attachment_handler_get_target_table;
}
static void
-attachment_handler_mail_init (EAttachmentHandlerMail *handler)
+mail_attachment_handler_init (EMailAttachmentHandler *handler)
{
- handler->priv = E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE (handler);
+ handler->priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
}
GType
-e_attachment_handler_mail_get_type (void)
+e_mail_attachment_handler_get_type (void)
{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EAttachmentHandlerMailClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) attachment_handler_mail_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EAttachmentHandlerMail),
- 0, /* n_preallocs */
- (GInstanceInitFunc) attachment_handler_mail_init,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- E_TYPE_ATTACHMENT_HANDLER,
- "EAttachmentHandlerMail", &type_info, 0);
- }
+ return mail_attachment_handler_type;
+}
- return type;
+void
+e_mail_attachment_handler_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EMailAttachmentHandlerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_attachment_handler_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailAttachmentHandler),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_attachment_handler_init,
+ NULL /* value_table */
+ };
+
+ mail_attachment_handler_type = g_type_module_register_type (
+ type_module, E_TYPE_ATTACHMENT_HANDLER,
+ "EMailAttachmentHandler", &type_info, 0);
}
diff --git a/modules/mail/e-mail-attachment-handler.h b/modules/mail/e-mail-attachment-handler.h
new file mode 100644
index 0000000000..13032b488c
--- /dev/null
+++ b/modules/mail/e-mail-attachment-handler.h
@@ -0,0 +1,67 @@
+/*
+ * e-mail-attachment-handler.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_ATTACHMENT_HANDLER_H
+#define E_MAIL_ATTACHMENT_HANDLER_H
+
+#include <widgets/misc/e-attachment-handler.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_ATTACHMENT_HANDLER \
+ (e_mail_attachment_handler_get_type ())
+#define E_MAIL_ATTACHMENT_HANDLER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandler))
+#define E_MAIL_ATTACHMENT_HANDLER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandlerClass))
+#define E_IS_MAIL_ATTACHMENT_HANDLER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER))
+#define E_IS_MAIL_ATTACHMENT_HANDLER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_ATTACHMENT_HANDLER))
+#define E_MAIL_ATTACHMENT_HANDLER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandlerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAttachmentHandler EMailAttachmentHandler;
+typedef struct _EMailAttachmentHandlerClass EMailAttachmentHandlerClass;
+typedef struct _EMailAttachmentHandlerPrivate EMailAttachmentHandlerPrivate;
+
+struct _EMailAttachmentHandler {
+ EAttachmentHandler parent;
+ EMailAttachmentHandlerPrivate *priv;
+};
+
+struct _EMailAttachmentHandlerClass {
+ EAttachmentHandlerClass parent_class;
+};
+
+GType e_mail_attachment_handler_get_type (void);
+void e_mail_attachment_handler_register_type
+ (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_ATTACHMENT_HANDLER_H */
diff --git a/modules/mail/e-mail-config-hook.c b/modules/mail/e-mail-config-hook.c
new file mode 100644
index 0000000000..4b37a6b171
--- /dev/null
+++ b/modules/mail/e-mail-config-hook.c
@@ -0,0 +1,69 @@
+/*
+ * e-mail-config-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-config-hook.h"
+
+#include "e-util/e-config.h"
+#include "mail/em-config.h"
+
+static const EConfigHookTargetMask no_masks[] = {
+ { NULL }
+};
+
+static const EConfigHookTargetMap targets[] = {
+ { "folder", EM_CONFIG_TARGET_FOLDER, no_masks },
+ { "prefs", EM_CONFIG_TARGET_PREFS, no_masks },
+ { "account", EM_CONFIG_TARGET_ACCOUNT, no_masks },
+ { NULL }
+};
+
+static void
+mail_config_hook_class_init (EPluginHookClass *class)
+{
+ gint ii;
+
+ class->id = "org.gnome.evolution.mail.config:1.0";
+
+ for (ii = 0; targets[ii].type != NULL; ii++)
+ e_config_hook_class_add_target_map (
+ (EConfigHookClass *) class, &targets[ii]);
+}
+
+void
+e_mail_config_hook_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EConfigHookClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_config_hook_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EConfigHook),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ NULL /* value_table */
+ };
+
+ g_type_module_register_type (
+ type_module, e_config_hook_get_type (),
+ "EMailConfigHook", &type_info, 0);
+}
diff --git a/modules/mail/e-mail-config-hook.h b/modules/mail/e-mail-config-hook.h
new file mode 100644
index 0000000000..e54ad81815
--- /dev/null
+++ b/modules/mail/e-mail-config-hook.h
@@ -0,0 +1,33 @@
+/*
+ * e-mail-config-hook.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_HOOK_H
+#define E_MAIL_CONFIG_HOOK_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_config_hook_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_HOOK_H */
diff --git a/modules/mail/e-mail-event-hook.c b/modules/mail/e-mail-event-hook.c
new file mode 100644
index 0000000000..a6be6d294f
--- /dev/null
+++ b/modules/mail/e-mail-event-hook.c
@@ -0,0 +1,93 @@
+/*
+ * e-mail-event-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-event-hook.h"
+
+#include "e-util/e-event.h"
+#include "mail/em-event.h"
+
+static const EEventHookTargetMask folder_masks[] = {
+ { "newmail", EM_EVENT_FOLDER_NEWMAIL },
+ { NULL }
+};
+
+static const EEventHookTargetMask composer_masks[] = {
+ { "sendoption", EM_EVENT_COMPOSER_SEND_OPTION },
+ { NULL }
+};
+
+static const EEventHookTargetMask message_masks[] = {
+ { "replyall", EM_EVENT_MESSAGE_REPLY_ALL },
+ { "reply", EM_EVENT_MESSAGE_REPLY },
+ { NULL }
+};
+
+static const EEventHookTargetMask send_receive_masks[] = {
+ { "sendreceive", EM_EVENT_SEND_RECEIVE },
+ { NULL }
+};
+
+static const EEventHookTargetMask custom_icon_masks[] = {
+ { "customicon", EM_EVENT_CUSTOM_ICON },
+ { NULL }
+};
+
+static const EEventHookTargetMap targets[] = {
+ { "folder", EM_EVENT_TARGET_FOLDER, folder_masks },
+ { "message", EM_EVENT_TARGET_MESSAGE, message_masks },
+ { "composer", EM_EVENT_TARGET_COMPOSER, composer_masks },
+ { "sendreceive", EM_EVENT_TARGET_SEND_RECEIVE, send_receive_masks },
+ { "customicon", EM_EVENT_TARGET_CUSTOM_ICON, custom_icon_masks },
+ { NULL }
+};
+
+static void
+mail_event_hook_class_init (EPluginHookClass *class)
+{
+ gint ii;
+
+ class->id = "org.gnome.evolution.mail.events:1.0";
+
+ for (ii = 0; targets[ii].type != NULL; ii++)
+ e_event_hook_class_add_target_map (
+ (EEventHookClass *) class, &targets[ii]);
+}
+
+void
+e_mail_event_hook_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EEventHookClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_event_hook_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EEventHook),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ NULL /* value_table */
+ };
+
+ g_type_module_register_type (
+ type_module, e_event_hook_get_type (),
+ "EMailEventHook", &type_info, 0);
+}
diff --git a/modules/mail/e-mail-event-hook.h b/modules/mail/e-mail-event-hook.h
new file mode 100644
index 0000000000..9cad43a0c2
--- /dev/null
+++ b/modules/mail/e-mail-event-hook.h
@@ -0,0 +1,33 @@
+/*
+ * e-mail-event-hook.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_EVENT_HOOK_H
+#define E_MAIL_EVENT_HOOK_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_event_hook_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_EVENT_HOOK_H */
diff --git a/modules/mail/e-mail-junk-hook.c b/modules/mail/e-mail-junk-hook.c
new file mode 100644
index 0000000000..2687223af9
--- /dev/null
+++ b/modules/mail/e-mail-junk-hook.c
@@ -0,0 +1,323 @@
+/*
+ * e-mail-junk-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-junk-hook.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-junk-plugin.h>
+
+#include "e-util/e-error.h"
+#include "mail/em-junk.h"
+#include "mail/em-utils.h"
+#include "mail/mail-session.h"
+
+#define E_MAIL_JUNK_HOOK_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookPrivate))
+
+struct _EMailJunkHookPrivate {
+ EMJunkInterface interface;
+};
+
+struct ErrorData {
+ const gchar *error_message;
+ GError *error;
+};
+
+static gpointer parent_class;
+static GType mail_junk_hook_type;
+
+static gboolean
+mail_junk_hook_idle_cb (struct ErrorData *data)
+{
+ GtkWidget *widget;
+
+ widget = e_error_new (
+ NULL, data->error_message, data->error->message, NULL);
+ em_utils_show_error_silent (widget);
+
+ g_error_free (data->error);
+ g_slice_free (struct ErrorData, data);
+
+ return FALSE;
+}
+
+static void
+mail_junk_hook_error (const gchar *error_message,
+ GError *error)
+{
+ struct ErrorData *data;
+
+ g_return_if_fail (error != NULL);
+
+ data = g_slice_new (struct ErrorData);
+ data->error_message = error_message;
+ data->error = error;
+
+ g_idle_add ((GSourceFunc) mail_junk_hook_idle_cb, data);
+}
+
+static const gchar *
+mail_junk_hook_get_name (CamelJunkPlugin *junk_plugin)
+{
+ EMJunkInterface *interface;
+
+ interface = (EMJunkInterface *) junk_plugin;
+
+ if (!interface->hook->plugin->enabled)
+ return _("None");
+
+ return interface->hook->plugin->name;
+}
+
+static void
+mail_junk_hook_plugin_init (CamelJunkPlugin *junk_plugin)
+{
+ EMJunkInterface *interface;
+ EPluginClass *class;
+
+ interface = (EMJunkInterface *) junk_plugin;
+
+ class = E_PLUGIN_GET_CLASS (interface->hook->plugin);
+ g_return_if_fail (class->enable != NULL);
+
+ class->enable (interface->hook->plugin, 1);
+}
+
+static gboolean
+mail_junk_hook_check_junk (CamelJunkPlugin *junk_plugin,
+ CamelMimeMessage *mime_message)
+{
+ EMJunkTarget target = { mime_message, NULL };
+ EMJunkInterface *interface;
+ gpointer result;
+
+ interface = (EMJunkInterface *) junk_plugin;
+
+ if (!interface->hook->plugin->enabled)
+ return FALSE;
+
+ result = e_plugin_invoke (
+ interface->hook->plugin,
+ interface->check_junk, &target);
+
+ if (target.error != NULL)
+ mail_junk_hook_error ("mail:junk-check-error", target.error);
+
+ return (result != NULL);
+}
+
+static void
+mail_junk_hook_report_junk (CamelJunkPlugin *junk_plugin,
+ CamelMimeMessage *mime_message)
+{
+ EMJunkTarget target = { mime_message, NULL };
+ EMJunkInterface *interface;
+
+ interface = (EMJunkInterface *) junk_plugin;
+
+ if (!interface->hook->plugin->enabled)
+ return;
+
+ e_plugin_invoke (
+ interface->hook->plugin,
+ interface->report_junk, &target);
+
+ if (target.error != NULL)
+ mail_junk_hook_error ("mail:junk-report-error", target.error);
+}
+
+static void
+mail_junk_hook_report_notjunk (CamelJunkPlugin *junk_plugin,
+ CamelMimeMessage *mime_message)
+{
+ EMJunkTarget target = { mime_message, NULL };
+ EMJunkInterface *interface;
+
+ interface = (EMJunkInterface *) junk_plugin;
+
+ if (!interface->hook->plugin->enabled)
+ return;
+
+ e_plugin_invoke (
+ interface->hook->plugin,
+ interface->report_notjunk, &target);
+
+ if (target.error != NULL)
+ mail_junk_hook_error (
+ "mail:junk-not-report-error", target.error);
+}
+
+static void
+mail_junk_hook_commit_reports (CamelJunkPlugin *junk_plugin)
+{
+ EMJunkInterface *interface;
+
+ interface = (EMJunkInterface *) junk_plugin;
+
+ if (!interface->hook->plugin->enabled)
+ return;
+
+ e_plugin_invoke (
+ interface->hook->plugin,
+ interface->commit_reports, NULL);
+}
+
+static void
+mail_junk_hook_finalize (GObject *object)
+{
+ EMailJunkHookPrivate *priv;
+
+ priv = E_MAIL_JUNK_HOOK_GET_PRIVATE (object);
+
+ g_free (priv->interface.check_junk);
+ g_free (priv->interface.report_junk);
+ g_free (priv->interface.report_notjunk);
+ g_free (priv->interface.commit_reports);
+ g_free (priv->interface.validate_binary);
+ g_free (priv->interface.plugin_name);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gint
+mail_junk_hook_construct (EPluginHook *hook,
+ EPlugin *plugin,
+ xmlNodePtr node)
+{
+ EMailJunkHookPrivate *priv;
+ gchar *property;
+
+ priv = E_MAIL_JUNK_HOOK_GET_PRIVATE (hook);
+
+ /* Chain up to parent's construct() method. */
+ if (E_PLUGIN_HOOK_CLASS (parent_class)->construct (hook, plugin, node) == -1)
+ return -1;
+
+ if (!plugin->enabled)
+ return -1;
+
+ node = xmlFirstElementChild (node);
+
+ if (node == NULL)
+ return -1;
+
+ if (g_strcmp0 ((gchar *) node->name, "interface") != 0)
+ return -1;
+
+ property = e_plugin_xml_prop (node, "check_junk");
+ priv->interface.check_junk = property;
+
+ property = e_plugin_xml_prop (node, "report_junk");
+ priv->interface.report_junk = property;
+
+ property = e_plugin_xml_prop (node, "report_non_junk");
+ priv->interface.report_notjunk = property;
+
+ property = e_plugin_xml_prop (node, "commit_reports");
+ priv->interface.commit_reports = property;
+
+ property = e_plugin_xml_prop (node, "validate_binary");
+ priv->interface.validate_binary = property;
+
+ property = e_plugin_xml_prop (node, "name");
+ priv->interface.plugin_name = property;
+
+ if (priv->interface.check_junk == NULL)
+ return -1;
+
+ if (priv->interface.report_junk == NULL)
+ return -1;
+
+ if (priv->interface.report_notjunk == NULL)
+ return -1;
+
+ if (priv->interface.commit_reports == NULL)
+ return -1;
+
+ mail_session_add_junk_plugin (
+ priv->interface.plugin_name, &priv->interface.camel);
+
+ return 0;
+}
+
+static void
+mail_junk_hook_class_init (EMailJunkHookClass *class)
+{
+ GObjectClass *object_class;
+ EPluginHookClass *plugin_hook_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailJunkHookPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = mail_junk_hook_finalize;
+
+ plugin_hook_class = E_PLUGIN_HOOK_CLASS (class);
+ plugin_hook_class->construct = mail_junk_hook_construct;
+ plugin_hook_class->id = "org.gnome.evolution.mail.junk:1.0";
+}
+
+static void
+mail_junk_hook_init (EMailJunkHook *mail_junk_hook)
+{
+ EMJunkInterface *interface;
+
+ mail_junk_hook->priv = E_MAIL_JUNK_HOOK_GET_PRIVATE (mail_junk_hook);
+
+ interface = &mail_junk_hook->priv->interface;
+ interface->camel.get_name = mail_junk_hook_get_name;
+ interface->camel.api_version = 1;
+ interface->camel.check_junk = mail_junk_hook_check_junk;
+ interface->camel.report_junk = mail_junk_hook_report_junk;
+ interface->camel.report_notjunk = mail_junk_hook_report_notjunk;
+ interface->camel.commit_reports = mail_junk_hook_commit_reports;
+ interface->camel.init = mail_junk_hook_plugin_init;
+ interface->hook = E_PLUGIN_HOOK (mail_junk_hook);
+}
+
+GType
+e_mail_junk_hook_get_type (void)
+{
+ return mail_junk_hook_type;
+}
+
+void
+e_mail_junk_hook_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EMailJunkHookClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_junk_hook_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailJunkHook),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_junk_hook_init,
+ NULL /* value_table */
+ };
+
+ mail_junk_hook_type = g_type_module_register_type (
+ type_module, E_TYPE_PLUGIN_HOOK,
+ "EMailJunkHook", &type_info, 0);
+}
diff --git a/modules/mail/e-mail-junk-hook.h b/modules/mail/e-mail-junk-hook.h
new file mode 100644
index 0000000000..f5882e66b3
--- /dev/null
+++ b/modules/mail/e-mail-junk-hook.h
@@ -0,0 +1,66 @@
+/*
+ * e-mail-junk-hook.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_JUNK_HOOK_H
+#define E_MAIL_JUNK_HOOK_H
+
+#include <e-util/e-plugin.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_JUNK_HOOK \
+ (e_mail_junk_hook_get_type ())
+#define E_MAIL_JUNK_HOOK(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHook))
+#define E_MAIL_JUNK_HOOK_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookClass))
+#define E_IS_MAIL_JUNK_HOOK(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_JUNK_HOOK))
+#define E_IS_MAIL_JUNK_HOOK_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_JUNK_HOOK))
+#define E_MAIL_JUNK_HOOK_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailJunkHook EMailJunkHook;
+typedef struct _EMailJunkHookClass EMailJunkHookClass;
+typedef struct _EMailJunkHookPrivate EMailJunkHookPrivate;
+
+struct _EMailJunkHook {
+ EPluginHook parent;
+ EMailJunkHookPrivate *priv;
+};
+
+struct _EMailJunkHookClass {
+ EPluginHookClass parent_class;
+};
+
+GType e_mail_junk_hook_get_type (void);
+void e_mail_junk_hook_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_JUNK_HOOK_H */
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
new file mode 100644
index 0000000000..fd1e7263c4
--- /dev/null
+++ b/modules/mail/e-mail-shell-backend.c
@@ -0,0 +1,987 @@
+/*
+ * e-mail-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-shell-backend.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-disco-store.h>
+#include <camel/camel-offline-store.h>
+#include <camel/camel-session.h>
+#include <camel/camel-url.h>
+
+#include "e-util/e-account-utils.h"
+#include "e-util/e-binding.h"
+#include "e-util/e-error.h"
+#include "e-util/e-import.h"
+#include "e-util/e-util.h"
+#include "shell/e-shell.h"
+#include "shell/e-shell-window.h"
+#include "composer/e-msg-composer.h"
+#include "widgets/misc/e-preferences-window.h"
+
+#include "e-mail-shell-migrate.h"
+#include "e-mail-shell-settings.h"
+#include "e-mail-shell-sidebar.h"
+#include "e-mail-shell-view.h"
+
+#include "e-mail-browser.h"
+#include "e-mail-local.h"
+#include "e-mail-reader.h"
+#include "e-mail-store.h"
+#include "em-account-editor.h"
+#include "em-account-prefs.h"
+#include "em-composer-prefs.h"
+#include "em-composer-utils.h"
+#include "em-folder-utils.h"
+#include "em-format-hook.h"
+#include "em-format-html-display.h"
+#include "em-mailer-prefs.h"
+#include "em-network-prefs.h"
+#include "em-utils.h"
+#include "mail-config.h"
+#include "mail-ops.h"
+#include "mail-send-recv.h"
+#include "mail-session.h"
+#include "mail-vfolder.h"
+#include "importers/mail-importer.h"
+
+#define E_MAIL_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_SHELL_BACKEND, EMailShellBackendPrivate))
+
+#define BACKEND_NAME "mail"
+#define QUIT_POLL_INTERVAL 1 /* seconds */
+
+struct _EMailShellBackendPrivate {
+ gint mail_sync_in_progress;
+ guint mail_sync_timeout_source_id;
+};
+
+static gpointer parent_class;
+static GType mail_shell_backend_type;
+
+extern gint camel_application_is_exiting;
+
+static void
+mail_shell_backend_init_importers (void)
+{
+ EImportClass *import_class;
+ EImportImporter *importer;
+
+ import_class = g_type_class_ref (e_import_get_type ());
+
+ importer = mbox_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+
+ importer = elm_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+
+ importer = pine_importer_peek ();
+ e_import_class_add_importer (import_class, importer, NULL, NULL);
+}
+
+static void
+mail_shell_backend_mail_icon_cb (EShellWindow *shell_window,
+ const gchar *icon_name)
+{
+ GtkAction *action;
+
+ action = e_shell_window_get_shell_view_action (
+ shell_window, BACKEND_NAME);
+ g_object_set (action, "icon-name", icon_name, NULL);
+}
+
+static void
+action_mail_folder_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EMFolderTree *folder_tree = NULL;
+ EMailShellSidebar *mail_shell_sidebar;
+ EShellSidebar *shell_sidebar;
+ EShellView *shell_view;
+ const gchar *view_name;
+
+ /* Take care not to unnecessarily load the mail shell view. */
+ view_name = e_shell_window_get_active_view (shell_window);
+ if (g_strcmp0 (view_name, BACKEND_NAME) != 0)
+ goto exit;
+
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar);
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+exit:
+ em_folder_utils_create_folder (
+ NULL, folder_tree, GTK_WINDOW (shell_window));
+}
+
+static void
+action_mail_message_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EShellSidebar *shell_sidebar;
+ EShellView *shell_view;
+ EMFolderTree *folder_tree;
+ const gchar *view_name;
+ gchar *uri = NULL;
+
+ if (!em_utils_check_user_can_send_mail ())
+ return;
+
+ /* Take care not to unnecessarily load the mail shell view. */
+ view_name = e_shell_window_get_active_view (shell_window);
+ if (g_strcmp0 (view_name, BACKEND_NAME) != 0)
+ goto exit;
+
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar);
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ uri = em_folder_tree_get_selected_uri (folder_tree);
+
+exit:
+ em_utils_compose_new_message (uri);
+
+ g_free (uri);
+}
+
+static GtkActionEntry item_entries[] = {
+
+ { "mail-message-new",
+ "mail-message-new",
+ NC_("New", "_Mail Message"),
+ "<Shift><Control>m",
+ N_("Compose a new mail message"),
+ G_CALLBACK (action_mail_message_new_cb) }
+};
+
+static GtkActionEntry source_entries[] = {
+
+ { "mail-folder-new",
+ "folder-new",
+ NC_("New", "Mail _Folder"),
+ NULL,
+ N_("Create a new mail folder"),
+ G_CALLBACK (action_mail_folder_new_cb) }
+};
+
+static void
+mail_shell_backend_init_preferences (EShell *shell)
+{
+ EAccountList *account_list;
+ GtkWidget *preferences_window;
+
+ account_list = e_get_account_list ();
+ preferences_window = e_shell_get_preferences_window (shell);
+
+ e_preferences_window_add_page (
+ E_PREFERENCES_WINDOW (preferences_window),
+ "mail-accounts",
+ "preferences-mail-accounts",
+ _("Mail Accounts"),
+ em_account_prefs_new (account_list),
+ 100);
+
+ e_preferences_window_add_page (
+ E_PREFERENCES_WINDOW (preferences_window),
+ "mail",
+ "preferences-mail",
+ _("Mail Preferences"),
+ em_mailer_prefs_new (shell),
+ 300);
+
+ e_preferences_window_add_page (
+ E_PREFERENCES_WINDOW (preferences_window),
+ "composer",
+ "preferences-composer",
+ _("Composer Preferences"),
+ em_composer_prefs_new (shell),
+ 400);
+
+ e_preferences_window_add_page (
+ E_PREFERENCES_WINDOW (preferences_window),
+ "system-network-proxy",
+ "preferences-system-network-proxy",
+ _("Network Preferences"),
+ em_network_prefs_new (),
+ 500);
+}
+
+static void
+mail_shell_backend_sync_store_done_cb (CamelStore *store,
+ gpointer user_data)
+{
+ EMailShellBackend *mail_shell_backend = user_data;
+
+ mail_shell_backend->priv->mail_sync_in_progress--;
+}
+
+static void
+mail_shell_backend_sync_store_cb (CamelStore *store,
+ EMailShellBackend *mail_shell_backend)
+{
+ if (!camel_application_is_exiting) {
+ mail_shell_backend->priv->mail_sync_in_progress++;
+ mail_sync_store (
+ store, FALSE,
+ mail_shell_backend_sync_store_done_cb,
+ mail_shell_backend);
+ }
+}
+
+static gboolean
+mail_shell_backend_mail_sync (EMailShellBackend *mail_shell_backend)
+{
+ if (camel_application_is_exiting)
+ return FALSE;
+
+ if (mail_shell_backend->priv->mail_sync_in_progress)
+ goto exit;
+
+ if (session == NULL || !camel_session_is_online (session))
+ goto exit;
+
+ e_mail_store_foreach (
+ (GHFunc) mail_shell_backend_sync_store_cb,
+ mail_shell_backend);
+
+exit:
+ return !camel_application_is_exiting;
+}
+
+static void
+mail_shell_backend_notify_online_cb (EShell *shell,
+ GParamSpec *pspec,
+ EShellBackend *shell_backend)
+{
+ gboolean online;
+
+ online = e_shell_get_online (shell);
+ camel_session_set_online (session, online);
+}
+
+static void
+mail_shell_backend_handle_email_uri_cb (gchar *folder_uri,
+ CamelFolder *folder,
+ gpointer user_data)
+{
+ EShellBackend *shell_backend = user_data;
+ CamelURL *url = user_data;
+ const gchar *forward;
+ const gchar *reply;
+ const gchar *uid;
+
+ if (folder == NULL) {
+ g_warning ("Could not open folder '%s'", folder_uri);
+ goto exit;
+ }
+
+ forward = camel_url_get_param (url, "forward");
+ reply = camel_url_get_param (url, "reply");
+ uid = camel_url_get_param (url, "uid");
+
+ if (reply != NULL) {
+ gint mode;
+
+ if (g_strcmp0 (reply, "all") == 0)
+ mode = REPLY_MODE_ALL;
+ else if (g_strcmp0 (reply, "list") == 0)
+ mode = REPLY_MODE_LIST;
+ else
+ mode = REPLY_MODE_SENDER;
+
+ em_utils_reply_to_message (folder, uid, NULL, mode, NULL);
+
+ } else if (forward != NULL) {
+ GPtrArray *uids;
+
+ uids = g_ptr_array_new ();
+ g_ptr_array_add (uids, g_strdup (uid));
+
+ if (g_strcmp0 (forward, "attached") == 0)
+ em_utils_forward_attached (folder, uids, folder_uri);
+ else if (g_strcmp0 (forward, "inline") == 0)
+ em_utils_forward_inline (folder, uids, folder_uri);
+ else if (g_strcmp0 (forward, "quoted") == 0)
+ em_utils_forward_quoted (folder, uids, folder_uri);
+ else
+ em_utils_forward_messages (folder, uids, folder_uri);
+
+ } else {
+ GtkWidget *browser;
+
+ /* FIXME Should pass in the shell module. */
+ browser = e_mail_browser_new (shell_backend);
+ e_mail_reader_set_folder (
+ E_MAIL_READER (browser), folder, folder_uri);
+ e_mail_reader_set_message (E_MAIL_READER (browser), uid);
+ gtk_widget_show (browser);
+ }
+
+exit:
+ camel_url_free (url);
+}
+
+static gboolean
+mail_shell_backend_handle_uri_cb (EShell *shell,
+ const gchar *uri,
+ EMailShellBackend *mail_shell_backend)
+{
+ gboolean handled = TRUE;
+
+ if (g_str_has_prefix (uri, "mailto:")) {
+ if (em_utils_check_user_can_send_mail ())
+ em_utils_compose_new_message_with_mailto (uri, NULL);
+
+ } else if (g_str_has_prefix (uri, "email:")) {
+ CamelURL *url;
+
+ url = camel_url_new (uri, NULL);
+ if (camel_url_get_param (url, "uid") != NULL) {
+ gchar *curi = em_uri_to_camel (uri);
+
+ mail_get_folder (
+ curi, 0,
+ mail_shell_backend_handle_email_uri_cb,
+ mail_shell_backend, mail_msg_unordered_push);
+ g_free (curi);
+
+ } else {
+ g_warning ("Email URI's must include a uid parameter");
+ camel_url_free (url);
+ }
+ } else
+ handled = FALSE;
+
+ return handled;
+}
+
+/* Helper for mail_shell_backend_prepare_for_[off|on]line_cb() */
+static void
+mail_shell_store_line_transition_done_cb (CamelStore *store,
+ gpointer user_data)
+{
+ EActivity *activity = user_data;
+
+ g_object_unref (activity);
+}
+
+/* Helper for mail_shell_backend_prepare_for_offline_cb() */
+static void
+mail_shell_store_prepare_for_offline_cb (CamelService *service,
+ gpointer unused,
+ EActivity *activity)
+{
+ if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
+ mail_store_set_offline (
+ CAMEL_STORE (service), TRUE,
+ mail_shell_store_line_transition_done_cb,
+ g_object_ref (activity));
+}
+
+static void
+mail_shell_backend_prepare_for_offline_cb (EShell *shell,
+ EActivity *activity,
+ EMailShellBackend *mail_shell_backend)
+{
+ GList *watched_windows;
+ GtkWidget *parent = NULL;
+ gboolean synchronize = FALSE;
+
+ watched_windows = e_shell_get_watched_windows (shell);
+ if (watched_windows != NULL)
+ parent = GTK_WIDGET (watched_windows->data);
+
+ if (e_shell_get_network_available (shell))
+ synchronize = em_utils_prompt_user (
+ GTK_WINDOW (parent),
+ "/apps/evolution/mail/prompts/quick_offline",
+ "mail:ask-quick-offline", NULL);
+
+ if (!synchronize) {
+ mail_cancel_all ();
+ camel_session_set_network_state (session, FALSE);
+ }
+
+ e_mail_store_foreach (
+ (GHFunc) mail_shell_store_prepare_for_offline_cb, activity);
+}
+
+/* Helper for mail_shell_backend_prepare_for_online_cb() */
+static void
+mail_shell_store_prepare_for_online_cb (CamelService *service,
+ gpointer unused,
+ EActivity *activity)
+{
+ if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
+ mail_store_set_offline (
+ CAMEL_STORE (service), FALSE,
+ mail_shell_store_line_transition_done_cb,
+ g_object_ref (activity));
+}
+
+static void
+mail_shell_backend_prepare_for_online_cb (EShell *shell,
+ EActivity *activity,
+ EMailShellBackend *mail_shell_backend)
+{
+ camel_session_set_online (session, TRUE);
+
+ e_mail_store_foreach (
+ (GHFunc) mail_shell_store_prepare_for_online_cb, activity);
+}
+
+/* Helper for mail_shell_backend_prepare_for_quit_cb() */
+static void
+mail_shell_backend_empty_junk (CamelStore *store,
+ gpointer opaque_store_info,
+ EMailShellBackend *mail_shell_backend)
+{
+ CamelFolder *folder;
+ GPtrArray *uids;
+ guint32 flags;
+ guint32 mask;
+ guint ii;
+
+ folder = camel_store_get_junk (store, NULL);
+ if (folder == NULL)
+ return;
+
+ uids = camel_folder_get_uids (folder);
+ flags = mask = CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN;
+
+ camel_folder_freeze (folder);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ const gchar *uid = uids->pdata[ii];
+ camel_folder_set_message_flags (folder, uid, flags, mask);
+ }
+
+ camel_folder_thaw (folder);
+
+ camel_folder_free_uids (folder, uids);
+}
+
+/* Helper for mail_shell_backend_final_sync() */
+static void
+mail_shell_backend_final_sync_done_cb (CamelStore *store,
+ gpointer user_data)
+{
+ g_object_unref (E_ACTIVITY (user_data));
+}
+
+/* Helper for mail_shell_backend_prepare_for_quit_cb() */
+static void
+mail_shell_backend_final_sync (CamelStore *store,
+ gpointer opaque_store_info,
+ gpointer user_data)
+{
+ struct {
+ EActivity *activity;
+ gboolean empty_trash;
+ } *sync_data = user_data;
+
+ /* Reffing the activity delays quitting; the reference count
+ * acts like a counting semaphore. */
+ mail_sync_store (
+ store, sync_data->empty_trash,
+ mail_shell_backend_final_sync_done_cb,
+ g_object_ref (sync_data->activity));
+}
+
+/* Helper for mail_shell_backend_prepare_for_quit_cb() */
+static gboolean
+mail_shell_backend_poll_to_quit (EActivity *activity)
+{
+ return mail_msg_active ((guint) -1);
+}
+
+/* Helper for mail_shell_backend_prepare_for_quit_cb() */
+static void
+mail_shell_backend_ready_to_quit (EActivity *activity)
+{
+ mail_session_shutdown ();
+ g_object_unref (activity);
+}
+
+static void
+mail_shell_backend_prepare_for_quit_cb (EShell *shell,
+ EActivity *activity,
+ EMailShellBackend *mail_shell_backend)
+{
+ EShellSettings *shell_settings;
+ EAccountList *account_list;
+ GConfClient *client;
+ const gchar *key;
+ gboolean empty_junk;
+ gboolean empty_trash;
+ gint empty_date;
+ gint empty_days;
+ gint now;
+ GError *error = NULL;
+
+ struct {
+ EActivity *activity;
+ gboolean empty_trash;
+ } sync_data;
+
+ client = e_shell_get_gconf_client (shell);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ camel_application_is_exiting = TRUE;
+ now = time (NULL) / 60 / 60 / 24;
+
+ account_list = e_get_account_list ();
+ e_account_list_prune_proxies (account_list);
+
+ mail_vfolder_shutdown ();
+
+ empty_junk = e_shell_settings_get_boolean (
+ shell_settings, "mail-empty-junk-on-exit");
+
+ empty_trash = e_shell_settings_get_boolean (
+ shell_settings, "mail-empty-trash-on-exit");
+
+ /* XXX No EShellSettings properties for these keys. */
+
+ empty_date = empty_days = 0;
+
+ if (empty_junk) {
+ key = "/apps/evolution/mail/junk/empty_on_exit_days";
+ empty_days = gconf_client_get_int (client, key, &error);
+ if (error == NULL) {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ empty_trash = FALSE;
+ }
+ }
+
+ if (empty_junk) {
+ key = "/apps/evolution/mail/junk/empty_date";
+ empty_date = gconf_client_get_int (client, key, &error);
+ if (error == NULL) {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ empty_trash = FALSE;
+ }
+ }
+
+ empty_junk &= (empty_days = 0) || (empty_date + empty_days <= now);
+
+ if (empty_junk) {
+ e_mail_store_foreach (
+ (GHFunc) mail_shell_backend_empty_junk,
+ mail_shell_backend);
+
+ key = "/apps/evolution/mail/junk/empty_date";
+ gconf_client_set_int (client, key, now, NULL);
+ }
+
+ empty_date = empty_days = 0;
+
+ if (empty_trash) {
+ key = "/apps/evolution/mail/trash/empty_on_exit_days";
+ empty_days = gconf_client_get_int (client, key, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ empty_trash = FALSE;
+ }
+ }
+
+ if (empty_trash) {
+ key = "/apps/evolution/mail/trash/empty_date";
+ empty_date = gconf_client_get_int (client, key, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ empty_trash = FALSE;
+ }
+ }
+
+ empty_trash &= (empty_days == 0) || (empty_date + empty_days <= now);
+
+ sync_data.activity = activity;
+ sync_data.empty_trash = empty_trash;
+
+ e_mail_store_foreach (
+ (GHFunc) mail_shell_backend_final_sync, &sync_data);
+
+ if (empty_trash) {
+ key = "/apps/evolution/mail/trash/empty_date";
+ gconf_client_set_int (client, key, now, NULL);
+ }
+
+ /* Cancel all activities. */
+ mail_cancel_all ();
+
+ /* Now we poll until all activities are actually cancelled.
+ * Reffing the activity delays quitting; the reference count
+ * acts like a counting semaphore. */
+ if (mail_msg_active ((guint) -1))
+ g_timeout_add_seconds_full (
+ G_PRIORITY_DEFAULT, QUIT_POLL_INTERVAL,
+ (GSourceFunc) mail_shell_backend_poll_to_quit,
+ g_object_ref (activity),
+ (GDestroyNotify) mail_shell_backend_ready_to_quit);
+ else
+ mail_shell_backend_ready_to_quit (g_object_ref (activity));
+}
+
+static void
+mail_shell_backend_quit_requested_cb (EShell *shell,
+ EShellBackend *shell_backend)
+{
+ CamelFolder *folder;
+ GList *watched_windows;
+ GtkWindow *parent = NULL;
+ guint32 unsent;
+ gint response;
+
+ /* We can quit immediately if offline. */
+ if (!camel_session_is_online (session))
+ return;
+
+ /* Check Outbox for any unsent messages. */
+
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ if (folder == NULL)
+ return;
+
+ if (camel_object_get (
+ folder, NULL, CAMEL_FOLDER_VISIBLE, &unsent, 0) != 0)
+ return;
+
+ if (unsent == 0)
+ return;
+
+ /* Try to find a parent window for the dialog.
+ * First list item is what's currently focused. */
+ watched_windows = e_shell_get_watched_windows (shell);
+ if (watched_windows != NULL)
+ parent = GTK_WINDOW (watched_windows->data);
+ response = e_error_run (parent, "mail:exit-unsaved", NULL);
+
+ if (response == GTK_RESPONSE_YES)
+ return;
+
+ e_shell_cancel_quit (shell);
+}
+
+static void
+mail_shell_backend_send_receive_cb (EShell *shell,
+ GtkWindow *parent,
+ EShellBackend *shell_backend)
+{
+ em_utils_clear_get_password_canceled_accounts_flag ();
+ mail_send_receive (parent);
+}
+
+static void
+mail_shell_backend_window_weak_notify_cb (EShell *shell,
+ GObject *where_the_object_was)
+{
+ g_signal_handlers_disconnect_by_func (
+ shell, mail_shell_backend_mail_icon_cb,
+ where_the_object_was);
+}
+
+static void
+mail_shell_backend_window_created_cb (EShell *shell,
+ GtkWindow *window,
+ EShellBackend *shell_backend)
+{
+ EShellSettings *shell_settings;
+ static gboolean first_time = TRUE;
+ const gchar *backend_name;
+
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ /* This applies to both the composer and signature editor. */
+ if (GTKHTML_IS_EDITOR (window)) {
+ GList *spell_languages;
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "composer-inline-spelling",
+ G_OBJECT (window), "inline-spelling");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "composer-magic-links",
+ G_OBJECT (window), "magic-links");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "composer-magic-smileys",
+ G_OBJECT (window), "magic-smileys");
+
+ spell_languages = e_load_spell_languages ();
+ gtkhtml_editor_set_spell_languages (
+ GTKHTML_EDITOR (window), spell_languages);
+ g_list_free (spell_languages);
+ }
+
+ if (E_IS_MSG_COMPOSER (window)) {
+ /* Integrate the new composer into the mail module. */
+ em_configure_new_composer (E_MSG_COMPOSER (window));
+ return;
+ }
+
+ if (!E_IS_SHELL_WINDOW (window))
+ return;
+
+ backend_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ e_shell_window_register_new_item_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ item_entries, G_N_ELEMENTS (item_entries));
+
+ e_shell_window_register_new_source_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ source_entries, G_N_ELEMENTS (source_entries));
+
+ g_signal_connect_swapped (
+ shell, "event::mail-icon",
+ G_CALLBACK (mail_shell_backend_mail_icon_cb), window);
+
+ g_object_weak_ref (
+ G_OBJECT (window), (GWeakNotify)
+ mail_shell_backend_window_weak_notify_cb, shell);
+
+ if (first_time) {
+ g_signal_connect (
+ window, "map-event",
+ G_CALLBACK (e_msg_composer_check_autosave), NULL);
+ first_time = FALSE;
+ }
+}
+
+static void
+mail_shell_backend_constructed (GObject *object)
+{
+ EMailShellBackendPrivate *priv;
+ EShell *shell;
+ EShellBackend *shell_backend;
+ const gchar *data_dir;
+
+ priv = E_MAIL_SHELL_BACKEND_GET_PRIVATE (object);
+
+ shell_backend = E_SHELL_BACKEND (object);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ /* This also initializes Camel, so it needs to happen early. */
+ mail_session_init (shell_backend);
+
+ /* Register format types for EMFormatHook. */
+ em_format_hook_register_type (em_format_get_type ());
+ em_format_hook_register_type (em_format_html_get_type ());
+ em_format_hook_register_type (em_format_html_display_get_type ());
+
+ /* Register plugin hook types. */
+ em_format_hook_get_type ();
+
+ mail_shell_backend_init_importers ();
+
+ g_signal_connect (
+ shell, "notify::online",
+ G_CALLBACK (mail_shell_backend_notify_online_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "handle-uri",
+ G_CALLBACK (mail_shell_backend_handle_uri_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "prepare-for-offline",
+ G_CALLBACK (mail_shell_backend_prepare_for_offline_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "prepare-for-online",
+ G_CALLBACK (mail_shell_backend_prepare_for_online_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "prepare-for-quit",
+ G_CALLBACK (mail_shell_backend_prepare_for_quit_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "quit-requested",
+ G_CALLBACK (mail_shell_backend_quit_requested_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "send-receive",
+ G_CALLBACK (mail_shell_backend_send_receive_cb),
+ shell_backend);
+
+ g_signal_connect (
+ shell, "window-created",
+ G_CALLBACK (mail_shell_backend_window_created_cb),
+ shell_backend);
+
+ mail_config_init ();
+ mail_msg_init ();
+
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ e_mail_store_init (data_dir);
+
+ /* Initialize settings before initializing preferences,
+ * since the preferences bind to the shell settings. */
+ e_mail_shell_settings_init (shell);
+ mail_shell_backend_init_preferences (shell);
+}
+
+static void
+mail_shell_backend_start (EShellBackend *shell_backend)
+{
+ EMailShellBackendPrivate *priv;
+ EShell *shell;
+ EShellSettings *shell_settings;
+ gboolean enable_search_folders;
+
+ priv = E_MAIL_SHELL_BACKEND_GET_PRIVATE (shell_backend);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ /* XXX Do we really still need this flag? */
+ mail_session_set_interactive (TRUE);
+
+ enable_search_folders = e_shell_settings_get_boolean (
+ shell_settings, "mail-enable-search-folders");
+ if (enable_search_folders)
+ vfolder_load_storage ();
+
+ mail_autoreceive_init (shell_backend, session);
+
+ if (g_getenv ("CAMEL_FLUSH_CHANGES") != NULL)
+ priv->mail_sync_timeout_source_id = g_timeout_add_seconds (
+ mail_config_get_sync_timeout (),
+ (GSourceFunc) mail_shell_backend_mail_sync,
+ shell_backend);
+}
+
+static void
+mail_shell_backend_class_init (EMailShellBackendClass *class)
+{
+ GObjectClass *object_class;
+ EShellBackendClass *shell_backend_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = mail_shell_backend_constructed;
+
+ shell_backend_class = E_SHELL_BACKEND_CLASS (class);
+ shell_backend_class->shell_view_type = E_TYPE_MAIL_SHELL_VIEW;
+ shell_backend_class->name = BACKEND_NAME;
+ shell_backend_class->aliases = "";
+ shell_backend_class->schemes = "mailto:email";
+ shell_backend_class->sort_order = 200;
+ shell_backend_class->start = mail_shell_backend_start;
+ shell_backend_class->migrate = e_mail_shell_migrate;
+}
+
+static void
+mail_shell_backend_init (EMailShellBackend *mail_shell_backend)
+{
+ mail_shell_backend->priv =
+ E_MAIL_SHELL_BACKEND_GET_PRIVATE (mail_shell_backend);
+}
+
+GType
+e_mail_shell_backend_get_type (void)
+{
+ return mail_shell_backend_type;
+}
+
+void
+e_mail_shell_backend_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EMailShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_shell_backend_init,
+ NULL /* value_table */
+ };
+
+ mail_shell_backend_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_BACKEND,
+ "EMailShellBackend", &type_info, 0);
+}
+
+/******************* Code below here belongs elsewhere. *******************/
+
+#include "filter/filter-option.h"
+#include "shell/e-shell-settings.h"
+#include "mail/e-mail-label-list-store.h"
+
+GSList *
+e_mail_labels_get_filter_options (void)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ EMailLabelListStore *list_store;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GSList *list = NULL;
+ gboolean valid;
+
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+ list_store = e_shell_settings_get_object (
+ shell_settings, "mail-label-list-store");
+
+ model = GTK_TREE_MODEL (list_store);
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+
+ while (valid) {
+ struct _filter_option *option;
+ gchar *name, *tag;
+
+ name = e_mail_label_list_store_get_name (list_store, &iter);
+ tag = e_mail_label_list_store_get_tag (list_store, &iter);
+
+ option = g_new0 (struct _filter_option, 1);
+ option->title = e_str_without_underscores (name);
+ option->value = tag; /* takes ownership */
+
+ g_free (name);
+
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
+
+ g_object_unref (list_store);
+
+ return list;
+}
diff --git a/modules/mail/e-mail-shell-backend.h b/modules/mail/e-mail-shell-backend.h
new file mode 100644
index 0000000000..73ef10e75b
--- /dev/null
+++ b/modules/mail/e-mail-shell-backend.h
@@ -0,0 +1,75 @@
+/*
+ * e-mail-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_SHELL_BACKEND_H
+#define E_MAIL_SHELL_BACKEND_H
+
+#include <shell/e-shell-backend.h>
+
+#include <camel/camel-folder.h>
+#include <camel/camel-store.h>
+#include <e-util/e-signature-list.h>
+#include <libedataserver/e-account-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_SHELL_BACKEND \
+ (e_mail_shell_backend_get_type ())
+#define E_MAIL_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_SHELL_BACKEND, EMailShellBackend))
+#define E_MAIL_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_SHELL_BACKEND, EMailShellBackendClass))
+#define E_IS_MAIL_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_SHELL_BACKEND))
+#define E_IS_MAIL_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_SHELL_BACKEND))
+#define E_MAIL_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_SHELL_BACKEND, EMailShellBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailShellBackend EMailShellBackend;
+typedef struct _EMailShellBackendClass EMailShellBackendClass;
+typedef struct _EMailShellBackendPrivate EMailShellBackendPrivate;
+
+struct _EMailShellBackend {
+ EShellBackend parent;
+ EMailShellBackendPrivate *priv;
+};
+
+struct _EMailShellBackendClass {
+ EShellBackendClass parent_class;
+};
+
+GType e_mail_shell_backend_get_type (void);
+void e_mail_shell_backend_register_type
+ (GTypeModule *type_module);
+
+/* XXX Find a better place for this function. */
+GSList * e_mail_labels_get_filter_options(void);
+
+G_END_DECLS
+
+#endif /* E_MAIL_SHELL_BACKEND_H */
diff --git a/modules/mail/e-mail-shell-content.c b/modules/mail/e-mail-shell-content.c
new file mode 100644
index 0000000000..20c9df7a29
--- /dev/null
+++ b/modules/mail/e-mail-shell-content.c
@@ -0,0 +1,1029 @@
+/*
+ * e-mail-shell-content.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-shell-content.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-store.h>
+#include <libedataserver/e-data-server-util.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/gconf-bridge.h"
+#include "widgets/menus/gal-view-etable.h"
+#include "widgets/menus/gal-view-instance.h"
+#include "widgets/misc/e-paned.h"
+
+#include "em-search-context.h"
+#include "em-utils.h"
+#include "mail-config.h"
+#include "mail-ops.h"
+
+#include "e-mail-reader.h"
+#include "e-mail-search-bar.h"
+#include "e-mail-shell-backend.h"
+#include "e-mail-shell-view-actions.h"
+
+#define E_MAIL_SHELL_CONTENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_SHELL_CONTENT, EMailShellContentPrivate))
+
+#define STATE_KEY_SCROLLBAR_POSITION "ScrollbarPosition"
+#define STATE_KEY_SELECTED_MESSAGE "SelectedMessage"
+
+struct _EMailShellContentPrivate {
+ GtkWidget *paned;
+ GtkWidget *message_list;
+ GtkWidget *search_bar;
+
+ EMFormatHTMLDisplay *html_display;
+ GalViewInstance *view_instance;
+ GtkOrientation orientation;
+
+ /* ETable scrolling hack */
+ gdouble default_scrollbar_position;
+
+ guint paned_binding_id;
+ guint scroll_timeout_id;
+
+ /* Signal handler IDs */
+ guint message_list_built_id;
+ guint message_list_scrolled_id;
+
+ guint preview_visible : 1;
+ guint suppress_message_selection : 1;
+ guint show_deleted : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_ORIENTATION,
+ PROP_PREVIEW_VISIBLE,
+ PROP_SHOW_DELETED
+};
+
+static gpointer parent_class;
+static GType mail_shell_content_type;
+
+static void
+mail_shell_content_etree_unfreeze (MessageList *message_list,
+ GdkEvent *event)
+{
+ ETableItem *item;
+ GObject *object;
+
+ item = e_tree_get_item (message_list->tree);
+ object = G_OBJECT (((GnomeCanvasItem *) item)->canvas);
+
+ g_object_set_data (object, "freeze-cursor", 0);
+}
+
+static void
+mail_shell_content_message_list_scrolled_cb (EMailShellContent *mail_shell_content,
+ MessageList *message_list)
+{
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ GKeyFile *key_file;
+ const gchar *folder_uri;
+ const gchar *key;
+ gchar *group_name;
+ gdouble position;
+
+ /* Save the scrollbar position for the current folder. */
+
+ folder_uri = message_list->folder_uri;
+
+ if (folder_uri == NULL)
+ return;
+
+ shell_content = E_SHELL_CONTENT (mail_shell_content);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ key = STATE_KEY_SCROLLBAR_POSITION;
+ group_name = g_strdup_printf ("Folder %s", folder_uri);
+ position = message_list_get_scrollbar_position (message_list);
+
+ g_key_file_set_double (key_file, group_name, key, position);
+ e_shell_view_set_state_dirty (shell_view);
+
+ g_free (group_name);
+}
+
+static gboolean
+mail_shell_content_scroll_timeout_cb (EMailShellContent *mail_shell_content)
+{
+ EMailShellContentPrivate *priv = mail_shell_content->priv;
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ MessageList *message_list;
+ EMailReader *reader;
+ GKeyFile *key_file;
+ const gchar *folder_uri;
+ const gchar *key;
+ gchar *group_name;
+
+ /* Initialize the scrollbar position for the current folder
+ * and setup a callback to handle scrollbar position changes. */
+
+ shell_content = E_SHELL_CONTENT (mail_shell_content);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ reader = E_MAIL_READER (mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder_uri = message_list->folder_uri;
+
+ if (folder_uri == NULL)
+ goto skip;
+
+ /* Restore the message list scrollbar position. */
+
+ key = STATE_KEY_SCROLLBAR_POSITION;
+ group_name = g_strdup_printf ("Folder %s", folder_uri);
+
+ if (g_key_file_has_key (key_file, group_name, key, NULL)) {
+ gdouble position;
+
+ position = g_key_file_get_double (
+ key_file, group_name, key, NULL);
+ message_list_set_scrollbar_position (message_list, position);
+ }
+
+ g_free (group_name);
+
+skip:
+ priv->message_list_scrolled_id = g_signal_connect_swapped (
+ message_list, "message-list-scrolled",
+ G_CALLBACK (mail_shell_content_message_list_scrolled_cb),
+ mail_shell_content);
+
+ priv->scroll_timeout_id = 0;
+
+ return FALSE;
+}
+
+static void
+mail_shell_content_message_list_built_cb (EMailShellContent *mail_shell_content,
+ MessageList *message_list)
+{
+ EMailShellContentPrivate *priv = mail_shell_content->priv;
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ GtkScrolledWindow *scrolled_window;
+ GtkWidget *vscrollbar;
+ GKeyFile *key_file;
+ gchar *uid;
+
+ g_signal_handler_disconnect (
+ message_list, priv->message_list_built_id);
+ priv->message_list_built_id = 0;
+
+ shell_content = E_SHELL_CONTENT (mail_shell_content);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ if (message_list->cursor_uid != NULL)
+ uid = NULL;
+
+ else if (message_list->folder_uri == NULL)
+ uid = NULL;
+
+ else if (mail_shell_content->priv->suppress_message_selection)
+ uid = NULL;
+
+ else {
+ const gchar *folder_uri;
+ const gchar *key;
+ gchar *group_name;
+
+ key = STATE_KEY_SELECTED_MESSAGE;
+ folder_uri = message_list->folder_uri;
+ group_name = g_strdup_printf ("Folder %s", folder_uri);
+ uid = g_key_file_get_string (key_file, group_name, key, NULL);
+ g_free (group_name);
+ }
+
+ if (uid != NULL) {
+ CamelFolder *folder;
+ CamelMessageInfo *info;
+
+ folder = message_list->folder;
+ info = camel_folder_get_message_info (folder, uid);
+ if (info != NULL) {
+ EMailReader *reader;
+
+ reader = E_MAIL_READER (mail_shell_content);
+ e_mail_reader_set_message (reader, uid);
+ camel_folder_free_message_info (folder, info);
+ }
+
+ g_free (uid);
+ }
+
+ /* FIXME This is a gross workaround for an ETable bug that I can't
+ * fix (Ximian bug #55303).
+ *
+ * Since e_canvas_item_region_show_relay() uses a timeout,
+ * we have to use a timeout of the same interval but a lower
+ * priority. */
+ priv->scroll_timeout_id = g_timeout_add_full (
+ G_PRIORITY_LOW, 250, (GSourceFunc)
+ mail_shell_content_scroll_timeout_cb,
+ mail_shell_content, NULL);
+
+ /* FIXME This is another ugly hack to hide a side-effect of the
+ * previous workaround. */
+ scrolled_window = GTK_SCROLLED_WINDOW (message_list);
+ vscrollbar = gtk_scrolled_window_get_vscrollbar (scrolled_window);
+ g_signal_connect_swapped (
+ vscrollbar, "button-press-event",
+ G_CALLBACK (mail_shell_content_etree_unfreeze),
+ message_list);
+}
+
+static void
+mail_shell_content_display_view_cb (EMailShellContent *mail_shell_content,
+ GalView *gal_view)
+{
+ EMailReader *reader;
+ MessageList *message_list;
+
+ reader = E_MAIL_READER (mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ if (GAL_IS_VIEW_ETABLE (gal_view))
+ gal_view_etable_attach_tree (
+ GAL_VIEW_ETABLE (gal_view), message_list->tree);
+}
+
+static void
+mail_shell_content_message_selected_cb (EMailShellContent *mail_shell_content,
+ const gchar *message_uid,
+ MessageList *message_list)
+{
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ GKeyFile *key_file;
+ const gchar *folder_uri;
+ const gchar *key;
+ gchar *group_name;
+
+ folder_uri = message_list->folder_uri;
+
+ /* This also gets triggered when selecting a store name on
+ * the sidebar such as "On This Computer", in which case
+ * 'folder_uri' will be NULL. */
+ if (folder_uri == NULL)
+ return;
+
+ shell_content = E_SHELL_CONTENT (mail_shell_content);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ key = STATE_KEY_SELECTED_MESSAGE;
+ group_name = g_strdup_printf ("Folder %s", folder_uri);
+
+ if (message_uid != NULL)
+ g_key_file_set_string (key_file, group_name, key, message_uid);
+ else
+ g_key_file_remove_key (key_file, group_name, key, NULL);
+ e_shell_view_set_state_dirty (shell_view);
+
+ g_free (group_name);
+}
+
+static GtkOrientation
+mail_shell_content_get_orientation (EMailShellContent *mail_shell_content)
+{
+ return mail_shell_content->priv->orientation;
+}
+
+static void
+mail_shell_content_set_orientation (EMailShellContent *mail_shell_content,
+ GtkOrientation orientation)
+{
+ mail_shell_content->priv->orientation = orientation;
+
+ g_object_notify (G_OBJECT (mail_shell_content), "orientation");
+
+ e_mail_shell_content_update_view_instance (mail_shell_content);
+}
+
+static void
+mail_shell_content_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ORIENTATION:
+ mail_shell_content_set_orientation (
+ E_MAIL_SHELL_CONTENT (object),
+ g_value_get_enum (value));
+ return;
+
+ case PROP_PREVIEW_VISIBLE:
+ e_mail_shell_content_set_preview_visible (
+ E_MAIL_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SHOW_DELETED:
+ e_mail_shell_content_set_show_deleted (
+ E_MAIL_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_shell_content_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ORIENTATION:
+ g_value_set_enum (
+ value,
+ mail_shell_content_get_orientation (
+ E_MAIL_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_PREVIEW_VISIBLE:
+ g_value_set_boolean (
+ value,
+ e_mail_shell_content_get_preview_visible (
+ E_MAIL_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SHOW_DELETED:
+ g_value_set_boolean (
+ value,
+ e_mail_shell_content_get_show_deleted (
+ E_MAIL_SHELL_CONTENT (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_shell_content_dispose (GObject *object)
+{
+ EMailShellContentPrivate *priv;
+
+ priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (object);
+
+ if (priv->paned != NULL) {
+ g_object_unref (priv->paned);
+ priv->paned = NULL;
+ }
+
+ if (priv->message_list != NULL) {
+ g_object_unref (priv->message_list);
+ priv->message_list = NULL;
+ }
+
+ if (priv->search_bar != NULL) {
+ g_object_unref (priv->search_bar);
+ priv->search_bar = NULL;
+ }
+
+ if (priv->html_display != NULL) {
+ g_object_unref (priv->html_display);
+ priv->html_display = NULL;
+ }
+
+ if (priv->view_instance != NULL) {
+ g_object_unref (priv->view_instance);
+ priv->view_instance = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_shell_content_constructed (GObject *object)
+{
+ EMailShellContentPrivate *priv;
+ EShellContent *shell_content;
+ EShellBackend *shell_backend;
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ EMailReader *reader;
+ MessageList *message_list;
+ GConfBridge *bridge;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GtkHTML *html;
+ GalViewCollection *view_collection;
+ const gchar *key;
+
+ priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (object);
+ priv->html_display = em_format_html_display_new ();
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_content = E_SHELL_CONTENT (object);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ view_collection = shell_view_class->view_collection;
+
+ html = EM_FORMAT_HTML (priv->html_display)->html;
+
+ /* Build content widgets. */
+
+ container = GTK_WIDGET (object);
+
+ widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->paned = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (object), "orientation",
+ G_OBJECT (widget), "orientation");
+
+ container = widget;
+
+ widget = message_list_new (shell_backend);
+ gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
+ priv->message_list = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_vbox_new (FALSE, 1);
+ gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (object), "preview-visible",
+ G_OBJECT (widget), "visible");
+
+ container = widget;
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (html));
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ gtk_widget_show (GTK_WIDGET (html));
+ gtk_widget_show (widget);
+
+ widget = e_mail_search_bar_new (html);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->search_bar = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (em_format_redraw), priv->html_display);
+
+ /* Load the view instance. */
+
+ e_mail_shell_content_update_view_instance (
+ E_MAIL_SHELL_CONTENT (shell_content));
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/mail/display/hpaned_size";
+ gconf_bridge_bind_property (bridge, key, object, "hposition");
+
+ object = G_OBJECT (priv->paned);
+ key = "/apps/evolution/mail/display/paned_size";
+ gconf_bridge_bind_property (bridge, key, object, "vposition");
+
+ object = G_OBJECT (shell_content);
+ key = "/apps/evolution/mail/display/show_deleted";
+ gconf_bridge_bind_property (bridge, key, object, "show-deleted");
+
+ /* Message list customizations. */
+
+ reader = E_MAIL_READER (shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ g_signal_connect_swapped (
+ message_list, "message-selected",
+ G_CALLBACK (mail_shell_content_message_selected_cb),
+ shell_content);
+}
+
+static guint32
+mail_shell_content_check_state (EShellContent *shell_content)
+{
+ return e_mail_reader_check_state (E_MAIL_READER (shell_content));
+}
+
+static GtkActionGroup *
+mail_shell_content_get_action_group (EMailReader *reader)
+{
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+
+ shell_content = E_SHELL_CONTENT (reader);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ return E_SHELL_WINDOW_ACTION_GROUP_MAIL (shell_window);
+}
+
+static gboolean
+mail_shell_content_get_hide_deleted (EMailReader *reader)
+{
+ EMailShellContent *mail_shell_content;
+
+ mail_shell_content = E_MAIL_SHELL_CONTENT (reader);
+
+ return !e_mail_shell_content_get_show_deleted (mail_shell_content);
+}
+
+static EMFormatHTMLDisplay *
+mail_shell_content_get_html_display (EMailReader *reader)
+{
+ EMailShellContentPrivate *priv;
+
+ priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (reader);
+
+ return priv->html_display;
+}
+
+static MessageList *
+mail_shell_content_get_message_list (EMailReader *reader)
+{
+ EMailShellContentPrivate *priv;
+
+ priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (reader);
+
+ return MESSAGE_LIST (priv->message_list);
+}
+
+static EShellBackend *
+mail_shell_content_get_shell_backend (EMailReader *reader)
+{
+ EShellContent *shell_content;
+ EShellView *shell_view;
+
+ shell_content = E_SHELL_CONTENT (reader);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+
+ return e_shell_view_get_shell_backend (shell_view);
+}
+
+static GtkWindow *
+mail_shell_content_get_window (EMailReader *reader)
+{
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+
+ shell_content = E_SHELL_CONTENT (reader);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ return GTK_WINDOW (shell_window);
+}
+
+static void
+mail_shell_content_set_folder (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri)
+{
+ EMailShellContentPrivate *priv;
+ EMailReaderIface *default_iface;
+ MessageList *message_list;
+ gboolean different_folder;
+
+ priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (reader);
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ message_list_freeze (message_list);
+
+ different_folder =
+ message_list->folder != NULL &&
+ folder != message_list->folder;
+
+ /* Chain up to interface's default set_folder() method. */
+ default_iface = g_type_default_interface_peek (E_TYPE_MAIL_READER);
+ default_iface->set_folder (reader, folder, folder_uri);
+
+ if (folder == NULL)
+ goto exit;
+
+ mail_refresh_folder (folder, NULL, NULL);
+
+ /* This function gets triggered several times at startup,
+ * so we don't want to reset the message suppression state
+ * unless we're actually switching to a different folder. */
+ if (different_folder)
+ priv->suppress_message_selection = FALSE;
+
+ /* This is a one-time-only callback. */
+ if (message_list->cursor_uid == NULL && priv->message_list_built_id == 0)
+ priv->message_list_built_id = g_signal_connect_swapped (
+ message_list, "message-list-built",
+ G_CALLBACK (mail_shell_content_message_list_built_cb),
+ reader);
+
+exit:
+ message_list_thaw (message_list);
+}
+
+static void
+mail_shell_content_show_search_bar (EMailReader *reader)
+{
+ EMailShellContentPrivate *priv;
+
+ priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (reader);
+
+ gtk_widget_show (priv->search_bar);
+}
+
+static void
+mail_shell_content_class_init (EMailShellContentClass *class)
+{
+ GObjectClass *object_class;
+ EShellContentClass *shell_content_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailShellContentPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_shell_content_set_property;
+ object_class->get_property = mail_shell_content_get_property;
+ object_class->dispose = mail_shell_content_dispose;
+ object_class->constructed = mail_shell_content_constructed;
+
+ shell_content_class = E_SHELL_CONTENT_CLASS (class);
+ shell_content_class->new_search_context = em_search_context_new;
+ shell_content_class->check_state = mail_shell_content_check_state;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PREVIEW_VISIBLE,
+ g_param_spec_boolean (
+ "preview-visible",
+ _("Preview is Visible"),
+ _("Whether the preview pane is visible"),
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_DELETED,
+ g_param_spec_boolean (
+ "show-deleted",
+ "Show Deleted",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_override_property (
+ object_class, PROP_ORIENTATION, "orientation");
+}
+
+static void
+mail_shell_content_reader_init (EMailReaderIface *iface)
+{
+ iface->get_action_group = mail_shell_content_get_action_group;
+ iface->get_hide_deleted = mail_shell_content_get_hide_deleted;
+ iface->get_html_display = mail_shell_content_get_html_display;
+ iface->get_message_list = mail_shell_content_get_message_list;
+ iface->get_shell_backend = mail_shell_content_get_shell_backend;
+ iface->get_window = mail_shell_content_get_window;
+ iface->set_folder = mail_shell_content_set_folder;
+ iface->show_search_bar = mail_shell_content_show_search_bar;
+}
+
+static void
+mail_shell_content_init (EMailShellContent *mail_shell_content)
+{
+ mail_shell_content->priv =
+ E_MAIL_SHELL_CONTENT_GET_PRIVATE (mail_shell_content);
+
+ mail_shell_content->priv->preview_visible = TRUE;
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_mail_shell_content_get_type (void)
+{
+ return mail_shell_content_type;
+}
+
+void
+e_mail_shell_content_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EMailShellContentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_shell_content_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailShellContent),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_shell_content_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo orientable_info = {
+ (GInterfaceInitFunc) NULL,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ static const GInterfaceInfo reader_info = {
+ (GInterfaceInitFunc) mail_shell_content_reader_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ mail_shell_content_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_CONTENT,
+ "EMailShellContent", &type_info, 0);
+
+ g_type_module_add_interface (
+ type_module, mail_shell_content_type,
+ GTK_TYPE_ORIENTABLE, &orientable_info);
+
+ g_type_module_add_interface (
+ type_module, mail_shell_content_type,
+ E_TYPE_MAIL_READER, &reader_info);
+}
+
+GtkWidget *
+e_mail_shell_content_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_SHELL_CONTENT,
+ "shell-view", shell_view, NULL);
+}
+
+gboolean
+e_mail_shell_content_get_preview_visible (EMailShellContent *mail_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_MAIL_SHELL_CONTENT (mail_shell_content), FALSE);
+
+ return mail_shell_content->priv->preview_visible;
+}
+
+void
+e_mail_shell_content_set_preview_visible (EMailShellContent *mail_shell_content,
+ gboolean preview_visible)
+{
+ g_return_if_fail (E_IS_MAIL_SHELL_CONTENT (mail_shell_content));
+
+ if (preview_visible == mail_shell_content->priv->preview_visible)
+ return;
+
+ /* If we're showing the preview, tell EMailReader to reload the
+ * selected message. This should force it to download the full
+ * message if necessary, so we don't get an empty preview. */
+ if (preview_visible) {
+ EMailReader *reader;
+ MessageList *message_list;
+
+ reader = E_MAIL_READER (mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ e_mail_reader_set_message (reader, message_list->cursor_uid);
+ }
+
+ mail_shell_content->priv->preview_visible = preview_visible;
+
+ g_object_notify (G_OBJECT (mail_shell_content), "preview-visible");
+}
+
+gboolean
+e_mail_shell_content_get_show_deleted (EMailShellContent *mail_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_MAIL_SHELL_CONTENT (mail_shell_content), FALSE);
+
+ return mail_shell_content->priv->show_deleted;
+}
+
+void
+e_mail_shell_content_set_show_deleted (EMailShellContent *mail_shell_content,
+ gboolean show_deleted)
+{
+ g_return_if_fail (E_IS_MAIL_SHELL_CONTENT (mail_shell_content));
+
+ mail_shell_content->priv->show_deleted = show_deleted;
+
+ g_object_notify (G_OBJECT (mail_shell_content), "show-deleted");
+}
+
+GalViewInstance *
+e_mail_shell_content_get_view_instance (EMailShellContent *mail_shell_content)
+{
+ g_return_val_if_fail (
+ E_IS_MAIL_SHELL_CONTENT (mail_shell_content), NULL);
+
+ return mail_shell_content->priv->view_instance;
+}
+
+void
+e_mail_shell_content_set_search_strings (EMailShellContent *mail_shell_content,
+ GSList *search_strings)
+{
+ EMailSearchBar *search_bar;
+ ESearchingTokenizer *tokenizer;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_CONTENT (mail_shell_content));
+
+ search_bar = E_MAIL_SEARCH_BAR (mail_shell_content->priv->search_bar);
+ tokenizer = e_mail_search_bar_get_tokenizer (search_bar);
+
+ e_searching_tokenizer_set_secondary_case_sensitivity (tokenizer, FALSE);
+ e_searching_tokenizer_set_secondary_search_string (tokenizer, NULL);
+
+ while (search_strings != NULL) {
+ e_searching_tokenizer_add_secondary_search_string (
+ tokenizer, search_strings->data);
+ search_strings = g_slist_next (search_strings);
+ }
+
+ e_mail_search_bar_changed (search_bar);
+}
+
+void
+e_mail_shell_content_update_view_instance (EMailShellContent *mail_shell_content)
+{
+ EMailReader *reader;
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ GalViewCollection *view_collection;
+ GalViewInstance *view_instance;
+ MessageList *message_list;
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+ gboolean outgoing_folder;
+ gboolean show_vertical_view;
+ gchar *view_id;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_CONTENT (mail_shell_content));
+
+ shell_content = E_SHELL_CONTENT (mail_shell_content);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ view_collection = shell_view_class->view_collection;
+
+ reader = E_MAIL_READER (mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ /* If no folder is selected, return silently. */
+ if (message_list->folder == NULL)
+ return;
+
+ /* If we have a folder, we should also have a URI. */
+ g_return_if_fail (message_list->folder_uri != NULL);
+
+ if (mail_shell_content->priv->view_instance != NULL) {
+ g_object_unref (mail_shell_content->priv->view_instance);
+ mail_shell_content->priv->view_instance = NULL;
+ }
+
+ view_id = mail_config_folder_to_safe_url (message_list->folder);
+ view_instance = e_shell_view_new_view_instance (shell_view, view_id);
+ mail_shell_content->priv->view_instance = view_instance;
+
+ orientable = GTK_ORIENTABLE (mail_shell_content);
+ orientation = gtk_orientable_get_orientation (orientable);
+ show_vertical_view = (orientation == GTK_ORIENTATION_HORIZONTAL);
+
+ if (show_vertical_view) {
+ gchar *filename;
+ gchar *safe_view_id;
+
+ /* Force the view instance into vertical view. */
+
+ g_free (view_instance->custom_filename);
+ g_free (view_instance->current_view_filename);
+
+ safe_view_id = g_strdup (view_id);
+ e_filename_make_safe (safe_view_id);
+
+ filename = g_strdup_printf (
+ "custom_wide_view-%s.xml", safe_view_id);
+ view_instance->custom_filename = g_build_filename (
+ view_collection->local_dir, filename, NULL);
+ g_free (filename);
+
+ filename = g_strdup_printf (
+ "current_wide_view-%s.xml", safe_view_id);
+ view_instance->current_view_filename = g_build_filename (
+ view_collection->local_dir, filename, NULL);
+ g_free (filename);
+
+ g_free (safe_view_id);
+ }
+
+ g_free (view_id);
+
+ outgoing_folder =
+ em_utils_folder_is_drafts (
+ message_list->folder, message_list->folder_uri) ||
+ em_utils_folder_is_outbox (
+ message_list->folder, message_list->folder_uri) ||
+ em_utils_folder_is_sent (
+ message_list->folder, message_list->folder_uri);
+
+ if (outgoing_folder) {
+ if (show_vertical_view)
+ gal_view_instance_set_default_view (
+ view_instance, "Wide_View_Sent");
+ else
+ gal_view_instance_set_default_view (
+ view_instance, "As_Sent_Folder");
+ } else if (show_vertical_view) {
+ gal_view_instance_set_default_view (
+ view_instance, "Wide_View_Normal");
+ }
+
+ gal_view_instance_load (view_instance);
+
+ if (!gal_view_instance_exists (view_instance)) {
+ gchar *state_filename;
+
+ state_filename = mail_config_folder_to_cachename (
+ message_list->folder, "et-header-");
+
+ if (g_file_test (state_filename, G_FILE_TEST_IS_REGULAR)) {
+ ETableSpecification *spec;
+ ETableState *state;
+ GalView *view;
+ gchar *spec_filename;
+
+ spec = e_table_specification_new ();
+ spec_filename = g_build_filename (
+ EVOLUTION_ETSPECDIR,
+ "message-list.etspec",
+ NULL);
+ e_table_specification_load_from_file (
+ spec, spec_filename);
+ g_free (spec_filename);
+
+ state = e_table_state_new ();
+ view = gal_view_etable_new (spec, "");
+
+ e_table_state_load_from_file (
+ state, state_filename);
+ gal_view_etable_set_state (
+ GAL_VIEW_ETABLE (view), state);
+ gal_view_instance_set_custom_view (
+ view_instance, view);
+
+ g_object_unref (state);
+ g_object_unref (view);
+ g_object_unref (spec);
+ }
+
+ g_free (state_filename);
+ }
+
+ g_signal_connect (
+ view_instance, "display-view",
+ G_CALLBACK (mail_shell_content_display_view_cb),
+ mail_shell_content);
+
+ mail_shell_content_display_view_cb (
+ mail_shell_content,
+ gal_view_instance_get_current_view (view_instance));
+}
diff --git a/modules/mail/e-mail-shell-content.h b/modules/mail/e-mail-shell-content.h
new file mode 100644
index 0000000000..88714f8f95
--- /dev/null
+++ b/modules/mail/e-mail-shell-content.h
@@ -0,0 +1,89 @@
+/*
+ * e-mail-shell-content.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_SHELL_CONTENT_H
+#define E_MAIL_SHELL_CONTENT_H
+
+#include <shell/e-shell-content.h>
+#include <shell/e-shell-view.h>
+
+#include <mail/em-format-html-display.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_SHELL_CONTENT \
+ (e_mail_shell_content_get_type ())
+#define E_MAIL_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_SHELL_CONTENT, EMailShellContent))
+#define E_MAIL_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_SHELL_CONTENT, EMailShellContentClass))
+#define E_IS_MAIL_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_SHELL_CONTENT))
+#define E_IS_MAIL_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_SHELL_CONTENT))
+#define E_MAIL_SHELL_CONTENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_SHELL_CONTENT, EMailShellContentClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailShellContent EMailShellContent;
+typedef struct _EMailShellContentClass EMailShellContentClass;
+typedef struct _EMailShellContentPrivate EMailShellContentPrivate;
+
+struct _EMailShellContent {
+ EShellContent parent;
+ EMailShellContentPrivate *priv;
+};
+
+struct _EMailShellContentClass {
+ EShellContentClass parent_class;
+};
+
+GType e_mail_shell_content_get_type (void);
+void e_mail_shell_content_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_mail_shell_content_new(EShellView *shell_view);
+gboolean e_mail_shell_content_get_preview_visible
+ (EMailShellContent *mail_shell_content);
+void e_mail_shell_content_set_preview_visible
+ (EMailShellContent *mail_shell_content,
+ gboolean preview_visible);
+gboolean e_mail_shell_content_get_show_deleted
+ (EMailShellContent *mail_shell_content);
+void e_mail_shell_content_set_show_deleted
+ (EMailShellContent *mail_shell_content,
+ gboolean show_deleted);
+GalViewInstance *
+ e_mail_shell_content_get_view_instance
+ (EMailShellContent *mail_shell_content);
+void e_mail_shell_content_set_search_strings
+ (EMailShellContent *mail_shell_content,
+ GSList *search_strings);
+void e_mail_shell_content_update_view_instance
+ (EMailShellContent *mail_shell_content);
+
+G_END_DECLS
+
+#endif /* E_MAIL_SHELL_CONTENT_H */
diff --git a/mail/em-migrate.c b/modules/mail/e-mail-shell-migrate.c
index b3888dc7c0..7176d4fba7 100644
--- a/mail/em-migrate.c
+++ b/modules/mail/e-mail-shell-migrate.c
@@ -1,4 +1,6 @@
/*
+ * e-mail-shell-migrate.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,16 +15,11 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "e-mail-shell-migrate.h"
#include <stdio.h>
#include <stdlib.h>
@@ -37,6 +34,7 @@
#include <ctype.h>
#include <glib.h>
+#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gtk/gtk.h>
@@ -53,27 +51,26 @@
#include <libxml/parser.h>
#include <libxml/xmlmemory.h>
-#include <glib/gi18n.h>
-
#include <e-util/e-util.h>
#include <libedataserver/e-xml-utils.h>
#include <libedataserver/e-data-server-util.h>
#include <e-util/e-xml-utils.h>
+#include "e-util/e-account-utils.h"
#include "e-util/e-bconf-map.h"
-#include "libedataserver/e-account-list.h"
-#include "e-util/e-signature-list.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
#include "e-util/e-plugin.h"
+#include "e-util/e-signature-utils.h"
-#include "mail-component.h"
+#include "e-mail-shell-backend.h"
+#include "shell/e-shell-migrate.h"
+
+#include "e-mail-store.h"
#include "mail-config.h"
-#include "mail-session.h"
#include "em-utils.h"
-#include "em-migrate.h"
-#define d(x)
+#define d(x) x
#ifndef G_OS_WIN32
/* No versions previous to 2.8 or thereabouts have been available on
@@ -380,7 +377,7 @@ parse_lsub (const gchar *lsub, gchar *dir_sep)
return NULL;
}
-static gint
+static gboolean
read_imap_storeinfo (struct _account_info_1_0 *si)
{
FILE *storeinfo;
@@ -433,7 +430,7 @@ read_imap_storeinfo (struct _account_info_1_0 *si)
g_free (path);
if (storeinfo == NULL) {
g_warning ("could not find imap store info '%s'", path);
- return -1;
+ return FALSE;
}
/* ignore version */
@@ -473,10 +470,10 @@ read_imap_storeinfo (struct _account_info_1_0 *si)
fclose (storeinfo);
- return 0;
+ return TRUE;
}
-static gint
+static gboolean
load_accounts_1_0 (xmlDocPtr doc)
{
xmlNodePtr source;
@@ -485,7 +482,7 @@ load_accounts_1_0 (xmlDocPtr doc)
gchar key[32];
if (!(source = e_bconf_get_path (doc, "/Mail/Accounts")))
- return 0;
+ return TRUE;
if ((val = e_bconf_get_value (source, "num"))) {
count = atoi (val);
@@ -536,11 +533,11 @@ load_accounts_1_0 (xmlDocPtr doc)
g_hash_table_insert (accounts_name_1_0, ai->name, ai);
}
- return 0;
+ return TRUE;
}
-static gint
-em_migrate_1_0 (const gchar *evolution_dir, xmlDocPtr config_xmldb, xmlDocPtr filters, xmlDocPtr vfolders, CamelException *ex)
+static gboolean
+em_migrate_1_0 (const gchar *data_dir, xmlDocPtr config_xmldb, xmlDocPtr filters, xmlDocPtr vfolders, GError **error)
{
accounts_1_0 = g_hash_table_new_full (
g_str_hash, g_str_equal,
@@ -555,11 +552,11 @@ em_migrate_1_0 (const gchar *evolution_dir, xmlDocPtr config_xmldb, xmlDocPtr fi
g_hash_table_destroy (accounts_1_0);
g_hash_table_destroy (accounts_name_1_0);
- return 0;
+ return TRUE;
}
/* 1.2 upgrade functions */
-static gint
+static gboolean
is_xml1encoded (const gchar *txt)
{
const guchar *p;
@@ -653,7 +650,7 @@ utf8_reencode (const gchar *txt)
}
}
-static gint
+static gboolean
upgrade_xml_1_2_rec (xmlNodePtr node)
{
const gchar *value_tags[] = { "string", "address", "regex", "file", "command", NULL };
@@ -718,16 +715,16 @@ upgrade_xml_1_2_rec (xmlNodePtr node)
node = node->next;
}
- return 0;
+ return TRUE;
}
-static gint
+static gboolean
em_upgrade_xml_1_2 (xmlDocPtr doc)
{
xmlNodePtr root;
if (!doc || !(root = xmlDocGetRootElement (doc)))
- return 0;
+ return TRUE;
return upgrade_xml_1_2_rec (root);
}
@@ -963,7 +960,7 @@ static struct {
};
/* remaps mail config from bconf to gconf */
-static gint
+static gboolean
bconf_import(GConfClient *gconf, xmlDocPtr config_xmldb)
{
xmlNodePtr source;
@@ -1014,11 +1011,11 @@ bconf_import(GConfClient *gconf, xmlDocPtr config_xmldb)
e_bconf_import_xml_blob(gconf, config_xmldb, signature_map, "/Mail/Signatures",
"/apps/evolution/mail/signatures", "signature", NULL);
- return 0;
+ return TRUE;
}
-static gint
-em_migrate_1_2(const gchar *evolution_dir, xmlDocPtr config_xmldb, xmlDocPtr filters, xmlDocPtr vfolders, CamelException *ex)
+static gboolean
+em_migrate_1_2(const gchar *data_dir, xmlDocPtr config_xmldb, xmlDocPtr filters, xmlDocPtr vfolders, GError **error)
{
GConfClient *gconf;
@@ -1029,7 +1026,7 @@ em_migrate_1_2(const gchar *evolution_dir, xmlDocPtr config_xmldb, xmlDocPtr fil
em_upgrade_xml_1_2(filters);
em_upgrade_xml_1_2(vfolders);
- return 0;
+ return TRUE;
}
/* 1.4 upgrade functions */
@@ -1105,18 +1102,31 @@ em_migrate_setup_progress_dialog (const gchar *title, const gchar *desc)
gchar *markup;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title ((GtkWindow *) window, _("Migrating..."));
+ gtk_window_set_modal ((GtkWindow *) window, TRUE);
+ gtk_container_set_border_width ((GtkContainer *) window, 6);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
+ gtk_container_add ((GtkContainer *) window, vbox);
- gtk_window_set_title (GTK_WINDOW (window), _("Migrating..."));
- gtk_window_set_modal (GTK_WINDOW (window), TRUE);
- gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (window), 6);
+ w = gtk_label_new (desc);
- hbox = gtk_hbox_new (FALSE, 24);
+ gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
+ gtk_widget_show (w);
+ gtk_box_pack_start ((GtkBox *) vbox, w, TRUE, TRUE, 0);
- /* Install the info image */
- w = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- gtk_misc_set_alignment (GTK_MISC (w), 0.5, 0.0);
- gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_widget_show (hbox);
+ gtk_box_pack_start ((GtkBox *) vbox, hbox, TRUE, TRUE, 0);
+
+ label = (GtkLabel *) gtk_label_new ("");
+ gtk_widget_show ((GtkWidget *) label);
+ gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) label, TRUE, TRUE, 0);
+
+ progress = (GtkProgressBar *) gtk_progress_bar_new ();
+ gtk_widget_show ((GtkWidget *) progress);
+ gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) progress, TRUE, TRUE, 0);
/* Prepare the message */
vbox = gtk_vbox_new (FALSE, 12);
@@ -1157,7 +1167,7 @@ em_migrate_setup_progress_dialog (const gchar *title, const gchar *desc)
static void
em_migrate_close_progress_dialog (void)
{
- gtk_widget_destroy (GTK_WIDGET (window));
+ gtk_widget_destroy ((GtkWidget *) window);
}
static void
@@ -1238,7 +1248,7 @@ is_mail_folder (const gchar *metadata)
return FALSE;
}
-static gint
+static gboolean
get_local_et_expanded (const gchar *dirname)
{
xmlNodePtr node;
@@ -1253,24 +1263,24 @@ get_local_et_expanded (const gchar *dirname)
if (stat (buf, &st) == -1) {
g_free (buf);
- return -1;
+ return FALSE;
}
if (!(doc = xmlParseFile (buf))) {
g_free (buf);
- return -1;
+ return FALSE;
}
g_free (buf);
if (!(node = xmlDocGetRootElement (doc)) || strcmp ((gchar *)node->name, "expanded_state") != 0) {
xmlFreeDoc (doc);
- return -1;
+ return FALSE;
}
if (!(buf = (gchar *)xmlGetProp (node, (const guchar *)"default"))) {
xmlFreeDoc (doc);
- return -1;
+ return FALSE;
}
thread_list = strcmp (buf, "0") == 0 ? 0 : 1;
@@ -1356,7 +1366,7 @@ static gint open_flags[3] = {
O_WRONLY | O_CREAT | O_APPEND,
};
-static gint
+static gboolean
cp (const gchar *src, const gchar *dest, gboolean show_progress, gint mode)
{
guchar readbuf[65536];
@@ -1370,18 +1380,18 @@ cp (const gchar *src, const gchar *dest, gboolean show_progress, gint mode)
* want to corrupt their existing data */
if (g_stat (dest, &st) == 0 && st.st_size > 0 && mode == CP_UNIQUE) {
errno = EEXIST;
- return -1;
+ return FALSE;
}
if (g_stat (src, &st) == -1
|| (readfd = g_open (src, O_RDONLY | O_BINARY, 0)) == -1)
- return -1;
+ return FALSE;
if ((writefd = g_open (dest, open_flags[mode] | O_BINARY, 0666)) == -1) {
errnosav = errno;
close (readfd);
errno = errnosav;
- return -1;
+ return FALSE;
}
do {
@@ -1418,7 +1428,7 @@ cp (const gchar *src, const gchar *dest, gboolean show_progress, gint mode)
utime (dest, &ut);
chmod (dest, st.st_mode);
- return 0;
+ return TRUE;
exception:
@@ -1433,12 +1443,12 @@ cp (const gchar *src, const gchar *dest, gboolean show_progress, gint mode)
unlink (dest);
errno = errnosav;
- return -1;
+ return FALSE;
}
#ifndef G_OS_WIN32
-static gint
+static gboolean
cp_r (const gchar *src, const gchar *dest, const gchar *pattern, gint mode)
{
GString *srcpath, *destpath;
@@ -1448,10 +1458,10 @@ cp_r (const gchar *src, const gchar *dest, const gchar *pattern, gint mode)
DIR *dir;
if (g_mkdir_with_parents (dest, 0777) == -1)
- return -1;
+ return FALSE;
if (!(dir = opendir (src)))
- return -1;
+ return FALSE;
srcpath = g_string_new (src);
g_string_append_c (srcpath, '/');
@@ -1486,7 +1496,7 @@ cp_r (const gchar *src, const gchar *dest, const gchar *pattern, gint mode)
g_string_free (destpath, TRUE);
g_string_free (srcpath, TRUE);
- return 0;
+ return TRUE;
}
static void
@@ -1523,18 +1533,21 @@ mbox_build_filename (GString *path, const gchar *toplevel_dir, const gchar *full
}
}
-static gint
-em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *full_name, CamelException *ex)
+static gboolean
+em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *full_name, GError **error)
{
CamelFolder *old_folder = NULL, *new_folder = NULL;
CamelStore *local_store = NULL;
+ CamelException ex;
gchar *name, *uri;
GPtrArray *uids;
struct stat st;
- gint thread_list;
+ gboolean thread_list;
gint index, i;
GString *src, *dest;
- gint res = -1;
+ gboolean success = FALSE;
+
+ camel_exception_init (&ex);
src = g_string_new("");
@@ -1544,7 +1557,7 @@ em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *
|| !is_mail_folder(src->str)) {
/* Not an evolution mail folder */
g_string_free(src, TRUE);
- return 0;
+ return TRUE;
}
dest = g_string_new("");
@@ -1569,16 +1582,18 @@ em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *
dlen = dest->len;
if (g_mkdir_with_parents (dest->str, 0777) == -1 && errno != EEXIST) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to create new folder `%s': %s"),
- dest->str, g_strerror(errno));
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Unable to create new folder `%s': %s"),
+ dest->str, g_strerror (errno));
goto fatal;
}
*p = '/';
mode = CP_UNIQUE;
retry_copy:
- if (cp (src->str, dest->str, TRUE, mode) == -1) {
+ if (!cp (src->str, dest->str, TRUE, mode)) {
if (errno == EEXIST) {
gint save = errno;
@@ -1595,9 +1610,11 @@ em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *
errno = save;
}
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to copy folder `%s' to `%s': %s"),
- src->str, dest->str, g_strerror(errno));
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Unable to copy folder `%s' to `%s': %s"),
+ src->str, dest->str, g_strerror (errno));
goto fatal;
}
ignore:
@@ -1617,14 +1634,14 @@ em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *
goto cmeta_err;
/* write the meta count */
- if (camel_file_util_encode_uint32 (fp, thread_list != -1 ? 1 : 0) == -1)
+ if (camel_file_util_encode_uint32 (fp, thread_list ? 1 : 0) == -1)
goto cmeta_err;
- if (thread_list != -1) {
+ if (!thread_list) {
if (camel_file_util_encode_string (fp, "evolution:thread_list") == -1)
goto cmeta_err;
- if (camel_file_util_encode_string (fp, thread_list ? "1" : "0") == -1)
+ if (camel_file_util_encode_string (fp, !thread_list ? "1" : "0") == -1)
goto cmeta_err;
}
@@ -1663,16 +1680,16 @@ em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *
} else {
guint32 flags = CAMEL_STORE_FOLDER_CREATE;
- if (!(local_store = camel_session_get_store ((CamelSession *) session, uri, ex))
- || !(old_folder = camel_store_get_folder (local_store, name, 0, ex)))
+ if (!(local_store = camel_session_get_store ((CamelSession *) session, uri, &ex))
+ || !(old_folder = camel_store_get_folder (local_store, name, 0, &ex)))
goto fatal;
flags |= (index ? CAMEL_STORE_FOLDER_BODY_INDEX : 0);
- if (!(new_folder = camel_store_get_folder (session->store, full_name, flags, ex)))
+ if (!(new_folder = camel_store_get_folder (session->store, full_name, flags, &ex)))
goto fatal;
- if (thread_list != -1) {
- camel_object_meta_set (new_folder, "evolution:thread_list", thread_list ? "1" : "0");
+ if (!thread_list) {
+ camel_object_meta_set (new_folder, "evolution:thread_list", !thread_list ? "1" : "0");
camel_object_state_write (new_folder);
}
@@ -1684,17 +1701,17 @@ em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *
if (!(info = camel_folder_get_message_info (old_folder, uids->pdata[i])))
continue;
- if (!(message = camel_folder_get_message (old_folder, uids->pdata[i], ex))) {
+ if (!(message = camel_folder_get_message (old_folder, uids->pdata[i], &ex))) {
camel_folder_free_message_info (old_folder, info);
camel_folder_free_uids (old_folder, uids);
goto fatal;
}
- camel_folder_append_message (new_folder, message, info, NULL, ex);
+ camel_folder_append_message (new_folder, message, info, NULL, &ex);
camel_folder_free_message_info (old_folder, info);
camel_object_unref (message);
- if (camel_exception_is_set (ex))
+ if (camel_exception_is_set (&ex))
break;
em_migrate_set_progress (((double) i + 1) / ((double) uids->len));
@@ -1702,10 +1719,10 @@ em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *
camel_folder_free_uids (old_folder, uids);
- if (camel_exception_is_set (ex))
+ if (camel_exception_is_set (&ex))
goto fatal;
}
- res = 0;
+ success = TRUE;
fatal:
g_free (uri);
g_free (name);
@@ -1718,34 +1735,42 @@ fatal:
if (new_folder)
camel_object_unref(new_folder);
- return res;
+ if (camel_exception_is_set (&ex)) {
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ "%s", camel_exception_get_description (&ex));
+ camel_exception_clear (&ex);
+ }
+
+ return success;
}
-static gint
-em_migrate_dir (EMMigrateSession *session, const gchar *dirname, const gchar *full_name, CamelException *ex)
+static gboolean
+em_migrate_dir (EMMigrateSession *session, const gchar *dirname, const gchar *full_name, GError **error)
{
gchar *path;
DIR *dir;
struct stat st;
struct dirent *dent;
- gint res = 0;
+ gboolean success = TRUE;
- if (em_migrate_folder(session, dirname, full_name, ex) == -1)
- return -1;
+ if (!em_migrate_folder(session, dirname, full_name, error))
+ return FALSE;
/* no subfolders, not readable, don't care */
path = g_strdup_printf ("%s/subfolders", dirname);
if (stat (path, &st) == -1 || !S_ISDIR (st.st_mode)) {
g_free (path);
- return 0;
+ return TRUE;
}
if (!(dir = opendir (path))) {
g_free (path);
- return 0;
+ return TRUE;
}
- while (res == 0 && (dent = readdir (dir))) {
+ while (success && (dent = readdir (dir))) {
gchar *full_path;
gchar *name;
@@ -1759,7 +1784,7 @@ em_migrate_dir (EMMigrateSession *session, const gchar *dirname, const gchar *fu
}
name = g_strdup_printf ("%s/%s", full_name, dent->d_name);
- res = em_migrate_dir (session, full_path, name, ex);
+ success = em_migrate_dir (session, full_path, name, error);
g_free (full_path);
g_free (name);
}
@@ -1768,29 +1793,33 @@ em_migrate_dir (EMMigrateSession *session, const gchar *dirname, const gchar *fu
g_free (path);
- return res;
+ return success;
}
-static gint
-em_migrate_local_folders_1_4 (EMMigrateSession *session, CamelException *ex)
+static gboolean
+em_migrate_local_folders_1_4 (EMMigrateSession *session, GError **error)
{
struct dirent *dent;
struct stat st;
DIR *dir;
- gint res = 0;
+ gboolean success = TRUE;
if (!(dir = opendir (session->srcdir))) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to scan for existing mailboxes at `%s': %s"),
- session->srcdir, g_strerror(errno));
- return -1;
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Unable to scan for existing mailboxes at "
+ "`%s': %s"), session->srcdir, g_strerror (errno));
+ return FALSE;
}
- em_migrate_setup_progress_dialog (NULL, _("The location and hierarchy of the Evolution mailbox "
- "folders has changed since Evolution 1.x.\n\nPlease be "
- "patient while Evolution migrates your folders..."));
+ em_migrate_setup_progress_dialog (
+ _("Migrating Folders"),
+ _("The location and hierarchy of the Evolution mailbox "
+ "folders has changed since Evolution 1.x.\n\nPlease be "
+ "patient while Evolution migrates your folders..."));
- while (res == 0 && (dent = readdir (dir))) {
+ while (success && (dent = readdir (dir))) {
gchar *full_path;
if (dent->d_name[0] == '.')
@@ -1802,7 +1831,7 @@ em_migrate_local_folders_1_4 (EMMigrateSession *session, CamelException *ex)
continue;
}
- res = em_migrate_dir (session, full_path, dent->d_name, ex);
+ success = em_migrate_dir (session, full_path, dent->d_name, error);
g_free (full_path);
}
@@ -1810,7 +1839,7 @@ em_migrate_local_folders_1_4 (EMMigrateSession *session, CamelException *ex)
em_migrate_close_progress_dialog ();
- return res;
+ return success;
}
static gchar *
@@ -1906,7 +1935,7 @@ get_nth_sig (gint id)
gchar *uid = NULL;
gint i = 0;
- list = mail_config_get_signatures ();
+ list = e_get_signature_list ();
iter = e_list_get_iterator ((EList *) list);
while (e_iterator_is_valid (iter) && i < id) {
@@ -1930,7 +1959,7 @@ em_upgrade_accounts_1_4 (void)
EAccountList *accounts;
EIterator *iter;
- if (!(accounts = mail_config_get_accounts ()))
+ if (!(accounts = e_get_account_list ()))
return;
iter = e_list_get_iterator ((EList *) accounts);
@@ -1963,18 +1992,18 @@ em_upgrade_accounts_1_4 (void)
g_object_unref (iter);
- mail_config_save_accounts ();
+ e_account_list_save (accounts);
}
-static gint
-em_migrate_pop_uid_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
+static gboolean
+em_migrate_pop_uid_caches_1_4 (const gchar *data_dir, GError **error)
{
GString *oldpath, *newpath;
struct dirent *dent;
gsize olen, nlen;
gchar *cache_dir;
DIR *dir;
- gint res = 0;
+ gboolean success = TRUE;
/* Sigh, too many unique strings to translate, for cases which shouldn't ever happen */
@@ -1983,14 +2012,16 @@ em_migrate_pop_uid_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
if (!(dir = opendir (cache_dir))) {
if (errno == ENOENT) {
g_free(cache_dir);
- return 0;
+ return TRUE;
}
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to open old POP keep-on-server data `%s': %s"),
- cache_dir, g_strerror (errno));
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Unable to open old POP keep-on-server data "
+ "`%s': %s"), cache_dir, g_strerror (errno));
g_free (cache_dir);
- return -1;
+ return FALSE;
}
oldpath = g_string_new (cache_dir);
@@ -1998,15 +2029,18 @@ em_migrate_pop_uid_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
olen = oldpath->len;
g_free (cache_dir);
- cache_dir = g_build_filename (evolution_dir, "mail", "pop", NULL);
+ cache_dir = g_build_filename (data_dir, "pop", NULL);
if (g_mkdir_with_parents (cache_dir, 0777) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to create POP3 keep-on-server data directory `%s': %s"),
- cache_dir, g_strerror(errno));
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Unable to create POP3 keep-on-server data "
+ "directory `%s': %s"), cache_dir,
+ g_strerror (errno));
g_string_free (oldpath, TRUE);
g_free (cache_dir);
closedir (dir);
- return -1;
+ return FALSE;
}
newpath = g_string_new (cache_dir);
@@ -2014,7 +2048,7 @@ em_migrate_pop_uid_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
nlen = newpath->len;
g_free (cache_dir);
- while (res == 0 && (dent = readdir (dir))) {
+ while (success && (dent = readdir (dir))) {
if (strncmp (dent->d_name, "cache-pop:__", 12) != 0)
continue;
@@ -2028,11 +2062,14 @@ em_migrate_pop_uid_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
g_string_truncate (newpath, newpath->len - 1);
if (g_mkdir_with_parents (newpath->str, 0777) == -1
- || cp(oldpath->str, (g_string_append(newpath, "/uid-cache"))->str, FALSE, CP_UNIQUE)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to copy POP3 keep-on-server data `%s': %s"),
- oldpath->str, g_strerror(errno));
- res = -1;
+ || !cp(oldpath->str, (g_string_append(newpath, "/uid-cache"))->str, FALSE, CP_UNIQUE)) {
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Unable to copy POP3 keep-on-server data "
+ "`%s': %s"), oldpath->str,
+ g_strerror (errno));
+ success = FALSE;
}
}
@@ -2042,11 +2079,11 @@ em_migrate_pop_uid_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
closedir (dir);
- return res;
+ return success;
}
-static gint
-em_migrate_imap_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
+static gboolean
+em_migrate_imap_caches_1_4 (const gchar *data_dir, GError **error)
{
gchar *src, *dest;
struct stat st;
@@ -2054,10 +2091,10 @@ em_migrate_imap_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
src = g_build_filename (g_get_home_dir (), "evolution", "mail", "imap", NULL);
if (stat (src, &st) == -1 || !S_ISDIR (st.st_mode)) {
g_free (src);
- return 0;
+ return TRUE;
}
- dest = g_build_filename (evolution_dir, "mail", "imap", NULL);
+ dest = g_build_filename (data_dir, "imap", NULL);
/* we don't care if this fails, it's only a cache... */
cp_r (src, dest, "summary", CP_OVERWRITE);
@@ -2065,11 +2102,11 @@ em_migrate_imap_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
g_free (dest);
g_free (src);
- return 0;
+ return TRUE;
}
-static gint
-em_migrate_folder_expand_state_1_4 (const gchar *evolution_dir, CamelException *ex)
+static gboolean
+em_migrate_folder_expand_state_1_4 (const gchar *data_dir, GError **error)
{
GString *srcpath, *destpath;
gsize slen, dlen, rlen;
@@ -2082,15 +2119,15 @@ em_migrate_folder_expand_state_1_4 (const gchar *evolution_dir, CamelException *
g_string_append (srcpath, "/evolution/config");
if (stat (srcpath->str, &st) == -1 || !S_ISDIR (st.st_mode)) {
g_string_free (srcpath, TRUE);
- return 0;
+ return TRUE;
}
- destpath = g_string_new (evolution_dir);
- g_string_append (destpath, "/mail/config");
+ destpath = g_string_new (data_dir);
+ g_string_append (destpath, "/config");
if (g_mkdir_with_parents (destpath->str, 0777) == -1 || !(dir = opendir (srcpath->str))) {
g_string_free (destpath, TRUE);
g_string_free (srcpath, TRUE);
- return 0;
+ return TRUE;
}
g_string_append (srcpath, "/et-expanded-");
@@ -2121,7 +2158,7 @@ em_migrate_folder_expand_state_1_4 (const gchar *evolution_dir, CamelException *
/* this should always be the case afaik... */
inptr += rlen;
new = g_string_new ("mbox:");
- g_string_append_printf (new, "%s/mail/local#", evolution_dir);
+ g_string_append_printf (new, "%s/local#", data_dir);
full_name = g_strdup (inptr);
inptr = full_name + strlen (full_name) - 12;
@@ -2163,11 +2200,11 @@ em_migrate_folder_expand_state_1_4 (const gchar *evolution_dir, CamelException *
g_string_free (destpath, TRUE);
g_string_free (srcpath, TRUE);
- return 0;
+ return TRUE;
}
-static gint
-em_migrate_folder_view_settings_1_4 (const gchar *evolution_dir, CamelException *ex)
+static gboolean
+em_migrate_folder_view_settings_1_4 (const gchar *data_dir, GError **error)
{
GString *srcpath, *destpath;
gsize slen, dlen, rlen;
@@ -2180,15 +2217,15 @@ em_migrate_folder_view_settings_1_4 (const gchar *evolution_dir, CamelException
g_string_append (srcpath, "/evolution/views/mail");
if (stat (srcpath->str, &st) == -1 || !S_ISDIR (st.st_mode)) {
g_string_free (srcpath, TRUE);
- return 0;
+ return TRUE;
}
- destpath = g_string_new (evolution_dir);
- g_string_append (destpath, "/mail/views");
+ destpath = g_string_new (data_dir);
+ g_string_append (destpath, "/views");
if (g_mkdir_with_parents (destpath->str, 0777) == -1 || !(dir = opendir (srcpath->str))) {
g_string_free (destpath, TRUE);
g_string_free (srcpath, TRUE);
- return 0;
+ return TRUE;
}
g_string_append_c (srcpath, '/');
@@ -2240,7 +2277,7 @@ em_migrate_folder_view_settings_1_4 (const gchar *evolution_dir, CamelException
/* this should always be the case afaik... */
inptr += rlen;
new = g_string_new ("mbox:");
- g_string_append_printf (new, "%s/mail/local#", evolution_dir);
+ g_string_append_printf (new, "%s/local#", data_dir);
full_name = g_strdup (inptr);
inptr = full_name + strlen (full_name) - 12;
@@ -2285,7 +2322,7 @@ em_migrate_folder_view_settings_1_4 (const gchar *evolution_dir, CamelException
g_string_free (destpath, TRUE);
g_string_free (srcpath, TRUE);
- return 0;
+ return TRUE;
}
#define SUBFOLDER_DIR_NAME "subfolders"
@@ -2366,16 +2403,16 @@ e_path_to_physical (const gchar *prefix, const gchar *vpath)
return ppath;
}
-static gint
-em_migrate_imap_cmeta_1_4(const gchar *evolution_dir, CamelException *ex)
+static gboolean
+em_migrate_imap_cmeta_1_4(const gchar *data_dir, GError **error)
{
GConfClient *gconf;
GSList *paths, *p;
EAccountList *accounts;
const EAccount *account;
- if (!(accounts = mail_config_get_accounts()))
- return 0;
+ if (!(accounts = e_get_account_list ()))
+ return TRUE;
gconf = gconf_client_get_default();
paths = gconf_client_get_list(gconf, "/apps/evolution/shell/offline/folder_paths", GCONF_VALUE_STRING, NULL);
@@ -2395,8 +2432,8 @@ em_migrate_imap_cmeta_1_4(const gchar *evolution_dir, CamelException *ex)
if (url) {
gchar *dir, *base;
- base = g_strdup_printf("%s/mail/imap/%s@%s/folders",
- evolution_dir,
+ base = g_strdup_printf("%s/imap/%s@%s/folders",
+ data_dir,
url->user?url->user:"",
url->host?url->host:"");
@@ -2440,7 +2477,7 @@ em_migrate_imap_cmeta_1_4(const gchar *evolution_dir, CamelException *ex)
/* we couldn't care less if this doesn't work */
- return 0;
+ return TRUE;
}
static void
@@ -2479,8 +2516,8 @@ remove_system_searches(xmlDocPtr searches)
}
}
-static gint
-em_migrate_1_4 (const gchar *evolution_dir, xmlDocPtr filters, xmlDocPtr vfolders, CamelException *ex)
+static gboolean
+em_migrate_1_4 (const gchar *data_dir, xmlDocPtr filters, xmlDocPtr vfolders, GError **error)
{
EMMigrateSession *session;
CamelException lex;
@@ -2488,43 +2525,44 @@ em_migrate_1_4 (const gchar *evolution_dir, xmlDocPtr filters, xmlDocPtr vfolder
gchar *path;
xmlDocPtr searches;
- path = g_build_filename (evolution_dir, "mail", NULL);
-
- camel_init (path, TRUE);
+ camel_init (data_dir, TRUE);
camel_provider_init();
- session = (EMMigrateSession *) em_migrate_session_new (path);
- g_free (path);
+ session = (EMMigrateSession *) em_migrate_session_new (data_dir);
session->srcdir = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
path = g_strdup_printf ("mbox:%s/.evolution/mail/local", g_get_home_dir ());
if (stat (path + 5, &st) == -1) {
if (errno != ENOENT || g_mkdir_with_parents (path + 5, 0777) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to create local mail storage `%s': %s"),
- path + 5, g_strerror (errno));
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Failed to create local mail storage "
+ "`%s': %s"), path + 5, g_strerror (errno));
g_free (session->srcdir);
camel_object_unref (session);
g_free (path);
- return -1;
+ return FALSE;
}
}
camel_exception_init (&lex);
if (!(session->store = camel_session_get_store ((CamelSession *) session, path, &lex))) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to create local mail storage `%s': %s"),
- path, lex.desc);
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Failed to create local mail storage `%s': %s"),
+ path, lex.desc);
g_free (session->srcdir);
camel_object_unref (session);
camel_exception_clear (&lex);
g_free (path);
- return -1;
+ return FALSE;
}
g_free (path);
- if (em_migrate_local_folders_1_4 (session, ex) == -1)
- return -1;
+ if (!em_migrate_local_folders_1_4 (session, error))
+ return FALSE;
camel_object_unref (session->store);
g_free (session->srcdir);
@@ -2542,26 +2580,24 @@ em_migrate_1_4 (const gchar *evolution_dir, xmlDocPtr filters, xmlDocPtr vfolder
g_free(path);
if (searches) {
remove_system_searches(searches);
- path = g_build_filename(evolution_dir, "mail", NULL);
- emm_save_xml(searches, path, "searches.xml");
- g_free(path);
+ emm_save_xml(searches, data_dir, "searches.xml");
xmlFreeDoc(searches);
}
- if (em_migrate_pop_uid_caches_1_4 (evolution_dir, ex) == -1)
- return -1;
+ if (!em_migrate_pop_uid_caches_1_4 (data_dir, error))
+ return FALSE;
/* these are non-fatal */
- em_migrate_imap_caches_1_4 (evolution_dir, ex);
- camel_exception_clear(ex);
- em_migrate_folder_expand_state_1_4 (evolution_dir, ex);
- camel_exception_clear(ex);
- em_migrate_folder_view_settings_1_4 (evolution_dir, ex);
- camel_exception_clear(ex);
- em_migrate_imap_cmeta_1_4(evolution_dir, ex);
- camel_exception_clear(ex);
-
- return 0;
+ em_migrate_imap_caches_1_4 (data_dir, error);
+ g_clear_error (error);
+ em_migrate_folder_expand_state_1_4 (data_dir, error);
+ g_clear_error (error);
+ em_migrate_folder_view_settings_1_4 (data_dir, error);
+ g_clear_error (error);
+ em_migrate_imap_cmeta_1_4 (data_dir, error);
+ g_clear_error (error);
+
+ return TRUE;
}
static void
@@ -2571,7 +2607,7 @@ em_update_accounts_2_11 (void)
EIterator *iter;
gboolean changed = FALSE;
- if (!(accounts = mail_config_get_accounts ()))
+ if (!(accounts = e_get_account_list ()))
return;
iter = e_list_get_iterator ((EList *) accounts);
@@ -2594,13 +2630,13 @@ em_update_accounts_2_11 (void)
g_object_unref (iter);
if (changed)
- mail_config_save_accounts ();
+ e_account_list_save (accounts);
}
#endif /* !G_OS_WIN32 */
-static gint
-emm_setup_initial(const gchar *evolution_dir)
+static gboolean
+emm_setup_initial(const gchar *data_dir)
{
GDir *dir;
const gchar *d;
@@ -2612,10 +2648,10 @@ emm_setup_initial(const gchar *evolution_dir)
d(printf("Setting up initial mail tree\n"));
- base = g_build_filename(evolution_dir, "mail", "local", NULL);
+ base = g_build_filename(data_dir, "local", NULL);
if (g_mkdir_with_parents(base, 0777) == -1 && errno != EEXIST) {
g_free(base);
- return -1;
+ return FALSE;
}
/* e.g. try en-AU then en, etc */
@@ -2631,7 +2667,7 @@ emm_setup_initial(const gchar *evolution_dir)
}
/* Make sure we found one. */
- g_return_val_if_fail (*language_names != NULL, 0);
+ g_return_val_if_fail (*language_names != NULL, FALSE);
dir = g_dir_open(local, 0, NULL);
if (dir) {
@@ -2651,7 +2687,7 @@ emm_setup_initial(const gchar *evolution_dir)
g_free(local);
g_free(base);
- return 0;
+ return TRUE;
}
static gboolean
@@ -2766,8 +2802,8 @@ em_update_sa_junk_setting_2_23 (void)
static gboolean
update_progress_in_main_thread (double *progress)
{
- em_migrate_set_progress (*progress);
- return FALSE;
+ em_migrate_set_progress (*progress);
+ return FALSE;
}
static void
@@ -2795,13 +2831,11 @@ migrate_folders(CamelStore *store, gboolean is_local, CamelFolderInfo *fi, const
if (folder != NULL)
camel_folder_summary_migrate_infos (folder->summary);
-
migrate_folders(store, is_local, fi->child, acc, ex, done, nth_folder, total_folders);
-
fi = fi->next;
}
- if ( (*nth_folder) == (total_folders - 1))
+ if ((*nth_folder) == (total_folders - 1))
*done = TRUE;
}
@@ -2811,28 +2845,30 @@ count_folders (CamelFolderInfo *fi, gint *count)
{
while (fi) {
*count = *count + 1;
- count_folders (fi->child , count);
+ count_folders (fi->child, count);
fi = fi->next;
}
}
static CamelStore *
-setup_local_store (MailComponent *mc)
+setup_local_store (EShellBackend *shell_backend,
+ EMMigrateSession *session)
{
CamelURL *url;
+ const gchar *data_dir;
gchar *tmp;
CamelStore *store;
url = camel_url_new("mbox:", NULL);
- tmp = g_build_filename (mail_component_peek_base_directory(mc), "local", NULL);
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ tmp = g_build_filename (data_dir, "local", NULL);
camel_url_set_path(url, tmp);
g_free(tmp);
tmp = camel_url_to_string(url, 0);
- store = (CamelStore *)camel_session_get_service(session, tmp, CAMEL_PROVIDER_STORE, NULL);
+ store = (CamelStore *)camel_session_get_service(CAMEL_SESSION (session), tmp, CAMEL_PROVIDER_STORE, NULL);
g_free(tmp);
return store;
-
}
struct migrate_folders_to_db_structure {
@@ -2844,7 +2880,8 @@ struct migrate_folders_to_db_structure {
gboolean is_local_store;
};
-static void migrate_folders_to_db_thread (struct migrate_folders_to_db_structure *migrate_dbs)
+static void
+migrate_folders_to_db_thread (struct migrate_folders_to_db_structure *migrate_dbs)
{
gint num_of_folders = 0, nth_folder = 0;
count_folders (migrate_dbs->info, &num_of_folders);
@@ -2854,115 +2891,132 @@ static void migrate_folders_to_db_thread (struct migrate_folders_to_db_structure
}
static void
-migrate_to_db()
+migrate_to_db (EShellBackend *shell_backend)
{
- EAccountList *accounts;
- EIterator *iter;
- gint i=0, len;
- MailComponent *component = mail_component_peek ();
- CamelStore *store = NULL;
- CamelFolderInfo *info;
+ EMMigrateSession *session;
+ EAccountList *accounts;
+ EIterator *iter;
+ gint i=0, len;
+ CamelStore *store = NULL;
+ CamelFolderInfo *info;
+ const gchar *data_dir;
- if (!(accounts = mail_config_get_accounts ()))
- return;
+ if (!(accounts = e_get_account_list ()))
+ return;
- iter = e_list_get_iterator ((EList *) accounts);
- len = e_list_length ((EList *) accounts);
+ iter = e_list_get_iterator ((EList *) accounts);
+ len = e_list_length ((EList *) accounts);
+
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ session = (EMMigrateSession *) em_migrate_session_new (data_dir);
+ camel_session_set_online ((CamelSession *) session, FALSE);
+ em_migrate_setup_progress_dialog (
+ _("Migrating Folders"),
+ _("The summary format of the Evolution mailbox "
+ "folders has been moved to SQLite since Evolution 2.24.\n\nPlease be "
+ "patient while Evolution migrates your folders..."));
+
+ em_migrate_set_progress ( (double)i/(len+1));
+ store = setup_local_store (shell_backend, session);
+ info = camel_store_get_folder_info (store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST|CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, NULL);
+ if (info) {
+ GThread *thread;
+ struct migrate_folders_to_db_structure migrate_dbs;
+
+ if (g_str_has_suffix (((CamelService *)store)->url->path, ".evolution/mail/local"))
+ migrate_dbs.is_local_store = TRUE;
+ else
+ migrate_dbs.is_local_store = FALSE;
+ camel_exception_init (&migrate_dbs.ex);
+ migrate_dbs.account_name = _("On This Computer");
+ migrate_dbs.info = info;
+ migrate_dbs.store = store;
+ migrate_dbs.done = FALSE;
- camel_session_set_online ((CamelSession *) session, FALSE);
+ thread = g_thread_create ((GThreadFunc) migrate_folders_to_db_thread, &migrate_dbs, TRUE, NULL);
+ while (!migrate_dbs.done)
+ g_main_context_iteration (NULL, TRUE);
+ }
+ i++;
+ em_migrate_set_progress ( (double)i/(len+1));
- em_migrate_setup_progress_dialog (_("Migrating Folders"), _("The summary format of the Evolution mailbox "
- "folders has been moved to SQLite since Evolution 2.24.\n\nPlease be "
- "patient while Evolution migrates your folders..."));
+ while (e_iterator_is_valid (iter)) {
+ EAccount *account = (EAccount *) e_iterator_get (iter);
+ EAccountService *service;
+ const gchar *name;
+
+ service = account->source;
+ name = account->name;
+ em_migrate_set_progress ( (double)i/(len+1));
+ if (account->enabled
+ && service->url != NULL
+ && service->url[0]
+ && strncmp(service->url, "mbox:", 5) != 0) {
- store = setup_local_store (component);
- info = camel_store_get_folder_info (store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST|CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, NULL);
+ CamelException ex;
- if (info) {
+ camel_exception_init (&ex);
+ e_mail_store_add_by_uri (service->url, name);
+
+ store = (CamelStore *) camel_session_get_service (CAMEL_SESSION (session), service->url, CAMEL_PROVIDER_STORE, &ex);
+ info = camel_store_get_folder_info (store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST|CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, &ex);
+ if (info) {
GThread *thread;
struct migrate_folders_to_db_structure migrate_dbs;
- if (g_str_has_suffix (((CamelService *)store)->url->path, ".evolution/mail/local"))
- migrate_dbs.is_local_store = TRUE;
- else
- migrate_dbs.is_local_store = FALSE;
- camel_exception_init (&migrate_dbs.ex);
- migrate_dbs.account_name = _("On This Computer");
+ migrate_dbs.ex = ex;
+ migrate_dbs.account_name = account->name;
migrate_dbs.info = info;
migrate_dbs.store = store;
migrate_dbs.done = FALSE;
thread = g_thread_create ((GThreadFunc) migrate_folders_to_db_thread, &migrate_dbs, TRUE, NULL);
while (!migrate_dbs.done)
- g_main_context_iteration (NULL, TRUE);
+ g_main_context_iteration (NULL, TRUE);
+ } else
+ printf("%s:%s: failed to get folder infos \n", G_STRLOC, G_STRFUNC);
+ camel_exception_clear(&ex);
+
}
i++;
- while (e_iterator_is_valid (iter)) {
- EAccount *account = (EAccount *) e_iterator_get (iter);
- EAccountService *service;
- const gchar *name;
-
- service = account->source;
- name = account->name;
- if (account->enabled
- && service->url != NULL
- && service->url[0]
- && strncmp(service->url, "mbox:", 5) != 0) {
-
- CamelException ex;
-
- camel_exception_init (&ex);
- mail_component_load_store_by_uri (component, service->url, name);
-
- store = (CamelStore *) camel_session_get_service (session, service->url, CAMEL_PROVIDER_STORE, &ex);
- info = camel_store_get_folder_info (store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST|CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, &ex);
- if (info) {
- GThread *thread;
- struct migrate_folders_to_db_structure migrate_dbs;
-
- migrate_dbs.ex = ex;
- migrate_dbs.account_name = account->name;
- migrate_dbs.info = info;
- migrate_dbs.store = store;
- migrate_dbs.done = FALSE;
-
- thread = g_thread_create ((GThreadFunc) migrate_folders_to_db_thread, &migrate_dbs, TRUE, NULL);
- while (!migrate_dbs.done)
- g_main_context_iteration (NULL, TRUE);
- } else
- printf("%s:%s: failed to get folder infos \n", G_STRLOC, G_STRFUNC);
- camel_exception_clear(&ex);
- }
- i++;
- e_iterator_next (iter);
- }
- /* camel_session_set_online ((CamelSession *) session, TRUE); */
- g_object_unref (iter);
- em_migrate_close_progress_dialog ();
+ e_iterator_next (iter);
+
+ }
+
+ //camel_session_set_online ((CamelSession *) session, TRUE);
+
+ g_object_unref (iter);
+ em_migrate_close_progress_dialog ();
+
+ g_object_unref (session);
}
-gint
-em_migrate (const gchar *evolution_dir, gint major, gint minor, gint revision, CamelException *ex)
+gboolean
+e_mail_shell_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
{
struct stat st;
+ const gchar *data_dir;
gchar *path;
/* make sure ~/.evolution/mail exists */
- path = g_build_filename (evolution_dir, "mail", NULL);
- if (g_stat (path, &st) == -1) {
- if (errno != ENOENT || g_mkdir_with_parents (path, 0777) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to create local mail folders at `%s': %s"),
- path, g_strerror (errno));
- g_free (path);
- return -1;
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ if (g_stat (data_dir, &st) == -1) {
+ if (errno != ENOENT || g_mkdir_with_parents (data_dir, 0777) == -1) {
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Unable to create local mail folders at "
+ "`%s': %s"), data_dir, g_strerror (errno));
+ return FALSE;
}
}
- g_free (path);
-
if (major == 0)
- return emm_setup_initial(evolution_dir);
+ return emm_setup_initial (data_dir);
if (major == 1 && minor < 5) {
#ifndef G_OS_WIN32
@@ -2970,46 +3024,46 @@ em_migrate (const gchar *evolution_dir, gint major, gint minor, gint revision, C
path = g_build_filename (g_get_home_dir (), "evolution", NULL);
if (minor <= 2 && !(config_xmldb = emm_load_xml (path, "config.xmldb"))) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to read settings from previous Evolution install, "
- "`evolution/config.xmldb' does not exist or is corrupt."));
- g_free (path);
- return -1;
+ g_set_error (
+ error, E_SHELL_MIGRATE_ERROR,
+ E_SHELL_MIGRATE_ERROR_FAILED,
+ _("Unable to read settings from previous "
+ "Evolution install, `evolution/config.xmldb' "
+ "does not exist or is corrupt."));
+ return FALSE;
}
filters = emm_load_xml (path, "filters.xml");
vfolders = emm_load_xml (path, "vfolders.xml");
g_free (path);
if (minor == 0) {
- if (em_migrate_1_0 (evolution_dir, config_xmldb, filters, vfolders, ex) == -1) {
+ if (!em_migrate_1_0 (data_dir, config_xmldb, filters, vfolders, error)) {
xmlFreeDoc (config_xmldb);
xmlFreeDoc (filters);
xmlFreeDoc (vfolders);
- return -1;
+ return FALSE;
}
}
if (minor <= 2) {
- if (em_migrate_1_2 (evolution_dir, config_xmldb, filters, vfolders, ex) == -1) {
+ if (!em_migrate_1_2 (data_dir, config_xmldb, filters, vfolders, error)) {
xmlFreeDoc (config_xmldb);
xmlFreeDoc (filters);
xmlFreeDoc (vfolders);
- return -1;
+ return FALSE;
}
xmlFreeDoc (config_xmldb);
}
if (minor <= 4) {
- if (em_migrate_1_4 (evolution_dir, filters, vfolders, ex) == -1) {
+ if (!em_migrate_1_4 (data_dir, filters, vfolders, error)) {
xmlFreeDoc (filters);
xmlFreeDoc (vfolders);
- return -1;
+ return FALSE;
}
}
- path = g_build_filename (evolution_dir, "mail", NULL);
-
if (filters) {
emm_save_xml (filters, path, "filters.xml");
xmlFreeDoc (filters);
@@ -3039,8 +3093,8 @@ em_migrate (const gchar *evolution_dir, gint major, gint minor, gint revision, C
if (major < 2 || (major == 2 && minor < 24)) {
em_update_sa_junk_setting_2_23 ();
- migrate_to_db ();
+ migrate_to_db (shell_backend);
}
- return 0;
+ return TRUE;
}
diff --git a/mail/mail-types.h b/modules/mail/e-mail-shell-migrate.h
index 5d2ef80ef2..8f3057ec0d 100644
--- a/mail/mail-types.h
+++ b/modules/mail/e-mail-shell-migrate.h
@@ -1,4 +1,5 @@
/*
+ * e-mail-shell-migrate.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,17 +19,20 @@
*
*/
-#ifndef MAIL_TYPES_H
-#define MAIL_TYPES_H 1
+#ifndef E_MAIL_SHELL_BACKEND_MIGRATE_H
+#define E_MAIL_SHELL_BACKEND_MIGRATE_H
+
+#include <glib.h>
+#include <shell/e-shell-backend.h>
G_BEGIN_DECLS
-typedef struct _FolderBrowser FolderBrowser;
-typedef struct _MessageBrowser MessageBrowser;
-typedef struct _SubscribeDialog SubscribeDialog;
-typedef struct _MessageList MessageList;
-typedef struct _MailDisplay MailDisplay;
+gboolean e_mail_shell_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
G_END_DECLS
-#endif /* MAIL_TYPES_H */
+#endif /* E_MAIL_SHELL_BACKEND_MIGRATE_H */
diff --git a/modules/mail/e-mail-shell-settings.c b/modules/mail/e-mail-shell-settings.c
new file mode 100644
index 0000000000..907c5fb643
--- /dev/null
+++ b/modules/mail/e-mail-shell-settings.c
@@ -0,0 +1,229 @@
+/*
+ * e-mail-shell-settings.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-shell-settings.h"
+
+#include <gconf/gconf-client.h>
+#include <libedataserver/e-account-list.h>
+
+#include "e-util/e-signature-list.h"
+#include "mail/e-mail-label-list-store.h"
+#include "mail/mail-session.h"
+
+void
+e_mail_shell_settings_init (EShell *shell)
+{
+ EShellSettings *shell_settings;
+ gpointer object;
+
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ /*** Global Objects ***/
+
+ e_shell_settings_install_property (
+ g_param_spec_object (
+ "mail-label-list-store",
+ NULL,
+ NULL,
+ E_TYPE_MAIL_LABEL_LIST_STORE,
+ G_PARAM_READWRITE));
+
+ object = e_mail_label_list_store_new ();
+ e_shell_settings_set_object (
+ shell_settings, "mail-label-list-store", object);
+ g_object_unref (object);
+
+ e_shell_settings_install_property (
+ g_param_spec_pointer (
+ "mail-session",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ camel_object_ref (session);
+ e_shell_settings_set_pointer (
+ shell_settings, "mail-session", session);
+
+ /*** Mail Preferences ***/
+
+ e_shell_settings_install_property_for_key (
+ "mail-address-compress",
+ "/apps/evolution/mail/display/address_compress");
+
+ e_shell_settings_install_property_for_key (
+ "mail-address-count",
+ "/apps/evolution/mail/display/address_count");
+
+ e_shell_settings_install_property_for_key (
+ "mail-charset",
+ "/apps/evolution/mail/display/charset");
+
+ e_shell_settings_install_property_for_key (
+ "mail-check-for-junk",
+ "/apps/evolution/mail/junk/check_incoming");
+
+ e_shell_settings_install_property_for_key (
+ "mail-citation-color",
+ "/apps/evolution/mail/display/citation_colour");
+
+ e_shell_settings_install_property_for_key (
+ "mail-confirm-expunge",
+ "/apps/evolution/mail/prompts/expunge");
+
+ e_shell_settings_install_property_for_key (
+ "mail-confirm-unwanted-html",
+ "/apps/evolution/mail/prompts/unwanted_html");
+
+ e_shell_settings_install_property_for_key (
+ "mail-empty-junk-on-exit",
+ "/apps/evolution/mail/junk/empty_on_exit");
+
+ e_shell_settings_install_property_for_key (
+ "mail-empty-trash-on-exit",
+ "/apps/evolution/mail/trash/empty_on_exit");
+
+ e_shell_settings_install_property_for_key (
+ "mail-enable-search-folders",
+ "/apps/evolution/mail/display/enable_vfolders");
+
+ e_shell_settings_install_property_for_key (
+ "mail-font-monospace",
+ "/apps/evolution/mail/display/fonts/monospace");
+
+ e_shell_settings_install_property_for_key (
+ "mail-font-variable",
+ "/apps/evolution/mail/display/fonts/variable");
+
+ e_shell_settings_install_property_for_key (
+ "mail-force-message-limit",
+ "/apps/evolution/mail/display/force_message_limit");
+
+ /* This value corresponds to MailConfigForwardStyle enum. */
+ e_shell_settings_install_property_for_key (
+ "mail-forward-style",
+ "/apps/evolution/mail/format/forward_style");
+
+ /* This value corresponds to MailConfigHTTPMode enum. */
+ e_shell_settings_install_property_for_key (
+ "mail-image-loading-policy",
+ "/apps/evolution/mail/display/load_http_images");
+
+ e_shell_settings_install_property_for_key (
+ "mail-magic-spacebar",
+ "/apps/evolution/mail/display/magic_spacebar");
+
+ e_shell_settings_install_property_for_key (
+ "mail-mark-citations",
+ "/apps/evolution/mail/display/mark_citations");
+
+ e_shell_settings_install_property_for_key (
+ "mail-mark-seen",
+ "/apps/evolution/mail/display/mark_seen");
+
+ e_shell_settings_install_property_for_key (
+ "mail-mark-seen-timeout",
+ "/apps/evolution/mail/display/mark_seen_timeout");
+
+ e_shell_settings_install_property_for_key (
+ "mail-message-text-part-limit",
+ "/apps/evolution/mail/display/message_text_part_limit");
+
+ e_shell_settings_install_property_for_key (
+ "mail-only-local-photos",
+ "/apps/evolution/mail/display/photo_local");
+
+ e_shell_settings_install_property_for_key (
+ "mail-prompt-delete-in-vfolder",
+ "/apps/evolution/mail/prompts/delete_in_vfolder");
+
+ /* This value corresponds to MailConfigReplyStyle enum,
+ * but the ordering of the combo box items in preferences
+ * has changed. We use transformation functions there. */
+ e_shell_settings_install_property_for_key (
+ "mail-reply-style",
+ "/apps/evolution/mail/format/reply_style");
+
+ e_shell_settings_install_property_for_key (
+ "mail-show-animated-images",
+ "/apps/evolution/mail/display/animated_images");
+
+ e_shell_settings_install_property_for_key (
+ "mail-show-sender-photo",
+ "/apps/evolution/mail/display/sender_photo");
+
+ e_shell_settings_install_property_for_key (
+ "mail-side-bar-search",
+ "/apps/evolution/mail/display/side_bar_search");
+
+ e_shell_settings_install_property_for_key (
+ "mail-use-custom-fonts",
+ "/apps/evolution/mail/display/fonts/use_custom");
+
+ /*** Composer Preferences ***/
+
+ e_shell_settings_install_property_for_key (
+ "composer-charset",
+ "/apps/evolution/mail/composer/charset");
+
+ e_shell_settings_install_property_for_key (
+ "composer-format-html",
+ "/apps/evolution/mail/composer/send_html");
+
+ e_shell_settings_install_property_for_key (
+ "composer-inline-spelling",
+ "/apps/evolution/mail/composer/inline_spelling");
+
+ e_shell_settings_install_property_for_key (
+ "composer-magic-links",
+ "/apps/evolution/mail/composer/magic_links");
+
+ e_shell_settings_install_property_for_key (
+ "composer-magic-smileys",
+ "/apps/evolution/mail/composer/magic_smileys");
+
+ e_shell_settings_install_property_for_key (
+ "composer-outlook-filenames",
+ "/apps/evolution/mail/composer/outlook_filenames");
+
+ e_shell_settings_install_property_for_key (
+ "composer-prompt-only-bcc",
+ "/apps/evolution/mail/prompts/only_bcc");
+
+ e_shell_settings_install_property_for_key (
+ "composer-prompt-empty-subject",
+ "/apps/evolution/mail/prompts/empty_subject");
+
+ e_shell_settings_install_property_for_key (
+ "composer-reply-start-bottom",
+ "/apps/evolution/mail/composer/reply_start_bottom");
+
+ e_shell_settings_install_property_for_key (
+ "composer-request-receipt",
+ "/apps/evolution/mail/composer/request_receipt");
+
+ e_shell_settings_install_property_for_key (
+ "composer-spell-color",
+ "/apps/evolution/mail/composer/spell_color");
+
+ e_shell_settings_install_property_for_key (
+ "composer-top-signature",
+ "/apps/evolution/mail/composer/top_signature");
+}
diff --git a/modules/mail/e-mail-shell-settings.h b/modules/mail/e-mail-shell-settings.h
new file mode 100644
index 0000000000..4267fd8a60
--- /dev/null
+++ b/modules/mail/e-mail-shell-settings.h
@@ -0,0 +1,33 @@
+/*
+ * e-mail-shell-settings.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_SHELL_SETTINGS_H
+#define E_MAIL_SHELL_SETTINGS_H
+
+#include <shell/e-shell.h>
+
+G_BEGIN_DECLS
+
+void e_mail_shell_settings_init (EShell *shell);
+
+G_END_DECLS
+
+#endif /* E_MAIL_SHELL_SETTINGS_H */
diff --git a/modules/mail/e-mail-shell-sidebar.c b/modules/mail/e-mail-shell-sidebar.c
new file mode 100644
index 0000000000..0f8e4f5783
--- /dev/null
+++ b/modules/mail/e-mail-shell-sidebar.c
@@ -0,0 +1,657 @@
+/*
+ * e-mail-shell-sidebar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-shell-sidebar.h"
+
+#include <string.h>
+#include <camel/camel.h>
+
+#include "e-util/e-binding.h"
+
+#include "em-utils.h"
+#include "em-folder-utils.h"
+
+#include "e-mail-local.h"
+#include "e-mail-store.h"
+
+#define E_MAIL_SHELL_SIDEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_SHELL_SIDEBAR, EMailShellSidebarPrivate))
+
+#define STATE_KEY_EXPANDED "Expanded"
+
+struct _EMailShellSidebarPrivate {
+ GtkWidget *folder_tree;
+};
+
+enum {
+ PROP_0,
+ PROP_FOLDER_TREE
+};
+
+static gpointer parent_class;
+static GType mail_shell_sidebar_type;
+
+static void
+mail_shell_sidebar_restore_state (EMailShellSidebar *mail_shell_sidebar)
+{
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ EMFolderTree *folder_tree;
+ GtkTreeModel *tree_model;
+ GtkTreeView *tree_view;
+ GtkTreeIter iter;
+ GKeyFile *key_file;
+ gboolean valid;
+ gchar *selected;
+ gchar **groups;
+ gint ii;
+
+ shell_sidebar = E_SHELL_SIDEBAR (mail_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+ tree_view = GTK_TREE_VIEW (folder_tree);
+ tree_model = gtk_tree_view_get_model (tree_view);
+
+ /* Restore selected folder. */
+
+ selected = g_key_file_get_string (
+ key_file, "Folder Tree", "Selected", NULL);
+ if (selected != NULL) {
+ em_folder_tree_set_selected (folder_tree, selected, FALSE);
+ g_free (selected);
+ }
+
+ /* Set the initial folder tree expanded state in two stages:
+ *
+ * 1) Iterate over the "Store" and "Folder" state file groups
+ * and apply the "Expanded" keys where possible.
+ *
+ * 2) Iterate over the top-level nodes in the folder tree
+ * (these are all stores) and expand those that have no
+ * corresponding "Expanded" key in the state file. This
+ * ensures that new stores are expanded by default.
+ */
+
+ /* Stage 1 */
+
+ groups = g_key_file_get_groups (key_file, NULL);
+
+ for (ii = 0; groups[ii] != NULL; ii++) {
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ const gchar *group_name = groups[ii];
+ const gchar *key = STATE_KEY_EXPANDED;
+ const gchar *uri;
+ gboolean expanded;
+
+ if (g_str_has_prefix (group_name, "Store ")) {
+ uri = group_name + 6;
+ expanded = TRUE;
+ } else if (g_str_has_prefix (group_name, "Folder ")) {
+ uri = group_name + 7;
+ expanded = FALSE;
+ } else
+ continue;
+
+ if (g_key_file_has_key (key_file, group_name, key, NULL))
+ expanded = g_key_file_get_boolean (
+ key_file, group_name, key, NULL);
+
+ if (!expanded)
+ continue;
+
+ reference = em_folder_tree_model_lookup_uri (
+ EM_FOLDER_TREE_MODEL (tree_model), uri);
+ if (reference == NULL)
+ continue;
+
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (tree_model, &iter, path);
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
+ gtk_tree_path_free (path);
+ }
+
+ g_strfreev (groups);
+
+ /* Stage 2 */
+
+ valid = gtk_tree_model_get_iter_first (tree_model, &iter);
+
+ while (valid) {
+ const gchar *key = STATE_KEY_EXPANDED;
+ gchar *group_name;
+ gchar *uri;
+
+ gtk_tree_model_get (
+ tree_model, &iter, COL_STRING_URI, &uri, -1);
+
+ if (uri == NULL)
+ goto next;
+
+ group_name = g_strdup_printf ("Store %s", uri);
+
+ if (!g_key_file_has_key (key_file, group_name, key, NULL)) {
+ GtkTreePath *path;
+
+ path = gtk_tree_model_get_path (tree_model, &iter);
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
+ gtk_tree_path_free (path);
+ }
+
+ g_free (group_name);
+ g_free (uri);
+
+ next:
+ valid = gtk_tree_model_iter_next (tree_model, &iter);
+ }
+}
+
+static void
+mail_shell_sidebar_row_collapsed_cb (EShellSidebar *shell_sidebar,
+ GtkTreeIter *iter,
+ GtkTreePath *path,
+ GtkTreeView *tree_view)
+{
+ EShellView *shell_view;
+ GtkTreeModel *model;
+ GKeyFile *key_file;
+ const gchar *key;
+ gboolean is_folder;
+ gboolean is_store;
+ gchar *group_name;
+ gchar *uri;
+
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ model = gtk_tree_view_get_model (tree_view);
+
+ gtk_tree_model_get (
+ model, iter,
+ COL_STRING_URI, &uri,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_BOOL_IS_FOLDER, &is_folder, -1);
+
+ g_return_if_fail (is_store || is_folder);
+
+ key = STATE_KEY_EXPANDED;
+ if (is_store)
+ group_name = g_strdup_printf ("Store %s", uri);
+ else
+ group_name = g_strdup_printf ("Folder %s", uri);
+
+ g_key_file_set_boolean (key_file, group_name, key, FALSE);
+ e_shell_view_set_state_dirty (shell_view);
+
+ g_free (group_name);
+ g_free (uri);
+}
+
+static void
+mail_shell_sidebar_row_expanded_cb (EShellSidebar *shell_sidebar,
+ GtkTreeIter *unused,
+ GtkTreePath *path,
+ GtkTreeView *tree_view)
+{
+ EShellView *shell_view;
+ GtkTreeModel *model;
+ GKeyFile *key_file;
+ const gchar *key;
+ gboolean is_folder;
+ gboolean is_store;
+ gchar *group_name;
+ gchar *uri;
+
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ path = gtk_tree_path_copy (path);
+ model = gtk_tree_view_get_model (tree_view);
+
+ /* Expand the node and all ancestors. */
+ while (gtk_tree_path_get_depth (path) > 0) {
+ GtkTreeIter iter;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+
+ gtk_tree_model_get (
+ model, &iter,
+ COL_STRING_URI, &uri,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_BOOL_IS_FOLDER, &is_folder, -1);
+
+ g_return_if_fail (is_store || is_folder);
+
+ key = STATE_KEY_EXPANDED;
+ if (is_store)
+ group_name = g_strdup_printf ("Store %s", uri);
+ else
+ group_name = g_strdup_printf ("Folder %s", uri);
+
+ g_key_file_set_boolean (key_file, group_name, key, TRUE);
+ e_shell_view_set_state_dirty (shell_view);
+
+ g_free (group_name);
+ g_free (uri);
+
+ gtk_tree_path_up (path);
+ }
+
+ gtk_tree_path_free (path);
+}
+
+static void
+mail_shell_sidebar_model_loaded_row_cb (EMailShellSidebar *mail_shell_sidebar,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GtkTreeModel *model)
+{
+ EShellSidebar *shell_sidebar;
+ EShellView *shell_view;
+ GtkTreeView *tree_view;
+ GKeyFile *key_file;
+ gboolean is_folder;
+ gboolean is_store;
+ const gchar *key;
+ gchar *group_name;
+ gchar *uri;
+ gboolean expanded;
+
+ shell_sidebar = E_SHELL_SIDEBAR (mail_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ tree_view = GTK_TREE_VIEW (mail_shell_sidebar->priv->folder_tree);
+
+ gtk_tree_model_get (
+ model, iter,
+ COL_STRING_URI, &uri,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_BOOL_IS_FOLDER, &is_folder, -1);
+
+ g_return_if_fail (is_store || is_folder);
+
+ key = STATE_KEY_EXPANDED;
+ if (is_store) {
+ group_name = g_strdup_printf ("Store %s", uri);
+ expanded = TRUE;
+ } else {
+ group_name = g_strdup_printf ("Folder %s", uri);
+ expanded = FALSE;
+ }
+
+ if (g_key_file_has_key (key_file, group_name, key, NULL))
+ expanded = g_key_file_get_boolean (
+ key_file, group_name, key, NULL);
+
+ if (expanded)
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
+
+ g_free (group_name);
+ g_free (uri);
+}
+
+static void
+mail_shell_sidebar_selection_changed_cb (EShellSidebar *shell_sidebar,
+ GtkTreeSelection *selection)
+{
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GKeyFile *key_file;
+ const gchar *icon_name;
+ gchar *display_name = NULL;
+ gchar *uri = NULL;
+ gboolean is_folder = FALSE;
+ guint flags = 0;
+
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ gtk_tree_model_get (
+ model, &iter,
+ COL_STRING_DISPLAY_NAME, &display_name,
+ COL_STRING_URI, &uri,
+ COL_BOOL_IS_FOLDER, &is_folder,
+ COL_UINT_FLAGS, &flags, -1);
+
+ if (uri != NULL)
+ g_key_file_set_string (
+ key_file, "Folder Tree", "Selected", uri);
+ else
+ g_key_file_remove_key (
+ key_file, "Folder Tree", "Selected", NULL);
+
+ e_shell_view_set_state_dirty (shell_view);
+
+ if (is_folder)
+ icon_name = em_folder_utils_get_icon_name (flags);
+ else {
+ icon_name = shell_view_class->icon_name;
+ display_name = g_strdup (shell_view_class->label);
+ }
+
+ e_shell_sidebar_set_icon_name (shell_sidebar, icon_name);
+ e_shell_sidebar_set_primary_text (shell_sidebar, display_name);
+
+ g_free (display_name);
+ g_free (uri);
+}
+
+static void
+mail_shell_sidebar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FOLDER_TREE:
+ g_value_set_object (
+ value, e_mail_shell_sidebar_get_folder_tree (
+ E_MAIL_SHELL_SIDEBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_shell_sidebar_dispose (GObject *object)
+{
+ EMailShellSidebarPrivate *priv;
+
+ priv = E_MAIL_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ if (priv->folder_tree != NULL) {
+ g_object_unref (priv->folder_tree);
+ priv->folder_tree = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_shell_sidebar_finalize (GObject *object)
+{
+ EMailShellSidebarPrivate *priv;
+
+ priv = E_MAIL_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+mail_shell_sidebar_constructed (GObject *object)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EShellSettings *shell_settings;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ EShell *shell;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ /* Chain up to parent's constructed method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ shell_sidebar = E_SHELL_SIDEBAR (object);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (object);
+
+ /* Build sidebar widgets. */
+
+ container = GTK_WIDGET (object);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = em_folder_tree_new ();
+ em_folder_tree_set_excluded (EM_FOLDER_TREE (widget), 0);
+ em_folder_tree_enable_drag_and_drop (EM_FOLDER_TREE (widget));
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ mail_shell_sidebar->priv->folder_tree = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-side-bar-search",
+ G_OBJECT (widget), "enable-search");
+
+ tree_view = GTK_TREE_VIEW (mail_shell_sidebar->priv->folder_tree);
+ selection = gtk_tree_view_get_selection (tree_view);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (em_folder_tree_model_get_selection (
+ EM_FOLDER_TREE_MODEL (model)) == NULL)
+ mail_shell_sidebar_restore_state (mail_shell_sidebar);
+
+ em_folder_tree_model_set_selection (
+ EM_FOLDER_TREE_MODEL (model), selection);
+
+ g_signal_connect_swapped (
+ tree_view, "row-collapsed",
+ G_CALLBACK (mail_shell_sidebar_row_collapsed_cb),
+ shell_sidebar);
+
+ g_signal_connect_swapped (
+ tree_view, "row-expanded",
+ G_CALLBACK (mail_shell_sidebar_row_expanded_cb),
+ shell_sidebar);
+
+ g_signal_connect_swapped (
+ model, "loaded-row",
+ G_CALLBACK (mail_shell_sidebar_model_loaded_row_cb),
+ shell_sidebar);
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (mail_shell_sidebar_selection_changed_cb),
+ shell_sidebar);
+}
+
+static guint32
+mail_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EShellView *shell_view;
+ EMFolderTree *folder_tree;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ CamelFolder *folder;
+ CamelStore *local_store;
+ CamelStore *store;
+ gchar *full_name;
+ gchar *uri;
+ gboolean allows_children = TRUE;
+ gboolean can_delete = TRUE;
+ gboolean is_junk = FALSE;
+ gboolean is_outbox = FALSE;
+ gboolean is_store;
+ gboolean is_trash = FALSE;
+ guint32 folder_flags = 0;
+ guint32 state = 0;
+
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+
+ local_store = e_mail_local_get_store ();
+
+ mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar);
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ tree_view = GTK_TREE_VIEW (folder_tree);
+
+ selection = gtk_tree_view_get_selection (tree_view);
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return 0;
+
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_UINT_FLAGS, &folder_flags,
+ COL_STRING_URI, &uri, -1);
+
+ if (!is_store) {
+ is_junk = (strcmp (full_name, CAMEL_VJUNK_NAME) == 0);
+ is_trash = (strcmp (full_name, CAMEL_VTRASH_NAME) == 0);
+ allows_children = !(is_junk || is_trash);
+
+ /* Don't allow deletion of special local folders. */
+ if (store == local_store)
+ can_delete =
+ (strcmp (full_name, "Drafts") != 0) &&
+ (strcmp (full_name, "Inbox") != 0) &&
+ (strcmp (full_name, "Outbox") != 0) &&
+ (strcmp (full_name, "Sent") != 0) &&
+ (strcmp (full_name, "Templates") != 0);
+
+ folder = em_folder_tree_get_selected_folder (folder_tree);
+ is_outbox = em_utils_folder_is_outbox (folder, NULL);
+ can_delete &= !(folder_flags & CAMEL_FOLDER_SYSTEM);
+ }
+
+ if (allows_children)
+ state |= E_MAIL_SHELL_SIDEBAR_FOLDER_ALLOWS_CHILDREN;
+ if (can_delete)
+ state |= E_MAIL_SHELL_SIDEBAR_FOLDER_CAN_DELETE;
+ if (is_junk)
+ state |= E_MAIL_SHELL_SIDEBAR_FOLDER_IS_JUNK;
+ if (is_outbox)
+ state |= E_MAIL_SHELL_SIDEBAR_FOLDER_IS_OUTBOX;
+ if (is_store)
+ state |= E_MAIL_SHELL_SIDEBAR_FOLDER_IS_STORE;
+ if (is_trash)
+ state |= E_MAIL_SHELL_SIDEBAR_FOLDER_IS_TRASH;
+
+ return state;
+}
+
+static void
+mail_shell_sidebar_class_init (EMailShellSidebarClass *class)
+{
+ GObjectClass *object_class;
+ EShellSidebarClass *shell_sidebar_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailShellSidebarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->get_property = mail_shell_sidebar_get_property;
+ object_class->dispose = mail_shell_sidebar_dispose;
+ object_class->finalize = mail_shell_sidebar_finalize;
+ object_class->constructed = mail_shell_sidebar_constructed;
+
+ shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
+ shell_sidebar_class->check_state = mail_shell_sidebar_check_state;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FOLDER_TREE,
+ g_param_spec_object (
+ "folder-tree",
+ NULL,
+ NULL,
+ EM_TYPE_FOLDER_TREE,
+ G_PARAM_READABLE));
+}
+
+static void
+mail_shell_sidebar_init (EMailShellSidebar *mail_shell_sidebar)
+{
+ mail_shell_sidebar->priv =
+ E_MAIL_SHELL_SIDEBAR_GET_PRIVATE (mail_shell_sidebar);
+
+ /* Postpone widget construction until we have a shell view. */
+}
+
+GType
+e_mail_shell_sidebar_get_type (void)
+{
+ return mail_shell_sidebar_type;
+}
+
+void
+e_mail_shell_sidebar_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EMailShellSidebarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_shell_sidebar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailShellSidebar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_shell_sidebar_init,
+ NULL /* value_table */
+ };
+
+ mail_shell_sidebar_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_SIDEBAR,
+ "EMailShellSidebar", &type_info, 0);
+}
+
+GtkWidget *
+e_mail_shell_sidebar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_SHELL_SIDEBAR,
+ "shell-view", shell_view, NULL);
+}
+
+EMFolderTree *
+e_mail_shell_sidebar_get_folder_tree (EMailShellSidebar *mail_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_MAIL_SHELL_SIDEBAR (mail_shell_sidebar), NULL);
+
+ return EM_FOLDER_TREE (mail_shell_sidebar->priv->folder_tree);
+}
diff --git a/modules/mail/e-mail-shell-sidebar.h b/modules/mail/e-mail-shell-sidebar.h
new file mode 100644
index 0000000000..10a2ff6a2a
--- /dev/null
+++ b/modules/mail/e-mail-shell-sidebar.h
@@ -0,0 +1,81 @@
+/*
+ * e-mail-shell-sidebar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_SHELL_SIDEBAR_H
+#define E_MAIL_SHELL_SIDEBAR_H
+
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+#include <mail/em-folder-tree.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_SHELL_SIDEBAR \
+ (e_mail_shell_sidebar_get_type ())
+#define E_MAIL_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_SHELL_SIDEBAR, EMailShellSidebar))
+#define E_MAIL_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_SHELL_SIDEBAR, EMailShellSidebarClass))
+#define E_IS_MAIL_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_SHELL_SIDEBAR))
+#define E_IS_MAIL_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_SHELL_SIDEBAR))
+#define E_MAIL_SHELL_SIDEBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_SHELL_SIDEBAR, EMailShellSidebarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailShellSidebar EMailShellSidebar;
+typedef struct _EMailShellSidebarClass EMailShellSidebarClass;
+typedef struct _EMailShellSidebarPrivate EMailShellSidebarPrivate;
+
+enum {
+ E_MAIL_SHELL_SIDEBAR_FOLDER_ALLOWS_CHILDREN = 1 << 0,
+ E_MAIL_SHELL_SIDEBAR_FOLDER_CAN_DELETE = 1 << 1,
+ E_MAIL_SHELL_SIDEBAR_FOLDER_IS_JUNK = 1 << 2,
+ E_MAIL_SHELL_SIDEBAR_FOLDER_IS_OUTBOX = 1 << 3,
+ E_MAIL_SHELL_SIDEBAR_FOLDER_IS_STORE = 1 << 4,
+ E_MAIL_SHELL_SIDEBAR_FOLDER_IS_TRASH = 1 << 5
+};
+
+struct _EMailShellSidebar {
+ EShellSidebar parent;
+ EMailShellSidebarPrivate *priv;
+};
+
+struct _EMailShellSidebarClass {
+ EShellSidebarClass parent_class;
+};
+
+GType e_mail_shell_sidebar_get_type (void);
+void e_mail_shell_sidebar_register_type
+ (GTypeModule *type_module);
+GtkWidget * e_mail_shell_sidebar_new(EShellView *shell_view);
+EMFolderTree * e_mail_shell_sidebar_get_folder_tree
+ (EMailShellSidebar *mail_shell_sidebar);
+
+G_END_DECLS
+
+#endif /* E_MAIL_SHELL_SIDEBAR_H */
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
new file mode 100644
index 0000000000..5e6a9ba9cf
--- /dev/null
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -0,0 +1,1844 @@
+/*
+ * e-mail-shell-view-actions.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-shell-view-private.h"
+
+#define STATE_KEY_SEARCH_FILTER "SearchFilter"
+#define STATE_KEY_SEARCH_SCOPE "SearchScope"
+#define STATE_KEY_SEARCH_TEXT "SearchText"
+
+static void
+action_gal_save_custom_view_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellContent *mail_shell_content;
+ EShellView *shell_view;
+ GalViewInstance *view_instance;
+
+ /* All shell views repond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with saving the custom view. */
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ mail_shell_content = mail_shell_view->priv->mail_shell_content;
+ view_instance = e_mail_shell_content_get_view_instance (mail_shell_content);
+ gal_view_instance_save_as (view_instance);
+}
+
+static void
+action_mail_account_disable_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EMFolderTree *folder_tree;
+ EAccountList *account_list;
+ EAccount *account;
+ gchar *folder_uri;
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ folder_uri = em_folder_tree_get_selected_uri (folder_tree);
+ g_return_if_fail (folder_uri != NULL);
+
+ account_list = e_get_account_list ();
+ account = mail_config_get_account_by_source_url (folder_uri);
+ g_return_if_fail (account != NULL);
+
+ if (e_account_list_account_has_proxies (account_list, account))
+ e_account_list_remove_account_proxies (account_list, account);
+
+ account->enabled = !account->enabled;
+ e_account_list_change (account_list, account);
+ e_mail_store_remove_by_uri (folder_uri);
+
+ if (account->parent_uid != NULL)
+ e_account_list_remove (account_list, account);
+
+ e_account_list_save (account_list);
+
+ g_free (folder_uri);
+}
+
+static void
+action_mail_create_search_folder_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ /* FIXME */
+ g_print ("Action: %s\n", gtk_action_get_name (GTK_ACTION (action)));
+}
+
+static void
+action_mail_download_foreach_cb (CamelService *service)
+{
+ if (CAMEL_IS_DISCO_STORE (service) || CAMEL_IS_OFFLINE_STORE (service))
+ mail_store_prepare_offline (CAMEL_STORE (service));
+}
+
+static void
+action_mail_download_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ e_mail_store_foreach ((GHFunc) action_mail_download_foreach_cb, NULL);
+}
+
+static void
+action_mail_empty_trash_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ em_utils_empty_trash (GTK_WIDGET (shell_window));
+}
+
+static void
+action_mail_flush_outbox_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ mail_send ();
+}
+
+static void
+action_mail_folder_copy_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ CamelFolderInfo *folder_info;
+ EMFolderTree *folder_tree;
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ folder_info = em_folder_tree_get_selected_folder_info (folder_tree);
+ g_return_if_fail (folder_info != NULL);
+
+ /* XXX Leaking folder_info? */
+ em_folder_utils_copy_folder (folder_info, FALSE);
+}
+
+static void
+action_mail_folder_delete_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EMFolderTree *folder_tree;
+ CamelFolder *folder;
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ folder = em_folder_tree_get_selected_folder (folder_tree);
+ g_return_if_fail (folder != NULL);
+
+ em_folder_utils_delete_folder (folder);
+}
+
+static void
+action_mail_folder_expunge_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailReader *reader;
+ MessageList *message_list;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ g_return_if_fail (message_list->folder != NULL);
+
+ em_utils_expunge_folder (
+ GTK_WIDGET (shell_window), message_list->folder);
+}
+
+static void
+action_mail_folder_mark_all_as_read_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailReader *reader;
+ MessageList *message_list;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ CamelFolder *folder;
+ GtkWindow *parent;
+ GPtrArray *uids;
+ const gchar *key;
+ const gchar *prompt;
+ guint ii;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ parent = GTK_WINDOW (shell_window);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder = message_list->folder;
+ g_return_if_fail (folder != NULL);
+
+ key = "/apps/evolution/mail/prompts/mark_all_read";
+ prompt = "mail:ask-mark-all-read";
+
+ if (!em_utils_prompt_user (parent, key, prompt, NULL))
+ return;
+
+ uids = message_list_get_uids (message_list);
+
+ camel_folder_freeze (folder);
+ for (ii = 0; ii < uids->len; ii++)
+ camel_folder_set_message_flags (
+ folder, uids->pdata[ii],
+ CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
+ camel_folder_thaw (folder);
+
+ message_list_free_uids (message_list, uids);
+}
+
+static void
+action_mail_folder_move_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ CamelFolderInfo *folder_info;
+ EMFolderTree *folder_tree;
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ folder_info = em_folder_tree_get_selected_folder_info (folder_tree);
+ g_return_if_fail (folder_info != NULL);
+
+ /* XXX Leaking folder_info? */
+ em_folder_utils_copy_folder (folder_info, TRUE);
+}
+
+static void
+action_mail_folder_new_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EMailShellSidebar *mail_shell_sidebar;
+ CamelFolderInfo *folder_info;
+ EMFolderTree *folder_tree;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ folder_info = em_folder_tree_get_selected_folder_info (folder_tree);
+ g_return_if_fail (folder_info != NULL);
+
+ em_folder_utils_create_folder (
+ folder_info, folder_tree, GTK_WINDOW (shell_window));
+ camel_folder_info_free (folder_info);
+}
+
+static void
+action_mail_folder_properties_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EMFolderTree *folder_tree;
+ EShellView *shell_view;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *uri;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+ tree_view = GTK_TREE_VIEW (folder_tree);
+ selection = gtk_tree_view_get_selection (tree_view);
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_URI, &uri, -1);
+ em_folder_properties_show (shell_view, NULL, uri);
+ g_free (uri);
+}
+
+static void
+action_mail_folder_refresh_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EMFolderTree *folder_tree;
+ CamelFolder *folder;
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ folder = em_folder_tree_get_selected_folder (folder_tree);
+ g_return_if_fail (folder != NULL);
+
+ mail_refresh_folder (folder, NULL, NULL);
+}
+
+static void
+action_mail_folder_rename_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EMFolderTree *folder_tree;
+ CamelFolder *folder;
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ folder = em_folder_tree_get_selected_folder (folder_tree);
+ g_return_if_fail (folder != NULL);
+
+ em_folder_utils_rename_folder (folder);
+}
+
+/* Helper for action_mail_folder_select_all_cb() */
+static gboolean
+action_mail_folder_select_all_timeout_cb (MessageList *message_list)
+{
+ message_list_select_all (message_list);
+ gtk_widget_grab_focus (GTK_WIDGET (message_list));
+
+ return FALSE;
+}
+
+static void
+action_mail_folder_select_all_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailReader *reader;
+ MessageList *message_list;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ if (message_list->threaded) {
+ gtk_action_activate (ACTION (MAIL_THREADS_EXPAND_ALL));
+
+ /* XXX The timeout below is added so that the execution
+ * thread to expand all conversation threads would
+ * have completed. The timeout 505 is just to ensure
+ * that the value is a small delta more than the
+ * timeout value in mail_regen_list(). */
+ g_timeout_add (
+ 505, (GSourceFunc)
+ action_mail_folder_select_all_timeout_cb,
+ message_list);
+ } else
+ /* If there is no threading, just select all immediately. */
+ action_mail_folder_select_all_timeout_cb (message_list);
+}
+
+static void
+action_mail_folder_select_thread_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ MessageList *message_list;
+ EMailReader *reader;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ message_list_select_thread (message_list);
+}
+
+static void
+action_mail_folder_select_subthread_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ MessageList *message_list;
+ EMailReader *reader;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ message_list_select_subthread (message_list);
+}
+
+static void
+action_mail_folder_unsubscribe_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellSidebar *mail_shell_sidebar;
+ EMFolderTree *folder_tree;
+ gchar *folder_uri;
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+ folder_uri = em_folder_tree_get_selected_uri (folder_tree);
+ em_folder_utils_unsubscribe_folder (folder_uri);
+ g_free (folder_uri);
+}
+
+static void
+action_mail_hide_deleted_cb (GtkToggleAction *action,
+ EMailShellView *mail_shell_view)
+{
+ MessageList *message_list;
+ EMailReader *reader;
+ gboolean active;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ active = gtk_toggle_action_get_active (action);
+ message_list_set_hidedeleted (message_list, active);
+}
+
+static void
+action_mail_hide_read_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ MessageList *message_list;
+ EMailReader *reader;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ message_list_hide_add (
+ message_list,
+ "(match-all (system-flag \"seen\"))",
+ ML_HIDE_SAME, ML_HIDE_SAME);
+}
+
+static void
+action_mail_hide_selected_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ MessageList *message_list;
+ EMailReader *reader;
+ GPtrArray *uids;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ uids = message_list_get_selected (message_list);
+ message_list_hide_uids (message_list, uids);
+ message_list_free_uids (message_list, uids);
+}
+
+static void
+action_mail_label_cb (GtkToggleAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailReader *reader;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+ const gchar *tag;
+ gint ii;
+
+ tag = g_object_get_data (G_OBJECT (action), "tag");
+ g_return_if_fail (tag != NULL);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder = message_list->folder;
+
+ uids = message_list_get_selected (message_list);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ if (gtk_toggle_action_get_active (action))
+ camel_folder_set_message_user_flag (
+ folder, uids->pdata[ii], tag, TRUE);
+ else {
+ camel_folder_set_message_user_flag (
+ folder, uids->pdata[ii], tag, FALSE);
+ camel_folder_set_message_user_tag (
+ folder, uids->pdata[ii], "label", NULL);
+ }
+ }
+
+ message_list_free_uids (message_list, uids);
+}
+
+static void
+action_mail_label_new_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ EMailLabelDialog *label_dialog;
+ EMailLabelListStore *store;
+ EMailReader *reader;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *dialog;
+ GPtrArray *uids;
+ GdkColor label_color;
+ const gchar *property_name;
+ const gchar *label_name;
+ gchar *label_tag;
+ gint n_children;
+ guint ii;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ dialog = e_mail_label_dialog_new (GTK_WINDOW (shell_window));
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Add Label"));
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ label_dialog = E_MAIL_LABEL_DIALOG (dialog);
+ label_name = e_mail_label_dialog_get_label_name (label_dialog);
+ e_mail_label_dialog_get_label_color (label_dialog, &label_color);
+
+ property_name = "mail-label-list-store";
+ store = e_shell_settings_get_object (shell_settings, property_name);
+ e_mail_label_list_store_set (store, NULL, label_name, &label_color);
+ g_object_unref (store);
+
+ /* XXX This is awkward. We've added a new label to the list store
+ * but we don't have the new label's tag nor an iterator to use
+ * to fetch it. We know the label was appended to the store,
+ * so we have to dig it out manually. EMailLabelListStore API
+ * probably needs some rethinking. */
+ model = GTK_TREE_MODEL (store);
+ n_children = gtk_tree_model_iter_n_children (model, NULL);
+ gtk_tree_model_iter_nth_child (model, &iter, NULL, n_children - 1);
+ label_tag = e_mail_label_list_store_get_tag (store, &iter);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder = message_list->folder;
+
+ uids = message_list_get_selected (message_list);
+
+ for (ii = 0; ii < uids->len; ii++)
+ camel_folder_set_message_user_flag (
+ folder, uids->pdata[ii], label_tag, TRUE);
+
+ message_list_free_uids (message_list, uids);
+
+ g_free (label_tag);
+
+exit:
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_mail_label_none_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellSettings *shell_settings;
+ EShellWindow *shell_window;
+ EMailReader *reader;
+ MessageList *message_list;
+ GtkTreeModel *tree_model;
+ CamelFolder *folder;
+ GtkTreeIter iter;
+ GPtrArray *uids;
+ gboolean valid;
+ guint ii;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ tree_model = e_shell_settings_get_object (
+ shell_settings, "mail-label-list-store");
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ uids = message_list_get_selected (message_list);
+ folder = message_list->folder;
+
+ valid = gtk_tree_model_get_iter_first (tree_model, &iter);
+
+ while (valid) {
+ gchar *tag;
+
+ tag = e_mail_label_list_store_get_tag (
+ E_MAIL_LABEL_LIST_STORE (tree_model), &iter);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ camel_folder_set_message_user_flag (
+ folder, uids->pdata[ii], tag, FALSE);
+ camel_folder_set_message_user_tag (
+ folder, uids->pdata[ii], "label", NULL);
+ }
+
+ g_free (tag);
+
+ valid = gtk_tree_model_iter_next (tree_model, &iter);
+ }
+
+ message_list_free_uids (message_list, uids);
+}
+
+static void
+action_mail_search_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMailShellView *mail_shell_view)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *search_hint;
+
+ /* XXX Figure out a way to handle this in EShellContent
+ * instead of every shell view having to handle it.
+ * The problem is EShellContent does not know what
+ * the search option actions are for this view. It
+ * would have to dig up the popup menu and retrieve
+ * the action for each menu item. Seems messy. */
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ search_hint = gtk_action_get_label (GTK_ACTION (current));
+ e_shell_content_set_search_hint (shell_content, search_hint);
+}
+
+static void
+action_mail_show_hidden_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ MessageList *message_list;
+ EMailReader *reader;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ message_list_hide_clear (message_list);
+}
+
+static void
+action_mail_smart_backward_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSettings *shell_settings;
+ EMailShellSidebar *mail_shell_sidebar;
+ EMFolderTree *folder_tree;
+ EMFormatHTMLDisplay *html_display;
+ EMailReader *reader;
+ MessageList *message_list;
+ GtkToggleAction *toggle_action;
+ GtkHTML *html;
+ gboolean caret_mode;
+ gboolean magic_spacebar;
+
+ /* This implements the so-called "Magic Backspace". */
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ magic_spacebar = e_shell_settings_get_boolean (
+ shell_settings, "mail-magic-spacebar");
+
+ toggle_action = GTK_TOGGLE_ACTION (ACTION (MAIL_CARET_MODE));
+ caret_mode = gtk_toggle_action_get_active (toggle_action);
+
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ if (gtk_html_command (html, "scroll-backward"))
+ return;
+
+ if (caret_mode || !magic_spacebar)
+ return;
+
+ /* XXX Are two separate calls really necessary? */
+
+ if (message_list_select (
+ message_list, MESSAGE_LIST_SELECT_PREVIOUS,
+ 0, CAMEL_MESSAGE_SEEN))
+ return;
+
+ if (message_list_select (
+ message_list, MESSAGE_LIST_SELECT_PREVIOUS |
+ MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN))
+ return;
+
+ em_folder_tree_select_prev_path (folder_tree, TRUE);
+
+ gtk_widget_grab_focus (GTK_WIDGET (message_list));
+}
+
+static void
+action_mail_smart_forward_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSettings *shell_settings;
+ EMailShellSidebar *mail_shell_sidebar;
+ EMFolderTree *folder_tree;
+ EMFormatHTMLDisplay *html_display;
+ EMailReader *reader;
+ MessageList *message_list;
+ GtkToggleAction *toggle_action;
+ GtkHTML *html;
+ gboolean caret_mode;
+ gboolean magic_spacebar;
+
+ /* This implements the so-called "Magic Spacebar". */
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ magic_spacebar = e_shell_settings_get_boolean (
+ shell_settings, "mail-magic-spacebar");
+
+ toggle_action = GTK_TOGGLE_ACTION (ACTION (MAIL_CARET_MODE));
+ caret_mode = gtk_toggle_action_get_active (toggle_action);
+
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ if (gtk_html_command (html, "scroll-forward"))
+ return;
+
+ if (caret_mode || !magic_spacebar)
+ return;
+
+ /* XXX Are two separate calls really necessary? */
+
+ if (message_list_select (
+ message_list, MESSAGE_LIST_SELECT_NEXT,
+ 0, CAMEL_MESSAGE_SEEN))
+ return;
+
+ if (message_list_select (
+ message_list, MESSAGE_LIST_SELECT_NEXT |
+ MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN))
+ return;
+
+ em_folder_tree_select_next_path (folder_tree, TRUE);
+
+ gtk_widget_grab_focus (GTK_WIDGET (message_list));
+}
+
+static void
+action_mail_stop_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ mail_cancel_all ();
+}
+
+static void
+action_mail_threads_collapse_all_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ MessageList *message_list;
+ EMailReader *reader;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ message_list_set_threaded_collapse_all (message_list);
+}
+
+static void
+action_mail_threads_expand_all_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ MessageList *message_list;
+ EMailReader *reader;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ message_list_set_threaded_expand_all (message_list);
+}
+
+static void
+action_mail_threads_group_by_cb (GtkToggleAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellContent *mail_shell_content;
+ MessageList *message_list;
+ EMailReader *reader;
+ gboolean active;
+
+ mail_shell_content = mail_shell_view->priv->mail_shell_content;
+ active = gtk_toggle_action_get_active (action);
+
+ reader = E_MAIL_READER (mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ message_list_set_threaded (message_list, active);
+}
+
+static void
+action_mail_tools_filters_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ em_utils_edit_filters (GTK_WIDGET (shell_window));
+}
+
+static void
+action_mail_tools_search_folders_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ vfolder_edit (E_SHELL_VIEW (mail_shell_view));
+}
+
+static void
+action_mail_tools_subscriptions_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GtkWidget *dialog;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ dialog = em_subscribe_editor_new ();
+ gtk_window_set_transient_for (
+ GTK_WINDOW (dialog), GTK_WINDOW (shell_window));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ /* XXX Dialog destroys itself. */
+}
+
+static void
+action_mail_view_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMailShellView *mail_shell_view)
+{
+ EMailShellContent *mail_shell_content;
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+
+ mail_shell_content = mail_shell_view->priv->mail_shell_content;
+ orientable = GTK_ORIENTABLE (mail_shell_content);
+
+ switch (gtk_radio_action_get_current_value (action)) {
+ case 0:
+ orientation = GTK_ORIENTATION_VERTICAL;
+ break;
+ case 1:
+ orientation = GTK_ORIENTATION_HORIZONTAL;
+ break;
+ default:
+ g_return_if_reached ();
+ }
+
+ gtk_orientable_set_orientation (orientable, orientation);
+}
+
+static void
+action_search_execute_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ EMailReader *reader;
+ MessageList *message_list;
+ GKeyFile *key_file;
+ const gchar *folder_uri;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ /* All shell views respond to the activation of this action,
+ * which is defined by EShellWindow. But only the currently
+ * active shell view proceeds with executing the search. */
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder_uri = message_list->folder_uri;
+
+ if (folder_uri != NULL) {
+ const gchar *key;
+ const gchar *string;
+ gchar *group_name;
+
+ key = STATE_KEY_SEARCH_TEXT;
+ string = e_shell_content_get_search_text (shell_content);
+ group_name = g_strdup_printf ("Folder %s", folder_uri);
+
+ if (string != NULL && *string != '\0')
+ g_key_file_set_string (
+ key_file, group_name, key, string);
+ else
+ g_key_file_remove_key (
+ key_file, group_name, key, NULL);
+ e_shell_view_set_state_dirty (shell_view);
+
+ g_free (group_name);
+ }
+
+ e_mail_shell_view_execute_search (mail_shell_view);
+}
+
+static void
+action_search_filter_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMailShellView *mail_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EMailReader *reader;
+ MessageList *message_list;
+ GKeyFile *key_file;
+ const gchar *folder_uri;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder_uri = message_list->folder_uri;
+
+ if (folder_uri != NULL) {
+ const gchar *key;
+ const gchar *string;
+ gchar *group_name;
+
+ key = STATE_KEY_SEARCH_FILTER;
+ string = gtk_action_get_name (GTK_ACTION (current));
+ group_name = g_strdup_printf ("Folder %s", folder_uri);
+
+ g_key_file_set_string (key_file, group_name, key, string);
+ e_shell_view_set_state_dirty (shell_view);
+
+ g_free (group_name);
+ }
+
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+}
+
+static void
+action_search_scope_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMailShellView *mail_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EMailReader *reader;
+ MessageList *message_list;
+ GKeyFile *key_file;
+ const gchar *folder_uri;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder_uri = message_list->folder_uri;
+
+ if (folder_uri != NULL) {
+ const gchar *key;
+ const gchar *string;
+ gchar *group_name;
+
+ key = STATE_KEY_SEARCH_SCOPE;
+ string = gtk_action_get_name (GTK_ACTION (current));
+ group_name = g_strdup_printf ("Folder %s", folder_uri);
+
+ g_key_file_set_string (key_file, group_name, key, string);
+ e_shell_view_set_state_dirty (shell_view);
+
+ g_free (group_name);
+ }
+
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+}
+
+static GtkActionEntry mail_entries[] = {
+
+ { "mail-account-disable",
+ NULL,
+ N_("_Disable Account"),
+ NULL,
+ N_("Disable this account"),
+ G_CALLBACK (action_mail_account_disable_cb) },
+
+ { "mail-create-search-folder",
+ NULL,
+ N_("C_reate Search Folder From Search..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_mail_create_search_folder_cb) },
+
+ { "mail-download",
+ NULL,
+ N_("_Download Messages for Offline Usage"),
+ NULL,
+ N_("Download messages of accounts and folders marked for offline"),
+ G_CALLBACK (action_mail_download_cb) },
+
+ { "mail-empty-trash",
+ NULL,
+ N_("Empty _Trash"),
+ NULL,
+ N_("Permanently remove all the deleted messages from all folders"),
+ G_CALLBACK (action_mail_empty_trash_cb) },
+
+ { "mail-flush-outbox",
+ "mail-send",
+ N_("Fl_ush Outbox"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_mail_flush_outbox_cb) },
+
+ { "mail-folder-copy",
+ "folder-copy",
+ N_("_Copy Folder To..."),
+ NULL,
+ N_("Copy the selected folder into another folder"),
+ G_CALLBACK (action_mail_folder_copy_cb) },
+
+ { "mail-folder-delete",
+ GTK_STOCK_DELETE,
+ NULL,
+ NULL,
+ N_("Permanently remove this folder"),
+ G_CALLBACK (action_mail_folder_delete_cb) },
+
+ { "mail-folder-expunge",
+ NULL,
+ N_("E_xpunge"),
+ "<Control>e",
+ N_("Permanently remove all deleted messages from this folder"),
+ G_CALLBACK (action_mail_folder_expunge_cb) },
+
+ { "mail-folder-mark-all-as-read",
+ "mail-read",
+ N_("Mar_k All Messages as Read"),
+ NULL,
+ N_("Mark all messages in the folder as read"),
+ G_CALLBACK (action_mail_folder_mark_all_as_read_cb) },
+
+ { "mail-folder-move",
+ "folder-move",
+ N_("_Move Folder To..."),
+ NULL,
+ N_("Move the selected folder into another folder"),
+ G_CALLBACK (action_mail_folder_move_cb) },
+
+ { "mail-folder-new",
+ "folder-new",
+ N_("_New..."),
+ NULL,
+ N_("Create a new folder for storing mail"),
+ G_CALLBACK (action_mail_folder_new_cb) },
+
+ { "mail-folder-properties",
+ GTK_STOCK_PROPERTIES,
+ NULL,
+ NULL,
+ N_("Change the properties of this folder"),
+ G_CALLBACK (action_mail_folder_properties_cb) },
+
+ { "mail-folder-refresh",
+ GTK_STOCK_REFRESH,
+ NULL,
+ "F5",
+ N_("Refresh the folder"),
+ G_CALLBACK (action_mail_folder_refresh_cb) },
+
+ { "mail-folder-rename",
+ NULL,
+ N_("_Rename..."),
+ "F2",
+ N_("Change the name of this folder"),
+ G_CALLBACK (action_mail_folder_rename_cb) },
+
+ { "mail-folder-select-all",
+ NULL,
+ N_("Select _All Messages"),
+ "<Control>a",
+ N_("Select all visible messages"),
+ G_CALLBACK (action_mail_folder_select_all_cb) },
+
+ { "mail-folder-select-thread",
+ NULL,
+ N_("Select Message _Thread"),
+ "<Control>h",
+ N_("Select all messages in the same thread as the selected message"),
+ G_CALLBACK (action_mail_folder_select_thread_cb) },
+
+ { "mail-folder-select-subthread",
+ NULL,
+ N_("Select Message S_ubthread"),
+ "<Shift><Control>h",
+ N_("Select all replies to the currently selected message"),
+ G_CALLBACK (action_mail_folder_select_subthread_cb) },
+
+ { "mail-folder-unsubscribe",
+ NULL,
+ N_("_Unsubscribe"),
+ NULL,
+ N_("Unsubscribe from the selected folder"),
+ G_CALLBACK (action_mail_folder_unsubscribe_cb) },
+
+ { "mail-label-new",
+ NULL,
+ N_("_New Label"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_mail_label_new_cb) },
+
+ { "mail-label-none",
+ NULL,
+ N_("N_one"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_mail_label_none_cb) },
+
+ { "mail-hide-read",
+ NULL,
+ N_("Hide _Read Messages"),
+ NULL,
+ N_("Temporarily hide all messages that have already been read"),
+ G_CALLBACK (action_mail_hide_read_cb) },
+
+ { "mail-hide-selected",
+ NULL,
+ N_("Hide S_elected Messages"),
+ NULL,
+ N_("Temporarily hide the selected messages"),
+ G_CALLBACK (action_mail_hide_selected_cb) },
+
+ { "mail-show-hidden",
+ NULL,
+ N_("Show Hidde_n Messages"),
+ NULL,
+ N_("Show messages that have been temporarily hidden"),
+ G_CALLBACK (action_mail_show_hidden_cb) },
+
+ { "mail-smart-backward",
+ NULL,
+ NULL, /* No menu item; key press only */
+ NULL,
+ NULL,
+ G_CALLBACK (action_mail_smart_backward_cb) },
+
+ { "mail-smart-forward",
+ NULL,
+ NULL, /* No menu item; key press only */
+ NULL,
+ NULL,
+ G_CALLBACK (action_mail_smart_forward_cb) },
+
+ { "mail-stop",
+ GTK_STOCK_STOP,
+ N_("Cancel"),
+ NULL,
+ N_("Cancel the current mail operation"),
+ G_CALLBACK (action_mail_stop_cb) },
+
+ { "mail-threads-collapse-all",
+ NULL,
+ N_("Collapse All _Threads"),
+ "<Shift><Control>b",
+ N_("Collapse all message threads"),
+ G_CALLBACK (action_mail_threads_collapse_all_cb) },
+
+ { "mail-threads-expand-all",
+ NULL,
+ N_("E_xpand All Threads"),
+ NULL,
+ N_("Expand all message threads"),
+ G_CALLBACK (action_mail_threads_expand_all_cb) },
+
+ { "mail-tools-filters",
+ NULL,
+ N_("_Message Filters"),
+ NULL,
+ N_("Create or edit rules for filtering new mail"),
+ G_CALLBACK (action_mail_tools_filters_cb) },
+
+ { "mail-tools-search-folders",
+ NULL,
+ N_("Search F_olders"),
+ NULL,
+ N_("Create or edit search folder definitions"),
+ G_CALLBACK (action_mail_tools_search_folders_cb) },
+
+ { "mail-tools-subscriptions",
+ NULL,
+ N_("_Subscriptions..."),
+ NULL,
+ N_("Subscribe or unsubscribe to folders on remote servers"),
+ G_CALLBACK (action_mail_tools_subscriptions_cb) },
+
+ /*** Menus ***/
+
+ { "mail-folder-menu",
+ NULL,
+ N_("F_older"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-label-menu",
+ NULL,
+ N_("_Label"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-preview-menu",
+ NULL,
+ N_("_Preview"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static EPopupActionEntry mail_popup_entries[] = {
+
+ { "mail-popup-account-disable",
+ NULL,
+ "mail-account-disable" },
+
+ { "mail-popup-empty-trash",
+ NULL,
+ "mail-empty-trash" },
+
+ { "mail-popup-flush-outbox",
+ NULL,
+ "mail-flush-outbox" },
+
+ { "mail-popup-folder-copy",
+ NULL,
+ "mail-folder-copy" },
+
+ { "mail-popup-folder-delete",
+ NULL,
+ "mail-folder-delete" },
+
+ { "mail-popup-folder-move",
+ NULL,
+ "mail-folder-move" },
+
+ { "mail-popup-folder-new",
+ N_("_New Folder..."),
+ "mail-folder-new" },
+
+ { "mail-popup-folder-properties",
+ NULL,
+ "mail-folder-properties" },
+
+ { "mail-popup-folder-refresh",
+ NULL,
+ "mail-folder-refresh" },
+
+ { "mail-popup-folder-rename",
+ NULL,
+ "mail-folder-rename" },
+
+ { "mail-popup-folder-unsubscribe",
+ NULL,
+ "mail-folder-unsubscribe" }
+};
+
+static GtkToggleActionEntry mail_toggle_entries[] = {
+
+ { "mail-hide-deleted",
+ NULL,
+ N_("Hide _Deleted Messages"),
+ NULL,
+ N_("Hide deleted messages rather than displaying "
+ "them with a line through them"),
+ G_CALLBACK (action_mail_hide_deleted_cb),
+ TRUE },
+
+ { "mail-preview",
+ NULL,
+ N_("Show Message _Preview"),
+ "<Control>m",
+ N_("Show message preview pane"),
+ NULL, /* Handled by property bindings */
+ TRUE },
+
+ { "mail-threads-group-by",
+ NULL,
+ N_("_Group By Threads"),
+ "<Control>t",
+ N_("Threaded message list"),
+ G_CALLBACK (action_mail_threads_group_by_cb),
+ FALSE }
+};
+
+static GtkRadioActionEntry mail_view_entries[] = {
+
+ /* This action represents the initial active mail view.
+ * It should not be visible in the UI, nor should it be
+ * possible to switch to it from another shell view. */
+ { "mail-view-initial",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ -1 },
+
+ { "mail-view-classic",
+ NULL,
+ N_("_Classic View"),
+ NULL,
+ N_("Show message preview below the message list"),
+ 0 },
+
+ { "mail-view-vertical",
+ NULL,
+ N_("_Vertical View"),
+ NULL,
+ N_("Show message preview alongside the message list"),
+ 1 }
+};
+
+static GtkRadioActionEntry mail_filter_entries[] = {
+
+ { "mail-filter-all-messages",
+ NULL,
+ N_("All Messages"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_ALL_MESSAGES },
+
+ { "mail-filter-important-messages",
+ "emblem-important",
+ N_("Important Messages"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_IMPORTANT_MESSAGES },
+
+ { "mail-filter-last-5-days-messages",
+ NULL,
+ N_("Last 5 Days' Messages"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_LAST_5_DAYS_MESSAGES },
+
+ { "mail-filter-messages-not-junk",
+ "mail-mark-notjunk",
+ N_("Messages Not Junk"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_MESSAGES_NOT_JUNK },
+
+ { "mail-filter-messages-with-attachments",
+ "mail-attachment",
+ N_("Messages with Attachments"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_MESSAGES_WITH_ATTACHMENTS },
+
+ { "mail-filter-no-label",
+ NULL,
+ N_("No Label"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_NO_LABEL },
+
+ { "mail-filter-read-messages",
+ "mail-read",
+ N_("Read Messages"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_READ_MESSAGES },
+
+ { "mail-filter-recent-messages",
+ NULL,
+ N_("Recent Messages"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_RECENT_MESSAGES },
+
+ { "mail-filter-unread-messages",
+ "mail-unread",
+ N_("Unread Messages"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_FILTER_UNREAD_MESSAGES }
+};
+
+static GtkRadioActionEntry mail_search_entries[] = {
+
+ { "mail-search-body-contains",
+ NULL,
+ N_("Body contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SEARCH_BODY_CONTAINS },
+
+ { "mail-search-message-contains",
+ NULL,
+ N_("Message contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SEARCH_MESSAGE_CONTAINS },
+
+ { "mail-search-recipients-contain",
+ NULL,
+ N_("Recipients contain"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SEARCH_RECIPIENTS_CONTAIN },
+
+ { "mail-search-sender-contains",
+ NULL,
+ N_("Sender contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SEARCH_SENDER_CONTAINS },
+
+ { "mail-search-subject-contains",
+ NULL,
+ N_("Subject contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SEARCH_SUBJECT_CONTAINS },
+
+ { "mail-search-subject-or-recipients-contains",
+ NULL,
+ N_("Subject or Recipients contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SEARCH_SUBJECT_OR_RECIPIENTS_CONTAINS },
+
+ { "mail-search-subject-or-sender-contains",
+ NULL,
+ N_("Subject or Sender contains"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SEARCH_SUBJECT_OR_SENDER_CONTAINS }
+};
+
+static GtkRadioActionEntry mail_scope_entries[] = {
+
+ { "mail-scope-all-accounts",
+ NULL,
+ N_("All Accounts"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SCOPE_ALL_ACCOUNTS },
+
+ { "mail-scope-current-account",
+ NULL,
+ N_("Current Account"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SCOPE_CURRENT_ACCOUNT },
+
+ { "mail-scope-current-folder",
+ NULL,
+ N_("Current Folder"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ MAIL_SCOPE_CURRENT_FOLDER }
+};
+
+void
+e_mail_shell_view_actions_init (EMailShellView *mail_shell_view)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ GtkActionGroup *action_group;
+ GtkRadioAction *radio_action;
+ GConfBridge *bridge;
+ GObject *object;
+ GObject *src_object;
+ GObject *dst_object;
+ const gchar *key;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ /* Mail Actions */
+ action_group = ACTION_GROUP (MAIL);
+ gtk_action_group_add_actions (
+ action_group, mail_entries,
+ G_N_ELEMENTS (mail_entries), mail_shell_view);
+ e_action_group_add_popup_actions (
+ action_group, mail_popup_entries,
+ G_N_ELEMENTS (mail_popup_entries));
+ gtk_action_group_add_toggle_actions (
+ action_group, mail_toggle_entries,
+ G_N_ELEMENTS (mail_toggle_entries), mail_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, mail_view_entries,
+ G_N_ELEMENTS (mail_view_entries), -1,
+ G_CALLBACK (action_mail_view_cb), mail_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, mail_search_entries,
+ G_N_ELEMENTS (mail_search_entries),
+ MAIL_SEARCH_SUBJECT_OR_SENDER_CONTAINS,
+ G_CALLBACK (action_mail_search_cb), mail_shell_view);
+ gtk_action_group_add_radio_actions (
+ action_group, mail_scope_entries,
+ G_N_ELEMENTS (mail_scope_entries),
+ MAIL_SCOPE_CURRENT_FOLDER,
+ G_CALLBACK (action_search_scope_cb), mail_shell_view);
+
+ radio_action = GTK_RADIO_ACTION (ACTION (MAIL_SCOPE_ALL_ACCOUNTS));
+ e_shell_content_set_scope_action (shell_content, radio_action);
+ e_shell_content_set_scope_visible (shell_content, TRUE);
+
+ /* Bind GObject properties for GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (ACTION (MAIL_PREVIEW));
+ key = "/apps/evolution/mail/display/show_preview";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (MAIL_THREADS_GROUP_BY));
+ key = "/apps/evolution/mail/display/thread_list";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (MAIL_VIEW_VERTICAL));
+ key = "/apps/evolution/mail/display/layout";
+ gconf_bridge_bind_property (bridge, key, object, "current-value");
+
+ /* Fine tuning. */
+
+ src_object = G_OBJECT (ACTION (MAIL_THREADS_GROUP_BY));
+
+ dst_object = G_OBJECT (ACTION (MAIL_FOLDER_SELECT_THREAD));
+ e_binding_new (src_object, "active", dst_object, "sensitive");
+
+ dst_object = G_OBJECT (ACTION (MAIL_FOLDER_SELECT_SUBTHREAD));
+ e_binding_new (src_object, "active", dst_object, "sensitive");
+
+ dst_object = G_OBJECT (ACTION (MAIL_THREADS_COLLAPSE_ALL));
+ e_binding_new (src_object, "active", dst_object, "sensitive");
+
+ dst_object = G_OBJECT (ACTION (MAIL_THREADS_EXPAND_ALL));
+ e_binding_new (src_object, "active", dst_object, "sensitive");
+
+ e_mutual_binding_new (
+ G_OBJECT (ACTION (MAIL_PREVIEW)), "active",
+ G_OBJECT (shell_content), "preview-visible");
+
+ /* XXX The boolean sense of the GConf key is the inverse of
+ * the menu item, so we have to maintain two properties. */
+ e_mutual_binding_new_with_negation (
+ G_OBJECT (shell_content), "show-deleted",
+ G_OBJECT (ACTION (MAIL_HIDE_DELETED)), "active");
+
+ g_signal_connect (
+ ACTION (GAL_SAVE_CUSTOM_VIEW), "activate",
+ G_CALLBACK (action_gal_save_custom_view_cb), mail_shell_view);
+
+ g_signal_connect (
+ ACTION (SEARCH_EXECUTE), "activate",
+ G_CALLBACK (action_search_execute_cb), mail_shell_view);
+}
+
+/* Helper for e_mail_shell_view_update_popup_labels() */
+static void
+mail_shell_view_update_label_action (GtkToggleAction *action,
+ MessageList *message_list,
+ GPtrArray *uids,
+ const gchar *label_tag)
+{
+ CamelFolder *folder;
+ gboolean exists = FALSE;
+ gboolean not_exists = FALSE;
+ gboolean sensitive;
+ guint ii;
+
+ folder = message_list->folder;
+
+ /* Figure out the proper label action state for the selected
+ * messages. If all the selected messages have the given label,
+ * make the toggle action active. If all the selected message
+ * DO NOT have the given label, make the toggle action inactive.
+ * If some do and some don't, make the action insensitive. */
+
+ for (ii = 0; ii < uids->len && (!exists || !not_exists); ii++) {
+ const gchar *old_label;
+ gchar *new_label;
+
+ /* Check for new-style labels. */
+ if (camel_folder_get_message_user_flag (
+ folder, uids->pdata[ii], label_tag)) {
+ exists = TRUE;
+ continue;
+ }
+
+ /* Check for old-style labels. */
+ old_label = camel_folder_get_message_user_tag (
+ folder, uids->pdata[ii], "label");
+ if (old_label == NULL) {
+ not_exists = TRUE;
+ continue;
+ }
+
+ /* Convert old-style labels ("<name>") to "$Label<name>". */
+ new_label = g_alloca (strlen (old_label) + 10);
+ g_stpcpy (g_stpcpy (new_label, "$Label"), old_label);
+
+ if (strcmp (new_label, label_tag) == 0)
+ exists = TRUE;
+ else
+ not_exists = TRUE;
+ }
+
+ sensitive = !(exists && not_exists);
+ gtk_toggle_action_set_active (action, exists);
+ gtk_action_set_sensitive (GTK_ACTION (action), sensitive);
+}
+
+void
+e_mail_shell_view_update_popup_labels (EMailShellView *mail_shell_view)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ EMailReader *reader;
+ MessageList *message_list;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ GPtrArray *uids;
+ const gchar *path;
+ gboolean valid;
+ guint merge_id;
+ gint ii = 0;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ tree_model = e_shell_settings_get_object (
+ shell_settings, "mail-label-list-store");
+
+ action_group = ACTION_GROUP (MAIL_LABEL);
+ merge_id = mail_shell_view->priv->label_merge_id;
+ path = "/mail-message-popup/mail-label-menu/mail-label-actions";
+
+ /* Unmerge the previous menu items. */
+ gtk_ui_manager_remove_ui (ui_manager, merge_id);
+ e_action_group_remove_all_actions (action_group);
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ uids = message_list_get_selected (message_list);
+
+ valid = gtk_tree_model_get_iter_first (tree_model, &iter);
+
+ while (valid) {
+ GtkToggleAction *toggle_action;
+ GtkAction *action;
+ gchar *action_name;
+ gchar *stock_id;
+ gchar *label;
+ gchar *tag;
+
+ label = e_mail_label_list_store_get_name (
+ E_MAIL_LABEL_LIST_STORE (tree_model), &iter);
+ stock_id = e_mail_label_list_store_get_stock_id (
+ E_MAIL_LABEL_LIST_STORE (tree_model), &iter);
+ tag = e_mail_label_list_store_get_tag (
+ E_MAIL_LABEL_LIST_STORE (tree_model), &iter);
+ action_name = g_strdup_printf ("mail-label-%d", ii);
+
+ /* XXX Add a tooltip! */
+ toggle_action = gtk_toggle_action_new (
+ action_name, label, NULL, stock_id);
+
+ g_object_set_data_full (
+ G_OBJECT (toggle_action), "tag",
+ tag, (GDestroyNotify) g_free);
+
+ /* Configure the action before we connect to signals. */
+ mail_shell_view_update_label_action (
+ toggle_action, message_list, uids, tag);
+
+ g_signal_connect (
+ toggle_action, "toggled",
+ G_CALLBACK (action_mail_label_cb), mail_shell_view);
+
+ /* The action group takes ownership of the action. */
+ action = GTK_ACTION (toggle_action);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (toggle_action);
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id, path, action_name,
+ action_name, GTK_UI_MANAGER_AUTO, FALSE);
+
+ g_free (label);
+ g_free (stock_id);
+ g_free (action_name);
+
+ valid = gtk_tree_model_iter_next (tree_model, &iter);
+ ii++;
+ }
+
+ message_list_free_uids (message_list, uids);
+
+ g_object_unref (tree_model);
+}
+
+void
+e_mail_shell_view_update_search_filter (EMailShellView *mail_shell_view)
+{
+ EShell *shell;
+ EShellContent *shell_content;
+ EShellSettings *shell_settings;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GtkActionGroup *action_group;
+ GtkRadioAction *radio_action;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ GList *list;
+ GSList *group;
+ gboolean valid;
+ gint ii = 0;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ tree_model = e_shell_settings_get_object (
+ shell_settings, "mail-label-list-store");
+
+ action_group = ACTION_GROUP (MAIL_FILTER);
+ e_action_group_remove_all_actions (action_group);
+
+ /* Add the standard filter actions. */
+ gtk_action_group_add_radio_actions (
+ action_group, mail_filter_entries,
+ G_N_ELEMENTS (mail_filter_entries),
+ MAIL_FILTER_ALL_MESSAGES,
+ G_CALLBACK (action_search_filter_cb),
+ mail_shell_view);
+
+ /* Retrieve the radio group from an action we just added. */
+ list = gtk_action_group_list_actions (action_group);
+ radio_action = GTK_RADIO_ACTION (list->data);
+ group = gtk_radio_action_get_group (radio_action);
+ g_list_free (list);
+
+ valid = gtk_tree_model_get_iter_first (tree_model, &iter);
+
+ while (valid) {
+ GtkAction *action;
+ gchar *action_name;
+ gchar *stock_id;
+ gchar *label;
+
+ label = e_mail_label_list_store_get_name (
+ E_MAIL_LABEL_LIST_STORE (tree_model), &iter);
+ stock_id = e_mail_label_list_store_get_stock_id (
+ E_MAIL_LABEL_LIST_STORE (tree_model), &iter);
+
+ action_name = g_strdup_printf ("mail-filter-label-%d", ii);
+ radio_action = gtk_radio_action_new (
+ action_name, label, NULL, stock_id, ii);
+ g_free (action_name);
+
+ gtk_radio_action_set_group (radio_action, group);
+ group = gtk_radio_action_get_group (radio_action);
+
+ /* The action group takes ownership of the action. */
+ action = GTK_ACTION (radio_action);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (radio_action);
+
+ g_free (label);
+ g_free (stock_id);
+
+ valid = gtk_tree_model_iter_next (tree_model, &iter);
+ ii++;
+ }
+
+ /* Use any action in the group; doesn't matter which. */
+ e_shell_content_set_filter_action (shell_content, radio_action);
+
+ ii = MAIL_FILTER_UNREAD_MESSAGES;
+ e_shell_content_add_filter_separator_after (shell_content, ii);
+
+ ii = MAIL_FILTER_READ_MESSAGES;
+ e_shell_content_add_filter_separator_before (shell_content, ii);
+
+ g_object_unref (tree_model);
+}
diff --git a/modules/mail/e-mail-shell-view-actions.h b/modules/mail/e-mail-shell-view-actions.h
new file mode 100644
index 0000000000..3fb7142fff
--- /dev/null
+++ b/modules/mail/e-mail-shell-view-actions.h
@@ -0,0 +1,259 @@
+/*
+ * e-mail-shell-view-actions.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_SHELL_VIEW_ACTIONS_H
+#define E_MAIL_SHELL_VIEW_ACTIONS_H
+
+#include <shell/e-shell-window-actions.h>
+
+/* Mail Actions */
+#define E_SHELL_WINDOW_ACTION_MAIL_ACCOUNT_DISABLE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-account-disable")
+#define E_SHELL_WINDOW_ACTION_MAIL_ADD_SENDER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-add-sender")
+#define E_SHELL_WINDOW_ACTION_MAIL_CARET_MODE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-caret-mode")
+#define E_SHELL_WINDOW_ACTION_MAIL_CHECK_FOR_JUNK(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-check-for-junk")
+#define E_SHELL_WINDOW_ACTION_MAIL_CLIPBOARD_COPY(window) \
+ E_SHELL_WINDOw_ACTION ((window), "mail-clipboard-copy")
+#define E_SHELL_WINDOW_ACTION_MAIL_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-copy")
+#define E_SHELL_WINDOW_ACTION_MAIL_CREATE_SEARCH_FOLDER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-create-search-folder")
+#define E_SHELL_WINDOW_ACTION_MAIL_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-delete")
+#define E_SHELL_WINDOW_ACTION_MAIL_DOWNLOAD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-download")
+#define E_SHELL_WINDOW_ACTION_MAIL_EMPTY_TRASH(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-empty-trash")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_ON_MAILING_LIST(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-on-mailing-list")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_ON_RECIPIENTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-on-recipients")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_ON_SENDER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-on-sender")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_ON_SUBJECT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-on-subject")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTERS_APPLY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filters-apply")
+#define E_SHELL_WINDOW_ACTION_MAIL_FIND(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-find")
+#define E_SHELL_WINDOW_ACTION_MAIL_FLAG_CLEAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-flag-clear")
+#define E_SHELL_WINDOW_ACTION_MAIL_FLAG_COMPLETED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-flag-completed")
+#define E_SHELL_WINDOW_ACTION_MAIL_FLAG_FOR_FOLLOWUP(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-flag-for-followup")
+#define E_SHELL_WINDOW_ACTION_MAIL_FLUSH_OUTBOX(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-flush-outbox")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_COPY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-copy")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_DELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-delete")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_EXPUNGE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-expunge")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_MARK_ALL_READ(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-mark-all-read")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_MOVE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-move")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-new")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_PROPERTIES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-properties")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_REFRESH(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-refresh")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_RENAME(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-rename")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_SELECT_ALL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-select-all")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_SELECT_THREAD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-select-thread")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_SELECT_SUBTHREAD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-select-subthread")
+#define E_SHELL_WINDOW_ACTION_MAIL_FOLDER_UNSUBSCRIBE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-folder-unsubscribe")
+#define E_SHELL_WINDOW_ACTION_MAIL_FORWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-forward")
+#define E_SHELL_WINDOW_ACTION_MAIL_FORWARD_ATTACHED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-forward-attached")
+#define E_SHELL_WINDOW_ACTION_MAIL_FORWARD_INLINE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-forward-inline")
+#define E_SHELL_WINDOW_ACTION_MAIL_FORWARD_QUOTED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-forward-quoted")
+#define E_SHELL_WINDOW_ACTION_MAIL_HIDE_DELETED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-hide-deleted")
+#define E_SHELL_WINDOW_ACTION_MAIL_HIDE_READ(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-hide-read")
+#define E_SHELL_WINDOW_ACTION_MAIL_HIDE_SELECTED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-hide-selected")
+#define E_SHELL_WINDOW_ACTION_MAIL_LABEL_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-label-new")
+#define E_SHELL_WINDOW_ACTION_MAIL_LABEL_NONE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-label-none")
+#define E_SHELL_WINDOW_ACTION_MAIL_LOAD_IMAGES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-load-images")
+#define E_SHELL_WINDOW_ACTION_MAIL_MARK_IMPORTANT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-mark-important")
+#define E_SHELL_WINDOW_ACTION_MAIL_MARK_JUNK(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-mark-junk")
+#define E_SHELL_WINDOW_ACTION_MAIL_MARK_NOTJUNK(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-mark-notjunk")
+#define E_SHELL_WINDOW_ACTION_MAIL_MARK_READ(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-mark-read")
+#define E_SHELL_WINDOW_ACTION_MAIL_MARK_UNIMPORTANT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-mark-unimportant")
+#define E_SHELL_WINDOW_ACTION_MAIL_MARK_UNREAD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-mark-unread")
+#define E_SHELL_WINDOW_ACTION_MAIL_MESSAGE_EDIT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-message-edit")
+#define E_SHELL_WINDOW_ACTION_MAIL_MESSAGE_NEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-message-new")
+#define E_SHELL_WINDOW_ACTION_MAIL_MESSAGE_OPEN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-message-open")
+#define E_SHELL_WINDOW_ACTION_MAIL_MOVE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-move")
+#define E_SHELL_WINDOW_ACTION_MAIL_NEXT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-next")
+#define E_SHELL_WINDOW_ACTION_MAIL_NEXT_IMPORTANT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-next-important")
+#define E_SHELL_WINDOW_ACTION_MAIL_NEXT_THREAD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-next-thread")
+#define E_SHELL_WINDOW_ACTION_MAIL_NEXT_UNREAD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-next-unread")
+#define E_SHELL_WINDOW_ACTION_MAIL_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-preview")
+#define E_SHELL_WINDOW_ACTION_MAIL_PREVIOUS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-previous")
+#define E_SHELL_WINDOW_ACTION_MAIL_PREVIOUS_IMPORTANT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-previous-important")
+#define E_SHELL_WINDOW_ACTION_MAIL_PREVIOUS_UNREAD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-previous-unread")
+#define E_SHELL_WINDOW_ACTION_MAIL_PRINT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-print")
+#define E_SHELL_WINDOW_ACTION_MAIL_PRINT_PREVIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-print-preview")
+#define E_SHELL_WINDOW_ACTION_MAIL_REDIRECT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-redirect")
+#define E_SHELL_WINDOW_ACTION_MAIL_REPLY_ALL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-reply-all")
+#define E_SHELL_WINDOW_ACTION_MAIL_REPLY_LIST(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-reply-list")
+#define E_SHELL_WINDOW_ACTION_MAIL_REPLY_SENDER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-reply-sender")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_FOLDER_FROM_MAILING_LIST(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-folder-from-mailing-list")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_FOLDER_FROM_RECIPIENTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-folder-from-recipients")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_FOLDER_FROM_SENDER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-folder-from-sender")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_FOLDER_FROM_SUBJECT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-folder-from-subject")
+#define E_SHELL_WINDOW_ACTION_MAIL_SELECT_ALL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-select-all")
+#define E_SHELL_WINDOW_ACTION_MAIL_SHOW_ALL_HEADERS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-show-all-headers")
+#define E_SHELL_WINDOW_ACTION_MAIL_SHOW_HIDDEN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-show-hidden")
+#define E_SHELL_WINDOW_ACTION_MAIL_SHOW_SOURCE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-show-source")
+#define E_SHELL_WINDOW_ACTION_MAIL_SMART_BACKWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-smart-backward")
+#define E_SHELL_WINDOW_ACTION_MAIL_SMART_FORWARD(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-smart-forward")
+#define E_SHELL_WINDOW_ACTION_MAIL_STOP(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-stop")
+#define E_SHELL_WINDOW_ACTION_MAIL_THREADS_COLLAPSE_ALL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-threads-collapse-all")
+#define E_SHELL_WINDOW_ACTION_MAIL_THREADS_EXPAND_ALL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-threads-expand-all")
+#define E_SHELL_WINDOW_ACTION_MAIL_THREADS_GROUP_BY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-threads-group-by")
+#define E_SHELL_WINDOW_ACTION_MAIL_TOOLS_FILTERS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-tools-filters")
+#define E_SHELL_WINDOW_ACTION_MAIL_TOOLS_SEARCH_FOLDERS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-tools-search-folders")
+#define E_SHELL_WINDOW_ACTION_MAIL_TOOLS_SUBSCRIPTIONS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-tools-subscriptions")
+#define E_SHELL_WINDOW_ACTION_MAIL_UNDELETE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-undelete")
+#define E_SHELL_WINDOW_ACTION_MAIL_VIEW_CLASSIC(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-view-classic")
+#define E_SHELL_WINDOW_ACTION_MAIL_VIEW_VERTICAL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-view-vertical")
+#define E_SHELL_WINDOW_ACTION_MAIL_ZOOM_100(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-zoom-100")
+#define E_SHELL_WINDOW_ACTION_MAIL_ZOOM_IN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-zoom-in")
+#define E_SHELL_WINDOW_ACTION_MAIL_ZOOM_OUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-zoom-out")
+
+/* Mail Query Actions */
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_ALL_MESSAGES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-all-messages")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_IMPORTANT_MESSAGES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-important-messages")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_LAST_5_DAYS_MESSAGES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-last-5-days-messages")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_MESSAGES_NOT_JUNK(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-messages-not-junk")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_MESSAGES_WITH_ATTACHMENTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-messages-with-attachments")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_NO_LABEL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-no-label")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_READ_MESSAGES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-read-messages")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_RECENT_MESSAGES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-recent-messages")
+#define E_SHELL_WINDOW_ACTION_MAIL_FILTER_UNREAD_MESSAGES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-filter-unread-messages")
+#define E_SHELL_WINDOW_ACTION_MAIL_SCOPE_ALL_ACCOUNTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-scope-all-accounts")
+#define E_SHELL_WINDOW_ACTION_MAIL_SCOPE_CURRENT_ACCOUNT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-scope-current-account")
+#define E_SHELL_WINDOW_ACTION_MAIL_SCOPE_CURRENT_FOLDER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-scope-current-folder")
+#define E_SHELL_WINDOW_ACTION_MAIL_SCOPE_CURRENT_MESSAGE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-scope-current-message")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_BODY_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-body-contains")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_MESSAGE_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-message-contains")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_RECIPIENTS_CONTAIN(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-recipients-contain")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_SENDER_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-sender-contains")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_SUBJECT_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-subject-contains")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_SUBJECT_OR_RECIPIENTS_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-subject-or-recipients-contains")
+#define E_SHELL_WINDOW_ACTION_MAIL_SEARCH_SUBJECT_OR_SENDER_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-search-subject-or-sender-contains")
+
+/* Action Groups */
+#define E_SHELL_WINDOW_ACTION_GROUP_MAIL(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "mail")
+#define E_SHELL_WINDOW_ACTION_GROUP_MAIL_FILTER(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "mail-filter")
+#define E_SHELL_WINDOW_ACTION_GROUP_MAIL_LABEL(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "mail-label")
+
+#endif /* E_MAIL_SHELL_VIEW_ACTIONS_H */
diff --git a/modules/mail/e-mail-shell-view-private.c b/modules/mail/e-mail-shell-view-private.c
new file mode 100644
index 0000000000..ca2aa8592e
--- /dev/null
+++ b/modules/mail/e-mail-shell-view-private.c
@@ -0,0 +1,1009 @@
+/*
+ * e-mail-shell-view-private.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-shell-view-private.h"
+
+#include "widgets/menus/gal-view-factory-etable.h"
+
+static void
+mail_shell_view_folder_tree_selected_cb (EMailShellView *mail_shell_view,
+ const gchar *full_name,
+ const gchar *uri,
+ guint32 flags,
+ EMFolderTree *folder_tree)
+{
+ EShellView *shell_view;
+ EMailReader *reader;
+ gboolean folder_selected;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+
+ folder_selected =
+ !(flags & CAMEL_FOLDER_NOSELECT) &&
+ full_name != NULL;
+
+ if (folder_selected)
+ e_mail_reader_set_folder_uri (reader, uri);
+ else
+ e_mail_reader_set_folder (reader, NULL, NULL);
+
+ e_shell_view_update_actions (shell_view);
+}
+
+static gboolean
+mail_shell_view_folder_tree_key_press_event_cb (EMailShellView *mail_shell_view,
+ GdkEventKey *event)
+{
+ EMailReader *reader;
+ gboolean handled = FALSE;
+
+ if ((event->state & GDK_CONTROL_MASK) != 0)
+ goto ctrl;
+
+ /* <keyval> alone */
+ switch (event->keyval) {
+ case GDK_period:
+ case GDK_comma:
+ case GDK_bracketleft:
+ case GDK_bracketright:
+ goto emit;
+
+ default:
+ goto exit;
+ }
+
+ctrl:
+ /* Ctrl + <keyval> */
+ switch (event->keyval) {
+ case GDK_period:
+ case GDK_comma:
+ goto emit;
+
+ default:
+ goto exit;
+ }
+
+ /* All branches jump past this. */
+ g_return_val_if_reached (FALSE);
+
+emit:
+ /* Forward the key press to the EMailReader interface. */
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ g_signal_emit_by_name (reader, "key-press-event", event, &handled);
+
+exit:
+ return handled;
+}
+
+static void
+mail_shell_view_folder_tree_popup_event_cb (EShellView *shell_view,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/mail-folder-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+}
+
+static gboolean
+mail_shell_view_key_press_event_cb (EMailShellView *mail_shell_view,
+ GdkEventKey *event)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if ((event->state & GDK_CONTROL_MASK) != 0)
+ return FALSE;
+
+ switch (event->keyval) {
+ case GDK_space:
+ action = ACTION (MAIL_SMART_FORWARD);
+ break;
+
+ case GDK_BackSpace:
+ action = ACTION (MAIL_SMART_BACKWARD);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ gtk_action_activate (action);
+
+ return TRUE;
+}
+
+static gint
+mail_shell_view_message_list_key_press_cb (EMailShellView *mail_shell_view,
+ gint row,
+ ETreePath path,
+ gint col,
+ GdkEvent *event)
+{
+ return mail_shell_view_key_press_event_cb (
+ mail_shell_view, &event->key);
+}
+
+static gboolean
+mail_shell_view_message_list_right_click_cb (EShellView *shell_view,
+ gint row,
+ ETreePath path,
+ gint col,
+ GdkEventButton *event)
+{
+ const gchar *widget_path;
+
+ widget_path = "/mail-message-popup";
+ e_shell_view_show_popup_menu (shell_view, widget_path, event);
+
+ return TRUE;
+}
+
+static void
+mail_shell_view_reader_changed_cb (EMailShellView *mail_shell_view,
+ EMailReader *reader)
+{
+ EMailShellContent *mail_shell_content;
+
+ mail_shell_content = mail_shell_view->priv->mail_shell_content;
+ e_mail_shell_content_update_view_instance (mail_shell_content);
+ e_mail_shell_view_update_sidebar (mail_shell_view);
+}
+
+static void
+mail_shell_view_reader_status_message_cb (EMailShellView *mail_shell_view,
+ const gchar *status_message)
+{
+ EShellView *shell_view;
+ EShellTaskbar *shell_taskbar;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_taskbar = e_shell_view_get_shell_taskbar (shell_view);
+
+ e_shell_taskbar_set_message (shell_taskbar, status_message);
+}
+
+static void
+mail_shell_view_scroll_cb (EMailShellView *mail_shell_view,
+ GtkOrientation orientation,
+ GtkScrollType scroll_type,
+ gfloat position,
+ GtkHTML *html)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSettings *shell_settings;
+ EMailReader *reader;
+ MessageList *message_list;
+ gboolean magic_spacebar;
+
+ if (html->binding_handled)
+ return;
+
+ if (orientation != GTK_ORIENTATION_VERTICAL)
+ return;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ magic_spacebar = e_shell_settings_get_boolean (
+ shell_settings, "mail-magic-spacebar");
+
+ if (!magic_spacebar)
+ return;
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ if (scroll_type == GTK_SCROLL_PAGE_FORWARD) {
+ gtk_widget_grab_focus (GTK_WIDGET (message_list));
+ message_list_select (
+ message_list, MESSAGE_LIST_SELECT_NEXT,
+ 0, CAMEL_MESSAGE_SEEN);
+ } else {
+ gtk_widget_grab_focus (GTK_WIDGET (message_list));
+ message_list_select (
+ message_list, MESSAGE_LIST_SELECT_PREVIOUS,
+ 0, CAMEL_MESSAGE_SEEN);
+ }
+}
+
+static void
+mail_shell_view_load_view_collection (EShellViewClass *shell_view_class)
+{
+ GalViewCollection *collection;
+ GalViewFactory *factory;
+ ETableSpecification *spec;
+ const gchar *base_dir;
+ gchar *filename;
+
+ collection = shell_view_class->view_collection;
+
+ base_dir = EVOLUTION_ETSPECDIR;
+ spec = e_table_specification_new ();
+ filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL);
+ if (!e_table_specification_load_from_file (spec, filename))
+ g_critical ("Unable to load ETable specification file "
+ "for mail");
+ g_free (filename);
+
+ factory = gal_view_factory_etable_new (spec);
+ gal_view_collection_add_factory (collection, factory);
+ g_object_unref (factory);
+ g_object_unref (spec);
+
+ gal_view_collection_load (collection);
+}
+
+static void
+mail_shell_view_notify_view_id_cb (EMailShellView *mail_shell_view)
+{
+ EMailShellContent *mail_shell_content;
+ GalViewInstance *view_instance;
+ const gchar *view_id;
+
+ mail_shell_content = mail_shell_view->priv->mail_shell_content;
+ view_instance = NULL; /* FIXME */
+ view_id = e_shell_view_get_view_id (E_SHELL_VIEW (mail_shell_view));
+
+ /* A NULL view ID implies we're in a custom view. But you can
+ * only get to a custom view via the "Define Views" dialog, which
+ * would have already modified the view instance appropriately.
+ * Furthermore, there's no way to refer to a custom view by ID
+ * anyway, since custom views have no IDs. */
+ if (view_id == NULL)
+ return;
+
+ gal_view_instance_set_current_view_id (view_instance, view_id);
+}
+
+void
+e_mail_shell_view_private_init (EMailShellView *mail_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ if (!gal_view_collection_loaded (shell_view_class->view_collection))
+ mail_shell_view_load_view_collection (shell_view_class);
+
+ g_signal_connect (
+ mail_shell_view, "notify::view-id",
+ G_CALLBACK (mail_shell_view_notify_view_id_cb), NULL);
+}
+
+void
+e_mail_shell_view_private_constructed (EMailShellView *mail_shell_view)
+{
+ EMailShellViewPrivate *priv = mail_shell_view->priv;
+ EMailShellSidebar *mail_shell_sidebar;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellContent *shell_content;
+ EShellSettings *shell_settings;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ EMFormatHTMLDisplay *html_display;
+ EMFolderTree *folder_tree;
+ RuleContext *context;
+ FilterRule *rule = NULL;
+ GtkTreeModel *tree_model;
+ GtkUIManager *ui_manager;
+ MessageList *message_list;
+ EMailReader *reader;
+ GtkHTML *html;
+ const gchar *source;
+ guint merge_id;
+ gint ii = 0;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ tree_model = e_shell_settings_get_object (
+ shell_settings, "mail-label-list-store");
+
+ e_shell_window_add_action_group (shell_window, "mail");
+ e_shell_window_add_action_group (shell_window, "mail-filter");
+ e_shell_window_add_action_group (shell_window, "mail-label");
+
+ merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+ priv->label_merge_id = merge_id;
+
+ /* Cache these to avoid lots of awkward casting. */
+ priv->mail_shell_backend = g_object_ref (shell_backend);
+ priv->mail_shell_content = g_object_ref (shell_content);
+ priv->mail_shell_sidebar = g_object_ref (shell_sidebar);
+
+ reader = E_MAIL_READER (shell_content);
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar);
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ g_signal_connect_swapped (
+ folder_tree, "folder-selected",
+ G_CALLBACK (mail_shell_view_folder_tree_selected_cb),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ folder_tree, "key-press-event",
+ G_CALLBACK (mail_shell_view_folder_tree_key_press_event_cb),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ folder_tree, "popup-event",
+ G_CALLBACK (mail_shell_view_folder_tree_popup_event_cb),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ message_list->tree, "key-press",
+ G_CALLBACK (mail_shell_view_message_list_key_press_cb),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ message_list->tree, "right-click",
+ G_CALLBACK (mail_shell_view_message_list_right_click_cb),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ reader, "changed",
+ G_CALLBACK (mail_shell_view_reader_changed_cb),
+ mail_shell_view);
+
+ /* Use the same callback as "changed". */
+ g_signal_connect_swapped (
+ reader, "folder-loaded",
+ G_CALLBACK (mail_shell_view_reader_changed_cb),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ reader, "folder-loaded",
+ G_CALLBACK (e_mail_shell_view_restore_state),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ tree_model, "row-changed",
+ G_CALLBACK (e_mail_shell_view_update_search_filter),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ tree_model, "row-deleted",
+ G_CALLBACK (e_mail_shell_view_update_search_filter),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ tree_model, "row-inserted",
+ G_CALLBACK (e_mail_shell_view_update_search_filter),
+ mail_shell_view);
+
+ g_signal_connect_swapped (
+ html, "key-press-event",
+ G_CALLBACK (mail_shell_view_key_press_event_cb),
+ mail_shell_view);
+
+ g_signal_connect_data (
+ html, "scroll",
+ G_CALLBACK (mail_shell_view_scroll_cb),
+ mail_shell_view, (GClosureNotify) NULL,
+ G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+
+ g_signal_connect_swapped (
+ html, "status-message",
+ G_CALLBACK (mail_shell_view_reader_status_message_cb),
+ mail_shell_view);
+
+ e_mail_shell_view_actions_init (mail_shell_view);
+ e_mail_shell_view_update_search_filter (mail_shell_view);
+ e_mail_reader_init (reader);
+
+ /* Populate built-in rules for search entry popup menu.
+ * Keep the assertions, please. If the conditions aren't
+ * met we're going to crash anyway, just more mysteriously. */
+ context = e_shell_content_get_search_context (shell_content);
+ source = FILTER_SOURCE_DEMAND;
+ while ((rule = rule_context_next_rule (context, rule, source))) {
+ g_assert (ii < MAIL_NUM_SEARCH_RULES);
+ priv->search_rules[ii++] = g_object_ref (rule);
+ }
+ g_assert (ii == MAIL_NUM_SEARCH_RULES);
+}
+
+void
+e_mail_shell_view_private_dispose (EMailShellView *mail_shell_view)
+{
+ EMailShellViewPrivate *priv = mail_shell_view->priv;
+ gint ii;
+
+ DISPOSE (priv->mail_shell_backend);
+ DISPOSE (priv->mail_shell_content);
+ DISPOSE (priv->mail_shell_sidebar);
+
+ for (ii = 0; ii < MAIL_NUM_SEARCH_RULES; ii++)
+ DISPOSE (priv->search_rules[ii]);
+}
+
+void
+e_mail_shell_view_private_finalize (EMailShellView *mail_shell_view)
+{
+ /* XXX Nothing to do? */
+}
+
+void
+e_mail_shell_view_restore_state (EMailShellView *mail_shell_view)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ EMailReader *reader;
+ MessageList *message_list;
+ const gchar *folder_uri;
+ gchar *group_name;
+
+ /* XXX Move this to EMailShellContent. */
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ reader = E_MAIL_READER (shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder_uri = message_list->folder_uri;
+ g_return_if_fail (folder_uri != NULL);
+
+ group_name = g_strdup_printf ("Folder %s", folder_uri);
+ e_shell_content_restore_state (shell_content, group_name);
+ g_free (group_name);
+}
+
+void
+e_mail_shell_view_execute_search (EMailShellView *mail_shell_view)
+{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ EShellSettings *shell_settings;
+ EMFormatHTMLDisplay *html_display;
+ EMailShellContent *mail_shell_content;
+ MessageList *message_list;
+ FilterRule *rule;
+ EMailReader *reader;
+ CamelFolder *folder;
+ GtkAction *action;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter tree_iter;
+ GString *string;
+ GList *iter;
+ GSList *search_strings = NULL;
+ const gchar *folder_uri;
+ const gchar *text;
+ gboolean valid;
+ gchar *query;
+ gchar *temp;
+ gchar *tag;
+ gint value;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ mail_shell_content = mail_shell_view->priv->mail_shell_content;
+
+ reader = E_MAIL_READER (shell_content);
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder_uri = message_list->folder_uri;
+ folder = message_list->folder;
+
+ /* This returns a new object reference. */
+ model = e_shell_settings_get_object (
+ shell_settings, "mail-label-list-store");
+
+ text = e_shell_content_get_search_text (shell_content);
+ if (text == NULL || *text == '\0') {
+ query = g_strdup ("");
+ goto filter;
+ }
+
+ /* Replace variables in the selected rule with the
+ * current search text and extract a query string. */
+
+ action = ACTION (MAIL_SEARCH_SUBJECT_OR_SENDER_CONTAINS);
+ value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+ g_return_if_fail (value >= 0 && value < MAIL_NUM_SEARCH_RULES);
+ rule = mail_shell_view->priv->search_rules[value];
+
+ for (iter = rule->parts; iter != NULL; iter = iter->next) {
+ FilterPart *part = iter->data;
+ FilterElement *element = NULL;
+
+ if (strcmp (part->name, "subject") == 0)
+ element = filter_part_find_element (part, "subject");
+ else if (strcmp (part->name, "body") == 0)
+ element = filter_part_find_element (part, "word");
+ else if (strcmp (part->name, "sender") == 0)
+ element = filter_part_find_element (part, "sender");
+ else if (strcmp (part->name, "to") == 0)
+ element = filter_part_find_element (part, "recipient");
+
+ if (strcmp (part->name, "body") == 0) {
+ struct _camel_search_words *words;
+ gint ii;
+
+ words = camel_search_words_split ((guchar *) text);
+ for (ii = 0; ii < words->len; ii++)
+ search_strings = g_slist_prepend (
+ search_strings, g_strdup (
+ words->words[ii]->word));
+ camel_search_words_free (words);
+ }
+
+ if (element != NULL) {
+ FilterInput *input = FILTER_INPUT (element);
+ filter_input_set_value (input, text);
+ }
+ }
+
+ string = g_string_sized_new (1024);
+ filter_rule_build_code (rule, string);
+ query = g_string_free (string, FALSE);
+
+filter:
+
+ /* Apply selected filter. */
+
+ value = e_shell_content_get_filter_value (shell_content);
+ switch (value) {
+ case MAIL_FILTER_ALL_MESSAGES:
+ break;
+
+ case MAIL_FILTER_UNREAD_MESSAGES:
+ temp = g_strdup_printf (
+ "(and %s (match-all (not "
+ "(system-flag \"Seen\"))))", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case MAIL_FILTER_NO_LABEL:
+ string = g_string_sized_new (1024);
+ g_string_append_printf (
+ string, "(and %s (and ", query);
+ valid = gtk_tree_model_get_iter_first (
+ model, &tree_iter);
+ while (valid) {
+ tag = e_mail_label_list_store_get_tag (
+ E_MAIL_LABEL_LIST_STORE (model),
+ &tree_iter);
+ g_string_append_printf (
+ string, " (match-all (not (or "
+ "(= (user-tag \"label\") \"%s\") "
+ "(user-flag \"$Label%s\") "
+ "(user-flag \"%s\"))))",
+ tag, tag, tag);
+ g_free (tag);
+
+ valid = gtk_tree_model_iter_next (
+ model, &tree_iter);
+ }
+ g_string_append_len (string, "))", 2);
+ g_free (query);
+ query = g_string_free (string, FALSE);
+ break;
+
+ case MAIL_FILTER_READ_MESSAGES:
+ temp = g_strdup_printf (
+ "(and %s (match-all "
+ "(system-flag \"Seen\")))", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case MAIL_FILTER_RECENT_MESSAGES:
+ if (em_utils_folder_is_sent (folder, folder_uri))
+ temp = g_strdup_printf (
+ "(and %s (match-all "
+ "(> (get-sent-date) "
+ "(- (get-current-date) 86400))))",
+ query);
+ else
+ temp = g_strdup_printf (
+ "(and %s (match-all "
+ "(> (get-received-date) "
+ "(- (get-current-date) 86400))))",
+ query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case MAIL_FILTER_LAST_5_DAYS_MESSAGES:
+ if (em_utils_folder_is_sent (folder, folder_uri))
+ temp = g_strdup_printf (
+ "(and %s (match-all "
+ "(> (get-sent-date) "
+ "(- (get-current-date) 432000))))",
+ query);
+ else
+ temp = g_strdup_printf (
+ "(and %s (match-all "
+ "(> (get-received-date) "
+ "(- (get-current-date) 432000))))",
+ query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case MAIL_FILTER_MESSAGES_WITH_ATTACHMENTS:
+ temp = g_strdup_printf (
+ "(and %s (match-all "
+ "(system-flag \"Attachments\")))", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case MAIL_FILTER_IMPORTANT_MESSAGES:
+ temp = g_strdup_printf (
+ "(and %s (match-all "
+ "(system-flag \"Flagged\")))", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ case MAIL_FILTER_MESSAGES_NOT_JUNK:
+ temp = g_strdup_printf (
+ "(and %s (match-all (not "
+ "(system-flag \"junk\"))))", query);
+ g_free (query);
+ query = temp;
+ break;
+
+ default:
+ /* The action value also serves as a path for
+ * the label list store. That's why we number
+ * the label actions from zero. */
+ path = gtk_tree_path_new_from_indices (value, -1);
+ gtk_tree_model_get_iter (model, &tree_iter, path);
+ gtk_tree_path_free (path);
+
+ tag = e_mail_label_list_store_get_tag (
+ E_MAIL_LABEL_LIST_STORE (model), &tree_iter);
+ temp = g_strdup_printf (
+ "(and %s (match-all (or "
+ "(= (user-tag \"label\") \"%s\") "
+ "(user-flag \"$Label%s\") "
+ "(user-flag \"%s\"))))",
+ query, tag, tag, tag);
+ g_free (tag);
+
+ g_free (query);
+ query = temp;
+ break;
+ }
+
+ message_list_set_search (message_list, query);
+
+ e_mail_shell_content_set_search_strings (
+ mail_shell_content, search_strings);
+
+ g_slist_foreach (search_strings, (GFunc) g_free, NULL);
+ g_slist_free (search_strings);
+
+ g_object_unref (model);
+ g_free (query);
+}
+
+/* Helper for e_mail_shell_view_create_filter_from_selected() */
+static void
+mail_shell_view_create_filter_cb (CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *message,
+ gpointer user_data)
+{
+ struct {
+ const gchar *source;
+ gint type;
+ } *filter_data = user_data;
+
+ if (message != NULL)
+ filter_gui_add_from_message (
+ message, filter_data->source, filter_data->type);
+
+ g_free (filter_data);
+}
+
+void
+e_mail_shell_view_create_filter_from_selected (EMailShellView *mail_shell_view,
+ gint filter_type)
+{
+ EMailReader *reader;
+ MessageList *message_list;
+ CamelFolder *folder;
+ const gchar *filter_source;
+ const gchar *folder_uri;
+ GPtrArray *uids;
+
+ struct {
+ const gchar *source;
+ gint type;
+ } *filter_data;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder_uri = message_list->folder_uri;
+ folder = message_list->folder;
+
+ if (em_utils_folder_is_sent (folder, folder_uri))
+ filter_source = FILTER_SOURCE_OUTGOING;
+ else if (em_utils_folder_is_outbox (folder, folder_uri))
+ filter_source = FILTER_SOURCE_OUTGOING;
+ else
+ filter_source = FILTER_SOURCE_INCOMING;
+
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len == 1) {
+ filter_data = g_malloc (sizeof (*filter_data));
+ filter_data->source = filter_source;
+ filter_data->type = filter_type;
+
+ mail_get_message (
+ folder, uids->pdata[0],
+ mail_shell_view_create_filter_cb,
+ filter_data, mail_msg_unordered_push);
+ }
+
+ em_utils_uids_free (uids);
+}
+
+/* Helper for e_mail_shell_view_create_vfolder_from_selected() */
+static void
+mail_shell_view_create_vfolder_cb (CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *message,
+ gpointer user_data)
+{
+ struct {
+ gchar *uri;
+ gint type;
+ } *vfolder_data = user_data;
+
+ if (message != NULL)
+ vfolder_gui_add_from_message (
+ message, vfolder_data->type, vfolder_data->uri);
+
+ g_free (vfolder_data->uri);
+ g_free (vfolder_data);
+}
+
+void
+e_mail_shell_view_create_vfolder_from_selected (EMailShellView *mail_shell_view,
+ gint vfolder_type)
+{
+ EMailReader *reader;
+ MessageList *message_list;
+ CamelFolder *folder;
+ const gchar *folder_uri;
+ GPtrArray *uids;
+
+ struct {
+ gchar *uri;
+ gint type;
+ } *vfolder_data;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
+
+ reader = E_MAIL_READER (mail_shell_view->priv->mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder_uri = message_list->folder_uri;
+ folder = message_list->folder;
+
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len == 1) {
+ vfolder_data = g_malloc (sizeof (*vfolder_data));
+ vfolder_data->uri = g_strdup (folder_uri);
+ vfolder_data->type = vfolder_type;
+
+ mail_get_message (
+ folder, uids->pdata[0],
+ mail_shell_view_create_vfolder_cb,
+ vfolder_data, mail_msg_unordered_push);
+ }
+
+ em_utils_uids_free (uids);
+}
+
+void
+e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view)
+{
+ EMailShellContent *mail_shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellView *shell_view;
+ EMailReader *reader;
+ MessageList *message_list;
+ CamelStore *local_store;
+ CamelFolder *folder;
+ GPtrArray *selected;
+ GString *buffer;
+ const gchar *display_name;
+ const gchar *folder_uri;
+ gchar *folder_name;
+ gchar *title;
+ guint32 num_deleted;
+ guint32 num_junked;
+ guint32 num_junked_not_deleted;
+ guint32 num_unread;
+ guint32 num_visible;
+
+ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
+
+ mail_shell_content = mail_shell_view->priv->mail_shell_content;
+
+ shell_view = E_SHELL_VIEW (mail_shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ reader = E_MAIL_READER (mail_shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ folder_uri = message_list->folder_uri;
+ folder = message_list->folder;
+
+ local_store = e_mail_local_get_store ();
+
+ /* If no folder is selected, reset the sidebar banners
+ * to their default values and stop. */
+ if (folder == NULL) {
+ GtkAction *action;
+ gchar *label;
+
+ action = e_shell_view_get_action (shell_view);
+
+ g_object_get (action, "label", &label, NULL);
+ e_shell_sidebar_set_secondary_text (shell_sidebar, NULL);
+ e_shell_view_set_title (shell_view, label);
+ g_free (label);
+
+ return;
+ }
+
+ camel_object_get (
+ folder, NULL,
+ CAMEL_FOLDER_NAME, &folder_name,
+ CAMEL_FOLDER_DELETED, &num_deleted,
+ CAMEL_FOLDER_JUNKED, &num_junked,
+ CAMEL_FOLDER_JUNKED_NOT_DELETED, &num_junked_not_deleted,
+ CAMEL_FOLDER_UNREAD, &num_unread,
+ CAMEL_FOLDER_VISIBLE, &num_visible,
+ NULL);
+
+ buffer = g_string_sized_new (256);
+ selected = message_list_get_selected (message_list);
+
+ if (selected->len > 1)
+ g_string_append_printf (
+ buffer, ngettext ("%d selected, ", "%d selected, ",
+ selected->len), selected->len);
+
+ if (CAMEL_IS_VTRASH_FOLDER (folder)) {
+ CamelVTrashFolder *trash_folder;
+
+ trash_folder = (CamelVTrashFolder *) folder;
+
+ /* "Trash" folder */
+ if (trash_folder->type == CAMEL_VTRASH_FOLDER_TRASH)
+ g_string_append_printf (
+ buffer, ngettext ("%d deleted",
+ "%d deleted", num_deleted), num_deleted);
+
+ /* "Junk" folder (hide deleted messages) */
+ else if (e_mail_reader_get_hide_deleted (reader))
+ g_string_append_printf (
+ buffer, ngettext ("%d junk",
+ "%d junk", num_junked_not_deleted),
+ num_junked_not_deleted);
+
+ /* "Junk" folder (show deleted messages) */
+ else
+ g_string_append_printf (
+ buffer, ngettext ("%d junk", "%d junk",
+ num_junked), num_junked);
+
+ /* "Drafts" folder */
+ } else if (em_utils_folder_is_drafts (folder, folder_uri)) {
+ g_string_append_printf (
+ buffer, ngettext ("%d draft", "%d drafts",
+ num_visible), num_visible);
+
+ /* "Outbox" folder */
+ } else if (em_utils_folder_is_outbox (folder, folder_uri)) {
+ g_string_append_printf (
+ buffer, ngettext ("%d unsent", "%d unsent",
+ num_visible), num_visible);
+
+ /* "Sent" folder */
+ } else if (em_utils_folder_is_sent (folder, folder_uri)) {
+ g_string_append_printf (
+ buffer, ngettext ("%d sent", "%d sent",
+ num_visible), num_visible);
+
+ /* Normal folder */
+ } else {
+ if (!e_mail_reader_get_hide_deleted (reader))
+ num_visible +=
+ num_deleted - num_junked +
+ num_junked_not_deleted;
+
+ if (num_unread > 0 && selected->len <= 1)
+ g_string_append_printf (
+ buffer, ngettext ("%d unread, ",
+ "%d unread, ", num_unread), num_unread);
+ g_string_append_printf (
+ buffer, ngettext ("%d total", "%d total",
+ num_visible), num_visible);
+ }
+
+ message_list_free_uids (message_list, selected);
+
+ /* Choose a suitable folder name for displaying. */
+ if (folder->parent_store == local_store && (
+ strcmp (folder_name, "Drafts") == 0 ||
+ strcmp (folder_name, "Inbox") == 0 ||
+ strcmp (folder_name, "Outbox") == 0 ||
+ strcmp (folder_name, "Sent") == 0 ||
+ strcmp (folder_name, "Templates") == 0))
+ display_name = _(folder_name);
+ else if (strcmp (folder_name, "INBOX") == 0)
+ display_name = _("Inbox");
+ else
+ display_name = folder_name;
+
+ title = g_strdup_printf ("%s (%s)", display_name, buffer->str);
+ e_shell_sidebar_set_secondary_text (shell_sidebar, buffer->str);
+ e_shell_view_set_title (shell_view, title);
+ g_free (title);
+
+ camel_object_free (folder, CAMEL_FOLDER_NAME, folder_name);
+ g_string_free (buffer, TRUE);
+}
diff --git a/modules/mail/e-mail-shell-view-private.h b/modules/mail/e-mail-shell-view-private.h
new file mode 100644
index 0000000000..988d494219
--- /dev/null
+++ b/modules/mail/e-mail-shell-view-private.h
@@ -0,0 +1,173 @@
+/*
+ * e-mail-shell-view-private.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_SHELL_VIEW_PRIVATE_H
+#define E_MAIL_SHELL_VIEW_PRIVATE_H
+
+#include "e-mail-shell-view.h"
+
+#include <glib/gi18n.h>
+#include <gtkhtml/gtkhtml.h>
+#include <camel/camel-disco-store.h>
+#include <camel/camel-offline-store.h>
+#include <camel/camel-vtrash-folder.h>
+#include <camel/camel-search-private.h> /* for camel_search_word */
+
+#include "e-util/e-util.h"
+#include "e-util/e-binding.h"
+#include "e-util/gconf-bridge.h"
+#include "e-util/e-account-utils.h"
+#include "filter/filter-part.h"
+#include "widgets/misc/e-popup-action.h"
+#include "widgets/menus/gal-view-instance.h"
+
+#include "e-mail-label-dialog.h"
+#include "e-mail-label-list-store.h"
+#include "e-mail-local.h"
+#include "e-mail-reader.h"
+#include "e-mail-store.h"
+#include "em-composer-utils.h"
+#include "em-folder-properties.h"
+#include "em-folder-selector.h"
+#include "em-folder-utils.h"
+#include "em-subscribe-editor.h"
+#include "em-utils.h"
+#include "mail-autofilter.h"
+#include "mail-config.h"
+#include "mail-ops.h"
+#include "mail-send-recv.h"
+#include "mail-vfolder.h"
+
+#include "e-mail-shell-backend.h"
+#include "e-mail-shell-content.h"
+#include "e-mail-shell-sidebar.h"
+#include "e-mail-shell-view-actions.h"
+
+#define E_MAIL_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_SHELL_VIEW, EMailShellViewPrivate))
+
+/* Shorthand, requires a variable named "shell_window". */
+#define ACTION(name) \
+ (E_SHELL_WINDOW_ACTION_##name (shell_window))
+#define ACTION_GROUP(name) \
+ (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window))
+
+/* For use in dispose() methods. */
+#define DISPOSE(obj) \
+ G_STMT_START { \
+ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \
+ } G_STMT_END
+
+/* ETable Specifications */
+#define ETSPEC_FILENAME "message-list.etspec"
+
+G_BEGIN_DECLS
+
+/* Filter items are displayed in ascending order.
+ * Labels are numbered from zero, so subsequent items must have
+ * sufficiently large values. Unfortunately this introduces an
+ * arbitrary upper bound on labels. */
+enum {
+ MAIL_FILTER_ALL_MESSAGES = -3,
+ MAIL_FILTER_UNREAD_MESSAGES = -2,
+ MAIL_FILTER_NO_LABEL = -1,
+ /* Labels go here */
+ MAIL_FILTER_READ_MESSAGES = 5000,
+ MAIL_FILTER_RECENT_MESSAGES = 5001,
+ MAIL_FILTER_LAST_5_DAYS_MESSAGES = 5002,
+ MAIL_FILTER_MESSAGES_WITH_ATTACHMENTS = 5003,
+ MAIL_FILTER_IMPORTANT_MESSAGES = 5004,
+ MAIL_FILTER_MESSAGES_NOT_JUNK = 5005
+};
+
+/* Search items are displayed in ascending order. */
+enum {
+ MAIL_SEARCH_SUBJECT_OR_SENDER_CONTAINS,
+ MAIL_SEARCH_SUBJECT_OR_RECIPIENTS_CONTAINS,
+ MAIL_SEARCH_RECIPIENTS_CONTAIN,
+ MAIL_SEARCH_MESSAGE_CONTAINS,
+ MAIL_SEARCH_SUBJECT_CONTAINS,
+ MAIL_SEARCH_SENDER_CONTAINS,
+ MAIL_SEARCH_BODY_CONTAINS,
+ MAIL_NUM_SEARCH_RULES
+};
+
+/* Scope items are displayed in ascending order. */
+enum {
+ MAIL_SCOPE_CURRENT_FOLDER,
+ MAIL_SCOPE_CURRENT_ACCOUNT,
+ MAIL_SCOPE_ALL_ACCOUNTS
+};
+
+struct _EMailShellViewPrivate {
+
+ /*** Other Stuff ***/
+
+ /* These are just for convenience. */
+ EMailShellBackend *mail_shell_backend;
+ EMailShellContent *mail_shell_content;
+ EMailShellSidebar *mail_shell_sidebar;
+
+ /* For UI merging and unmerging. */
+ guint merge_id;
+ guint label_merge_id;
+
+ /* Filter rules correspond to the search entry menu. */
+ FilterRule *search_rules[MAIL_NUM_SEARCH_RULES];
+
+ guint show_deleted : 1;
+};
+
+void e_mail_shell_view_private_init
+ (EMailShellView *mail_shell_view,
+ EShellViewClass *shell_view_class);
+void e_mail_shell_view_private_constructed
+ (EMailShellView *mail_shell_view);
+void e_mail_shell_view_private_dispose
+ (EMailShellView *mail_shell_view);
+void e_mail_shell_view_private_finalize
+ (EMailShellView *mail_shell_view);
+
+/* Private Utilities */
+
+void e_mail_shell_view_actions_init
+ (EMailShellView *mail_shell_view);
+void e_mail_shell_view_restore_state
+ (EMailShellView *mail_shell_view);
+void e_mail_shell_view_execute_search
+ (EMailShellView *mail_shell_view);
+void e_mail_shell_view_create_filter_from_selected
+ (EMailShellView *mail_shell_view,
+ gint filter_type);
+void e_mail_shell_view_create_vfolder_from_selected
+ (EMailShellView *mail_shell_view,
+ gint vfolder_type);
+void e_mail_shell_view_update_popup_labels
+ (EMailShellView *mail_shell_view);
+void e_mail_shell_view_update_search_filter
+ (EMailShellView *mail_shell_view);
+void e_mail_shell_view_update_sidebar
+ (EMailShellView *mail_shell_view);
+
+G_END_DECLS
+
+#endif /* E_MAIL_SHELL_VIEW_PRIVATE_H */
diff --git a/modules/mail/e-mail-shell-view.c b/modules/mail/e-mail-shell-view.c
new file mode 100644
index 0000000000..fb045905e6
--- /dev/null
+++ b/modules/mail/e-mail-shell-view.c
@@ -0,0 +1,262 @@
+/*
+ * e-mail-shell-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-shell-view-private.h"
+
+static gpointer parent_class;
+static GType mail_shell_view_type;
+
+static void
+mail_shell_view_dispose (GObject *object)
+{
+ e_mail_shell_view_private_dispose (E_MAIL_SHELL_VIEW (object));
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_shell_view_finalize (GObject *object)
+{
+ e_mail_shell_view_private_finalize (E_MAIL_SHELL_VIEW (object));
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+mail_shell_view_constructed (GObject *object)
+{
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ e_mail_shell_view_private_constructed (E_MAIL_SHELL_VIEW (object));
+}
+
+static void
+mail_shell_view_toggled (EShellView *shell_view)
+{
+ EMailShellViewPrivate *priv;
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+ const gchar *basename;
+ gboolean view_is_active;
+
+ priv = E_MAIL_SHELL_VIEW_GET_PRIVATE (shell_view);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ view_is_active = e_shell_view_is_active (shell_view);
+ basename = E_MAIL_READER_UI_DEFINITION;
+
+ if (view_is_active && priv->merge_id == 0) {
+ priv->merge_id = e_load_ui_definition (ui_manager, basename);
+ e_mail_reader_create_charset_menu (
+ E_MAIL_READER (priv->mail_shell_content),
+ ui_manager, priv->merge_id);
+ } else if (!view_is_active && priv->merge_id != 0) {
+ gtk_ui_manager_remove_ui (ui_manager, priv->merge_id);
+ priv->merge_id = 0;
+ }
+
+ /* Chain up to parent's toggled() method. */
+ E_SHELL_VIEW_CLASS (parent_class)->toggled (shell_view);
+}
+
+static void
+mail_shell_view_update_actions (EShellView *shell_view)
+{
+ EMailShellView *mail_shell_view;
+ EMailShellSidebar *mail_shell_sidebar;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellWindow *shell_window;
+ EMFolderTree *folder_tree;
+ EAccount *account = NULL;
+ GtkAction *action;
+ const gchar *label;
+ gchar *uri;
+ gboolean sensitive;
+ guint32 state;
+
+ /* Be descriptive. */
+ gboolean account_is_groupwise;
+ gboolean folder_allows_children;
+ gboolean folder_can_be_deleted;
+ gboolean folder_is_junk;
+ gboolean folder_is_outbox;
+ gboolean folder_is_store;
+ gboolean folder_is_trash;
+
+ mail_shell_view = E_MAIL_SHELL_VIEW (shell_view);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ e_mail_reader_update_actions (E_MAIL_READER (shell_content));
+
+ mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
+ folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ state = e_shell_sidebar_check_state (shell_sidebar);
+
+ folder_allows_children =
+ (state & E_MAIL_SHELL_SIDEBAR_FOLDER_ALLOWS_CHILDREN);
+ folder_can_be_deleted =
+ (state & E_MAIL_SHELL_SIDEBAR_FOLDER_CAN_DELETE);
+ folder_is_junk =
+ (state & E_MAIL_SHELL_SIDEBAR_FOLDER_IS_JUNK);
+ folder_is_outbox =
+ (state & E_MAIL_SHELL_SIDEBAR_FOLDER_IS_OUTBOX);
+ folder_is_store =
+ (state & E_MAIL_SHELL_SIDEBAR_FOLDER_IS_STORE);
+ folder_is_trash =
+ (state & E_MAIL_SHELL_SIDEBAR_FOLDER_IS_TRASH);
+
+ uri = em_folder_tree_get_selected_uri (folder_tree);
+ if (uri != NULL) {
+ account = mail_config_get_account_by_source_url (uri);
+
+ /* FIXME This belongs in a GroupWise plugin. */
+ account_is_groupwise =
+ (g_strrstr (uri, "groupwise://") != NULL) &&
+ account != NULL && account->parent_uid != NULL;
+
+ g_free (uri);
+ }
+
+ action = ACTION (MAIL_ACCOUNT_DISABLE);
+ sensitive = (account != NULL) && folder_is_store;
+ if (account_is_groupwise)
+ label = _("Proxy _Logout");
+ else
+ label = _("_Disable Account");
+ gtk_action_set_sensitive (action, sensitive);
+ g_object_set (action, "label", label, NULL);
+
+ action = ACTION (MAIL_EMPTY_TRASH);
+ sensitive = folder_is_trash;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FLUSH_OUTBOX);
+ sensitive = folder_is_outbox;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FOLDER_COPY);
+ sensitive = !folder_is_store;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FOLDER_DELETE);
+ sensitive = !folder_is_store && folder_can_be_deleted;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FOLDER_MOVE);
+ sensitive = !folder_is_store && folder_can_be_deleted;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FOLDER_NEW);
+ sensitive = folder_allows_children;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FOLDER_PROPERTIES);
+ sensitive = !folder_is_store;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FOLDER_REFRESH);
+ sensitive = !folder_is_store;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FOLDER_RENAME);
+ sensitive = !folder_is_store && folder_can_be_deleted;
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = ACTION (MAIL_FOLDER_UNSUBSCRIBE);
+ sensitive = !folder_is_store && folder_can_be_deleted;
+ gtk_action_set_sensitive (action, sensitive);
+
+ e_mail_shell_view_update_popup_labels (mail_shell_view);
+}
+
+static void
+mail_shell_view_class_init (EMailShellViewClass *class,
+ GTypeModule *type_module)
+{
+ GObjectClass *object_class;
+ EShellViewClass *shell_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = mail_shell_view_dispose;
+ object_class->finalize = mail_shell_view_finalize;
+ object_class->constructed = mail_shell_view_constructed;
+
+ shell_view_class = E_SHELL_VIEW_CLASS (class);
+ shell_view_class->label = _("Mail");
+ shell_view_class->icon_name = "evolution-mail";
+ shell_view_class->ui_definition = "evolution-mail.ui";
+ shell_view_class->ui_manager_id = "org.gnome.evolution.mail";
+ shell_view_class->search_options = "/mail-search-options";
+ shell_view_class->search_rules = "searchtypes.xml";
+ shell_view_class->new_shell_content = e_mail_shell_content_new;
+ shell_view_class->new_shell_sidebar = e_mail_shell_sidebar_new;
+ shell_view_class->toggled = mail_shell_view_toggled;
+ shell_view_class->update_actions = mail_shell_view_update_actions;
+}
+
+static void
+mail_shell_view_init (EMailShellView *mail_shell_view,
+ EShellViewClass *shell_view_class)
+{
+ mail_shell_view->priv =
+ E_MAIL_SHELL_VIEW_GET_PRIVATE (mail_shell_view);
+
+ e_mail_shell_view_private_init (mail_shell_view, shell_view_class);
+}
+
+GType
+e_mail_shell_view_get_type (void)
+{
+ return mail_shell_view_type;
+}
+
+void
+e_mail_shell_view_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (EMailShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_shell_view_init,
+ NULL /* value_table */
+ };
+
+ mail_shell_view_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_VIEW,
+ "EMailShellView", &type_info, 0);
+}
diff --git a/modules/mail/e-mail-shell-view.h b/modules/mail/e-mail-shell-view.h
new file mode 100644
index 0000000000..d20bde74a6
--- /dev/null
+++ b/modules/mail/e-mail-shell-view.h
@@ -0,0 +1,72 @@
+/*
+ * e-mail-shell-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_SHELL_VIEW_H
+#define E_MAIL_SHELL_VIEW_H
+
+#include <shell/e-shell-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_SHELL_VIEW \
+ (e_mail_shell_view_get_type ())
+#define E_MAIL_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_SHELL_VIEW, EMailShellView))
+#define E_MAIL_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_SHELL_VIEW, EMailShellViewClass))
+#define E_IS_MAIL_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_SHELL_VIEW))
+#define E_IS_MAIL_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_SHELL_VIEW))
+#define E_MAIL_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_SHELL_VIEW, EMailShellViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailShellView EMailShellView;
+typedef struct _EMailShellViewClass EMailShellViewClass;
+typedef struct _EMailShellViewPrivate EMailShellViewPrivate;
+
+struct _EMailShellView {
+ EShellView parent;
+ EMailShellViewPrivate *priv;
+};
+
+struct _EMailShellViewClass {
+ EShellViewClass parent_class;
+};
+
+GType e_mail_shell_view_get_type (void);
+void e_mail_shell_view_register_type
+ (GTypeModule *type_module);
+gboolean e_mail_shell_view_get_show_deleted
+ (EMailShellView *mail_shell_view);
+void e_mail_shell_view_set_show_deleted
+ (EMailShellView *mail_shell_view,
+ gboolean show_deleted);
+
+G_END_DECLS
+
+#endif /* E_MAIL_SHELL_VIEW_H */
diff --git a/modules/mail/em-account-prefs.c b/modules/mail/em-account-prefs.c
new file mode 100644
index 0000000000..0f86cd8341
--- /dev/null
+++ b/modules/mail/em-account-prefs.c
@@ -0,0 +1,323 @@
+/*
+ * em-account-prefs.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* XXX EAccountManager handles all the user interface stuff. This subclass
+ * applies policies using mailer resources that EAccountManager does not
+ * have access to. The desire is to someday move account management
+ * completely out of the mailer, perhaps to evolution-data-server. */
+
+#include "em-account-prefs.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <camel/camel-url.h>
+
+#include <glib/gi18n.h>
+
+#include "e-util/e-error.h"
+
+#include "e-mail-store.h"
+#include "em-config.h"
+#include "em-account-editor.h"
+
+#define EM_ACCOUNT_PREFS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_ACCOUNT_PREFS, EMAccountPrefsPrivate))
+
+struct _EMAccountPrefsPrivate {
+ gpointer assistant; /* weak pointer */
+ gpointer editor; /* weak pointer */
+};
+
+static gpointer parent_class;
+
+static void
+account_prefs_enable_account_cb (EAccountTreeView *tree_view)
+{
+ EAccount *account;
+
+ account = e_account_tree_view_get_selected (tree_view);
+ g_return_if_fail (account != NULL);
+
+ e_mail_store_add_by_uri (account->source->url, account->name);
+}
+
+static void
+account_prefs_disable_account_cb (EAccountTreeView *tree_view)
+{
+ EAccountList *account_list;
+ EAccount *account;
+ gpointer parent;
+ gint response;
+
+ account = e_account_tree_view_get_selected (tree_view);
+ g_return_if_fail (account != NULL);
+
+ account_list = e_account_tree_view_get_account_list (tree_view);
+ g_return_if_fail (account_list != NULL);
+
+ if (!e_account_list_account_has_proxies (account_list, account))
+ return;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (tree_view));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ response = e_error_run (
+ parent, "mail:ask-delete-proxy-accounts", NULL);
+
+ if (response != GTK_RESPONSE_YES) {
+ g_signal_stop_emission_by_name (tree_view, "disable-account");
+ return;
+ }
+
+ e_account_list_remove_account_proxies (account_list, account);
+
+ e_mail_store_remove_by_uri (account->source->url);
+}
+
+static void
+account_prefs_add_account (EAccountManager *manager)
+{
+ EMAccountPrefsPrivate *priv;
+ EMAccountEditor *emae;
+ gpointer parent;
+
+ priv = EM_ACCOUNT_PREFS_GET_PRIVATE (manager);
+
+ if (priv->assistant != NULL) {
+ gtk_window_present (GTK_WINDOW (priv->assistant));
+ return;
+ }
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ /** @HookPoint-EMConfig: New Mail Account Assistant
+ * @Id: org.gnome.evolution.mail.config.accountAssistant
+ * @Type: E_CONFIG_ASSISTANT
+ * @Class: org.gnome.evolution.mail.config:1.0
+ * @Target: EMConfigTargetAccount
+ *
+ * The new mail account assistant.
+ */
+ emae = em_account_editor_new (
+ NULL, EMAE_ASSISTANT,
+ "org.gnome.evolution.mail.config.accountAssistant");
+ priv->assistant = emae->editor;
+
+ g_object_add_weak_pointer (G_OBJECT (priv->assistant), &priv->assistant);
+ gtk_window_set_transient_for (GTK_WINDOW (priv->assistant), parent);
+ gtk_widget_show (priv->assistant);
+}
+
+static void
+account_prefs_edit_account (EAccountManager *manager)
+{
+ EMAccountPrefsPrivate *priv;
+ EMAccountEditor *emae;
+ EAccountTreeView *tree_view;
+ EAccountList *account_list;
+ EAccount *account;
+ gpointer parent;
+
+ priv = EM_ACCOUNT_PREFS_GET_PRIVATE (manager);
+
+ if (priv->editor != NULL) {
+ gtk_window_present (GTK_WINDOW (priv->editor));
+ return;
+ }
+
+ account_list = e_account_manager_get_account_list (manager);
+ tree_view = e_account_manager_get_tree_view (manager);
+ account = e_account_tree_view_get_selected (tree_view);
+ g_return_if_fail (account != NULL);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ /** @HookPoint-EMConfig: Mail Account Editor
+ * @Id: org.gnome.evolution.mail.config.accountEditor
+ * @Type: E_CONFIG_BOOK
+ * @Class: org.gnome.evolution.mail.config:1.0
+ * @Target: EMConfigTargetAccount
+ *
+ * The account editor window.
+ */
+ emae = em_account_editor_new (
+ account, EMAE_NOTEBOOK,
+ "org.gnome.evolution.mail.config.accountEditor");
+ priv->editor = emae->editor;
+
+ g_object_add_weak_pointer (G_OBJECT (priv->editor), &priv->editor);
+ gtk_window_set_transient_for (GTK_WINDOW (priv->editor), parent);
+ gtk_widget_show (priv->editor);
+}
+
+static void
+account_prefs_delete_account (EAccountManager *manager)
+{
+ EMAccountPrefsPrivate *priv;
+ EAccountTreeView *tree_view;
+ EAccountList *account_list;
+ EAccount *account;
+ gboolean has_proxies;
+ gpointer parent;
+ gint response;
+
+ priv = EM_ACCOUNT_PREFS_GET_PRIVATE (manager);
+
+ account_list = e_account_manager_get_account_list (manager);
+ tree_view = e_account_manager_get_tree_view (manager);
+ account = e_account_tree_view_get_selected (tree_view);
+ g_return_if_fail (account != NULL);
+
+ /* Make sure we aren't editing anything... */
+ if (priv->editor != NULL)
+ return;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ has_proxies =
+ e_account_list_account_has_proxies (account_list, account);
+
+ response = e_error_run (
+ parent, has_proxies ?
+ "mail:ask-delete-account-with-proxies" :
+ "mail:ask-delete-account", NULL);
+
+ if (response != GTK_RESPONSE_YES) {
+ g_signal_stop_emission_by_name (manager, "delete-account");
+ return;
+ }
+
+ /* Remove the account from the folder tree. */
+ if (account->enabled && account->source && account->source->url)
+ e_mail_store_remove_by_uri (account->source->url);
+
+ /* Remove all the proxies the account has created. */
+ if (has_proxies)
+ e_account_list_remove_account_proxies (account_list, account);
+
+ /* Remove it from the config file. */
+ e_account_list_remove (account_list, account);
+
+ e_account_list_save (account_list);
+}
+
+static void
+account_prefs_dispose (GObject *object)
+{
+ EMAccountPrefsPrivate *priv;
+
+ priv = EM_ACCOUNT_PREFS_GET_PRIVATE (object);
+
+ if (priv->assistant != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->assistant), &priv->assistant);
+ priv->assistant = NULL;
+ }
+
+ if (priv->editor != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->editor), &priv->editor);
+ priv->editor = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+account_prefs_class_init (EMAccountPrefsClass *class)
+{
+ GObjectClass *object_class;
+ EAccountManagerClass *account_manager_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMAccountPrefsPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = account_prefs_dispose;
+
+ account_manager_class = E_ACCOUNT_MANAGER_CLASS (class);
+ account_manager_class->add_account = account_prefs_add_account;
+ account_manager_class->edit_account = account_prefs_edit_account;
+ account_manager_class->delete_account = account_prefs_delete_account;
+}
+
+static void
+account_prefs_init (EMAccountPrefs *prefs)
+{
+ EAccountManager *manager;
+ EAccountTreeView *tree_view;
+
+ prefs->priv = EM_ACCOUNT_PREFS_GET_PRIVATE (prefs);
+
+ manager = E_ACCOUNT_MANAGER (prefs);
+ tree_view = e_account_manager_get_tree_view (manager);
+
+ g_signal_connect (
+ tree_view, "enable-account",
+ G_CALLBACK (account_prefs_enable_account_cb), NULL);
+
+ g_signal_connect (
+ tree_view, "disable-account",
+ G_CALLBACK (account_prefs_disable_account_cb), NULL);
+}
+
+GType
+em_account_prefs_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMAccountPrefsClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) account_prefs_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMAccountPrefs),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) account_prefs_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_ACCOUNT_MANAGER, "EMAccountPrefs",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+em_account_prefs_new (EAccountList *account_list)
+{
+ g_return_val_if_fail (E_IS_ACCOUNT_LIST (account_list), NULL);
+
+ return g_object_new (
+ EM_TYPE_ACCOUNT_PREFS, "account-list", account_list, NULL);
+}
diff --git a/modules/mail/em-account-prefs.h b/modules/mail/em-account-prefs.h
new file mode 100644
index 0000000000..82df8fa941
--- /dev/null
+++ b/modules/mail/em-account-prefs.h
@@ -0,0 +1,69 @@
+/*
+ * em-account-prefs.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef EM_ACCOUNT_PREFS_H
+#define EM_ACCOUNT_PREFS_H
+
+#include <gtk/gtk.h>
+#include <table/e-table.h>
+#include <libedataserver/e-account-list.h>
+#include <misc/e-account-manager.h>
+
+/* Standard GObject macros */
+#define EM_TYPE_ACCOUNT_PREFS \
+ (em_account_prefs_get_type ())
+#define EM_ACCOUNT_PREFS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_ACCOUNT_PREFS, EMAccountPrefs))
+#define EM_ACCOUNT_PREFS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_ACCOUNT_PREFS, EMAccountPrefsClass))
+#define EM_IS_ACCOUNT_PREFS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_ACCOUNT_PREFS))
+#define EM_IS_ACCOUNT_PREFS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_ACCOUNT_PREFS))
+#define EM_ACCOUNT_PREFS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_ACCOUNT_PREFS, EMAccountPrefsClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMAccountPrefs EMAccountPrefs;
+typedef struct _EMAccountPrefsClass EMAccountPrefsClass;
+typedef struct _EMAccountPrefsPrivate EMAccountPrefsPrivate;
+
+struct _EMAccountPrefs {
+ EAccountManager parent;
+ EMAccountPrefsPrivate *priv;
+};
+
+struct _EMAccountPrefsClass {
+ EAccountManagerClass parent_class;
+};
+
+GType em_account_prefs_get_type (void);
+GtkWidget * em_account_prefs_new (EAccountList *account_list);
+
+G_END_DECLS
+
+#endif /* EM_ACCOUNT_PREFS_H */
diff --git a/modules/mail/em-composer-prefs.c b/modules/mail/em-composer-prefs.c
new file mode 100644
index 0000000000..4c29125c0b
--- /dev/null
+++ b/modules/mail/em-composer-prefs.c
@@ -0,0 +1,567 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/e-signature-utils.h"
+#include "e-util/gconf-bridge.h"
+
+#include "em-composer-prefs.h"
+#include "composer/e-msg-composer.h"
+
+#include <camel/camel-iconv.h>
+
+#include <misc/e-gui-utils.h>
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include <gtkhtml/gtkhtml.h>
+#include <editor/gtkhtml-spell-language.h>
+
+#include "e-util/e-error.h"
+#include "e-util/e-util-private.h"
+#include "widgets/misc/e-charset-combo-box.h"
+#include "widgets/misc/e-signature-editor.h"
+#include "widgets/misc/e-signature-manager.h"
+#include "widgets/misc/e-signature-preview.h"
+
+#include "mail-config.h"
+#include "em-config.h"
+
+static gpointer parent_class;
+
+static gboolean
+transform_color_to_string (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ const GdkColor *color;
+ gchar *string;
+
+ color = g_value_get_boxed (src_value);
+ string = gdk_color_to_string (color);
+ g_value_set_string (dst_value, string);
+ g_free (string);
+
+ return TRUE;
+}
+
+static gboolean
+transform_string_to_color (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ GdkColor color;
+ const gchar *string;
+ gboolean success = FALSE;
+
+ string = g_value_get_string (src_value);
+ if (gdk_color_parse (string, &color)) {
+ g_value_set_boxed (dst_value, &color);
+ success = TRUE;
+ }
+
+ return success;
+}
+
+static gboolean
+transform_old_to_new_reply_style (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gboolean success = TRUE;
+
+ /* XXX This is the kind of legacy crap we wind up
+ * with when we don't migrate things properly. */
+
+ switch (g_value_get_int (src_value)) {
+ case 0: /* Quoted: 0 -> 2 */
+ g_value_set_int (dst_value, 2);
+ break;
+
+ case 1: /* Do Not Quote: 1 -> 3 */
+ g_value_set_int (dst_value, 3);
+ break;
+
+ case 2: /* Attach: 2 -> 0 */
+ g_value_set_int (dst_value, 0);
+ break;
+
+ case 3: /* Outlook: 3 -> 1 */
+ g_value_set_int (dst_value, 1);
+ break;
+
+ default:
+ success = FALSE;
+ break;
+ }
+
+ return success;
+}
+
+static gboolean
+transform_new_to_old_reply_style (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
+{
+ gboolean success = TRUE;
+
+ /* XXX This is the kind of legacy crap we wind up
+ * with when we don't migrate things properly. */
+
+ switch (g_value_get_int (src_value)) {
+ case 0: /* Attach: 0 -> 2 */
+ g_value_set_int (dst_value, 2);
+ break;
+
+ case 1: /* Outlook: 1 -> 3 */
+ g_value_set_int (dst_value, 3);
+ break;
+
+ case 2: /* Quoted: 2 -> 0 */
+ g_value_set_int (dst_value, 0);
+ break;
+
+ case 3: /* Do Not Quote: 3 -> 1 */
+ g_value_set_int (dst_value, 1);
+ break;
+
+ default:
+ success = FALSE;
+ break;
+ }
+
+ return success;
+}
+
+static void
+composer_prefs_finalize (GObject *object)
+{
+ EMComposerPrefs *prefs = (EMComposerPrefs *) object;
+
+ g_object_unref (prefs->gui);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+composer_prefs_class_init (EMComposerPrefsClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = composer_prefs_finalize;
+}
+
+static void
+composer_prefs_init (EMComposerPrefs *prefs)
+{
+}
+
+GType
+em_composer_prefs_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMComposerPrefsClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) composer_prefs_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMComposerPrefs),
+ 0, /* n_allocs */
+ (GInstanceInitFunc) composer_prefs_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_VBOX, "EMComposerPrefs", &type_info, 0);
+ }
+
+ return type;
+}
+
+void
+em_composer_prefs_new_signature (GtkWindow *parent,
+ gboolean html_mode)
+{
+ GtkWidget *editor;
+
+ editor = e_signature_editor_new ();
+ gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (editor), html_mode);
+ gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
+ gtk_widget_show (editor);
+}
+
+static void
+spell_language_toggled_cb (GtkCellRendererToggle *renderer,
+ const gchar *path_string,
+ EMComposerPrefs *prefs)
+{
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gboolean active;
+ gboolean valid;
+
+ model = prefs->language_model;
+
+ /* Convert the path string to a tree iterator. */
+ path = gtk_tree_path_new_from_string (path_string);
+ valid = gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+ g_return_if_fail (valid);
+
+ /* Toggle the active state. */
+ gtk_tree_model_get (model, &iter, 0, &active, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !active, -1);
+}
+
+static void
+spell_language_save (EMComposerPrefs *prefs)
+{
+ GList *spell_languages = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid;
+
+ model = prefs->language_model;
+
+ /* Build a list of active spell languages. */
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+ while (valid) {
+ const GtkhtmlSpellLanguage *language;
+ gboolean active;
+
+ gtk_tree_model_get (
+ model, &iter, 0, &active, 2, &language, -1);
+
+ if (active)
+ spell_languages = g_list_prepend (
+ spell_languages, (gpointer) language);
+
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
+ spell_languages = g_list_reverse (spell_languages);
+
+ /* Update the GConf value. */
+ e_save_spell_languages (spell_languages);
+
+ g_list_free (spell_languages);
+}
+
+static void
+spell_setup (EMComposerPrefs *prefs)
+{
+ const GList *available_languages;
+ GList *active_languages;
+ GtkListStore *store;
+
+ store = GTK_LIST_STORE (prefs->language_model);
+ available_languages = gtkhtml_spell_language_get_available ();
+
+ active_languages = e_load_spell_languages ();
+
+ /* Populate the GtkListStore. */
+ while (available_languages != NULL) {
+ const GtkhtmlSpellLanguage *language;
+ GtkTreeIter tree_iter;
+ const gchar *name;
+ gboolean active;
+
+ language = available_languages->data;
+ name = gtkhtml_spell_language_get_name (language);
+ active = (g_list_find (active_languages, language) != NULL);
+
+ gtk_list_store_append (store, &tree_iter);
+
+ gtk_list_store_set (
+ store, &tree_iter,
+ 0, active, 1, name, 2, language, -1);
+
+ available_languages = available_languages->next;
+ }
+
+ g_list_free (active_languages);
+}
+
+static GtkWidget *
+emcp_widget_glade (EConfig *ec,
+ EConfigItem *item,
+ GtkWidget *parent,
+ GtkWidget *old,
+ gpointer data)
+{
+ EMComposerPrefs *prefs = data;
+
+ return glade_xml_get_widget (prefs->gui, item->label);
+}
+
+/* plugin meta-data */
+static EMConfigItem emcp_items[] = {
+ { E_CONFIG_BOOK, (gchar *) "", (gchar *) "composer_toplevel", emcp_widget_glade },
+ { E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) "vboxGeneral", emcp_widget_glade },
+ { E_CONFIG_SECTION, (gchar *) "00.general/00.behavior", (gchar *) "vboxBehavior", emcp_widget_glade },
+ { E_CONFIG_SECTION, (gchar *) "00.general/10.alerts", (gchar *) "vboxAlerts", emcp_widget_glade },
+ { E_CONFIG_PAGE, (gchar *) "10.signatures", (gchar *) "vboxSignatures", emcp_widget_glade },
+ /* signature/signatures and signature/preview parts not usable */
+
+ { E_CONFIG_PAGE, (gchar *) "20.spellcheck", (gchar *) "vboxSpellChecking", emcp_widget_glade },
+ { E_CONFIG_SECTION, (gchar *) "20.spellcheck/00.languages", (gchar *) "vbox178", emcp_widget_glade },
+ { E_CONFIG_SECTION, (gchar *) "20.spellcheck/00.options", (gchar *) "vboxOptions", emcp_widget_glade },
+};
+
+static void
+emcp_free (EConfig *ec, GSList *items, gpointer data)
+{
+ /* the prefs data is freed automagically */
+ g_slist_free (items);
+}
+
+static void
+em_composer_prefs_construct (EMComposerPrefs *prefs,
+ EShell *shell)
+{
+ GtkWidget *toplevel, *widget, *info_pixmap;
+ GtkWidget *container;
+ EShellSettings *shell_settings;
+ ESignatureList *signature_list;
+ ESignatureTreeView *signature_tree_view;
+ GladeXML *gui;
+ GtkTreeView *view;
+ GtkListStore *store;
+ GtkTreeSelection *selection;
+ GtkCellRenderer *renderer;
+ GConfBridge *bridge;
+ GConfClient *client;
+ EMConfig *ec;
+ EMConfigTargetPrefs *target;
+ GSList *l;
+ gint i;
+ gchar *gladefile;
+
+ bridge = gconf_bridge_get ();
+ client = mail_config_get_gconf_client ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ gladefile = g_build_filename (EVOLUTION_GLADEDIR,
+ "mail-config.glade",
+ NULL);
+ gui = glade_xml_new (gladefile, "composer_toplevel", NULL);
+ prefs->gui = gui;
+ g_free (gladefile);
+
+ /** @HookPoint-EMConfig: Mail Composer Preferences
+ * @Id: org.gnome.evolution.mail.composerPrefs
+ * @Type: E_CONFIG_BOOK
+ * @Class: org.gnome.evolution.mail.config:1.0
+ * @Target: EMConfigTargetPrefs
+ *
+ * The mail composer preferences settings page.
+ */
+ ec = em_config_new(E_CONFIG_BOOK, "org.gnome.evolution.mail.composerPrefs");
+ l = NULL;
+ for (i = 0; i < G_N_ELEMENTS (emcp_items); i++)
+ l = g_slist_prepend(l, &emcp_items[i]);
+ e_config_add_items((EConfig *)ec, l, NULL, NULL, emcp_free, prefs);
+
+ /* General tab */
+
+ /* Default Behavior */
+ widget = glade_xml_get_widget (gui, "chkSendHTML");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-format-html",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "chkPromptEmptySubject");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-prompt-empty-subject",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "chkPromptBccOnly");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-prompt-only-bcc",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "chkAutoSmileys");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-magic-smileys",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "chkRequestReceipt");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-request-receipt",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "chkReplyStartBottom");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-reply-start-bottom",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "chkOutlookFilenames");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-outlook-filenames",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "chkTopSignature");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-top-signature",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "chkEnableSpellChecking");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-inline-spelling",
+ G_OBJECT (widget), "active");
+
+ widget = e_charset_combo_box_new ();
+ container = glade_xml_get_widget (gui, "hboxComposerCharset");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "composer-charset",
+ G_OBJECT (widget), "charset");
+
+ /* Spell Checking */
+ widget = glade_xml_get_widget (gui, "listSpellCheckLanguage");
+ view = GTK_TREE_VIEW (widget);
+ store = gtk_list_store_new (
+ 3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER);
+ g_signal_connect_swapped (
+ store, "row-changed",
+ G_CALLBACK (spell_language_save), prefs);
+ prefs->language_model = GTK_TREE_MODEL (store);
+ gtk_tree_view_set_model (view, prefs->language_model);
+ renderer = gtk_cell_renderer_toggle_new ();
+ g_signal_connect (
+ renderer, "toggled",
+ G_CALLBACK (spell_language_toggled_cb), prefs);
+ gtk_tree_view_insert_column_with_attributes (
+ view, -1, _("Enabled"),
+ renderer, "active", 0, NULL);
+
+ gtk_tree_view_insert_column_with_attributes (
+ view, -1, _("Language(s)"),
+ gtk_cell_renderer_text_new (),
+ "text", 1, NULL);
+ selection = gtk_tree_view_get_selection (view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
+ info_pixmap = glade_xml_get_widget (gui, "pixmapSpellInfo");
+ gtk_image_set_from_stock (
+ GTK_IMAGE (info_pixmap),
+ GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON);
+
+ widget = glade_xml_get_widget (gui, "colorButtonSpellCheckColor");
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "composer-spell-color",
+ G_OBJECT (widget), "color",
+ transform_string_to_color,
+ transform_color_to_string,
+ NULL, NULL);
+
+ spell_setup (prefs);
+
+ /* Forwards and Replies */
+ widget = glade_xml_get_widget (gui, "comboboxForwardStyle");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-forward-style",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "comboboxReplyStyle");
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "mail-reply-style",
+ G_OBJECT (widget), "active",
+ transform_old_to_new_reply_style,
+ transform_new_to_old_reply_style,
+ NULL, NULL);
+
+ /* Signatures */
+ signature_list = e_get_signature_list ();
+ container = glade_xml_get_widget (gui, "alignSignatures");
+ widget = e_signature_manager_new (signature_list);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ /* The mail shell backend responds to the "window-created" signal
+ * that this triggers and configures it with composer preferences. */
+ g_signal_connect_swapped (
+ widget, "editor-created",
+ G_CALLBACK (e_shell_watch_window), shell);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "composer-format-html",
+ G_OBJECT (widget), "prefer-html");
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-command-line",
+ G_OBJECT (widget), "allow-scripts");
+
+ signature_tree_view = e_signature_manager_get_tree_view (
+ E_SIGNATURE_MANAGER (widget));
+
+ container = glade_xml_get_widget (gui, "scrolled-sig");
+ widget = e_signature_preview_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-command-line",
+ G_OBJECT (widget), "allow-scripts");
+
+ e_binding_new (
+ G_OBJECT (signature_tree_view), "selected",
+ G_OBJECT (widget), "signature");
+
+ /* get our toplevel widget */
+ target = em_config_target_new_prefs (ec, client);
+ e_config_set_target ((EConfig *)ec, (EConfigTarget *)target);
+ toplevel = e_config_create_widget ((EConfig *)ec);
+ gtk_container_add (GTK_CONTAINER (prefs), toplevel);
+}
+
+GtkWidget *
+em_composer_prefs_new (EShell *shell)
+{
+ EMComposerPrefs *prefs;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ prefs = g_object_new (EM_TYPE_COMPOSER_PREFS, NULL);
+ em_composer_prefs_construct (prefs, shell);
+
+ return GTK_WIDGET (prefs);
+}
diff --git a/mail/em-composer-prefs.h b/modules/mail/em-composer-prefs.h
index 1ff850623d..6faa18b7d9 100644
--- a/mail/em-composer-prefs.h
+++ b/modules/mail/em-composer-prefs.h
@@ -20,13 +20,15 @@
*
*/
-#ifndef __EM_COMPOSER_PREFS_H__
-#define __EM_COMPOSER_PREFS_H__
+#ifndef EM_COMPOSER_PREFS_H
+#define EM_COMPOSER_PREFS_H
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gtkhtml/gtkhtml.h>
+#include <shell/e-shell.h>
+
/* Standard GObject macros */
#define EM_TYPE_COMPOSER_PREFS \
(em_composer_prefs_get_type ())
@@ -52,7 +54,6 @@ typedef struct _EMComposerPrefs EMComposerPrefs;
typedef struct _EMComposerPrefsClass EMComposerPrefsClass;
struct _ESignature;
-struct _GladeXML;
struct _EMComposerPrefs {
GtkVBox parent;
@@ -61,10 +62,6 @@ struct _EMComposerPrefs {
/* General tab */
- /* Default Behavior */
- GtkOptionMenu *charset;
-
- GtkColorButton *color;
GtkTreeModel *language_model;
/* Forwards and Replies */
@@ -72,20 +69,7 @@ struct _EMComposerPrefs {
GtkComboBox *reply_style;
/* Signatures */
- GtkTreeView *sig_list;
- GHashTable *sig_hash;
- GtkButton *sig_add;
- GtkButton *sig_add_script;
- GtkButton *sig_edit;
- GtkButton *sig_delete;
GtkHTML *sig_preview;
-
- GladeXML *sig_script_gui;
- GtkWidget *sig_script_dialog;
-
- guint sig_added_id;
- guint sig_removed_id;
- guint sig_changed_id;
};
struct _EMComposerPrefsClass {
@@ -93,14 +77,10 @@ struct _EMComposerPrefsClass {
};
GType em_composer_prefs_get_type (void);
-GtkWidget * em_composer_prefs_new (void);
+GtkWidget * em_composer_prefs_new (EShell *shell);
void em_composer_prefs_new_signature (GtkWindow *parent,
gboolean html_mode);
-/* needed by global config */
-#define EM_COMPOSER_PREFS_CONTROL_ID \
- "OAFIID:GNOME_Evolution_Mail_ComposerPrefs_ConfigControl:" BASE_VERSION
-
G_END_DECLS
-#endif /* __EM_COMPOSER_PREFS_H__ */
+#endif /* EM_COMPOSER_PREFS_H */
diff --git a/mail/em-mailer-prefs.c b/modules/mail/em-mailer-prefs.c
index 7da40551a5..621dae4ce5 100644
--- a/mail/em-mailer-prefs.c
+++ b/modules/mail/em-mailer-prefs.c
@@ -25,15 +25,14 @@
#endif
#include <string.h>
+#include <glib/gi18n-lib.h>
#include "em-mailer-prefs.h"
-#include "em-format.h"
+#include "em-format/em-format.h"
#include <camel/camel-iconv.h>
#include <gtkhtml/gtkhtml-properties.h>
#include <libxml/tree.h>
-#include "misc/e-charset-picker.h"
-#include <bonobo/bonobo-generic-factory.h>
#include <glade/glade.h>
@@ -41,18 +40,20 @@
#include "libedataserverui/e-cell-renderer-color.h"
+#include "e-util/e-binding.h"
#include "e-util/e-datetime-format.h"
#include "e-util/e-util-private.h"
-#include "e-util/e-util-labels.h"
+#include "widgets/misc/e-charset-combo-box.h"
+#include "e-mail-label-manager.h"
#include "mail-config.h"
-#include "em-junk-hook.h"
+#include "em-junk.h"
#include "em-config.h"
#include "mail-session.h"
static void em_mailer_prefs_class_init (EMMailerPrefsClass *class);
static void em_mailer_prefs_init (EMMailerPrefs *dialog);
-static void em_mailer_prefs_dispose (GObject *obj);
+static void em_mailer_prefs_finalize (GObject *object);
static GtkVBoxClass *parent_class = NULL;
@@ -128,7 +129,7 @@ em_mailer_prefs_class_init (EMMailerPrefsClass *klass)
object_class = (GObjectClass *) klass;
parent_class = g_type_class_ref (gtk_vbox_get_type ());
- object_class->dispose = em_mailer_prefs_dispose;
+ object_class->finalize = em_mailer_prefs_finalize;
}
static void
@@ -138,15 +139,10 @@ em_mailer_prefs_init (EMMailerPrefs *preferences)
}
static void
-em_mailer_prefs_dispose (GObject *obj)
+em_mailer_prefs_finalize (GObject *obj)
{
EMMailerPrefs *prefs = (EMMailerPrefs *) obj;
- if (prefs->header_list_store) {
- g_object_unref (prefs->header_list_store);
- prefs->header_list_store = NULL;
- }
-
g_object_unref (prefs->gui);
if (prefs->labels_change_notify_id) {
@@ -155,155 +151,48 @@ em_mailer_prefs_dispose (GObject *obj)
prefs->labels_change_notify_id = 0;
}
- ((GObjectClass *)(parent_class))->dispose (obj);
+ ((GObjectClass *)(parent_class))->finalize (obj);
}
-static void
-color_button_set_color (GtkColorButton *color_button, const gchar *spec)
+static gboolean
+mark_seen_timeout_transform (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
{
- GdkColor color;
+ gdouble v_double;
- if (gdk_color_parse (spec, &color))
- gtk_color_button_set_color (color_button, &color);
+ /* Shell Settings (gint) -> Spin Button (double) */
+ v_double = (gdouble) g_value_get_int (src_value);
+ g_value_set_double (dst_value, v_double / 1000.0);
+
+ return TRUE;
}
-static void
-citation_color_set (GtkColorButton *color_button, EMMailerPrefs *prefs)
+static gboolean
+mark_seen_timeout_reverse_transform (const GValue *src_value,
+ GValue *dst_value,
+ gpointer user_data)
{
- GdkColor color;
- gchar spec[16];
+ gdouble v_double;
- gtk_color_button_get_color (color_button, &color);
- g_snprintf (spec, sizeof (spec), "#%04x%04x%04x",
- color.red, color.green, color.blue);
+ /* Spin Button (double) -> Shell Settings (gint) */
+ v_double = g_value_get_double (src_value);
+ g_value_set_int (dst_value, v_double * 1000);
- gconf_client_set_string (prefs->gconf,
- "/apps/evolution/mail/display/citation_colour",
- spec, NULL);
+ return TRUE;
}
enum {
- LABEL_LIST_COLUMN_COLOR,
- LABEL_LIST_COLUMN_TAG,
- LABEL_LIST_COLUMN_NAME
-};
-
-enum {
JH_LIST_COLUMN_NAME,
JH_LIST_COLUMN_VALUE
};
-static void
-label_sensitive_buttons (EMMailerPrefs *prefs)
-{
- gboolean can_remove = FALSE, have_selected = FALSE, locked;
-
- g_return_if_fail (prefs);
-
- /* it's not sensitive if it's locked for updates */
- locked = !GTK_WIDGET_IS_SENSITIVE (prefs->label_tree);
-
- if (!locked) {
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gchar *tag = NULL;
-
- gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1);
-
- can_remove = tag && !e_util_labels_is_system (tag);
- have_selected = TRUE;
-
- g_free (tag);
- }
- }
-
- gtk_widget_set_sensitive (prefs->label_remove, !locked && can_remove);
- gtk_widget_set_sensitive (prefs->label_edit, !locked && have_selected);
-}
-
-static void
-label_tree_cursor_changed (GtkWidget *widget, gpointer user_data)
-{
- label_sensitive_buttons (user_data);
-}
-
-static void
-label_tree_refill (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data)
-{
- EMMailerPrefs *prefs = (EMMailerPrefs *)user_data;
- GSList *labels, *l;
- GtkTreeSelection *selection;
- GtkListStore *store;
- GtkTreeModel *model;
- GtkTreeIter last_iter;
- gchar *last_path = NULL;
-
- g_return_if_fail (prefs != NULL);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &last_iter))
- last_path = gtk_tree_model_get_string_from_iter (model, &last_iter);
-
- store = GTK_LIST_STORE (model);
- gtk_list_store_clear (store);
-
- /* cannot use mail-config cache here, because it's (or can be) updated later than this function call */
- labels = e_util_labels_parse (client);
-
- for (l = labels; l; l = l->next) {
- GdkColor color;
- GtkTreeIter iter;
- EUtilLabel *label = l->data;
-
- if (label->colour)
- gdk_color_parse (label->colour, &color);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (
- store, &iter,
- LABEL_LIST_COLUMN_COLOR, label->colour ? &color : NULL,
- LABEL_LIST_COLUMN_NAME, label->name,
- LABEL_LIST_COLUMN_TAG, label->tag,
- -1);
- }
-
- if (last_path) {
- gint children;
-
- children = gtk_tree_model_iter_n_children (model, NULL);
- if (children > 0) {
- GtkTreePath *path;
-
- if (!gtk_tree_model_get_iter_from_string (model, &last_iter, last_path))
- gtk_tree_model_iter_nth_child (model, &last_iter, NULL, children - 1);
-
- path = gtk_tree_model_get_path (model, &last_iter);
- if (path) {
- GtkTreeViewColumn *focus_col = gtk_tree_view_get_column (GTK_TREE_VIEW (prefs->label_tree), LABEL_LIST_COLUMN_NAME);
-
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (prefs->label_tree), path, focus_col, FALSE);
- gtk_tree_view_row_activated (GTK_TREE_VIEW (prefs->label_tree), path, focus_col);
- gtk_tree_path_free (path);
- }
- }
-
- g_free (last_path);
- }
-
- label_sensitive_buttons (prefs);
- e_util_labels_free (labels);
-}
static void
jh_tree_refill (EMMailerPrefs *prefs)
{
- GtkListStore *store;
+ GtkListStore *store = prefs->junk_header_list_store;
GSList *l, *cjh = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
- store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (prefs->junk_header_tree)));
gtk_list_store_clear (store);
for (l = cjh; l; l = l->next) {
@@ -420,126 +309,28 @@ jh_remove_cb (GtkWidget *widget, gpointer user_data)
}
}
-static gboolean
-init_junk_tree (GtkTreeView *jh_tree, EMMailerPrefs *prefs)
+static GtkListStore *
+init_junk_tree (GtkWidget *label_tree, EMMailerPrefs *prefs)
{
GtkListStore *store;
GtkCellRenderer *renderer;
gint col;
- g_return_val_if_fail (jh_tree != NULL, FALSE);
- g_return_val_if_fail (prefs != NULL, FALSE);
+ g_return_val_if_fail (label_tree != NULL, NULL);
+ g_return_val_if_fail (prefs != NULL, NULL);
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- gtk_tree_view_set_model (GTK_TREE_VIEW (jh_tree), GTK_TREE_MODEL (store));
- g_object_unref (store);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (label_tree), GTK_TREE_MODEL (store));
renderer = gtk_cell_renderer_text_new ();
- col = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (jh_tree), -1, _("Header"), renderer, "text", JH_LIST_COLUMN_NAME, NULL);
+ col = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Header"), renderer, "text", JH_LIST_COLUMN_NAME, NULL);
g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (jh_tree), -1, _("Contains Value"), renderer, "text", JH_LIST_COLUMN_VALUE, NULL);
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Contains Value"), renderer, "text", JH_LIST_COLUMN_VALUE, NULL);
g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
- jh_tree_refill (prefs);
-
- return TRUE;
-}
-
-static gboolean
-init_label_tree (GtkWidget *label_tree, EMMailerPrefs *prefs, gboolean locked)
-{
- GtkListStore *store;
- GtkCellRenderer *renderer;
- gint col;
-
- g_return_val_if_fail (label_tree != NULL, FALSE);
- g_return_val_if_fail (prefs != NULL, FALSE);
-
- store = gtk_list_store_new (3, GDK_TYPE_COLOR, G_TYPE_STRING, G_TYPE_STRING);
- gtk_tree_view_set_model (GTK_TREE_VIEW (label_tree), GTK_TREE_MODEL (store));
- g_object_unref (store);
-
- renderer = e_cell_renderer_color_new ();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Color"), renderer, "color", LABEL_LIST_COLUMN_COLOR, NULL);
-
- renderer = gtk_cell_renderer_text_new ();
- col = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Tag"), renderer, "text", LABEL_LIST_COLUMN_TAG, NULL);
- g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL);
- gtk_tree_view_column_set_visible (gtk_tree_view_get_column (GTK_TREE_VIEW (label_tree), col - 1), FALSE);
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Name"), renderer, "text", LABEL_LIST_COLUMN_NAME, NULL);
- g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL);
-
- if (!locked)
- g_signal_connect (label_tree, "cursor-changed", G_CALLBACK (label_tree_cursor_changed), prefs);
-
- label_tree_refill (NULL, 0, NULL, prefs);
-
- prefs->labels_change_notify_id = gconf_client_notify_add (prefs->gconf, E_UTIL_LABELS_GCONF_KEY, label_tree_refill, prefs, NULL, NULL);
-
- return TRUE;
-}
-
-static void
-label_add_cb (GtkWidget *widget, gpointer user_data)
-{
- gchar *tag;
-
- tag = e_util_labels_add_with_dlg (GTK_WINDOW (gtk_widget_get_toplevel (widget)), NULL);
-
- g_free (tag);
-}
-
-static void
-label_remove_cb (GtkWidget *widget, gpointer user_data)
-{
- EMMailerPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- g_return_if_fail (prefs != NULL);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gchar *tag = NULL;
-
- gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1);
-
- if (tag && !e_util_labels_is_system (tag))
- e_util_labels_remove (tag);
-
- g_free (tag);
- }
-}
-
-static void
-label_edit_cb (GtkWidget *widget, gpointer user_data)
-{
- EMMailerPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- g_return_if_fail (prefs != NULL);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gchar *tag = NULL;
-
- gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1);
-
- if (tag) {
- gchar *str = e_util_labels_add_with_dlg (GTK_WINDOW (gtk_widget_get_toplevel (widget)), tag);
-
- g_free (str);
- }
-
- g_free (tag);
- }
+ return store;
}
static void
@@ -724,80 +515,6 @@ emmp_header_entry_changed (GtkWidget *entry, gpointer user_data)
}
static void
-mark_seen_timeout_changed (GtkSpinButton *spin, EMMailerPrefs *prefs)
-{
- gint timeout;
-
- timeout = (gint) (gtk_spin_button_get_value (prefs->timeout) * 1000.0);
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/mark_seen_timeout", timeout, NULL);
-}
-
-static void
-address_compress_count_changed (GtkSpinButton *spin, EMMailerPrefs *prefs)
-{
- gint count;
-
- count = (gint) gtk_spin_button_get_value (prefs->address_count);
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/address_count", count, NULL);
-}
-
-static void
-mlimit_count_changed (GtkSpinButton *spin, EMMailerPrefs *prefs)
-{
- gint count;
-
- count = (gint) gtk_spin_button_get_value (prefs->mlimit_count);
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/message_text_part_limit", count, NULL);
-}
-
-static void
-spin_button_init (EMMailerPrefs *prefs, GtkSpinButton *spin, const gchar *key, gfloat div, GCallback value_changed)
-{
- GError *err = NULL;
- double min, max;
- gchar *mkey, *p;
- gint val;
-
- gtk_spin_button_get_range (spin, &min, &max);
-
- mkey = g_alloca (strlen (key) + 5);
- p = g_stpcpy (mkey, key);
- *p++ = '_';
-
- /* see if the admin locked down the min value */
- strcpy (p, "min");
- val = gconf_client_get_int (prefs->gconf, mkey, &err);
- if (err == NULL)
- g_clear_error (&err);
- else
- min = (1.0 * val) / div;
-
- /* see if the admin locked down the max value */
- strcpy (p, "max");
- val = gconf_client_get_int (prefs->gconf, mkey, &err);
- if (err == NULL)
- g_clear_error (&err);
- else
- max = (1.0 * val) / div;
-
- gtk_spin_button_set_range (spin, min, max);
-
- /* get the value */
- val = gconf_client_get_int (prefs->gconf, key, NULL);
- gtk_spin_button_set_value (spin, (1.0 * val) / div);
-
- if (value_changed) {
- g_object_set_data ((GObject *) spin, "key", (gpointer) key);
- g_signal_connect (spin, "value-changed", value_changed, prefs);
- }
-
- if (!gconf_client_key_is_writable (prefs->gconf, key, NULL))
- gtk_widget_set_sensitive ((GtkWidget *) spin, FALSE);
-}
-
-static void
toggle_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs)
{
const gchar *key;
@@ -807,16 +524,6 @@ toggle_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs)
}
static void
-photo_toggle_changed (GtkToggleButton *toggle, EMMailerPrefs *prefs)
-{
- toggle_button_toggled (toggle, prefs);
- if (gtk_toggle_button_get_active (toggle))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, TRUE);
- else
- gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, FALSE);
-}
-
-static void
junk_book_lookup_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs)
{
toggle_button_toggled (toggle, prefs);
@@ -840,30 +547,6 @@ custom_junk_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs)
}
static void
-custom_font_changed (GtkToggleButton *toggle, EMMailerPrefs *prefs)
-{
- gboolean use_custom;
-
- use_custom = !gtk_toggle_button_get_active (toggle);
-
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->font_fixed), use_custom);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->font_variable), use_custom);
-
- gconf_client_set_bool (prefs->gconf, "/apps/evolution/mail/display/fonts/use_custom", use_custom, NULL);
-}
-
-static void
-font_changed (GtkFontButton *font_button, EMMailerPrefs *prefs)
-{
- const gchar *key;
- const gchar *font_name;
-
- key = g_object_get_data (G_OBJECT (font_button), "key");
- font_name = gtk_font_button_get_font_name (font_button);
- gconf_client_set_string (prefs->gconf, key, font_name, NULL);
-}
-
-static void
toggle_button_init (EMMailerPrefs *prefs, GtkToggleButton *toggle, gint not, const gchar *key, GCallback toggled)
{
gboolean bool;
@@ -881,114 +564,91 @@ toggle_button_init (EMMailerPrefs *prefs, GtkToggleButton *toggle, gint not, con
}
static void
-charset_activate (GtkWidget *item, EMMailerPrefs *prefs)
-{
- GtkWidget *menu;
- gchar *string;
-
- menu = gtk_option_menu_get_menu (prefs->charset);
- if (!(string = e_charset_picker_get_charset (menu)))
- string = g_strdup (camel_iconv_locale_charset ());
-
- gconf_client_set_string (prefs->gconf, "/apps/evolution/mail/display/charset", string, NULL);
- g_free (string);
-}
-
-static void
-charset_menu_init (EMMailerPrefs *prefs)
+trash_days_changed (GtkComboBox *combo_box,
+ EMMailerPrefs *prefs)
{
- GtkWidget *menu, *item;
- GList *items;
- gchar *buf;
-
- buf = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/charset", NULL);
- menu = e_charset_picker_new (buf && *buf ? buf : camel_iconv_locale_charset ());
- gtk_option_menu_set_menu (prefs->charset, GTK_WIDGET (menu));
- g_free (buf);
-
- items = GTK_MENU_SHELL (menu)->children;
- while (items) {
- item = items->data;
- g_signal_connect (item, "activate", G_CALLBACK (charset_activate), prefs);
- items = items->next;
- }
+ gint index;
- if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/charset", NULL))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->charset, FALSE);
-}
+ index = gtk_combo_box_get_active (combo_box);
+ g_return_if_fail (index >= 0);
+ g_return_if_fail (index < G_N_ELEMENTS (empty_trash_frequency));
-static void
-trash_days_changed (GtkComboBox *combobox, EMMailerPrefs *prefs)
-{
- gint idx;
-
- idx = gtk_combo_box_get_active (combobox);
- g_return_if_fail (idx >= 0 && idx < G_N_ELEMENTS (empty_trash_frequency));
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/trash/empty_on_exit_days", empty_trash_frequency [idx].days, NULL);
+ gconf_client_set_int (
+ prefs->gconf,
+ "/apps/evolution/mail/trash/empty_on_exit_days",
+ empty_trash_frequency[index].days, NULL);
}
static void
-emmp_empty_trash_init (EMMailerPrefs *prefs)
+emmp_empty_trash_init (EMMailerPrefs *prefs,
+ GtkComboBox *combo_box)
{
- gint locked, days, hist = 0, i;
-
- toggle_button_init (prefs, prefs->empty_trash, FALSE,
- "/apps/evolution/mail/trash/empty_on_exit",
- G_CALLBACK (toggle_button_toggled));
+ gint days, hist = 0, ii;
+ GtkTreeModel *model;
- days = gconf_client_get_int(prefs->gconf, "/apps/evolution/mail/trash/empty_on_exit_days", NULL);
+ days = gconf_client_get_int (
+ prefs->gconf,
+ "/apps/evolution/mail/trash/empty_on_exit_days", NULL);
- gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (prefs->empty_trash_days)));
- for (i = 0; i < G_N_ELEMENTS (empty_trash_frequency); i++) {
- if (days >= empty_trash_frequency[i].days)
- hist = i;
+ model = gtk_combo_box_get_model (combo_box);
+ gtk_list_store_clear (GTK_LIST_STORE (model));
- gtk_combo_box_append_text (prefs->empty_trash_days, _(empty_trash_frequency[i].label));
+ for (ii = 0; ii < G_N_ELEMENTS (empty_trash_frequency); ii++) {
+ if (days >= empty_trash_frequency[ii].days)
+ hist = ii;
+ gtk_combo_box_append_text (
+ combo_box, gettext (empty_trash_frequency[ii].label));
}
- g_signal_connect (prefs->empty_trash_days, "changed", G_CALLBACK (trash_days_changed), prefs);
- gtk_combo_box_set_active (prefs->empty_trash_days, hist);
+ g_signal_connect (
+ combo_box, "changed",
+ G_CALLBACK (trash_days_changed), prefs);
- locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/trash/empty_on_exit_days", NULL);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->empty_trash_days, !locked);
+ gtk_combo_box_set_active (combo_box, hist);
}
static void
-junk_days_changed (GtkComboBox *combobox, EMMailerPrefs *prefs)
+junk_days_changed (GtkComboBox *combo_box,
+ EMMailerPrefs *prefs)
{
- gint idx;
+ gint index;
- idx = gtk_combo_box_get_active (combobox);
- g_return_if_fail (idx >= 0 && idx < G_N_ELEMENTS (empty_trash_frequency));
+ index = gtk_combo_box_get_active (combo_box);
+ g_return_if_fail (index >= 0);
+ g_return_if_fail (index < G_N_ELEMENTS (empty_trash_frequency));
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/junk/empty_on_exit_days", empty_trash_frequency[idx].days, NULL);
+ gconf_client_set_int (
+ prefs->gconf,
+ "/apps/evolution/mail/junk/empty_on_exit_days",
+ empty_trash_frequency[index].days, NULL);
}
static void
-emmp_empty_junk_init (EMMailerPrefs *prefs)
+emmp_empty_junk_init (EMMailerPrefs *prefs,
+ GtkComboBox *combo_box)
{
- gint locked, days, hist = 0, i;
-
- toggle_button_init (prefs, prefs->empty_junk, FALSE,
- "/apps/evolution/mail/junk/empty_on_exit",
- G_CALLBACK (toggle_button_toggled));
+ gint days, hist = 0, ii;
+ GtkTreeModel *model;
- days = gconf_client_get_int(prefs->gconf, "/apps/evolution/mail/junk/empty_on_exit_days", NULL);
+ days = gconf_client_get_int (
+ prefs->gconf,
+ "/apps/evolution/mail/junk/empty_on_exit_days", NULL);
- gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (prefs->empty_junk_days)));
- for (i = 0; i < G_N_ELEMENTS (empty_trash_frequency); i++) {
- if (days >= empty_trash_frequency[i].days)
- hist = i;
+ model = gtk_combo_box_get_model (combo_box);
+ gtk_list_store_clear (GTK_LIST_STORE (model));
- gtk_combo_box_append_text (prefs->empty_junk_days, _(empty_trash_frequency[i].label));
+ for (ii = 0; ii < G_N_ELEMENTS (empty_trash_frequency); ii++) {
+ if (days >= empty_trash_frequency[ii].days)
+ hist = ii;
+ gtk_combo_box_append_text (
+ combo_box, gettext (empty_trash_frequency[ii].label));
}
- g_signal_connect (prefs->empty_junk_days, "changed", G_CALLBACK (junk_days_changed), prefs);
- gtk_combo_box_set_active (prefs->empty_junk_days, hist);
+ g_signal_connect (
+ combo_box, "changed",
+ G_CALLBACK (junk_days_changed), prefs);
- locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/junk/empty_on_exit_days", NULL);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->empty_junk_days, !locked);
+ gtk_combo_box_set_active (combo_box, hist);
}
static void
@@ -1050,17 +710,17 @@ junk_plugin_changed (GtkWidget *combo, EMMailerPrefs *prefs)
gconf_client_set_string (prefs->gconf, "/apps/evolution/mail/junk/default_plugin", def_plugin, NULL);
while (plugins) {
- struct _EMJunkHookItem *item = plugins->data;;
+ EMJunkInterface *iface = plugins->data;
- if (item->plugin_name && def_plugin && !strcmp (item->plugin_name, def_plugin)) {
+ if (iface->plugin_name && def_plugin && !strcmp (iface->plugin_name, def_plugin)) {
gboolean status;
- session->junk_plugin = CAMEL_JUNK_PLUGIN (&(item->csp));
- status = e_plugin_invoke (item->hook->hook.plugin, item->validate_binary, NULL) != NULL;
+ session->junk_plugin = CAMEL_JUNK_PLUGIN (&iface->camel);
+ status = e_plugin_invoke (iface->hook->plugin, iface->validate_binary, NULL) != NULL;
if ((gboolean)status == TRUE) {
gchar *text, *html;
gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-info", GTK_ICON_SIZE_MENU);
- text = g_strdup_printf (_("%s plugin is available and the binary is installed."), item->plugin_name);
+ text = g_strdup_printf (_("%s plugin is available and the binary is installed."), iface->plugin_name);
html = g_strdup_printf ("<i>%s</i>", text);
gtk_label_set_markup (prefs->plugin_status, html);
g_free (html);
@@ -1068,7 +728,7 @@ junk_plugin_changed (GtkWidget *combo, EMMailerPrefs *prefs)
} else {
gchar *text, *html;
gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-warning", GTK_ICON_SIZE_MENU);
- text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), item->plugin_name);
+ text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), iface->plugin_name);
html = g_strdup_printf ("<i>%s</i>", text);
gtk_label_set_markup (prefs->plugin_status, html);
g_free (html);
@@ -1101,20 +761,20 @@ junk_plugin_setup (GtkWidget *combo, EMMailerPrefs *prefs)
}
while (plugins) {
- struct _EMJunkHookItem *item = plugins->data;;
+ EMJunkInterface *iface = plugins->data;
- gtk_combo_box_append_text (GTK_COMBO_BOX (combo), item->plugin_name);
- if (!def_set && pdefault && item->plugin_name && !strcmp(pdefault, item->plugin_name)) {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), iface->plugin_name);
+ if (!def_set && pdefault && iface->plugin_name && !strcmp(pdefault, iface->plugin_name)) {
gboolean status;
def_set = TRUE;
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), index);
- status = e_plugin_invoke (item->hook->hook.plugin, item->validate_binary, NULL) != NULL;
+ status = e_plugin_invoke (iface->hook->plugin, iface->validate_binary, NULL) != NULL;
if (status) {
gchar *text, *html;
gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-info", GTK_ICON_SIZE_MENU);
/* May be a better text */
- text = g_strdup_printf (_("%s plugin is available and the binary is installed."), item->plugin_name);
+ text = g_strdup_printf (_("%s plugin is available and the binary is installed."), iface->plugin_name);
html = g_strdup_printf ("<i>%s</i>", text);
gtk_label_set_markup (prefs->plugin_status, html);
g_free (html);
@@ -1123,7 +783,7 @@ junk_plugin_setup (GtkWidget *combo, EMMailerPrefs *prefs)
gchar *text, *html;
gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-warning", GTK_ICON_SIZE_MENU);
/* May be a better text */
- text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), item->plugin_name);
+ text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), iface->plugin_name);
html = g_strdup_printf ("<i>%s</i>", text);
gtk_label_set_markup (prefs->plugin_status, html);
g_free (html);
@@ -1144,15 +804,19 @@ create_combo_text_widget (void) {
}
static void
-em_mailer_prefs_construct (EMMailerPrefs *prefs)
+em_mailer_prefs_construct (EMMailerPrefs *prefs,
+ EShell *shell)
{
GSList *header_config_list, *header_add_list, *p;
+ EShellSettings *shell_settings;
GHashTable *default_header_hash;
- GtkWidget *toplevel, *table;
+ GtkWidget *toplevel;
+ GtkWidget *container;
+ GtkWidget *table;
+ GtkWidget *widget;
GtkTreeSelection *selection;
GtkCellRenderer *renderer;
GtkTreeIter iter;
- gchar *font, *buf;
GladeXML *gui;
gboolean locked;
gint val, i;
@@ -1161,6 +825,8 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs)
GSList *l;
gchar *gladefile;
+ shell_settings = e_shell_get_shell_settings (shell);
+
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
"mail-config.glade",
NULL);
@@ -1186,96 +852,124 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs)
/* General tab */
/* Message Display */
- prefs->timeout_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkMarkTimeout"));
- toggle_button_init (prefs, prefs->timeout_toggle, FALSE,
- "/apps/evolution/mail/display/mark_seen",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->timeout = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "spinMarkTimeout"));
- spin_button_init (prefs, prefs->timeout,
- "/apps/evolution/mail/display/mark_seen_timeout",
- 1000.0, G_CALLBACK (mark_seen_timeout_changed));
-
- prefs->mlimit_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "mlimit_checkbutton"));
- toggle_button_init (prefs, prefs->mlimit_toggle, FALSE,
- "/apps/evolution/mail/display/force_message_limit",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->magic_spacebar = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "magic_spacebar_checkbox"));
- toggle_button_init (prefs, prefs->magic_spacebar, FALSE,
- "/apps/evolution/mail/display/magic_spacebar",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->mlimit_count = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "mlimit_spin"));
- spin_button_init (prefs, prefs->mlimit_count,
- "/apps/evolution/mail/display/message_text_part_limit",
- 1, G_CALLBACK (mlimit_count_changed));
-
- prefs->address_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "address_checkbox"));
- toggle_button_init (prefs, prefs->address_toggle, FALSE,
- "/apps/evolution/mail/display/address_compress",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->address_count = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "address_spin"));
- spin_button_init (prefs, prefs->address_count,
- "/apps/evolution/mail/display/address_count",
- 1, G_CALLBACK (address_compress_count_changed));
-
- prefs->charset = GTK_OPTION_MENU (glade_xml_get_widget (gui, "omenuCharset"));
- charset_menu_init (prefs);
-
- prefs->citation_highlight = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkHighlightCitations"));
- toggle_button_init (prefs, prefs->citation_highlight, FALSE,
- "/apps/evolution/mail/display/mark_citations",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->citation_color = GTK_COLOR_BUTTON (glade_xml_get_widget (gui, "colorButtonHighlightCitations"));
- buf = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/citation_colour", NULL);
- color_button_set_color (prefs->citation_color, buf ? buf : "#737373");
- g_signal_connect (prefs->citation_color, "color-set", G_CALLBACK (citation_color_set), prefs);
- if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/citation_colour", NULL))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->citation_color, FALSE);
- g_free (buf);
-
- prefs->enable_search_folders = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkEnableSearchFolders"));
- toggle_button_init (prefs, prefs->enable_search_folders, FALSE,
- "/apps/evolution/mail/display/enable_vfolders",
- G_CALLBACK (toggle_button_toggled));
+ widget = glade_xml_get_widget (gui, "chkMarkTimeout");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-mark-seen",
+ G_OBJECT (widget), "active");
+
+ /* The "mark seen" timeout requires special transform functions
+ * because we display the timeout value to the user in seconds
+ * but store the settings value in milliseconds. */
+ widget = glade_xml_get_widget (gui, "spinMarkTimeout");
+ prefs->timeout = GTK_SPIN_BUTTON (widget);
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-mark-seen",
+ G_OBJECT (widget), "sensitive");
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "mail-mark-seen-timeout",
+ G_OBJECT (widget), "value",
+ mark_seen_timeout_transform,
+ mark_seen_timeout_reverse_transform,
+ NULL, NULL);
+
+ widget = glade_xml_get_widget (gui, "mlimit_checkbutton");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-force-message-limit",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "mlimit_spin");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-force-message-limit",
+ G_OBJECT (widget), "sensitive");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-message-text-part-limit",
+ G_OBJECT (widget), "value");
+
+ widget = glade_xml_get_widget (gui, "address_checkbox");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-address-compress",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "address_spin");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-address-compress",
+ G_OBJECT (widget), "sensitive");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-address-count",
+ G_OBJECT (widget), "value");
+
+ widget = glade_xml_get_widget (gui, "magic_spacebar_checkbox");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-magic-spacebar",
+ G_OBJECT (widget), "active");
+
+ widget = e_charset_combo_box_new ();
+ container = glade_xml_get_widget (gui, "hboxDefaultCharset");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-charset",
+ G_OBJECT (widget), "charset");
+
+ widget = glade_xml_get_widget (gui, "chkHighlightCitations");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-mark-citations",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "colorButtonHighlightCitations");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-mark-citations",
+ G_OBJECT (widget), "sensitive");
+ e_mutual_binding_new_full (
+ G_OBJECT (shell_settings), "mail-citation-color",
+ G_OBJECT (widget), "color",
+ e_binding_transform_string_to_color,
+ e_binding_transform_color_to_string,
+ NULL, NULL);
+
+ widget = glade_xml_get_widget (gui, "chkEnableSearchFolders");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-enable-search-folders",
+ G_OBJECT (widget), "active");
/* Deleting Mail */
- prefs->empty_trash = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkEmptyTrashOnExit"));
- prefs->empty_trash_days = GTK_COMBO_BOX (glade_xml_get_widget (gui, "comboboxEmptyTrashDays"));
- emmp_empty_trash_init (prefs);
-
- prefs->confirm_expunge = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkConfirmExpunge"));
- toggle_button_init (prefs, prefs->confirm_expunge, FALSE,
- "/apps/evolution/mail/prompts/expunge",
- G_CALLBACK (toggle_button_toggled));
-
- /* Mail Fonts */
- font = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/fonts/monospace", NULL);
- prefs->font_fixed = GTK_FONT_BUTTON (glade_xml_get_widget (gui, "FontFixed"));
- gtk_font_button_set_font_name (prefs->font_fixed, font);
- g_free (font);
- g_object_set_data ((GObject *) prefs->font_fixed, "key", (gpointer) "/apps/evolution/mail/display/fonts/monospace");
- g_signal_connect (prefs->font_fixed, "font-set", G_CALLBACK (font_changed), prefs);
- if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/fonts/monospace", NULL))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->font_fixed, FALSE);
-
- font = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/fonts/variable", NULL);
- prefs->font_variable = GTK_FONT_BUTTON (glade_xml_get_widget (gui, "FontVariable"));
- gtk_font_button_set_font_name (prefs->font_variable, font);
- g_free (font);
- g_object_set_data ((GObject *) prefs->font_variable, "key", (gpointer) "/apps/evolution/mail/display/fonts/variable");
- g_signal_connect (prefs->font_variable, "font-set", G_CALLBACK (font_changed), prefs);
- if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/fonts/variable", NULL))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->font_variable, FALSE);
-
- prefs->font_share = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "radFontUseSame"));
- toggle_button_init (prefs, prefs->font_share, TRUE,
- "/apps/evolution/mail/display/fonts/use_custom",
- G_CALLBACK (custom_font_changed));
- custom_font_changed (prefs->font_share, prefs);
+ widget = glade_xml_get_widget (gui, "chkEmptyTrashOnExit");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-empty-trash-on-exit",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "comboboxEmptyTrashDays");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-empty-trash-on-exit",
+ G_OBJECT (widget), "sensitive");
+ emmp_empty_trash_init (prefs, GTK_COMBO_BOX (widget));
+
+ widget = glade_xml_get_widget (gui, "chkConfirmExpunge");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-confirm-expunge",
+ G_OBJECT (widget), "active");
+
+ /* Mail Fonts */
+ widget = glade_xml_get_widget (gui, "radFontUseSame");
+ e_mutual_binding_new_with_negation (
+ G_OBJECT (shell_settings), "mail-use-custom-fonts",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "FontFixed");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-font-monospace",
+ G_OBJECT (widget), "font-name");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-use-custom-fonts",
+ G_OBJECT (widget), "sensitive");
+
+ widget = glade_xml_get_widget (gui, "FontVariable");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-font-variable",
+ G_OBJECT (widget), "font-name");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-use-custom-fonts",
+ G_OBJECT (widget), "sensitive");
/* HTML Mail tab */
@@ -1302,49 +996,40 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs)
g_signal_connect (prefs->images_sometimes, "toggled", G_CALLBACK (http_images_changed), prefs);
g_signal_connect (prefs->images_always, "toggled", G_CALLBACK (http_images_changed), prefs);
- prefs->show_animated = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkShowAnimatedImages"));
- toggle_button_init (prefs, prefs->show_animated, FALSE,
- "/apps/evolution/mail/display/animate_images",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->prompt_unwanted_html = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkPromptWantHTML"));
- toggle_button_init (prefs, prefs->prompt_unwanted_html, FALSE,
- "/apps/evolution/mail/prompts/unwanted_html",
- G_CALLBACK (toggle_button_toggled));
-
- /* Labels... */
- locked = !gconf_client_key_is_writable (prefs->gconf, E_UTIL_LABELS_GCONF_KEY, NULL);
- prefs->label_add = glade_xml_get_widget (gui, "labelAdd");
- prefs->label_edit = glade_xml_get_widget (gui, "labelEdit");
- prefs->label_remove = glade_xml_get_widget (gui, "labelRemove");
- prefs->label_tree = glade_xml_get_widget (gui, "labelTree");
+ widget = glade_xml_get_widget (gui, "chkShowAnimatedImages");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-show-animated-images",
+ G_OBJECT (widget), "active");
- gtk_widget_set_sensitive (prefs->label_add, !locked);
- gtk_widget_set_sensitive (prefs->label_remove, !locked);
- gtk_widget_set_sensitive (prefs->label_edit, !locked);
- gtk_widget_set_sensitive (prefs->label_tree, !locked);
+ widget = glade_xml_get_widget (gui, "chkPromptWantHTML");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-confirm-unwanted-html",
+ G_OBJECT (widget), "active");
- init_label_tree (prefs->label_tree, prefs, locked);
+ container = glade_xml_get_widget (gui, "labels-alignment");
+ widget = e_mail_label_manager_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
- if (!locked) {
- g_signal_connect (G_OBJECT (prefs->label_add), "clicked", G_CALLBACK (label_add_cb), prefs);
- g_signal_connect (G_OBJECT (prefs->label_remove), "clicked", G_CALLBACK (label_remove_cb), prefs);
- g_signal_connect (G_OBJECT (prefs->label_edit), "clicked", G_CALLBACK (label_edit_cb), prefs);
- }
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-label-list-store",
+ G_OBJECT (widget), "list-store");
/* headers */
locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/headers", NULL);
- prefs->photo_show= GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "photo_show"));
- toggle_button_init (prefs, prefs->photo_show, FALSE,
- "/apps/evolution/mail/display/sender_photo",
- G_CALLBACK (photo_toggle_changed));
- prefs->photo_local = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "photo_local"));
- toggle_button_init (prefs, prefs->photo_local, FALSE,
- "/apps/evolution/mail/display/photo_local",
- G_CALLBACK (toggle_button_toggled));
- if (!gtk_toggle_button_get_active (prefs->photo_show))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, FALSE);
+ widget = glade_xml_get_widget (gui, "photo_show");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-show-sender-photo",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "photo_local");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-show-sender-photo",
+ G_OBJECT (widget), "sensitive");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-only-local-photos",
+ G_OBJECT (widget), "active");
/* always de-sensitised until the user types something in the entry */
prefs->add_header = GTK_BUTTON (glade_xml_get_widget (gui, "cmdHeadersAdd"));
@@ -1456,14 +1141,21 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs)
e_datetime_format_add_setup_widget (table, 1, "mail", "table", DTFormatKindDateTime, _("Table column:"));
/* Junk prefs */
- prefs->check_incoming = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkCheckIncomingMail"));
- toggle_button_init (prefs, prefs->check_incoming, FALSE,
- "/apps/evolution/mail/junk/check_incoming",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->empty_junk = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "junk_empty_check"));
- prefs->empty_junk_days = GTK_COMBO_BOX (glade_xml_get_widget (gui, "junk_empty_combobox"));
- emmp_empty_junk_init (prefs);
+ widget = glade_xml_get_widget (gui, "chkCheckIncomingMail");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-check-for-junk",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "junk_empty_check");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-empty-junk-on-exit",
+ G_OBJECT (widget), "active");
+
+ widget = glade_xml_get_widget (gui, "junk_empty_combobox");
+ e_mutual_binding_new (
+ G_OBJECT (shell_settings), "mail-empty-junk-on-exit",
+ G_OBJECT (widget), "sensitive");
+ emmp_empty_junk_init (prefs, GTK_COMBO_BOX (widget));
prefs->default_junk_plugin = GTK_COMBO_BOX (glade_xml_get_widget (gui, "default_junk_plugin"));
prefs->plugin_status = GTK_LABEL (glade_xml_get_widget (gui, "plugin_status"));
@@ -1486,7 +1178,7 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs)
junk_book_lookup_button_toggled (prefs->junk_book_lookup, prefs);
- init_junk_tree ((GtkTreeView *)prefs->junk_header_tree, prefs);
+ prefs->junk_header_list_store = init_junk_tree ((GtkWidget *)prefs->junk_header_tree, prefs);
toggle_button_init (prefs, prefs->junk_header_check, FALSE,
"/apps/evolution/mail/junk/check_custom_header",
G_CALLBACK (custom_junk_button_toggled));
@@ -1504,14 +1196,18 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs)
}
GtkWidget *
-em_mailer_prefs_new (void)
+em_mailer_prefs_new (EShell *shell)
{
EMMailerPrefs *new;
- new = (EMMailerPrefs *) g_object_new (em_mailer_prefs_get_type (), NULL);
- em_mailer_prefs_construct (new);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ new = g_object_new (EM_TYPE_MAILER_PREFS, NULL);
+
+ /* FIXME Kill this function. */
+ em_mailer_prefs_construct (new, shell);
- return (GtkWidget *) new;
+ return GTK_WIDGET (new);
}
static struct _EMMailerPrefsHeader *
diff --git a/mail/em-mailer-prefs.h b/modules/mail/em-mailer-prefs.h
index f9f36662ff..01f823b11e 100644
--- a/mail/em-mailer-prefs.h
+++ b/modules/mail/em-mailer-prefs.h
@@ -20,19 +20,32 @@
*
*/
-#ifndef __EM_MAILER_PREFS_H__
-#define __EM_MAILER_PREFS_H__
+#ifndef EM_MAILER_PREFS_H
+#define EM_MAILER_PREFS_H
#include <gtk/gtk.h>
-#include <shell/Evolution.h>
+#include <glade/glade.h>
#include <gconf/gconf-client.h>
-#include <e-util/e-signature.h>
-
-#define EM_MAILER_PREFS_TYPE (em_mailer_prefs_get_type ())
-#define EM_MAILER_PREFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EM_MAILER_PREFS_TYPE, EMMailerPrefs))
-#define EM_MAILER_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EM_MAILER_PREFS_TYPE, EMMailerPrefsClass))
-#define EM_IS_MAILER_PREFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EM_MAILER_PREFS_TYPE))
-#define EM_IS_MAILER_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EM_MAILER_PREFS_TYPE))
+#include <shell/e-shell.h>
+
+/* Standard GObject macros */
+#define EM_TYPE_MAILER_PREFS \
+ (em_mailer_prefs_get_type ())
+#define EM_MAILER_PREFS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_MAILER_PREFS, EMMailerPrefs))
+#define EM_MAILER_PREFS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_MAILER_PREFS, EMMailerPrefsClass))
+#define EM_IS_MAILER_PREFS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_MAILER_PREFS))
+#define EM_IS_MAILER_PREFS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_MAILER_PREFS))
+#define EM_MAILER_PREFS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_MAILER_PREFS))
G_BEGIN_DECLS
@@ -49,30 +62,13 @@ struct _EMMailerPrefsHeader {
struct _EMMailerPrefs {
GtkVBox parent_object;
- GNOME_Evolution_Shell shell;
-
- struct _GladeXML *gui;
- struct _GConfClient *gconf;
+ GladeXML *gui;
+ GConfClient *gconf;
/* General tab */
/* Message Display */
- GtkToggleButton *timeout_toggle;
GtkSpinButton *timeout;
- GtkToggleButton *address_toggle;
- GtkSpinButton *address_count;
- GtkToggleButton *mlimit_toggle;
- GtkSpinButton *mlimit_count;
- GtkOptionMenu *charset;
- GtkToggleButton *citation_highlight;
- GtkColorButton *citation_color;
- GtkToggleButton *enable_search_folders;
- GtkToggleButton *magic_spacebar;
-
- /* Deleting Mail */
- GtkToggleButton *empty_trash;
- GtkComboBox *empty_trash_days;
- GtkToggleButton *confirm_expunge;
/* HTML Mail tab */
GtkFontButton *font_variable;
@@ -84,15 +80,14 @@ struct _EMMailerPrefs {
GtkToggleButton *images_sometimes;
GtkToggleButton *images_never;
- GtkToggleButton *show_animated;
GtkToggleButton *autodetect_links;
- GtkToggleButton *prompt_unwanted_html;
/* Labels and Colours tab */
GtkWidget *label_add;
GtkWidget *label_edit;
GtkWidget *label_remove;
GtkWidget *label_tree;
+ GtkListStore *label_list_store;
guint labels_change_notify_id; /* mail_config's notify id */
/* Headers tab */
@@ -101,13 +96,6 @@ struct _EMMailerPrefs {
GtkEntry *entry_header;
GtkTreeView *header_list;
GtkListStore *header_list_store;
- GtkToggleButton *photo_show;
- GtkToggleButton *photo_local;
-
- /* Junk prefs */
- GtkToggleButton *check_incoming;
- GtkToggleButton *empty_junk;
- GtkComboBox *empty_junk_days;
GtkToggleButton *sa_local_tests_only;
GtkToggleButton *sa_use_daemon;
@@ -117,6 +105,7 @@ struct _EMMailerPrefs {
GtkToggleButton *junk_header_check;
GtkTreeView *junk_header_tree;
+ GtkListStore *junk_header_list_store;
GtkButton *junk_header_add;
GtkButton *junk_header_remove;
GtkToggleButton *junk_book_lookup;
@@ -125,23 +114,18 @@ struct _EMMailerPrefs {
struct _EMMailerPrefsClass {
GtkVBoxClass parent_class;
-
- /* signals */
-
};
-GType em_mailer_prefs_get_type (void);
-GtkWidget * create_combo_text_widget (void);
-
-GtkWidget *em_mailer_prefs_new (void);
+GType em_mailer_prefs_get_type (void);
+GtkWidget * create_combo_text_widget (void);
-EMMailerPrefsHeader *em_mailer_prefs_header_from_xml(const gchar *xml);
-gchar *em_mailer_prefs_header_to_xml(EMMailerPrefsHeader *header);
-void em_mailer_prefs_header_free(EMMailerPrefsHeader *header);
+GtkWidget * em_mailer_prefs_new (EShell *shell);
-/* needed by global config */
-#define EM_MAILER_PREFS_CONTROL_ID "OAFIID:GNOME_Evolution_Mail_MailerPrefs_ConfigControl:" BASE_VERSION
+EMMailerPrefsHeader *
+ em_mailer_prefs_header_from_xml (const gchar *xml);
+gchar * em_mailer_prefs_header_to_xml (EMMailerPrefsHeader *header);
+void em_mailer_prefs_header_free (EMMailerPrefsHeader *header);
G_END_DECLS
-#endif /* __EM_MAILER_PREFS_H__ */
+#endif /* EM_MAILER_PREFS_H */
diff --git a/mail/em-network-prefs.c b/modules/mail/em-network-prefs.c
index d8b576f1f1..4c05fca77d 100644
--- a/mail/em-network-prefs.c
+++ b/modules/mail/em-network-prefs.c
@@ -32,8 +32,6 @@
#include "em-network-prefs.h"
-#include <bonobo/bonobo-generic-factory.h>
-
#include <gdk/gdkkeysyms.h>
#include <gconf/gconf-client.h>
#include <glade/glade.h>
diff --git a/mail/em-network-prefs.h b/modules/mail/em-network-prefs.h
index 0b6cd5ff63..057247b750 100644
--- a/mail/em-network-prefs.h
+++ b/modules/mail/em-network-prefs.h
@@ -20,18 +20,31 @@
*
*/
-#ifndef __EM_NETWORK_PREFS_H__
-#define __EM_NETWORK_PREFS_H__
+#ifndef EM_NETWORK_PREFS_H
+#define EM_NETWORK_PREFS_H
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gconf/gconf-client.h>
-#define EM_NETWORK_PREFS_TYPE (em_network_prefs_get_type ())
-#define EM_NETWORK_PREFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EM_NETWORK_PREFS_TYPE, EMNetworkPrefs))
-#define EM_NETWORK_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EM_NETWORK_PREFS_TYPE, EMNetworkPrefsClass))
-#define EM_IS_NETWORK_PREFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EM_NETWORK_PREFS_TYPE))
-#define EM_IS_NETWORK_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EM_NETWORK_PREFS_TYPE))
+/* Standard GObject macros */
+#define EM_TYPE_NETWORK_PREFS \
+ (em_network_prefs_get_type ())
+#define EM_NETWORK_PREFS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_NETWORK_PREFS, EMNetworkPrefs))
+#define EM_NETWORK_PREFS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_NETWORK_PREFS, EMNetworkPrefsClass))
+#define EM_IS_NETWORK_PREFS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_NETWORK_PREFS))
+#define EM_IS_NETWORK_PREFS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_NETWORK_PREFS))
+#define EM_NETWORK_PREFS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_NETWORK_PREFS, EMNetworkPrefsClass))
G_BEGIN_DECLS
@@ -56,17 +69,12 @@ struct _EMNetworkPrefs {
GtkToggleButton *sys_proxy;
GtkToggleButton *no_proxy;
GtkToggleButton *manual_proxy;
-#if 0
- GtkToggleButton *auto_proxy;
-#endif
GtkToggleButton *use_auth;
GtkEntry *http_host;
GtkEntry *https_host;
+ GtkEntry *socks_host;
GtkEntry *ignore_hosts;
-#if 0
- GtkEntry *auto_proxy_url;
-#endif
GtkEntry *auth_user;
GtkEntry *auth_pwd;
@@ -80,28 +88,15 @@ struct _EMNetworkPrefs {
GtkSpinButton *http_port;
GtkSpinButton *https_port;
-#if 0
- GtkLabel *lbl_socks_host;
- GtkEntry *socks_host;
- GtkLabel *lbl_socks_port;
- GtkSpinButton *socks_port;
-#endif
};
struct _EMNetworkPrefsClass {
GtkVBoxClass parent_class;
-
- /* signals */
-
};
-GType em_network_prefs_get_type (void);
-
-GtkWidget *em_network_prefs_new (void);
-
-/* needed by global config */
-#define EM_NETWORK_PREFS_CONTROL_ID "OAFIID:GNOME_Evolution_Mail_NetworkPrefs_ConfigControl:" BASE_VERSION
+GType em_network_prefs_get_type (void);
+GtkWidget * em_network_prefs_new (void);
G_END_DECLS
-#endif /* __EM_NETWORK_PREFS_H__ */
+#endif /* EM_NETWORK_PREFS_H */
diff --git a/modules/mail/evolution-module-mail.c b/modules/mail/evolution-module-mail.c
new file mode 100644
index 0000000000..1bb58c7742
--- /dev/null
+++ b/modules/mail/evolution-module-mail.c
@@ -0,0 +1,71 @@
+/*
+ * evolution-module-mail.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-attachment-handler.h"
+
+#include "e-mail-config-hook.h"
+#include "e-mail-event-hook.h"
+#include "e-mail-junk-hook.h"
+
+#include "e-mail-shell-backend.h"
+#include "e-mail-shell-content.h"
+#include "e-mail-shell-sidebar.h"
+#include "e-mail-shell-view.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
+
+ e_mail_attachment_handler_register_type (type_module);
+
+ e_mail_config_hook_register_type (type_module);
+ e_mail_event_hook_register_type (type_module);
+ e_mail_junk_hook_register_type (type_module);
+
+ e_mail_shell_backend_register_type (type_module);
+ e_mail_shell_content_register_type (type_module);
+ e_mail_shell_sidebar_register_type (type_module);
+ e_mail_shell_view_register_type (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init (GModule *module)
+{
+ /* FIXME Until mail is split into a module library and a
+ * reusable shared library, prevent the module from
+ * being unloaded. Unloading the module resets all
+ * static variables, which screws up foo_get_type()
+ * functions among other things. */
+ g_module_make_resident (module);
+
+ return NULL;
+}
diff --git a/modules/plugin-lib/Makefile.am b/modules/plugin-lib/Makefile.am
new file mode 100644
index 0000000000..cce60902fa
--- /dev/null
+++ b/modules/plugin-lib/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"evolution-plugin-lib\" \
+ -I$(top_srcdir) \
+ $(E_UTIL_CFLAGS)
+
+module_LTLIBRARIES = libevolution-module-plugin-lib.la
+
+libevolution_module_plugin_lib_la_SOURCES = \
+ evolution-module-plugin-lib.c \
+ e-plugin-lib.c \
+ e-plugin-lib.h
+
+libevolution_module_plugin_lib_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(E_UTIL_LIBS)
+
+libevolution_module_plugin_lib_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/plugin-lib/e-plugin-lib.c b/modules/plugin-lib/e-plugin-lib.c
new file mode 100644
index 0000000000..c7a0233bb3
--- /dev/null
+++ b/modules/plugin-lib/e-plugin-lib.c
@@ -0,0 +1,249 @@
+/*
+ * e-plugin-lib.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-plugin-lib.h"
+
+#include <string.h>
+
+static gpointer parent_class;
+static GType plugin_lib_type;
+
+/* TODO:
+ We need some way to manage lifecycle.
+ We need some way to manage state.
+
+ Maybe just the g module init method will do, or we could add
+ another which returns context.
+
+ There is also the question of per-instance context, e.g. for config
+ pages.
+*/
+
+static gint
+plugin_lib_loadmodule (EPlugin *plugin)
+{
+ EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+ EPluginLibEnableFunc enable;
+
+ if (plugin_lib->module != NULL)
+ return 0;
+
+ if (plugin_lib->location == NULL) {
+ g_warning ("Location not set in plugin '%s'", plugin->name);
+ return -1;
+ }
+
+ if ((plugin_lib->module = g_module_open (plugin_lib->location, 0)) == NULL) {
+ g_warning ("can't load plugin '%s': %s", plugin_lib->location, g_module_error ());
+ return -1;
+ }
+
+ if (g_module_symbol (plugin_lib->module, "e_plugin_lib_enable", (gpointer)&enable)) {
+ if (enable (plugin_lib, TRUE) != 0) {
+ plugin->enabled = FALSE;
+ g_module_close (plugin_lib->module);
+ plugin_lib->module = NULL;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static gpointer
+plugin_lib_invoke (EPlugin *plugin, const gchar *name, gpointer data)
+{
+ EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+ EPluginLibFunc cb;
+
+ if (!plugin->enabled) {
+ g_warning ("trying to invoke '%s' on disabled plugin '%s'", name, plugin->id);
+ return NULL;
+ }
+
+ if (plugin_lib_loadmodule (plugin) != 0)
+ return NULL;
+
+ if (!g_module_symbol (plugin_lib->module, name, (gpointer)&cb)) {
+ g_warning ("Cannot resolve symbol '%s' in plugin '%s' (not exported?)", name, plugin_lib->location);
+ return NULL;
+ }
+
+ return cb (plugin_lib, data);
+}
+
+static gpointer
+plugin_lib_get_symbol (EPlugin *plugin, const gchar *name)
+{
+ EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+ gpointer symbol;
+
+ if (plugin_lib_loadmodule (plugin) != 0)
+ return NULL;
+
+ if (!g_module_symbol (plugin_lib->module, name, &symbol))
+ return NULL;
+
+ return symbol;
+}
+
+static gint
+plugin_lib_construct (EPlugin *plugin, xmlNodePtr root)
+{
+ EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+
+ /* Set the location before chaining up, as some EPluginHooks
+ * will cause the module to load during hook construction. */
+
+ plugin_lib->location = e_plugin_xml_prop (root, "location");
+
+ if (plugin_lib->location == NULL) {
+ g_warning ("Library plugin '%s' has no location", plugin->id);
+ return -1;
+ }
+#ifdef G_OS_WIN32
+ {
+ gchar *mapped_location =
+ e_util_rplugin_libace_prefix (EVOLUTION_PREFIX,
+ e_util_get_prefix (),
+ plugin_lib->location);
+ g_free (plugin_lib->location);
+ plugin_lib->location = mapped_location;
+ }
+#endif
+
+ /* Chain up to parent's construct() method. */
+ if (E_PLUGIN_CLASS (parent_class)->construct (plugin, root) == -1)
+ return -1;
+
+ /* If we're enabled, check for the load-on-startup property */
+ if (plugin->enabled) {
+ xmlChar *tmp;
+
+ tmp = xmlGetProp (root, (const guchar *)"load-on-startup");
+ if (tmp) {
+ if (plugin_lib_loadmodule (plugin) != 0) {
+ xmlFree (tmp);
+ return -1;
+ }
+ xmlFree (tmp);
+ }
+ }
+
+ return 0;
+}
+
+static GtkWidget *
+plugin_lib_get_configure_widget (EPlugin *plugin)
+{
+ EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+ EPluginLibGetConfigureWidgetFunc get_configure_widget;
+
+ if (plugin_lib_loadmodule (plugin) != 0) {
+ return NULL;
+ }
+
+ if (g_module_symbol (plugin_lib->module, "e_plugin_lib_get_configure_widget", (gpointer)&get_configure_widget)) {
+ return (GtkWidget*) get_configure_widget (plugin_lib);
+ }
+ return NULL;
+}
+
+static void
+plugin_lib_enable (EPlugin *plugin, gint state)
+{
+ EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+ EPluginLibEnableFunc enable;
+
+ E_PLUGIN_CLASS (parent_class)->enable (plugin, state);
+
+ /* if we're disabling and it isn't loaded, nothing to do */
+ if (!state && plugin_lib->module == NULL)
+ return;
+
+ /* this will noop if we're disabling since we tested it above */
+ if (plugin_lib_loadmodule (plugin) != 0)
+ return;
+
+ if (g_module_symbol (plugin_lib->module, "e_plugin_lib_enable", (gpointer) &enable)) {
+ if (enable (plugin_lib, state) != 0)
+ return;
+ }
+}
+
+static void
+plugin_lib_finalize (GObject *object)
+{
+ EPluginLib *plugin_lib = E_PLUGIN_LIB (object);
+
+ g_free (plugin_lib->location);
+
+ if (plugin_lib->module)
+ g_module_close (plugin_lib->module);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+plugin_lib_class_init (EPluginClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = plugin_lib_finalize;
+
+ class->construct = plugin_lib_construct;
+ class->invoke = plugin_lib_invoke;
+ class->get_symbol = plugin_lib_get_symbol;
+ class->enable = plugin_lib_enable;
+ class->get_configure_widget = plugin_lib_get_configure_widget;
+ class->type = "shlib";
+}
+
+GType
+e_plugin_lib_get_type (void)
+{
+ return plugin_lib_type;
+}
+
+void
+e_plugin_lib_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EPluginLibClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) plugin_lib_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EPluginLib),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ NULL /* value_table */
+ };
+
+ plugin_lib_type = g_type_module_register_type (
+ type_module, E_TYPE_PLUGIN,
+ "EPluginLib", &type_info, 0);
+}
diff --git a/modules/plugin-lib/e-plugin-lib.h b/modules/plugin-lib/e-plugin-lib.h
new file mode 100644
index 0000000000..b485d9625e
--- /dev/null
+++ b/modules/plugin-lib/e-plugin-lib.h
@@ -0,0 +1,92 @@
+/*
+ * e-plugin-lib.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_PLUGIN_LIB_H
+#define E_PLUGIN_LIB_H
+
+#include <gmodule.h>
+#include <e-util/e-plugin.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PLUGIN_LIB \
+ (e_plugin_lib_get_type ())
+#define E_PLUGIN_LIB(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_PLUGIN_LIB, EPluginLib))
+#define E_PLUGIN_LIB_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_PLUGIN_LIB, EPluginLibClass))
+#define E_IS_PLUGIN_LIB(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_PLUGIN_LIB))
+#define E_IS_PLUGIN_LIB_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_PLUGIN_LIB))
+#define E_PLUGIN_LIB_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_PLUGIN_LIB, EPluginLibClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPluginLib EPluginLib;
+typedef struct _EPluginLibClass EPluginLibClass;
+
+/* The callback signature used for epluginlib methods */
+typedef gpointer (*EPluginLibFunc) (EPluginLib *ep, gpointer data);
+
+/* The setup method, this will be called when the plugin is
+ * initialized. In the future it may also be called when the plugin
+ * is disabled. */
+typedef gint (*EPluginLibEnableFunc) (EPluginLib *ep, gint enable);
+
+typedef gpointer (*EPluginLibGetConfigureWidgetFunc) (EPluginLib *ep);
+
+/**
+ * struct _EPluginLib -
+ *
+ * @plugin: Superclass.
+ * @location: The filename of the shared object.
+ * @module: The GModule once it is loaded.
+ *
+ * This is a concrete EPlugin class. It loads and invokes dynamically
+ * loaded libraries using GModule. The shared object isn't loaded
+ * until the first callback is invoked.
+ *
+ * When the plugin is loaded, and if it exists, "e_plugin_lib_enable"
+ * will be invoked to initialize the plugin.
+ **/
+struct _EPluginLib {
+ EPlugin parent;
+
+ gchar *location;
+ GModule *module;
+};
+
+struct _EPluginLibClass {
+ EPluginClass parent_class;
+};
+
+GType e_plugin_lib_get_type (void);
+void e_plugin_lib_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_PLUGIN_LIB_H */
diff --git a/e-util/e-corba-utils.c b/modules/plugin-lib/evolution-module-plugin-lib.c
index 338b88efee..833ca5906d 100644
--- a/e-util/e-corba-utils.c
+++ b/modules/plugin-lib/evolution-module-plugin-lib.c
@@ -1,4 +1,6 @@
/*
+ * evolution-module-plugin-lib.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,31 +15,27 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
-#include "e-corba-utils.h"
+#include "e-plugin-lib.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
-
-const CORBA_char *
-e_safe_corba_string (const gchar *s)
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
{
- if (s == NULL)
- return (CORBA_char *) "";
+ /* Register dynamically loaded types. */
- return s;
+ e_plugin_lib_register_type (type_module);
}
-CORBA_char *
-e_safe_corba_string_dup (const gchar *s)
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
{
- return CORBA_string_dup (e_safe_corba_string (s));
}
diff --git a/plugins/mono/Camel.cs b/modules/plugin-mono/Camel.cs
index 4ad80e7012..4ad80e7012 100644
--- a/plugins/mono/Camel.cs
+++ b/modules/plugin-mono/Camel.cs
diff --git a/plugins/mono/Evolution.cs b/modules/plugin-mono/Evolution.cs
index 0db54405b3..0db54405b3 100644
--- a/plugins/mono/Evolution.cs
+++ b/modules/plugin-mono/Evolution.cs
diff --git a/modules/plugin-mono/Makefile.am b/modules/plugin-mono/Makefile.am
new file mode 100644
index 0000000000..f4f436ae66
--- /dev/null
+++ b/modules/plugin-mono/Makefile.am
@@ -0,0 +1,22 @@
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"evolution-plugin-mono\" \
+ -I$(top_srcdir) \
+ $(E_UTIL_CFLAGS) \
+ $(MONO_CFLAGS)
+
+module_LTLIBRARIES = libevolution-module-plugin-mono.la
+
+libevolution_module_plugin_mono_la_SOURCES = \
+ evolution-module-plugin-mono.c \
+ e-plugin-mono.c \
+ e-plugin-mono.h
+
+libevolution_module_plugin_mono_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(E_UTIL_LIBS) \
+ $(MONO_LIBS)
+
+libevolution_module_plugin_mono_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/plugin-mono/e-plugin-mono.c b/modules/plugin-mono/e-plugin-mono.c
new file mode 100644
index 0000000000..1c43fb9d56
--- /dev/null
+++ b/modules/plugin-mono/e-plugin-mono.c
@@ -0,0 +1,261 @@
+/*
+ * e-plugin-mono.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-plugin-mono.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+#include "e-plugin-mono.h"
+
+#include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/object.h>
+#include <mono/metadata/appdomain.h>
+#include <mono/metadata/assembly.h>
+#include <mono/metadata/threads.h>
+#include <mono/metadata/mono-config.h>
+#include <mono/jit/jit.h>
+
+#define E_PLUGIN_MONO_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_PLUGIN_MONO, EPluginMonoPrivate))
+
+struct _EPluginMonoPrivate {
+ MonoAssembly *assembly;
+ MonoClass *class;
+ MonoObject *plugin;
+ GHashTable *methods;
+};
+
+static MonoDomain *domain;
+static gpointer parent_class;
+static GType plugin_mono_type;
+
+static gchar *
+get_xml_prop (xmlNodePtr node, const gchar *id)
+{
+ xmlChar *prop;
+ gchar *out = NULL;
+
+ prop = xmlGetProp (node, (xmlChar *) id);
+
+ if (prop != NULL) {
+ out = g_strdup ((gchar *) prop);
+ xmlFree (prop);
+ }
+
+ return out;
+}
+
+static void
+plugin_mono_finalize (GObject *object)
+{
+ EPluginMono *plugin_mono;
+
+ plugin_mono = E_PLUGIN_MONO (object);
+
+ g_free (plugin_mono->location);
+ g_free (plugin_mono->handler);
+
+ g_hash_table_destroy (plugin_mono->priv->methods);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gint
+plugin_mono_construct (EPlugin *plugin, xmlNodePtr root)
+{
+ EPluginMono *plugin_mono;
+
+ /* Chain up to parent's construct() method. */
+ if (E_PLUGIN_CLASS (parent_class)->construct (plugin, root) == -1)
+ return -1;
+
+ plugin_mono = E_PLUGIN_MONO (plugin);
+ plugin_mono->location = get_xml_prop (root, "location");
+ plugin_mono->handler = get_xml_prop (root, "handler");
+
+ return (plugin_mono->location != NULL) ? 0 : -1;
+}
+
+/*
+ Two approaches:
+ You can have a Evolution.Plugin implementation which has every
+ callback as methods on it. Or you can just use static methods
+ for everything.
+
+ All methods take a single (structured) argument.
+*/
+
+static gpointer
+plugin_mono_invoke (EPlugin *plugin,
+ const gchar *name,
+ gpointer data)
+{
+ EPluginMono *plugin_mono;
+ EPluginMonoPrivate *priv;
+ MonoMethodDesc *d;
+ MonoMethod *m;
+ MonoObject *x = NULL, *res;
+ gpointer *params;
+
+ plugin_mono = E_PLUGIN_MONO (plugin);
+ priv = plugin_mono->priv;
+
+ /* we need to do this every time since we may be called from any thread for some uses */
+ mono_thread_attach (domain);
+
+ if (priv->assembly == NULL) {
+ priv->assembly = mono_domain_assembly_open (
+ domain, plugin_mono->location);
+ if (priv->assembly == NULL) {
+ g_warning (
+ "Can't load assembly '%s'",
+ plugin_mono->location);
+ return NULL;
+ }
+
+ if (plugin_mono->handler == NULL
+ || (priv->class = mono_class_from_name (mono_assembly_get_image (priv->assembly), "", plugin_mono->handler)) == NULL) {
+ } else {
+ priv->plugin = mono_object_new (domain, priv->class);
+ /* could conceivably init with some context too */
+ mono_runtime_object_init (priv->plugin);
+ }
+ }
+
+ m = g_hash_table_lookup (priv->methods, name);
+ if (m == NULL) {
+ if (priv->class) {
+ /* class method */
+ MonoMethod* mono_method;
+ gpointer iter = NULL;
+
+ d = mono_method_desc_new (name, FALSE);
+ /*if (d == NULL) {
+ g_warning ("Can't create method descriptor for '%s'", name);
+ return NULL;
+ }*/
+
+ while ((mono_method = mono_class_get_methods (priv->class, &iter))) {
+ g_print ("\n\a Method name is : <%s>\n\a", mono_method_get_name (mono_method));
+ }
+//mono_class_get_method_from_name
+ m = mono_class_get_method_from_name (priv->class, name, -1);
+ if (m == NULL) {
+ g_warning ("Can't find method callback '%s'", name);
+ return NULL;
+ }
+ } else {
+ /* static method */
+ d = mono_method_desc_new (name, FALSE);
+ if (d == NULL) {
+ g_warning ("Can't create method descriptor for '%s'", name);
+ return NULL;
+ }
+
+ m = mono_method_desc_search_in_image (d, mono_assembly_get_image (priv->assembly));
+ if (m == NULL) {
+ g_warning ("Can't find method callback '%s'", name);
+ return NULL;
+ }
+ }
+
+ g_hash_table_insert (priv->methods, g_strdup (name), m);
+ }
+
+ params = g_malloc0(sizeof (*params)*1);
+ params[0] = &data;
+ res = mono_runtime_invoke (m, priv->plugin, params, &x);
+ /* do i need to free params?? */
+
+ if (x)
+ mono_print_unhandled_exception (x);
+
+ if (res) {
+ gpointer *p = mono_object_unbox (res);
+ return *p;
+ } else
+ return NULL;
+}
+
+static void
+plugin_mono_class_init (EPluginMonoClass *class)
+{
+ GObjectClass *object_class;
+ EPluginClass *plugin_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EPluginMonoPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = plugin_mono_finalize;
+
+ plugin_class = E_PLUGIN_CLASS (class);
+ plugin_class->construct = plugin_mono_construct;
+ plugin_class->invoke = plugin_mono_invoke;
+ plugin_class->type = "mono";
+}
+
+static void
+plugin_mono_init (EPluginMono *plugin_mono)
+{
+ GHashTable *methods;
+
+ methods = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+
+ plugin_mono->priv = E_PLUGIN_MONO_GET_PRIVATE (plugin_mono);
+ plugin_mono->priv->methods = methods;
+}
+
+GType
+e_plugin_mono_get_type (void)
+{
+ return plugin_mono_type;
+}
+
+void
+e_plugin_mono_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EPluginMonoClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) plugin_mono_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EPluginMono),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) plugin_mono_init,
+ NULL /* value_table */
+ };
+
+ plugin_mono_type = g_type_module_register_type (
+ type_module, E_TYPE_PLUGIN,
+ "EPluginMono", &type_info, 0);
+
+ domain = mono_jit_init ("Evolution");
+ mono_thread_attach (domain);
+}
diff --git a/modules/plugin-mono/e-plugin-mono.h b/modules/plugin-mono/e-plugin-mono.h
new file mode 100644
index 0000000000..a4ed2d42ec
--- /dev/null
+++ b/modules/plugin-mono/e-plugin-mono.h
@@ -0,0 +1,69 @@
+/*
+ * e-plugin-mono.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_PLUGIN_MONO_H
+#define E_PLUGIN_MONO_H
+
+#include <e-util/e-plugin.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PLUGIN_MONO \
+ (e_plugin_mono_get_type ())
+#define E_PLUGIN_MONO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_PLUGIN_MONO, EPluginMono))
+#define E_PLUGIN_MONO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_PLUGIN_MONO, EPluginMonoClass))
+#define E_IS_PLUGIN_MONO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_PLUGIN_MONO))
+#define E_IS_PLUGIN_MONO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_PLUGIN_MONO))
+#define E_PLUGIN_MONO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_PLUGIN_MONO, EPluginMonoClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPluginMono EPluginMono;
+typedef struct _EPluginMonoClass EPluginMonoClass;
+typedef struct _EPluginMonoPrivate EPluginMonoPrivate;
+
+struct _EPluginMono {
+ EPlugin parent;
+ EPluginMonoPrivate *priv;
+
+ gchar *location;
+ gchar *handler;
+};
+
+struct _EPluginMonoClass {
+ EPluginClass parent_class;
+};
+
+GType e_plugin_mono_get_type (void);
+void e_plugin_mono_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_PLUGIN_MONO_H */
diff --git a/widgets/misc/e-config-page.c b/modules/plugin-mono/evolution-module-plugin-mono.c
index 922a26960c..75ad534a47 100644
--- a/widgets/misc/e-config-page.c
+++ b/modules/plugin-mono/evolution-module-plugin-mono.c
@@ -1,4 +1,6 @@
/*
+ * evolution-module-plugin-mono.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,36 +15,27 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
-
-#include "e-config-page.h"
-G_DEFINE_TYPE (EConfigPage, e_config_page, GTK_TYPE_EVENT_BOX)
+#include "e-plugin-mono.h"
-/* GObject methods. */
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
-static void
-e_config_page_class_init (EConfigPageClass *class)
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
{
-}
+ /* Register dynamically loaded types. */
-static void
-e_config_page_init (EConfigPage *page)
-{
+ e_plugin_mono_register_type (type_module);
}
-GtkWidget *
-e_config_page_new (void)
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
{
- return g_object_new (e_config_page_get_type (), NULL);
}
-
diff --git a/modules/plugin-python/Makefile.am b/modules/plugin-python/Makefile.am
new file mode 100644
index 0000000000..e6a32c3c83
--- /dev/null
+++ b/modules/plugin-python/Makefile.am
@@ -0,0 +1,31 @@
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"evolution-plugin-python\" \
+ -I$(top_srcdir) \
+ $(E_UTIL_CFLAGS) \
+ $(PY_INCLUDES)
+
+module_LTLIBRARIES = libevolution-module-plugin-python.la
+
+libevolution_module_plugin_python_la_SOURCES = \
+ evolution-module-plugin-python.c \
+ e-plugin-python.c \
+ e-plugin-python.h
+
+libevolution_module_plugin_python_la_LIBADD = \
+ -lpthread -ldl -lutil -lm \
+ $(top_builddir)/e-util/libeutil.la \
+ $(E_UTIL_LIBS) \
+ $(PY_LIBS)
+
+libevolution_module_plugin_python_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED)
+
+example_sources = \
+ example/hello_python.py \
+ example/org-gnome-hello-python-ui.xml \
+ example/org-gnome-hello-python.eplug.xml \
+ example/Makefile.am
+
+EXTRA_DIST = $(example_sources)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/plugin-python/e-plugin-python.c b/modules/plugin-python/e-plugin-python.c
new file mode 100644
index 0000000000..747ba57bac
--- /dev/null
+++ b/modules/plugin-python/e-plugin-python.c
@@ -0,0 +1,230 @@
+/*
+ * e-plugin-python.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* Include <Python.h> first to avoid:
+ * warning: "_POSIX_C_SOURCE" redefined */
+#include <Python.h>
+
+#include "e-plugin-python.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+#define E_PLUGIN_PYTHON_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_PLUGIN_PYTHON, EPluginPythonPrivate))
+
+struct _EPluginPythonPrivate {
+ PyObject *pModule;
+ PyObject *pClass;
+ PyObject *pFunc;
+ PyObject *pDict;
+ GHashTable *methods;
+};
+
+static gpointer parent_class;
+static GType plugin_python_type;
+
+static gchar *
+get_xml_prop (xmlNodePtr node, const gchar *id)
+{
+ xmlChar *prop;
+ gchar *out = NULL;
+
+ prop = xmlGetProp (node, (xmlChar *) id);
+
+ if (prop != NULL) {
+ out = g_strdup ((gchar *) prop);
+ xmlFree (prop);
+ }
+
+ return out;
+}
+
+static void
+plugin_python_finalize (GObject *object)
+{
+ EPluginPython *plugin_python;
+
+ plugin_python = E_PLUGIN_PYTHON (object);
+
+ g_free (plugin_python->location);
+ g_free (plugin_python->module_name);
+ g_free (plugin_python->pClass);
+
+ g_hash_table_destroy (plugin_python->priv->methods);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gint
+plugin_python_construct (EPlugin *plugin, xmlNodePtr root)
+{
+ EPluginPython *plugin_python;
+
+ /* Chain up to parent's construct() method. */
+ if (E_PLUGIN_CLASS (parent_class)->construct (plugin, root) == -1)
+ return -1;
+
+ plugin_python = E_PLUGIN_PYTHON (plugin);
+ plugin_python->location = get_xml_prop (root, "location");
+ plugin_python->module_name = get_xml_prop (root, "module_name");
+ plugin_python->pClass = get_xml_prop (root, "pClass");
+
+ return (plugin_python->location != NULL) ? 0 : -1;
+}
+
+static gpointer
+plugin_python_invoke (EPlugin *plugin,
+ const gchar *name,
+ gpointer data)
+{
+ EPluginPython *plugin_python;
+ EPluginPythonPrivate *priv;
+ PyObject *pModuleName, *pFunc;
+ PyObject *pInstance, *pValue = NULL;
+
+ plugin_python = E_PLUGIN_PYTHON (plugin);
+ priv = plugin_python->priv;
+
+ /* We need to do this every time since we may be called
+ * from any thread for some uses. */
+ Py_Initialize ();
+
+ if (priv->pModule == NULL) {
+ gchar *string;
+
+ pModuleName = PyString_FromString (plugin_python->module_name);
+
+ string = g_strdup_printf (
+ "import sys; "
+ "sys.path.insert(0, '%s')",
+ plugin_python->location);
+ PyRun_SimpleString (string);
+ g_free (string);
+
+ priv->pModule = PyImport_Import (pModuleName);
+
+ Py_DECREF (pModuleName); //Free
+
+ if (priv->pModule == NULL) {
+ PyErr_Print ();
+ g_warning (
+ "Can't load python module '%s'",
+ plugin_python->location);
+ return NULL;
+ }
+
+ priv->pDict = PyModule_GetDict (priv->pModule);
+
+ if (plugin_python->pClass != NULL) {
+ priv->pClass = PyDict_GetItemString (
+ priv->pDict, plugin_python->pClass);
+ }
+ }
+
+ if (priv->pClass) {
+
+ if (PyCallable_Check (priv->pClass))
+ pInstance = PyObject_CallObject (priv->pClass, NULL);
+
+ pValue = PyObject_CallMethod (pInstance, (gchar *) name, NULL);
+
+ } else {
+
+ pFunc = PyDict_GetItemString (priv->pDict, name);
+
+ if (pFunc && PyCallable_Check (pFunc))
+ pValue = PyObject_CallObject (pFunc, NULL);
+ else
+ PyErr_Print ();
+ }
+
+ if (pValue) {
+ Py_DECREF(pValue);
+ /* Fixme */
+ return NULL;
+ } else
+ return NULL;
+}
+
+static void
+plugin_python_class_init (EPluginPythonClass *class)
+{
+ GObjectClass *object_class;
+ EPluginClass *plugin_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EPluginPythonPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = plugin_python_finalize;
+
+ plugin_class = E_PLUGIN_CLASS (class);
+ plugin_class->construct = plugin_python_construct;
+ plugin_class->invoke = plugin_python_invoke;
+ plugin_class->type = "python";
+}
+
+static void
+plugin_python_init (EPluginPython *plugin_python)
+{
+ GHashTable *methods;
+
+ methods = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+
+ plugin_python->priv = E_PLUGIN_PYTHON_GET_PRIVATE (plugin_python);
+ plugin_python->priv->methods = methods;
+}
+
+GType
+e_plugin_python_get_type (void)
+{
+ return plugin_python_type;
+}
+
+void
+e_plugin_python_register_type (GTypeModule *type_module)
+{
+ static const GTypeInfo type_info = {
+ sizeof (EPluginPythonClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) plugin_python_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EPluginPython),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) plugin_python_init,
+ NULL /* value_table */
+ };
+
+ plugin_python_type = g_type_module_register_type (
+ type_module, E_TYPE_PLUGIN,
+ "EPluginPython", &type_info, 0);
+
+ /* TODO Does this mean I can cache the instance of pyobjects? */
+ Py_Initialize ();
+}
diff --git a/modules/plugin-python/e-plugin-python.h b/modules/plugin-python/e-plugin-python.h
new file mode 100644
index 0000000000..9ee780c76c
--- /dev/null
+++ b/modules/plugin-python/e-plugin-python.h
@@ -0,0 +1,70 @@
+/*
+ * e-plugin-python.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_PLUGIN_PYTHON_H
+#define E_PLUGIN_PYTHON_H
+
+#include <e-util/e-plugin.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PLUGIN_PYTHON \
+ (e_plugin_python_get_type ())
+#define E_PLUGIN_PYTHON(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_PLUGIN_PYTHON, EPluginPython))
+#define E_PLUGIN_PYTHON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_PLUGIN_PYTHON, EPluginPythonClass))
+#define E_IS_PLUGIN_PYTHON(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_PLUGIN_PYTHON))
+#define E_IS_PLUGIN_PYTHON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_PLUGIN_PYTHON))
+#define E_PLUGIN_PYTHON_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_PLUGIN_PYTHON, EPluginPythonClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPluginPython EPluginPython;
+typedef struct _EPluginPythonClass EPluginPythonClass;
+typedef struct _EPluginPythonPrivate EPluginPythonPrivate;
+
+struct _EPluginPython {
+ EPlugin parent;
+ EPluginPythonPrivate *priv;
+
+ gchar *location;
+ gchar *pClass;
+ gchar *module_name;
+};
+
+struct _EPluginPythonClass {
+ EPluginClass parent_class;
+};
+
+GType e_plugin_python_get_type (void);
+void e_plugin_python_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_PLUGIN_PYTHON_H */
diff --git a/modules/plugin-python/evolution-module-plugin-python.c b/modules/plugin-python/evolution-module-plugin-python.c
new file mode 100644
index 0000000000..84ab3b3e8c
--- /dev/null
+++ b/modules/plugin-python/evolution-module-plugin-python.c
@@ -0,0 +1,41 @@
+/*
+ * evolution-module-plugin-python.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include "e-plugin-python.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
+
+ e_plugin_python_register_type (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/plugins/python/example/Makefile.am b/modules/plugin-python/example/Makefile.am
index 8e5ddd49fd..cc14dc94d9 100644
--- a/plugins/python/example/Makefile.am
+++ b/modules/plugin-python/example/Makefile.am
@@ -9,9 +9,6 @@ plugin_DATA = \
org-gnome-hello-python-ui.xml \
org-gnome-hello-python.eplug
-liborg_gnome_py_plug_test_la_LIBADD= \
- $(NO_UNDEFINED_REQUIRED_LIBS)
-
liborg_gnome_py_plug_test_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
errordir = $(privdatadir)/errors
diff --git a/plugins/python/example/hello_python.py b/modules/plugin-python/example/hello_python.py
index 16dc2a12f8..16dc2a12f8 100644
--- a/plugins/python/example/hello_python.py
+++ b/modules/plugin-python/example/hello_python.py
diff --git a/plugins/python/example/org-gnome-hello-python-ui.xml b/modules/plugin-python/example/org-gnome-hello-python-ui.xml
index 074960e84d..074960e84d 100644
--- a/plugins/python/example/org-gnome-hello-python-ui.xml
+++ b/modules/plugin-python/example/org-gnome-hello-python-ui.xml
diff --git a/plugins/python/example/org-gnome-hello-python.eplug.xml b/modules/plugin-python/example/org-gnome-hello-python.eplug.xml
index 8f77d5ba01..8f77d5ba01 100644
--- a/plugins/python/example/org-gnome-hello-python.eplug.xml
+++ b/modules/plugin-python/example/org-gnome-hello-python.eplug.xml
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 88edda37f0..c20e1dde91 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1,4 +1,4 @@
SUBDIRS = $(plugins_enabled)
-DIST_SUBDIRS = $(all_plugins_base) $(all_plugins_standard) $(all_plugins_experimental) profiler python
+DIST_SUBDIRS = $(all_plugins_base) $(all_plugins_standard) $(all_plugins_experimental) profiler
-include $(top_srcdir)/git.mk
diff --git a/plugins/attachment-reminder/Makefile.am b/plugins/attachment-reminder/Makefile.am
index 6d207ef839..8fb3c30ad2 100644
--- a/plugins/attachment-reminder/Makefile.am
+++ b/plugins/attachment-reminder/Makefile.am
@@ -22,9 +22,13 @@ plugin_LTLIBRARIES = liborg-gnome-evolution-attachment-reminder.la
liborg_gnome_evolution_attachment_reminder_la_SOURCES = attachment-reminder.c
liborg_gnome_evolution_attachment_reminder_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_evolution_attachment_reminder_la_LIBADD = \
+ $(top_builddir)/composer/libcomposer.la \
+ $(top_builddir)/shell/libeshell.la \
+ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
$(top_builddir)/e-util/libeutil.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/mail/libevolution-mail.la \
$(EVOLUTION_MAIL_LIBS)
schemadir = $(GCONF_SCHEMA_FILE_DIR)
diff --git a/plugins/attachment-reminder/attachment-reminder.c b/plugins/attachment-reminder/attachment-reminder.c
index 87acc1662d..330fd5df8f 100644
--- a/plugins/attachment-reminder/attachment-reminder.c
+++ b/plugins/attachment-reminder/attachment-reminder.c
@@ -67,7 +67,7 @@ enum {
CLUE_N_COLUMNS
};
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl);
void org_gnome_evolution_attachment_reminder (EPlugin *ep, EMEventTargetComposer *t);
@@ -85,7 +85,7 @@ static gboolean clue_foreach_check_isempty (GtkTreeModel *model, GtkTreePath
*path, GtkTreeIter *iter, UIData *ui);
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
return 0;
}
diff --git a/plugins/audio-inline/Makefile.am b/plugins/audio-inline/Makefile.am
index b9ee89f93b..785d53557a 100644
--- a/plugins/audio-inline/Makefile.am
+++ b/plugins/audio-inline/Makefile.am
@@ -17,10 +17,10 @@ plugin_LTLIBRARIES = liborg-gnome-audio-inline.la
liborg_gnome_audio_inline_la_SOURCES = audio-inline.c
liborg_gnome_audio_inline_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_audio_inline_la_LIBADD = \
- $(GSTREAMER_LIBS) \
- $(EVOLUTION_MAIL_LIBS) \
- $(NO_UNDEFINED_REQUIRED_LIBS)
+liborg_gnome_audio_inline_la_LIBADD = \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(GSTREAMER_LIBS) \
+ $(EVOLUTION_MAIL_LIBS)
EXTRA_DIST = org-gnome-audio-inline.eplug.xml
diff --git a/plugins/audio-inline/org-gnome-audio-inline.eplug.xml b/plugins/audio-inline/org-gnome-audio-inline.eplug.xml
index 14ad280740..1e853df10b 100644
--- a/plugins/audio-inline/org-gnome-audio-inline.eplug.xml
+++ b/plugins/audio-inline/org-gnome-audio-inline.eplug.xml
@@ -4,33 +4,94 @@
type="shlib"
id="org.gnome.evolution.plugin.audioInline"
location="@PLUGINDIR@/liborg-gnome-audio-inline@SOEXT@"
- _name="Audio Inline">
+ _name="Inline Audio">
- <_description>Play audio attachments directly from Evolution.</_description>
<author name="Radek Doulík" email="rodo@novell.com"/>
+ <_description>
+ Play audio attachments directly in mail messages.
+ </_description>
<hook class="org.gnome.evolution.mail.format:1.0">
<group id="EMFormatHTMLDisplay">
- <item mime_type="audio/ac3" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-ac3" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/basic" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/mpeg" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-mpeg" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/mpeg3" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-mpeg3" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/mp3" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-mp3" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/mp4" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/flac" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-flac" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/mod" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-mod" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-wav" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/microsoft-wav" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-wma" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="audio/x-ms-wma" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="application/ogg" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
- <item mime_type="application/x-ogg" format="org_gnome_audio_inline_format" flags="inline_disposition"/>
+ <item
+ mime_type="audio/ac3"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-ac3"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/basic"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/mpeg"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-mpeg"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/mpeg3"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-mpeg3"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/mp3"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-mp3"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/mp4"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/flac"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-flac"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/mod"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-mod"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-wav"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/microsoft-wav"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-wma"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="audio/x-ms-wma"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item
+ mime_type="application/ogg"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
+ <item mime_type="application/x-ogg"
+ format="org_gnome_audio_inline_format"
+ flags="inline_disposition"/>
</group>
</hook>
diff --git a/plugins/backup-restore/Makefile.am b/plugins/backup-restore/Makefile.am
index c1792abb64..b848d3c51b 100644
--- a/plugins/backup-restore/Makefile.am
+++ b/plugins/backup-restore/Makefile.am
@@ -1,11 +1,12 @@
AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
-DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
-DEVOLUTION_TOOLSDIR=\""$(privlibexecdir)"\" \
-DPREFIX=\""$(prefix)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DDATADIR=\""$(datadir)"\" \
-DLIBDIR=\""$(libdir)"\" \
- -I$(top_srcdir) \
$(EVOLUTION_CALENDAR_CFLAGS) \
$(SHELL_CFLAGS) \
$(E_UTIL_CFLAGS)
@@ -15,17 +16,20 @@ AM_CPPFLAGS = \
error_DATA = org-gnome-backup-restore.error
errordir = $(privdatadir)/errors
-plugin_DATA = org-gnome-backup-restore.eplug org-gnome-backup-restore.xml
+plugin_DATA = org-gnome-backup-restore.eplug
plugin_LTLIBRARIES = liborg-gnome-backup-restore.la
liborg_gnome_backup_restore_la_SOURCES = backup-restore.c
liborg_gnome_backup_restore_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_backup_restore_la_LIBADD = \
- $(top_builddir)/e-util/libeutil.la
+liborg_gnome_backup_restore_la_LIBADD = \
+ $(SHELL_LIBS) \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/shell/libeshell.la
privlibexec_PROGRAMS = evolution-backup
evolution_backup_SOURCES = backup.c
-evolution_backup_LDADD = $(SHELL_LIBS) \
+evolution_backup_LDADD = \
+ $(SHELL_LIBS) \
$(top_builddir)/e-util/libeutil.la
if OS_WIN32
@@ -35,8 +39,7 @@ endif
EXTRA_DIST = \
org-gnome-backup-restore.eplug.xml \
- org-gnome-backup-restore.error.xml \
- org-gnome-backup-restore.xml
+ org-gnome-backup-restore.error.xml
BUILT_SOURCES = org-gnome-backup-restore.eplug \
org-gnome-backup-restore.error
diff --git a/plugins/backup-restore/backup-restore.c b/plugins/backup-restore/backup-restore.c
index 79221d4573..6df2763698 100644
--- a/plugins/backup-restore/backup-restore.c
+++ b/plugins/backup-restore/backup-restore.c
@@ -31,17 +31,16 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
-#include <libgnomeui/gnome-druid.h>
-#include <libgnomeui/gnome-druid-page-standard.h>
-#include "shell/es-menu.h"
#include "mail/em-config.h"
#include "mail/em-account-editor.h"
#include "e-util/e-error.h"
#include "e-util/e-util.h"
#include "e-util/e-dialog-utils.h"
+#include "shell/e-shell-window.h"
+
+gboolean e_plugin_ui_init (GtkUIManager *ui_manager,
+ EShellWindow *shell_window);
-void org_gnome_backup_restore_backup (EPlugin *ep, ESMenuTargetShell *target);
-void org_gnome_backup_restore_restore (EPlugin *ep, ESMenuTargetShell *target);
GtkWidget * backup_restore_page (EPlugin *ep, EConfigHookItemFactoryData *hook_data);
void backup_restore_commit (EPlugin *ep, EMConfigTargetAccount *target);
void backup_restore_abort (EPlugin *ep, EMConfigTargetAccount *target);
@@ -104,7 +103,7 @@ dialog_prompt_user(GtkWindow *parent, const gchar *string, const gchar *tag, con
/* We should hardcode this to true */
gtk_toggle_button_set_active ((GtkToggleButton *)check, TRUE);
gtk_container_set_border_width((GtkContainer *)check, 12);
- gtk_box_pack_start ((GtkBox *)((GtkDialog *) mbox)->vbox, check, TRUE, TRUE, 0);
+ gtk_box_pack_start ((GtkBox *)gtk_dialog_get_content_area ((GtkDialog *) mbox), check, TRUE, TRUE, 0);
gtk_widget_show (check);
button = gtk_dialog_run ((GtkDialog *) mbox);
@@ -129,19 +128,20 @@ epbr_perform_pre_backup_checks (gchar * dir)
#endif
}
-void
-org_gnome_backup_restore_backup (EPlugin *ep, ESMenuTargetShell *target)
+static void
+action_settings_backup_cb (GtkAction *action,
+ EShellWindow *shell_window)
{
GtkWidget *dlg;
GtkWidget *vbox;
+ GtkWindow *parent;
gint response;
- dlg = e_file_get_save_filesel(target->target.widget, _("Select name of the Evolution backup file"), NULL, GTK_FILE_CHOOSER_ACTION_SAVE);
+ parent = GTK_WINDOW (shell_window);
-/* dlg = gtk_file_chooser_dialog_new (_("Select name of the Evolution backup file"), GTK_WINDOW (target->target.widget), */
-/* GTK_FILE_CHOOSER_ACTION_SAVE, */
-/* GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, */
-/* GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); */
+ dlg = e_file_get_save_filesel (
+ parent, _("Select name of the Evolution backup file"),
+ NULL, GTK_FILE_CHOOSER_ACTION_SAVE);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dlg), "evolution-backup.tar.gz");
@@ -164,7 +164,9 @@ org_gnome_backup_restore_backup (EPlugin *ep, ESMenuTargetShell *target)
if (epbr_perform_pre_backup_checks (dir)) {
- mask = dialog_prompt_user (GTK_WINDOW (target->target.widget), _("_Restart Evolution after backup"), "org.gnome.backup-restore:backup-confirm", NULL);
+ mask = dialog_prompt_user (
+ parent, _("_Restart Evolution after backup"),
+ "org.gnome.backup-restore:backup-confirm", NULL);
if (mask & BR_OK)
backup (filename, (mask & BR_START) ? TRUE: FALSE);
} else {
@@ -180,19 +182,21 @@ org_gnome_backup_restore_backup (EPlugin *ep, ESMenuTargetShell *target)
gtk_widget_destroy (dlg);
}
-void
-org_gnome_backup_restore_restore (EPlugin *ep, ESMenuTargetShell *target)
+static void
+action_settings_restore_cb (GtkAction *action,
+ EShellWindow *shell_window)
{
GtkWidget *dlg;
GtkWidget *vbox;
+ GtkWindow *parent;
gint response;
- dlg = e_file_get_save_filesel(target->target.widget, _("Select name of the Evolution backup file to restore"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN);
+ parent = GTK_WINDOW (shell_window);
-/* dlg = gtk_file_chooser_dialog_new (_("Select Evolution backup file to restore"), GTK_WINDOW (target->target.widget), */
-/* GTK_FILE_CHOOSER_ACTION_OPEN, */
-/* GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, */
-/* GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); */
+ dlg = e_file_get_save_filesel (
+ parent,
+ _("Select name of the Evolution backup file to restore"),
+ NULL, GTK_FILE_CHOOSER_ACTION_OPEN);
vbox = gtk_vbox_new (FALSE, 6);
gtk_widget_show (vbox);
@@ -211,11 +215,13 @@ org_gnome_backup_restore_restore (EPlugin *ep, ESMenuTargetShell *target)
if (sanity_check (filename)) {
guint32 mask;
- mask = dialog_prompt_user (GTK_WINDOW (target->target.widget), _("_Restart Evolution after restore"), "org.gnome.backup-restore:restore-confirm", NULL);
+ mask = dialog_prompt_user (
+ parent, _("_Restart Evolution after restore"),
+ "org.gnome.backup-restore:restore-confirm", NULL);
if (mask & BR_OK)
restore (filename, mask & BR_START);
} else {
- e_error_run (GTK_WINDOW (target->target.widget), "org.gnome.backup-restore:invalid-backup", NULL);
+ e_error_run (parent, "org.gnome.backup-restore:invalid-backup", NULL);
}
g_free (filename);
@@ -227,77 +233,74 @@ org_gnome_backup_restore_restore (EPlugin *ep, ESMenuTargetShell *target)
}
static void
-check_toggled (GtkToggleButton *button, GnomeDruid *druid)
+check_toggled (GtkToggleButton *button, GtkAssistant *assistant)
{
- GtkWidget *box = g_object_get_data ((GObject *)button, "box");
- gboolean state = gtk_toggle_button_get_active ((GtkToggleButton *)button);
- gchar *prevfile = g_object_get_data ((GObject *)druid, "restore-file");
+ GtkWidget *box = g_object_get_data ((GObject *)button, "box");
+ gboolean state = gtk_toggle_button_get_active ((GtkToggleButton *)button);
gtk_widget_set_sensitive (box, state);
- gnome_druid_set_show_finish (druid, state);
- if (state && !prevfile)
- gnome_druid_set_buttons_sensitive (druid, TRUE, FALSE, TRUE, TRUE);
- else
- gnome_druid_set_buttons_sensitive (druid, TRUE, TRUE, TRUE, TRUE);
- g_object_set_data ((GObject *)druid, "restore", GINT_TO_POINTER (state?1:0));
+ g_object_set_data ((GObject *)assistant, "restore", GINT_TO_POINTER (state?1:0));
+ e_config_target_changed ((EConfig *) g_object_get_data ((GObject *)assistant, "restore-config"), E_CONFIG_TARGET_CHANGED_STATE);
}
static void
-restore_wizard (GnomeDruidPage *druidpage, GnomeDruid *druid, gpointer user_data)
+file_changed (GtkFileChooser *chooser, GtkAssistant *assistant)
{
- gboolean state = GPOINTER_TO_INT(g_object_get_data((GObject *)druid, "restore")) ? TRUE:FALSE;
- gchar *file = g_object_get_data ((GObject *)druid, "restore-file");
+ gchar *file = NULL, *prevfile = NULL;
+ gchar *uri = NULL;
- if (state) {
- if (!file ||!sanity_check (file)) {
- e_error_run ((GtkWindow *)druid, "org.gnome.backup-restore:invalid-backup", NULL);
- } else
- restore (file, TRUE);
+ uri = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (chooser));
+ e_file_update_save_path (uri, TRUE);
- }
+ file = gtk_file_chooser_get_filename (chooser);
+ prevfile = g_object_get_data ((GObject *)assistant, "restore-file");
+ g_object_set_data ((GObject *)assistant, "restore-file", file);
+ g_free (prevfile);
+
+ e_config_target_changed ((EConfig *) g_object_get_data ((GObject *)assistant, "restore-config"), E_CONFIG_TARGET_CHANGED_STATE);
}
-static void
-file_changed (GtkFileChooser *chooser, GnomeDruid *druid)
+static gboolean
+backup_restore_check (EConfig *ec, const gchar *pageid, gpointer data)
{
- gchar *file = NULL, *prevfile=NULL;
- gchar *uri = NULL;
+ GtkAssistant *assistant = data;
+ gint do_restore;
+ gchar *file;
- uri = gtk_file_chooser_get_current_folder_uri(GTK_FILE_CHOOSER (chooser));
- e_file_update_save_path(uri, TRUE);
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_ASSISTANT (data), FALSE);
- file = gtk_file_chooser_get_filename (chooser);
- prevfile = g_object_get_data ((GObject *)druid, "restore-file");
- g_object_set_data ((GObject *)druid, "restore-file", file);
- g_free (prevfile);
- if (file) {
- gnome_druid_set_buttons_sensitive (druid, TRUE, TRUE, TRUE, TRUE);
- } else
- gnome_druid_set_buttons_sensitive (druid, TRUE, FALSE, TRUE, TRUE);
+ do_restore = GPOINTER_TO_INT (g_object_get_data ((GObject *)assistant, "restore"));
+ file = g_object_get_data ((GObject *)assistant, "restore-file");
+
+ e_config_set_page_is_finish (ec, "0.startup_page.10.backup_restore", do_restore);
+ return !do_restore || file;
}
+
GtkWidget *
backup_restore_page (EPlugin *ep, EConfigHookItemFactoryData *hook_data)
{
- GtkWidget *page;
- GtkWidget *box, *hbox, *label, *cbox, *button;
+ GtkWidget *page, *hbox, *label, *cbox, *button;
+ GtkAssistant *assistant = GTK_ASSISTANT (hook_data->parent);
+
+ page = gtk_vbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (page), 12);
- page = gnome_druid_page_standard_new_with_vals (_("Restore from backup"), NULL, NULL);
hbox = gtk_hbox_new (FALSE, 6);
label = gtk_label_new (_("You can restore Evolution from your backup. It can restore all the Mails, Calendars, Tasks, Memos, Contacts. It also restores all your personal settings, mail filters etc."));
gtk_label_set_line_wrap ((GtkLabel *)label, TRUE);
gtk_label_set_single_line_mode ((GtkLabel *)label, FALSE);
gtk_box_pack_start ((GtkBox *)hbox, label, FALSE, FALSE, 6);
- box = gtk_vbox_new (FALSE, 6);
- gtk_box_pack_start ((GtkBox *)box, hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start ((GtkBox *)page, hbox, FALSE, FALSE, 0);
hbox = gtk_hbox_new (FALSE, 6);
cbox = gtk_check_button_new_with_mnemonic (_("_Restore Evolution from the backup file"));
- g_signal_connect (cbox, "toggled", G_CALLBACK (check_toggled), hook_data->parent);
+ g_signal_connect (cbox, "toggled", G_CALLBACK (check_toggled), assistant);
gtk_box_pack_start ((GtkBox *)hbox, cbox, FALSE, FALSE, 6);
- gtk_box_pack_start ((GtkBox *)box, hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start ((GtkBox *)page, hbox, FALSE, FALSE, 0);
hbox = gtk_hbox_new (FALSE, 6);
g_object_set_data ((GObject *)cbox, "box", hbox);
@@ -305,24 +308,37 @@ backup_restore_page (EPlugin *ep, EConfigHookItemFactoryData *hook_data)
gtk_box_pack_start ((GtkBox *)hbox, label, FALSE, FALSE, 12);
button = gtk_file_chooser_button_new (_("Choose a file to restore"), GTK_FILE_CHOOSER_ACTION_OPEN);
- g_signal_connect (button, "selection-changed", G_CALLBACK (file_changed), hook_data->parent);
+ g_signal_connect (button, "selection-changed", G_CALLBACK (file_changed), assistant);
gtk_file_chooser_button_set_width_chars ((GtkFileChooserButton *)button, 20);
gtk_box_pack_start ((GtkBox *)hbox, button, FALSE, FALSE, 0);
- gtk_box_pack_start ((GtkBox *)box, hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start ((GtkBox *)page, hbox, FALSE, FALSE, 0);
gtk_widget_set_sensitive (hbox, FALSE);
- gtk_container_add ((GtkContainer *) GNOME_DRUID_PAGE_STANDARD (page)->vbox, box);
- gtk_widget_show_all (box);
- gnome_druid_append_page (GNOME_DRUID (hook_data->parent), GNOME_DRUID_PAGE (page));
- g_object_set_data ((GObject *)hook_data->parent, "restore", GINT_TO_POINTER (FALSE));
- g_signal_connect (page, "finish", G_CALLBACK (restore_wizard), NULL);
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_title (assistant, page, _("Restore from backup"));
+ gtk_widget_show_all (page);
+
+ g_object_set_data ((GObject *)assistant, "restore", GINT_TO_POINTER (FALSE));
+ g_object_set_data ((GObject *)assistant, "restore-config", hook_data->config);
+
+ e_config_add_page_check (hook_data->config, "0.startup_page.10.backup_restore", backup_restore_check, assistant);
+
return GTK_WIDGET (page);
}
void
backup_restore_commit (EPlugin *ep, EMConfigTargetAccount *target)
{
- /* Nothing really */
- printf("commit\n");
+ GtkWidget *assistant = target->target.config->widget;
+ gboolean state = GPOINTER_TO_INT (g_object_get_data ((GObject *)assistant, "restore")) ? TRUE : FALSE;
+ gchar *file = g_object_get_data ((GObject *)assistant, "restore-file");
+
+ if (state) {
+ if (!file || !sanity_check (file)) {
+ e_error_run ((GtkWindow *)assistant, "org.gnome.backup-restore:invalid-backup", NULL);
+ } else {
+ restore (file, TRUE);
+ }
+ }
}
void
@@ -331,3 +347,35 @@ backup_restore_abort (EPlugin *ep, EMConfigTargetAccount *target)
/* Nothing really */
}
+static GtkActionEntry entries[] = {
+
+ { "settings-backup",
+ NULL,
+ N_("_Backup Settings..."),
+ NULL,
+ N_("Backup Evolution data and settings to an archive file"),
+ G_CALLBACK (action_settings_backup_cb) },
+
+ { "settings-restore",
+ NULL,
+ N_("R_estore Settings..."),
+ NULL,
+ N_("Restore Evolution data and settings from an archive file"),
+ G_CALLBACK (action_settings_restore_cb) }
+};
+
+gboolean
+e_plugin_ui_init (GtkUIManager *ui_manager,
+ EShellWindow *shell_window)
+{
+ GtkActionGroup *action_group;
+
+ action_group = e_shell_window_get_action_group (shell_window, "shell");
+
+ /* Add actions to the "shell" action group. */
+ gtk_action_group_add_actions (
+ action_group, entries,
+ G_N_ELEMENTS (entries), shell_window);
+
+ return TRUE;
+}
diff --git a/plugins/backup-restore/org-gnome-backup-restore.eplug.xml b/plugins/backup-restore/org-gnome-backup-restore.eplug.xml
index 2ed7222adc..c78b376296 100644
--- a/plugins/backup-restore/org-gnome-backup-restore.eplug.xml
+++ b/plugins/backup-restore/org-gnome-backup-restore.eplug.xml
@@ -9,31 +9,24 @@
<author name="JP Rosevear" email="jpr@novell.com"/>
<_description>Backup and restore your Evolution data and settings.</_description>
- <hook class="org.gnome.evolution.shell.bonobomenu:1.0">
-
- <menu id="org.gnome.evolution.shell" target="shell">
- <!-- the path to the bonobo menu description -->
- <ui file="@PLUGINDIR@/org-gnome-backup-restore.xml"/>
- <item
- type="item"
- verb="EPBRBackup"
- path="/commands/EPBRBackup"
- enable="one"
- activate="org_gnome_backup_restore_backup"/>
- <item
- type="item"
- verb="EPBRRestore"
- path="/commands/EPBRRestore"
- enable="one"
- activate="org_gnome_backup_restore_restore"/>
- </menu>
+ <hook class="org.gnome.evolution.ui:1.0">
+ <ui-manager id="org.gnome.evolution.shell">
+ <menubar name='main-menu'>
+ <menu action='file-menu'>
+ <placeholder name='file-actions'>
+ <menuitem action='settings-backup'/>
+ <menuitem action='settings-restore'/>
+ </placeholder>
+ </menu>
+ </menubar>
+ </ui-manager>
+ </hook>
+ <hook class="org.gnome.evolution.mail.config:1.0">
+ <group target="account" id="org.gnome.evolution.mail.config.accountWizard" commit="backup_restore_commit" abort="backup_restore_abort">
+ <item type="page" path="0.startup_page.10.backup_restore" factory="backup_restore_page"/>
+ </group>
</hook>
- <hook class="org.gnome.evolution.mail.config:1.0">
- <group target="account" id="org.gnome.evolution.mail.config.accountWizard" commit="backup_restore_commit" abort="backup_restore_abort">
- <item type="page" path="0.startup_page.10" factory="backup_restore_page"/>
- </group>
- </hook>
</e-plugin>
</e-plugin-list>
diff --git a/plugins/backup-restore/org-gnome-backup-restore.xml b/plugins/backup-restore/org-gnome-backup-restore.xml
deleted file mode 100644
index e546ce5581..0000000000
--- a/plugins/backup-restore/org-gnome-backup-restore.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<Root>
- <commands>
- <cmd name="EPBRBackup" _label="_Backup Settings..."
- _tip="Backup and restore Evolution data and settings"
- pixtype="pixmap"/>
-
- <cmd name="EPBRRestore" _label="R_estore Settings..."
- _tip="Backup and restore Evolution data and settings"
- pixtype="pixmap"/>
-
- </commands>
-
- <menu>
- <submenu name="File">
- <placeholder name="FileOps">
- <menuitem name="EPBRBackup" verb=""/>
- <menuitem name="EPBRRestore" verb=""/>
- </placeholder>
- </submenu>
- </menu>
-</Root>
diff --git a/plugins/bbdb/Makefile.am b/plugins/bbdb/Makefile.am
index 182c1e808b..0a44dc0c26 100644
--- a/plugins/bbdb/Makefile.am
+++ b/plugins/bbdb/Makefile.am
@@ -21,8 +21,10 @@ liborg_gnome_evolution_bbdb_la_SOURCES = bbdb.c bbdb.h gaimbuddies.c
liborg_gnome_evolution_bbdb_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_evolution_bbdb_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(NO_UNDEFINED_REQUIRED_LIBS)
+ $(top_builddir)/composer/libcomposer.la \
+ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
+ $(EVOLUTION_ADDRESSBOOK_LIBS)
EXTRA_DIST = org-gnome-evolution-bbdb.eplug.xml
diff --git a/plugins/bbdb/bbdb.c b/plugins/bbdb/bbdb.c
index 81bad245fe..d5104dcf0c 100644
--- a/plugins/bbdb/bbdb.c
+++ b/plugins/bbdb/bbdb.c
@@ -42,7 +42,7 @@
#define d(x)
/* Plugin hooks */
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
void bbdb_handle_send (EPlugin *ep, EMEventTargetComposer *target);
GtkWidget *bbdb_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data);
@@ -51,8 +51,8 @@ struct bbdb_stuff {
EMConfigTargetPrefs *target;
ESourceList *source_list;
- GtkWidget *option_menu;
- GtkWidget *gaim_option_menu;
+ GtkWidget *combo_box;
+ GtkWidget *gaim_combo_box;
GtkWidget *check;
GtkWidget *check_gaim;
};
@@ -63,7 +63,7 @@ static void bbdb_do_it (EBook *book, const gchar *name, const gchar *email);
static void add_email_to_contact (EContact *contact, const gchar *email);
static void enable_toggled_cb (GtkWidget *widget, gpointer data);
static void source_changed_cb (ESourceComboBox *source_combo_box, struct bbdb_stuff *stuff);
-static GtkWidget *create_addressbook_option_menu (struct bbdb_stuff *stuff, gint type);
+static GtkWidget *create_addressbook_combo_box (struct bbdb_stuff *stuff, gint type);
static void cleanup_cb (GObject *o, gpointer data);
static ESource *
@@ -106,7 +106,7 @@ find_esource_by_uri (ESourceList *source_list, const gchar *target_uri)
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
/* Start up the plugin. */
if (enable) {
@@ -463,7 +463,7 @@ enable_toggled_cb (GtkWidget *widget, gpointer data)
/* Save the new setting to gconf */
gconf_client_set_bool (stuff->target->gconf, GCONF_KEY_ENABLE, active, NULL);
- gtk_widget_set_sensitive (stuff->option_menu, active);
+ gtk_widget_set_sensitive (stuff->combo_box, active);
addressbook = gconf_client_get_string (stuff->target->gconf, GCONF_KEY_WHICH_ADDRESSBOOK, NULL);
@@ -472,7 +472,7 @@ enable_toggled_cb (GtkWidget *widget, gpointer data)
GError *error = NULL;
selected_source = e_source_combo_box_get_active (
- E_SOURCE_COMBO_BOX (stuff->option_menu));
+ E_SOURCE_COMBO_BOX (stuff->combo_box));
if (selected_source != NULL)
uri = e_source_get_uri (selected_source);
@@ -503,10 +503,10 @@ enable_gaim_toggled_cb (GtkWidget *widget, gpointer data)
gconf_client_set_bool (stuff->target->gconf, GCONF_KEY_ENABLE_GAIM, active, NULL);
addressbook_gaim = gconf_client_get_string (stuff->target->gconf, GCONF_KEY_WHICH_ADDRESSBOOK_GAIM, NULL);
- gtk_widget_set_sensitive (stuff->gaim_option_menu, active);
+ gtk_widget_set_sensitive (stuff->gaim_combo_box, active);
if (active && !addressbook_gaim) {
selected_source = e_source_combo_box_get_active (
- E_SOURCE_COMBO_BOX (stuff->gaim_option_menu));
+ E_SOURCE_COMBO_BOX (stuff->gaim_combo_box));
gconf_client_set_string (stuff->target->gconf, GCONF_KEY_WHICH_ADDRESSBOOK_GAIM, e_source_get_uri (selected_source), NULL);
}
@@ -560,7 +560,7 @@ gaim_source_changed_cb (ESourceComboBox *source_combo_box,
}
static GtkWidget *
-create_addressbook_option_menu (struct bbdb_stuff *stuff, gint type)
+create_addressbook_combo_box (struct bbdb_stuff *stuff, gint type)
{
GtkWidget *combo_box;
ESourceList *source_list;
@@ -604,8 +604,8 @@ bbdb_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data)
GtkWidget *hbox;
GtkWidget *inner_vbox;
GtkWidget *check;
- GtkWidget *option;
- GtkWidget *gaim_option;
+ GtkWidget *combo_box;
+ GtkWidget *gaim_combo_box;
GtkWidget *check_gaim;
GtkWidget *label;
GtkWidget *gaim_label;
@@ -652,12 +652,12 @@ bbdb_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data)
label = gtk_label_new (_("Select Address book for Automatic Contacts"));
gtk_box_pack_start (GTK_BOX (inner_vbox), label, FALSE, FALSE, 0);
- /* Source selection option menu */
- option = create_addressbook_option_menu (stuff, AUTOMATIC_CONTACTS_ADDRESSBOOK);
- g_signal_connect (option, "changed", G_CALLBACK (source_changed_cb), stuff);
- gtk_widget_set_sensitive (option, gconf_client_get_bool (target->gconf, GCONF_KEY_ENABLE, NULL));
- gtk_box_pack_start (GTK_BOX (inner_vbox), option, FALSE, FALSE, 0);
- stuff->option_menu = option;
+ /* Source selection combo box */
+ combo_box = create_addressbook_combo_box (stuff, AUTOMATIC_CONTACTS_ADDRESSBOOK);
+ g_signal_connect (combo_box, "changed", G_CALLBACK (source_changed_cb), stuff);
+ gtk_widget_set_sensitive (combo_box, gconf_client_get_bool (target->gconf, GCONF_KEY_ENABLE, NULL));
+ gtk_box_pack_start (GTK_BOX (inner_vbox), combo_box, FALSE, FALSE, 0);
+ stuff->combo_box = combo_box;
/* "Instant Messaging Contacts" */
frame = gtk_vbox_new (FALSE, 6);
@@ -688,12 +688,12 @@ bbdb_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data)
gaim_label = gtk_label_new (_("Select Address book for Pidgin buddy list"));
gtk_box_pack_start (GTK_BOX (inner_vbox), gaim_label, FALSE, FALSE, 0);
- /* Gaim Source Selection Option Menu */
- gaim_option = create_addressbook_option_menu (stuff, GAIM_ADDRESSBOOK);
- g_signal_connect (gaim_option, "changed", G_CALLBACK (gaim_source_changed_cb), stuff);
- gtk_widget_set_sensitive (gaim_option, gconf_client_get_bool (target->gconf, GCONF_KEY_ENABLE_GAIM, NULL));
- gtk_box_pack_start (GTK_BOX (inner_vbox), gaim_option, FALSE, FALSE, 0);
- stuff->gaim_option_menu = gaim_option;
+ /* Gaim Source Selection Combo Box */
+ gaim_combo_box = create_addressbook_combo_box (stuff, GAIM_ADDRESSBOOK);
+ g_signal_connect (gaim_combo_box, "changed", G_CALLBACK (gaim_source_changed_cb), stuff);
+ gtk_widget_set_sensitive (gaim_combo_box, gconf_client_get_bool (target->gconf, GCONF_KEY_ENABLE_GAIM, NULL));
+ gtk_box_pack_start (GTK_BOX (inner_vbox), gaim_combo_box, FALSE, FALSE, 0);
+ stuff->gaim_combo_box = gaim_combo_box;
/* Synchronize now button. */
button = gtk_button_new_with_mnemonic (_("Synchronize with _buddy list now"));
diff --git a/plugins/bogo-junk-plugin/Makefile.am b/plugins/bogo-junk-plugin/Makefile.am
index f488ddf0f7..00453ef090 100644
--- a/plugins/bogo-junk-plugin/Makefile.am
+++ b/plugins/bogo-junk-plugin/Makefile.am
@@ -11,8 +11,10 @@ plugin_LTLIBRARIES = liborg-gnome-bogo-junk-plugin.la
liborg_gnome_bogo_junk_plugin_la_SOURCES = bf-junk-filter.c
liborg_gnome_bogo_junk_plugin_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_bogo_junk_plugin_la_LIBADD = \
- $(GNOME_PLATFORM_LIBS) \
- $(top_builddir)/e-util/libeutil.la
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(EVOLUTION_MAIL_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
schemadir = $(GCONF_SCHEMA_FILE_DIR)
schema_in_files = bogo-junk-plugin.schemas.in
diff --git a/plugins/bogo-junk-plugin/bf-junk-filter.c b/plugins/bogo-junk-plugin/bf-junk-filter.c
index 3de8c30955..da384225c8 100644
--- a/plugins/bogo-junk-plugin/bf-junk-filter.c
+++ b/plugins/bogo-junk-plugin/bf-junk-filter.c
@@ -44,7 +44,7 @@
#include <gtk/gtk.h>
#include <e-util/e-plugin.h>
#include "mail/em-config.h"
-#include <mail/em-junk-hook.h>
+#include <mail/em-junk.h>
#include <camel/camel-data-wrapper.h>
#include <camel/camel-mime-message.h>
#include <camel/camel-mime-parser.h>
@@ -70,15 +70,15 @@ static const gchar em_junk_bf_gconf_dir[] = EM_JUNK_BF_GCONF_DIR;
GtkWidget * org_gnome_bogo_convert_unicode (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
/* plugin fonction prototypes */
-gboolean em_junk_bf_check_junk (EPlugin *ep, EMJunkHookTarget *target);
-gpointer em_junk_bf_validate_binary (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_bf_report_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_bf_report_non_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_bf_commit_reports (EPlugin *ep, EMJunkHookTarget *target);
+gboolean em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target);
+gpointer em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target);
+void em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target);
+void em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target);
+void em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target);
static gint pipe_to_bogofilter (CamelMimeMessage *msg, const gchar **argv, GError **error);
/* eplugin stuff */
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
#define EM_JUNK_BF_GCONF_DIR_LENGTH (G_N_ELEMENTS (em_junk_bf_gconf_dir) - 1)
@@ -241,7 +241,7 @@ em_junk_bf_setting_notify (GConfClient *gconf,
}
gboolean
-em_junk_bf_check_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target)
{
CamelMimeMessage *msg = target->m;
gint rv;
@@ -266,7 +266,7 @@ em_junk_bf_check_junk (EPlugin *ep, EMJunkHookTarget *target)
}
void
-em_junk_bf_report_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target)
{
CamelMimeMessage *msg = target->m;
@@ -287,7 +287,7 @@ em_junk_bf_report_junk (EPlugin *ep, EMJunkHookTarget *target)
}
void
-em_junk_bf_report_non_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target)
{
CamelMimeMessage *msg = target->m;
@@ -308,18 +308,18 @@ em_junk_bf_report_non_junk (EPlugin *ep, EMJunkHookTarget *target)
}
void
-em_junk_bf_commit_reports (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target)
{
}
gpointer
-em_junk_bf_validate_binary (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target)
{
return g_file_test (em_junk_bf_binary, G_FILE_TEST_EXISTS) ? (gpointer) "1" : NULL;
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
GConfClient *gconf;
diff --git a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml b/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml
index e1d8cc83a0..1317b988d9 100644
--- a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml
+++ b/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml
@@ -7,13 +7,12 @@
<_description>Filter junk messages using Bogofilter.</_description>
<author name="Mikhail Zabaluev" email="mhz@altlinux.org"/>
<hook class="org.gnome.evolution.mail.junk:1.0">
- <group id="EMJunk" >
- <item name="Bogofilter" report_non_junk="em_junk_bf_report_non_junk"
- report_junk="em_junk_bf_report_junk"
- check_junk="em_junk_bf_check_junk"
- commit_reports="em_junk_bf_commit_reports"
- validate_binary="em_junk_bf_validate_binary"/>
- </group>
+ <interface name="Bogofilter"
+ report_non_junk="em_junk_bf_report_non_junk"
+ report_junk="em_junk_bf_report_junk"
+ check_junk="em_junk_bf_check_junk"
+ commit_reports="em_junk_bf_commit_reports"
+ validate_binary="em_junk_bf_validate_binary"/>
</hook>
<!-- hook into the 'mail properties' menu -->
<hook class="org.gnome.evolution.mail.config:1.0">
diff --git a/plugins/caldav/caldav-source.c b/plugins/caldav/caldav-source.c
index 3407353574..f5d8f59d12 100644
--- a/plugins/caldav/caldav-source.c
+++ b/plugins/caldav/caldav-source.c
@@ -42,7 +42,7 @@
/*****************************************************************************/
/* prototypes */
-gint e_plugin_lib_enable (EPluginLib *ep,
+gint e_plugin_lib_enable (EPlugin *ep,
gint enable);
GtkWidget * oge_caldav (EPlugin *epl,
@@ -66,7 +66,7 @@ ensure_caldav_source_group (ECalSourceType source_type)
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
if (enable) {
diff --git a/plugins/calendar-weather/Makefile.am b/plugins/calendar-weather/Makefile.am
index 360555810a..484adf71e9 100644
--- a/plugins/calendar-weather/Makefile.am
+++ b/plugins/calendar-weather/Makefile.am
@@ -1,26 +1,16 @@
eds_datadir = `pkg-config --variable=privdatadir evolution-data-server-1.2`
-weatherdatadir = $(datadir)/evolution/$(BASE_VERSION)/weather
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_builddir)/shell \
- $(EVOLUTION_CALENDAR_CFLAGS) \
- $(SOURCE_SEL_CFLAGS) \
- -DWEATHER_DATADIR=\""$(weatherdatadir)"\" \
- -DWEATHER_EDS_DATADIR=\""$(eds_datadir)/weather"\" \
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ $(EVOLUTION_CALENDAR_CFLAGS) \
+ $(SOURCE_SEL_CFLAGS) \
+ -DWEATHER_DATADIR=\""$(weatherdatadir)"\" \
+ -DWEATHER_EDS_DATADIR=\""$(eds_datadir)/weather"\" \
$(LIBGWEATHER_CFLAGS)
@EVO_PLUGIN_RULE@
-weatherdata_DATA = \
- category_weather_cloudy_16.png \
- category_weather_fog_16.png \
- category_weather_partly_cloudy_16.png \
- category_weather_rain_16.png \
- category_weather_snow_16.png \
- category_weather_sun_16.png \
- category_weather_tstorm_16.png
-
plugin_DATA = org-gnome-calendar-weather.eplug
plugin_LTLIBRARIES = liborg-gnome-calendar-weather.la
diff --git a/plugins/calendar-weather/calendar-weather.c b/plugins/calendar-weather/calendar-weather.c
index cacc7e00fa..b558f7e3d2 100644
--- a/plugins/calendar-weather/calendar-weather.c
+++ b/plugins/calendar-weather/calendar-weather.c
@@ -24,7 +24,6 @@
#include "e-util/e-icon-factory.h"
#include <calendar/gui/e-cal-config.h>
#include <calendar/gui/e-cal-event.h>
-#include <calendar/gui/calendar-component.h>
#include <libedataserver/e-source.h>
#include <libedataserver/e-url.h>
#include <libedataserver/e-categories.h>
@@ -42,17 +41,17 @@ GtkWidget *e_calendar_weather_location (EPlugin *epl, EConfigHookItemFactoryData
GtkWidget *e_calendar_weather_refresh (EPlugin *epl, EConfigHookItemFactoryData *data);
GtkWidget *e_calendar_weather_units (EPlugin *epl, EConfigHookItemFactoryData *data);
gboolean e_calendar_weather_check (EPlugin *epl, EConfigHookPageCheckData *data);
-void e_calendar_weather_migrate (EPlugin *epl, ECalEventTargetComponent *data);
-gint e_plugin_lib_enable (EPluginLib *epl, gint enable);
+void e_calendar_weather_migrate (EPlugin *epl, ECalEventTargetBackend *data);
+gint e_plugin_lib_enable (EPlugin *epl, gint enable);
#define WEATHER_BASE_URI "weather://"
gint
-e_plugin_lib_enable (EPluginLib *epl, gint enable)
+e_plugin_lib_enable (EPlugin *epl, gint enable)
{
GList *l;
- gboolean found = FALSE;
const gchar *tmp;
+ gint ii;
static struct {
const gchar *description;
@@ -74,43 +73,35 @@ e_plugin_lib_enable (EPluginLib *epl, gint enable)
/* Add the categories icons if we don't have them. */
for (l = e_categories_get_list (); l; l = g_list_next (l)) {
- if (!strcmp ((const gchar *)l->data, tmp)) {
- found = TRUE;
- break;
- }
+ if (!strcmp ((const gchar *)l->data, tmp))
+ goto exit;
}
- if (!found) {
- gint i;
-
- for (i = 0; categories[i].description; i++) {
- gchar *filename;
+ for (ii = 0; categories[ii].description; ii++) {
+ gchar *filename;
- filename = e_icon_factory_get_icon_filename (categories[i].icon_name, GTK_ICON_SIZE_MENU);
- e_categories_add (_(categories[i].description), NULL, filename, FALSE);
- g_free (filename);
- }
+ filename = e_icon_factory_get_icon_filename (
+ categories[ii].icon_name, GTK_ICON_SIZE_MENU);
+ e_categories_add (
+ _(categories[ii].description), NULL, filename, FALSE);
+ g_free (filename);
}
+exit:
return 0;
}
void
-e_calendar_weather_migrate (EPlugin *epl, ECalEventTargetComponent *data)
+e_calendar_weather_migrate (EPlugin *epl, ECalEventTargetBackend *data)
{
/* Perform a migration step here. This allows us to keep the weather calendar completely
* separate from evolution. If the plugin isn't built, the weather source group won't
* show up in the user's evolution. If it is, this will create it if it doesn't exist */
- CalendarComponent *component;
- ESourceList *source_list;
ESourceGroup *group;
GSList *groups;
ESourceGroup *weather = NULL;
- component = data->component;
- source_list = calendar_component_peek_source_list (component);
-
- groups = e_source_list_peek_groups (source_list);
+ groups = e_source_list_peek_groups (data->source_list);
if (groups) {
/* groups are already there, we need to search */
GSList *g;
@@ -124,7 +115,7 @@ e_calendar_weather_migrate (EPlugin *epl, ECalEventTargetComponent *data)
if (!weather) {
group = e_source_group_new (_("Weather"), WEATHER_BASE_URI);
- e_source_list_add_group (source_list, group, -1);
+ e_source_list_add_group (data->source_list, group, -1);
weather = group;
}
@@ -132,7 +123,7 @@ e_calendar_weather_migrate (EPlugin *epl, ECalEventTargetComponent *data)
if (weather)
g_object_unref (weather);
- e_source_list_sync (source_list, NULL);
+ e_source_list_sync (data->source_list, NULL);
}
static void
diff --git a/plugins/calendar-weather/category_weather_cloudy_16.png b/plugins/calendar-weather/category_weather_cloudy_16.png
deleted file mode 100644
index ddb3ba7c59..0000000000
--- a/plugins/calendar-weather/category_weather_cloudy_16.png
+++ /dev/null
Binary files differ
diff --git a/plugins/calendar-weather/category_weather_fog_16.png b/plugins/calendar-weather/category_weather_fog_16.png
deleted file mode 100644
index 23e4e2f1d4..0000000000
--- a/plugins/calendar-weather/category_weather_fog_16.png
+++ /dev/null
Binary files differ
diff --git a/plugins/calendar-weather/category_weather_partly_cloudy_16.png b/plugins/calendar-weather/category_weather_partly_cloudy_16.png
deleted file mode 100644
index 472feaa654..0000000000
--- a/plugins/calendar-weather/category_weather_partly_cloudy_16.png
+++ /dev/null
Binary files differ
diff --git a/plugins/calendar-weather/category_weather_rain_16.png b/plugins/calendar-weather/category_weather_rain_16.png
deleted file mode 100644
index e00d5e1c82..0000000000
--- a/plugins/calendar-weather/category_weather_rain_16.png
+++ /dev/null
Binary files differ
diff --git a/plugins/calendar-weather/category_weather_snow_16.png b/plugins/calendar-weather/category_weather_snow_16.png
deleted file mode 100644
index 5e95985f5f..0000000000
--- a/plugins/calendar-weather/category_weather_snow_16.png
+++ /dev/null
Binary files differ
diff --git a/plugins/calendar-weather/category_weather_sun_16.png b/plugins/calendar-weather/category_weather_sun_16.png
deleted file mode 100644
index 780c61c23c..0000000000
--- a/plugins/calendar-weather/category_weather_sun_16.png
+++ /dev/null
Binary files differ
diff --git a/plugins/calendar-weather/category_weather_tstorm_16.png b/plugins/calendar-weather/category_weather_tstorm_16.png
deleted file mode 100644
index b2af092b53..0000000000
--- a/plugins/calendar-weather/category_weather_tstorm_16.png
+++ /dev/null
Binary files differ
diff --git a/plugins/copy-tool/ChangeLog b/plugins/copy-tool/ChangeLog
deleted file mode 100644
index 5fab320dc8..0000000000
--- a/plugins/copy-tool/ChangeLog
+++ /dev/null
@@ -1,67 +0,0 @@
-2008-08-27 Sankar P <psankar@novell.com>
-
-License Changes
-
- * copy-tool.c:
-
-2008-08-12 Bharath Acharya <abharath@novell.com>
-
- * Makefile.am: Use NO_UNDEFINED. Link with more libraries. To generate
- dlls on Windows.
-
-2007-04-02 Sankar P <psankar@novell.com>
-
- * Committed on behalf of Gilles Dartiguelongue <dartigug@esiee.fr>
-
- * org-gnome-copy-tool.eplug.xml:
- Cleanup.
- Fixes part of #301149
-
-2006-05-19 Hiroyuki Ikezoe <poincare@ikezoe.net>
-
- ** Fixes bug #322771
- * copy-tool.c: Use GtkClipboard instead of GtkInvisible.
-
-2005-11-30 Simon Zheng <Simon.Zheng@Sun.Com>
-
- Fix for 322733.
-
- * copy-tool.c: (ct_selection_get): Removed printf() statement
- in order to avoid printing NULL point.
- (org_gnome_copy_tool_copy_address): Removed printf() statement.
- (ct_selection_clear_event): Removed printf() statement.
-
-2005-05-11 Not Zed <NotZed@Ximian.com>
-
- * Makefile.am: added built_sources/cleanfiles.
-
-2005-05-06 Not Zed <NotZed@Ximian.com>
-
- * Makefile.am:
- * org-gnome-copy-tool.eplug.xml: s/.in/.xml/ & i18n.
-
-2005-02-24 Björn Torkelsson <torkel@acc.umu.se>
-
- * org-gnome-copy-tool.eplug.in: Added a . to the end of description.
-
-2004-11-03 Not Zed <NotZed@Ximian.com>
-
- * org-gnome-copy-tool.eplug.in: gave it a better name and fixed
- the description and author tags.
-
-2004-11-01 JP Rosevear <jpr@novell.com>
-
- * Makefile.am: dist .eplug.in file
-
-2004-10-28 Not Zed <NotZed@Ximian.com>
-
- * org-gnome-copy-tool.eplug.in: fix folderview popup hook id.
-
-2004-10-21 JP Rosevear <jpr@novell.com>
-
- * org-gnome-copy-tool.eplug.in: s/image/icon/
-
-2004-10-20 Not Zed <NotZed@Ximian.com>
-
- * implemented a copy-utils plugin.
-
diff --git a/plugins/copy-tool/Makefile.am b/plugins/copy-tool/Makefile.am
deleted file mode 100644
index 87d1dff454..0000000000
--- a/plugins/copy-tool/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- $(EVOLUTION_MAIL_CFLAGS)
-
-@EVO_PLUGIN_RULE@
-
-plugin_DATA = org-gnome-copy-tool.eplug
-plugin_LTLIBRARIES = liborg-gnome-copy-tool.la
-
-liborg_gnome_copy_tool_la_SOURCES = copy-tool.c
-liborg_gnome_copy_tool_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_copy_tool_la_LIBADD = \
- $(EVOLUTION_MAIL_LIBS)
-
-EXTRA_DIST = org-gnome-copy-tool.eplug.xml
-
-BUILT_SOURCES = $(plugin_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
--include $(top_srcdir)/git.mk
diff --git a/plugins/copy-tool/copy-tool.c b/plugins/copy-tool/copy-tool.c
deleted file mode 100644
index 769bd00431..0000000000
--- a/plugins/copy-tool/copy-tool.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-/* Add 'copy to clipboard' things to various menu's.
-
- Uh, so far only to copy mail addresses from mail content */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib/gi18n-lib.h>
-#include <string.h>
-
-#include "mail/em-popup.h"
-
-#include <gtk/gtk.h>
-
-#include "camel/camel-internet-address.h"
-#include "camel/camel-url.h"
-
-void org_gnome_copy_tool_copy_address(gpointer ep, EMPopupTargetURI *t);
-
-void
-org_gnome_copy_tool_copy_address(gpointer ep, EMPopupTargetURI *t)
-{
- if (t->uri) {
- CamelInternetAddress *cia = camel_internet_address_new();
- CamelURL *curl;
- GtkClipboard *clipboard;
- gchar *addr;
- const gchar *tmp;
-
- curl = camel_url_new(t->uri, NULL);
- camel_address_decode((CamelAddress *)cia, curl->path);
- /* should it perhaps use address format? */
- addr = camel_address_encode((CamelAddress *)cia);
- tmp = addr && addr[0] ? addr : t->uri + 7;
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
-
- gtk_clipboard_set_text (clipboard, tmp, strlen (tmp));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text (clipboard, tmp, strlen (tmp));
-
- g_free(addr);
- camel_url_free(curl);
- camel_object_unref(cia);
- }
-}
diff --git a/plugins/copy-tool/org-gnome-copy-tool.eplug.xml b/plugins/copy-tool/org-gnome-copy-tool.eplug.xml
deleted file mode 100644
index 3b6a30752d..0000000000
--- a/plugins/copy-tool/org-gnome-copy-tool.eplug.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0"?>
-<e-plugin-list>
- <e-plugin
- type="shlib"
- id="org.gnome.evolution.plugin.copyTool"
- location="@PLUGINDIR@/liborg-gnome-copy-tool@SOEXT@"
- _name="Copy Tool">
- <_description>Copy things to the clipboard.</_description>
- <author name="Michael Zucchi" email="notzed@ximian.com"/>
-
- <!-- hook into the uri popup menu -->
- <hook class="org.gnome.evolution.mail.popup:1.0">
- <menu id="org.gnome.evolution.mail.folderview.popup" target="uri">
- <item
- type="item"
- path="80.test"
- icon="gtk-copy"
- _label="Copy _Email Address"
- visible="mailto"
- activate="org_gnome_copy_tool_copy_address"/>
- </menu>
- </hook>
- </e-plugin>
-</e-plugin-list>
diff --git a/plugins/default-mailer/Makefile.am b/plugins/default-mailer/Makefile.am
index 94d3436f0e..ccb8071a99 100644
--- a/plugins/default-mailer/Makefile.am
+++ b/plugins/default-mailer/Makefile.am
@@ -1,6 +1,6 @@
AM_CPPFLAGS = \
-I$(top_srcdir) \
- -I$(top_builddir)/shell \
+ -I$(top_srcdir)/widgets \
$(EVOLUTION_MAIL_CFLAGS)
@EVO_PLUGIN_RULE@
diff --git a/plugins/email-custom-header/Makefile.am b/plugins/email-custom-header/Makefile.am
index efd46a5435..2ab28fad67 100644
--- a/plugins/email-custom-header/Makefile.am
+++ b/plugins/email-custom-header/Makefile.am
@@ -23,8 +23,7 @@ liborg_gnome_email_custom_header_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
$(top_builddir)/mail/libevolution-mail.la \
- $(EVOLUTION_MAIL_LIBS) \
- $(NO_UNDEFINED_REQUIRED_LIBS)
+ $(EVOLUTION_MAIL_LIBS)
liborg_gnome_email_custom_header_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
diff --git a/plugins/email-custom-header/email-custom-header.c b/plugins/email-custom-header/email-custom-header.c
index 4617edb83e..127cbdc815 100644
--- a/plugins/email-custom-header/email-custom-header.c
+++ b/plugins/email-custom-header/email-custom-header.c
@@ -29,7 +29,6 @@
#include <gconf/gconf-client.h>
#include <e-util/e-error.h>
#include <glade/glade.h>
-#include "mail/em-menu.h"
#include "mail/em-utils.h"
#include "mail/em-event.h"
#include "composer/e-msg-composer.h"
@@ -80,13 +79,13 @@ static void epech_dialog_dispose (GObject *object);
static void epech_setup_widgets (CustomHeaderOptionsDialog *mch);
static gint epech_check_existing_composer_window(gconstpointer a, gconstpointer b);
static void commit_changes (ConfigData *cd);
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl);
gboolean e_plugin_ui_init(GtkUIManager *ui_manager, EMsgComposer *composer);
GtkWidget *org_gnome_email_custom_header_config_option (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
return 0;
}
@@ -549,13 +548,13 @@ destroy_compo_data (gpointer data)
static void action_email_custom_header_cb (GtkAction *action, EMsgComposer *composer)
{
- GtkUIManager *manager;
+ GtkUIManager *ui_manager;
GtkWidget *menuitem;
CustomHeaderOptionsDialog *dialog = NULL;
EmailCustomHeaderWindow *new_email_custom_header_window = NULL;
- manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (composer));
- menuitem = gtk_ui_manager_get_widget (manager, "/main-menu/insert-menu/insert-menu-top/Custom Header");
+ ui_manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (composer));
+ menuitem = gtk_ui_manager_get_widget (ui_manager, "/main-menu/insert-menu/insert-menu-top/Custom Header");
new_email_custom_header_window = g_object_get_data ((GObject *) composer, "compowindow");
diff --git a/plugins/exchange-operations/exchange-account-setup.c b/plugins/exchange-operations/exchange-account-setup.c
index 296e44282c..5943d5f3df 100644
--- a/plugins/exchange-operations/exchange-account-setup.c
+++ b/plugins/exchange-operations/exchange-account-setup.c
@@ -668,7 +668,7 @@ construct_owa_url (CamelURL *url)
return owa_url;
}
-/* used by editor and druid - same code */
+/* used by editor and assistant - same code */
GtkWidget *
org_gnome_exchange_owa_url(EPlugin *epl, EConfigHookItemFactoryData *data)
{
@@ -734,7 +734,7 @@ org_gnome_exchange_owa_url(EPlugin *epl, EConfigHookItemFactoryData *data)
/* url has hostname but not owa_url.
* Account has been created using x-c-s or evo is upgraded to 2.2
- * When invoked from druid, hostname will get set after validation,
+ * When invoked from assistant, hostname will get set after validation,
* so this condition will never be true during account creation.
*/
owa_url = construct_owa_url (url);
diff --git a/plugins/exchange-operations/exchange-operations.c b/plugins/exchange-operations/exchange-operations.c
index d79948ccc4..35ed781fad 100644
--- a/plugins/exchange-operations/exchange-operations.c
+++ b/plugins/exchange-operations/exchange-operations.c
@@ -58,7 +58,7 @@ free_exchange_listener (void)
}
gint
-e_plugin_lib_enable (EPluginLib *eplib, gint enable)
+e_plugin_lib_enable (EPlugin *eplib, gint enable)
{
if (!exchange_global_config_listener) {
exchange_global_config_listener = exchange_config_listener_new ();
diff --git a/plugins/exchange-operations/exchange-user-dialog.c b/plugins/exchange-operations/exchange-user-dialog.c
index 6cb20e682d..eec2c7bddc 100644
--- a/plugins/exchange-operations/exchange-user-dialog.c
+++ b/plugins/exchange-operations/exchange-user-dialog.c
@@ -22,9 +22,6 @@
#include "exchange-user-dialog.h"
#include "e2k-types.h"
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-widget.h>
#include <e-util/e-dialog-utils.h>
#include <libedataserverui/e-name-selector.h>
#include "e2k-xml-utils.h"
diff --git a/plugins/exchange-operations/org-gnome-exchange-operations.eplug.xml b/plugins/exchange-operations/org-gnome-exchange-operations.eplug.xml
index 381ac94e4c..063d5c98c6 100644
--- a/plugins/exchange-operations/org-gnome-exchange-operations.eplug.xml
+++ b/plugins/exchange-operations/org-gnome-exchange-operations.eplug.xml
@@ -33,7 +33,7 @@
<group
target="account"
- id="org.gnome.evolution.mail.config.accountDruid"
+ id="org.gnome.evolution.mail.config.accountAssistant"
check="org_gnome_exchange_check_options">
<item type="item_table"
path="10.receive/10.config/20.owa"
diff --git a/plugins/external-editor/Makefile.am b/plugins/external-editor/Makefile.am
index 05457efd17..8c47bca60c 100644
--- a/plugins/external-editor/Makefile.am
+++ b/plugins/external-editor/Makefile.am
@@ -35,8 +35,15 @@ liborg_gnome_external_editor_la_SOURCES = \
liborg_gnome_external_editor_la_LDFLAGS = \
-module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_external_editor_la_LIBADD = \
- $(NO_UNDEFINED_REQUIRED_LIBS)
+liborg_gnome_external_editor_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/composer/libcomposer.la \
+ $(top_builddir)/shell/libeshell.la \
+ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(EVOLUTION_MAIL_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
schemadir = $(GCONF_SCHEMA_FILE_DIR)
schema_in_files = apps-evolution-external-editor.schemas.in
diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c
index e6ed35cf6b..88858c0211 100644
--- a/plugins/external-editor/external-editor.c
+++ b/plugins/external-editor/external-editor.c
@@ -26,7 +26,6 @@
#include <config.h>
#endif
-#include <mail/em-menu.h>
#include <mail/em-config.h>
#include <mail/em-composer-utils.h>
#include <mail/mail-config.h>
diff --git a/plugins/face/Makefile.am b/plugins/face/Makefile.am
index 86a522a2d0..07cbb8199d 100644
--- a/plugins/face/Makefile.am
+++ b/plugins/face/Makefile.am
@@ -22,8 +22,7 @@ liborg_gnome_face_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
$(top_builddir)/mail/libevolution-mail.la \
- $(EVOLUTION_MAIL_LIBS) \
- $(NO_UNDEFINED_REQUIRED_LIBS)
+ $(EVOLUTION_MAIL_LIBS)
liborg_gnome_face_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
diff --git a/plugins/face/face.c b/plugins/face/face.c
index 6bbc7bbf1a..1bb56c2bff 100644
--- a/plugins/face/face.c
+++ b/plugins/face/face.c
@@ -28,7 +28,6 @@
#include "composer/e-msg-composer.h"
#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include <mail/em-menu.h>
#include <e-util/e-error.h>
#include <e-util/e-util.h>
diff --git a/plugins/folder-unsubscribe/ChangeLog b/plugins/folder-unsubscribe/ChangeLog
deleted file mode 100644
index fd8eb19b43..0000000000
--- a/plugins/folder-unsubscribe/ChangeLog
+++ /dev/null
@@ -1,58 +0,0 @@
-2008-09-23 Matthew Barnes <mbarnes@redhat.com>
-
- ** Fixes part of bug #552850
-
- * org-gnome-mail-folder-unsubscribe.eplug.xml:
- Prefer the term "side bar" over "folder tree".
-
-2008-08-27 Sankar P <psankar@novell.com>
-
-License Changes
-
- * folder-unsubscribe.c:
-
-2008-08-12 Bharath Acharya <abharath@novell.com>
-
- * Makefile.am: Use NO_UNDEFINED. Link with more libraries. To generate
- dlls on Windows.
-
-2007-12-20 Matthew Barnes <mbarnes@redhat.com>
-
- ** Fixes part of bug #362638
-
- * folder-unsubscribe.c:
- Use the new MailMsg API for messages.
-
-2007-11-18 Gilles Dartiguelongue <gdartigu@svn.gnome.org>
-
- ** Fix bug #495875
-
- * org-gnome-mail-folder-unsubscribe.eplug.xml:
- right click menu reordering
-
-2007-04-02 Sankar P <psankar@novell.com>
-
- * Committed on behalf of Gilles Dartiguelongue <dartigug@esiee.fr>
-
- * org-gnome-mail-folder-unsubscribe.eplug.xml:
- Cleanup.
- Fixes part of #301149
-
-
-2005-05-06 Not Zed <NotZed@Ximian.com>
-
- * Makefile.am:
- * org-gnome-mail-folder-unsubscribe.eplug.xml: s/.in/.xml/ & i18n.
-
-2005-02-24 Björn Torkelsson <torkel@acc.umu.se>
-
- * org-gnome-mail-folder-unsubscribe.eplug.in: Updated description.
-
-2004-11-01 JP Rosevear <jpr@novell.com>
-
- * Makefile.am: dist .eplug.in file
-
-2004-10-28 Not Zed <NotZed@Ximian.com>
-
- * org-gnome-mail-folder-unsubscribe.eplug.in: fix hook id
-
diff --git a/plugins/folder-unsubscribe/Makefile.am b/plugins/folder-unsubscribe/Makefile.am
deleted file mode 100644
index 242d911ed0..0000000000
--- a/plugins/folder-unsubscribe/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- $(EVOLUTION_MAIL_CFLAGS)
-
-@EVO_PLUGIN_RULE@
-
-plugin_DATA = org-gnome-mail-folder-unsubscribe.eplug
-plugin_LTLIBRARIES = liborg-gnome-mail-folder-unsubscribe.la
-
-liborg_gnome_mail_folder_unsubscribe_la_SOURCES = folder-unsubscribe.c
-liborg_gnome_mail_folder_unsubscribe_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_mail_folder_unsubscribe_la_LIBADD = \
- $(top_builddir)/mail/libevolution-mail.la \
- $(EVOLUTION_MAIL_LIBS)
-
-EXTRA_DIST = org-gnome-mail-folder-unsubscribe.eplug.xml
-
--include $(top_srcdir)/git.mk
diff --git a/plugins/folder-unsubscribe/folder-unsubscribe.c b/plugins/folder-unsubscribe/folder-unsubscribe.c
deleted file mode 100644
index d1b8957fb0..0000000000
--- a/plugins/folder-unsubscribe/folder-unsubscribe.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jeffrey Stedfast <fejj@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-
-#include <string.h>
-
-#include <camel/camel-session.h>
-#include <camel/camel-store.h>
-#include <camel/camel-url.h>
-
-#include "mail/em-popup.h"
-#include "mail/mail-mt.h"
-#include "mail/mail-ops.h"
-
-void org_gnome_mail_folder_unsubscribe (EPlugin *plug, EMPopupTargetFolder *target);
-
-struct _folder_unsub_t {
- MailMsg base;
-
- gchar *uri;
-};
-
-static gchar *
-folder_unsubscribe_desc (struct _folder_unsub_t *msg)
-{
- return g_strdup_printf (
- _("Unsubscribing from folder \"%s\""), msg->uri);
-}
-
-extern CamelSession *session;
-
-static void
-folder_unsubscribe_exec (struct _folder_unsub_t *msg)
-{
- const gchar *path = NULL;
- CamelStore *store;
- CamelURL *url;
-
- if (!(store = camel_session_get_store (session, msg->uri, &msg->base.ex)))
- return;
-
- url = camel_url_new (msg->uri, NULL);
- if (((CamelService *) store)->provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH)
- path = url->fragment;
- else if (url->path && url->path[0])
- path = url->path + 1;
-
- if (path != NULL)
- camel_store_unsubscribe_folder (store, path, &msg->base.ex);
-
- camel_url_free (url);
-}
-
-static void
-folder_unsubscribe_free (struct _folder_unsub_t *msg)
-{
- g_free (msg->uri);
-}
-
-static MailMsgInfo unsubscribe_info = {
- sizeof (struct _folder_unsub_t),
- (MailMsgDescFunc) folder_unsubscribe_desc,
- (MailMsgExecFunc) folder_unsubscribe_exec,
- (MailMsgDoneFunc) NULL,
- (MailMsgFreeFunc) folder_unsubscribe_free
-};
-
-void
-org_gnome_mail_folder_unsubscribe (EPlugin *plug, EMPopupTargetFolder *target)
-{
- struct _folder_unsub_t *unsub;
-
- if (target->uri == NULL)
- return;
-
- unsub = mail_msg_new (&unsubscribe_info);
- unsub->uri = g_strdup (target->uri);
-
- mail_msg_unordered_push (unsub);
-}
diff --git a/plugins/folder-unsubscribe/org-gnome-mail-folder-unsubscribe.eplug.xml b/plugins/folder-unsubscribe/org-gnome-mail-folder-unsubscribe.eplug.xml
deleted file mode 100644
index 24271fa8af..0000000000
--- a/plugins/folder-unsubscribe/org-gnome-mail-folder-unsubscribe.eplug.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?>
-<e-plugin-list>
- <e-plugin
- id="org.gnome.evolution.mail.folder.unsubscribe"
- type="shlib"
- domain="@GETTEXT_PACKAGE@"
- _name="Unsubscribe Folders"
- location="@PLUGINDIR@/liborg-gnome-mail-folder-unsubscribe@SOEXT@">
- <_description>Unsubscribe from an IMAP folder by right-clicking on it in the folder tree.</_description>
- <author name="Jeffrey Stedfast" email="fejj@novell.com"/>
-
- <hook class="org.gnome.evolution.mail.popup:1.0">
- <menu id="org.gnome.evolution.mail.foldertree.popup" target="folder">
- <item type="item" path="30.emc.03" _label="_Unsubscribe"
- activate="org_gnome_mail_folder_unsubscribe"
- enable="delete" visible="delete"/>
- </menu>
- </hook>
- </e-plugin>
-</e-plugin-list>
diff --git a/plugins/google-account-setup/Makefile.am b/plugins/google-account-setup/Makefile.am
index 67a7c2c152..3434dbb331 100644
--- a/plugins/google-account-setup/Makefile.am
+++ b/plugins/google-account-setup/Makefile.am
@@ -1,7 +1,7 @@
AM_CPPFLAGS = \
-I . \
- -I$(top_srcdir) \
- -I$(top_builddir)/shell \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
-DCALDAV_GLADEDIR=\""$(gladedir)"\" \
$(EVOLUTION_CALENDAR_CFLAGS) \
$(EVOLUTION_ADDRESSBOOK_CFLAGS)
diff --git a/plugins/google-account-setup/google-source.c b/plugins/google-account-setup/google-source.c
index 2a8b6c46e5..1dc76a0431 100644
--- a/plugins/google-account-setup/google-source.c
+++ b/plugins/google-account-setup/google-source.c
@@ -37,7 +37,6 @@
#include <calendar/gui/e-cal-config.h>
#include <calendar/gui/e-cal-event.h>
-#include <calendar/gui/calendar-component.h>
#include <libedataserver/e-url.h>
#include <libedataserver/e-account-list.h>
@@ -61,9 +60,9 @@
/*****************************************************************************/
/* prototypes */
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
GtkWidget *plugin_google (EPlugin *epl, EConfigHookItemFactoryData *data);
-void e_calendar_google_migrate (EPlugin *epl, ECalEventTargetComponent *data);
+void e_calendar_google_migrate (EPlugin *epl, ECalEventTargetBackend *data);
/*****************************************************************************/
/* plugin intialization */
@@ -83,7 +82,7 @@ ensure_google_source_group (void)
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
if (enable) {
@@ -785,15 +784,13 @@ plugin_google (EPlugin *epl,
}
void
-e_calendar_google_migrate (EPlugin *epl, ECalEventTargetComponent *data)
+e_calendar_google_migrate (EPlugin *epl, ECalEventTargetBackend *data)
{
- CalendarComponent *component;
ESourceList *source_list;
ESourceGroup *google = NULL;
gboolean changed = FALSE;
- component = data->component;
- source_list = calendar_component_peek_source_list (component);
+ source_list = data->source_list;
google = e_source_list_peek_group_by_base_uri (source_list, GOOGLE_BASE_URI);
if (google) {
diff --git a/plugins/groupwise-account-setup/groupwise-account-setup.c b/plugins/groupwise-account-setup/groupwise-account-setup.c
index 6375446d7e..0872a9c2a7 100644
--- a/plugins/groupwise-account-setup/groupwise-account-setup.c
+++ b/plugins/groupwise-account-setup/groupwise-account-setup.c
@@ -32,7 +32,7 @@
static CamelGwListener *config_listener = NULL;
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
GtkWidget* org_gnome_gw_account_setup(struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
void ensure_mandatory_esource_properties (EPlugin *ep, ESEventTargetUpgrade *target);
@@ -114,7 +114,7 @@ free_groupwise_listener ( void )
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
if (!config_listener) {
config_listener = camel_gw_listener_new ();
diff --git a/plugins/groupwise-account-setup/org-gnome-gw-account-setup.eplug.xml b/plugins/groupwise-account-setup/org-gnome-gw-account-setup.eplug.xml
index 16947d89c7..f99606f8a4 100644
--- a/plugins/groupwise-account-setup/org-gnome-gw-account-setup.eplug.xml
+++ b/plugins/groupwise-account-setup/org-gnome-gw-account-setup.eplug.xml
@@ -6,7 +6,7 @@
<_description>Add Novell GroupWise support to Evolution.</_description>
<hook class="org.gnome.evolution.mail.config:1.0">
- <group target="account" id="org.gnome.evolution.mail.config.accountDruid">
+ <group target="account" id="org.gnome.evolution.mail.config.accountAssistant">
<item type="item_table" path="20.receive_options/30.soapport/50.dummy" factory="org_gnome_groupwise_account_setup"/>
</group>
</hook>
diff --git a/plugins/groupwise-features/Makefile.am b/plugins/groupwise-features/Makefile.am
index b26fa1693d..20fd6bf812 100644
--- a/plugins/groupwise-features/Makefile.am
+++ b/plugins/groupwise-features/Makefile.am
@@ -45,7 +45,6 @@ liborg_gnome_groupwise_features_la_LIBADD= \
$(top_builddir)/calendar/gui/libevolution-calendar.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
$(top_builddir)/filter/libfilter.la \
- $(NO_UNDEFINED_REQUIRED_LIBS) \
$(EVOLUTION_CALENDAR_LIBS) \
$(EVOLUTION_MAIL_LIBS) \
$(CAMEL_GROUPWISE_LIBS)
diff --git a/plugins/groupwise-features/install-shared.c b/plugins/groupwise-features/install-shared.c
index 6dcbfe8d22..a208116f0a 100644
--- a/plugins/groupwise-features/install-shared.c
+++ b/plugins/groupwise-features/install-shared.c
@@ -27,8 +27,6 @@
#include <string.h>
#include <glib.h>
#include <gtk/gtk.h>
-#include <libgnomeui/gnome-druid.h>
-#include <libgnomeui/gnome-druid-page-edge.h>
#include <glib/gi18n.h>
#include <gconf/gconf-client.h>
#include <e-util/e-config.h>
@@ -154,7 +152,7 @@ accept_free(gpointer data)
}
static void
-accept_clicked(GnomeDruidPage *page, GtkWidget *druid, CamelMimeMessage *msg)
+apply_clicked (GtkAssistant *assistant, CamelMimeMessage *msg)
{
EMFolderTreeModel *model;
EMFolderTree *folder_tree;
@@ -165,6 +163,7 @@ accept_clicked(GnomeDruidPage *page, GtkWidget *druid, CamelMimeMessage *msg)
accept_data = g_new0(struct AcceptData, 1);
model = mail_component_peek_tree_model (NULL);
folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
+
dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
uri = em_folder_tree_get_selected_uri(folder_tree);
em_folder_selector_set_selected ((EMFolderSelector *) dialog, uri);
@@ -174,11 +173,10 @@ accept_clicked(GnomeDruidPage *page, GtkWidget *druid, CamelMimeMessage *msg)
accept_data->model = model;
g_object_set_data_full((GObject *)dialog, "accept-data", accept_data, accept_free);
g_signal_connect (dialog, "response", G_CALLBACK (install_folder_response), accept_data);
- g_object_set_data_full((GObject *)dialog, "druid", druid, (GDestroyNotify)gtk_widget_destroy);
+ g_object_set_data_full((GObject *)dialog, "assistant", assistant, (GDestroyNotify)gtk_widget_destroy);
gtk_window_set_title (GTK_WINDOW (dialog), "Install Shared Folder");
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_widget_show (dialog);
-
}
void
@@ -188,8 +186,6 @@ org_gnome_popup_wizard (EPlugin *ep, EMEventTargetMessage *target)
const gchar *name;
const gchar *email;
GtkWidget *window;
- GnomeDruid *wizard;
- GnomeDruidPageEdge *title_page;
CamelMimeMessage *msg = (CamelMimeMessage *) target->message;
CamelStreamMem *content;
CamelDataWrapper *dw;
@@ -216,20 +212,36 @@ org_gnome_popup_wizard (EPlugin *ep, EMEventTargetMessage *target)
from_addr = camel_mime_message_get_from ((CamelMimeMessage *)target->message);
if (from_addr && camel_internet_address_get(from_addr, 0, &name, &email)) {
+ GtkWidget *page;
+ GtkAssistant *assistant = GTK_ASSISTANT (gtk_assistant_new ());
+
start_message = g_strdup_printf (_("The user '%s' has shared a folder with you\n\n"
"Message from '%s'\n\n\n"
"%s\n\n\n"
- "Click 'Forward' to install the shared folder\n\n"),
+ "Click 'Apply' to install the shared folder\n\n"),
name, name, content->buffer->data);
- title_page = GNOME_DRUID_PAGE_EDGE (gnome_druid_page_edge_new_with_vals(GNOME_EDGE_START, TRUE, _("Install the shared folder"), start_message, NULL, NULL, NULL));
- g_free(start_message);
- wizard = GNOME_DRUID (gnome_druid_new_with_window (_("Shared Folder Installation"), NULL, TRUE, (GtkWidget**)(&window)));
- gtk_window_set_position (GTK_WINDOW (window) , GTK_WIN_POS_CENTER_ALWAYS);
- gnome_druid_append_page(wizard, GNOME_DRUID_PAGE(title_page));
- gtk_widget_show_all (GTK_WIDGET (title_page));
- camel_object_ref(msg);
- g_object_set_data_full((GObject *)title_page, "msg", msg, camel_object_unref);
- g_signal_connect (title_page, "next", G_CALLBACK(accept_clicked), msg);
+
+ page = gtk_label_new (start_message);
+ gtk_label_set_line_wrap (GTK_LABEL (page), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (page), 0.0, 0.0);
+ gtk_misc_set_padding (GTK_MISC (page), 10, 10);
+
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_title (assistant, page, _("Install the shared folder"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
+ gtk_assistant_set_page_complete (assistant, page, TRUE);
+
+ gtk_window_set_title (GTK_WINDOW (assistant), _("Shared Folder Installation"));
+ gtk_window_set_position (GTK_WINDOW (assistant) , GTK_WIN_POS_CENTER_ALWAYS);
+
+ camel_object_ref (msg);
+ g_object_set_data_full((GObject *)page, "msg", msg, camel_object_unref);
+
+ g_signal_connect (assistant, "apply", G_CALLBACK (apply_clicked), msg);
+
+ gtk_widget_show_all (GTK_WIDGET (assistant));
+
+ g_free (start_message);
} else
g_warning ("Could not get the sender name");
diff --git a/plugins/groupwise-features/proxy-login.c b/plugins/groupwise-features/proxy-login.c
index b8fe49506b..123fc0641b 100644
--- a/plugins/groupwise-features/proxy-login.c
+++ b/plugins/groupwise-features/proxy-login.c
@@ -43,6 +43,7 @@
#include <e-util/e-error.h>
#include <e-util/e-icon-factory.h>
#include <e-util/e-util-private.h>
+#include <e-util/e-account-utils.h>
#include <e-gw-container.h>
#include <e-gw-connection.h>
@@ -303,7 +304,7 @@ proxy_login_cb (GtkDialog *dialog, gint state)
static void
proxy_soap_login (gchar *email)
{
- EAccountList *accounts = mail_config_get_accounts();
+ EAccountList *accounts = e_get_account_list ();
EAccount *srcAccount;
EAccount *dstAccount;
EGwConnection *proxy_cnc, *cnc;
diff --git a/plugins/groupwise-features/share-folder-common.c b/plugins/groupwise-features/share-folder-common.c
index c9e8ffb572..791a2da541 100644
--- a/plugins/groupwise-features/share-folder-common.c
+++ b/plugins/groupwise-features/share-folder-common.c
@@ -382,6 +382,7 @@ create_shared_folder(EPopup *ep, EPopupItem *p, gpointer data)
model = mail_component_peek_tree_model (mail_component_peek ());
folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
+
dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
uri = em_folder_tree_get_selected_uri(folder_tree);
em_folder_selector_set_selected ((EMFolderSelector *) dialog, uri);
diff --git a/plugins/hula-account-setup/hula-account-setup.c b/plugins/hula-account-setup/hula-account-setup.c
index 3f5898b724..34427f3b71 100644
--- a/plugins/hula-account-setup/hula-account-setup.c
+++ b/plugins/hula-account-setup/hula-account-setup.c
@@ -27,7 +27,7 @@
static CamelHulaListener *config_listener = NULL;
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
GtkWidget* org_gnome_evolution_hula_account_setup (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
static void
@@ -37,7 +37,7 @@ free_hula_listener ( void )
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
if (!config_listener) {
config_listener = camel_hula_listener_new ();
diff --git a/plugins/hula-account-setup/org-gnome-evolution-hula-account-setup.eplug.xml b/plugins/hula-account-setup/org-gnome-evolution-hula-account-setup.eplug.xml
index 68ae2fe8dd..e90ce650cb 100644
--- a/plugins/hula-account-setup/org-gnome-evolution-hula-account-setup.eplug.xml
+++ b/plugins/hula-account-setup/org-gnome-evolution-hula-account-setup.eplug.xml
@@ -6,7 +6,7 @@
<_description>Add Hula support to Evolution.</_description>
<hook class="org.gnome.evolution.mail.config:1.0">
- <group target="account" id="org.gnome.evolution.mail.config.accountDruid">
+ <group target="account" id="org.gnome.evolution.mail.config.accountAssistant">
<item type="item_table" path="20.receive_options/30.soapport/50.dummy" factory="org_gnome_evolution_hula_account_setup"/>
</group>
</hook>
diff --git a/plugins/imap-features/Makefile.am b/plugins/imap-features/Makefile.am
index c539a70cb2..d21841f7c7 100644
--- a/plugins/imap-features/Makefile.am
+++ b/plugins/imap-features/Makefile.am
@@ -18,9 +18,10 @@ plugin_LTLIBRARIES = liborg-gnome-imap-features.la
liborg_gnome_imap_features_la_SOURCES = \
imap-headers.c
-liborg_gnome_imap_features_la_LIBADD= \
- $(NO_UNDEFINED_REQUIRED_LIBS) \
- $(EVOLUTION_MAIL_LIBS)
+liborg_gnome_imap_features_la_LIBADD= \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(EVOLUTION_MAIL_LIBS)
liborg_gnome_imap_features_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
diff --git a/plugins/imap-features/imap-headers.c b/plugins/imap-features/imap-headers.c
index 0154074498..baa6ee43dc 100644
--- a/plugins/imap-features/imap-headers.c
+++ b/plugins/imap-features/imap-headers.c
@@ -31,8 +31,7 @@
#include <gtk/gtk.h>
-#include <libedataserver/e-account.h>
-#include <libedataserver/e-account-list.h>
+#include "e-util/e-account-utils.h"
#include <camel/camel-url.h>
#include <camel/camel-exception.h>
@@ -84,7 +83,7 @@ imap_headers_commit (EPlugin *efp, EConfigHookItemFactoryData *data)
if (g_str_has_prefix (account->source->url, "imap://") ||
(use_imap && g_str_has_prefix (account->source->url, "groupwise://"))) {
EAccount *temp = NULL;
- EAccountList *accounts = mail_config_get_accounts ();
+ EAccountList *accounts = e_get_account_list ();
CamelURL *url = NULL;
CamelException ex;
GtkTreeModel *model;
diff --git a/plugins/ipod-sync/Makefile.am b/plugins/ipod-sync/Makefile.am
index a55fc83a4e..74522a41a3 100644
--- a/plugins/ipod-sync/Makefile.am
+++ b/plugins/ipod-sync/Makefile.am
@@ -17,7 +17,7 @@ liborg_gnome_ipod_sync_evolution_la_SOURCES = \
format-handler.h \
evolution-ipod-sync.h
-liborg_gnome_ipod_sync_evolution_la_LDFLAGS = -module -avoid-version
+liborg_gnome_ipod_sync_evolution_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_ipod_sync_evolution_la_LIBADD = \
$(EVOLUTION_CALENDAR_LIBS)
diff --git a/plugins/itip-formatter/Makefile.am b/plugins/itip-formatter/Makefile.am
index 80b70cc6c9..5253742169 100644
--- a/plugins/itip-formatter/Makefile.am
+++ b/plugins/itip-formatter/Makefile.am
@@ -1,5 +1,6 @@
AM_CPPFLAGS = \
-I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
$(EVOLUTION_MAIL_CFLAGS) \
$(EVOLUTION_CALENDAR_CFLAGS)
diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c
index 89313dd995..94f9081ecd 100644
--- a/plugins/itip-formatter/itip-formatter.c
+++ b/plugins/itip-formatter/itip-formatter.c
@@ -46,7 +46,6 @@
#include <gtkhtml/gtkhtml-embedded.h>
#include <mail/em-format-hook.h>
#include <mail/em-config.h>
-#include <mail/em-format.h>
#include <mail/em-format-html.h>
#include <mail/em-utils.h>
#include <mail/mail-folder-cache.h>
@@ -57,6 +56,7 @@
#include <calendar/gui/calendar-config.h>
#include <calendar/gui/itip-utils.h>
#include <calendar/common/authentication.h>
+#include <shell/e-shell.h>
#include "itip-view.h"
#define CLASSID "itip://"
@@ -715,18 +715,27 @@ find_cal_opened_cb (ECal *ecal, ECalendarStatus status, gpointer data)
if ((pitip->method == ICAL_METHOD_PUBLISH || pitip->method == ICAL_METHOD_REQUEST)
&& !pitip->current_ecal) {
/* Reuse already declared one or rename? */
+ EShell *shell;
+ EShellSettings *shell_settings;
ESource *source = NULL;
gchar *uid;
+ /* FIXME Find a better way to obtain the shell. */
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
switch (pitip->type) {
case E_CAL_SOURCE_TYPE_EVENT:
- uid = calendar_config_get_primary_calendar ();
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-calendar");
break;
case E_CAL_SOURCE_TYPE_TODO:
- uid = calendar_config_get_primary_tasks ();
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-task-list");
break;
case E_CAL_SOURCE_TYPE_JOURNAL:
- uid = calendar_config_get_primary_memos ();
+ uid = e_shell_settings_get_string (
+ shell_settings, "cal-primary-memo-list");
break;
default:
uid = NULL;
diff --git a/plugins/mail-account-disable/ChangeLog b/plugins/mail-account-disable/ChangeLog
deleted file mode 100644
index 86dc9a4897..0000000000
--- a/plugins/mail-account-disable/ChangeLog
+++ /dev/null
@@ -1,62 +0,0 @@
-2008-10-03 Sankar P <psankar@novell.com>
-
-License Changes
-
- * mail-account-disable.c:
-
-2007-11-18 Gilles Dartiguelongue <gdartigu@svn.gnome.org>
-
- ** Fix bug #495875
-
- * mail-account-disable.c:
- right click menu reordering
-
-2007-04-02 Sankar P <psankar@novell.com>
-
- * Committed on behalf of Gilles Dartiguelongue <dartigug@esiee.fr>
-
- * org-gnome-mail-account-disable.eplug.xml:
- Cleanup.
- Fixes part of #301149
-
-2006-08-21 Matthew Barnes <mbarnes@redhat.com>
-
- * mail-account-disable.c:
- "Disable" did not work for "On This Computer" - fixes bug 350901.
-
-2006-01-06 Simon Zheng <simon.zheng@sun.com>
-
- * mail-account-disable.c:
- use libedataserver/e-account-list.h instead of e-util/e-account-list.h.
- use libedataserver/e-account.h instead of e-util/e-account.h.
-
-2005-12-12 Harish Krishnaswamy <kharish@novell.com>
-
- * Makefile.am: Fix make-clean issues.
-
-2005-08-23 Not Zed <NotZed@Ximian.com>
-
- * Makefile.am: Remove the special case for win32, its a bug on all
- platforms, silly.
-
- * mail-account-disable.c (mail_account_disable): make signature
- match usage.
-
-2005-07-13 Tor Lillqvist <tml@novell.com>
-
- * Makefile.am (INCLUDES): Remove duplicated line.
- (LDFLAGS): Use NO_UNDEFINED.
- (LIBADD): Link with the required libraries, but let's do it only
- on Win32.
-
- * org-gnome-mail-account-disable.eplug.xml: Use SOEXT.
-
-2005-07-12 Vivek Jain <jvivek@novell.com>
-
- have a ChangeLog and transfer the changelog entry from the main
- ChangeLog
- (2005-07-10 Shreyas Srinivasan <sshreyas@novell.com>)
-
- * plugins/mail-account-disable/*: Plugin to add Disable/ Proxy
- Logout to a store menu on right click.
-
diff --git a/plugins/mail-account-disable/Makefile.am b/plugins/mail-account-disable/Makefile.am
deleted file mode 100644
index 7793f851d7..0000000000
--- a/plugins/mail-account-disable/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/widgets \
- -I$(top_builddir)/mail \
- $(EVOLUTION_MAIL_CFLAGS) \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\"
-
-@EVO_PLUGIN_RULE@
-
-plugin_DATA = org-gnome-mail-account-disable.eplug
-plugin_LTLIBRARIES = libmail-account-disable.la
-
-libmail_account_disable_la_SOURCES = mail-account-disable.c
-libmail_account_disable_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
-libmail_account_disable_la_LIBADD = $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/mail/libevolution-mail.la \
- $(EVOLUTION_MAIL_LIBS)
-
-EXTRA_DIST = org-gnome-mail-account-disable.eplug.xml
-
-BUILT_SOURCES = $(plugin_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
--include $(top_srcdir)/git.mk
diff --git a/plugins/mail-account-disable/mail-account-disable.c b/plugins/mail-account-disable/mail-account-disable.c
deleted file mode 100644
index aee3043682..0000000000
--- a/plugins/mail-account-disable/mail-account-disable.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Shreyas Srinivasan <sshreyas@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <string.h>
-#include <mail/mail-component.h>
-#include <mail/em-folder-selector.h>
-#include <mail/em-popup.h>
-#include <mail/em-account-editor.h>
-#include <mail/mail-config.h>
-#include <libedataserver/e-account.h>
-#include <libedataserver/e-account-list.h>
-
-#define ACCOUNT_DISABLE 0
-#define PROXY_LOGOUT 1
-
-void mail_account_disable (EPopup *ep, EPopupItem *p, gpointer data);
-void org_gnome_create_mail_account_disable (EPlugin *ep, EMPopupTargetFolder *t);
-
-static EPopupItem popup_items[] = {
- { E_POPUP_ITEM, (gchar *) "40.emc.04", (gchar *) N_("_Disable"), mail_account_disable, NULL, NULL, 0, EM_POPUP_FOLDER_STORE },
- { E_POPUP_ITEM, (gchar *) "40.emc.04", (gchar *) N_("Proxy _Logout"), mail_account_disable, NULL, NULL, 0, EM_POPUP_FOLDER_STORE }
-};
-
-static void
-popup_free (EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free (items);
-}
-
-void
-mail_account_disable (EPopup *ep, EPopupItem *p, gpointer data)
-{
- MailComponent *component;
- EAccount *account = data;
-
- g_assert (account != NULL);
-
- component = mail_component_peek ();
-
- if (mail_config_has_proxies (account))
- mail_config_remove_account_proxies (account);
-
- account->enabled = !account->enabled;
- e_account_list_change (mail_config_get_accounts (), account);
- mail_component_remove_store_by_uri (component, account->source->url);
-
- if (account->parent_uid)
- mail_config_remove_account (account);
-
- mail_config_save_accounts();
-}
-
-void
-org_gnome_create_mail_account_disable (EPlugin *ep, EMPopupTargetFolder *t)
-{
- EAccount *account;
- GSList *menus = NULL;
-
- account = mail_config_get_account_by_source_url (t->uri);
-
- if (account == NULL)
- return;
-
- if (g_strrstr (t->uri,"groupwise://") && account->parent_uid) {
- popup_items[PROXY_LOGOUT].label = _(popup_items [PROXY_LOGOUT].label);
- menus = g_slist_prepend (menus, &popup_items [PROXY_LOGOUT]);
- }
- else {
- popup_items[ACCOUNT_DISABLE].label = _(popup_items [ACCOUNT_DISABLE].label);
- menus = g_slist_prepend (menus, &popup_items [ACCOUNT_DISABLE]);
- }
-
- e_popup_add_items (t->target.popup, menus, NULL, popup_free, account);
-}
-
diff --git a/plugins/mail-account-disable/org-gnome-mail-account-disable.eplug.xml b/plugins/mail-account-disable/org-gnome-mail-account-disable.eplug.xml
deleted file mode 100644
index 535a87a314..0000000000
--- a/plugins/mail-account-disable/org-gnome-mail-account-disable.eplug.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0"?>
-<e-plugin-list>
- <e-plugin
- id="org.gnome.mail.account.disable"
- type="shlib"
- domain="@GETTEXT_PACKAGE@"
- _name="Disable Account"
- location="@PLUGINDIR@/libmail-account-disable@SOEXT@">
- <_description>Disable an account by right-clicking on it in the folder tree.</_description>
- <author name="Shreyas Srinivasan" email="sshreyas@novell.com"/>
-
- <hook class="org.gnome.evolution.mail.popup:1.0">
- <menu id="org.gnome.evolution.mail.foldertree.popup" target="folder"
- factory="org_gnome_create_mail_account_disable">
- </menu>
- </hook>
- </e-plugin>
-</e-plugin-list>
diff --git a/plugins/mail-notification/Makefile.am b/plugins/mail-notification/Makefile.am
index 0915329b42..b53e6a55a6 100644
--- a/plugins/mail-notification/Makefile.am
+++ b/plugins/mail-notification/Makefile.am
@@ -9,7 +9,8 @@ AM_CPPFLAGS = \
-I$(top_srcdir) \
-I$(top_srcdir)/widgets \
$(EVOLUTION_MAIL_CFLAGS) \
- $(LIBNOTIFY_CFLAGS)
+ $(LIBNOTIFY_CFLAGS) \
+ $(CANBERRA_CFLAGS)
if DBUS_SUPPORT
AM_CPPFLAGS += -DDBUS_API_SUBJECT_TO_CHANGE=1 \
@@ -24,9 +25,12 @@ plugin_LTLIBRARIES = liborg-gnome-mail-notification.la
liborg_gnome_mail_notification_la_SOURCES = mail-notification.c
liborg_gnome_mail_notification_la_LDFLAGS = \
-module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_mail_notification_la_LIBADD = \
- $(LIBNOTIFY_LIBS) \
- $(NO_UNDEFINED_REQUIRED_LIBS)
+liborg_gnome_mail_notification_la_LIBADD = \
+ $(CANBERRA_LIBS) \
+ $(LIBNOTIFY_LIBS) \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(GNOME_PLATFORM_LIBS)
if DBUS_SUPPORT
liborg_gnome_mail_notification_la_LIBADD += $(DBUS_GLIB_LIBS)
diff --git a/plugins/mail-notification/apps-evolution-mail-notification.schemas.in b/plugins/mail-notification/apps-evolution-mail-notification.schemas.in
index c0a038068d..ad7dd91615 100644
--- a/plugins/mail-notification/apps-evolution-mail-notification.schemas.in
+++ b/plugins/mail-notification/apps-evolution-mail-notification.schemas.in
@@ -91,6 +91,17 @@
<long>Sound file to be played when new messages arrive, if not in beep mode.</long>
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/evolution/eplugin/mail-notification/sound-use-theme</key>
+ <applyto>/apps/evolution/eplugin/mail-notification/sound-use-theme</applyto>
+ <owner>evolution-mail</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Use sound theme</short>
+ <long>Play themed sound when new messages arrive, if not in beep mode.</long>
+ </locale>
+ </schema>
</schemalist>
</gconfschemafile>
diff --git a/plugins/mail-notification/mail-notification.c b/plugins/mail-notification/mail-notification.c
index c42473acc7..f6272ba873 100644
--- a/plugins/mail-notification/mail-notification.c
+++ b/plugins/mail-notification/mail-notification.c
@@ -29,7 +29,7 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gconf/gconf-client.h>
-#include <libgnome/gnome-sound.h>
+#include <canberra-gtk.h>
#ifdef HAVE_DBUS
#include <dbus/dbus-glib.h>
@@ -38,7 +38,9 @@
#include <time.h>
+#include "e-util/e-binding.h"
#include "e-util/e-config.h"
+#include "e-util/gconf-bridge.h"
#include "mail/em-utils.h"
#include "mail/em-event.h"
#include "mail/em-folder-tree-model.h"
@@ -84,7 +86,7 @@ static GStaticMutex mlock = G_STATIC_MUTEX_INIT;
static gboolean
is_part_enabled (const gchar *gconf_key)
{
- /* the part is enabled by defaul */
+ /* the part is enabled by default */
gboolean res = TRUE;
GConfClient *client;
GConfValue *is_key;
@@ -102,17 +104,6 @@ is_part_enabled (const gchar *gconf_key)
return res;
}
-static void
-set_part_enabled (const gchar *gconf_key, gboolean enable)
-{
- GConfClient *client;
-
- client = gconf_client_get_default ();
-
- gconf_client_set_bool (client, gconf_key, enable, NULL);
- g_object_unref (client);
-}
-
/* ------------------------------------------------------------------- */
/* DBUS part */
/* ------------------------------------------------------------------- */
@@ -201,14 +192,6 @@ init_dbus (void)
return TRUE;
}
-static void
-toggled_dbus_cb (GtkWidget *widget, gpointer data)
-{
- g_return_if_fail (widget != NULL);
-
- set_part_enabled (GCONF_KEY_ENABLED_DBUS, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
-}
-
/* ------------------------------------------------------------------- */
static void
@@ -236,21 +219,6 @@ enable_dbus (gint enable)
bus = NULL;
}
}
-
-static GtkWidget *
-get_config_widget_dbus (void)
-{
- GtkWidget *w;
-
- w = gtk_check_button_new_with_mnemonic (_("Generate a _D-Bus message"));
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), is_part_enabled (GCONF_KEY_ENABLED_DBUS));
- g_signal_connect (G_OBJECT (w), "toggled", G_CALLBACK (toggled_dbus_cb), NULL);
- gtk_widget_show (w);
-
- return w;
-}
-
#endif
/* ------------------------------------------------------------------- */
@@ -276,12 +244,12 @@ icon_activated (GtkStatusIcon *icon, NotifyNotification *pnotify)
icon_activated (GtkStatusIcon *icon, gpointer pnotify)
#endif
{
- #ifdef HAVE_LIBNOTIFY
+#ifdef HAVE_LIBNOTIFY
if (notify)
notify_notification_close (notify, NULL);
notify = NULL;
- #endif
+#endif
gtk_status_icon_set_visible (status_icon, FALSE);
g_object_unref (status_icon);
@@ -314,45 +282,6 @@ stop_blinking_cb (gpointer data)
return FALSE;
}
-struct _StatusConfigureWidgets
-{
- GtkWidget *enable;
- GtkWidget *blink;
- #ifdef HAVE_LIBNOTIFY
- GtkWidget *message;
- #endif
-};
-
-static void
-toggled_status_cb (GtkWidget *widget, gpointer data)
-{
- struct _StatusConfigureWidgets *scw = (struct _StatusConfigureWidgets *) data;
- gboolean enabl;
-
- g_return_if_fail (scw != NULL);
- g_return_if_fail (scw->enable != NULL);
- g_return_if_fail (scw->blink != NULL);
- #ifdef HAVE_LIBNOTIFY
- g_return_if_fail (scw->message != NULL);
- #endif
-
- enabl = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->enable));
- if (widget == scw->enable)
- set_part_enabled (GCONF_KEY_ENABLED_STATUS, enabl);
-
- #define work_widget(w, key) \
- gtk_widget_set_sensitive (w, enabl); \
- if (widget == w) \
- set_part_enabled (key, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
-
- work_widget (scw->blink, GCONF_KEY_STATUS_BLINK);
- #ifdef HAVE_LIBNOTIFY
- work_widget (scw->message, GCONF_KEY_STATUS_NOTIFICATION);
- #endif
-
- #undef work_widget
-}
-
/* ------------------------------------------------------------------- */
static void
@@ -409,11 +338,11 @@ popup_menu_status (GtkStatusIcon *status_icon, guint button, guint activate_time
menu = GTK_MENU (gtk_menu_new ());
item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLOSE, NULL);
- #ifdef HAVE_LIBNOTIFY
+#ifdef HAVE_LIBNOTIFY
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (icon_activated), notify);
- #else
+#else
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (icon_activated), NULL);
- #endif
+#endif
gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
@@ -513,7 +442,7 @@ new_notify_status (EMEventTargetFolder *t)
gtk_status_icon_set_visible (status_icon, TRUE);
- #ifdef HAVE_LIBNOTIFY
+#ifdef HAVE_LIBNOTIFY
/* Now check whether we're supposed to send notifications */
if (is_part_enabled (GCONF_KEY_STATUS_NOTIFICATION)) {
if (notify) {
@@ -534,16 +463,16 @@ new_notify_status (EMEventTargetFolder *t)
}
}
}
- #endif
+#endif
g_free (msg);
if (new_icon) {
- #ifdef HAVE_LIBNOTIFY
+#ifdef HAVE_LIBNOTIFY
g_signal_connect (G_OBJECT (status_icon), "activate", G_CALLBACK (icon_activated), notify);
- #else
+#else
g_signal_connect (G_OBJECT (status_icon), "activate", G_CALLBACK (icon_activated), NULL);
- #endif
+#endif
g_signal_connect (G_OBJECT (status_icon), "popup-menu", G_CALLBACK (popup_menu_status), NULL);
}
@@ -555,56 +484,77 @@ read_notify_status (EMEventTargetMessage *t)
if (!status_icon)
return;
- #ifdef HAVE_LIBNOTIFY
+#ifdef HAVE_LIBNOTIFY
icon_activated (status_icon, notify);
- #else
+#else
icon_activated (status_icon, NULL);
- #endif
-}
-
-static void
-enable_status (gint enable)
-{
- /* this does nothing on enable, it's here just to be
- consistent with other parts of this plugin */
+#endif
}
static GtkWidget *
get_config_widget_status (void)
{
- GtkWidget *vbox, *parent, *alignment;
- struct _StatusConfigureWidgets *scw;
+ GtkWidget *vbox;
+ GtkWidget *master;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GConfBridge *bridge;
+ const gchar *text;
- vbox = gtk_vbox_new (FALSE, 0);
- scw = g_malloc0 (sizeof (struct _StatusConfigureWidgets));
+ bridge = gconf_bridge_get ();
- #define create_check(c, key, desc) \
- c = gtk_check_button_new_with_mnemonic (desc); \
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c), is_part_enabled (key)); \
- gtk_box_pack_start (GTK_BOX (parent), c, FALSE, FALSE, 0); \
- g_signal_connect (G_OBJECT (c), "toggled", G_CALLBACK (toggled_status_cb), scw);
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
- parent = vbox;
- create_check (scw->enable, GCONF_KEY_ENABLED_STATUS, _("Show icon in _notification area"));
+ container = vbox;
- parent = gtk_vbox_new (FALSE, 0);
- create_check (scw->blink, GCONF_KEY_STATUS_BLINK, _("B_link icon in notification area"));
- #ifdef HAVE_LIBNOTIFY
- create_check (scw->message, GCONF_KEY_STATUS_NOTIFICATION, _("Popup _message together with the icon"));
- #endif
+ text = _("Show icon in _notification area");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
- alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 20, 0);
- gtk_container_add (GTK_CONTAINER (alignment), parent);
- gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_ENABLED_STATUS,
+ G_OBJECT (widget), "active");
- #undef create_check
+ master = widget;
- /* to let structure free properly */
- g_object_set_data_full (G_OBJECT (vbox), "scw-data", scw, g_free);
+ widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 12, 0);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (master), "active",
+ G_OBJECT (widget), "sensitive");
+
+ container = widget;
+
+ widget = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
- toggled_status_cb (NULL, scw);
- gtk_widget_show_all (vbox);
+ container = widget;
+
+ text = _("B_link icon in notification area");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_STATUS_BLINK,
+ G_OBJECT (widget), "active");
+
+#ifdef HAVE_LIBNOTIFY
+ text = _("Popup _message together with the icon");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_STATUS_NOTIFICATION,
+ G_OBJECT (widget), "active");
+#endif
return vbox;
}
@@ -618,57 +568,39 @@ get_config_widget_status (void)
#define GCONF_KEY_SOUND_BEEP GCONF_KEY_ROOT "sound-beep"
#define GCONF_KEY_SOUND_FILE GCONF_KEY_ROOT "sound-file"
+#define GCONF_KEY_SOUND_PLAY_FILE GCONF_KEY_ROOT "sound-play-file"
+#define GCONF_KEY_SOUND_USE_THEME GCONF_KEY_ROOT "sound-use-theme"
+
+static ca_context *mailnotification = NULL;
static void
-do_play_sound (gboolean beep, const gchar *file)
-{
- if (beep)
- gdk_beep ();
- else if (!file || !*file)
- g_warning ("No file to play!");
+do_play_sound (gboolean beep, gboolean use_theme, const gchar *file)
+{
+ if (!beep) {
+ if ( (file || *file) && !use_theme )
+ ca_context_play(mailnotification, 0,
+ CA_PROP_MEDIA_FILENAME, file,
+ NULL);
+ else
+ ca_context_play(mailnotification, 0,
+ CA_PROP_EVENT_ID,"message-new-email",
+ NULL);
+ }
else
- gnome_sound_play (file);
+ gdk_beep();
}
struct _SoundConfigureWidgets
{
GtkWidget *enable;
GtkWidget *beep;
+ GtkWidget *use_theme;
GtkWidget *file;
- GtkWidget *label;
GtkWidget *filechooser;
GtkWidget *play;
};
static void
-toggled_sound_cb (GtkWidget *widget, gpointer data)
-{
- struct _SoundConfigureWidgets *scw = (struct _SoundConfigureWidgets *) data;
- gboolean enabl;
-
- g_return_if_fail (data != NULL);
- g_return_if_fail (scw->enable != NULL);
- g_return_if_fail (scw->beep != NULL);
- g_return_if_fail (scw->file != NULL);
- g_return_if_fail (scw->label != NULL);
- g_return_if_fail (scw->filechooser != NULL);
- g_return_if_fail (scw->play != NULL);
-
- enabl = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->enable));
- if (widget == scw->enable)
- set_part_enabled (GCONF_KEY_ENABLED_SOUND, enabl);
-
- gtk_widget_set_sensitive (scw->beep, enabl);
- gtk_widget_set_sensitive (scw->file, enabl);
- gtk_widget_set_sensitive (scw->label, enabl);
- gtk_widget_set_sensitive (scw->filechooser, enabl && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->file)));
- gtk_widget_set_sensitive (scw->play, enabl);
-
- if (widget == scw->beep || widget == scw->file)
- set_part_enabled (GCONF_KEY_SOUND_BEEP, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->beep)));
-}
-
-static void
sound_file_set_cb (GtkWidget *widget, gpointer data)
{
gchar *file;
@@ -697,7 +629,9 @@ sound_play_cb (GtkWidget *widget, gpointer data)
return;
file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (scw->filechooser));
- do_play_sound (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->beep)), file);
+ do_play_sound (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (scw->beep)),
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (scw->use_theme)),
+ file);
g_free (file);
}
@@ -718,7 +652,9 @@ sound_notify_idle_cb (gpointer user_data)
client = gconf_client_get_default ();
file = gconf_client_get_string (client, GCONF_KEY_SOUND_FILE, NULL);
- do_play_sound (is_part_enabled (GCONF_KEY_SOUND_BEEP), file);
+ do_play_sound (is_part_enabled (GCONF_KEY_SOUND_BEEP),
+ is_part_enabled (GCONF_KEY_SOUND_USE_THEME),
+ file);
g_object_unref (client);
g_free (file);
@@ -754,47 +690,129 @@ read_notify_sound (EMEventTargetMessage *t)
static void
enable_sound (gint enable)
{
- if (enable)
- gnome_sound_init ("localhost");
+ if (enable) {
+ ca_context_create(&mailnotification);
+ ca_context_change_props(
+ mailnotification,
+ CA_PROP_APPLICATION_NAME,
+ "mailnotification Plugin",
+ NULL);
+ }
else
- gnome_sound_shutdown ();
+ ca_context_destroy(mailnotification);
}
static GtkWidget *
get_config_widget_sound (void)
{
- GtkWidget *vbox, *alignment, *parent, *hbox;
+ GtkWidget *vbox;
+ GtkWidget *container;
+ GtkWidget *master;
+ GtkWidget *widget;
gchar *file;
+ GConfBridge *bridge;
GConfClient *client;
+ GSList *group = NULL;
struct _SoundConfigureWidgets *scw;
+ const gchar *text;
+
+ bridge = gconf_bridge_get ();
- vbox = gtk_vbox_new (FALSE, 0);
scw = g_malloc0 (sizeof (struct _SoundConfigureWidgets));
- scw->enable = gtk_check_button_new_with_mnemonic (_("_Play sound when new messages arrive"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scw->enable), is_part_enabled (GCONF_KEY_ENABLED_SOUND));
- gtk_box_pack_start (GTK_BOX (vbox), scw->enable, FALSE, FALSE, 0);
- g_signal_connect (G_OBJECT (scw->enable), "toggled", G_CALLBACK (toggled_sound_cb), scw);
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
+
+ container = vbox;
- parent = gtk_vbox_new (FALSE, 0);
- scw->beep = gtk_radio_button_new_with_mnemonic (NULL, _("_Beep"));
- scw->file = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (scw->beep), _("Play _sound file"));
+ text = _("_Play sound when new messages arrive");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
- if (is_part_enabled (GCONF_KEY_SOUND_BEEP))
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scw->beep), TRUE);
- else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scw->file), TRUE);
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_ENABLED_SOUND,
+ G_OBJECT (widget), "active");
+
+ master = widget;
+ scw->enable = widget;
+
+ widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 12, 0);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (master), "active",
+ G_OBJECT (widget), "sensitive");
+
+ container = widget;
+
+ widget = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("_Beep");
+ widget = gtk_radio_button_new_with_mnemonic (group, text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_SOUND_BEEP,
+ G_OBJECT (widget), "active");
- g_signal_connect (G_OBJECT (scw->beep), "toggled", G_CALLBACK (toggled_sound_cb), scw);
- g_signal_connect (G_OBJECT (scw->file), "toggled", G_CALLBACK (toggled_sound_cb), scw);
+ scw->beep = widget;
- hbox = gtk_hbox_new (FALSE, 0);
- scw->label = gtk_label_new_with_mnemonic (_("Specify _filename:"));
- scw->filechooser = gtk_file_chooser_button_new (_("Select sound file"), GTK_FILE_CHOOSER_ACTION_OPEN);
- scw->play = gtk_button_new_with_mnemonic (_("Pl_ay"));
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
- gtk_label_set_mnemonic_widget (GTK_LABEL (scw->label), scw->filechooser);
- gtk_button_set_image (GTK_BUTTON (scw->play), gtk_image_new_from_icon_name ("media-playback-start", GTK_ICON_SIZE_BUTTON));
+ text = _("Use sound _theme");
+ widget = gtk_radio_button_new_with_mnemonic (group, text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_SOUND_USE_THEME,
+ G_OBJECT (widget), "active");
+
+ scw->use_theme = widget;
+
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+
+ widget = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Play _file:");
+ widget = gtk_radio_button_new_with_mnemonic (group, text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_SOUND_PLAY_FILE,
+ G_OBJECT (widget), "active");
+
+ scw->file = widget;
+
+ text = _("Select sound file");
+ widget = gtk_file_chooser_button_new (
+ text, GTK_FILE_CHOOSER_ACTION_OPEN);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ scw->filechooser = widget;
+
+ widget = gtk_button_new ();
+ gtk_button_set_image (
+ GTK_BUTTON (widget), gtk_image_new_from_icon_name (
+ "media-playback-start", GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ scw->play = widget;
client = gconf_client_get_default ();
file = gconf_client_get_string (client, GCONF_KEY_SOUND_FILE, NULL);
@@ -805,28 +823,16 @@ get_config_widget_sound (void)
g_object_unref (client);
g_free (file);
- g_signal_connect (G_OBJECT (scw->filechooser), "file-set", G_CALLBACK (sound_file_set_cb), scw);
- g_signal_connect (G_OBJECT (scw->play), "clicked", G_CALLBACK (sound_play_cb), scw);
-
- gtk_box_pack_start (GTK_BOX (hbox), scw->label, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), scw->filechooser, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), scw->play, FALSE, FALSE, 0);
-
- gtk_box_pack_start (GTK_BOX (parent), scw->beep, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (parent), scw->file, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (parent), hbox, FALSE, FALSE, 0);
-
- alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 20, 0);
- gtk_container_add (GTK_CONTAINER (alignment), parent);
- gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
+ g_signal_connect (
+ scw->filechooser, "file-set",
+ G_CALLBACK (sound_file_set_cb), scw);
+ g_signal_connect (
+ scw->play, "clicked",
+ G_CALLBACK (sound_play_cb), scw);
/* to let structure free properly */
g_object_set_data_full (G_OBJECT (vbox), "scw-data", scw, g_free);
- toggled_sound_cb (NULL, scw);
- gtk_widget_show_all (vbox);
-
return vbox;
}
@@ -834,49 +840,54 @@ get_config_widget_sound (void)
/* Plugin itself part */
/* ------------------------------------------------------------------- */
-static void
-toggled_only_inbox_cb (GtkWidget *widget, gpointer data)
-{
- g_return_if_fail (widget != NULL);
-
- set_part_enabled (GCONF_KEY_NOTIFY_ONLY_INBOX, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
-}
-
static GtkWidget *
get_cfg_widget (void)
{
- GtkWidget *cfg, *vbox, *check;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GConfBridge *bridge;
+ const gchar *text;
- vbox = gtk_vbox_new (FALSE, 6);
- check = gtk_check_button_new_with_mnemonic (_("Notify new messages for _Inbox only"));
+ bridge = gconf_bridge_get ();
+
+ widget = gtk_vbox_new (FALSE, 12);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Notify new messages for _Inbox only");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), is_part_enabled (GCONF_KEY_NOTIFY_ONLY_INBOX));
- g_signal_connect (G_OBJECT (check), "toggled", G_CALLBACK (toggled_only_inbox_cb), NULL);
- gtk_widget_show (check);
- gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_NOTIFY_ONLY_INBOX,
+ G_OBJECT (widget), "active");
#ifdef HAVE_DBUS
- cfg = get_config_widget_dbus ();
- if (cfg)
- gtk_box_pack_start (GTK_BOX (vbox), cfg, FALSE, FALSE, 0);
+ text = _("Generate a _D-Bus message");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ gconf_bridge_bind_property (
+ bridge, GCONF_KEY_ENABLED_DBUS,
+ G_OBJECT (widget), "active");
#endif
- cfg = get_config_widget_status ();
- if (cfg)
- gtk_box_pack_start (GTK_BOX (vbox), cfg, FALSE, FALSE, 0);
- cfg = get_config_widget_sound ();
- if (cfg)
- gtk_box_pack_start (GTK_BOX (vbox), cfg, FALSE, FALSE, 0);
+ widget = get_config_widget_status ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- gtk_widget_show (vbox);
+ widget = get_config_widget_sound ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- return vbox;
+ return container;
}
void org_gnome_mail_new_notify (EPlugin *ep, EMEventTargetFolder *t);
void org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t);
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl);
void
@@ -926,16 +937,13 @@ org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t)
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
if (enable) {
#ifdef HAVE_DBUS
if (is_part_enabled (GCONF_KEY_ENABLED_DBUS))
enable_dbus (enable);
#endif
- if (is_part_enabled (GCONF_KEY_ENABLED_STATUS))
- enable_status (enable);
-
if (is_part_enabled (GCONF_KEY_ENABLED_SOUND))
enable_sound (enable);
@@ -944,7 +952,6 @@ e_plugin_lib_enable (EPluginLib *ep, gint enable)
#ifdef HAVE_DBUS
enable_dbus (enable);
#endif
- enable_status (enable);
enable_sound (enable);
enabled = FALSE;
diff --git a/plugins/mail-to-task/Makefile.am b/plugins/mail-to-task/Makefile.am
index dc63da7a8c..0815e65dda 100644
--- a/plugins/mail-to-task/Makefile.am
+++ b/plugins/mail-to-task/Makefile.am
@@ -6,20 +6,20 @@ AM_CPPFLAGS = \
@EVO_PLUGIN_RULE@
-plugin_DATA = org-gnome-mail-to-task.eplug org-gnome-mail-to-task.xml
+plugin_DATA = org-gnome-mail-to-task.eplug
plugin_LTLIBRARIES = liborg-gnome-mail-to-task.la
liborg_gnome_mail_to_task_la_SOURCES = mail-to-task.c
liborg_gnome_mail_to_task_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_mail_to_task_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/calendar/gui/libevolution-calendar.la \
$(top_builddir)/calendar/common/libevolution-calendarprivate.la \
$(top_builddir)/mail/libevolution-mail.la \
$(EVOLUTION_CALENDAR_LIBS) \
$(EVOLUTION_MAIL_LIBS)
-EXTRA_DIST = org-gnome-mail-to-task.eplug.xml \
- org-gnome-mail-to-task.xml
+EXTRA_DIST = org-gnome-mail-to-task.eplug.xml
BUILT_SOURCES = org-gnome-mail-to-task.eplug
CLEANFILES = $(BUILT_SOURCES)
diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c
index 94b629eae2..1b8ad64768 100644
--- a/plugins/mail-to-task/mail-to-task.c
+++ b/plugins/mail-to-task/mail-to-task.c
@@ -32,10 +32,12 @@
#include <string.h>
#include <stdio.h>
+#include <gtkhtml/gtkhtml.h>
#include <gconf/gconf-client.h>
#include <libecal/e-cal.h>
#include <libedataserver/e-account.h>
#include <libedataserverui/e-source-selector-dialog.h>
+
#include <camel/camel-folder.h>
#include <camel/camel-medium.h>
#include <camel/camel-mime-message.h>
@@ -43,17 +45,30 @@
#include <camel/camel-stream.h>
#include <camel/camel-stream-mem.h>
#include <camel/camel-utf8.h>
-#include "mail/em-menu.h"
-#include "mail/em-popup.h"
-#include "mail/em-utils.h"
-#include "mail/em-folder-view.h"
-#include "mail/em-format-html.h"
-#include "mail/mail-config.h"
-#include "e-util/e-dialog-utils.h"
-#include <gtkhtml/gtkhtml.h>
+
+#include <mail/em-utils.h>
+#include <mail/em-format-html.h>
+#include <mail/mail-config.h>
+#include <e-util/e-account-utils.h>
+#include <e-util/e-dialog-utils.h>
#include <calendar/common/authentication.h>
+#include <misc/e-popup-action.h>
+#include <shell/e-shell-view.h>
+#include <shell/e-shell-window-actions.h>
#include <calendar/gui/cal-editor-utils.h>
+#define E_SHELL_WINDOW_ACTION_CONVERT_TO_EVENT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-convert-to-event")
+#define E_SHELL_WINDOW_ACTION_CONVERT_TO_MEETING(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-convert-to-meeting")
+#define E_SHELL_WINDOW_ACTION_CONVERT_TO_MEMO(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-convert-to-memo")
+#define E_SHELL_WINDOW_ACTION_CONVERT_TO_TASK(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-convert-to-task")
+
+gboolean e_plugin_ui_init (GtkUIManager *ui_manager,
+ EShellView *shell_view);
+
static gchar *
clean_name(const guchar *s)
{
@@ -215,7 +230,7 @@ set_organizer (ECalComponent *comp)
ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
gchar *res;
- account = mail_config_get_default_account ();
+ account = e_get_default_account ();
if (!account)
return NULL;
@@ -522,7 +537,13 @@ do_manage_comp_idle (GSList *manage_comp_datas)
}
if (edit_comp) {
- open_component_editor (mc->client, edit_comp, edit_comp == mc->comp, &error);
+ EShell *shell;
+
+ /* FIXME Pass in the EShell instance. */
+ shell = e_shell_get_default ();
+ open_component_editor (
+ shell, mc->client, edit_comp,
+ edit_comp == mc->comp, &error);
if (edit_comp != mc->comp)
g_object_unref (edit_comp);
}
@@ -742,12 +763,6 @@ do_mail_to_event (AsyncData *data)
return TRUE;
}
-static void
-copy_uids (gchar *uid, GPtrArray *uid_array)
-{
- g_ptr_array_add (uid_array, g_strdup (uid));
-}
-
static gboolean
text_contains_nonwhitespace (const gchar *text, gint len)
{
@@ -775,47 +790,51 @@ text_contains_nonwhitespace (const gchar *text, gint len)
/* should be freed with g_free after done with it */
static gchar *
-get_selected_text (EMFolderView *emfv)
+get_selected_text (EMailReader *reader)
{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
gchar *text = NULL;
gint len;
- if (!emfv || !emfv->preview || !gtk_html_command (((EMFormatHTML *)emfv->preview)->html, "is-selection-active"))
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ if (!gtk_html_command (html, "is-selection-active"))
return NULL;
- if (gtk_html_command (((EMFormatHTML *)emfv->preview)->html, "is-selection-active")
- && (text = gtk_html_get_selection_plain_text (((EMFormatHTML *)emfv->preview)->html, &len))
- && len && text && text[0] && text_contains_nonwhitespace (text, len)) {
- /* selection is ok, so use it as returned from gtkhtml widget */
- } else {
+ text = gtk_html_get_selection_plain_text (html, &len);
+
+ if (text == NULL || !text_contains_nonwhitespace (text, len)) {
g_free (text);
- text = NULL;
+ return NULL;
}
return text;
}
static void
-mail_to_event (ECalSourceType source_type, gboolean with_attendees, GPtrArray *uids, CamelFolder *folder, EMFolderView *emfv)
+mail_to_event (ECalSourceType source_type,
+ gboolean with_attendees,
+ EShellView *shell_view)
{
- GPtrArray *uid_array = NULL;
+ EShellContent *shell_content;
+ EMailReader *reader;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *selected;
ESourceList *source_list = NULL;
gboolean done = FALSE;
GSList *groups, *p;
ESource *source = NULL;
GError *error = NULL;
- g_return_if_fail (uids != NULL);
- g_return_if_fail (folder != NULL);
- g_return_if_fail (emfv != NULL);
+ shell_content = e_shell_view_get_shell_content (shell_view);
- if (uids->len > 0) {
- uid_array = g_ptr_array_new ();
- g_ptr_array_foreach (uids, (GFunc)copy_uids, (gpointer) uid_array);
- } else {
- /* nothing selected */
- return;
- }
+ reader = E_MAIL_READER (shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+ selected = message_list_get_selected (message_list);
+ folder = message_list->folder;
if (!e_cal_get_sources (&source_list, source_type, &error)) {
e_notice (NULL, GTK_MESSAGE_ERROR, _("Cannot get source list. %s"), error ? error->message : _("Unknown error."));
@@ -883,11 +902,11 @@ mail_to_event (ECalSourceType source_type, gboolean with_attendees, GPtrArray *u
data = g_new0 (AsyncData, 1);
data->client = client;
data->folder = folder;
- data->uids = uid_array;
+ data->uids = selected;
data->with_attendees = with_attendees;
- if (uid_array->len == 1)
- data->selected_text = get_selected_text (emfv);
+ if (selected->len == 1)
+ data->selected_text = get_selected_text (reader);
else
data->selected_text = NULL;
@@ -901,72 +920,138 @@ mail_to_event (ECalSourceType source_type, gboolean with_attendees, GPtrArray *u
g_object_unref (source_list);
}
-/* ************************************************************************* */
-
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
-void org_gnome_mail_to_event (gpointer ep, EMPopupTargetSelect *t);
-void org_gnome_mail_to_event_menu (EPlugin *ep, EMMenuTargetSelect *t);
-void org_gnome_mail_to_meeting (gpointer ep, EMPopupTargetSelect *t);
-void org_gnome_mail_to_meeting_menu (EPlugin *ep, EMMenuTargetSelect *t);
-void org_gnome_mail_to_task (gpointer ep, EMPopupTargetSelect *t);
-void org_gnome_mail_to_task_menu (EPlugin *ep, EMMenuTargetSelect *t);
-void org_gnome_mail_to_memo (gpointer ep, EMPopupTargetSelect *t);
-void org_gnome_mail_to_memo_menu (EPlugin *ep, EMMenuTargetSelect *t);
-
-gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+static void
+action_mail_convert_to_event_cb (GtkAction *action,
+ EShellView *shell_view)
{
- return 0;
+ mail_to_event (E_CAL_SOURCE_TYPE_EVENT, FALSE, shell_view);
}
-void
-org_gnome_mail_to_event (gpointer ep, EMPopupTargetSelect *t)
+static void
+action_mail_convert_to_meeting_cb (GtkAction *action,
+ EShellView *shell_view)
{
- mail_to_event (E_CAL_SOURCE_TYPE_EVENT, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+ mail_to_event (E_CAL_SOURCE_TYPE_EVENT, TRUE, shell_view);
}
-void
-org_gnome_mail_to_event_menu (EPlugin *ep, EMMenuTargetSelect *t)
+static void
+action_mail_convert_to_memo_cb (GtkAction *action,
+ EShellView *shell_view)
{
- mail_to_event (E_CAL_SOURCE_TYPE_EVENT, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+ mail_to_event (E_CAL_SOURCE_TYPE_JOURNAL, FALSE, shell_view);
}
-void
-org_gnome_mail_to_meeting (gpointer ep, EMPopupTargetSelect *t)
+static void
+action_mail_convert_to_task_cb (GtkAction *action,
+ EShellView *shell_view)
{
- mail_to_event (E_CAL_SOURCE_TYPE_EVENT, TRUE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+ mail_to_event (E_CAL_SOURCE_TYPE_TODO, FALSE, shell_view);
}
-void
-org_gnome_mail_to_meeting_menu (EPlugin *ep, EMMenuTargetSelect *t)
-{
- mail_to_event (E_CAL_SOURCE_TYPE_EVENT, TRUE, t->uids, t->folder, (EMFolderView *) t->target.widget);
-}
+static GtkActionEntry entries[] = {
+
+ { "mail-convert-to-event",
+ "appointment-new",
+ N_("Create an _Event"),
+ NULL,
+ N_("Create a new event from the selected message"),
+ G_CALLBACK (action_mail_convert_to_event_cb) },
+
+ { "mail-convert-to-meeting",
+ "stock_new-meeting",
+ N_("Create a _Meeting"),
+ NULL,
+ N_("Create a new meeting from the selected message"),
+ G_CALLBACK (action_mail_convert_to_meeting_cb) },
+
+ { "mail-convert-to-memo",
+ "stock_insert-note",
+ N_("Create a Mem_o"),
+ NULL,
+ N_("Create a new memo from the selected message"),
+ G_CALLBACK (action_mail_convert_to_memo_cb) },
+
+ { "mail-convert-to-task",
+ "stock_todo",
+ N_("Create a _Task"),
+ NULL,
+ N_("Create a new task from the selected message"),
+ G_CALLBACK (action_mail_convert_to_task_cb) }
+};
-void
-org_gnome_mail_to_task (gpointer ep, EMPopupTargetSelect *t)
-{
- /* do not create assigned tasks */
- mail_to_event (E_CAL_SOURCE_TYPE_TODO, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
-}
+static EPopupActionEntry popup_entries[] = {
-void
-org_gnome_mail_to_task_menu (EPlugin *ep, EMMenuTargetSelect *t)
-{
- /* do not create assigned tasks */
- mail_to_event (E_CAL_SOURCE_TYPE_TODO, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
-}
+ { "mail-popup-convert-to-event",
+ NULL,
+ "mail-convert-to-event" },
+
+ { "mail-popup-convert-to-meeting",
+ NULL,
+ "mail-convert-to-meeting" },
-void
-org_gnome_mail_to_memo (gpointer ep, EMPopupTargetSelect *t)
+ { "mail-popup-convert-to-memo",
+ NULL,
+ "mail-convert-to-memo" },
+
+ { "mail-popup-convert-to-task",
+ NULL,
+ "mail-convert-to-task" }
+};
+
+static void
+update_actions_cb (EShellView *shell_view)
{
- /* do not set organizer and attendees for memos */
- mail_to_event (E_CAL_SOURCE_TYPE_JOURNAL, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ GtkAction *action;
+ gboolean sensitive;
+ guint32 state;
+
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ state = e_mail_reader_check_state (E_MAIL_READER (shell_content));
+
+ sensitive =
+ (state & E_MAIL_READER_SELECTION_SINGLE) ||
+ (state & E_MAIL_READER_SELECTION_MULTIPLE);
+
+ action = E_SHELL_WINDOW_ACTION_CONVERT_TO_EVENT (shell_window);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = E_SHELL_WINDOW_ACTION_CONVERT_TO_MEMO (shell_window);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action = E_SHELL_WINDOW_ACTION_CONVERT_TO_TASK (shell_window);
+ gtk_action_set_sensitive (action, sensitive);
+
+ sensitive = (state & E_MAIL_READER_SELECTION_SINGLE);
+
+ action = E_SHELL_WINDOW_ACTION_CONVERT_TO_MEETING (shell_window);
+ gtk_action_set_sensitive (action, sensitive);
+
}
-void
-org_gnome_mail_to_memo_menu (EPlugin *ep, EMMenuTargetSelect *t)
+gboolean
+e_plugin_ui_init (GtkUIManager *ui_manager,
+ EShellView *shell_view)
{
- /* do not set organizer and attendees for memos */
- mail_to_event (E_CAL_SOURCE_TYPE_JOURNAL, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action_group = e_shell_window_get_action_group (shell_window, "mail");
+
+ gtk_action_group_add_actions (
+ action_group, entries,
+ G_N_ELEMENTS (entries), shell_view);
+ e_action_group_add_popup_actions (
+ action_group, popup_entries,
+ G_N_ELEMENTS (popup_entries));
+
+ g_signal_connect (
+ shell_view, "update-actions",
+ G_CALLBACK (update_actions_cb), NULL);
+
+ return TRUE;
}
diff --git a/plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml b/plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
index e8494fb2d7..614da8cf3b 100644
--- a/plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
+++ b/plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
@@ -1,80 +1,33 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<e-plugin-list>
- <e-plugin
- type="shlib"
- id="org.gnome.evolution.plugin.mailToTask"
- location="@PLUGINDIR@/liborg-gnome-mail-to-task@SOEXT@"
- _name="Mail-to-Task">
- <_description>Convert a mail message to a task.</_description>
+ <e-plugin type="shlib" location="/home/mbarnes/local/lib/evolution/2.28/plugins/liborg-gnome-mail-to-task.so" id="org.gnome.evolution.plugin.mailToTask" name="Mail-to-Task">
<author name="Rodrigo Moya" email="rodrigo@novell.com"/>
+ <_description>Convert a mail message to a task.</_description>
- <!-- hook into the uri popup menu -->
- <hook class="org.gnome.evolution.mail.popup:1.0">
- <menu id="org.gnome.evolution.mail.folderview.popup" target="select">
- <item
- type="item"
- path="70.mail_to_event1"
- icon="appointment-new"
- _label="Create an _Event"
- enable="many"
- visible="many"
- activate="org_gnome_mail_to_event"/>
- <item
- type="item"
- path="70.mail_to_event2"
- icon="stock_new-meeting"
- _label="Create a _Meeting"
- enable="one"
- visible="many"
- activate="org_gnome_mail_to_meeting"/>
- <item
- type="item"
- path="70.mail_to_event3"
- icon="stock_todo"
- _label="Create a _Task"
- enable="many"
- visible="many"
- activate="org_gnome_mail_to_task"/>
- <item
- type="item"
- path="70.mail_to_event4"
- icon="stock_insert-note"
- _label="Create a Mem_o"
- enable="many"
- visible="many"
- activate="org_gnome_mail_to_memo"/>
- </menu>
+ <hook class="org.gnome.evolution.ui:1.0">
+ <ui-manager id="org.gnome.evolution.mail">
+ <menubar name='main-menu'>
+ <placeholder name='custom-menus'>
+ <menu action="mail-message-menu">
+ <placeholder name="mail-message-actions">
+ <menuitem action="mail-convert-to-event"/>
+ <menuitem action="mail-convert-to-meeting"/>
+ <menuitem action="mail-convert-to-task"/>
+ <menuitem action="mail-convert-to-memo"/>
+ </placeholder>
+ </menu>
+ </placeholder>
+ </menubar>
+ <popup name="mail-message-popup">
+ <placeholder name="mail-message-popup-actions">
+ <menuitem action="mail-popup-convert-to-event"/>
+ <menuitem action="mail-popup-convert-to-meeting"/>
+ <menuitem action="mail-popup-convert-to-task"/>
+ <menuitem action="mail-popup-convert-to-memo"/>
+ </placeholder>
+ </popup>
+ </ui-manager>
</hook>
- <hook class="org.gnome.evolution.mail.bonobomenu:1.0">
- <menu id="org.gnome.evolution.mail.browser" target="select">
- <!-- the path to the bonobo menu description -->
- <ui file="@PLUGINDIR@/org-gnome-mail-to-task.xml"/>
- <item
- type="item"
- verb="ConvertEvent"
- path="/commands/ConvertEvent"
- enable="many"
- activate="org_gnome_mail_to_event_menu"/>
- <item
- type="item"
- verb="ConvertMeeting"
- path="/commands/ConvertMeeting"
- enable="one"
- activate="org_gnome_mail_to_meeting_menu"/>
- <item
- type="item"
- verb="ConvertTask"
- path="/commands/ConvertTask"
- enable="many"
- activate="org_gnome_mail_to_task_menu"/>
- <item
- type="item"
- verb="ConvertMemo"
- path="/commands/ConvertMemo"
- enable="many"
- activate="org_gnome_mail_to_memo_menu"/>
- </menu>
- </hook>
-
+
</e-plugin>
</e-plugin-list>
diff --git a/plugins/mail-to-task/org-gnome-mail-to-task.xml b/plugins/mail-to-task/org-gnome-mail-to-task.xml
deleted file mode 100644
index c3d72b6d09..0000000000
--- a/plugins/mail-to-task/org-gnome-mail-to-task.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<Root>
- <commands>
- <cmd name="ConvertEvent" _label="Create an _Event"
- _tip="Create a new event from the selected message"
- pixtype="stock" pixname="appointment-new"/>
- <cmd name="ConvertMeeting" _label="Create a _Meeting"
- _tip="Create a new meeting from the selected message"
- pixtype="stock" pixname="stock_new-meeting"/>
- <cmd name="ConvertTask" _label="Create a _Task"
- _tip="Create a new task from the selected message"
- pixtype="stock" pixname="stock_todo"/>
- <cmd name="ConvertMemo" _label="Create a Mem_o"
- _tip="Create a new memo from the selected message"
- pixtype="stock" pixname="stock_insert-note"/>
- </commands>
-
- <menu>
- <placeholder name="MessagePlaceholder">
- <submenu name="Message">
- <separator f="" name="emaillist5"/>
- <menuitem name="ConvertEvent" verb=""/>
- <menuitem name="ConvertMeeting" verb=""/>
- <menuitem name="ConvertTask" verb=""/>
- <menuitem name="ConvertMemo" verb=""/>
- </submenu>
- </placeholder>
- </menu>
-</Root>
diff --git a/plugins/mark-all-read/Makefile.am b/plugins/mark-all-read/Makefile.am
index b653e8c1f7..aac01d2b37 100644
--- a/plugins/mark-all-read/Makefile.am
+++ b/plugins/mark-all-read/Makefile.am
@@ -1,5 +1,6 @@
AM_CPPFLAGS = \
- -I$(top_srcdir)\
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
$(EVOLUTION_MAIL_CFLAGS)
@EVO_PLUGIN_RULE@
@@ -12,6 +13,7 @@ liborg_gnome_mark_all_read_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_mark_all_read_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
$(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/shell/libeshell.la \
$(EVOLUTION_MAIL_LIBS)
EXTRA_DIST = org-gnome-mark-all-read.eplug.xml
diff --git a/plugins/mark-all-read/mark-all-read.c b/plugins/mark-all-read/mark-all-read.c
index e210af6547..dacb5e5685 100644
--- a/plugins/mark-all-read/mark-all-read.c
+++ b/plugins/mark-all-read/mark-all-read.c
@@ -28,20 +28,26 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include <e-util/e-config.h>
-#include <mail/em-popup.h>
+#include <e-util/e-plugin-ui.h>
+#include <mail/em-folder-tree.h>
#include <mail/mail-ops.h>
#include <mail/mail-mt.h>
#include <camel/camel-vee-folder.h>
#include "e-util/e-error.h"
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+#include <shell/e-shell-window.h>
+
#define PRIMARY_TEXT \
N_("Also mark messages in subfolders?")
#define SECONDARY_TEXT \
N_("Do you want to mark messages as read in the current folder " \
"only, or in the current folder as well as all subfolders?")
-void org_gnome_mark_all_read (EPlugin *ep, EMPopupTargetFolder *target);
+gboolean e_plugin_ui_init (GtkUIManager *ui_manager,
+ EShellView *shell_view);
+
static void mar_got_folder (gchar *uri, CamelFolder *folder, gpointer data);
static void mar_all_sub_folders (CamelStore *store, CamelFolderInfo *fi, CamelException *ex);
@@ -194,16 +200,6 @@ prompt_user (void)
return response;
}
-void
-org_gnome_mark_all_read (EPlugin *ep, EMPopupTargetFolder *t)
-{
- if (t->uri == NULL) {
- return;
- }
-
- mail_get_folder(t->uri, 0, mar_got_folder, NULL, mail_msg_unordered_push);
-}
-
static void
mark_all_as_read (CamelFolder *folder)
{
@@ -274,3 +270,50 @@ mar_all_sub_folders (CamelStore *store, CamelFolderInfo *fi, CamelException *ex)
fi = fi->next;
}
}
+
+static void
+action_mail_mark_read_recursive_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ EShellSidebar *shell_sidebar;
+ EMFolderTree *folder_tree;
+ const gchar *folder_uri;
+
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+ folder_uri = em_folder_tree_get_selected_uri (folder_tree);
+ g_return_if_fail (folder_uri != NULL);
+
+ mail_get_folder (
+ folder_uri, 0, mar_got_folder, NULL, mail_msg_unordered_push);
+
+ g_object_unref (folder_tree);
+}
+
+static GtkActionEntry entries[] = {
+
+ { "mail-mark-read-recursive",
+ "mail-mark-read",
+ N_("Mark Me_ssages as Read"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_mail_mark_read_recursive_cb) }
+};
+
+gboolean
+e_plugin_ui_init (GtkUIManager *ui_manager,
+ EShellView *shell_view)
+{
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action_group = e_shell_window_get_action_group (shell_window, "mail");
+
+ /* Add actions to the "mail" action group. */
+ gtk_action_group_add_actions (
+ action_group, entries,
+ G_N_ELEMENTS (entries), shell_view);
+
+ return TRUE;
+}
diff --git a/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml b/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
index 356b8a5793..a254e1e4db 100644
--- a/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
+++ b/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
@@ -1,18 +1,21 @@
<?xml version="1.0"?>
<e-plugin-list>
- <e-plugin
- id="org.gnome.evolution.mail.folder.mark_all_read"
- type="shlib"
- domain="@GETTEXT_PACKAGE@"
- _name="Mark All Read"
- location="@PLUGINDIR@/liborg-gnome-mark-all-read@SOEXT@">
- <author name="Chenthill Palanisamy" email="pchenthill@novell.com"/>
- <_description>Mark all messages in a folder as read.</_description>
+ <e-plugin id="org.gnome.evolution.mail.folder.mark_all_read"
+ type="shlib"
+ domain="@GETTEXT_PACKAGE@"
+ _name="Mark All Read"
+ location="@PLUGINDIR@/liborg-gnome-mark-all-read@SOEXT@">
+ <author name="Chenthill Palanisamy" email="pchenthill@novell.com"/>
+ <_description>Mark all messages in a folder as read.</_description>
- <hook class="org.gnome.evolution.mail.popup:1.0">
- <menu id="org.gnome.evolution.mail.foldertree.popup" target="folder">
- <item type="item" path="30.emc.01" icon="mail-mark-read" _label="Mark Me_ssages as Read" activate="org_gnome_mark_all_read" enable="folder" visible="folder"/>
- </menu>
- </hook>
- </e-plugin>
+ <hook class="org.gnome.evolution.ui:1.0">
+ <ui-manager id="org.gnome.evolution.mail">
+ <popup name="mail-folder-popup">
+ <placeholder name="mail-folder-popup-actions">
+ <menuitem action="mail-mark-read-recursive"/>
+ </placeholder>
+ </popup>
+ </ui-manager>
+ </hook>
+ </e-plugin>
</e-plugin-list>
diff --git a/plugins/mono/ChangeLog b/plugins/mono/ChangeLog
deleted file mode 100644
index d994cc06f5..0000000000
--- a/plugins/mono/ChangeLog
+++ /dev/null
@@ -1,84 +0,0 @@
-2009-02-05 Suman Manjunath <msuman@novell.com>
-
- * mono-plugin.c: Include <mono/metadata/mono-config.h> to fix an implicit-
- function-declaration compiler warning.
-
-2009-01-28 Suman Manjunath <msuman@novell.com>
-
- * mono-plugin.c: Include <mono/metadata/threads.h> to fix an implicit-
- function-declaration compiler warning.
-
-2008-10-22 Matthew Barnes <mbarnes@redhat.com>
-
- ** Fixes part of bug #549025
-
- * Makefile.am:
- Add $(MONO_CFLAGS) and $(MONO_LIBS) explicitly. The mono plugin
- is the only module that should be linking against libmono.
-
-2008-09-02 Sankar P <psankar@novell.com>
-
-License Changes
-
- * mono-plugin.c:
-
-2008-08-27 Sankar P <psankar@novell.com>
-
-License Changes
-
- * mono-plugin.h:
-
-2008-04-01 Johnny Jacob <jjohnny@novell.com>
-
- * Camel.cs: Type cast. Fixes compile error.
-
-2008-03-19 Sankar P <psankar@novell.com>
-
- * mono-plugin.c: (epm_invoke),
- (load_plugin_type_register_function):
- * org-gnome-evolution-mono.eplug.xml:
- - Use Plugin load levels. Mono loader should load
- and register the type "mono", before a plugin
- of type "mono" is loaded.
-
-2007-10-02 Matthew Barnes <mbarnes@redhat.com>
-
- ** Fixes part of bug #469657
-
- * mono-plugin.c:
- Use destroy functions in GHashTables to simplify memory management.
-
-2007-04-02 Sankar P <psankar@novell.com>
-
- * Committed on behalf of Gilles Dartiguelongue <dartigug@esiee.fr>
-
- * org-gnome-evolution-mono.eplug.xml:
- Cleanup.
- Fixes part of #301149
-
-2005-12-17 Tor Lillqvist <tml@novell.com>
-
- * mono-plugin.c: Drop unused inclusion of <dirent.h>.
-
-2005-08-19 Not Zed <NotZed@Ximian.com>
-
- ** See #308117.
-
- * Makefile.am: link to proper libraries.
-
-2005-06-15 Harish Krishnaswamy <kharish@novell.com>
-
- * Makefile.am : mono-plugin.h should be included
- in the sources too.
-
-2005-05-25 Not Zed <NotZed@Ximian.com>
-
- * mono-plugin.c: implement the mono loader as a plugin itself.
-
-2005-05-17 Not Zed <NotZed@Ximian.com>
-
- * Evolution.cs: added initial e_error wrapper.
-
- * Camel.cs: added multipart & contenttype wrappers.
-
-
diff --git a/plugins/mono/Makefile.am b/plugins/mono/Makefile.am
deleted file mode 100644
index 6121bd7f85..0000000000
--- a/plugins/mono/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- $(E_UTIL_CFLAGS) \
- $(MONO_CFLAGS)
-
-@EVO_PLUGIN_RULE@
-
-plugin_DATA = org-gnome-evolution-mono.eplug
-plugin_LTLIBRARIES = liborg-gnome-evolution-mono.la
-
-liborg_gnome_evolution_mono_la_SOURCES = mono-plugin.c mono-plugin.h
-liborg_gnome_evolution_mono_la_LDFLAGS = -module -avoid-version
-liborg_gnome_evolution_mono_la_LIBADD = \
- $(E_UTIL_LIBS) \
- $(MONO_LIBS)
-
-EXTRA_DIST = org-gnome-evolution-mono.eplug.xml
-
-BUILT_SOURCES = $(plugin_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
--include $(top_srcdir)/git.mk
diff --git a/plugins/mono/mono-plugin.c b/plugins/mono/mono-plugin.c
deleted file mode 100644
index ae5f199c46..0000000000
--- a/plugins/mono/mono-plugin.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <sys/types.h>
-#include <string.h>
-
-#include "mono-plugin.h"
-
-#include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/object.h>
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/assembly.h>
-#include <mono/metadata/threads.h>
-#include <mono/metadata/mono-config.h>
-#include <mono/jit/jit.h>
-
-#define d(x) (x)
-
-static MonoDomain *domain;
-
-/* ********************************************************************** */
-static gpointer epm_parent_class;
-
-typedef struct _EPluginMonoPrivate {
- MonoAssembly *assembly;
- MonoClass *klass;
- MonoObject *plugin;
- GHashTable *methods;
-} EPluginMonoPrivate;
-
-#define epm ((EPluginMono *)ep)
-
-gpointer load_plugin_type_register_function (gpointer a, gpointer b);
-
-static gchar *
-get_xml_prop(xmlNodePtr node, const gchar *id)
-{
- gchar *p = xmlGetProp(node, id);
- gchar *out = NULL;
-
- if (p) {
- out = g_strdup(p);
- xmlFree(p);
- }
-
- return out;
-}
-
-/*
- Two approaches:
- You can have a Evolution.Plugin implementation which has every callback as methods on it.
- Or you can just use static methods for everything.
-
- All methods take a single (structured) argument.
-*/
-
-static gpointer
-epm_invoke(EPlugin *ep, const gchar *name, gpointer data)
-{
- EPluginMonoPrivate *p = epm->priv;
- MonoMethodDesc *d;
- MonoMethod *m;
- MonoObject *x = NULL, *res;
- gpointer *params;
-
- g_print ("\n\a epm_invoke in mono-plugin.c in mono plugin loader is called \n\a");
-
- /* we need to do this every time since we may be called from any thread for some uses */
- mono_thread_attach(domain);
-
- if (p->assembly == NULL) {
- p->assembly = mono_domain_assembly_open(domain, epm->location);
- if (p->assembly == NULL) {
- g_warning("can't load assembly '%s'", epm->location);
- return NULL;
- }
-
- if (epm->handler == NULL
- || (p->klass = mono_class_from_name(mono_assembly_get_image(p->assembly), "", epm->handler)) == NULL) {
- d(printf("Using static callbacks only"));
- } else {
- p->plugin = mono_object_new(domain, p->klass);
- /* could conceivably init with some context too */
- mono_runtime_object_init(p->plugin);
- }
- }
-
- m = g_hash_table_lookup(p->methods, name);
- if (m == NULL) {
- if (p->klass) {
- d(printf("looking up method '%s' in class\n", name));
- /* class method */
-
- d = mono_method_desc_new(name, FALSE);
- /*if (d == NULL) {
- g_warning("Can't create method descriptor for '%s'", name);
- return NULL;
- }*/
-
- gpointer iter = NULL;
- MonoMethod* mono_method;
-
- d(printf ("\n\a About to get methods in klass\n\a"));
-
- while ((mono_method = mono_class_get_methods (p->klass, &iter))) {
- g_print ("\n\a Method name is : <%s>\n\a", mono_method_get_name(mono_method));
- }
- d(printf ("\n\a Got methods in klass \n\a"));
-//mono_class_get_method_from_name
- m = mono_class_get_method_from_name (p->klass, name, -1);
- if (m == NULL) {
- g_warning("Can't find method callback '%s'", name);
- return NULL;
- }
- } else {
- d(printf("looking up static method '%s'\n", name));
- /* static method */
- d = mono_method_desc_new(name, FALSE);
- if (d == NULL) {
- g_warning("Can't create method descriptor for '%s'", name);
- return NULL;
- }
-
- m = mono_method_desc_search_in_image(d, mono_assembly_get_image(p->assembly));
- if (m == NULL) {
- g_warning("Can't find method callback '%s'", name);
- return NULL;
- }
- }
-
- g_hash_table_insert(p->methods, g_strdup(name), m);
- }
-
- params = g_malloc0(sizeof(*params)*1);
- params[0] = &data;
- res = mono_runtime_invoke(m, p->plugin, params, &x);
- /* do i need to free params?? */
-
- if (x)
- mono_print_unhandled_exception(x);
-
- if (res) {
- gpointer *p = mono_object_unbox(res);
- d(printf("mono method returned '%p' %ld\n", *p, (glong)*p));
- return *p;
- } else
- return NULL;
-}
-
-static gint
-epm_construct(EPlugin *ep, xmlNodePtr root)
-{
- if (((EPluginClass *)epm_parent_class)->construct(ep, root) == -1)
- return -1;
-
- epm->location = get_xml_prop(root, "location");
- epm->handler = get_xml_prop(root, "handler");
-
- if (epm->location == NULL)
- return -1;
-
- return 0;
-}
-
-static void
-epm_finalise(GObject *o)
-{
- EPlugin *ep = (EPlugin *)o;
- EPluginMonoPrivate *p = epm->priv;
-
- g_free(epm->location);
- g_free(epm->handler);
-
- g_hash_table_destroy(p->methods);
-
- g_free(epm->priv);
-
- ((GObjectClass *)epm_parent_class)->finalize(o);
-}
-
-static void
-epm_class_init(EPluginClass *klass)
-{
- ((GObjectClass *)klass)->finalize = epm_finalise;
- klass->construct = epm_construct;
- klass->invoke = epm_invoke;
- klass->type = "mono";
-}
-
-static void
-epm_init(GObject *o)
-{
- EPlugin *ep = (EPlugin *)o;
-
- epm->priv = g_malloc0(sizeof(*epm->priv));
- epm->priv->methods = g_hash_table_new_full(
- g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) NULL);
-}
-
-gpointer
-load_plugin_type_register_function (gpointer a, gpointer b)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EPluginMonoClass), NULL, NULL, (GClassInitFunc) epm_class_init, NULL, NULL,
- sizeof(EPluginMono), 0, (GInstanceInitFunc) epm_init,
- };
-
- epm_parent_class = g_type_class_ref(e_plugin_get_type());
- type = g_type_register_static(e_plugin_get_type(), "EPluginMono", &info, 0);
- e_plugin_register_type (type);
- d(printf("\nType EPluginMono registered from the mono-plugin-loader\n"));
- domain = mono_jit_init("Evolution");
- mono_thread_attach(domain);
- }
-
- return GUINT_TO_POINTER(type);
-}
diff --git a/plugins/mono/mono-plugin.h b/plugins/mono/mono-plugin.h
deleted file mode 100644
index 8ea867e806..0000000000
--- a/plugins/mono/mono-plugin.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Sankar P <psankar@novell.com>
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _ORG_GNOME_EVOLUTION_MONO_H
-#define _ORG_GNOME_EVOLUTION_MONO_H
-
-#include "e-util/e-plugin.h"
-
-/* ********************************************************************** */
-/* This is ALL private */
-
-typedef struct _EPluginMono EPluginMono;
-typedef struct _EPluginMonoClass EPluginMonoClass;
-
-struct _EPluginMono {
- EPlugin plugin;
-
- struct _EPluginMonoPrivate *priv;
-
- gchar *location; /* location */
- gchar *handler; /* handler class */
-};
-
-struct _EPluginMonoClass {
- EPluginClass plugin_class;
-};
-
-gpointer org_gnome_evolution_mono_get_type(gpointer a, gpointer b);
-
-#endif /* ! _ORG_GNOME_EVOLUTION_MONO_H */
diff --git a/plugins/mono/org-gnome-evolution-mono.eplug.xml b/plugins/mono/org-gnome-evolution-mono.eplug.xml
deleted file mode 100644
index 8b7ea0d043..0000000000
--- a/plugins/mono/org-gnome-evolution-mono.eplug.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<e-plugin-list>
- <e-plugin type="shlib" id="org.gnome.evolution.plugin.mono"
- location="@PLUGINDIR@/liborg-gnome-evolution-mono@SOEXT@" _name="Mono Loader" load_level="1">
-
- <_description>Support plugins written in Mono.</_description>
- <author name="Michael Zucchi" email="notzed@ximian.com"/>
- <author name="Sankar P" email="psankar@novell.com"/>
-
- </e-plugin>
-</e-plugin-list>
diff --git a/plugins/plugin-manager/Makefile.am b/plugins/plugin-manager/Makefile.am
index eb8126c398..5f1228f439 100644
--- a/plugins/plugin-manager/Makefile.am
+++ b/plugins/plugin-manager/Makefile.am
@@ -1,21 +1,22 @@
AM_CPPFLAGS = \
-I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
$(EVOLUTION_MAIL_CFLAGS)
@EVO_PLUGIN_RULE@
-plugin_DATA = org-gnome-plugin-manager.eplug org-gnome-plugin-manager.xml
+plugin_DATA = org-gnome-plugin-manager.eplug
plugin_LTLIBRARIES = liborg-gnome-plugin-manager.la
liborg_gnome_plugin_manager_la_SOURCES = plugin-manager.c
liborg_gnome_plugin_manager_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_plugin_manager_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/shell/libeshell.la \
$(EVOLUTION_MAIL_LIBS)
-EXTRA_DIST = \
- org-gnome-plugin-manager.eplug.xml \
- org-gnome-plugin-manager.xml
+EXTRA_DIST = \
+ org-gnome-plugin-manager.eplug.xml
BUILT_SOURCES = org-gnome-plugin-manager.eplug
diff --git a/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml b/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
index 406f19b648..da270764a0 100644
--- a/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
+++ b/plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
@@ -6,18 +6,19 @@
location="@PLUGINDIR@/liborg-gnome-plugin-manager@SOEXT@"
_name="Plugin Manager"
system_plugin="true">
- <_description>Manage your Evolution plugins.</_description>
<author name="Michael Zucchi" email="notzed@ximian.com"/>
- <hook class="org.gnome.evolution.shell.bonobomenu:1.0">
- <menu id="org.gnome.evolution.shell" target="shell">
- <!-- the path to the bonobo menu description -->
- <ui file="@PLUGINDIR@/org-gnome-plugin-manager.xml"/>
- <item
- type="item"
- verb="EPluginManagerManage"
- path="/commands/EPluginManagerManage"
- activate="org_gnome_plugin_manager_manage"/>
- </menu>
+ <_description>Manage your Evolution plugins.</_description>
+
+ <hook class="org.gnome.evolution.ui:1.0">
+ <ui-manager id="org.gnome.evolution.shell">
+ <menubar name="main-menu">
+ <menu action="edit-menu">
+ <placeholder name="administrative-actions">
+ <menuitem action="plugin-manager"/>
+ </placeholder>
+ </menu>
+ </menubar>
+ </ui-manager>
</hook>
</e-plugin>
</e-plugin-list>
diff --git a/plugins/plugin-manager/org-gnome-plugin-manager.xml b/plugins/plugin-manager/org-gnome-plugin-manager.xml
deleted file mode 100644
index 3f74a2dd4c..0000000000
--- a/plugins/plugin-manager/org-gnome-plugin-manager.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<Root>
- <commands>
- <cmd name="EPluginManagerManage" _label="_Plugins"
- _tip="Enable and disable plugins"/>
- </commands>
-
- <menu>
- <submenu name="Edit">
- <placeholder name="PluginManagerPlaceholder">
- <menuitem name="EPluginManagerManage" verb=""/>
- </placeholder>
- </submenu>
-
- </menu>
-</Root>
diff --git a/plugins/plugin-manager/plugin-manager.c b/plugins/plugin-manager/plugin-manager.c
index 816505b662..838de0e2f3 100644
--- a/plugins/plugin-manager/plugin-manager.c
+++ b/plugins/plugin-manager/plugin-manager.c
@@ -32,7 +32,8 @@
#include <stdio.h>
#include "e-util/e-plugin.h"
-#include "shell/es-menu.h"
+#include "shell/e-shell-window.h"
+#include "shell/e-shell-window-actions.h"
#define d(S) (S)
@@ -61,7 +62,6 @@ static struct {
typedef struct _Manager Manager;
struct _Manager {
- GtkDialog *dialog;
GtkTreeView *treeview;
GtkTreeModel *model;
@@ -75,13 +75,13 @@ struct _Manager {
};
/* for tracking if we're shown */
-static GtkDialog *dialog;
static GtkWidget *notebook;
static GtkWidget *configure_page;
static gint last_selected_page;
static gulong switch_page_handler_id;
-void org_gnome_plugin_manager_manage(gpointer ep, ESMenuTargetShell *t);
+gboolean e_plugin_ui_init (GtkUIManager *ui_manager,
+ EShellWindow *shell_window);
static void
eppm_set_label (GtkLabel *l, const gchar *v)
@@ -221,19 +221,15 @@ eppm_free (gpointer data)
}
static void
-eppm_response (GtkDialog *w, gint button, Manager *m)
-{
- gtk_widget_destroy (GTK_WIDGET (w));
- dialog = NULL;
-}
-
-void
-org_gnome_plugin_manager_manage (gpointer ep, ESMenuTargetShell *t)
+action_plugin_manager_cb (GtkAction *action,
+ EShellWindow *shell_window)
{
Manager *m;
gint i;
+ GtkWidget *dialog;
GtkWidget *hbox, *w;
GtkWidget *overview_page;
+ GtkWidget *content_area;
GtkListStore *store;
GtkTreeSelection *selection;
GtkCellRenderer *renderer;
@@ -241,26 +237,23 @@ org_gnome_plugin_manager_manage (gpointer ep, ESMenuTargetShell *t)
gchar *string;
GtkWidget *subvbox;
- if (dialog) {
- gtk_window_present (GTK_WINDOW (dialog));
- return;
- }
-
m = g_malloc0 (sizeof (*m));
/* Setup the ui */
- m->dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Plugin Manager"),
- GTK_WINDOW (gtk_widget_get_toplevel (t->target.widget)),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
- NULL));
+ dialog = gtk_dialog_new_with_buttons (
+ _("Plugin Manager"),
+ GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
- gtk_window_set_default_size (GTK_WINDOW (m->dialog), 640, 400);
- g_object_set (G_OBJECT (m->dialog), "has_separator", FALSE, NULL);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 640, 400);
+ g_object_set (dialog, "has_separator", FALSE, NULL);
hbox = gtk_hbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
- gtk_box_pack_start (GTK_BOX (m->dialog->vbox), hbox, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
string = g_strdup_printf ("<i>%s</i>", _("Note: Some changes will not take effect until restart"));
@@ -272,7 +265,7 @@ org_gnome_plugin_manager_manage (gpointer ep, ESMenuTargetShell *t)
gtk_widget_show (w);
g_free (string);
- gtk_box_pack_start (GTK_BOX (m->dialog->vbox), w, FALSE, TRUE, 6);
+ gtk_box_pack_start (GTK_BOX (content_area), w, FALSE, TRUE, 6);
notebook = gtk_notebook_new ();
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), TRUE);
@@ -423,24 +416,34 @@ org_gnome_plugin_manager_manage (gpointer ep, ESMenuTargetShell *t)
atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (m->treeview)), _("Plugin"));
- g_object_set_data_full (G_OBJECT (m->dialog), "plugin-manager", m, eppm_free);
- g_signal_connect (m->dialog, "response", G_CALLBACK (eppm_response), m);
-
- dialog = m->dialog;
+ gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_show (GTK_WIDGET (m->dialog));
+ gtk_widget_destroy (dialog);
+ eppm_free (m);
}
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+static GtkActionEntry entries[] = {
-gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+ { "plugin-manager",
+ NULL,
+ N_("_Plugins"),
+ NULL,
+ N_("Enable and disable plugins"),
+ G_CALLBACK (action_plugin_manager_cb) }
+};
+
+gboolean
+e_plugin_ui_init (GtkUIManager *ui_manager,
+ EShellWindow *shell_window)
{
- if (enable) {
- } else {
- /* This plugin can't be disabled ... */
- return -1;
- }
+ GtkActionGroup *action_group;
+
+ action_group = E_SHELL_WINDOW_ACTION_GROUP_SHELL (shell_window);
+
+ /* Add actions to the "shell" action group. */
+ gtk_action_group_add_actions (
+ action_group, entries,
+ G_N_ELEMENTS (entries), shell_window);
- return 0;
+ return TRUE;
}
diff --git a/plugins/prefer-plain/prefer-plain.c b/plugins/prefer-plain/prefer-plain.c
index dd7e4539b8..b896f19299 100644
--- a/plugins/prefer-plain/prefer-plain.c
+++ b/plugins/prefer-plain/prefer-plain.c
@@ -26,16 +26,16 @@
#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
+#include <gconf/gconf-client.h>
#include <string.h>
#include <stdio.h>
-#include "camel/camel-multipart.h"
-#include "camel/camel-mime-part.h"
-#include "mail/em-format-hook.h"
-#include "mail/em-format.h"
+#include <camel/camel-multipart.h>
+#include <camel/camel-mime-part.h>
-#include <gconf/gconf-client.h>
-#include "mail/em-config.h"
+#include <em-format/em-format.h>
+#include <mail/em-config.h>
+#include <mail/em-format-hook.h>
void org_gnome_prefer_plain_multipart_alternative(gpointer ep, EMFormatHookTarget *t);
void org_gnome_prefer_plain_text_html(gpointer ep, EMFormatHookTarget *t);
@@ -243,10 +243,10 @@ org_gnome_prefer_plain_config_mode(struct _EPlugin *epl, struct _EConfigHookItem
return (GtkWidget *)dropdown;
}
-gint e_plugin_lib_enable(EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable(EPlugin *ep, gint enable);
gint
-e_plugin_lib_enable(EPluginLib *ep, gint enable)
+e_plugin_lib_enable(EPlugin *ep, gint enable)
{
gchar *key;
gint i;
diff --git a/plugins/profiler/Makefile.am b/plugins/profiler/Makefile.am
index b276c41296..21f63af33f 100644
--- a/plugins/profiler/Makefile.am
+++ b/plugins/profiler/Makefile.am
@@ -10,7 +10,7 @@ plugin_DATA = org-gnome-evolution-profiler.eplug
plugin_LTLIBRARIES = liborg-gnome-evolution-profiler.la
liborg_gnome_evolution_profiler_la_SOURCES = profiler.c
-liborg_gnome_evolution_profiler_la_LDFLAGS = -module -avoid-version
+liborg_gnome_evolution_profiler_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
EXTRA_DIST = org-gnome-evolution-profiler.eplug.xml
diff --git a/plugins/profiler/profiler.c b/plugins/profiler/profiler.c
index c6843d349b..1200661b51 100644
--- a/plugins/profiler/profiler.c
+++ b/plugins/profiler/profiler.c
@@ -40,7 +40,7 @@ org_gnome_evolution_profiler_event(EPlugin *ep, EProfileEventTarget *t)
if (!fp) {
gchar *name;
- name = g_strdup_printf("eprofile.%ld", (glong)getpid());
+ name = g_strdup_printf("eprofile.%ld", (glong) getpid());
fp = fopen(name, "w");
if (fp)
fprintf(stderr, "Generating profiling data in `%s'\n", name);
diff --git a/plugins/pst-import/Makefile.am b/plugins/pst-import/Makefile.am
index 35788872c1..56d4e21600 100644
--- a/plugins/pst-import/Makefile.am
+++ b/plugins/pst-import/Makefile.am
@@ -24,8 +24,10 @@ plugin_LTLIBRARIES = liborg-gnome-pst-import.la
liborg_gnome_pst_import_la_SOURCES = pst-importer.c
liborg_gnome_pst_import_la_LDFLAGS = \
-module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_pst_import_la_LIBADD = \
- $(NO_UNDEFINED_REQUIRED_LIBS) \
+liborg_gnome_pst_import_la_LIBADD = \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(EVOLUTION_CALENDAR_LIBS) \
+ $(EVOLUTION_MAIL_LIBS) \
$(LIBPST_LIBS)
EXTRA_DIST = org-gnome-pst-import.eplug.xml
diff --git a/plugins/pst-import/pst-importer.c b/plugins/pst-import/pst-importer.c
index ddc7e7662f..8009d563f7 100644
--- a/plugins/pst-import/pst-importer.c
+++ b/plugins/pst-import/pst-importer.c
@@ -61,7 +61,7 @@
#include <camel/camel-stream-fs.h>
#include <camel/camel-file-utils.h>
-#include <mail/mail-component.h>
+#include <mail/e-mail-local.h>
#include <mail/mail-mt.h>
#include <mail/mail-tools.h>
#include <mail/em-utils.h>
@@ -94,7 +94,7 @@ gboolean org_credativ_evolution_readpst_supported (EPlugin *epl, EImportTarget *
GtkWidget *org_credativ_evolution_readpst_getwidget (EImport *ei, EImportTarget *target, EImportImporter *im);
void org_credativ_evolution_readpst_import (EImport *ei, EImportTarget *target, EImportImporter *im);
void org_credativ_evolution_readpst_cancel (EImport *ei, EImportTarget *target, EImportImporter *im);
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
/* em-folder-selection-button.h is private, even though other internal evo plugins use it!
so declare the functions here
@@ -225,7 +225,7 @@ get_suggested_foldername (EImportTargetURI *target)
/* Suggest a folder that is in the same mail storage as the users' inbox,
with a name derived from the .PST file */
- inbox = mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_INBOX);
+ inbox = e_mail_local_get_folder_uri (E_MAIL_FOLDER_INBOX);
delim = g_strrstr (inbox, "#");
if (delim != NULL) {
@@ -255,10 +255,11 @@ get_suggested_foldername (EImportTargetURI *target)
}
if (mail_tool_uri_to_folder (foldername->str, 0, NULL) != NULL) {
+ CamelFolder *folder;
+
/* Folder exists - add a number */
gint i, len;
len = foldername->len;
- CamelFolder *folder;
for (i=1; i<10000; i++) {
g_string_truncate (foldername, len);
@@ -350,7 +351,7 @@ pst_import_describe (PstImporter *m, gint complete)
}
static ECal*
-open_ecal (ECalSourceType type, gchar *name)
+open_ecal (ECalSourceType type, const gchar *name)
{
/* Hack - grab the first calendar we can find
TODO - add a selection mechanism in get_widget */
@@ -730,7 +731,7 @@ static CamelMimePart *
attachment_to_part (PstImporter *m, pst_item_attach *attach)
{
CamelMimePart *part;
- gchar *mimetype;
+ const gchar *mimetype;
part = camel_mime_part_new ();
@@ -831,7 +832,7 @@ pst_process_email (PstImporter *m, pst_item *item)
if (item->email->sentto_address.str != NULL) {
addr = camel_internet_address_new ();
- if (camel_address_decode (CAMEL_ADDRESS (addr), item->email->sentto_address.str) > 0);
+ if (camel_address_decode (CAMEL_ADDRESS (addr), item->email->sentto_address.str) > 0)
camel_mime_message_set_recipients (msg, "To", addr);
camel_object_unref (addr);
@@ -840,7 +841,7 @@ pst_process_email (PstImporter *m, pst_item *item)
if (item->email->cc_address.str != NULL) {
addr = camel_internet_address_new ();
- if (camel_address_decode (CAMEL_ADDRESS (addr), item->email->cc_address.str) > 0);
+ if (camel_address_decode (CAMEL_ADDRESS (addr), item->email->cc_address.str) > 0)
camel_mime_message_set_recipients (msg, "CC", addr);
camel_object_unref (addr);
@@ -941,7 +942,7 @@ contact_set_string (EContact *contact, EContactField id, gchar *string)
}
static void
-unknown_field (EContact *contact, GString *notes, gchar *name, gchar *string)
+unknown_field (EContact *contact, GString *notes, const gchar *name, gchar *string)
{
/* Field could not be mapped directly so add to notes field */
if (string != NULL) {
@@ -1010,9 +1011,9 @@ pst_process_contact (PstImporter *m, pst_item *item)
{
pst_item_contact *c;
EContact *ec;
- c = item->contact;
GString *notes;
+ c = item->contact;
notes = g_string_sized_new (2048);
ec = e_contact_new ();
@@ -1274,12 +1275,13 @@ fill_calcomponent (PstImporter *m, pst_item *item, ECalComponent *ec, const gcha
pst_item_appointment *a;
pst_item_email *e;
- a = item->appointment;
- e = item->email;
ECalComponentText text;
struct icaltimetype tt_start, tt_end;
ECalComponentDateTime dt_start, dt_end;
+ a = item->appointment;
+ e = item->email;
+
if (item->create_date) {
struct icaltimetype tt;
tt = get_ical_date (item->create_date, FALSE);
@@ -1653,7 +1655,7 @@ org_credativ_evolution_readpst_cancel (EImport *ei, EImportTarget *target, EImpo
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
if (enable) {
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
diff --git a/plugins/python/ChangeLog b/plugins/python/ChangeLog
deleted file mode 100644
index 38cd85f29f..0000000000
--- a/plugins/python/ChangeLog
+++ /dev/null
@@ -1,38 +0,0 @@
-2008-09-24 Philip Withnall <philip@tecnocode.co.uk>
-
- ** Fixes bug #553479
-
- * org-gnome-evolution-python.eplug.xml: String capitalisation
- improvements.
-
-2008-09-12 Sankar P <psankar@novell.com>
-
-License Changes
-
- * python-plugin-loader.c:
- * python-plugin-loader.h:
-
-2008-07-21 Johnny Jacob <jjohnny@novell.com>
-
- * Makefile.am (example_sources): More typo fixes. :(
-
-2008-07-21 Johnny Jacob <jjohnny@novell.com>
-
- * Makefile.am (example_SOURCES): Add example sources
- EXTRA_DIST.
-
-2008-06-12 Johnny Jacob <jjohnny@novell.com>
-
- * example/org-gnome-hello-python-ui.xml: Added.
-
- * example/org-gnome-hello-python.eplug.xml: Added.
-
- * example/Makefile.am : Added.
-
- * example/hello_python.py: Added.
-
-2008-06-09 Johnny Jacob <jjohnny@novell.com>
-
- * python-plugin-loader.c: Python plugin loader.
- Initial Commit.
-
diff --git a/plugins/python/Makefile.am b/plugins/python/Makefile.am
deleted file mode 100644
index f6a48ac727..0000000000
--- a/plugins/python/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- $(E_UTIL_CFLAGS) \
- $(PY_INCLUDES)
-
-@EVO_PLUGIN_RULE@
-
-plugin_DATA = org-gnome-evolution-python.eplug
-plugin_LTLIBRARIES = liborg-gnome-evolution-python.la
-
-liborg_gnome_evolution_python_la_SOURCES = python-plugin-loader.c python-plugin-loader.h
-liborg_gnome_evolution_python_la_LDFLAGS = -module -avoid-version
-liborg_gnome_evolution_python_la_LIBADD = \
- -lpthread -ldl -lutil -lm \
- $(PY_LIBS) \
- $(E_UTIL_LIBS)
-
-example_sources = \
- example/hello_python.py \
- example/org-gnome-hello-python-ui.xml \
- example/org-gnome-hello-python.eplug.xml \
- example/Makefile.am
-
-EXTRA_DIST = org-gnome-evolution-python.eplug.xml \
- $(example_sources)
-
-BUILT_SOURCES = $(plugin_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
--include $(top_srcdir)/git.mk
diff --git a/plugins/python/org-gnome-evolution-python.eplug.xml b/plugins/python/org-gnome-evolution-python.eplug.xml
deleted file mode 100644
index 5f215f65e5..0000000000
--- a/plugins/python/org-gnome-evolution-python.eplug.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0"?>
-<e-plugin-list>
- <e-plugin type="shlib" id="org.gnome.evolution.plugin.python"
- location="@PLUGINDIR@/liborg-gnome-evolution-python@SOEXT@" _name="Python Loader" load_level="1">
-
- <_description>A plugin which loads other plugins written using Python.</_description>
-
- <author name="Johnny Jacob" email="jjohnny@novell.com"/>
- </e-plugin>
-</e-plugin-list>
diff --git a/plugins/python/python-plugin-loader.c b/plugins/python/python-plugin-loader.c
deleted file mode 100644
index 0a03809e97..0000000000
--- a/plugins/python/python-plugin-loader.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Johnny Jacob <jjohnny@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <sys/types.h>
-#include <string.h>
-#include <Python.h>
-
-#include "python-plugin-loader.h"
-
-#define d(x)
-
-static gpointer epp_parent_class;
-
-typedef struct _EPluginPythonPrivate {
- PyObject *pModule;
- PyObject *pClass;
- PyObject *pFunc;
- PyObject *pDict;
- GHashTable *methods;
-} EPluginPythonPrivate;
-
-#define epp ((EPluginPython *)ep)
-
-gpointer load_plugin_type_register_function (gpointer a, gpointer b);
-
-static gchar *
-get_xml_prop(xmlNodePtr node, const gchar *id)
-{
- gchar *p = xmlGetProp(node, id);
- gchar *out = NULL;
-
- if (p) {
- out = g_strdup(p);
- xmlFree(p);
- }
-
- return out;
-}
-
-static gpointer
-epp_invoke(EPlugin *ep, const gchar *name, gpointer data)
-{
- EPluginPythonPrivate *p = epp->priv;
- PyObject *pModuleName, *pFunc;
- PyObject *pInstance, *pValue = NULL;
-
- /* we need to do this every time since we may be called from any thread for some uses */
- Py_Initialize();
-
- if (p->pModule == NULL) {
- pModuleName = PyString_FromString(epp->module_name);
-
- PyRun_SimpleString(g_strdup_printf ("import sys; sys.path.insert(0, '%s')", epp->location));
-
- p->pModule = PyImport_Import(pModuleName);
-
- Py_DECREF(pModuleName); //Free
-
- if (p->pModule == NULL) {
- PyErr_Print();
- g_warning("can't load python module '%s'", epp->location);
- return NULL;
- }
-
- p->pDict = PyModule_GetDict(p->pModule);
-
- if (epp->pClass) {
- p->pClass = PyDict_GetItemString(p->pDict, epp->pClass);
- }
- }
-
- if (p->pClass) {
-
- if (PyCallable_Check(p->pClass))
- pInstance = PyObject_CallObject(p->pClass, NULL);
-
- pValue = PyObject_CallMethod(pInstance, name, NULL);
-
- } else {
-
- pFunc = PyDict_GetItemString(p->pDict, name);
-
- if (pFunc && PyCallable_Check(pFunc))
- pValue = PyObject_CallObject(pFunc, NULL);
- else
- PyErr_Print();
- }
-
- if (pValue) {
- d(printf("%s(%d):%s: Result of call: %ld \n", __FILE__, __LINE__, __PRETTY_FUNCTION__, PyInt_AsLong(pValue)));
- Py_DECREF(pValue);
- /* Fixme */
- return NULL;
- } else
- return NULL;
-}
-
-static gint
-epp_construct(EPlugin *ep, xmlNodePtr root)
-{
- if (((EPluginClass *)epp_parent_class)->construct(ep, root) == -1)
- return -1;
-
- epp->location = get_xml_prop(root, "location");
- epp->module_name = get_xml_prop (root, "module_name");
- epp->pClass = get_xml_prop(root, "pClass");
-
- if (epp->location == NULL)
- return -1;
-
- return 0;
-}
-
-static void
-epp_finalise(GObject *o)
-{
- EPlugin *ep = (EPlugin *)o;
- EPluginPythonPrivate *p = epp->priv;
-
- g_free(epp->location);
- g_free(epp->module_name);
- g_free(epp->pClass);
-
- g_hash_table_destroy(p->methods);
-
- g_free(epp->priv);
-
- ((GObjectClass *)epp_parent_class)->finalize(o);
-}
-
-static void
-epp_class_init(EPluginClass *klass)
-{
- ((GObjectClass *)klass)->finalize = epp_finalise;
- klass->construct = epp_construct;
- klass->invoke = epp_invoke;
- klass->type = "python";
-}
-
-static void
-epp_init(GObject *o)
-{
- EPlugin *ep = (EPlugin *)o;
-
- epp->priv = g_malloc0(sizeof(*epp->priv));
- epp->priv->methods = g_hash_table_new_full(
- g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) NULL);
-}
-
-gpointer
-load_plugin_type_register_function (gpointer a, gpointer b)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(EPluginPythonClass), NULL, NULL, (GClassInitFunc) epp_class_init, NULL, NULL,
- sizeof(EPluginPython), 0, (GInstanceInitFunc) epp_init,
- };
-
- epp_parent_class = g_type_class_ref(e_plugin_get_type());
- type = g_type_register_static(e_plugin_get_type(), "EPluginPython", &info, 0);
- e_plugin_register_type (type);
-
- d(printf("\nType EPluginPython registered from the python-plugin-loader\n"));
-
- Py_Initialize(); //TODO : Does this mean i can cache the instance of pyobjects ?
- }
-
- return GUINT_TO_POINTER(type);
-}
diff --git a/plugins/python/python-plugin-loader.h b/plugins/python/python-plugin-loader.h
deleted file mode 100644
index 66bd8d5ba2..0000000000
--- a/plugins/python/python-plugin-loader.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Johnny Jacob <jjohnny@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
- EPlugin plugin;
-
- struct _EPluginPythonPrivate *priv;
-
- gchar *location; /* location */
- gchar *pClass; /* handler class */
- gchar *module_name;
-};
-
-struct _EPluginPythonClass {
- EPluginClass plugin_class;
-};
-
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
-
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
diff --git a/plugins/sa-junk-plugin/Makefile.am b/plugins/sa-junk-plugin/Makefile.am
index eebfdf0c26..66e31a0d6b 100644
--- a/plugins/sa-junk-plugin/Makefile.am
+++ b/plugins/sa-junk-plugin/Makefile.am
@@ -1,5 +1,6 @@
AM_CPPFLAGS = \
-I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
$(EVOLUTION_MAIL_CFLAGS)
@EVO_PLUGIN_RULE@
@@ -10,6 +11,11 @@ plugin_LTLIBRARIES = liborg-gnome-sa-junk-plugin.la
liborg_gnome_sa_junk_plugin_la_SOURCES = em-junk-filter.c
liborg_gnome_sa_junk_plugin_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+liborg_gnome_sa_junk_plugin_la_LIBADD = \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(EVOLUTION_MAIL_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
BUILT_SOURCES = $(plugin_DATA) $(error_DATA)
diff --git a/plugins/sa-junk-plugin/em-junk-filter.c b/plugins/sa-junk-plugin/em-junk-filter.c
index 74010f2555..ff38f18d6a 100644
--- a/plugins/sa-junk-plugin/em-junk-filter.c
+++ b/plugins/sa-junk-plugin/em-junk-filter.c
@@ -42,7 +42,7 @@
#include <camel/camel-stream-fs.h>
#include <camel/camel-stream-mem.h>
#include <camel/camel-i18n.h>
-#include <mail/em-junk-hook.h>
+#include <mail/em-junk.h>
#include <mail/em-utils.h>
#include <e-util/e-mktemp.h>
@@ -58,10 +58,10 @@ static pthread_mutex_t em_junk_sa_report_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t em_junk_sa_preferred_socket_path_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t em_junk_sa_spamd_restart_lock = PTHREAD_MUTEX_INITIALIZER;
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
-gboolean em_junk_sa_check_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_sa_report_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_sa_report_non_junk (EPlugin *ep, EMJunkHookTarget *target);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
+gboolean em_junk_sa_check_junk (EPlugin *ep, EMJunkTarget *target);
+void em_junk_sa_report_junk (EPlugin *ep, EMJunkTarget *target);
+void em_junk_sa_report_non_junk (EPlugin *ep, EMJunkTarget *target);
void em_junk_sa_commit_reports (EPlugin *ep);
gpointer em_junk_sa_validate_binary (EPlugin *ep);
GtkWidget *org_gnome_sa_use_remote_tests (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
@@ -571,7 +571,7 @@ em_junk_sa_respawn_spamd ()
}
gboolean
-em_junk_sa_check_junk(EPlugin *ep, EMJunkHookTarget *target)
+em_junk_sa_check_junk(EPlugin *ep, EMJunkTarget *target)
{
GByteArray *out = NULL;
const gchar *argv[7];
@@ -675,7 +675,7 @@ get_spamassassin_version ()
}
void
-em_junk_sa_report_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_sa_report_junk (EPlugin *ep, EMJunkTarget *target)
{
const gchar *sync_op =
(get_spamassassin_version () >= 3)
@@ -715,7 +715,7 @@ em_junk_sa_report_junk (EPlugin *ep, EMJunkHookTarget *target)
}
void
-em_junk_sa_report_non_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_sa_report_non_junk (EPlugin *ep, EMJunkTarget *target)
{
const gchar *sync_op =
(get_spamassassin_version () >= 3)
@@ -812,7 +812,7 @@ em_junk_sa_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry,
}
gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
{
em_junk_sa_init();
diff --git a/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml b/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml
index 3403a3b8aa..83ed170c74 100644
--- a/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml
+++ b/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml
@@ -6,14 +6,12 @@
<_description>Filter junk messages using SpamAssassin.</_description>
<author name="Vivek Jain" email="jvivek@novell.com"/>
<hook class="org.gnome.evolution.mail.junk:1.0">
- <group id="EMJunk" >
- <item name="SpamAssassin"
- check_junk="em_junk_sa_check_junk"
- report_junk="em_junk_sa_report_junk"
- report_non_junk="em_junk_sa_report_non_junk"
- commit_reports="em_junk_sa_commit_reports"
- validate_binary="em_junk_sa_validate_binary"/>
- </group>
+ <interface name="SpamAssassin"
+ check_junk="em_junk_sa_check_junk"
+ report_junk="em_junk_sa_report_junk"
+ report_non_junk="em_junk_sa_report_non_junk"
+ commit_reports="em_junk_sa_commit_reports"
+ validate_binary="em_junk_sa_validate_binary"/>
</hook>
<!-- hook into the 'mail properties' menu -->
<hook class="org.gnome.evolution.mail.config:1.0">
@@ -21,6 +19,6 @@
<item type="section_table" path="40.junk/10.options" _label="SpamAssassin Options"/>
<item type="item_table" path="40.junk/20.options" factory="org_gnome_sa_use_remote_tests"/>
</group>
- </hook>
+ </hook>
</e-plugin>
</e-plugin-list>
diff --git a/plugins/select-one-source/ChangeLog b/plugins/select-one-source/ChangeLog
deleted file mode 100644
index 0534fee906..0000000000
--- a/plugins/select-one-source/ChangeLog
+++ /dev/null
@@ -1,64 +0,0 @@
-2008-10-13 Suman Manjunath <msuman@novell.com>
-
- ** Fix for bug #424818 (bugzilla.novell.com)
-
- * mark-calendar-offline.c: Removed this unused PoC file. The
- corresponding plugin has also been integrated into the main code.
-
-2008-08-27 Sankar P <psankar@novell.com>
-
-License Changes
-
- * mark-calendar-offline.c:
- * select-one-source.c:
-
-2008-08-12 Bharath Acharya <abharath@novell.com>
-
- * Makefile.am: Use NO_UNDEFINED. Link with more libraries. To generate
- dlls on Windows.
-
-2007-11-11 Gilles Dartiguelongue <gdartigu@svn.gnome.org>
-
- ** Fix bug #495872
-
- * org-gnome-select-one-source.eplug.xml:
- add right-click menu item for memo component
-
-2007-04-02 Sankar P <psankar@novell.com>
-
- * Committed on behalf of Gilles Dartiguelongue <dartigug@esiee.fr>
-
- * org-gnome-select-one-source.eplug.xml:
- Cleanup.
- Fixes part of #301149
-
-2006-02-13 Karsten Bräckelmann <guenther@rudersport.de>
-
- * org-gnome-select-one-source.eplug.xml:
- Fix mnemonics to be consistent. Fixes bug #330934.
-
-2005-12-12 Harish Krishnaswamy <kharish@novell.com>
-
- * Makefile.am: Fix make-clean issues.
-
-2005-05-06 Not Zed <NotZed@Ximian.com>
-
- * Makefile.am:
- * org-gnome-select-one-source.eplug.xml: s/.in/.xml/ & i18n.
-
-2005-02-24 Björn Torkelsson <torkel@acc.umu.se>
-
- * org-gnome-select-one-source.eplug.in: Fixed description and
- added author.
- Added xml tag.
-
-2004-11-01 JP Rosevear <jpr@novell.com>
-
- * Makefile.am: dist .eplug.in file
-
-2004-10-20 JP Rosevear <jpr@novell.com>
-
- * select-one-source.c: implement a plugin that allows the user to
- limit the displayed task lists or calendars to the current
- calendar or task list
-
diff --git a/plugins/select-one-source/Makefile.am b/plugins/select-one-source/Makefile.am
deleted file mode 100644
index 3788fd30fa..0000000000
--- a/plugins/select-one-source/Makefile.am
+++ /dev/null
@@ -1,21 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/widgets \
- $(EVOLUTION_CALENDAR_CFLAGS)
-
-@EVO_PLUGIN_RULE@
-
-plugin_DATA = org-gnome-select-one-source.eplug
-plugin_LTLIBRARIES = liborg-gnome-select-one-source.la
-
-liborg_gnome_select_one_source_la_SOURCES = select-one-source.c
-liborg_gnome_select_one_source_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_select_one_source_la_LIBADD = \
- $(EVOLUTION_CALENDAR_LIBS)
-
-EXTRA_DIST = org-gnome-select-one-source.eplug.xml
-
-BUILT_SOURCES = $(plugin_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
--include $(top_srcdir)/git.mk
diff --git a/plugins/select-one-source/org-gnome-select-one-source.eplug.xml b/plugins/select-one-source/org-gnome-select-one-source.eplug.xml
deleted file mode 100644
index 12a3d03a88..0000000000
--- a/plugins/select-one-source/org-gnome-select-one-source.eplug.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0"?>
-<e-plugin-list>
- <e-plugin id="org.gnome.evolution.select_one_source" type="shlib"
- _name="Select One Source"
- location="@PLUGINDIR@/liborg-gnome-select-one-source@SOEXT@">
- <author name="JP Rosevear" email="jpr@novell.com"/>
- <_description>Quickly select a single calendar or task list for viewing.</_description>
-
- <hook class="org.gnome.evolution.calendar.popup:1.0">
- <menu id="org.gnome.evolution.tasks.source.popup" target="source">
- <item type="item" path="25.select_one_source" _label="Show _only this Task List" icon="stock_check-filled" activate="org_gnome_select_one_source"/>
- </menu>
- <menu id="org.gnome.evolution.memos.source.popup" target="source">
- <item type="item" path="25.select_one_source" _label="Show _only this Memo List" icon="stock_check-filled" activate="org_gnome_select_one_source"/>
- </menu>
- <menu id="org.gnome.evolution.calendar.source.popup" target="source">
- <item type="item" path="25.select_one_source" _label="Show _only this Calendar" icon="stock_check-filled" activate="org_gnome_select_one_source"/>
- </menu>
- </hook>
- </e-plugin>
-</e-plugin-list>
diff --git a/plugins/select-one-source/select-one-source.c b/plugins/select-one-source/select-one-source.c
deleted file mode 100644
index c211814151..0000000000
--- a/plugins/select-one-source/select-one-source.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-/* This is prototype code only, this may, or may not, use undocumented
- * unstable or private internal function calls. */
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <libedataserver/e-source.h>
-#include <libedataserverui/e-source-selector.h>
-#include <calendar/gui/e-cal-popup.h>
-
-void org_gnome_select_one_source (EPlugin *ep, ECalPopupTargetSource *target);
-
-void
-org_gnome_select_one_source (EPlugin *ep, ECalPopupTargetSource *target)
-{
- GSList *selection, *l;
- ESource *primary_source;
-
- selection = e_source_selector_get_selection (target->selector);
- primary_source = e_source_selector_peek_primary_selection (target->selector);
-
- for (l = selection; l; l = l->next) {
- ESource *source = l->data;
-
- if (source != primary_source)
- e_source_selector_unselect_source (target->selector, source);
- }
-
- e_source_selector_select_source (target->selector, primary_source);
-
- e_source_selector_free_selection (selection);
-}
diff --git a/plugins/startup-wizard/Makefile.am b/plugins/startup-wizard/Makefile.am
index 81c75776d9..39ddf0d043 100644
--- a/plugins/startup-wizard/Makefile.am
+++ b/plugins/startup-wizard/Makefile.am
@@ -1,5 +1,6 @@
-AM_CPPFLAGS = -I . \
- -I$(top_srcdir) \
+AM_CPPFLAGS = -I . \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
-I$(top_builddir)/shell \
$(EVOLUTION_CALENDAR_CFLAGS) \
$(EVOLUTION_MAIL_CFLAGS)
diff --git a/plugins/startup-wizard/startup-wizard.c b/plugins/startup-wizard/startup-wizard.c
index 7dd3f5b3e3..14c4c6cffe 100644
--- a/plugins/startup-wizard/startup-wizard.c
+++ b/plugins/startup-wizard/startup-wizard.c
@@ -24,11 +24,9 @@
#include <gconf/gconf-client.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#include <libgnomeui/gnome-druid.h>
-#include <libgnomeui/gnome-druid-page-edge.h>
-#include <libgnomeui/gnome-druid-page-standard.h>
#include "e-util/e-error.h"
#include "e-util/e-import.h"
+#include "shell/e-shell.h"
#include "shell/es-event.h"
#include "mail/em-config.h"
#include "mail/em-account-editor.h"
@@ -47,7 +45,7 @@ static GtkWidget *import_dialog, *import_progress, *import_label;
static GSList *import_iterator, *import_importers;
G_GNUC_NORETURN static void
-startup_wizard_delete (void) {
+startup_wizard_terminate (void) {
gtk_main_quit ();
_exit (0);
}
@@ -55,10 +53,12 @@ startup_wizard_delete (void) {
void
startup_wizard (EPlugin *ep, ESEventTargetUpgrade *target)
{
+ EMAccountEditor *emae;
+ GtkWidget *start_page;
GConfClient *client;
GSList *accounts;
- EMAccountEditor *emae;
- GnomeDruidPageEdge *start_page;
+ EConfig *config;
+ GList *page_children;
client = gconf_client_get_default ();
accounts = gconf_client_get_list (client, "/apps/evolution/mail/accounts", GCONF_VALUE_STRING, NULL);
@@ -73,26 +73,43 @@ startup_wizard (EPlugin *ep, ESEventTargetUpgrade *target)
/** @HookPoint-EMConfig: New Mail Account Wizard
* @Id: org.gnome.evolution.mail.config.accountWizard
- * @Type: E_CONFIG_DRUID
+ * @Type: E_CONFIG_ASSISTANT
* @Class: org.gnome.evolution.mail.config:1.0
* @Target: EMConfigTargetAccount
*
- * The new mail account druid.
+ * The new mail account assistant.
*/
- emae = em_account_editor_new (NULL, EMAE_DRUID, "org.gnome.evolution.mail.config.accountWizard");
-
- gtk_window_set_title (GTK_WINDOW (emae->editor), _("Evolution Setup Assistant"));
+ emae = em_account_editor_new (
+ NULL, EMAE_ASSISTANT,
+ "org.gnome.evolution.mail.config.accountWizard");
+
+ gtk_window_set_title (
+ GTK_WINDOW (emae->editor), _("Evolution Setup Assistant"));
+
+ config = (EConfig *) emae->config;
+ start_page = e_config_page_get (config, "0.start");
+
+ gtk_assistant_set_page_title (GTK_ASSISTANT (config->widget), start_page, _("Welcome"));
+ page_children = gtk_container_get_children (GTK_CONTAINER (start_page));
+ if (page_children) {
+ GtkLabel *label = GTK_LABEL (page_children->data);
+ if (label) {
+ gtk_label_set_text (label, _(""
+ "Welcome to Evolution. The next few screens will allow Evolution to connect "
+ "to your email accounts, and to import files from other applications. \n"
+ "\n"
+ "Please click the \"Forward\" button to continue. "));
+ }
+
+ g_list_free (page_children);
+ }
- start_page = GNOME_DRUID_PAGE_EDGE (e_config_page_get ((EConfig *) emae->config, "0.start"));
- gnome_druid_page_edge_set_title (start_page, _("Welcome"));
- gnome_druid_page_edge_set_text (start_page, _(""
- "Welcome to Evolution. The next few screens will allow Evolution to connect "
- "to your email accounts, and to import files from other applications. \n"
- "\n"
- "Please click the \"Forward\" button to continue. "));
- g_signal_connect (emae->editor, "delete-event", G_CALLBACK (startup_wizard_delete), NULL);
+ g_signal_connect (
+ emae->editor, "delete-event",
+ G_CALLBACK (startup_wizard_terminate), NULL);
gtk_widget_show (emae->editor);
+
gtk_main ();
}
@@ -112,13 +129,14 @@ startup_wizard_importer_page (EPlugin *ep, EConfigHookItemFactoryData *hook_data
if (import_importers == NULL)
return NULL;
- page = gnome_druid_page_standard_new_with_vals (_("Importing files"), NULL, NULL);
+ page = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (page), 12);
label = gtk_label_new (_("Please select the information that you would like to import:"));
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox), label, FALSE, FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (page), label, FALSE, FALSE, 3);
sep = gtk_hseparator_new ();
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox), sep, FALSE, FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (page), sep, FALSE, FALSE, 3);
table = gtk_table_new(g_slist_length(import_importers), 2, FALSE);
for (l = import_importers; l; l = l->next) {
@@ -141,10 +159,12 @@ startup_wizard_importer_page (EPlugin *ep, EConfigHookItemFactoryData *hook_data
gtk_table_attach((GtkTable *)table, w, 1, 2, row, row+1, GTK_FILL, 0, 3, 0);
row++;
}
- gtk_widget_show(table);
- gtk_box_pack_start((GtkBox *)((GnomeDruidPageStandard *)page)->vbox, table, FALSE, FALSE, 3);
- gnome_druid_append_page (GNOME_DRUID (hook_data->parent), GNOME_DRUID_PAGE (page));
+ gtk_box_pack_start (GTK_BOX (page), table, FALSE, FALSE, 3);
+
+ gtk_widget_show_all (page);
+ gtk_assistant_append_page (GTK_ASSISTANT (hook_data->parent), page);
+ gtk_assistant_set_page_title (GTK_ASSISTANT (hook_data->parent), page, _("Importing files"));
return page;
}
@@ -188,12 +208,19 @@ import_done(EImport *ei, gpointer d)
void
startup_wizard_commit (EPlugin *ep, EMConfigTargetAccount *target)
{
+ EShell *shell;
+ EShellSettings *shell_settings;
gchar *location;
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
/* Use System Timezone by default */
- calendar_config_set_use_system_timezone (TRUE);
+ e_shell_settings_set_boolean (
+ shell_settings, "cal-use-system-timezone", TRUE);
location = e_cal_util_get_system_timezone_location ();
- calendar_config_set_timezone (location);
+ e_shell_settings_set_string (
+ shell_settings, "cal-timezone-string", location);
g_free (location);
if (import_importers) {
@@ -217,6 +244,5 @@ startup_wizard_commit (EPlugin *ep, EMConfigTargetAccount *target)
void
startup_wizard_abort (EPlugin *ep, EMConfigTargetAccount *target)
{
- gtk_main_quit ();
- _exit (0);
+ startup_wizard_terminate ();
}
diff --git a/plugins/templates/org-gnome-templates.eplug.xml b/plugins/templates/org-gnome-templates.eplug.xml
index 02b14148ad..b4b8a81039 100644
--- a/plugins/templates/org-gnome-templates.eplug.xml
+++ b/plugins/templates/org-gnome-templates.eplug.xml
@@ -7,30 +7,22 @@
_name="Templates">
<_description>Drafts based template plugin</_description>
<author name="Bharath Acharya" email="abharath@novell.com"/>
- <author name="Diego Escalante Urrelo" email="diegoe@gnome.org"/>
+ <author name="Diego Escalante Urrelo" email="diegoe@gnome.org"/>
- <!-- hook into the mail popup menu -->
- <hook class="org.gnome.evolution.mail.popup:1.0">
- <menu
- id="org.gnome.evolution.mail.folderview.popup"
- target="select"
- factory="org_gnome_templates_popup">
- </menu>
+ <hook class="org.gnome.evolution.ui:1.0">
+ <ui-manager id="org.gnome.evolution.shell"/>
+ <ui-manager id="org.gnome.evolution.composer">
+ <menubar name='main-menu'>
+ <placeholder name='pre-edit-menu'>
+ <menu action='file-menu'>
+ <placeholder name="template-holder">
+ <menuitem action="template"/>
+ </placeholder>
+ </menu>
+ </placeholder>
+ </menubar>
+ </ui-manager>
</hook>
-
- <hook class="org.gnome.evolution.ui:1.0">
- <ui-manager id="org.gnome.evolution.composer">
- <menubar name='main-menu'>
- <placeholder name='pre-edit-menu'>
- <menu action='file-menu'>
- <placeholder name="template-holder">
- <menuitem action="Template"/>
- </placeholder>
- </menu>
- </placeholder>
- </menubar>
- </ui-manager>
- </hook>
</e-plugin>
</e-plugin-list>
diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c
index 4e03245e54..81f6bd7025 100644
--- a/plugins/templates/templates.c
+++ b/plugins/templates/templates.c
@@ -27,6 +27,7 @@
#include <glib/gi18n.h>
#include <string.h>
+#include <glade/glade.h>
#include <gconf/gconf-client.h>
#include <e-util/e-config.h>
@@ -34,14 +35,17 @@
#include <camel/camel-multipart.h>
#include <camel/camel-stream-mem.h>
+#include <mail/e-mail-local.h>
+#include <mail/e-mail-reader.h>
#include <mail/em-composer-utils.h>
-#include <mail/em-popup.h>
+#include <mail/em-utils.h>
#include <mail/mail-session.h>
-#include <mail/mail-component.h>
#include <mail/mail-ops.h>
+#include <mail/message-list.h>
#include <e-util/e-error.h>
#include <e-util/e-plugin.h>
-#include <glade/glade.h>
+#include <e-util/e-util.h>
+#include <shell/e-shell-view.h>
#include <composer/e-msg-composer.h>
@@ -63,32 +67,10 @@ enum {
CLUE_N_COLUMNS
};
-typedef struct {
- CamelMimeMessage *msg;
- EMPopupTargetSelect *t;
-} UserData;
-
-static gchar * get_content (CamelMimeMessage *message);
-
-static void reply_with_template (EPopup *ep, EPopupItem *item, gpointer data);
-
-static void popup_free (EPopup *ep, GSList *l, gpointer data);
-
-static GSList *fill_submenu (CamelStore *store,
- CamelFolderInfo *info,
- GSList *list,
- EMPopupTargetSelect *t);
-
-static GSList *append_to_menu (CamelFolder *folder,
- GPtrArray *uids,
- GSList *list,
- EMPopupTargetSelect *t);
-
-void org_gnome_templates_popup (EPlugin *ep, EMPopupTargetSelect *t);
-
GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl);
-gboolean e_plugin_ui_init (GtkUIManager *ui_manager, EMsgComposer *composer);
+gboolean e_plugin_ui_init (GtkUIManager *ui_manager, GObject *object);
+gint e_plugin_lib_enable (EPlugin *plugin, gboolean enabled);
/* Thanks to attachment reminder plugin for this*/
static void commit_changes (UIData *ui);
@@ -102,6 +84,8 @@ static void value_cell_edited_callback (GtkCellRendererText *cell, gchar *path_
static gboolean clue_foreach_check_isempty (GtkTreeModel *model, GtkTreePath
*path, GtkTreeIter *iter, UIData *ui);
+static gboolean plugin_enabled;
+
static void
selection_changed (GtkTreeSelection *selection, UIData *ui)
{
@@ -496,32 +480,23 @@ get_content (CamelMimeMessage *message)
}
static void
-reply_with_template (EPopup *ep, EPopupItem *item, gpointer data)
+action_reply_with_template_cb (GtkAction *action,
+ CamelMimeMessage *message)
{
- CamelMimeMessage *new, *template, *reply_to;
- CamelFolder *templates_folder;
+ CamelMimeMessage *new, *template;
+ CamelFolder *folder;
struct _camel_header_raw *header;
- UserData *userdata = item->user_data;
gchar *cont;
- /* We get the templates folder and all the uids of the messages in there */
- templates_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_TEMPLATES);
-
- /* Get from the currently selected folder, the currently selected message */
- reply_to = camel_folder_get_message (userdata->t->folder,
- g_ptr_array_index (userdata->t->uids, 0),
- NULL);
-
- /* The message we'll be using has been stored when building the menu */
- template = userdata->msg;
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_TEMPLATES);
+ template = g_object_get_data (G_OBJECT (action), "template");
/* The new message we are creating */
new = camel_mime_message_new();
/* Add the headers from the message we are replying to, so CC and that
- * stuff is preserved.
- */
- header = ((CamelMimePart *)reply_to)->headers;
+ * stuff is preserved. */
+ header = ((CamelMimePart *)message)->headers;
while (header) {
if (g_ascii_strncasecmp (header->name, "content-", 8) != 0) {
camel_medium_add_header((CamelMedium *) new,
@@ -538,7 +513,7 @@ reply_with_template (EPopup *ep, EPopupItem *item, gpointer data)
/* Set the To: field to the same To: field of the message we are replying to. */
camel_mime_message_set_recipients (new, CAMEL_RECIPIENT_TYPE_TO,
- camel_mime_message_get_from (reply_to));
+ camel_mime_message_get_from (message));
/* Copy the CC and BCC from the template.*/
camel_mime_message_set_recipients (new, CAMEL_RECIPIENT_TYPE_CC,
@@ -551,160 +526,144 @@ reply_with_template (EPopup *ep, EPopupItem *item, gpointer data)
cont, (gint) g_utf8_strlen(cont, -1), "text");
/* Create the composer */
- em_utils_edit_message (new, templates_folder);
+ em_utils_edit_message (new, folder);
camel_object_unref(new);
}
static void
-popup_free (EPopup *ep, GSList *l, gpointer data)
+build_template_menus_recurse (GtkUIManager *ui_manager,
+ GtkActionGroup *action_group,
+ const gchar *menu_path,
+ guint *action_count,
+ guint merge_id,
+ CamelFolderInfo *folder_info,
+ CamelMimeMessage *message)
{
- g_slist_free (l);
-}
+ CamelStore *store;
-static GSList
-*append_to_menu (CamelFolder *folder, GPtrArray *uids, GSList *list, EMPopupTargetSelect *t)
-{
- gint i;
+ store = e_mail_local_get_store ();
- for (i = 0; i < uids->len; i++) {
- const gchar *subject;
+ while (folder_info != NULL) {
+ CamelFolder *folder;
+ GPtrArray *uids;
+ GtkAction *action;
+ const gchar *action_label;
+ gchar *action_name;
gchar *path;
- EPopupItem *item;
- CamelMimeMessage *message;
- UserData *user_data;
- const gchar *uid;
-
- uid = g_strdup (g_ptr_array_index (uids, i));
-
- /* Same as in fill_submenu */
- if (!g_str_has_suffix (folder->name, "Templates"))
- path = g_strdup_printf ("80.%s", folder->full_name);
- else
- path = g_strdup ("80.Templates");
-
- /* If this uid is trashed, ignore it */
- if (camel_folder_get_message_flags (folder, uid) & CAMEL_MESSAGE_DELETED)
- continue;
-
- /* Get the message for this uid */
- message = camel_folder_get_message (folder,
- uid,
- NULL);
+ guint ii;
- subject = camel_mime_message_get_subject (message);
+ folder = camel_store_get_folder (
+ store, folder_info->full_name, 0, NULL);
- /* Create the menu item for it */
- item = g_slice_alloc0(sizeof(*item));
- item->type = E_POPUP_ITEM;
- item->path = g_strdup_printf ("%s/%02d", path, i);
- item->label = g_strdup ((strlen(subject) > 0) ? subject : _("No title"));
- item->visible = EM_POPUP_SELECT_MANY | EM_POPUP_SELECT_ONE;
+ action_name = g_strdup_printf (
+ "templates-menu-%d", *action_count);
+ *action_count = *action_count + 1;
- /* Make some info available to the callback */
- user_data = g_slice_new(UserData);
- user_data->msg = message;
- user_data->t = t;
-
- item->user_data = user_data;
- item->activate = reply_with_template;
-
- list = g_slist_prepend (list, item);
- }
+ /* To avoid having a Templates dir, we ignore the top level */
+ if (g_str_has_suffix (folder->name, "Templates"))
+ action_label = _("Templates");
+ else
+ action_label = folder->name;
- return list;
-}
+ action = gtk_action_new (
+ action_name, action_label, NULL, NULL);
-static GSList
-*fill_submenu (CamelStore *store, CamelFolderInfo *info, GSList *list, EMPopupTargetSelect *t)
-{
- while (info) {
- CamelFolder *folder;
- GPtrArray *uids;
- EPopupItem *item;
+ gtk_action_group_add_action (action_group, action);
- folder = camel_store_get_folder (store, info->full_name, 0, NULL);
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id, menu_path, action_name,
+ action_name, GTK_UI_MANAGER_MENU, FALSE);
- item = g_slice_alloc0(sizeof(*item));
- item->type = E_POPUP_SUBMENU;
- item->label = folder->name;
- item->visible = EM_POPUP_SELECT_MANY | EM_POPUP_SELECT_ONE;
+ path = g_strdup_printf ("%s/%s", menu_path, action_name);
- /* To avoid having a Templates dir, we ignore the top level */
- if (!g_str_has_suffix (folder->name, "Templates"))
- item->path = g_strdup_printf ("80.%s", folder->full_name);
- else
- item->path = g_strdup ("80.Templates");
+ g_object_unref (action);
+ g_free (action_name);
- list = g_slist_prepend (list, item);
+ /* Add submenus, if any. */
+ if (folder_info->child != NULL)
+ build_template_menus_recurse (
+ ui_manager, action_group,
+ path, action_count, merge_id,
+ folder_info->child, message);
- /* Get the uids for this folder and fill them in the menu */
+ /* Get the UIDs for this folder and add them to the menu. */
uids = camel_folder_get_uids (folder);
- list = append_to_menu (folder, uids, list, t);
- camel_folder_free_uids (folder, uids);
+ for (ii = 0; ii < uids->len; ii++) {
+ CamelMimeMessage *template;
+ const gchar *uid = uids->pdata[ii];
+ guint32 flags;
- /* If the folder has a child, call this function again */
- if (info->child) {
- list = fill_submenu (store, info->child, list, t);
- }
+ /* If the UIDs is marked for deletion, skip it. */
+ flags = camel_folder_get_message_flags (folder, uid);
+ if (flags & CAMEL_MESSAGE_DELETED)
+ continue;
- info = info->next;
- }
+ template = camel_folder_get_message (folder, uid, NULL);
+ camel_object_ref (template);
- return list;
-}
+ action_label =
+ camel_mime_message_get_subject (template);
+ if (action_label == NULL || *action_label == '\0')
+ action_label = _("No Title");
-void
-org_gnome_templates_popup (EPlugin *ep, EMPopupTargetSelect *t)
-{
- CamelFolder *templates_folder;
- CamelFolderInfo *templates_info;
- CamelStore *store;
+ action_name = g_strdup_printf (
+ "templates-item-%d", *action_count);
+ *action_count = *action_count + 1;
- GSList *list = NULL;
+ action = gtk_action_new (
+ action_name, action_label, NULL, NULL);
- /* We get the templates folder and all the uids of the messages in there */
- store = mail_component_peek_local_store (NULL);
+ g_object_set_data_full (
+ G_OBJECT (action), "template", template,
+ (GDestroyNotify) camel_object_unref);
- templates_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_TEMPLATES);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_reply_with_template_cb),
+ message);
- templates_info = camel_store_get_folder_info (store,
- templates_folder->full_name,
- CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_FAST,
- NULL);
+ gtk_action_group_add_action (action_group, action);
- /* Get subfolders and fill it */
- list = fill_submenu (store, templates_info, list, t);
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id, path, action_name,
+ action_name, GTK_UI_MANAGER_MENUITEM, FALSE);
- e_popup_add_items (t->target.popup, list, NULL, popup_free, NULL);
+ g_object_unref (action);
+ g_free (action_name);
+ }
+ camel_folder_free_uids (folder, uids);
+
+ g_free (path);
- return;
+ folder_info = folder_info->next;
+ }
}
static void
action_template_cb (GtkAction *action,
- EMsgComposer *composer)
+ EMsgComposer *composer)
{
CamelMessageInfo *info;
CamelMimeMessage *msg;
- CamelFolder *templates_folder;
+ CamelFolder *folder;
+
+ /* Get the templates folder and all UIDs of the messages there. */
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_TEMPLATES);
- /* We get the templates folder and all the uids of the messages in there */
- templates_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_TEMPLATES);
msg = e_msg_composer_get_message_draft (composer);
info = camel_message_info_new (NULL);
/* FIXME: what's the ~0 for? :) */
- camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DRAFT, ~0);
+ camel_message_info_set_flags (
+ info, CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DRAFT, ~0);
- mail_append_mail (templates_folder, msg, info, NULL, composer);
-
- return;
+ mail_append_mail (folder, msg, info, NULL, composer);
}
-static GtkActionEntry entries[] = {
+static GtkActionEntry composer_entries[] = {
- { "Template",
+ { "template",
GTK_STOCK_SAVE,
N_("Save as _Template"),
"<Shift><Control>t",
@@ -712,9 +671,73 @@ static GtkActionEntry entries[] = {
G_CALLBACK (action_template_cb) }
};
-gboolean
-e_plugin_ui_init (GtkUIManager *ui_manager,
- EMsgComposer *composer)
+static void
+update_actions_cb (EShellView *shell_view)
+{
+ EShellContent *shell_content;
+ EShellWindow *shell_window;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ MessageList *message_list;
+ CamelMimeMessage *message;
+ CamelFolderInfo *folder_info;
+ CamelFolder *folder;
+ CamelStore *store;
+ EMailReader *reader;
+ GPtrArray *uids;
+ guint action_count = 0;
+ guint merge_id;
+ gpointer data;
+
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ action_group = e_lookup_action_group (ui_manager, "templates");
+ data = g_object_get_data (G_OBJECT (action_group), "merge-id");
+ merge_id = GPOINTER_TO_UINT (data);
+ g_return_if_fail (merge_id > 0);
+
+ gtk_ui_manager_remove_ui (ui_manager, merge_id);
+ e_action_group_remove_all_actions (action_group);
+
+ if (!plugin_enabled)
+ return;
+
+ reader = E_MAIL_READER (shell_content);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len != 1)
+ goto exit;
+
+ /* This is the source message to use in replying with a template. */
+ message = camel_folder_get_message (folder, uids->pdata[0], NULL);
+
+ /* Now recursively build template submenus in the pop-up menu. */
+
+ store = e_mail_local_get_store ();
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_TEMPLATES);
+
+ folder_info = camel_store_get_folder_info (
+ store, folder->full_name,
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE |
+ CAMEL_STORE_FOLDER_INFO_FAST, NULL);
+
+ build_template_menus_recurse (
+ ui_manager, action_group,
+ "/mail-message-popup/mail-message-templates",
+ &action_count, merge_id, folder_info, message);
+
+exit:
+ em_utils_uids_free (uids);
+}
+
+static gboolean
+init_composer_actions (GtkUIManager *ui_manager,
+ EMsgComposer *composer)
{
GtkhtmlEditor *editor;
@@ -723,7 +746,64 @@ e_plugin_ui_init (GtkUIManager *ui_manager,
/* Add actions to the "composer" action group. */
gtk_action_group_add_actions (
gtkhtml_editor_get_action_group (editor, "composer"),
- entries, G_N_ELEMENTS (entries), composer);
+ composer_entries, G_N_ELEMENTS (composer_entries), composer);
return TRUE;
}
+
+static gboolean
+init_shell_actions (GtkUIManager *ui_manager,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ GtkActionGroup *action_group;
+ guint merge_id;
+
+ shell_view = e_shell_window_get_shell_view (shell_window, "mail");
+
+ /* This is where we keep dynamically-built menu items. */
+ e_shell_window_add_action_group (shell_window, "templates");
+ action_group = e_lookup_action_group (ui_manager, "templates");
+
+ merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+
+ g_object_set_data (
+ G_OBJECT (action_group), "merge-id",
+ GUINT_TO_POINTER (merge_id));
+
+ g_signal_connect (
+ shell_view, "update-actions",
+ G_CALLBACK (update_actions_cb), NULL);
+
+ return TRUE;
+}
+
+gboolean
+e_plugin_ui_init (GtkUIManager *ui_manager,
+ GObject *object)
+{
+ /* XXX This is a scenario I hadn't considered when designing
+ * EPluginUI: two different UI manager IDs with different
+ * closures sharing the same plugin entry point. We know
+ * the closures are both GObjects so we query the type.
+ * Awkward, but it should work for now. */
+
+ if (E_IS_MSG_COMPOSER (object))
+ return init_composer_actions (
+ ui_manager, E_MSG_COMPOSER (object));
+
+ if (E_IS_SHELL_WINDOW (object))
+ return init_shell_actions (
+ ui_manager, E_SHELL_WINDOW (object));
+
+ return FALSE;
+}
+
+gint
+e_plugin_lib_enable (EPlugin *plugin,
+ gboolean enabled)
+{
+ plugin_enabled = enabled;
+
+ return 0;
+}
diff --git a/plugins/tnef-attachments/Makefile.am b/plugins/tnef-attachments/Makefile.am
index d9447f263d..2273e6ed80 100644
--- a/plugins/tnef-attachments/Makefile.am
+++ b/plugins/tnef-attachments/Makefile.am
@@ -8,6 +8,7 @@ endif
AM_CPPFLAGS = \
-I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
-DGETTEXT_PACKAGE="\"$(GETTEXT_PACKAGE)\"" \
-DLOCALEDIR="\"$(localedir)\"" \
$(EVOLUTION_MAIL_CFLAGS) \
@@ -21,7 +22,9 @@ plugin_LTLIBRARIES = liborg-gnome-tnef-attachments.la
liborg_gnome_tnef_attachments_la_SOURCES = tnef-plugin.c
liborg_gnome_tnef_attachments_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_tnef_attachments_la_LIBADD = \
- $(NO_UNDEFINED_REQUIRED_LIBS) \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/em-format/libemformat.la \
+ $(EVOLUTION_MAIL_LIBS) \
-lytnef
EXTRA_DIST = org-gnome-tnef-attachments.eplug.xml
diff --git a/plugins/tnef-attachments/tnef-plugin.c b/plugins/tnef-attachments/tnef-plugin.c
index c03dd39d68..3e537e1dca 100644
--- a/plugins/tnef-attachments/tnef-plugin.c
+++ b/plugins/tnef-attachments/tnef-plugin.c
@@ -46,7 +46,7 @@
#include <camel/camel-multipart.h>
#include <camel/camel-stream-fs.h>
-#include <mail/em-format.h>
+#include <em-format/em-format.h>
#include <mail/em-format-hook.h>
#include <mail/em-utils.h>
#include <e-util/e-error.h>
@@ -158,7 +158,7 @@ org_gnome_format_tnef(gpointer ep, EMFormatHookTarget *t)
camel_medium_set_content_object((CamelMedium *)part, content);
camel_object_unref(content);
- type = em_utils_snoop_type(part);
+ type = em_format_snoop_type(part);
if (type)
camel_data_wrapper_set_mime_type((CamelDataWrapper *)part, type);
@@ -192,10 +192,10 @@ org_gnome_format_tnef(gpointer ep, EMFormatHookTarget *t)
g_free(tmpdir);
}
-gint e_plugin_lib_enable(EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable(EPlugin *ep, gint enable);
gint
-e_plugin_lib_enable(EPluginLib *ep, gint enable)
+e_plugin_lib_enable(EPlugin *ep, gint enable)
{
if (loaded)
return 0;
diff --git a/plugins/vcard-inline/Makefile.am b/plugins/vcard-inline/Makefile.am
index 5a8ed2c88e..dd8f92fd1a 100644
--- a/plugins/vcard-inline/Makefile.am
+++ b/plugins/vcard-inline/Makefile.am
@@ -18,10 +18,13 @@ plugin_LTLIBRARIES = liborg-gnome-vcard-inline.la
liborg_gnome_vcard_inline_la_SOURCES = vcard-inline.c
liborg_gnome_vcard_inline_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
liborg_gnome_vcard_inline_la_LIBADD = \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(EVOLUTION_MAIL_LIBS) \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(NO_UNDEFINED_REQUIRED_LIBS)
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \
+ $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \
+ $(top_builddir)/addressbook/printing/libecontactprint.la \
+ $(EVOLUTION_ADDRESSBOOK_LIBS) \
+ $(EVOLUTION_MAIL_LIBS)
EXTRA_DIST = org-gnome-vcard-inline.eplug.xml
diff --git a/plugins/vcard-inline/vcard-inline.c b/plugins/vcard-inline/vcard-inline.c
index 6c4eeebff6..0aafc8c82d 100644
--- a/plugins/vcard-inline/vcard-inline.c
+++ b/plugins/vcard-inline/vcard-inline.c
@@ -29,9 +29,9 @@
#include <camel/camel-stream-mem.h>
#include <gtkhtml/gtkhtml-embedded.h>
-#include "addressbook/gui/component/addressbook.h"
#include "addressbook/gui/merging/eab-contact-merging.h"
#include "addressbook/gui/widgets/eab-contact-display.h"
+#include "addressbook/util/addressbook.h"
#include "addressbook/util/eab-book-util.h"
#include "mail/em-format-hook.h"
#include "mail/em-format-html.h"
@@ -46,7 +46,6 @@ struct _VCardInlinePObject {
GList *contact_list;
GtkWidget *contact_display;
GtkWidget *message_label;
- EABContactDisplayRenderMode mode;
};
static gint org_gnome_vcard_inline_classid;
@@ -149,25 +148,23 @@ org_gnome_vcard_inline_toggle_cb (VCardInlinePObject *vcard_object,
GtkButton *button)
{
EABContactDisplay *contact_display;
+ EABContactDisplayMode mode;
const gchar *label;
contact_display = EAB_CONTACT_DISPLAY (vcard_object->contact_display);
+ mode = eab_contact_display_get_mode (contact_display);
/* Toggle between "full" and "compact" modes. */
- if (vcard_object->mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) {
- vcard_object->mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
+ if (mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) {
+ mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
label = _("Show Full vCard");
} else {
- vcard_object->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
+ mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
label = _("Show Compact vCard");
}
+ eab_contact_display_set_mode (contact_display, mode);
gtk_button_set_label (button, label);
-
- eab_contact_display_render (
- EAB_CONTACT_DISPLAY (vcard_object->contact_display),
- E_CONTACT (vcard_object->contact_list->data),
- vcard_object->mode);
}
static gboolean
@@ -179,11 +176,16 @@ org_gnome_vcard_inline_embed (EMFormatHTML *format,
GtkWidget *button_box;
GtkWidget *container;
GtkWidget *widget;
+ EContact *contact;
guint length;
vcard_object = (VCardInlinePObject *) object;
length = g_list_length (vcard_object->contact_list);
- g_return_val_if_fail (length > 0, FALSE);
+
+ if (vcard_object->contact_list != NULL)
+ contact = E_CONTACT (vcard_object->contact_list->data);
+ else
+ contact = NULL;
container = GTK_WIDGET (embedded);
@@ -203,15 +205,15 @@ org_gnome_vcard_inline_embed (EMFormatHTML *format,
button_box = widget;
widget = eab_contact_display_new ();
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (widget), contact);
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (widget),
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT);
gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
vcard_object->contact_display = g_object_ref (widget);
gtk_widget_show (widget);
- eab_contact_display_render (
- EAB_CONTACT_DISPLAY (vcard_object->contact_display),
- E_CONTACT (vcard_object->contact_list->data),
- vcard_object->mode);
-
widget = gtk_label_new (NULL);
gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
vcard_object->message_label = g_object_ref (widget);
@@ -280,7 +282,6 @@ org_gnome_vcard_inline_format (gpointer ep, EMFormatHookTarget *target)
camel_object_ref (target->part);
- vcard_object->mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
vcard_object->object.free = org_gnome_vcard_inline_pobject_free;
org_gnome_vcard_inline_decode (vcard_object, target->part);
diff --git a/plugins/webdav-account-setup/webdav-contacts-source.c b/plugins/webdav-account-setup/webdav-contacts-source.c
index b6d4443d4d..990a541cc9 100644
--- a/plugins/webdav-account-setup/webdav-contacts-source.c
+++ b/plugins/webdav-account-setup/webdav-contacts-source.c
@@ -52,7 +52,7 @@ GtkWidget *
plugin_webdav_contacts(EPlugin *epl, EConfigHookItemFactoryData *data);
gint
-e_plugin_lib_enable(EPluginLib *ep, gint enable);
+e_plugin_lib_enable(EPlugin *ep, gint enable);
static void
ensure_webdav_contacts_source_group(void)
@@ -341,7 +341,7 @@ plugin_webdav_contacts(EPlugin *epl, EConfigHookItemFactoryData *data)
}
gint
-e_plugin_lib_enable(EPluginLib *ep, gint enable)
+e_plugin_lib_enable(EPlugin *ep, gint enable)
{
if (enable) {
ensure_webdav_contacts_source_group();
diff --git a/po/ChangeLog b/po/ChangeLog
index 1f850530fb..f528c040ed 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,11 +1,3 @@
-2009-06-09 Manoj Kumar Giri <mgiri@redhat.com>
-
- * or.po: Updated Oriya Translation.
-
-2009-06-04 Manoj Kumar Giri <mgiri@redhat.com>
-
- * or.po: Updated Oriya Translation
-
2009-06-04 Manoj Kumar Giri <mgiri@redhat.com>
* or.po: Updated Oriya Translation
@@ -111,12 +103,10 @@
* or.po: Updated Oriya Translation.
-<<<<<<< .mine
2009-03-16 Manoj Kumar Giri <mgiri@redhat.com>
* or.po: Updated Oriya Translation.
-=======
2009-03-16 Dwayne Bailey <dwayne@translate.org.za>
* af.po: Fix msgfmt errors
@@ -127,7 +117,6 @@
Fixes bug #575466.
* LINGUAS: Added af.
->>>>>>> .r37444
2009-03-15 Daniel Nylander <po@danielnylander.se>
* sv.po: Updated Swedish translation.
@@ -425,9 +414,9 @@
* es.po: Updated Spanish translation.
-2009-02-06 Clytie Siddall <clytie@riverland.net.au>
+2009-02-06 Clytie Siddall <clytie@riverland.net.au>
- * vi.po: Updated Vietnamese translation
+ * vi.po Updated Vietnamese translation
2009-02-05 Sweta Kothari <swkothar@redhat.com>
diff --git a/po/LINGUAS b/po/LINGUAS
index 52f5410677..676422d11e 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -6,7 +6,6 @@ ar
as
ast
az
-be
be@latin
bg
bn
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4880ff848b..9319943ce3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,36 +1,7 @@
# List of source files containing translatable strings.
# Please keep this list in alphabetic order.
-a11y/addressbook/ea-addressbook-view.c
-a11y/addressbook/ea-minicard-view.c
-a11y/addressbook/ea-minicard.c
-a11y/calendar/ea-cal-view-event.c
-a11y/calendar/ea-cal-view.c
-a11y/calendar/ea-day-view-main-item.c
-a11y/calendar/ea-day-view.c
-a11y/calendar/ea-gnome-calendar.c
-a11y/calendar/ea-jump-button.c
-a11y/calendar/ea-week-view-main-item.c
-a11y/calendar/ea-week-view.c
-a11y/e-table/gal-a11y-e-cell-popup.c
-a11y/e-table/gal-a11y-e-cell-text.c
-a11y/e-table/gal-a11y-e-cell-toggle.c
-a11y/e-table/gal-a11y-e-cell-tree.c
-a11y/e-table/gal-a11y-e-cell.c
-a11y/e-table/gal-a11y-e-table-click-to-add.c
-a11y/e-table/gal-a11y-e-table-column-header.c
-a11y/widgets/ea-calendar-item.c
-a11y/widgets/ea-combo-button.c
addressbook/addressbook.error.xml
addressbook/conduit/address-conduit.c
-addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in
-addressbook/gui/component/addressbook-component.c
-addressbook/gui/component/addressbook-config.c
-addressbook/gui/component/addressbook-migrate.c
-addressbook/gui/component/addressbook-view.c
-addressbook/gui/component/addressbook.c
-addressbook/gui/component/apps_evolution_addressbook.schemas.in
-addressbook/gui/component/autocompletion-config.c
-addressbook/gui/component/ldap-config.glade
addressbook/gui/contact-editor/contact-editor.glade
addressbook/gui/contact-editor/e-contact-editor-fullname.c
addressbook/gui/contact-editor/e-contact-editor.c
@@ -52,9 +23,11 @@ addressbook/gui/widgets/e-minicard-label.c
addressbook/gui/widgets/e-minicard-view-widget.c
addressbook/gui/widgets/e-minicard-view.c
addressbook/gui/widgets/e-minicard.c
+addressbook/gui/widgets/ea-addressbook-view.c
+addressbook/gui/widgets/ea-minicard-view.c
+addressbook/gui/widgets/ea-minicard.c
addressbook/gui/widgets/eab-contact-display.c
addressbook/gui/widgets/eab-gui-util.c
-addressbook/gui/widgets/eab-popup-control.c
addressbook/gui/widgets/gal-view-factory-minicard.c
addressbook/importers/evolution-csv-importer.c
addressbook/importers/evolution-ldif-importer.c
@@ -64,12 +37,12 @@ addressbook/printing/test-print.c
addressbook/tools/evolution-addressbook-export-list-cards.c
addressbook/tools/evolution-addressbook-export-list-folders.c
addressbook/tools/evolution-addressbook-export.c
+addressbook/util/addressbook.c
calendar/calendar.error.xml
calendar/common/authentication.c
calendar/conduits/calendar/calendar-conduit.c
calendar/conduits/memo/memo-conduit.c
calendar/conduits/todo/todo-conduit.c
-calendar/gui/GNOME_Evolution_Calendar.server.in.in
calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.server.in.in
calendar/gui/alarm-notify/alarm-notify-dialog.c
calendar/gui/alarm-notify/alarm-notify.glade
@@ -78,13 +51,8 @@ calendar/gui/alarm-notify/notify-main.c
calendar/gui/alarm-notify/util.c
calendar/gui/apps_evolution_calendar.schemas.in
calendar/gui/cal-editor-utils.c
-calendar/gui/cal-search-bar.c
-calendar/gui/calendar-commands.c
-calendar/gui/calendar-component.c
calendar/gui/calendar-view-factory.c
calendar/gui/caltypes.xml
-calendar/gui/comp-editor-factory.c
-calendar/gui/control-factory.c
calendar/gui/dialogs/alarm-dialog.c
calendar/gui/dialogs/alarm-dialog.glade
calendar/gui/dialogs/alarm-list-dialog.c
@@ -123,14 +91,12 @@ calendar/gui/dialogs/task-page.c
calendar/gui/dialogs/task-page.glade
calendar/gui/e-alarm-list.c
calendar/gui/e-attachment-handler-calendar.c
-calendar/gui/e-cal-component-memo-preview.c
calendar/gui/e-cal-component-preview.c
calendar/gui/e-cal-list-view.c
calendar/gui/e-cal-list-view.etspec
calendar/gui/e-cal-model-calendar.c
calendar/gui/e-cal-model-tasks.c
calendar/gui/e-cal-model.c
-calendar/gui/e-cal-popup.c
calendar/gui/e-calendar-table.c
calendar/gui/e-calendar-table.etspec
calendar/gui/e-calendar-view.c
@@ -147,30 +113,30 @@ calendar/gui/e-meeting-time-sel.c
calendar/gui/e-meeting-time-sel.etspec
calendar/gui/e-memo-table.c
calendar/gui/e-memo-table.etspec
-calendar/gui/e-memos.c
-calendar/gui/e-tasks.c
calendar/gui/e-timezone-entry.c
calendar/gui/e-week-view-main-item.c
calendar/gui/e-week-view.c
+calendar/gui/ea-cal-view-event.c
+calendar/gui/ea-cal-view.c
+calendar/gui/ea-day-view-main-item.c
+calendar/gui/ea-day-view.c
+calendar/gui/ea-gnome-calendar.c
+calendar/gui/ea-jump-button.c
+calendar/gui/ea-week-view-main-item.c
+calendar/gui/ea-week-view.c
calendar/gui/gnome-cal.c
calendar/gui/goto-dialog.glade
calendar/gui/goto.c
calendar/gui/itip-utils.c
-calendar/gui/memos-component.c
-calendar/gui/memos-control.c
calendar/gui/memotypes.xml
-calendar/gui/migration.c
calendar/gui/misc.c
calendar/gui/print.c
-calendar/gui/tasks-component.c
-calendar/gui/tasks-control.c
calendar/gui/tasktypes.xml
calendar/gui/weekday-picker.c
calendar/importers/icalendar-importer.c
calendar/zones.h
-composer/e-composer-autosave.c
composer/e-composer-actions.c
-composer/e-composer-header.c
+composer/e-composer-autosave.c
composer/e-composer-header-table.c
composer/e-composer-name-header.c
composer/e-composer-post-header.c
@@ -180,10 +146,12 @@ composer/mail-composer.error.xml
data/evolution.desktop.in.in
data/evolution.keys.in.in
e-util/e-categories-config.c
+e-util/e-charset.c
e-util/e-datetime-format.c
e-util/e-dialog-utils.c
e-util/e-error.c
e-util/e-logger.c
+e-util/e-module.c
e-util/e-non-intrusive-error-dialog.c
e-util/e-non-intrusive-error-dialog.h
e-util/e-plugin.c
@@ -191,8 +159,9 @@ e-util/e-print.c
e-util/e-signature.c
e-util/e-system.error.xml
e-util/e-util.c
-e-util/e-util-labels.c
e-util/gconf-bridge.c
+em-format/em-format-quote.c
+em-format/em-format.c
filter/filter-datespec.c
filter/filter-file.c
filter/filter-input.c
@@ -203,35 +172,34 @@ filter/filter.error.xml
filter/filter.glade
filter/rule-context.c
filter/rule-editor.c
-mail/GNOME_Evolution_Mail.server.in.in
-mail/e-attachment-handler-mail.c
mail/e-mail-attachment-bar.c
+mail/e-mail-browser.c
+mail/e-mail-display.c
+mail/e-mail-label-dialog.c
+mail/e-mail-label-list-store.c
+mail/e-mail-label-manager.c
+mail/e-mail-label-tree-view.c
+mail/e-mail-local.c
+mail/e-mail-reader-utils.c
+mail/e-mail-reader.c
mail/e-mail-search-bar.c
+mail/e-mail-store.c
mail/em-account-editor.c
-mail/em-account-prefs.c
-mail/em-composer-prefs.c
mail/em-composer-utils.c
mail/em-filter-editor.c
mail/em-filter-folder-element.c
mail/em-filter-i18n.h
mail/em-filter-rule.c
-mail/em-folder-browser.c
mail/em-folder-properties.c
mail/em-folder-selection-button.c
mail/em-folder-selector.c
mail/em-folder-tree-model.c
mail/em-folder-tree.c
mail/em-folder-utils.c
-mail/em-folder-view.c
mail/em-format-html-display.c
mail/em-format-html-print.c
mail/em-format-html.c
-mail/em-format-quote.c
-mail/em-format.c
mail/em-junk-hook.c
-mail/em-mailer-prefs.c
-mail/em-migrate.c
-mail/em-popup.c
mail/em-subscribe-editor.c
mail/em-utils.c
mail/em-vfolder-editor.c
@@ -242,17 +210,14 @@ mail/importers/evolution-mbox-importer.c
mail/importers/mail-importer.c
mail/importers/pine-importer.c
mail/mail-autofilter.c
-mail/mail-component.c
mail/mail-config.c
mail/mail-config.glade
-mail/mail-crypto.c
mail/mail-dialogs.glade
mail/mail-folder-cache.c
mail/mail-mt.c
mail/mail-ops.c
mail/mail-send-recv.c
mail/mail-session.c
-mail/mail-signature-editor.c
mail/mail-tools.c
mail/mail-vfolder.c
mail/mail.error.xml
@@ -261,18 +226,61 @@ mail/message-list.etspec
mail/message-tag-editor.c
mail/message-tag-followup.c
mail/searchtypes.xml
+modules/addressbook/addressbook-config.c
+modules/addressbook/apps_evolution_addressbook.schemas.in
+modules/addressbook/autocompletion-config.c
+modules/addressbook/e-book-shell-backend.c
+modules/addressbook/e-book-shell-content.c
+modules/addressbook/e-book-shell-migrate.c
+modules/addressbook/e-book-shell-sidebar.c
+modules/addressbook/e-book-shell-view-actions.c
+modules/addressbook/e-book-shell-view.c
+modules/addressbook/eab-composer-util.c
+modules/addressbook/ldap-config.glade
+modules/calendar/e-cal-shell-backend.c
+modules/calendar/e-cal-shell-content.c
+modules/calendar/e-cal-shell-migrate.c
+modules/calendar/e-cal-shell-sidebar.c
+modules/calendar/e-cal-shell-view-actions.c
+modules/calendar/e-cal-shell-view-memopad.c
+modules/calendar/e-cal-shell-view-private.c
+modules/calendar/e-cal-shell-view-taskpad.c
+modules/calendar/e-cal-shell-view.c
+modules/calendar/e-memo-shell-backend.c
+modules/calendar/e-memo-shell-content.c
+modules/calendar/e-memo-shell-migrate.c
+modules/calendar/e-memo-shell-sidebar.c
+modules/calendar/e-memo-shell-view-actions.c
+modules/calendar/e-memo-shell-view-private.c
+modules/calendar/e-memo-shell-view.c
+modules/calendar/e-task-shell-backend.c
+modules/calendar/e-task-shell-content.c
+modules/calendar/e-task-shell-migrate.c
+modules/calendar/e-task-shell-sidebar.c
+modules/calendar/e-task-shell-view-actions.c
+modules/calendar/e-task-shell-view-private.c
+modules/calendar/e-task-shell-view.c
+modules/mail/e-attachment-handler-mail.c
+modules/mail/e-mail-shell-backend.c
+modules/mail/e-mail-shell-content.c
+modules/mail/e-mail-shell-migrate.c
+modules/mail/e-mail-shell-view-actions.c
+modules/mail/e-mail-shell-view-private.c
+modules/mail/e-mail-shell-view.c
+modules/mail/em-account-prefs.c
+modules/mail/em-composer-prefs.c
+modules/mail/em-mailer-prefs.c
plugins/addressbook-file/org-gnome-addressbook-file.eplug.xml
plugins/attachment-reminder/apps-evolution-attachment-reminder.schemas.in
plugins/attachment-reminder/attachment-reminder.c
plugins/attachment-reminder/attachment-reminder.glade
-plugins/attachment-reminder/org-gnome-evolution-attachment-reminder.eplug.xml
plugins/attachment-reminder/org-gnome-attachment-reminder.error.xml
+plugins/attachment-reminder/org-gnome-evolution-attachment-reminder.eplug.xml
plugins/audio-inline/org-gnome-audio-inline.eplug.xml
plugins/backup-restore/backup-restore.c
plugins/backup-restore/backup.c
plugins/backup-restore/org-gnome-backup-restore.eplug.xml
plugins/backup-restore/org-gnome-backup-restore.error.xml
-plugins/backup-restore/org-gnome-backup-restore.xml
plugins/bbdb/bbdb.c
plugins/bbdb/org-gnome-evolution-bbdb.eplug.xml
plugins/bogo-junk-plugin/bf-junk-filter.c
@@ -286,17 +294,16 @@ plugins/calendar-http/calendar-http.c
plugins/calendar-http/org-gnome-calendar-http.eplug.xml
plugins/calendar-weather/calendar-weather.c
plugins/calendar-weather/org-gnome-calendar-weather.eplug.xml
-plugins/copy-tool/org-gnome-copy-tool.eplug.xml
plugins/default-mailer/apps-evolution-mail-prompts-checkdefault.schemas.in
plugins/default-mailer/org-gnome-default-mailer.eplug.xml
plugins/default-mailer/org-gnome-default-mailer.error.xml
plugins/default-source/default-source.c
plugins/default-source/org-gnome-default-source.eplug.xml
+plugins/email-custom-header/apps_evolution_email_custom_header.schemas.in
plugins/email-custom-header/email-custom-header.c
plugins/email-custom-header/email-custom-header.glade
-plugins/email-custom-header/org-gnome-email-custom-header.glade
plugins/email-custom-header/org-gnome-email-custom-header.eplug.xml
-plugins/email-custom-header/apps_evolution_email_custom_header.schemas.in
+plugins/email-custom-header/org-gnome-email-custom-header.glade
plugins/exchange-operations/e-foreign-folder-dialog.glade
plugins/exchange-operations/exchange-account-setup.c
plugins/exchange-operations/exchange-calendar.c
@@ -327,15 +334,13 @@ plugins/exchange-operations/org-gnome-exchange-tasks-subscription.xml
plugins/exchange-operations/org-gnome-folder-permissions.xml
plugins/exchange-operations/org-gnome-folder-subscription.xml
plugins/external-editor/apps-evolution-external-editor.schemas.in
+plugins/external-editor/external-editor.c
plugins/external-editor/org-gnome-external-editor.eplug.xml
plugins/external-editor/org-gnome-external-editor.error.xml
-plugins/external-editor/external-editor.c
plugins/face/face.c
plugins/face/org-gnome-face.eplug.xml
-plugins/folder-unsubscribe/folder-unsubscribe.c
-plugins/folder-unsubscribe/org-gnome-mail-folder-unsubscribe.eplug.xml
-plugins/google-account-setup/google-source.c
plugins/google-account-setup/google-contacts-source.c
+plugins/google-account-setup/google-source.c
plugins/google-account-setup/org-gnome-evolution-google.eplug.xml
plugins/groupwise-account-setup/camel-gw-listener.c
plugins/groupwise-account-setup/org-gnome-gw-account-setup.eplug.xml
@@ -374,14 +379,11 @@ plugins/itip-formatter/itip-formatter.c
plugins/itip-formatter/itip-view.c
plugins/itip-formatter/org-gnome-itip-formatter.eplug.xml
plugins/itip-formatter/org-gnome-itip-formatter.error.xml
-plugins/mail-account-disable/mail-account-disable.c
-plugins/mail-account-disable/org-gnome-mail-account-disable.eplug.xml
plugins/mail-notification/apps-evolution-mail-notification.schemas.in
plugins/mail-notification/mail-notification.c
plugins/mail-notification/org-gnome-mail-notification.eplug.xml
plugins/mail-to-task/mail-to-task.c
plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
-plugins/mail-to-task/org-gnome-mail-to-task.xml
plugins/mailing-list-actions/org-gnome-mailing-list-actions.eplug.xml
plugins/mailing-list-actions/org-gnome-mailing-list-actions.error.xml
plugins/mailing-list-actions/org-gnome-mailing-list-actions.xml
@@ -389,7 +391,6 @@ plugins/mark-all-read/mark-all-read.c
plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
plugins/mono/org-gnome-evolution-mono.eplug.xml
plugins/plugin-manager/org-gnome-plugin-manager.eplug.xml
-plugins/plugin-manager/org-gnome-plugin-manager.xml
plugins/plugin-manager/plugin-manager.c
plugins/prefer-plain/org-gnome-prefer-plain.eplug.xml
plugins/prefer-plain/prefer-plain.c
@@ -413,38 +414,36 @@ plugins/save-calendar/ical-format.c
plugins/save-calendar/org-gnome-save-calendar.eplug.xml
plugins/save-calendar/rdf-format.c
plugins/save-calendar/save-calendar.c
-plugins/select-one-source/org-gnome-select-one-source.eplug.xml
plugins/startup-wizard/org-gnome-evolution-startup-wizard.eplug.xml
plugins/startup-wizard/startup-wizard.c
plugins/subject-thread/org-gnome-subject-thread.eplug.xml
plugins/subject-thread/subject-thread.c
plugins/templates/apps-evolution-template-placeholders.schemas.in
+plugins/templates/org-gnome-templates.eplug.xml
plugins/templates/templates.c
plugins/templates/templates.glade
-plugins/templates/org-gnome-templates.eplug.xml
plugins/tnef-attachments/org-gnome-tnef-attachments.eplug.xml
plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml
plugins/vcard-inline/vcard-inline.c
plugins/webdav-account-setup/org-gnome-evolution-webdav.eplug.xml
plugins/webdav-account-setup/webdav-contacts-source.c
-shell/GNOME_Evolution_Shell.server.in.in
-shell/test/GNOME_Evolution_Test.server.in.in
shell/apps_evolution_shell.schemas.in
-shell/e-active-connection-dialog.glade
-shell/e-component-registry.c
shell/e-config-upgrade.c
+shell/e-shell-backend.c
+shell/e-shell-content.c
shell/e-shell-importer.c
-shell/e-shell-settings-dialog.c
+shell/e-shell-migrate.c
+shell/e-shell-switcher.c
shell/e-shell-view.c
-shell/e-shell-window-commands.c
+shell/e-shell-window-actions.c
+shell/e-shell-window-private.c
shell/e-shell-window.c
shell/e-shell.c
-shell/e-user-creatable-items-handler.c
-shell/evolution-shell-component-utils.c
-shell/test/evolution-test-component.c
-shell/import.glade
shell/main.c
shell/shell.error.xml
+shell/test/e-test-shell-backend.c
+smclient/eggdesktopfile.c
+smclient/eggsmclient.c
smime/gui/ca-trust-dialog.c
smime/gui/cert-trust-dialog.c
smime/gui/certificate-manager.c
@@ -456,15 +455,6 @@ smime/lib/e-cert-db.c
smime/lib/e-cert.c
smime/lib/e-pkcs12.c
tools/killev.c
-ui/evolution-addressbook.xml
-ui/evolution-calendar.xml
-ui/evolution-mail-global.xml
-ui/evolution-mail-list.xml
-ui/evolution-mail-message.xml
-ui/evolution-mail-messagedisplay.xml
-ui/evolution-memos.xml
-ui/evolution-tasks.xml
-ui/evolution.xml
views/addressbook/galview.xml
views/calendar/galview.xml
views/mail/galview.xml
@@ -479,10 +469,13 @@ widgets/menus/gal-view-factory-etable.c
widgets/menus/gal-view-instance-save-as-dialog.c
widgets/menus/gal-view-instance-save-as-dialog.glade
widgets/menus/gal-view-instance.c
-widgets/menus/gal-view-menus.c
widgets/menus/gal-view-new-dialog.c
widgets/menus/gal-view-new-dialog.glade
-widgets/misc/e-attachment.c
+widgets/misc/e-account-manager.c
+widgets/misc/e-account-tree-view.c
+widgets/misc/e-action-combo-box.c
+widgets/misc/e-activity-proxy.c
+widgets/misc/e-activity.c
widgets/misc/e-attachment-dialog.c
widgets/misc/e-attachment-handler-image.c
widgets/misc/e-attachment-handler-sendto.c
@@ -491,31 +484,34 @@ widgets/misc/e-attachment-paned.c
widgets/misc/e-attachment-store.c
widgets/misc/e-attachment-tree-view.c
widgets/misc/e-attachment-view.c
+widgets/misc/e-attachment.c
widgets/misc/e-calendar-item.c
widgets/misc/e-calendar.c
widgets/misc/e-canvas-background.c
widgets/misc/e-canvas-vbox.c
-widgets/misc/e-cell-date-edit.c
-widgets/misc/e-cell-percent.c
-widgets/misc/e-charset-picker.c
+widgets/misc/e-charset-combo-box.c
widgets/misc/e-dateedit.c
-widgets/misc/e-filter-bar.c
-widgets/misc/e-filter-bar.h
widgets/misc/e-image-chooser.c
widgets/misc/e-map.c
widgets/misc/e-online-button.c
+widgets/misc/e-paned.c
widgets/misc/e-pilot-settings.c
-widgets/misc/e-reflow.c
-widgets/misc/e-search-bar.c
+widgets/misc/e-popup-action.c
+widgets/misc/e-preferences-window.c
widgets/misc/e-selection-model-array.c
widgets/misc/e-selection-model.c
widgets/misc/e-send-options.c
widgets/misc/e-send-options.glade
widgets/misc/e-signature-combo-box.c
-widgets/misc/e-task-widget.c
+widgets/misc/e-signature-editor.c
+widgets/misc/e-signature-manager.c
+widgets/misc/e-signature-script-dialog.c
widgets/misc/e-url-entry.c
+widgets/misc/ea-calendar-item.c
widgets/table/e-cell-combo.c
+widgets/table/e-cell-date-edit.c
widgets/table/e-cell-date.c
+widgets/table/e-cell-percent.c
widgets/table/e-cell-pixbuf.c
widgets/table/e-cell-text.c
widgets/table/e-table-click-to-add.c
@@ -538,4 +534,11 @@ widgets/table/e-table.c
widgets/table/e-tree-scrolled.c
widgets/table/e-tree-selection-model.c
widgets/table/e-tree.c
+widgets/table/gal-a11y-e-cell-popup.c
+widgets/table/gal-a11y-e-cell-text.c
+widgets/table/gal-a11y-e-cell-toggle.c
+widgets/table/gal-a11y-e-cell-tree.c
+widgets/table/gal-a11y-e-cell.c
+widgets/table/gal-a11y-e-table-click-to-add.c
+widgets/table/gal-a11y-e-table-column-header.c
widgets/text/e-text.c
diff --git a/po/et.po b/po/et.po
index 9ab01d5f14..1f66845cd4 100644
--- a/po/et.po
+++ b/po/et.po
@@ -3708,8 +3708,10 @@ msgstr "_Hiljutised dokumendid"
msgid "Attach"
msgstr "Manusta"
+#, fuzzy
+#| msgid "_Save"
msgid "Save"
-msgstr "Salvesta"
+msgstr "_Salvesta"
msgid "Changes made to this item may be discarded if an update arrives"
msgstr ""
@@ -3819,12 +3821,9 @@ msgstr "Sünd_mus"
msgid "Event cannot be edited, because the selected calendar is read only"
msgstr ""
-"Sündmust pole võimalik redigeerida, kuna valitud kalender on kirjutuskaitsega"
msgid "Event cannot be fully edited, because you are not the organizer"
msgstr ""
-"Sündmust pole võimalik täielikult redigeerida, kuna sina pole selle "
-"organiseerija"
msgid "This event has alarms"
msgstr "See sündmus on alarmidega"
@@ -10136,6 +10135,11 @@ msgstr "Kasutaja_nimi:"
msgid "V_ariable-width:"
msgstr "_Muutuva laiusega:"
+#, fuzzy
+#| msgid ""
+#| "Welcome to the Evolution Mail Configuration Assistant.\n"
+#| "\n"
+#| "Click \"Forward\" to begin. "
msgid ""
"Welcome to the Evolution Mail Configuration Assistant.\n"
"\n"
@@ -12619,40 +12623,6 @@ msgstr ""
msgid "Account &quot;{0}&quot; already exists. Please check your folder tree."
msgstr "Konto &quot;{0}&quot; on juba olemas. Palun kontrolli oma kaustapuud."
-msgid "Account Already Exists"
-msgstr "Konto on juba olemas"
-
-msgid "Invalid user"
-msgstr "Vigane kasutaja"
-
-msgid ""
-"Proxy login as &quot;{0}&quot; was unsuccessful. Please check your email "
-"address and try again."
-msgstr ""
-"Proksisse kasutajana &quot;{0}&quot; sisselogimine nurjus. Palun kontrolli "
-"oma e-posti aadressi ja proovi uuesti."
-
-#. To Translators: In this case, Proxy does not mean something like 'HTTP Proxy', but a GroupWise feature by which one person can send/read mails/appointments using another person's identity without knowing his password, for example if that other person is on vacation
-msgid "Proxy access cannot be given to user &quot;{0}&quot;"
-msgstr "Kasutajale &quot;{0}&quot; pole võimalik proksi ligipääsu anda"
-
-msgid "Specify User"
-msgstr "Kasutaja määramine"
-
-#. To Translators: In this case, Proxy does not mean something like 'HTTP Proxy', but a GroupWise feature by which one person can send/read mails/appointments using another person's identity without knowing his password, for example if that other person is on vacation
-msgid "You have already given proxy permissions to this user."
-msgstr "Sa oled sellele kasutajale juba proksile ligipääsu andnud."
-
-#. To Translators: In this case, Proxy does not mean something like 'HTTP Proxy', but a GroupWise feature by which one person can send/read mails/appointments using another person's identity without knowing his password, for example if that other person is on vacation
-msgid "You have to specify a valid user name to give proxy rights."
-msgstr ""
-
-msgid "You cannot share this folder with the specified user &quot;{0}&quot;"
-msgstr "Sul pole võimalik kausta määratud kasutajale &quot;{0}&quot; jagada"
-
-msgid "You have to specify a user name which you want to add to the list"
-msgstr "Sa pead määrama nimekirja lisatava kasutaja nime"
-
msgid "Do you want to resend the meeting ?"
msgstr "Kas soovid seda koosolekut uuesti saata?"
diff --git a/shell/Evolution-Component.idl b/shell/Evolution-Component.idl
deleted file mode 100644
index ccf806ff91..0000000000
--- a/shell/Evolution-Component.idl
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Interface for the Evolution components.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2003 Ximian, Inc.
- */
-
-#ifndef _GNOME_EVOLUTION_COMPONENT_IDL
-#define _GNOME_EVOLUTION_COMPONENT_IDL
-
-#include <Bonobo.idl>
-
-#ifndef __evolution_shell_COMPILATION
-#ifdef __ORBIT_IDL__
-%{
-#pragma include_defs shell/evolution-component.h
-%}
-#pragma inhibit push
-#endif
-#endif
-
-module GNOME {
-module Evolution {
- enum CreatableItem {
- CREATABLE_OBJECT,
- CREATABLE_FOLDER
- };
- enum ShellState {
- USER_OFFLINE,
- FORCED_OFFLINE,
- USER_ONLINE
- };
-
- /* A type of item that the component can create when asked by the user,
- e.g. a mail message or an appointment. */
- struct CreatableItemType {
- string id;
- string description;
- string menuDescription;
- string tooltip;
- char menuShortcut;
- string iconName;
- CreatableItem type;
- };
- typedef sequence <CreatableItemType> CreatableItemTypeList;
-
- interface ComponentView : Bonobo::Unknown {
- void getControls (out Bonobo::Control sidebar_control,
- out Bonobo::Control view_control,
- out Bonobo::Control statusbar_control);
- };
-
- interface Listener : Bonobo::Unknown {
- /* Indicate the change of state is complete */
- void complete();
- };
-
- interface Component : Bonobo::Unknown {
- exception Failed {};
- exception UnknownType {};
- /* We don't know about the old version we're upgrading from */
- exception UnsupportedVersion {};
- /* We encountered a non-recoverable, fatal error, explain why */
- exception UpgradeFailed {
- string what;
- string why;
- };
-
- /*** Upgrade path. ***/
-
- void upgradeFromVersion (in short major, in short minor, in short revision)
- raises (UnsupportedVersion, UpgradeFailed);
-
- /*** Basic functionality. ***/
- ComponentView createView(in ShellView parent,
- in boolean select_item)
- raises (Failed);
-
-
- /* Check if the component can quit.
- Do not perform any quit-related tasks however.
- May be called multiple times, depending on user interaction. */
- boolean requestQuit ();
-
- /* Ask the component to quit. Returns TRUE when the
- component has completed any closing-down tasks, and
- is ready to exit(). This will be called repeatedly
- at intervals until it returns TRUE. */
- boolean quit ();
-
- /* Notify the component of whether the shell is currently
- running in interactive mode or not. (I.e. basically,
- whether there are any Evolution windows on the screen.)
- @new_view_xid is an X Window ID ("None" if @now_interactive
- is FALSE) */
- void interactive (in boolean now_interactive,
- in unsigned long new_view_xid);
-
-
- /*** The following stuff is needed to build the "New" toolbar
- item as well as the "File -> New" submenu. ***/
-
- /* List of creatable items. */
- readonly attribute CreatableItemTypeList userCreatableItems;
-
- /* Pop up a new editing dialog for the item with the specified
- @item_type_name. */
- void requestCreateItem (in string item_type_name)
- raises (UnknownType, Failed);
-
-
- /*** URI handling (e.g. for the command-line, "evolution
- mailto:foo@bar.org") ***/
- void handleURI (in string uri);
-
-
- /*** Send/receive. ***/
-
- void sendAndReceive ();
-
- /* Set the online status of the component asynchronously */
-
- void setLineStatus(in ShellState shell_state, in Listener listener);
- };
-
-};
-};
-
-#ifndef __evolution_shell_COMPILATION
-#ifdef __ORBIT_IDL__
-#pragma inhibit pop
-#endif
-#endif
-#endif /* _GNOME_EVOLUTION_COMPONENT_IDL */
diff --git a/shell/Evolution-ConfigControl.idl b/shell/Evolution-ConfigControl.idl
deleted file mode 100644
index 901932d209..0000000000
--- a/shell/Evolution-ConfigControl.idl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Additional interfaces for the Controls used in configuration dialogs.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2002 Ximian, Inc.
- */
-
-#ifndef _GNOME_EVOLUTION_CONFIGCONTROL_IDL
-#define _GNOME_EVOLUTION_CONFIGCONTROL_IDL
-
-module GNOME {
-module Evolution {
- interface ConfigControl : Bonobo::Unknown {
- /* The actual Control. */
- readonly attribute Bonobo::Control control;
-
- /* Get the event source for this control. */
- readonly attribute Bonobo::EventSource eventSource;
- };
-}; /* module Evolution */
-}; /* module GNOME */
-
-#endif
diff --git a/shell/Evolution-Shell.idl b/shell/Evolution-Shell.idl
deleted file mode 100644
index d39ec8edeb..0000000000
--- a/shell/Evolution-Shell.idl
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Interface for the Evolution shell.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#ifndef _GNOME_EVOLUTION_SHELL_IDL
-#define _GNOME_EVOLUTION_SHELL_IDL
-
-#include <Bonobo.idl>
-
-#ifndef __evolution_shell_COMPILATION
-#ifdef __ORBIT_IDL__
-%{
-#pragma include_defs shell/evolution-component.h
-%}
-#pragma inhibit push
-#endif
-#endif
-
-module GNOME {
-module Evolution {
-
-
- interface ShellView : Bonobo::Unknown {
- /* Should really use a ComponentView i guess */
- void setTitle(in string component, in string title);
- void setComponent(in string component);
- void setButtonIcon(in string component, in string iconName);
- };
-
- interface Shell : Bonobo::Unknown {
- exception Busy {};
- exception ComponentNotFound {};
- exception InternalError {};
- exception InvalidURI {};
- exception NotFound {};
- exception NotReady {};
- exception UnsupportedSchema {};
-
- /**
- * createNewWindow:
- * @component_id: id or alias of the component to display in the new window.
- *
- */
- ShellView createNewWindow (in string component_id)
- raises (NotReady, ComponentNotFound, UnsupportedSchema, InternalError);
-
- /**
- * handleURI:
- * @uri: URI to handle
- *
- * This handles the specified URI. It is different from
- * `::createNewView' as it doesn't necessarily imply creating a
- * new ShellView. (For example, a `mailto:' URI will invoke
- * the message composer.)
- */
- void handleURI (in string uri)
- raises (NotReady, ComponentNotFound, NotFound, UnsupportedSchema, InvalidURI, InternalError);
-
- /**
- * setLineStatus:
- *
- * Set the shell into on-line or off-line mode.
- */
- void setLineStatus (in boolean online)
- raises (NotReady);
-
- /*
- * Lookup a component by id.
- */
- /*Component findComponent(in string id)
- raises (NotReady, ComponentNotFound);*/
- };
-};
-};
-
-#ifndef __evolution_shell_COMPILATION
-#ifdef __ORBIT_IDL__
-#pragma inhibit pop
-#endif
-#endif
-#endif /* _GNOME_EVOLUTION_SHELL_IDL */
diff --git a/shell/Evolution.idl b/shell/Evolution.idl
deleted file mode 100644
index 059d017444..0000000000
--- a/shell/Evolution.idl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * CORBA interface for the Evolution shell.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#ifndef _GNOME_EVOLUTION_IDL
-#define _GNOME_EVOLUTION_IDL
-
-#include <Bonobo.idl>
-
-#include <Evolution-ConfigControl.idl>
-#include <Evolution-Shell.idl>
-#include <Evolution-Component.idl>
-
-#endif
diff --git a/shell/GNOME_Evolution_Shell.server.in.in b/shell/GNOME_Evolution_Shell.server.in.in
deleted file mode 100644
index b055f3000d..0000000000
--- a/shell/GNOME_Evolution_Shell.server.in.in
+++ /dev/null
@@ -1,26 +0,0 @@
-<oaf_info>
-
- <oaf_server iid="OAFIID:GNOME_Evolution_Shell:@VERSION@"
- type="exe"
- location="@BINDIR_IN_SERVER_FILE@/evolution@EXEEXT@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Shell:@VERSION@"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Shell"/>
- </oaf_server>
-
- <oaf_server iid="OAFIID:GNOME_Evolution_Shell_Config_Factory:@VERSION@"
- type="exe"
- location="@BINDIR_IN_SERVER_FILE@/evolution-@VERSION@@EXEEXT@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/GenericFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string" _value="Evolution Shell Config factory"/>
- </oaf_server>
-
-</oaf_info>
diff --git a/shell/Makefile.am b/shell/Makefile.am
index ecf0dc4f47..a17c11a875 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -4,6 +4,7 @@ endif
AM_CPPFLAGS = \
-I$(top_srcdir)/widgets \
+ -I$(top_srcdir)/widgets/menus \
-I$(top_srcdir)/widgets/misc \
-I$(top_srcdir) \
-I$(top_srcdir)/shell \
@@ -11,8 +12,11 @@ AM_CPPFLAGS = \
-DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \
-DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
-DEVOLUTION_DATADIR=\""$(datadir)"\" \
+ -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-DEVOLUTION_HELPDIR=\""$(evolutionhelpdir)"\" \
+ -DEVOLUTION_MODULEDIR=\""$(moduledir)"\" \
+ -DEVOLUTION_RULEDIR=\""$(privdatadir)"\" \
-DEVOLUTION_UIDIR=\""$(evolutionuidir)"\" \
-DEVOLUTION_TOOLSDIR=\""$(privlibexecdir)"\" \
-DPREFIX=\""$(prefix)"\" \
@@ -26,62 +30,15 @@ AM_CPPFLAGS = \
if NM_SUPPORT
AM_CPPFLAGS += \
$(DBUS_GLIB_CFLAGS) \
- $(NM_FLAGS)
+ $(NM_CFLAGS)
endif
bin_PROGRAMS = evolution
-# Shell CORBA stuff
-
-IDLS = \
- Evolution-ConfigControl.idl \
- Evolution-Component.idl \
- Evolution-Shell.idl \
- Evolution.idl
-
-IDL_GENERATED_H = \
- Evolution.h
-
-IDL_GENERATED_C = \
- Evolution-common.c \
- Evolution-skels.c \
- Evolution-stubs.c
-
-idl_defines = \
- -D__evolution_shell_COMPILATION
-
-IDL_GENERATED = $(IDL_GENERATED_H) $(IDL_GENERATED_C)
-
-$(IDL_GENERATED_H): $(IDLS)
- $(ORBIT_IDL) -I $(srcdir) $(idl_defines) $(IDL_INCLUDES) $(srcdir)/Evolution.idl
-
-$(IDL_GENERATED_C): $(IDL_GENERATED_H)
-
if NM_SUPPORT
-NM_SUPPORT_FILES = e-shell-nm.c
+NM_SUPPORT_FILES = e-shell-nm.c
endif
-# Data Server CORBA stuff
-DATASERVER_IDL_GENERATED_H = \
- Evolution-DataServer.h
-
-DATASERVER_IDL_GENERATED_C = \
- Evolution-DataServer-common.c \
- Evolution-DataServer-skels.c \
- Evolution-DataServer-stubs.c
-
-DATASERVER_IDL_GENERATED = $(DATASERVER_IDL_GENERATED_C) $(DATASERVER_IDL_GENERATED_H)
-
-$(DATASERVER_IDL_GENERATED_H): $(DATASERVER_IDL)
- $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) $(DATASERVER_IDL)
-
-$(DATASERVER_IDL_GENERATED_C): $(DATASERVER_IDL_GENERATED_H)
-
-
-# IDL install
-
-idl_DATA = $(IDLS)
-
# Shell library
privsolib_LTLIBRARIES = \
@@ -90,33 +47,55 @@ privsolib_LTLIBRARIES = \
eshellincludedir = $(privincludedir)/shell
eshellinclude_HEADERS = \
- Evolution.h \
- e-component-view.h \
- e-user-creatable-items-handler.h \
- evolution-config-control.h \
- evolution-component.h \
- evolution-listener.h \
- evolution-shell-component-utils.h \
- es-event.h \
- es-menu.h
+ e-shell.h \
+ e-shell-backend.h \
+ e-shell-common.h \
+ e-shell-content.h \
+ e-shell-settings.h \
+ e-shell-sidebar.h \
+ e-shell-switcher.h \
+ e-shell-taskbar.h \
+ e-shell-view.h \
+ e-shell-window.h \
+ es-event.h
libeshell_la_SOURCES = \
+ $(NM_SUPPORT_FILES) \
$(IDL_GENERATED) \
- e-component-view.c \
- evolution-component.c \
- evolution-listener.c \
- e-user-creatable-items-handler.c \
- evolution-config-control.c \
- evolution-shell-component-utils.c \
- $(eshellinclude_HEADERS)
+ e-shell.c \
+ e-shell-backend.c \
+ e-shell-content.c \
+ e-shell-settings.c \
+ e-shell-sidebar.c \
+ e-shell-switcher.c \
+ e-shell-taskbar.c \
+ e-shell-view.c \
+ e-shell-window.c \
+ e-shell-window-private.c \
+ e-shell-window-private.h \
+ $(eshellinclude_HEADERS) \
+ e-shell-importer.c \
+ e-shell-importer.h \
+ e-shell-migrate.c \
+ e-shell-migrate.h \
+ e-shell-window-actions.h \
+ e-shell-window-actions.c \
+ es-event.c
libeshell_la_LDFLAGS = $(NO_UNDEFINED)
libeshell_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/filter/libfilter.la \
+ $(top_builddir)/smclient/libeggsmclient.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/widgets/menus/libmenus.la \
$(SHELL_LIBS)
+if NM_SUPPORT
+libeshell_la_LIBADD += $(DBUS_GLIB_LIBS)
+endif
+
# Evolution executable
if HAVE_WINDRES
@@ -124,36 +103,14 @@ EVOLUTIONICONRC = evolution-icon.o
endif
evolution_SOURCES = \
- $(DATASERVER_IDL_GENERATED) \
- $(NM_SUPPORT_FILES) \
- e-component-registry.c \
- e-component-registry.h \
e-config-upgrade.c \
e-config-upgrade.h \
- e-corba-config-page.c \
- e-corba-config-page.h \
- e-shell.c \
- e-shell.h \
- e-shell-constants.h \
- e-shell-importer.c \
- e-shell-importer.h \
- e-shell-settings-dialog.c \
- e-shell-settings-dialog.h \
- e-shell-window-commands.c \
- e-shell-window-commands.h \
- e-shell-window.c \
- e-shell-window.h \
- e-shell-view.c \
- e-shell-view.h \
- e-sidebar.c \
- e-sidebar.h \
- es-event.c \
- es-menu.c \
main.c
evolution_LDADD = \
libeshell.la \
$(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \
+ $(top_builddir)/widgets/menus/libmenus.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
$(top_builddir)/e-util/libeutil.la \
$(TZDIALOG_LIBS) \
@@ -166,19 +123,10 @@ endif
# Misc stuff
-server_in_files = GNOME_Evolution_Shell.server.in.in
-server_DATA = $(server_in_files:.server.in.in=.server)
-@EVO_SERVER_RULE@
-@INTLTOOL_SERVER_RULE@
-
error_DATA = shell.error
errordir = $(privdatadir)/errors
@EVO_PLUGIN_RULE@
-glade_DATA = \
- e-active-connection-dialog.glade \
- import.glade
-
# GConf schemas
schemadir = $(GCONF_SCHEMA_FILE_DIR)
@@ -210,10 +158,7 @@ endif
# Extra dist stuff
EXTRA_DIST = \
- $(IDLS) \
- $(server_in_files) \
shell.error.xml \
- $(glade_DATA) \
$(schema_in_files) \
ChangeLog.pre-1-4 \
evolution-nognome.in \
@@ -237,7 +182,7 @@ evolution.pure: evolution
endif
-BUILT_SOURCES = $(IDL_GENERATED) $(server_DATA) $(DATASERVER_IDL_GENERATED) $(error_DATA)
+BUILT_SOURCES = $(error_DATA)
CLEANFILES = $(BUILT_SOURCES)
DISTCLEANFILES = $(schema_DATA)
diff --git a/shell/apps_evolution_shell.schemas.in b/shell/apps_evolution_shell.schemas.in
index c5c6276c25..157df8cb9e 100644
--- a/shell/apps_evolution_shell.schemas.in
+++ b/shell/apps_evolution_shell.schemas.in
@@ -60,7 +60,7 @@
<schema>
<key>/schemas/apps/evolution/shell/current_folder</key>
- <applyto>/apps/evolution/shell/current-folder</applyto>
+ <applyto>/apps/evolution/shell/current_folder</applyto>
<owner>evolution</owner>
<type>string</type>
<locale name="C">
@@ -99,44 +99,54 @@
<!-- View defaults -->
<schema>
- <key>/schemas/apps/evolution/shell/view_defaults/width</key>
- <applyto>/apps/evolution/shell/view_defaults/width</applyto>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_y</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_y</applyto>
<owner>evolution</owner>
<type>int</type>
- <default>640</default>
<locale name="C">
- <short>Default window width</short>
- <long>The default width for the main window, in pixels.</long>
+ <short>Default window Y coordinate</short>
+ <long>The default Y coordinate for the main window.</long>
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/shell/view_defaults/height</key>
- <applyto>/apps/evolution/shell/view_defaults/height</applyto>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_x</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_x</applyto>
<owner>evolution</owner>
<type>int</type>
- <default>480</default>
<locale name="C">
- <short>Default window height</short>
- <long>The default height for the main window, in pixels.</long>
+ <short>Default window X coordinate</short>
+ <long>The default X coordinate for the main window.</long>
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/shell/view_defaults/maximized</key>
- <applyto>/apps/evolution/shell/view_defaults/maximized</applyto>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_width</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_width</applyto>
<owner>evolution</owner>
- <type>bool</type>
- <default>TRUE</default>
+ <type>int</type>
+ <default>640</default>
<locale name="C">
- <short>Default window state</short>
- <long>Whether or not the window should be maximized.</long>
+ <short>Default window width</short>
+ <long>The default width for the main window, in pixels.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_height</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_height</applyto>
+ <owner>evolution</owner>
+ <type>int</type>
+ <default>480</default>
+ <locale name="C">
+ <short>Default window height</short>
+ <long>The default height for the main window, in pixels.</long>
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/shell/view_defaults/maximized</key>
- <applyto>/apps/evolution/shell/view_defaults/maximized</applyto>
+ <key>/schemas/apps/evolution/shell/view_defaults/window_maximized</key>
+ <applyto>/apps/evolution/shell/view_defaults/window_maximized</applyto>
<owner>evolution</owner>
<type>bool</type>
<default>TRUE</default>
diff --git a/shell/e-active-connection-dialog.glade b/shell/e-active-connection-dialog.glade
deleted file mode 100644
index 534a7948f7..0000000000
--- a/shell/e-active-connection-dialog.glade
+++ /dev/null
@@ -1,193 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-
-<widget class="GtkDialog" id="active_connection_dialog">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Active Connections</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
- <property name="modal">False</property>
- <property name="default_width">256</property>
- <property name="default_height">192</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="has_separator">False</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area2">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
-
- <child>
- <widget class="GtkButton" id="cancelbutton1">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-cancel</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="response_id">-6</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="okbutton1">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-ok</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="response_id">-5</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Active Connections&lt;/b&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="active_connection_treeview">
- <property name="visible">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="instruction_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Click OK to close these connections and go offline</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/shell/e-component-registry.c b/shell/e-component-registry.c
deleted file mode 100644
index 1b36d14512..0000000000
--- a/shell/e-component-registry.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-component-registry.h"
-
-#include <glib/gi18n.h>
-
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-exception.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-struct _EComponentRegistryPrivate {
- GSList *infos;
-
- guint init:1;
-};
-
-G_DEFINE_TYPE (EComponentRegistry, e_component_registry, G_TYPE_OBJECT)
-
-/* EComponentInfo handling. */
-
-static EComponentInfo *
-component_info_new (const gchar *id,
- GNOME_Evolution_Component iface,
- const gchar *alias,
- const gchar *button_label,
- const gchar *button_tooltips,
- const gchar *menu_label,
- const gchar *menu_accelerator,
- const gchar *icon_name,
- gint sort_order)
-{
- EComponentInfo *info = g_new0 (EComponentInfo, 1);
-
- info->id = g_strdup (id);
- info->iface = bonobo_object_dup_ref(iface, NULL);
- info->alias = g_strdup (alias);
- info->button_label = g_strdup (button_label);
- info->button_tooltips = g_strdup (button_tooltips);
- info->menu_label = g_strdup (menu_label);
- info->menu_accelerator = g_strdup (menu_accelerator);
- info->icon_name = g_strdup (icon_name);
- info->sort_order = sort_order;
-
- return info;
-}
-
-static void
-component_info_free (EComponentInfo *info)
-{
- g_free (info->id);
- g_free (info->alias);
- g_free (info->button_label);
- g_free (info->button_tooltips);
- g_free (info->menu_label);
- g_free (info->menu_accelerator);
-
- if (info->iface != NULL)
- bonobo_object_release_unref (info->iface, NULL);
-
- g_slist_foreach (info->uri_schemas, (GFunc) g_free, NULL);
- g_slist_free (info->uri_schemas);
-
- g_free (info);
-}
-
-static gint
-component_info_compare_func (EComponentInfo *a,
- EComponentInfo *b)
-{
- if (a->sort_order != b->sort_order)
- return a->sort_order - b->sort_order;
-
- return strcmp (a->button_label, b->button_label);
-}
-
-/* Utility methods. */
-
-static void
-set_schemas (EComponentInfo *component_info,
- Bonobo_ServerInfo *server_info)
-{
- Bonobo_ActivationProperty *property = bonobo_server_info_prop_find (server_info, "evolution:uri_schemas");
- Bonobo_StringList *list;
- gint i;
-
- if (property == NULL)
- return;
-
- if (property->v._d != Bonobo_ACTIVATION_P_STRINGV) {
- CORBA_free (property);
- return;
- }
-
- list = & property->v._u.value_stringv;
-
- for (i = 0; i < list->_length; i ++)
- component_info->uri_schemas = g_slist_prepend (component_info->uri_schemas, g_strdup (list->_buffer [i]));
-
- CORBA_free (property);
-}
-
-static void
-query_components (EComponentRegistry *registry)
-{
- Bonobo_ServerInfoList *info_list;
- const gchar * const *language_names;
- CORBA_Environment ev;
- GSList *languages = NULL;
- gchar *query;
- gint i;
-
- if (registry->priv->init)
- return;
-
- registry->priv->init = TRUE;
-
- CORBA_exception_init (&ev);
- query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/Component:%s')", BASE_VERSION);
- info_list = bonobo_activation_query (query, NULL, &ev);
- g_free (query);
-
- if (BONOBO_EX (&ev)) {
- gchar *ex_text = bonobo_exception_get_text (&ev);
- g_warning ("Cannot query for components: %s\n", ex_text);
- g_free (ex_text);
- CORBA_exception_free (&ev);
- return;
- }
-
- language_names = g_get_language_names ();
- while (*language_names != NULL)
- languages = g_slist_append (languages, (gpointer)(*language_names++));
-
- for (i = 0; i < info_list->_length; i++) {
- const gchar *id;
- const gchar *label;
- const gchar *menu_label;
- const gchar *menu_accelerator;
- const gchar *alias;
- const gchar *icon_name;
- const gchar *sort_order_string;
- const gchar *tooltips;
- EComponentInfo *info;
- gint sort_order;
- GNOME_Evolution_Component iface;
-
- id = info_list->_buffer[i].iid;
- iface = bonobo_activation_activate_from_id ((gchar *)id, 0, NULL, &ev);
- if (BONOBO_EX (&ev) || iface == CORBA_OBJECT_NIL) {
- gchar *ex_text = bonobo_exception_get_text (&ev);
-
- g_warning("Cannot activate '%s': %s\n", id, ex_text);
- g_free(ex_text);
- CORBA_exception_free(&ev);
- CORBA_exception_init(&ev);
- continue;
- }
-
- label = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:button_label", languages);
-
- tooltips = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:button_tooltips", languages);
-
- menu_label = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:menu_label", languages);
-
- menu_accelerator = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:menu_accelerator", languages);
-
- alias = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:component_alias", NULL);
-
- icon_name = bonobo_server_info_prop_lookup (& info_list->_buffer[i], "evolution:button_icon", NULL);
-
- sort_order_string = bonobo_server_info_prop_lookup (& info_list->_buffer[i],
- "evolution:button_sort_order", NULL);
- if (sort_order_string == NULL)
- sort_order = 0;
- else
- sort_order = atoi (sort_order_string);
-
- info = component_info_new (id, iface, alias, label, tooltips, menu_label,
- menu_accelerator, icon_name, sort_order);
- set_schemas (info, & info_list->_buffer [i]);
-
- registry->priv->infos = g_slist_prepend (registry->priv->infos, info);
-
- bonobo_object_release_unref(iface, NULL);
- }
- g_slist_free(languages);
-
- CORBA_free (info_list);
- CORBA_exception_free (&ev);
-
- registry->priv->infos = g_slist_sort (registry->priv->infos,
- (GCompareFunc) component_info_compare_func);
-}
-
-/* GObject methods. */
-
-static void
-impl_finalize (GObject *object)
-{
- EComponentRegistry *component_registry;
- EComponentRegistryPrivate *priv;
-
- component_registry = E_COMPONENT_REGISTRY (object);
- priv = component_registry->priv;
-
- g_slist_foreach (priv->infos, (GFunc) component_info_free, NULL);
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_component_registry_parent_class)->finalize) (object);
-}
-
-static void
-e_component_registry_class_init (EComponentRegistryClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_component_registry_init (EComponentRegistry *registry)
-{
- registry->priv = g_new0 (EComponentRegistryPrivate, 1);
-}
-
-EComponentRegistry *
-e_component_registry_new (void)
-{
- return g_object_new (e_component_registry_get_type (), NULL);
-}
-
-GSList *
-e_component_registry_peek_list (EComponentRegistry *registry)
-{
- g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), NULL);
-
- query_components(registry);
-
- return registry->priv->infos;
-}
-
-EComponentInfo *
-e_component_registry_peek_info (EComponentRegistry *registry,
- enum _EComponentRegistryField field,
- const gchar *key)
-{
- GSList *p, *q;
-
- g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), NULL);
-
- query_components(registry);
-
- for (p = registry->priv->infos; p != NULL; p = p->next) {
- EComponentInfo *info = p->data;
-
- switch (field) {
- case ECR_FIELD_ID:
- if (info->id && (strcmp (info->id, key) == 0))
- return info;
- break;
- case ECR_FIELD_ALIAS:
- if (info->alias && (strcmp (info->alias, key) == 0))
- return info;
- break;
- case ECR_FIELD_SCHEMA:
- for (q = info->uri_schemas; q != NULL; q = q->next)
- if (strcmp((gchar *)q->data, key) == 0)
- return info;
- break;
- }
- }
-
- return NULL;
-}
-
-GNOME_Evolution_Component
-e_component_registry_activate (EComponentRegistry *registry,
- const gchar *id,
- CORBA_Environment *ev)
-{
- EComponentInfo *info;
-
- g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), CORBA_OBJECT_NIL);
-
- info = e_component_registry_peek_info (registry, ECR_FIELD_ID, id);
- if (info == NULL) {
- g_warning ("%s - Unknown id \"%s\"", G_STRFUNC, id);
- return CORBA_OBJECT_NIL;
- }
-
- /* it isn't in the registry unless it is already activated */
- return bonobo_object_dup_ref (info->iface, NULL);
-}
diff --git a/shell/e-component-registry.h b/shell/e-component-registry.h
deleted file mode 100644
index 373912db03..0000000000
--- a/shell/e-component-registry.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __E_COMPONENT_REGISTRY_H__
-#define __E_COMPONENT_REGISTRY_H__
-
-#include "Evolution.h"
-
-#include <glib-object.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_COMPONENT_REGISTRY (e_component_registry_get_type ())
-#define E_COMPONENT_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_COMPONENT_REGISTRY, EComponentRegistry))
-#define E_COMPONENT_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_COMPONENT_REGISTRY, EComponentRegistryClass))
-#define E_IS_COMPONENT_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_COMPONENT_REGISTRY))
-#define E_IS_COMPONENT_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_COMPONENT_REGISTRY))
-
-typedef struct _EComponentRegistry EComponentRegistry;
-typedef struct _EComponentRegistryPrivate EComponentRegistryPrivate;
-typedef struct _EComponentRegistryClass EComponentRegistryClass;
-
-struct _EComponentRegistry {
- GObject parent;
-
- EComponentRegistryPrivate *priv;
-};
-
-struct _EComponentRegistryClass {
- GObjectClass parent_class;
-};
-
-enum _EComponentRegistryField {
- ECR_FIELD_ID,
- ECR_FIELD_ALIAS,
- ECR_FIELD_SCHEMA
-};
-
-struct _EComponentInfo {
- gchar *id;
-
- gchar *alias;
-
- /* NULL if not activated. */
- GNOME_Evolution_Component iface;
-
- gchar *button_label;
- gchar *button_tooltips;
- gchar *menu_label;
- gchar *menu_accelerator;
- gchar *icon_name;
-
- gint sort_order;
-
- /* List of URI schemas that this component supports. */
- GSList *uri_schemas; /* <char *> */
-};
-typedef struct _EComponentInfo EComponentInfo;
-
-GType e_component_registry_get_type (void);
-EComponentRegistry *e_component_registry_new (void);
-
-GSList *e_component_registry_peek_list (EComponentRegistry *registry);
-EComponentInfo *e_component_registry_peek_info (EComponentRegistry *registry,
- enum _EComponentRegistryField type,
- const gchar *key);
-
-GNOME_Evolution_Component e_component_registry_activate (EComponentRegistry *registry,
- const gchar *id,
- CORBA_Environment *ev);
-
-G_END_DECLS
-
-#endif /* __E_COMPONENT_REGISTRY_H__ */
diff --git a/shell/e-component-view.c b/shell/e-component-view.c
deleted file mode 100644
index 58ea3f9a89..0000000000
--- a/shell/e-component-view.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Helper class for evolution components to setup a view
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-
-#include "e-component-view.h"
-
-#include "bonobo/bonobo-control.h"
-
-static BonoboObjectClass *parent_class = NULL;
-
-static void
-impl_ComponentView_getControls(PortableServer_Servant servant,
- Bonobo_Control *side_control,
- Bonobo_Control *view_control,
- Bonobo_Control *statusbar_control,
- CORBA_Environment *ev)
-{
- EComponentView *ecv = (EComponentView *)bonobo_object_from_servant(servant);
-
- *side_control = CORBA_Object_duplicate (BONOBO_OBJREF (ecv->side_control), ev);
- *view_control = CORBA_Object_duplicate (BONOBO_OBJREF (ecv->view_control), ev);
- *statusbar_control = CORBA_Object_duplicate (BONOBO_OBJREF (ecv->statusbar_control), ev);
-}
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- EComponentView *ecv = (EComponentView *)object;
-
- ecv->side_control = NULL;
- ecv->view_control = NULL;
- ecv->statusbar_control = NULL;
-
- ((GObjectClass *)parent_class)->dispose(object);
-}
-
-static void
-impl_finalise (GObject *object)
-{
- EComponentView *ecv = (EComponentView *)object;
-
- g_free(ecv->id);
-
- ((GObjectClass *)parent_class)->finalize(object);
-}
-
-static void
-e_component_view_class_init (EComponentViewClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_ComponentView__epv *epv;
-
- parent_class = g_type_class_ref(bonobo_object_get_type());
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalise;
-
- epv = & klass->epv;
- epv->getControls = impl_ComponentView_getControls;
-}
-
-static void
-e_component_view_init (EComponentView *shell)
-{
-}
-
-EComponentView *e_component_view_new(GNOME_Evolution_ShellView parent, const gchar *id, GtkWidget *side, GtkWidget *view, GtkWidget *statusbar)
-{
- EComponentView *new = g_object_new (e_component_view_get_type (), NULL);
- CORBA_Environment ev = { NULL };
-
- new->id = g_strdup(id);
- new->shell_view = CORBA_Object_duplicate(parent, &ev);
- CORBA_exception_free(&ev);
-
- /* FIXME: hook onto destroys */
- new->side_control = bonobo_control_new(side);
- new->view_control = bonobo_control_new(view);
- new->statusbar_control = bonobo_control_new(statusbar);
-
- return new;
-}
-
-EComponentView *e_component_view_new_controls(GNOME_Evolution_ShellView parent, const gchar *id, BonoboControl *side, BonoboControl *view, BonoboControl *statusbar)
-{
- EComponentView *new = g_object_new (e_component_view_get_type (), NULL);
- CORBA_Environment ev = { NULL };
-
- new->id = g_strdup(id);
- new->shell_view = CORBA_Object_duplicate(parent, &ev);
- CORBA_exception_free(&ev);
-
- /* FIXME: hook onto destroys */
- new->side_control = side;
- new->view_control = view;
- new->statusbar_control = statusbar;
-
- return new;
-}
-
-void
-e_component_view_set_title(EComponentView *ecv, const gchar *title)
-{
- CORBA_Environment ev = { NULL };
-
- /* save roundtrips, check title is the same */
- GNOME_Evolution_ShellView_setTitle(ecv->shell_view, ecv->id, title, &ev);
- CORBA_exception_free(&ev);
-}
-
-void
-e_component_view_set_button_icon (EComponentView *ecv, const gchar *iconName)
-{
- CORBA_Environment ev = { NULL };
-
- /* save roundtrips, check title is the same */
- GNOME_Evolution_ShellView_setButtonIcon(ecv->shell_view, ecv->id, iconName, &ev);
- CORBA_exception_free(&ev);
-}
-
-BONOBO_TYPE_FUNC_FULL (EComponentView, GNOME_Evolution_ComponentView, bonobo_object_get_type(), e_component_view)
-
diff --git a/shell/e-component-view.h b/shell/e-component-view.h
deleted file mode 100644
index ca40e3c381..0000000000
--- a/shell/e-component-view.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_COMPONENT_VIEW_H_
-#define _E_COMPONENT_VIEW_H_
-
-#include <gtk/gtk.h>
-#include <bonobo/bonobo-object.h>
-
-G_BEGIN_DECLS
-
-typedef struct _EComponentView EComponentView;
-typedef struct _EComponentViewPrivate EComponentViewPrivate;
-typedef struct _EComponentViewClass EComponentViewClass;
-
-#include "Evolution.h"
-
-#define E_TYPE_COMPONENT_VIEW (e_component_view_get_type ())
-#define E_COMPONENT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_COMPONENT_VIEW, EComponentView))
-#define E_COMPONENT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_COMPONENT_VIEW, EComponentViewClass))
-#define E_IS_COMPONENT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_COMPONENT_VIEW))
-#define E_IS_COMPONENT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_COMPONENT_VIEW))
-
-struct _EComponentView {
- BonoboObject parent;
-
- EComponentViewPrivate *priv;
-
- gchar *id;
- GNOME_Evolution_ShellView shell_view;
-
- struct _BonoboControl *side_control;
- struct _BonoboControl *view_control;
- struct _BonoboControl *statusbar_control;
-};
-
-struct _EComponentViewClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_ComponentView__epv epv;
-};
-
-GType e_component_view_get_type(void);
-EComponentView *e_component_view_new(GNOME_Evolution_ShellView shell_view, const gchar *id, GtkWidget *side, GtkWidget *view, GtkWidget *status);
-EComponentView *e_component_view_new_controls(GNOME_Evolution_ShellView parent, const gchar *id, struct _BonoboControl *side, struct _BonoboControl *view, struct _BonoboControl *statusbar);
-
-void e_component_view_set_title(EComponentView *ecv, const gchar *title);
-void e_component_view_set_button_icon (EComponentView *ecv, const gchar *iconName);
-
-G_END_DECLS
-
-#endif /* _E_COMPONENT_VIEW_H_ */
-
diff --git a/shell/e-corba-config-page.c b/shell/e-corba-config-page.c
deleted file mode 100644
index 02f8a631d3..0000000000
--- a/shell/e-corba-config-page.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-corba-config-page.h"
-
-#include "Evolution.h"
-
-#include <string.h>
-
-#include <bonobo/bonobo-widget.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-listener.h>
-
-struct _ECorbaConfigPagePrivate {
- GNOME_Evolution_ConfigControl config_control_interface;
-};
-
-G_DEFINE_TYPE (ECorbaConfigPage, e_corba_config_page, E_TYPE_CONFIG_PAGE)
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- ECorbaConfigPage *corba_config_page;
- ECorbaConfigPagePrivate *priv;
- CORBA_Environment ev;
-
- corba_config_page = E_CORBA_CONFIG_PAGE (object);
- priv = corba_config_page->priv;
-
- CORBA_exception_init (&ev);
-
- if (priv->config_control_interface != CORBA_OBJECT_NIL) {
- bonobo_object_release_unref (priv->config_control_interface, &ev);
- priv->config_control_interface = CORBA_OBJECT_NIL;
- }
-
- CORBA_exception_free (&ev);
-
- (* G_OBJECT_CLASS (e_corba_config_page_parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- ECorbaConfigPage *corba_config_page;
- ECorbaConfigPagePrivate *priv;
-
- corba_config_page = E_CORBA_CONFIG_PAGE (object);
- priv = corba_config_page->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_corba_config_page_parent_class)->finalize) (object);
-}
-
-/* GTK+ ctors. */
-
-static void
-e_corba_config_page_class_init (ECorbaConfigPageClass *class)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_corba_config_page_init (ECorbaConfigPage *corba_config_page)
-{
- ECorbaConfigPagePrivate *priv;
-
- priv = g_new (ECorbaConfigPagePrivate, 1);
- priv->config_control_interface = CORBA_OBJECT_NIL;
-
- corba_config_page->priv = priv;
-}
-
-
-gboolean
-e_corba_config_page_construct (ECorbaConfigPage *corba_config_page,
- GNOME_Evolution_ConfigControl corba_object)
-{
- Bonobo_Control control;
- GtkWidget *control_widget;
- CORBA_Environment ev;
-
- g_return_val_if_fail (E_IS_CORBA_CONFIG_PAGE (corba_config_page), FALSE);
- g_return_val_if_fail (corba_object != CORBA_OBJECT_NIL, FALSE);
-
- CORBA_exception_init (&ev);
-
- control = GNOME_Evolution_ConfigControl__get_control (corba_object, &ev);
- if (BONOBO_EX (&ev)) {
- g_warning ("Can't get control from ::ConfigControl -- %s", BONOBO_EX_REPOID (&ev));
- CORBA_exception_init (&ev);
- return FALSE;
- }
-
- control_widget = bonobo_widget_new_control_from_objref (control, CORBA_OBJECT_NIL);
- gtk_widget_show (control_widget);
- gtk_container_add (GTK_CONTAINER (corba_config_page), control_widget);
-
- /* Notice we *don't* unref the corba_object here as
- bonobo_widget_new_control_from_objref() effectively takes ownership
- for the object that we get from ::__get_control. */
-
- CORBA_exception_free (&ev);
-
- return TRUE;
-}
-
-GtkWidget *
-e_corba_config_page_new_from_objref (GNOME_Evolution_ConfigControl corba_object)
-{
- ECorbaConfigPage *corba_config_page;
-
- g_return_val_if_fail (corba_object != CORBA_OBJECT_NIL, NULL);
- g_return_val_if_fail (corba_object != CORBA_OBJECT_NIL, NULL);
-
- corba_config_page = g_object_new (e_corba_config_page_get_type (), NULL);
- if (! e_corba_config_page_construct (corba_config_page, corba_object)) {
- gtk_widget_destroy (GTK_WIDGET (corba_config_page));
- return NULL;
- }
-
- return GTK_WIDGET (corba_config_page);
-}
diff --git a/shell/e-corba-config-page.h b/shell/e-corba-config-page.h
deleted file mode 100644
index a09b86d0fe..0000000000
--- a/shell/e-corba-config-page.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_CORBA_CONFIG_PAGE_H_
-#define _E_CORBA_CONFIG_PAGE_H_
-
-#include "e-config-page.h"
-
-#include "Evolution.h"
-
-#include <bonobo/bonobo-object.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_CORBA_CONFIG_PAGE (e_corba_config_page_get_type ())
-#define E_CORBA_CONFIG_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CORBA_CONFIG_PAGE, ECorbaConfigPage))
-#define E_CORBA_CONFIG_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CORBA_CONFIG_PAGE, ECorbaConfigPageClass))
-#define E_IS_CORBA_CONFIG_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CORBA_CONFIG_PAGE))
-#define E_IS_CORBA_CONFIG_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CORBA_CONFIG_PAGE))
-
-
-typedef struct _ECorbaConfigPage ECorbaConfigPage;
-typedef struct _ECorbaConfigPagePrivate ECorbaConfigPagePrivate;
-typedef struct _ECorbaConfigPageClass ECorbaConfigPageClass;
-
-struct _ECorbaConfigPage {
- EConfigPage parent;
-
- ECorbaConfigPagePrivate *priv;
-};
-
-struct _ECorbaConfigPageClass {
- EConfigPageClass parent_class;
-};
-
-
-GType e_corba_config_page_get_type (void);
-GtkWidget *e_corba_config_page_new_from_objref (GNOME_Evolution_ConfigControl objref);
-gboolean e_corba_config_page_construct (ECorbaConfigPage *corba_config_page,
- GNOME_Evolution_ConfigControl objref);
-
-G_END_DECLS
-
-#endif /* _E_CORBA_CONFIG_PAGE_H_ */
diff --git a/shell/e-shell-backend.c b/shell/e-shell-backend.c
new file mode 100644
index 0000000000..c996d8ab01
--- /dev/null
+++ b/shell/e-shell-backend.c
@@ -0,0 +1,403 @@
+/*
+ * e-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-backend.h"
+
+#include <errno.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+
+#include "e-shell.h"
+#include "e-shell-view.h"
+
+#define E_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_BACKEND, EShellBackendPrivate))
+
+struct _EShellBackendPrivate {
+
+ gpointer shell; /* weak pointer */
+
+ /* We keep a reference to corresponding EShellView subclass
+ * since it keeps a reference back to us. This ensures the
+ * subclass is not finalized before we are, otherwise it
+ * would leak its EShellBackend reference. */
+ EShellViewClass *shell_view_class;
+
+ gchar *config_dir;
+ gchar *data_dir;
+
+ guint started : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_SHELL
+};
+
+enum {
+ ACTIVITY_ADDED,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+shell_backend_set_shell (EShellBackend *shell_backend,
+ EShell *shell)
+{
+ g_return_if_fail (shell_backend->priv->shell == NULL);
+
+ shell_backend->priv->shell = shell;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_backend),
+ &shell_backend->priv->shell);
+}
+
+static void
+shell_backend_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL:
+ shell_backend_set_shell (
+ E_SHELL_BACKEND (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_backend_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL:
+ g_value_set_object (
+ value, e_shell_backend_get_shell (
+ E_SHELL_BACKEND (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_backend_dispose (GObject *object)
+{
+ EShellBackendPrivate *priv;
+
+ priv = E_SHELL_BACKEND_GET_PRIVATE (object);
+
+ if (priv->shell != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell), &priv->shell);
+ priv->shell = NULL;
+ }
+
+ if (priv->shell_view_class != NULL) {
+ g_type_class_unref (priv->shell_view_class);
+ priv->shell_view_class = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_backend_finalize (GObject *object)
+{
+ EShellBackendPrivate *priv;
+
+ priv = E_SHELL_BACKEND_GET_PRIVATE (object);
+
+ g_free (priv->data_dir);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_backend_class_init (EShellBackendClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_backend_set_property;
+ object_class->get_property = shell_backend_get_property;
+ object_class->dispose = shell_backend_dispose;
+ object_class->finalize = shell_backend_finalize;
+
+ /**
+ * EShellBackend:shell
+ *
+ * The #EShell singleton.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ _("Shell"),
+ _("The EShell singleton"),
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * EShellBackend::activity-added
+ * @shell_backend: the #EShellBackend that emitted the signal
+ * @activity: an #EActivity
+ *
+ * Broadcasts a newly added activity.
+ **/
+ signals[ACTIVITY_ADDED] = g_signal_new (
+ "activity-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACTIVITY);
+}
+
+static void
+shell_backend_init (EShellBackend *shell_backend,
+ EShellBackendClass *class)
+{
+ EShellViewClass *shell_view_class;
+ gchar *dirname;
+
+ shell_backend->priv = E_SHELL_BACKEND_GET_PRIVATE (shell_backend);
+
+ /* Install a reference to ourselves in the corresponding
+ * EShellViewClass structure, */
+ shell_view_class = g_type_class_ref (class->shell_view_type);
+ shell_view_class->shell_backend = g_object_ref (shell_backend);
+ shell_backend->priv->shell_view_class = shell_view_class;
+
+ /* Determine the user data directory for this backend. */
+ shell_backend->priv->data_dir = g_build_filename (
+ e_get_user_data_dir (), class->name, NULL);
+
+ /* Determine the user configuration directory for this backend. */
+ shell_backend->priv->config_dir = g_build_filename (
+ shell_backend->priv->data_dir, "config", NULL);
+
+ /* Create the user configuration directory for this backend,
+ * which should also create the user data directory. */
+ dirname = shell_backend->priv->config_dir;
+ if (g_mkdir_with_parents (dirname, 0777) != 0)
+ g_critical (
+ "Cannot create directory %s: %s",
+ dirname, g_strerror (errno));
+}
+
+GType
+e_shell_backend_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_backend_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EShellBackend", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_backend_compare:
+ * @shell_backend_a: an #EShellBackend
+ * @shell_backend_b: an #EShellBackend
+ *
+ * Using the <structfield>sort_order</structfield> field from both backends'
+ * #EShellBackendClass, compares @shell_backend_a with @shell_mobule_b and
+ * returns -1, 0 or +1 if @shell_backend_a is found to be less than, equal
+ * to or greater than @shell_backend_b, respectively.
+ *
+ * Returns: -1, 0 or +1, for a less than, equal to or greater than result
+ **/
+gint
+e_shell_backend_compare (EShellBackend *shell_backend_a,
+ EShellBackend *shell_backend_b)
+{
+ gint a = E_SHELL_BACKEND_GET_CLASS (shell_backend_a)->sort_order;
+ gint b = E_SHELL_BACKEND_GET_CLASS (shell_backend_b)->sort_order;
+
+ return (a < b) ? -1 : (a > b);
+}
+
+/**
+ * e_shell_backend_get_config_dir:
+ * @shell_backend: an #EShellBackend
+ *
+ * Returns the absolute path to the configuration directory for
+ * @shell_backend. The string is owned by @shell_backend and should
+ * not be modified or freed.
+ *
+ * Returns: the backend's configuration directory
+ **/
+const gchar *
+e_shell_backend_get_config_dir (EShellBackend *shell_backend)
+{
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+ g_return_val_if_fail (shell_backend->priv->config_dir != NULL, NULL);
+
+ return shell_backend->priv->config_dir;
+}
+
+/**
+ * e_shell_backend_get_data_dir:
+ * @shell_backend: an #EShellBackend
+ *
+ * Returns the absolute path to the data directory for @shell_backend.
+ * The string is owned by @shell_backend and should not be modified or
+ * freed.
+ *
+ * Returns: the backend's data directory
+ **/
+const gchar *
+e_shell_backend_get_data_dir (EShellBackend *shell_backend)
+{
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+ g_return_val_if_fail (shell_backend->priv->data_dir != NULL, NULL);
+
+ return shell_backend->priv->data_dir;
+}
+
+/**
+ * e_shell_backend_get_shell:
+ * @shell_backend: an #EShellBackend
+ *
+ * Returns the #EShell singleton.
+ *
+ * Returns: the #EShell
+ **/
+EShell *
+e_shell_backend_get_shell (EShellBackend *shell_backend)
+{
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+
+ return E_SHELL (shell_backend->priv->shell);
+}
+
+/**
+ * e_shell_backend_add_activity:
+ * @shell_backend: an #EShellBackend
+ * @activity: an #EActivity
+ *
+ * Emits an #EShellBackend::activity-added signal.
+ **/
+void
+e_shell_backend_add_activity (EShellBackend *shell_backend,
+ EActivity *activity)
+{
+ g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ g_signal_emit (shell_backend, signals[ACTIVITY_ADDED], 0, activity);
+}
+
+/**
+ * e_shell_backend_start:
+ * @shell_backend: an #EShellBackend
+ *
+ * Tells the @shell_backend to begin loading data or running background
+ * tasks which may consume significant resources. This gets called in
+ * reponse to the user switching to the corresponding #EShellView for
+ * the first time. The function is idempotent for each @shell_backend.
+ **/
+void
+e_shell_backend_start (EShellBackend *shell_backend)
+{
+ EShellBackendClass *class;
+
+ g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+
+ if (shell_backend->priv->started)
+ return;
+
+ class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
+
+ if (class->start != NULL)
+ class->start (shell_backend);
+
+ shell_backend->priv->started = TRUE;
+}
+
+/**
+ * e_shell_migrate:
+ * @shell_backend: an #EShellBackend
+ * @major: major part of version to migrate from
+ * @minor: minor part of version to migrate from
+ * @micro: micro part of version to migrate from
+ * @error: return location for a #GError, or %NULL
+ *
+ * Attempts to migrate data and settings from version %major.%minor.%micro.
+ * Returns %TRUE if the migration was successful or if no action was
+ * necessary. Returns %FALSE and sets %error if the migration failed.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise
+ **/
+gboolean
+e_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ EShellBackendClass *class;
+
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), TRUE);
+
+ class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
+
+ if (class->migrate == NULL)
+ return TRUE;
+
+ return class->migrate (shell_backend, major, minor, micro, error);
+}
diff --git a/shell/e-shell-backend.h b/shell/e-shell-backend.h
new file mode 100644
index 0000000000..6dbbb33ea1
--- /dev/null
+++ b/shell/e-shell-backend.h
@@ -0,0 +1,139 @@
+/*
+ * e-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-backend
+ * @short_description: dynamically loaded capabilities
+ * @include: shell/e-shell-backend.h
+ **/
+
+#ifndef E_SHELL_BACKEND_H
+#define E_SHELL_BACKEND_H
+
+#include <shell/e-shell-common.h>
+#include <misc/e-activity.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_BACKEND \
+ (e_shell_backend_get_type ())
+#define E_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_BACKEND, EShellBackend))
+#define E_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_BACKEND, EShellBackendClass))
+#define E_IS_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_BACKEND))
+#define E_IS_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL_BACKEND))
+#define E_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_BACKEND, EShellBackendClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell.h>, because it includes us! */
+struct _EShell;
+
+typedef struct _EShellBackend EShellBackend;
+typedef struct _EShellBackendClass EShellBackendClass;
+typedef struct _EShellBackendPrivate EShellBackendPrivate;
+
+/**
+ * EShellBackend:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellBackend {
+ GObject parent;
+ EShellBackendPrivate *priv;
+};
+
+/**
+ * EShellBackendClass:
+ * @parent_class: The parent class structure.
+ * @name: The name of the backend. Also becomes the name of
+ * the corresponding #EShellView subclass that the
+ * backend will register.
+ * @aliases: Colon-separated list of aliases that can be used
+ * when referring to a backend by name.
+ * @schemes: Colon-separated list of URI schemes. The #EShell
+ * will forward command-line URIs to the appropriate
+ * backend based on this list.
+ * @sort_order: Used to determine the order of backends listed in
+ * the main menu and in the switcher. See
+ * e_shell_backend_compare().
+ * @shell_view_type: #GType for the corresponding #EShellView subclass.
+ * @start: Method for notifying the backend to begin loading
+ * data and running background tasks. This is called
+ * just before the first instantiation of the
+ * corresponding #EShellView subclass. It allows the
+ * backend to delay initialization steps that consume
+ * significant resources until they are actually needed.
+ * @migrate: Method for notifying the backend to migrate data and
+ * settings from the given version. Returns %TRUE if the
+ * migration was successful or if no action was necessary.
+ * Returns %FALSE and sets a #GError if the migration
+ * failed.
+ *
+ * #EShellBackendClass contains a number of important settings for subclasses.
+ **/
+struct _EShellBackendClass {
+ GObjectClass parent_class;
+
+ GType shell_view_type;
+
+ const gchar *name;
+ const gchar *aliases;
+ const gchar *schemes;
+ gint sort_order;
+
+ /* Methods */
+ void (*start) (EShellBackend *shell_backend);
+ gboolean (*migrate) (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+};
+
+GType e_shell_backend_get_type (void);
+gint e_shell_backend_compare (EShellBackend *shell_backend_a,
+ EShellBackend *shell_backend_b);
+const gchar * e_shell_backend_get_config_dir (EShellBackend *shell_backend);
+const gchar * e_shell_backend_get_data_dir (EShellBackend *shell_backend);
+const gchar * e_shell_backend_get_filename (EShellBackend *shell_backend);
+struct _EShell *e_shell_backend_get_shell (EShellBackend *shell_backend);
+void e_shell_backend_add_activity (EShellBackend *shell_backend,
+ EActivity *activity);
+void e_shell_backend_start (EShellBackend *shell_backend);
+gboolean e_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_SHELL_BACKEND_H */
diff --git a/shell/importer/intelligent.h b/shell/e-shell-common.h
index 5f5f7187f2..7ff35091aa 100644
--- a/shell/importer/intelligent.h
+++ b/shell/e-shell-common.h
@@ -1,4 +1,6 @@
/*
+ * e-shell-common.h
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,16 +15,19 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Kjartan Maraas <kmaraas@gnome.org>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef __INTELLIGENT_H__
-#define __INTELLIGENT_H__
-
-void intelligent_importer_init (void);
+#ifndef E_SHELL_COMMON_H
+#define E_SHELL_COMMON_H
+#ifdef HAVE_CONFIG_H
+#include <config.h>
#endif
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#endif /* E_SHELL_COMMON_H */
diff --git a/shell/e-shell-constants.h b/shell/e-shell-constants.h
deleted file mode 100644
index 13beed8aec..0000000000
--- a/shell/e-shell-constants.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_SHELL_CONSTANTS_H
-#define E_SHELL_CONSTANTS_H
-
-#define E_SHELL_URI_PREFIX "evolution:"
-#define E_SHELL_URI_PREFIX_LEN 10
-
-#define E_SHELL_DEFAULTURI_PREFIX "default:"
-#define E_SHELL_DEFAULTURI_PREFIX_LEN 8
-
-#define E_SHELL_MINI_ICON_SUFFIX "-mini"
-#define E_SHELL_MINI_ICON_SUFFIX_LEN 5
-
-#define E_SHELL_ICON_SIZE 48
-#define E_SHELL_MINI_ICON_SIZE 16
-
-#define E_PATH_SEPARATOR '/'
-#define E_PATH_SEPARATOR_S "/"
-
-#define E_LOCAL_STORAGE_NAME "local"
-#define E_SUMMARY_STORAGE_NAME "summary"
-
-#define E_SUMMARY_URI "evolution:/summary"
-#define E_LOCAL_INBOX_URI "evolution:/local/Inbox"
-#define E_LOCAL_CONTACTS_URI "evolution:/local/Contacts"
-#define E_LOCAL_CALENDAR_URI "evolution:/local/Calendar"
-#define E_LOCAL_TASKS_URI "evolution:/local/Tasks"
-
-#endif
diff --git a/shell/e-shell-content.c b/shell/e-shell-content.c
new file mode 100644
index 0000000000..2fc9569bd2
--- /dev/null
+++ b/shell/e-shell-content.c
@@ -0,0 +1,1559 @@
+/*
+ * e-shell-content.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-content.h"
+
+#include <glib/gi18n.h>
+
+#include "e-util/e-binding.h"
+#include "e-util/e-util.h"
+#include "filter/rule-editor.h"
+#include "widgets/misc/e-action-combo-box.h"
+#include "widgets/misc/e-hinted-entry.h"
+
+#include "e-shell-backend.h"
+#include "e-shell-view.h"
+#include "e-shell-window-actions.h"
+
+#define E_SHELL_CONTENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_CONTENT, EShellContentPrivate))
+
+#define STATE_KEY_SEARCH_FILTER "SearchFilter"
+#define STATE_KEY_SEARCH_SCOPE "SearchScope"
+#define STATE_KEY_SEARCH_TEXT "SearchText"
+
+struct _EShellContentPrivate {
+
+ gpointer shell_view; /* weak pointer */
+
+ RuleContext *search_context;
+ FilterRule *search_rule;
+ gchar *system_filename;
+ gchar *user_filename;
+
+ /* Container for the following widgets */
+ GtkWidget *search_bar;
+
+ /* Search bar widgets */
+ GtkWidget *filter_label;
+ GtkWidget *filter_combo_box;
+ GtkWidget *search_label;
+ GtkWidget *search_entry;
+ GtkWidget *scope_label;
+ GtkWidget *scope_combo_box;
+};
+
+enum {
+ PROP_0,
+ PROP_FILTER_ACTION,
+ PROP_FILTER_VALUE,
+ PROP_FILTER_VISIBLE,
+ PROP_SEARCH_CONTEXT,
+ PROP_SEARCH_HINT,
+ PROP_SEARCH_RULE,
+ PROP_SEARCH_TEXT,
+ PROP_SEARCH_VISIBLE,
+ PROP_SCOPE_ACTION,
+ PROP_SCOPE_VALUE,
+ PROP_SCOPE_VISIBLE,
+ PROP_SHELL_VIEW
+};
+
+static gpointer parent_class;
+
+static void
+shell_content_dialog_rule_changed (GtkWidget *dialog,
+ FilterRule *rule)
+{
+ gboolean sensitive;
+
+ sensitive = (rule != NULL) && (rule->parts != NULL);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_APPLY, sensitive);
+}
+
+static void
+action_search_execute_cb (GtkAction *action,
+ EShellContent *shell_content)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkWidget *widget;
+ const gchar *search_text;
+
+ /* EShellView subclasses are responsible for actually
+ * executing the search. This is all cosmetic stuff. */
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ widget = shell_content->priv->search_entry;
+
+ search_text = e_shell_content_get_search_text (shell_content);
+
+ if (search_text != NULL && *search_text != '\0') {
+ GtkStyle *style;
+ const GdkColor *color;
+
+ style = gtk_widget_get_style (widget);
+ color = &style->base[GTK_STATE_SELECTED];
+ gtk_widget_modify_base (widget, GTK_STATE_NORMAL, color);
+
+ style = gtk_widget_get_style (widget);
+ color = &style->text[GTK_STATE_SELECTED];
+ gtk_widget_modify_text (widget, GTK_STATE_NORMAL, color);
+ } else {
+ /* Text color will be updated when we move the focus. */
+ gtk_widget_modify_base (widget, GTK_STATE_NORMAL, NULL);
+ }
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_CLEAR (shell_window);
+ gtk_action_set_sensitive (action, TRUE);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_SAVE (shell_window);
+ gtk_action_set_sensitive (action, TRUE);
+
+ /* Direct the focus away from the search entry, so that a
+ * focus-in event is required before the text can be changed.
+ * This will reset the entry to the appropriate visual state. */
+ widget = gtk_bin_get_child (GTK_BIN (shell_content));
+ if (GTK_IS_PANED (widget))
+ widget = gtk_paned_get_child1 (GTK_PANED (widget));
+ gtk_widget_grab_focus (widget);
+}
+
+static void
+shell_content_entry_activated_cb (EShellContent *shell_content,
+ GtkWidget *entry)
+{
+ EShellWindow *shell_window;
+ EShellView *shell_view;
+ GtkAction *action;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ /* Verify the shell view is active before proceeding. */
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE (shell_window);
+ gtk_action_activate (action);
+}
+
+static void
+shell_content_entry_icon_press_cb (EShellContent *shell_content,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+
+ /* Show the search options menu when the icon is pressed. */
+
+ if (icon_pos != GTK_ENTRY_ICON_PRIMARY)
+ return;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS (shell_window);
+ gtk_action_activate (action);
+}
+
+static void
+shell_content_entry_icon_release_cb (EShellContent *shell_content,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+
+ /* Clear the search when the icon is pressed and released. */
+
+ if (icon_pos != GTK_ENTRY_ICON_SECONDARY)
+ return;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_CLEAR (shell_window);
+ gtk_action_activate (action);
+}
+
+static gboolean
+shell_content_entry_key_press_cb (EShellContent *shell_content,
+ GdkEventKey *key_event,
+ GtkWidget *entry)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+ guint mask;
+
+ mask = gtk_accelerator_get_default_mod_mask ();
+ if ((key_event->state & mask) != GDK_MOD1_MASK)
+ return FALSE;
+
+ if (key_event->keyval != GDK_Down)
+ return FALSE;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS (shell_window);
+ gtk_action_activate (action);
+
+ return TRUE;
+}
+
+static void
+shell_content_init_search_context (EShellContent *shell_content)
+{
+ EShellContentClass *shell_content_class;
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ EShellBackend *shell_backend;
+ RuleContext *context;
+ FilterRule *rule;
+ FilterPart *part;
+ gchar *system_filename;
+ gchar *user_filename;
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ g_return_if_fail (shell_view_class->search_rules != NULL);
+
+ shell_content_class = E_SHELL_CONTENT_GET_CLASS (shell_content);
+ g_return_if_fail (shell_content_class->new_search_context != NULL);
+
+ /* The basename for built-in searches is specified in the
+ * shell view class. All built-in search rules live in the
+ * same directory. */
+ system_filename = g_build_filename (
+ EVOLUTION_RULEDIR, shell_view_class->search_rules, NULL);
+
+ /* The filename for custom saved searches is always of
+ * the form "$(shell_backend_data_dir)/searches.xml". */
+ user_filename = g_build_filename (
+ e_shell_backend_get_data_dir (shell_backend),
+ "searches.xml", NULL);
+
+ context = shell_content_class->new_search_context ();
+ rule_context_add_part_set (
+ context, "partset", FILTER_TYPE_PART,
+ rule_context_add_part, rule_context_next_part);
+ rule_context_add_rule_set (
+ context, "ruleset", FILTER_TYPE_RULE,
+ rule_context_add_rule, rule_context_next_rule);
+ rule_context_load (context, system_filename, user_filename);
+
+ /* XXX Not sure why this is necessary. */
+ g_object_set_data_full (
+ G_OBJECT (context), "system",
+ g_strdup (system_filename), g_free);
+ g_object_set_data_full (
+ G_OBJECT (context), "user",
+ g_strdup (user_filename), g_free);
+
+ rule = filter_rule_new ();
+ part = rule_context_next_part (context, NULL);
+ if (part == NULL)
+ g_warning (
+ "Could not load %s search: no parts",
+ e_shell_view_get_name (shell_view));
+ else
+ filter_rule_add_part (rule, filter_part_clone (part));
+
+ shell_content->priv->search_context = context;
+ shell_content->priv->system_filename = system_filename;
+ shell_content->priv->user_filename = user_filename;
+}
+
+static void
+shell_content_set_shell_view (EShellContent *shell_content,
+ EShellView *shell_view)
+{
+ g_return_if_fail (shell_content->priv->shell_view == NULL);
+
+ shell_content->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &shell_content->priv->shell_view);
+}
+
+static void
+shell_content_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FILTER_ACTION:
+ e_shell_content_set_filter_action (
+ E_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_FILTER_VALUE:
+ e_shell_content_set_filter_value (
+ E_SHELL_CONTENT (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_FILTER_VISIBLE:
+ e_shell_content_set_filter_visible (
+ E_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SEARCH_HINT:
+ e_shell_content_set_search_hint (
+ E_SHELL_CONTENT (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SEARCH_RULE:
+ e_shell_content_set_search_rule (
+ E_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SEARCH_TEXT:
+ e_shell_content_set_search_text (
+ E_SHELL_CONTENT (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SEARCH_VISIBLE:
+ e_shell_content_set_search_visible (
+ E_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SCOPE_ACTION:
+ e_shell_content_set_scope_action (
+ E_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SCOPE_VALUE:
+ e_shell_content_set_scope_value (
+ E_SHELL_CONTENT (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_SCOPE_VISIBLE:
+ e_shell_content_set_scope_visible (
+ E_SHELL_CONTENT (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SHELL_VIEW:
+ shell_content_set_shell_view (
+ E_SHELL_CONTENT (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_content_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_FILTER_ACTION:
+ g_value_set_object (
+ value, e_shell_content_get_filter_action (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_FILTER_VALUE:
+ g_value_set_int (
+ value, e_shell_content_get_filter_value (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_FILTER_VISIBLE:
+ g_value_set_boolean (
+ value, e_shell_content_get_filter_visible (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_CONTEXT:
+ g_value_set_object (
+ value, e_shell_content_get_search_context (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_HINT:
+ g_value_set_string (
+ value, e_shell_content_get_search_hint (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_RULE:
+ g_value_set_object (
+ value, e_shell_content_get_search_rule (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_TEXT:
+ g_value_set_string (
+ value, e_shell_content_get_search_text (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SEARCH_VISIBLE:
+ g_value_set_boolean (
+ value, e_shell_content_get_search_visible (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SCOPE_ACTION:
+ g_value_set_object (
+ value, e_shell_content_get_scope_action (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SCOPE_VALUE:
+ g_value_set_int (
+ value, e_shell_content_get_scope_value (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SCOPE_VISIBLE:
+ g_value_set_boolean (
+ value, e_shell_content_get_scope_visible (
+ E_SHELL_CONTENT (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_shell_content_get_shell_view (
+ E_SHELL_CONTENT (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_content_dispose (GObject *object)
+{
+ EShellContentPrivate *priv;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (object);
+
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view), &priv->shell_view);
+ priv->shell_view = NULL;
+ }
+
+ if (priv->filter_label != NULL) {
+ g_object_unref (priv->filter_label);
+ priv->filter_label = NULL;
+ }
+
+ if (priv->filter_combo_box != NULL) {
+ g_object_unref (priv->filter_combo_box);
+ priv->filter_combo_box = NULL;
+ }
+
+ if (priv->search_context != NULL) {
+ g_object_unref (priv->search_context);
+ priv->search_context = NULL;
+ }
+
+ if (priv->search_label != NULL) {
+ g_object_unref (priv->search_label);
+ priv->search_label = NULL;
+ }
+
+ if (priv->search_entry != NULL) {
+ g_object_unref (priv->search_entry);
+ priv->search_entry = NULL;
+ }
+
+ if (priv->scope_label != NULL) {
+ g_object_unref (priv->scope_label);
+ priv->scope_label = NULL;
+ }
+
+ if (priv->scope_combo_box != NULL) {
+ g_object_unref (priv->scope_combo_box);
+ priv->scope_combo_box = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_content_finalize (GObject *object)
+{
+ EShellContentPrivate *priv;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (object);
+
+ g_free (priv->system_filename);
+ g_free (priv->user_filename);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_content_constructed (GObject *object)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ GtkSizeGroup *size_group;
+ GtkAction *action;
+ GtkWidget *widget;
+
+ shell_content = E_SHELL_CONTENT (object);
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ size_group = e_shell_view_get_size_group (shell_view);
+
+ widget = shell_content->priv->search_entry;
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_CLEAR (shell_window);
+ e_binding_new (
+ G_OBJECT (action), "sensitive",
+ G_OBJECT (widget), "secondary-icon-sensitive");
+ e_binding_new (
+ G_OBJECT (action), "stock-id",
+ G_OBJECT (widget), "secondary-icon-stock");
+ e_binding_new (
+ G_OBJECT (action), "tooltip",
+ G_OBJECT (widget), "secondary-icon-tooltip-text");
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE (shell_window);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_search_execute_cb), shell_content);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS (shell_window);
+ e_binding_new (
+ G_OBJECT (action), "sensitive",
+ G_OBJECT (widget), "primary-icon-sensitive");
+ e_binding_new (
+ G_OBJECT (action), "stock-id",
+ G_OBJECT (widget), "primary-icon-stock");
+ e_binding_new (
+ G_OBJECT (action), "tooltip",
+ G_OBJECT (widget), "primary-icon-tooltip-text");
+
+ widget = shell_content->priv->search_bar;
+ gtk_size_group_add_widget (size_group, widget);
+
+ shell_content_init_search_context (shell_content);
+}
+
+static void
+shell_content_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ EShellContentPrivate *priv;
+ GtkRequisition child_requisition;
+ GtkWidget *child;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (widget);
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ gtk_widget_size_request (child, requisition);
+
+ child = priv->search_bar;
+ gtk_widget_size_request (child, &child_requisition);
+ requisition->width = MAX (requisition->width, child_requisition.width);
+ requisition->height += child_requisition.height;
+}
+
+static void
+shell_content_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EShellContentPrivate *priv;
+ GtkAllocation child_allocation;
+ GtkRequisition child_requisition;
+ GtkWidget *child;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (widget);
+
+ widget->allocation = *allocation;
+
+ child = priv->search_bar;
+ gtk_widget_size_request (child, &child_requisition);
+
+ child_allocation.x = allocation->x;
+ child_allocation.y = allocation->y;
+ child_allocation.width = allocation->width;
+ child_allocation.height = child_requisition.height;
+
+ gtk_widget_size_allocate (child, &child_allocation);
+
+ child_allocation.y += child_requisition.height;
+ child_allocation.height =
+ allocation->height - child_requisition.height;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_size_allocate (child, &child_allocation);
+}
+
+static void
+shell_content_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ EShellContentPrivate *priv;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (container);
+
+ /* Look in the internal widgets first. */
+
+ if (widget == priv->search_bar) {
+ gtk_widget_unparent (priv->search_bar);
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ return;
+ }
+
+ /* Chain up to parent's remove() method. */
+ GTK_CONTAINER_CLASS (parent_class)->remove (container, widget);
+}
+
+static void
+shell_content_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ EShellContentPrivate *priv;
+
+ priv = E_SHELL_CONTENT_GET_PRIVATE (container);
+
+ if (include_internals)
+ callback (priv->search_bar, callback_data);
+
+ /* Chain up to parent's forall() method. */
+ GTK_CONTAINER_CLASS (parent_class)->forall (
+ container, include_internals, callback, callback_data);
+}
+
+static void
+shell_content_class_init (EShellContentClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellContentPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_content_set_property;
+ object_class->get_property = shell_content_get_property;
+ object_class->dispose = shell_content_dispose;
+ object_class->finalize = shell_content_finalize;
+ object_class->constructed = shell_content_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->size_request = shell_content_size_request;
+ widget_class->size_allocate = shell_content_size_allocate;
+
+ container_class = GTK_CONTAINER_CLASS (class);
+ container_class->remove = shell_content_remove;
+ container_class->forall = shell_content_forall;
+
+ class->new_search_context = rule_context_new;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FILTER_ACTION,
+ g_param_spec_object (
+ "filter-action",
+ NULL,
+ NULL,
+ GTK_TYPE_RADIO_ACTION,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FILTER_VALUE,
+ g_param_spec_int (
+ "filter-value",
+ NULL,
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FILTER_VISIBLE,
+ g_param_spec_boolean (
+ "filter-visible",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_CONTEXT,
+ g_param_spec_object (
+ "search-context",
+ NULL,
+ NULL,
+ RULE_TYPE_CONTEXT,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_HINT,
+ g_param_spec_string (
+ "search-hint",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_RULE,
+ g_param_spec_object (
+ "search-rule",
+ NULL,
+ NULL,
+ FILTER_TYPE_RULE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_TEXT,
+ g_param_spec_string (
+ "search-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SEARCH_VISIBLE,
+ g_param_spec_boolean (
+ "search-visible",
+ NULL,
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCOPE_ACTION,
+ g_param_spec_object (
+ "scope-action",
+ NULL,
+ NULL,
+ GTK_TYPE_RADIO_ACTION,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCOPE_VALUE,
+ g_param_spec_int (
+ "scope-value",
+ NULL,
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCOPE_VISIBLE,
+ g_param_spec_boolean (
+ "scope-visible",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ NULL,
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+shell_content_init (EShellContent *shell_content)
+{
+ GtkBox *box;
+ GtkLabel *label;
+ GtkWidget *widget;
+
+ shell_content->priv = E_SHELL_CONTENT_GET_PRIVATE (shell_content);
+
+ GTK_WIDGET_SET_FLAGS (shell_content, GTK_NO_WINDOW);
+
+ /*** Build the Search Bar ***/
+
+ widget = gtk_hbox_new (FALSE, 24);
+ gtk_widget_set_parent (widget, GTK_WIDGET (shell_content));
+ shell_content->priv->search_bar = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+
+ /* Filter Combo Widgets */
+
+ box = GTK_BOX (shell_content->priv->search_bar);
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ box = GTK_BOX (widget);
+
+ /* Translators: The "Show:" label precedes a combo box that
+ * allows the user to filter the current view. Examples of
+ * items that appear in the combo box are "Unread Messages",
+ * "Important Messages", or "Active Appointments". */
+ widget = gtk_label_new_with_mnemonic (_("Sho_w:"));
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->filter_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = e_action_combo_box_new ();
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->filter_combo_box = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Search Entry Widgets */
+
+ box = GTK_BOX (shell_content->priv->search_bar);
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_box_pack_start (box, widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ box = GTK_BOX (widget);
+
+ /* Translators: This is part of the quick search interface.
+ * example: Search: [_______________] in [ Current Folder ] */
+ widget = gtk_label_new_with_mnemonic (_("Sear_ch:"));
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->search_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = e_hinted_entry_new ();
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_box_pack_start (box, widget, TRUE, TRUE, 0);
+ shell_content->priv->search_entry = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "activate",
+ G_CALLBACK (shell_content_entry_activated_cb),
+ shell_content);
+
+ g_signal_connect_swapped (
+ widget, "icon-press",
+ G_CALLBACK (shell_content_entry_icon_press_cb),
+ shell_content);
+
+ g_signal_connect_swapped (
+ widget, "icon-release",
+ G_CALLBACK (shell_content_entry_icon_release_cb),
+ shell_content);
+
+ g_signal_connect_swapped (
+ widget, "key-press-event",
+ G_CALLBACK (shell_content_entry_key_press_cb),
+ shell_content);
+
+ /* Scope Combo Widgets */
+
+ /* Translators: This is part of the quick search interface.
+ * example: Search: [_______________] in [ Current Folder ] */
+ widget = gtk_label_new_with_mnemonic (_("i_n"));
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->scope_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = e_action_combo_box_new ();
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
+ shell_content->priv->scope_combo_box = g_object_ref (widget);
+ gtk_widget_show (widget);
+}
+
+GType
+e_shell_content_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EShellContentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_content_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellContent),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_content_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_BIN, "EShellContent", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_content_new:
+ * @shell_view: an #EShellView
+ *
+ * Creates a new #EShellContent instance belonging to @shell_view.
+ *
+ * Returns: a new #EShellContent instance
+ **/
+GtkWidget *
+e_shell_content_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_SHELL_CONTENT, "shell-view", shell_view, NULL);
+}
+
+/**
+ * e_shell_content_check_state:
+ * @shell_content: an #EShellContent
+ *
+ * #EShellContent subclasses should implement the
+ * <structfield>check_state</structfield> method in #EShellContentClass
+ * to return a set of flags describing the current content selection.
+ * Subclasses are responsible for defining their own flags. This is
+ * primarily used to assist shell views with updating actions (see
+ * e_shell_view_update_actions()).
+ *
+ * Returns: a set of flags describing the current @shell_content selection
+ **/
+guint32
+e_shell_content_check_state (EShellContent *shell_content)
+{
+ EShellContentClass *shell_content_class;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0);
+
+ shell_content_class = E_SHELL_CONTENT_GET_CLASS (shell_content);
+ g_return_val_if_fail (shell_content_class->check_state != NULL, 0);
+
+ return shell_content_class->check_state (shell_content);
+}
+
+/**
+ * e_shell_content_get_shell_view:
+ * @shell_content: an #EShellContent
+ *
+ * Returns the #EShellView that was passed to e_shell_content_new().
+ *
+ * Returns: the #EShellView to which @shell_content belongs
+ **/
+EShellView *
+e_shell_content_get_shell_view (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ return E_SHELL_VIEW (shell_content->priv->shell_view);
+}
+
+GtkRadioAction *
+e_shell_content_get_filter_action (EShellContent *shell_content)
+{
+ EActionComboBox *combo_box;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ return e_action_combo_box_get_action (combo_box);
+}
+
+void
+e_shell_content_set_filter_action (EShellContent *shell_content,
+ GtkRadioAction *filter_action)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_set_action (combo_box, filter_action);
+
+ g_object_notify (G_OBJECT (shell_content), "filter-action");
+}
+
+gint
+e_shell_content_get_filter_value (EShellContent *shell_content)
+{
+ EActionComboBox *combo_box;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0);
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ return e_action_combo_box_get_current_value (combo_box);
+}
+
+void
+e_shell_content_set_filter_value (EShellContent *shell_content,
+ gint filter_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_set_current_value (combo_box, filter_value);
+
+ g_object_notify (G_OBJECT (shell_content), "filter-value");
+}
+
+gboolean
+e_shell_content_get_filter_visible (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE);
+
+ return GTK_WIDGET_VISIBLE (shell_content->priv->filter_combo_box);
+}
+
+void
+e_shell_content_set_filter_visible (EShellContent *shell_content,
+ gboolean filter_visible)
+{
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ if (filter_visible) {
+ gtk_widget_show (shell_content->priv->filter_label);
+ gtk_widget_show (shell_content->priv->filter_combo_box);
+ } else {
+ gtk_widget_hide (shell_content->priv->filter_label);
+ gtk_widget_hide (shell_content->priv->filter_combo_box);
+ }
+}
+
+void
+e_shell_content_add_filter_separator_before (EShellContent *shell_content,
+ gint action_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_add_separator_before (combo_box, action_value);
+}
+
+void
+e_shell_content_add_filter_separator_after (EShellContent *shell_content,
+ gint action_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_add_separator_after (combo_box, action_value);
+}
+
+RuleContext *
+e_shell_content_get_search_context (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ return shell_content->priv->search_context;
+}
+
+const gchar *
+e_shell_content_get_search_hint (EShellContent *shell_content)
+{
+ EHintedEntry *entry;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ entry = E_HINTED_ENTRY (shell_content->priv->search_entry);
+
+ return e_hinted_entry_get_hint (entry);
+}
+
+void
+e_shell_content_set_search_hint (EShellContent *shell_content,
+ const gchar *search_hint)
+{
+ EHintedEntry *entry;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ entry = E_HINTED_ENTRY (shell_content->priv->search_entry);
+
+ e_hinted_entry_set_hint (entry, search_hint);
+
+ g_object_notify (G_OBJECT (shell_content), "search-hint");
+}
+
+FilterRule *
+e_shell_content_get_search_rule (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ return shell_content->priv->search_rule;
+}
+
+void
+e_shell_content_set_search_rule (EShellContent *shell_content,
+ FilterRule *search_rule)
+{
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ if (search_rule != NULL) {
+ g_return_if_fail (IS_FILTER_RULE (search_rule));
+ g_object_ref (search_rule);
+ }
+
+ if (shell_content->priv->search_rule != NULL)
+ g_object_unref (shell_content->priv->search_rule);
+
+ shell_content->priv->search_rule = search_rule;
+
+ g_object_notify (G_OBJECT (shell_content), "search-rule");
+}
+
+const gchar *
+e_shell_content_get_search_text (EShellContent *shell_content)
+{
+ EHintedEntry *entry;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ entry = E_HINTED_ENTRY (shell_content->priv->search_entry);
+
+ return e_hinted_entry_get_text (entry);
+}
+
+void
+e_shell_content_set_search_text (EShellContent *shell_content,
+ const gchar *search_text)
+{
+ EHintedEntry *entry;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ entry = E_HINTED_ENTRY (shell_content->priv->search_entry);
+
+ e_hinted_entry_set_text (entry, search_text);
+
+ g_object_notify (G_OBJECT (shell_content), "search-text");
+}
+
+gboolean
+e_shell_content_get_search_visible (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE);
+
+ return GTK_WIDGET_VISIBLE (shell_content->priv->search_entry);
+}
+
+void
+e_shell_content_set_search_visible (EShellContent *shell_content,
+ gboolean search_visible)
+{
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ if (search_visible) {
+ gtk_widget_show (shell_content->priv->search_label);
+ gtk_widget_show (shell_content->priv->search_entry);
+ } else {
+ gtk_widget_hide (shell_content->priv->search_label);
+ gtk_widget_hide (shell_content->priv->search_entry);
+ }
+}
+
+GtkRadioAction *
+e_shell_content_get_scope_action (EShellContent *shell_content)
+{
+ EActionComboBox *combo_box;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box);
+
+ return e_action_combo_box_get_action (combo_box);
+}
+
+void
+e_shell_content_set_scope_action (EShellContent *shell_content,
+ GtkRadioAction *scope_action)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box);
+
+ e_action_combo_box_set_action (combo_box, scope_action);
+
+ g_object_notify (G_OBJECT (shell_content), "scope-action");
+}
+
+gint
+e_shell_content_get_scope_value (EShellContent *shell_content)
+{
+ EActionComboBox *combo_box;
+
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0);
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box);
+
+ return e_action_combo_box_get_current_value (combo_box);
+}
+
+void
+e_shell_content_set_scope_value (EShellContent *shell_content,
+ gint scope_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box);
+
+ e_action_combo_box_set_current_value (combo_box, scope_value);
+
+ g_object_notify (G_OBJECT (shell_content), "scope-value");
+}
+
+gboolean
+e_shell_content_get_scope_visible (EShellContent *shell_content)
+{
+ g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE);
+
+ return GTK_WIDGET_VISIBLE (shell_content->priv->scope_combo_box);
+}
+
+void
+e_shell_content_set_scope_visible (EShellContent *shell_content,
+ gboolean scope_visible)
+{
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ if (scope_visible) {
+ gtk_widget_show (shell_content->priv->scope_label);
+ gtk_widget_show (shell_content->priv->scope_combo_box);
+ } else {
+ gtk_widget_hide (shell_content->priv->scope_label);
+ gtk_widget_hide (shell_content->priv->scope_combo_box);
+ }
+
+ g_object_notify (G_OBJECT (shell_content), "scope-visible");
+}
+
+void
+e_shell_content_run_advanced_search_dialog (EShellContent *shell_content)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkAction *action;
+ GtkWidget *dialog;
+ GtkWidget *widget;
+ FilterRule *rule;
+ RuleContext *context;
+ const gchar *user_filename;
+ gint response;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ user_filename = shell_content->priv->user_filename;
+
+ rule = e_shell_content_get_search_rule (shell_content);
+
+ if (rule == NULL)
+ rule = filter_rule_new ();
+ else
+ rule = filter_rule_clone (rule);
+
+ context = e_shell_content_get_search_context (shell_content);
+ widget = filter_rule_get_widget (rule, context);
+ filter_rule_set_source (rule, FILTER_SOURCE_INCOMING);
+
+ dialog = gtk_dialog_new_with_buttons (
+ _("Advanced Search"), GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_APPLY,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 7);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 300);
+
+ gtk_box_pack_start (
+ GTK_BOX (GTK_DIALOG (dialog)->vbox), widget, TRUE, TRUE, 0);
+
+ g_signal_connect_swapped (
+ rule, "changed", G_CALLBACK (
+ shell_content_dialog_rule_changed), dialog);
+
+ shell_content_dialog_rule_changed (dialog, rule);
+
+run:
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response != GTK_RESPONSE_OK && response != GTK_RESPONSE_APPLY)
+ goto exit;
+
+ if (!filter_rule_validate (rule))
+ goto run;
+
+ e_shell_content_set_search_rule (shell_content, rule);
+
+ action = E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE (shell_window);
+ gtk_action_activate (action);
+
+ if (response == GTK_RESPONSE_APPLY) {
+ if (!rule_context_find_rule (context, rule->name, rule->source))
+ rule_context_add_rule (context, rule);
+ rule_context_save (context, user_filename);
+ goto run;
+ }
+
+exit:
+ g_object_unref (rule);
+ gtk_widget_destroy (dialog);
+}
+
+void
+e_shell_content_run_edit_searches_dialog (EShellContent *shell_content)
+{
+ RuleContext *context;
+ RuleEditor *editor;
+ const gchar *user_filename;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ context = e_shell_content_get_search_context (shell_content);
+ user_filename = shell_content->priv->user_filename;
+
+ editor = rule_editor_new (
+ context, FILTER_SOURCE_INCOMING, _("Searches"));
+ gtk_window_set_title (GTK_WINDOW (editor), _("Searches"));
+
+ if (gtk_dialog_run (GTK_DIALOG (editor)) == GTK_RESPONSE_OK)
+ rule_context_save (context, user_filename);
+
+ gtk_widget_destroy (GTK_WIDGET (editor));
+}
+
+void
+e_shell_content_run_save_search_dialog (EShellContent *shell_content)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GtkWidget *dialog;
+ GtkWidget *widget;
+ FilterRule *rule;
+ RuleContext *context;
+ const gchar *search_text;
+ const gchar *user_filename;
+ gchar *search_name;
+ gint response;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ user_filename = shell_content->priv->user_filename;
+
+ rule = e_shell_content_get_search_rule (shell_content);
+ g_return_if_fail (IS_FILTER_RULE (rule));
+ rule = filter_rule_clone (rule);
+
+ search_text = e_shell_content_get_search_text (shell_content);
+ if (search_text == NULL || *search_text == '\0')
+ search_text = "''";
+
+ search_name = g_strdup_printf ("%s %s", rule->name, search_text);
+ filter_rule_set_name (rule, search_name);
+ g_free (search_name);
+
+ context = e_shell_content_get_search_context (shell_content);
+ widget = filter_rule_get_widget (rule, context);
+ filter_rule_set_source (rule, FILTER_SOURCE_INCOMING);
+
+ dialog = gtk_dialog_new_with_buttons (
+ _("Save Search"), GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 7);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 300);
+
+ gtk_box_pack_start (
+ GTK_BOX (GTK_DIALOG (dialog)->vbox), widget, TRUE, TRUE, 0);
+
+ g_signal_connect_swapped (
+ rule, "changed", G_CALLBACK (
+ shell_content_dialog_rule_changed), dialog);
+
+ shell_content_dialog_rule_changed (dialog, rule);
+
+run:
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response != GTK_RESPONSE_OK)
+ goto exit;
+
+ if (!filter_rule_validate (rule))
+ goto run;
+
+ rule_context_add_rule (context, rule);
+ rule_context_save (context, user_filename);
+
+exit:
+ g_object_unref (rule);
+ gtk_widget_destroy (dialog);
+}
+
+void
+e_shell_content_restore_state (EShellContent *shell_content,
+ const gchar *group_name)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ GKeyFile *key_file;
+ GtkAction *action;
+ GtkWidget *widget;
+ const gchar *key;
+ gchar *string;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+ g_return_if_fail (group_name != NULL);
+
+ shell_view = e_shell_content_get_shell_view (shell_content);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ key_file = e_shell_view_get_state_key_file (shell_view);
+
+ /* Changing the combo boxes triggers searches, so block
+ * the search action until the state is fully restored. */
+ action = e_shell_window_get_action (shell_window, "search-execute");
+ gtk_action_block_activate (action);
+
+ key = STATE_KEY_SEARCH_FILTER;
+ string = g_key_file_get_string (key_file, group_name, key, NULL);
+ if (string != NULL && *string != '\0')
+ action = e_shell_window_get_action (shell_window, string);
+ else
+ action = NULL;
+ if (action != NULL)
+ gtk_action_activate (action);
+ else {
+ /* Pick the first combo box item. */
+ widget = shell_content->priv->filter_combo_box;
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ }
+ g_free (string);
+
+ key = STATE_KEY_SEARCH_SCOPE;
+ string = g_key_file_get_string (key_file, group_name, key, NULL);
+ if (string != NULL && *string != '\0')
+ action = e_shell_window_get_action (shell_window, string);
+ else
+ action = NULL;
+ if (action != NULL)
+ gtk_action_activate (action);
+ else {
+ /* Pick the first combo box item. */
+ widget = shell_content->priv->scope_combo_box;
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ }
+ g_free (string);
+
+ key = STATE_KEY_SEARCH_TEXT;
+ string = g_key_file_get_string (key_file, group_name, key, NULL);
+ e_shell_content_set_search_text (shell_content, string);
+ g_free (string);
+
+ action = e_shell_window_get_action (shell_window, "search-execute");
+ gtk_action_unblock_activate (action);
+
+ /* Now execute the search. */
+ gtk_action_activate (action);
+}
diff --git a/shell/e-shell-content.h b/shell/e-shell-content.h
new file mode 100644
index 0000000000..8e754fff26
--- /dev/null
+++ b/shell/e-shell-content.h
@@ -0,0 +1,148 @@
+/*
+ * e-shell-content.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-content
+ * @short_description: the right side of the main window
+ * @include: shell/e-shell-content.h
+ **/
+
+#ifndef E_SHELL_CONTENT_H
+#define E_SHELL_CONTENT_H
+
+#include <shell/e-shell-common.h>
+#include <filter/filter-rule.h>
+#include <filter/rule-context.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_CONTENT \
+ (e_shell_content_get_type ())
+#define E_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_CONTENT, EShellContent))
+#define E_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_CONTENT, EShellContentClass))
+#define E_IS_SHELL_CONTENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_CONTENT))
+#define E_IS_SHELL_CONTENT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_SHELL_CONTENT))
+#define E_SHELL_CONTENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_CONTENT, EShellContentClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell-view.h>, because it includes us! */
+struct _EShellView;
+
+typedef struct _EShellContent EShellContent;
+typedef struct _EShellContentClass EShellContentClass;
+typedef struct _EShellContentPrivate EShellContentPrivate;
+
+/**
+ * EShellContent:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellContent {
+ GtkBin parent;
+ EShellContentPrivate *priv;
+};
+
+struct _EShellContentClass {
+ GtkBinClass parent_class;
+
+ /* Factory Methods */
+ RuleContext * (*new_search_context) (void);
+
+ guint32 (*check_state) (EShellContent *shell_content);
+};
+
+GType e_shell_content_get_type (void);
+GtkWidget * e_shell_content_new (struct _EShellView *shell_view);
+guint32 e_shell_content_check_state (EShellContent *shell_content);
+struct _EShellView *
+ e_shell_content_get_shell_view (EShellContent *shell_content);
+GtkRadioAction *e_shell_content_get_filter_action
+ (EShellContent *shell_content);
+void e_shell_content_set_filter_action
+ (EShellContent *shell_content,
+ GtkRadioAction *filter_action);
+gint e_shell_content_get_filter_value(EShellContent *shell_content);
+void e_shell_content_set_filter_value(EShellContent *shell_content,
+ gint filter_value);
+gboolean e_shell_content_get_filter_visible
+ (EShellContent *shell_content);
+void e_shell_content_set_filter_visible
+ (EShellContent *shell_content,
+ gboolean filter_visible);
+void e_shell_content_add_filter_separator_before
+ (EShellContent *shell_content,
+ gint action_value);
+void e_shell_content_add_filter_separator_after
+ (EShellContent *shell_content,
+ gint action_value);
+RuleContext * e_shell_content_get_search_context
+ (EShellContent *shell_content);
+const gchar * e_shell_content_get_search_hint (EShellContent *shell_content);
+void e_shell_content_set_search_hint (EShellContent *shell_content,
+ const gchar *search_hint);
+FilterRule * e_shell_content_get_search_rule (EShellContent *shell_content);
+void e_shell_content_set_search_rule (EShellContent *shell_content,
+ FilterRule *search_rule);
+const gchar * e_shell_content_get_search_text (EShellContent *shell_content);
+void e_shell_content_set_search_text (EShellContent *shell_content,
+ const gchar *search_text);
+gboolean e_shell_content_get_search_visible
+ (EShellContent *shell_content);
+void e_shell_content_set_search_visible
+ (EShellContent *shell_content,
+ gboolean search_visible);
+GtkRadioAction *e_shell_content_get_scope_action(EShellContent *shell_content);
+void e_shell_content_set_scope_action(EShellContent *shell_content,
+ GtkRadioAction *scope_action);
+gint e_shell_content_get_scope_value (EShellContent *shell_content);
+void e_shell_content_set_scope_value (EShellContent *shell_content,
+ gint scope_value);
+gboolean e_shell_content_get_scope_visible
+ (EShellContent *shell_content);
+void e_shell_content_set_scope_visible
+ (EShellContent *shell_content,
+ gboolean scope_visible);
+const gchar * e_shell_content_get_view_id (EShellContent *shell_content);
+void e_shell_content_set_view_id (EShellContent *shell_content,
+ const gchar *view_id);
+void e_shell_content_run_advanced_search_dialog
+ (EShellContent *shell_content);
+void e_shell_content_run_edit_searches_dialog
+ (EShellContent *shell_content);
+void e_shell_content_run_save_search_dialog
+ (EShellContent *shell_content);
+void e_shell_content_restore_state (EShellContent *shell_content,
+ const gchar *group_name);
+
+G_END_DECLS
+
+#endif /* E_SHELL_CONTENT_H */
diff --git a/shell/e-shell-importer.c b/shell/e-shell-importer.c
index c9953b9589..aba3546443 100644
--- a/shell/e-shell-importer.c
+++ b/shell/e-shell-importer.c
@@ -34,10 +34,6 @@
#include <glib/gi18n.h>
-#include <libgnomeui/gnome-druid.h>
-#include <libgnomeui/gnome-druid-page-edge.h>
-#include <libgnomeui/gnome-druid-page-standard.h>
-
#include "misc/e-gui-utils.h"
#include "e-util/e-dialog-utils.h"
@@ -48,7 +44,6 @@
#include "e-shell.h"
#include "e-shell-window.h"
-#include "e-shell-constants.h"
#include "e-shell-importer.h"
@@ -84,9 +79,7 @@ typedef struct _ImportDialogImporterPage {
typedef struct _ImportData {
EShellWindow *window;
- GladeXML *wizard;
- GtkWidget *dialog;
- GtkWidget *druid;
+ GtkWidget *assistant;
ImportDialogFilePage *filepage;
ImportDialogDestPage *destpage;
ImportDialogTypePage *typepage;
@@ -96,8 +89,6 @@ typedef struct _ImportData {
GtkWidget *typedialog;
GtkWidget *destdialog;
GtkWidget *intelligent;
- GnomeDruidPageEdge *start;
- GnomeDruidPageEdge *finish;
GtkWidget *vbox;
EImport *import;
@@ -236,7 +227,7 @@ filename_changed (GtkWidget *widget,
}
}
- gnome_druid_set_buttons_sensitive(GNOME_DRUID (data->druid), TRUE, fileok, TRUE, FALSE);
+ gtk_assistant_set_page_complete (GTK_ASSISTANT (data->assistant), page->vbox, fileok);
}
static void
@@ -250,29 +241,6 @@ filetype_changed_cb (GtkWidget *combobox, ImportData *data)
filename_changed (data->filepage->filename, data);
}
-#if 0
-static gint
-compare_info_name (gconstpointer data1, const void *data2)
-{
- const Bonobo_ServerInfo *info1 = (Bonobo_ServerInfo *)data1;
- const Bonobo_ServerInfo *info2 = (Bonobo_ServerInfo *)data2;
- const gchar *name1 = get_name_from_component_info (info1);
- const gchar *name2 = get_name_from_component_info (info2);
-
- /* If we can't find a name for a plug-in, its iid will be used
- * for display. Put such plug-ins at the end of the list since
- * their displayed name won't be really user-friendly
- */
- if (name1 == NULL) {
- return -1;
- }
- if (name2 == NULL) {
- return 1;
- }
- return g_utf8_collate (name1, name2);
-}
-#endif
-
static ImportDialogFilePage *
importer_file_page_new (ImportData *data)
{
@@ -328,6 +296,8 @@ importer_file_page_new (ImportData *data)
row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
gtk_label_set_mnemonic_widget(GTK_LABEL(label), page->filetype);
+ gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 12);
+
gtk_widget_show_all (table);
return page;
@@ -342,6 +312,8 @@ importer_dest_page_new (ImportData *data)
page->vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 12);
+
return page;
}
@@ -359,7 +331,10 @@ importer_type_page_new (ImportData *data)
page->file = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (page->intelligent),
_("Import a _single file"));
gtk_box_pack_start (GTK_BOX (page->vbox), page->file, FALSE, FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 12);
+
gtk_widget_show_all (page->vbox);
+
return page;
}
@@ -377,23 +352,25 @@ importer_importer_page_new (ImportData *data)
sep = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (page->vbox), sep, FALSE, FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 12);
+
gtk_widget_show_all (page->vbox);
return page;
}
-static gboolean
-prepare_intelligent_page (GnomeDruidPage *dpage,
- GnomeDruid *druid,
- ImportData *data)
+static void
+prepare_intelligent_page (GtkAssistant *assistant, GtkWidget *apage, ImportData *data)
{
GSList *l;
GtkWidget *table;
gint row;
ImportDialogImporterPage *page = data->importerpage;
- if (page->target != NULL)
- return FALSE;
+ if (page->target != NULL) {
+ gtk_assistant_set_page_complete (assistant, apage, FALSE);
+ return;
+ }
page->target = e_import_target_new_home(data->import, g_get_home_dir());
@@ -403,8 +380,8 @@ prepare_intelligent_page (GnomeDruidPage *dpage,
if (l == NULL) {
gtk_box_pack_start(GTK_BOX (data->importerpage->vbox), create_help("nodata_html"), FALSE, TRUE, 0);
- gnome_druid_set_buttons_sensitive(druid, TRUE, FALSE, TRUE, FALSE);
- return TRUE;
+ gtk_assistant_set_page_complete (assistant, apage, FALSE);
+ return;
}
table = gtk_table_new(g_slist_length(l), 2, FALSE);
@@ -432,33 +409,30 @@ prepare_intelligent_page (GnomeDruidPage *dpage,
gtk_widget_show(table);
gtk_box_pack_start((GtkBox *)data->importerpage->vbox, table, FALSE, FALSE, 0);
- return FALSE;
+ gtk_assistant_set_page_complete (assistant, apage, TRUE);
}
static void
-import_druid_cancel (GnomeDruid *druid,
- ImportData *data)
+import_assistant_cancel (GtkAssistant *assistant, ImportData *data)
{
if (data->import_dialog)
gtk_dialog_response (GTK_DIALOG (data->import_dialog), GTK_RESPONSE_CANCEL);
else
- gtk_widget_destroy (GTK_WIDGET (data->dialog));
+ gtk_widget_destroy (GTK_WIDGET (data->assistant));
}
static gboolean
-import_druid_esc (GnomeDruid *druid,
- GdkEventKey *event,
- ImportData *data)
+import_assistant_esc (GtkAssistant *assistant, GdkEventKey *event, ImportData *data)
{
if (event->keyval == GDK_Escape) {
- gtk_widget_destroy (GTK_WIDGET (data->dialog));
+ gtk_widget_destroy (GTK_WIDGET (assistant));
return TRUE;
} else
return FALSE;
}
static void
-import_druid_weak_notify (gpointer blah,
+import_assistant_weak_notify (gpointer blah,
GObject *where_the_object_was)
{
ImportData *data = (ImportData *) blah;
@@ -466,8 +440,8 @@ import_druid_weak_notify (gpointer blah,
if (data->import_dialog && (GObject *)data->import_dialog != where_the_object_was) {
/* postpone freeing of 'data' after the 'import_dialog' will stop,
but also indicate that the 'dialog' gone already */
- data->dialog = NULL;
- g_object_weak_ref ((GObject *)data->import_dialog, import_druid_weak_notify, data);
+ data->assistant = NULL;
+ g_object_weak_ref ((GObject *)data->import_dialog, import_assistant_weak_notify, data);
gtk_dialog_response (GTK_DIALOG (data->import_dialog), GTK_RESPONSE_CANCEL);
return;
}
@@ -481,7 +455,6 @@ import_druid_weak_notify (gpointer blah,
g_object_unref(data->import);
- g_object_unref(data->wizard);
g_free(data);
}
@@ -505,7 +478,7 @@ static void
import_done(EImport *ei, gpointer d)
{
ImportData *data = d;
- gboolean have_dialog = data->dialog != NULL;
+ gboolean have_dialog = data->assistant != NULL;
gtk_widget_destroy (data->import_dialog);
@@ -513,7 +486,7 @@ import_done(EImport *ei, gpointer d)
on the above destroy call */
if (have_dialog) {
data->import_dialog = NULL;
- gtk_widget_destroy (data->dialog);
+ gtk_widget_destroy (data->assistant);
}
}
@@ -532,9 +505,7 @@ import_intelligent_done(EImport *ei, gpointer d)
}
static void
-import_druid_finish (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
+import_assistant_apply (GtkAssistant *assistant, ImportData *data)
{
EImportCompleteFunc done = NULL;
gchar *msg = NULL;
@@ -567,16 +538,14 @@ import_druid_finish (GnomeDruidPage *page,
e_import_import(data->import, data->import_target, data->import_importer, import_status, import_done, data);
} else {
- gtk_widget_destroy(data->dialog);
+ gtk_widget_destroy(data->assistant);
}
g_free(msg);
}
-static gboolean
-prepare_file_page (GnomeDruidPage *dpage,
- GnomeDruid *druid,
- ImportData *data)
+static void
+prepare_file_page (GtkAssistant *assistant, GtkWidget *apage, ImportData *data)
{
GSList *importers, *imp;
GtkListStore *store;
@@ -584,7 +553,7 @@ prepare_file_page (GnomeDruidPage *dpage,
if (page->target != NULL) {
filename_changed(data->filepage->filename, data);
- return FALSE;
+ return;
}
page->target = e_import_target_new_uri(data->import, NULL, NULL);
@@ -613,23 +582,10 @@ prepare_file_page (GnomeDruidPage *dpage,
filename_changed (data->filepage->filename, data);
g_signal_connect (page->filetype, "changed", G_CALLBACK (filetype_changed_cb), data);
-
- return FALSE;
-}
-
-static gboolean
-next_file_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
-{
- /* We dont sensitise the next button if we're not already usable */
- return FALSE;
}
static gboolean
-prepare_dest_page (GnomeDruidPage *dpage,
- GnomeDruid *druid,
- ImportData *data)
+prepare_dest_page (GtkAssistant *assistant, GtkWidget *apage, ImportData *data)
{
ImportDialogDestPage *page = data->destpage;
@@ -643,174 +599,184 @@ prepare_dest_page (GnomeDruidPage *dpage,
gtk_widget_show(page->control);
}
- gtk_box_pack_start((GtkBox *)data->destpage->vbox, page->control, TRUE, TRUE, 0);
+ gtk_box_pack_start ((GtkBox *)data->destpage->vbox, page->control, TRUE, TRUE, 0);
+ gtk_assistant_set_page_complete (assistant, apage, TRUE);
return FALSE;
}
-static gboolean
-next_dest_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
-{
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->finish));
- return TRUE;
-}
-
-static gboolean
-next_type_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
+static void
+dialog_weak_notify (gpointer data,
+ GObject *where_the_dialog_was)
{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) {
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->intelligent));
- } else {
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->filedialog));
- }
+ gboolean *dialog_open = (gboolean *) data;
- return TRUE;
+ *dialog_open = FALSE;
}
-static gboolean
-back_finish_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
+enum {
+ PAGE_START,
+ PAGE_INTELI_OR_DIRECT,
+ PAGE_INTELI_SOURCE,
+ PAGE_FILE_CHOOSE,
+ PAGE_FILE_DEST,
+ PAGE_FINISH
+};
+
+static gint
+forward_cb (gint current_page, gpointer user_data)
{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) {
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->intelligent));
- } else {
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->destdialog));
+ ImportData *data = user_data;
+
+ switch (current_page) {
+ case PAGE_INTELI_OR_DIRECT:
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent)))
+ return PAGE_INTELI_SOURCE;
+ else
+ return PAGE_FILE_CHOOSE;
+ case PAGE_INTELI_SOURCE:
+ return PAGE_FINISH;
}
- return TRUE;
-}
-
-static gboolean
-back_intelligent_page (GnomeDruidPage *page,
- GnomeDruid *druid,
- ImportData *data)
-{
- gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->typedialog));
- return TRUE;
+ return current_page + 1;
}
static void
-dialog_weak_notify (gpointer data,
- GObject *where_the_dialog_was)
+import_assistant_prepare (GtkAssistant *assistant, GtkWidget *page, gpointer user_data)
{
- gboolean *dialog_open = (gboolean *) data;
-
- *dialog_open = FALSE;
+ ImportData *data = user_data;
+
+ if (page == data->importerpage->vbox)
+ prepare_intelligent_page (assistant, page, data);
+ else if (page == data->filepage->vbox)
+ prepare_file_page (assistant, page, data);
+ else if (page == data->destpage->vbox)
+ prepare_dest_page (assistant, page, data);
}
void
e_shell_importer_start_import (EShellWindow *shell_window)
{
+ const gchar *empty_xpm_img[] = {
+ "48 1 2 1",
+ " c None",
+ ". c #FFFFFF",
+ " "};
ImportData *data = g_new0 (ImportData, 1);
- GtkWidget *html;
+ GtkWidget *html, *page;
static gboolean dialog_open = FALSE;
- GdkPixbuf *icon;
- gchar *gladefile;
+ GdkPixbuf *icon, *spacer;
+ GtkAssistant *assistant;
if (dialog_open) {
return;
}
- data->import = e_import_new("org.gnome.evolution.shell.importer");
+ data->import = e_import_new ("org.gnome.evolution.shell.importer");
icon = e_icon_factory_get_icon ("stock_mail-import", GTK_ICON_SIZE_DIALOG);
+ spacer = gdk_pixbuf_new_from_xpm_data (empty_xpm_img);
dialog_open = TRUE;
data->window = shell_window;
+ data->assistant = gtk_assistant_new ();
- gladefile = g_build_filename (EVOLUTION_GLADEDIR, "import.glade", NULL);
- data->wizard = glade_xml_new (gladefile, NULL, NULL);
- g_free (gladefile);
- data->dialog = glade_xml_get_widget (data->wizard, "importwizard");
- gtk_window_set_default_size (GTK_WINDOW (data->dialog), 480, 320);
- gtk_window_set_wmclass (GTK_WINDOW (data->dialog), "importdruid",
- "Evolution:shell");
- e_dialog_set_transient_for (GTK_WINDOW (data->dialog), GTK_WIDGET (shell_window));
- g_object_weak_ref ((GObject *)data->dialog, dialog_weak_notify, &dialog_open);
-
- data->druid = glade_xml_get_widget (data->wizard, "druid1");
- g_signal_connect (data->druid, "cancel",
- G_CALLBACK (import_druid_cancel), data);
- g_signal_connect (data->druid, "key_press_event",
- G_CALLBACK (import_druid_esc), data);
-
- gtk_button_set_use_underline ((GtkButton *)((GnomeDruid *)data->druid)->finish, TRUE);
- gtk_button_set_label((GtkButton *)((GnomeDruid *)data->druid)->finish, _("_Import"));
+ assistant = GTK_ASSISTANT (data->assistant);
+
+ gtk_window_set_position (GTK_WINDOW (assistant), GTK_WIN_POS_CENTER);
+ gtk_window_set_title (GTK_WINDOW (assistant), _("Evolution Import Assistant"));
+ gtk_window_set_default_size (GTK_WINDOW (assistant), 500, 330);
/* Start page */
- data->start = GNOME_DRUID_PAGE_EDGE (glade_xml_get_widget (data->wizard, "page0"));
- gnome_druid_page_edge_set_logo (data->start, icon);
+ page = gtk_label_new ("");
+ gtk_label_set_line_wrap (GTK_LABEL (page), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (page), 0.0, 0.5);
+ gtk_misc_set_padding (GTK_MISC (page), 12, 12);
+ gtk_label_set_text (GTK_LABEL (page), _(
+ "Welcome to the Evolution Import Assistant.\n"
+ "With this assistant you will be guided through the process of importing external files into Evolution."));
+
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Evolution Import Assistant"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_INTRO);
+ gtk_assistant_set_page_side_image (assistant, page, spacer);
+ gtk_assistant_set_page_complete (assistant, page, TRUE);
/* Intelligent or direct import page */
- data->typedialog = glade_xml_get_widget (data->wizard, "page1");
- gnome_druid_page_standard_set_logo (GNOME_DRUID_PAGE_STANDARD (data->typedialog), icon);
- g_signal_connect (data->typedialog, "next",
- G_CALLBACK (next_type_page), data);
data->typepage = importer_type_page_new (data);
html = create_help ("type_html");
gtk_box_pack_start (GTK_BOX (data->typepage->vbox), html, FALSE, TRUE, 0);
gtk_box_reorder_child (GTK_BOX (data->typepage->vbox), html, 0);
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->typedialog)->vbox), data->typepage->vbox, TRUE, TRUE, 0);
+ page = data->typepage->vbox;
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Importer Type"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
+ gtk_assistant_set_page_complete (assistant, page, TRUE);
/* Intelligent importer source page */
- data->intelligent = glade_xml_get_widget (data->wizard, "page2-intelligent");
- gnome_druid_page_standard_set_logo (GNOME_DRUID_PAGE_STANDARD (data->intelligent), icon);
- g_signal_connect (data->intelligent, "back",
- G_CALLBACK (back_intelligent_page), data);
- g_signal_connect_after (data->intelligent, "prepare",
- G_CALLBACK (prepare_intelligent_page), data);
-
data->importerpage = importer_importer_page_new (data);
html = create_help ("intelligent_html");
gtk_box_pack_start (GTK_BOX (data->importerpage->vbox), html, FALSE, TRUE, 0);
gtk_box_reorder_child (GTK_BOX (data->importerpage->vbox), html, 0);
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->intelligent)->vbox), data->importerpage->vbox, TRUE, TRUE, 0);
+ page = data->importerpage->vbox;
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Select Information to Import"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
/* File selection and file type page */
- data->filedialog = glade_xml_get_widget (data->wizard, "page2-file");
- gnome_druid_page_standard_set_logo (GNOME_DRUID_PAGE_STANDARD (data->filedialog), icon);
- g_signal_connect_after (data->filedialog, "prepare",
- G_CALLBACK (prepare_file_page), data);
- g_signal_connect (data->filedialog, "next",
- G_CALLBACK (next_file_page), data);
data->filepage = importer_file_page_new (data);
-
html = create_help ("file_html");
gtk_box_pack_start (GTK_BOX (data->filepage->vbox), html, FALSE, TRUE, 0);
gtk_box_reorder_child (GTK_BOX (data->filepage->vbox), html, 0);
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->filedialog)->vbox), data->filepage->vbox, TRUE, TRUE, 0);
+ page = data->filepage->vbox;
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Select a File"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
/* File destination page */
- data->destdialog = glade_xml_get_widget (data->wizard, "page3-file");
- g_signal_connect_after (data->destdialog, "prepare",
- G_CALLBACK (prepare_dest_page), data);
- g_signal_connect (data->destdialog, "next",
- G_CALLBACK (next_dest_page), data);
-
data->destpage = importer_dest_page_new (data);
- gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->destdialog)->vbox), data->destpage->vbox, TRUE, TRUE, 0);
+ page = data->destpage->vbox;
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Import Location"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
/* Finish page */
- data->finish = GNOME_DRUID_PAGE_EDGE (glade_xml_get_widget (data->wizard, "page4"));
- gnome_druid_page_edge_set_logo (data->finish, icon);
- g_signal_connect (data->finish, "back",
- G_CALLBACK (back_finish_page), data);
+ page = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (page), 0.5, 0.5);
+ gtk_label_set_text (GTK_LABEL (page), _("Click \"Apply\" to begin importing the file into Evolution."));
- g_signal_connect (data->finish, "finish",
- G_CALLBACK (import_druid_finish), data);
+ gtk_assistant_append_page (assistant, page);
+ gtk_assistant_set_page_header_image (assistant, page, icon);
+ gtk_assistant_set_page_title (assistant, page, _("Import File"));
+ gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
+ gtk_assistant_set_page_side_image (assistant, page, spacer);
+ gtk_assistant_set_page_complete (assistant, page, TRUE);
- g_object_weak_ref ((GObject *)data->dialog, import_druid_weak_notify, data);
+ /* setup the rest */
+ g_object_weak_ref ((GObject *)assistant, dialog_weak_notify, &dialog_open);
+
+ gtk_assistant_set_forward_page_func (assistant, forward_cb, data, NULL);
+
+ g_signal_connect (assistant, "key_press_event", G_CALLBACK (import_assistant_esc), data);
+ g_signal_connect (assistant, "cancel", G_CALLBACK (import_assistant_cancel), data);
+ g_signal_connect (assistant, "prepare", G_CALLBACK (import_assistant_prepare), data);
+ g_signal_connect (assistant, "apply", G_CALLBACK (import_assistant_apply), data);
+
+ g_object_weak_ref ((GObject *)assistant, import_assistant_weak_notify, data);
g_object_unref (icon);
+ g_object_unref (spacer);
+
+ gtk_assistant_update_buttons_state (assistant);
- gtk_widget_show_all (data->dialog);
+ gtk_widget_show_all (data->assistant);
}
diff --git a/shell/e-shell-importer.h b/shell/e-shell-importer.h
index d9dffcfb0b..bd57fbd4f0 100644
--- a/shell/e-shell-importer.h
+++ b/shell/e-shell-importer.h
@@ -20,9 +20,16 @@
*
*/
-#ifndef _E_SHELL_IMPORTER_H_
-#define _E_SHELL_IMPORTER_H_
+#ifndef E_SHELL_IMPORTER_H
+#define E_SHELL_IMPORTER_H
-void e_shell_importer_start_import (EShellWindow *shell_window);
+#include "e-shell-common.h"
+#include "e-shell-window.h"
-#endif
+G_BEGIN_DECLS
+
+void e_shell_importer_start_import (EShellWindow *shell_window);
+
+G_END_DECLS
+
+#endif /* E_SHELL_IMPORTER_H */
diff --git a/shell/e-shell-migrate.c b/shell/e-shell-migrate.c
new file mode 100644
index 0000000000..18e085f0cc
--- /dev/null
+++ b/shell/e-shell-migrate.c
@@ -0,0 +1,351 @@
+/*
+ * e-shell-migrate.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-migrate.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <libedataserver/e-xml-utils.h>
+
+#include "e-util/e-bconf-map.h"
+#include "e-util/e-error.h"
+#include "e-util/e-fsutils.h"
+#include "e-util/e-util.h"
+
+#include "es-event.h"
+
+#define GCONF_VERSION_KEY "/apps/evolution/version"
+#define GCONF_LAST_VERSION_KEY "/apps/evolution/last_version"
+
+static const gchar *
+shell_migrate_get_old_data_dir (void)
+{
+ static gchar *old_data_dir = NULL;
+
+ if (G_UNLIKELY (old_data_dir == NULL))
+ old_data_dir = g_build_filename (
+ g_get_home_dir (), "evolution", NULL);
+
+ return old_data_dir;
+}
+
+static gboolean
+shell_migrate_attempt (EShell *shell,
+ gint major,
+ gint minor,
+ gint micro)
+{
+ GList *backends;
+ gboolean success = TRUE;
+
+ backends = e_shell_get_shell_backends (shell);
+
+ while (success && backends != NULL) {
+ EShellBackend *shell_backend = backends->data;
+ GError *error = NULL;
+
+ success = e_shell_backend_migrate (
+ shell_backend, major, minor, micro, &error);
+
+ if (error != NULL) {
+ gint response;
+
+ response = e_error_run (
+ NULL, "shell:upgrade-failed",
+ error->message, NULL);
+
+ if (response == GTK_RESPONSE_CANCEL)
+ success = FALSE;
+
+ g_error_free (error);
+ }
+
+ backends = g_list_next (backends);
+ }
+
+ return success;
+}
+
+static void
+shell_migrate_get_version (EShell *shell,
+ gint *major,
+ gint *minor,
+ gint *micro)
+{
+ GConfClient *client;
+ const gchar *key;
+ const gchar *old_data_dir;
+ gchar *string;
+
+ old_data_dir = shell_migrate_get_old_data_dir ();
+
+ key = GCONF_VERSION_KEY;
+ client = e_shell_get_gconf_client (shell);
+ string = gconf_client_get_string (client, key, NULL);
+
+ if (string != NULL) {
+ /* Since 1.4.0 we've kept the version key in GConf. */
+ sscanf (string, "%d.%d.%d", major, minor, micro);
+ g_free (string);
+
+ } else if (!g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) {
+ /* If the old data directory does not exist,
+ * it must be a new installation. */
+ *major = 0;
+ *minor = 0;
+ *micro = 0;
+
+ } else {
+ xmlDocPtr doc;
+ xmlNodePtr source;
+ gchar *filename;
+
+ filename = g_build_filename (
+ old_data_dir, "config.xmldb", NULL);
+ doc = e_xml_parse_file (filename);
+ g_free (filename);
+
+ if (doc == NULL)
+ return;
+
+ source = e_bconf_get_path (doc, "/Shell");
+ if (source != NULL) {
+ key = "upgrade_from_1_0_to_1_2_performed";
+ string = e_bconf_get_value (source, key);
+ }
+
+ if (string != NULL && *string == '1') {
+ *major = 1;
+ *minor = 2;
+ *micro = 0;
+ } else {
+ *major = 1;
+ *minor = 0;
+ *micro = 0;
+ }
+
+ g_free (string);
+
+ if (doc != NULL)
+ xmlFreeDoc (doc);
+ }
+}
+
+static gint
+shell_migrate_remove_dir (const gchar *root,
+ const gchar *path)
+{
+ GDir *dir;
+ const gchar *basename;
+ gchar *filename;
+ gint result = -1;
+
+ /* Recursively removes a directory and its contents. */
+
+ dir = g_dir_open (path, 0, NULL);
+ if (dir == NULL)
+ return -1;
+
+ while ((basename = g_dir_read_name (dir)) != NULL) {
+ filename = g_build_filename (path, basename, NULL);
+
+ /* Make sure we haven't strayed from the evolution dir. */
+ g_return_val_if_fail (strlen (path) >= strlen (root), -1);
+ g_return_val_if_fail (g_str_has_prefix (path, root), -1);
+
+ if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
+ if (shell_migrate_remove_dir (root, filename) < 0)
+ goto fail;
+ } else {
+ if (g_unlink (filename) < 0)
+ goto fail;
+ }
+
+ g_free (filename);
+ filename = NULL;
+ }
+
+ result = g_rmdir (path);
+
+fail:
+ g_free (filename);
+ g_dir_close (dir);
+
+ return result;
+}
+
+gboolean
+e_shell_migrate_attempt (EShell *shell)
+{
+ ESEvent *ese;
+ GConfClient *client;
+ const gchar *key;
+ const gchar *old_data_dir;
+ gint major, minor, micro;
+ gint last_major, last_minor, last_micro;
+ gint curr_major, curr_minor, curr_micro;
+ gboolean migrated = FALSE;
+ gchar *string;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+
+ client = e_shell_get_gconf_client (shell);
+ old_data_dir = shell_migrate_get_old_data_dir ();
+
+ if (sscanf (BASE_VERSION, "%d.%d", &curr_major, &curr_minor) != 2) {
+ g_warning ("Could not parse BASE_VERSION (%s)", BASE_VERSION);
+ return TRUE;
+ }
+
+ curr_micro = atoi (UPGRADE_REVISION);
+
+ shell_migrate_get_version (shell, &major, &minor, &micro);
+
+ if (!(curr_major > major ||
+ (curr_major == major && curr_minor > minor) ||
+ (curr_minor == minor && curr_micro > micro)))
+ goto check_old;
+
+ /* If upgrading from < 1.5, we need to copy most data from
+ * ~/evolution to ~/.evolution. Make sure we have the disk
+ * space for it before proceeding. */
+ if (major == 1 && minor < 5) {
+ glong avail;
+ glong usage;
+
+ usage = e_fsutils_usage (old_data_dir);
+ avail = e_fsutils_avail (g_get_home_dir ());
+ if (usage >= 0 && avail >= 0 && avail < usage) {
+ gchar *need;
+ gchar *have;
+
+ need = g_strdup_printf (_("%ld KB"), usage);
+ have = g_strdup_printf (_("%ld KB"), avail);
+
+ e_error_run (
+ NULL, "shell:upgrade-nospace",
+ need, have, NULL);
+
+ g_free (need);
+ g_free (have);
+
+ _exit (EXIT_SUCCESS);
+ }
+ }
+
+ if (!shell_migrate_attempt (shell, major, minor, micro))
+ _exit (EXIT_SUCCESS);
+
+ /* Record a successful migration. */
+ string = g_strdup_printf ("%d.%d.%d", major, minor, micro);
+ gconf_client_set_string (client, GCONF_VERSION_KEY, string, NULL);
+ g_free (string);
+
+ migrated = TRUE;
+
+check_old:
+
+ key = GCONF_LAST_VERSION_KEY;
+
+ /* Try to retrieve the last migrated version from GConf. */
+ string = gconf_client_get_string (client, key, NULL);
+ if (migrated || string == NULL || sscanf (string, "%d.%d.%d",
+ &last_major, &last_minor, &last_micro) != 3) {
+ last_major = major;
+ last_minor = minor;
+ last_micro = micro;
+ }
+ g_free (string);
+
+ /* If the last migrated version was old, check for stuff to remove. */
+ if (last_major == 1 && last_minor < 5 &&
+ g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) {
+
+ gint response;
+
+ string = g_strdup_printf (
+ "%d.%d.%d", last_major, last_minor, last_micro);
+ response = e_error_run (
+ NULL, "shell:upgrade-remove-1-4", string, NULL);
+ g_free (string);
+
+ switch (response) {
+ case GTK_RESPONSE_OK: /* delete */
+ response = e_error_run (
+ NULL,
+ "shell:upgrade-remove-1-4-confirm",
+ NULL);
+ if (response == GTK_RESPONSE_OK)
+ shell_migrate_remove_dir (
+ old_data_dir, old_data_dir);
+ else
+ break;
+ /* fall through */
+
+ case GTK_RESPONSE_ACCEPT: /* keep */
+ last_major = curr_major;
+ last_minor = curr_minor;
+ last_micro = curr_micro;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ last_major = curr_major;
+ last_minor = curr_minor;
+ last_micro = curr_micro;
+ }
+
+ string = g_strdup_printf (
+ "%d.%d.%d", last_major, last_minor, last_micro);
+ gconf_client_set_string (client, key, string, NULL);
+ g_free (string);
+
+ /** @Event: Shell attempted upgrade
+ * @Id: upgrade.done
+ * @Target: ESMenuTargetState
+ *
+ * This event is emitted whenever the shell successfully attempts
+ * an upgrade.
+ **/
+ ese = es_event_peek ();
+ e_event_emit (
+ (EEvent *) ese, "upgrade.done",
+ (EEventTarget *) es_event_target_new_upgrade (
+ ese, curr_major, curr_minor, curr_micro));
+
+ return TRUE;
+}
+
+GQuark
+e_shell_migrate_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0))
+ quark = g_quark_from_static_string (
+ "e-shell-migrate-error-quark");
+
+ return quark;
+}
diff --git a/widgets/misc/e-info-label.h b/shell/e-shell-migrate.h
index 977cc6ac4f..8ebe69709b 100644
--- a/widgets/misc/e-info-label.h
+++ b/shell/e-shell-migrate.h
@@ -1,4 +1,5 @@
/*
+ * e-shell-migrate.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,41 +15,38 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _E_INFO_LABEL_H
-#define _E_INFO_LABEL_H
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
+/* This is an EShell extension that handles migrating from older versions. */
-#define E_INFO_LABEL_GET_CLASS(emfv) ((EInfoLabelClass *) G_OBJECT_GET_CLASS (emfv))
+#ifndef E_SHELL_MIGRATE_H
+#define E_SHELL_MIGRATE_H
-typedef struct _EInfoLabel EInfoLabel;
-typedef struct _EInfoLabelClass EInfoLabelClass;
+#include <shell/e-shell-common.h>
+#include <shell/e-shell.h>
-struct _EInfoLabel {
- GtkHBox parent;
-
- GtkWidget *location;
- GtkWidget *info;
-};
+/**
+ * E_SHELL_MIGRATE_ERROR:
+ *
+ * Error domain for migration operations. Errors in this domain will be
+ * from the #EShellMigrateError enumeration. See #GError for information
+ * on error domains.
+ **/
+#define E_SHELL_MIGRATE_ERROR \
+ (e_shell_migrate_error_quark ())
-struct _EInfoLabelClass {
- GtkHBoxClass parent_class;
-};
+G_BEGIN_DECLS
-GType e_info_label_get_type(void);
+/* XXX Need more specific error codes? */
+typedef enum {
+ E_SHELL_MIGRATE_ERROR_FAILED
+} EShellMigrateError;
-GtkWidget *e_info_label_new(const gchar *icon);
-void e_info_label_set_info(EInfoLabel *, const gchar *loc, const gchar *info);
+gboolean e_shell_migrate_attempt (EShell *shell);
+GQuark e_shell_migrate_error_quark (void);
G_END_DECLS
-#endif /* ! _E_INFO_LABEL_H */
+#endif /* E_SHELL_MIGRATE_H */
diff --git a/shell/e-shell-nm.c b/shell/e-shell-nm.c
index 6a56d0f71b..c520600769 100644
--- a/shell/e-shell-nm.c
+++ b/shell/e-shell-nm.c
@@ -30,48 +30,40 @@
#include <string.h>
#include <glib.h>
#include <e-shell.h>
-#include <Evolution.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <NetworkManager/NetworkManager.h>
-gboolean e_shell_dbus_initialise (EShell *shell);
+static DBusConnection *dbus_connection;
-static DBusConnection *dbus_connection = NULL;
+/* Forward Declaration */
+gboolean e_shell_dbus_initialize (EShell *shell);
static gboolean
-reinit_dbus (gpointer user_data)
+reinit_dbus (EShell *shell)
{
- EShell *shell = user_data;
-
- if (e_shell_dbus_initialise (shell))
- return FALSE;
-
- /* keep trying to re-establish dbus connection */
-
- return TRUE;
+ return !e_shell_dbus_initialize (shell);
}
static DBusHandlerResult
e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED,
- DBusMessage *message, gpointer user_data)
+ DBusMessage *message,
+ gpointer user_data)
{
- const gchar *object;
- EShell *shell = user_data;
- GNOME_Evolution_ShellState shell_state;
- EShellLineStatus line_status;
DBusError error = DBUS_ERROR_INIT;
+ EShell *shell = user_data;
+ const gchar *path;
guint32 state;
- object = dbus_message_get_path (message);
+ path = dbus_message_get_path (message);
if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") &&
- object && !strcmp (object, DBUS_PATH_LOCAL)) {
+ path != NULL && strcmp (path, DBUS_PATH_LOCAL) == 0) {
dbus_connection_unref (dbus_connection);
dbus_connection = NULL;
- g_timeout_add_seconds (3, reinit_dbus, shell);
+ g_timeout_add_seconds (3, (GSourceFunc) reinit_dbus, shell);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -89,14 +81,16 @@ e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
- line_status = e_shell_get_line_status (shell);
-
- if (line_status == E_SHELL_LINE_STATUS_ONLINE && (state == NM_STATE_ASLEEP || state == NM_STATE_DISCONNECTED)) {
- shell_state = GNOME_Evolution_FORCED_OFFLINE;
- e_shell_set_line_status (shell, shell_state);
- } else if (line_status == E_SHELL_LINE_STATUS_FORCED_OFFLINE && state == NM_STATE_CONNECTED) {
- shell_state = GNOME_Evolution_USER_ONLINE;
- e_shell_set_line_status (shell, shell_state);
+ switch (state) {
+ case NM_STATE_CONNECTED:
+ e_shell_set_network_available (shell, TRUE);
+ break;
+ case NM_STATE_ASLEEP:
+ case NM_STATE_DISCONNECTED:
+ e_shell_set_network_available (shell, FALSE);
+ break;
+ default:
+ break;
}
return DBUS_HANDLER_RESULT_HANDLED;
@@ -109,32 +103,39 @@ check_initial_state (EShell *shell)
guint32 state = -1;
DBusError error = DBUS_ERROR_INIT;
- message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "state");
+ message = dbus_message_new_method_call (
+ NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "state");
/* assuming this should be safe to call syncronously */
- response = dbus_connection_send_with_reply_and_block (dbus_connection, message, 100, &error);
+ response = dbus_connection_send_with_reply_and_block (
+ dbus_connection, message, 100, &error);
if (response)
- dbus_message_get_args (response, &error, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);
+ dbus_message_get_args (
+ response, &error, DBUS_TYPE_UINT32,
+ &state, DBUS_TYPE_INVALID);
else {
- g_warning ("%s \n", error.message);
+ g_warning ("%s", error.message);
dbus_error_free (&error);
return;
}
- /* update the state only in the absence of network connection else let the old state prevail */
+ /* Update the state only in the absence of a network connection,
+ * otherwise let the old state prevail. */
if (state == NM_STATE_DISCONNECTED)
- e_shell_set_line_status (shell, GNOME_Evolution_FORCED_OFFLINE);
+ e_shell_set_network_available (shell, FALSE);
dbus_message_unref (message);
dbus_message_unref (response);
}
gboolean
-e_shell_dbus_initialise (EShell *shell)
+e_shell_dbus_initialize (EShell *shell)
{
DBusError error = DBUS_ERROR_INIT;
+ g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+
if (dbus_connection != NULL)
return TRUE;
diff --git a/shell/e-shell-settings-dialog.c b/shell/e-shell-settings-dialog.c
deleted file mode 100644
index 9c7c32d1d5..0000000000
--- a/shell/e-shell-settings-dialog.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib/gi18n.h>
-
-#include "e-shell-settings-dialog.h"
-
-#include "e-corba-config-page.h"
-#include <e-util/e-icon-factory.h>
-
-#include <bonobo/bonobo-widget.h>
-#include <bonobo/bonobo-exception.h>
-
-#include <bonobo-activation/bonobo-activation.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-struct _EShellSettingsDialogPrivate {
- GHashTable *types;
-};
-
-G_DEFINE_TYPE (EShellSettingsDialog, e_shell_settings_dialog, E_TYPE_MULTI_CONFIG_DIALOG)
-
-
-/* FIXME ugly hack to work around that sizing of invisible widgets is broken
- with Bonobo. */
-
-static void
-set_dialog_size (EShellSettingsDialog *dialog)
-{
- PangoLayout *layout;
- PangoContext *context;
- PangoFontMetrics *metrics;
- gint width, height;
-
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (dialog), "M");
- context = pango_layout_get_context (layout);
- metrics = pango_context_get_metrics (context,
- gtk_widget_get_style (GTK_WIDGET (dialog))->font_desc,
- pango_context_get_language (context));
-
- pango_layout_get_pixel_size (layout, &width, NULL);
-
- width *= 60;
- height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics)
- + pango_font_metrics_get_descent (metrics)) * 30;
-
- gtk_window_set_default_size((GtkWindow *)dialog, width, height);
- g_object_unref (layout);
- pango_font_metrics_unref (metrics);
-}
-
-
-/* Page handling. */
-
-struct _Page {
- gchar *title;
- gchar *description;
- GdkPixbuf *icon;
- Bonobo_ActivationProperty *type;
- gint priority;
- EConfigPage *page_widget;
-};
-typedef struct _Page Page;
-
-static Page *
-page_new (const gchar *title,
- const gchar *description,
- GdkPixbuf *icon,
- Bonobo_ActivationProperty *type,
- gint priority,
- EConfigPage *page_widget)
-{
- Page *page;
-
- if (icon != NULL)
- g_object_ref (icon);
-
- page = g_new (Page, 1);
- page->title = g_strdup (title);
- page->description = g_strdup (description);
- page->icon = icon;
- page->type = type;
- page->priority = priority;
- page->page_widget = page_widget;
-
- return page;
-}
-
-static void
-page_free (Page *page)
-{
- g_free (page->title);
- g_free (page->description);
-
- if (page->icon != NULL)
- g_object_unref (page->icon);
-
- g_free (page);
-}
-
-static gint
-compare_page_func (gconstpointer a,
- gconstpointer b)
-{
- const Page *page_a;
- const Page *page_b;
-
- page_a = (const Page *) a;
- page_b = (const Page *) b;
-
- if (page_a->priority == page_b->priority)
- return strcmp (page_a->title, page_b->title);
-
- return page_a->priority - page_b->priority;
-}
-
-static GList *
-sort_page_list (GList *list)
-{
- return g_list_sort (list, compare_page_func);
-}
-
-static void
-load_pages (EShellSettingsDialog *dialog)
-{
- EShellSettingsDialogPrivate *priv;
- Bonobo_ServerInfoList *control_list;
- const gchar * const *language_names;
- CORBA_Environment ev;
- GSList *languages = NULL;
- GList *page_list;
- GList *p;
- gint i, j;
-
- priv = dialog->priv;
-
- CORBA_exception_init (&ev);
-
- control_list = bonobo_activation_query ("repo_ids.has('IDL:GNOME/Evolution/ConfigControl:" BASE_VERSION "')", NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION || control_list == NULL) {
- g_warning ("Cannot load configuration pages -- %s", BONOBO_EX_REPOID (&ev));
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_exception_free (&ev);
-
- language_names = g_get_language_names ();
- while (*language_names != NULL)
- languages = g_slist_append (languages, (gpointer)(*language_names++));
-
- page_list = NULL;
- for (i = 0; i < control_list->_length; i ++) {
- CORBA_Object corba_object;
- Bonobo_ServerInfo *info;
- const gchar *title;
- const gchar *description;
- const gchar *icon_path;
- const gchar *priority_string;
- Bonobo_ActivationProperty *type;
- gint priority;
- GdkPixbuf *icon;
-
- CORBA_exception_init (&ev);
-
- info = & control_list->_buffer[i];
-
- title = bonobo_server_info_prop_lookup (info, "evolution2:config_item:title", languages);
- description = bonobo_server_info_prop_lookup (info, "evolution2:config_item:description", languages);
- icon_path = bonobo_server_info_prop_lookup (info, "evolution2:config_item:icon_name", NULL);
- type = bonobo_server_info_prop_find (info, "evolution2:config_item:type");
- priority_string = bonobo_server_info_prop_lookup (info, "evolution2:config_item:priority", NULL);
-
- if (icon_path == NULL) {
- icon = NULL;
- } else {
- if (g_path_is_absolute (icon_path)) {
- icon = gdk_pixbuf_new_from_file (icon_path, NULL);
- } else {
- icon = e_icon_factory_get_icon (icon_path, GTK_ICON_SIZE_DIALOG);
- }
- }
-
- if (type != NULL && type->v._d != Bonobo_ACTIVATION_P_STRINGV)
- type = NULL;
- if (priority_string == NULL)
- priority = 0xffff;
- else
- priority = atoi (priority_string);
-
- corba_object = bonobo_activation_activate_from_id ((gchar *) info->iid, 0, NULL, &ev);
-
- if (! BONOBO_EX (&ev)) {
- Page *page;
-
- page = page_new (title, description, icon, type, priority,
- E_CONFIG_PAGE (e_corba_config_page_new_from_objref (corba_object)));
-
- page_list = g_list_prepend (page_list, page);
- } else {
- gchar *bonobo_ex_text = bonobo_exception_get_text (&ev);
- g_warning ("Cannot activate %s -- %s", info->iid, bonobo_ex_text);
- g_free (bonobo_ex_text);
- }
-
- if (icon != NULL)
- g_object_unref (icon);
-
- CORBA_exception_free (&ev);
- }
- g_slist_free(languages);
-
- page_list = sort_page_list (page_list);
- for (p = page_list, i = 0; p != NULL; p = p->next, i++) {
- Page *page;
-
- page = (Page *) p->data;
-
- e_multi_config_dialog_add_page (E_MULTI_CONFIG_DIALOG (dialog),
- page->title,
- page->description,
- page->icon,
- page->page_widget);
-
- if (page->type != NULL) {
- Bonobo_StringList list = page->type->v._u.value_stringv;
-
- for (j = 0; j < list._length; j++) {
- if (g_hash_table_lookup (priv->types, list._buffer[j]) == NULL)
- g_hash_table_insert (priv->types, g_strdup (list._buffer[j]),
- GINT_TO_POINTER (i));
- }
- }
-
- page_free (page);
- }
-
- g_list_free (page_list);
- CORBA_free (control_list);
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_finalize (GObject *object)
-{
- EShellSettingsDialog *dialog;
- EShellSettingsDialogPrivate *priv;
-
- dialog = E_SHELL_SETTINGS_DIALOG (object);
- priv = dialog->priv;
-
- g_hash_table_destroy (priv->types);
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_shell_settings_dialog_parent_class)->finalize) (object);
-}
-
-
-static void
-e_shell_settings_dialog_class_init (EShellSettingsDialogClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_shell_settings_dialog_init (EShellSettingsDialog *dialog)
-{
- EShellSettingsDialogPrivate *priv;
-
- priv = g_new (EShellSettingsDialogPrivate, 1);
- priv->types = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) NULL);
-
- dialog->priv = priv;
-
- load_pages (dialog);
- set_dialog_size (dialog);
-
- gtk_window_set_title (GTK_WINDOW (dialog), _("Evolution Preferences"));
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-}
-
-
-GtkWidget *
-e_shell_settings_dialog_new (void)
-{
- EShellSettingsDialog *new;
-
- new = g_object_new (e_shell_settings_dialog_get_type (), NULL);
-
- return GTK_WIDGET (new);
-}
-
-void
-e_shell_settings_dialog_show_type (EShellSettingsDialog *dialog, const gchar *type)
-{
- EShellSettingsDialogPrivate *priv;
- gpointer key, value;
- gint page;
-
- g_return_if_fail (dialog != NULL);
- g_return_if_fail (E_IS_SHELL_SETTINGS_DIALOG (dialog));
- g_return_if_fail (type != NULL);
-
- priv = dialog->priv;
-
- if (!g_hash_table_lookup_extended (priv->types, type, &key, &value)) {
- gchar *slash, *supertype;
-
- slash = strchr (type, '/');
- if (slash) {
- supertype = g_strndup (type, slash - type);
- value = g_hash_table_lookup (priv->types, type);
- g_free (supertype);
- } else
- value = NULL;
- }
- page = GPOINTER_TO_INT (value);
-
- e_multi_config_dialog_show_page (E_MULTI_CONFIG_DIALOG (dialog), page);
-}
-
diff --git a/shell/e-shell-settings-dialog.h b/shell/e-shell-settings-dialog.h
deleted file mode 100644
index b39bc7beb3..0000000000
--- a/shell/e-shell-settings-dialog.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_SHELL_SETTINGS_DIALOG_H_
-#define _E_SHELL_SETTINGS_DIALOG_H_
-
-#include "e-multi-config-dialog.h"
-
-G_BEGIN_DECLS
-
-#define E_TYPE_SHELL_SETTINGS_DIALOG (e_shell_settings_dialog_get_type ())
-#define E_SHELL_SETTINGS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL_SETTINGS_DIALOG, EShellSettingsDialog))
-#define E_SHELL_SETTINGS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_SETTINGS_DIALOG, EShellSettingsDialogClass))
-#define E_IS_SHELL_SETTINGS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL_SETTINGS_DIALOG))
-#define E_IS_SHELL_SETTINGS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_SETTINGS_DIALOG))
-
-
-typedef struct _EShellSettingsDialog EShellSettingsDialog;
-typedef struct _EShellSettingsDialogPrivate EShellSettingsDialogPrivate;
-typedef struct _EShellSettingsDialogClass EShellSettingsDialogClass;
-
-struct _EShellSettingsDialog {
- EMultiConfigDialog parent;
-
- EShellSettingsDialogPrivate *priv;
-};
-
-struct _EShellSettingsDialogClass {
- EMultiConfigDialogClass parent_class;
-};
-
-
-GType e_shell_settings_dialog_get_type (void);
-GtkWidget *e_shell_settings_dialog_new (void);
-void e_shell_settings_dialog_show_type (EShellSettingsDialog *dialog,
- const gchar *type);
-
-G_END_DECLS
-
-#endif /* _E_SHELL_SETTINGS_DIALOG_H_ */
diff --git a/shell/e-shell-settings.c b/shell/e-shell-settings.c
new file mode 100644
index 0000000000..21cc855beb
--- /dev/null
+++ b/shell/e-shell-settings.c
@@ -0,0 +1,702 @@
+/*
+ * e-shell-settings.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-settings.h"
+
+#include "e-util/gconf-bridge.h"
+
+#define E_SHELL_SETTINGS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_SETTINGS, EShellSettingsPrivate))
+
+struct _EShellSettingsPrivate {
+ GArray *value_array;
+ guint debug : 1;
+};
+
+static GList *instances;
+static guint property_count;
+static gpointer parent_class;
+
+static GParamSpec *
+shell_settings_pspec_for_key (const gchar *property_name,
+ const gchar *gconf_key)
+{
+ GConfClient *client;
+ GConfEntry *entry;
+ GConfSchema *schema;
+ GConfValue *default_value;
+ GConfValueType value_type;
+ GParamSpec *pspec;
+ const gchar *bad_type;
+ const gchar *schema_name;
+ GError *error = NULL;
+
+ client = gconf_client_get_default ();
+
+ entry = gconf_client_get_entry (client, gconf_key, NULL, TRUE, &error);
+ if (error != NULL) {
+ g_error ("%s", error->message);
+ g_assert_not_reached ();
+ }
+
+ schema_name = gconf_entry_get_schema_name (entry);
+ if (schema_name == NULL) {
+ g_error ("No schema for GConf key '%s'", gconf_key);
+ g_assert_not_reached ();
+ }
+
+ schema = gconf_client_get_schema (client, schema_name, &error);
+ if (error != NULL) {
+ g_error ("%s", error->message);
+ g_assert_not_reached ();
+ }
+
+ value_type = gconf_schema_get_type (schema);
+ default_value = gconf_schema_get_default_value (schema);
+
+ /* If the schema does not specify a default value, make one up. */
+ if (default_value == NULL) {
+ default_value = gconf_value_new (value_type);
+
+ /* XXX This should NOT be necessary, but the GConfValue
+ * documentation claims it is. Bother. */
+ switch (value_type) {
+ case GCONF_VALUE_STRING:
+ gconf_value_set_string (default_value, "");
+ break;
+
+ case GCONF_VALUE_INT:
+ gconf_value_set_int (default_value, 0);
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ gconf_value_set_float (default_value, 0.0);
+ break;
+
+ case GCONF_VALUE_BOOL:
+ gconf_value_set_bool (default_value, FALSE);
+ break;
+
+ default:
+ /* We'll fail in the next switch statement. */
+ break;
+ }
+ }
+
+ switch (value_type) {
+ case GCONF_VALUE_STRING:
+ pspec = g_param_spec_string (
+ property_name, NULL, NULL,
+ gconf_value_get_string (default_value),
+ G_PARAM_READWRITE);
+ break;
+
+ case GCONF_VALUE_INT:
+ pspec = g_param_spec_int (
+ property_name, NULL, NULL,
+ G_MININT, G_MAXINT,
+ gconf_value_get_int (default_value),
+ G_PARAM_READWRITE);
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ pspec = g_param_spec_double (
+ property_name, NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE,
+ gconf_value_get_float (default_value),
+ G_PARAM_READWRITE);
+ break;
+
+ case GCONF_VALUE_BOOL:
+ pspec = g_param_spec_boolean (
+ property_name, NULL, NULL,
+ gconf_value_get_bool (default_value),
+ G_PARAM_READWRITE);
+ break;
+
+ case GCONF_VALUE_SCHEMA:
+ bad_type = "schema";
+ goto fail;
+
+ case GCONF_VALUE_LIST:
+ bad_type = "list";
+ goto fail;
+
+ case GCONF_VALUE_PAIR:
+ bad_type = "pair";
+ goto fail;
+
+ default:
+ bad_type = "invalid";
+ goto fail;
+ }
+
+ gconf_value_free (default_value);
+
+ return pspec;
+
+fail:
+ g_error (
+ "Unable to create EShellSettings property for "
+ "GConf key '%s' of type '%s'", gconf_key, bad_type);
+ g_assert_not_reached ();
+}
+
+static void
+shell_settings_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EShellSettingsPrivate *priv;
+ GValue *dest_value;
+
+ priv = E_SHELL_SETTINGS_GET_PRIVATE (object);
+
+ dest_value = &g_array_index (
+ priv->value_array, GValue, property_id - 1);
+
+ g_value_copy (value, dest_value);
+ g_object_notify (object, pspec->name);
+
+ if (priv->debug) {
+ gchar *contents;
+
+ contents = g_strdup_value_contents (value);
+ g_debug (
+ "Setting '%s' set to '%s' (%s)",
+ pspec->name, contents, G_VALUE_TYPE_NAME (value));
+ g_free (contents);
+ }
+}
+
+static void
+shell_settings_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EShellSettingsPrivate *priv;
+ GValue *src_value;
+
+ priv = E_SHELL_SETTINGS_GET_PRIVATE (object);
+
+ src_value = &g_array_index (
+ priv->value_array, GValue, property_id - 1);
+
+ g_value_copy (src_value, value);
+}
+
+static void
+shell_settings_finalize (GObject *object)
+{
+ EShellSettingsPrivate *priv;
+ guint ii;
+
+ priv = E_SHELL_SETTINGS_GET_PRIVATE (object);
+
+ for (ii = 0; ii < priv->value_array->len; ii++)
+ g_value_unset (&g_array_index (priv->value_array, GValue, ii));
+
+ g_array_free (priv->value_array, TRUE);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_settings_class_init (EShellSettingsClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellSettingsPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_settings_set_property;
+ object_class->get_property = shell_settings_get_property;
+ object_class->finalize = shell_settings_finalize;
+}
+
+static void
+shell_settings_init (EShellSettings *shell_settings,
+ GObjectClass *object_class)
+{
+ GArray *value_array;
+ GParamSpec **pspecs;
+ guint ii;
+
+ instances = g_list_prepend (instances, shell_settings);
+
+ value_array = g_array_new (FALSE, TRUE, sizeof (GValue));
+ g_array_set_size (value_array, property_count);
+
+ shell_settings->priv = E_SHELL_SETTINGS_GET_PRIVATE (shell_settings);
+ shell_settings->priv->value_array = value_array;
+
+ g_object_freeze_notify (G_OBJECT (shell_settings));
+
+ pspecs = g_object_class_list_properties (object_class, NULL);
+ for (ii = 0; ii < property_count; ii++) {
+ GParamSpec *pspec = pspecs[ii];
+ GValue *value;
+
+ value = &g_array_index (value_array, GValue, ii);
+ g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_param_value_set_default (pspec, value);
+ g_object_notify (G_OBJECT (shell_settings), pspec->name);
+
+ /* FIXME Need to bind those properties that have
+ * associated GConf keys. */
+ }
+ g_free (pspecs);
+
+ g_object_thaw_notify (G_OBJECT (shell_settings));
+}
+
+GType
+e_shell_settings_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellSettingsClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_settings_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellSettings),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_settings_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EShellSettings", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_settings_install_property:
+ * @pspec: a #GParamSpec
+ *
+ * Installs a new #EShellSettings class property from @pspec.
+ * This is usually done during initialization of an #EShellBackend
+ * or other dynamically loaded entity.
+ **/
+void
+e_shell_settings_install_property (GParamSpec *pspec)
+{
+ static GObjectClass *class = NULL;
+ GList *iter, *next;
+
+ g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+
+ if (G_UNLIKELY (class == NULL))
+ class = g_type_class_ref (E_TYPE_SHELL_SETTINGS);
+
+ if (g_object_class_find_property (class, pspec->name) != NULL) {
+ g_warning (
+ "Settings property \"%s\" already exists",
+ pspec->name);
+ return;
+ }
+
+ for (iter = instances; iter != NULL; iter = iter->next)
+ g_object_freeze_notify (iter->data);
+
+ g_object_class_install_property (class, ++property_count, pspec);
+
+ for (iter = instances; iter != NULL; iter = iter->next) {
+ EShellSettings *shell_settings;
+ GArray *value_array;
+ GValue *value;
+
+ shell_settings = E_SHELL_SETTINGS (iter->data);
+ value_array = shell_settings->priv->value_array;
+ g_array_set_size (value_array, property_count);
+
+ value = &g_array_index (
+ value_array, GValue, property_count - 1);
+ g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_param_value_set_default (pspec, value);
+ g_object_notify (G_OBJECT (shell_settings), pspec->name);
+ }
+
+ for (iter = instances; iter != NULL; iter = next) {
+ next = iter->next;
+ g_object_thaw_notify (iter->data);
+ }
+}
+
+/**
+ * e_shell_settings_install_property_for_key:
+ * @property_name: the name of the property to install
+ * @gconf_key: the GConf key to bind the property to
+ *
+ * Installs a new #EShellSettings class property by examining the
+ * GConf schema for @gconf_key to determine the appropriate type and
+ * default value. This is usually done during initialization of an
+ * #EShellBackend of other dynamically loaded entity.
+ *
+ * After the class property is installed, all #EShellSettings instances
+ * are bound to @gconf_key, causing @property_name and @gconf_key to have
+ * the same value at all times.
+ **/
+void
+e_shell_settings_install_property_for_key (const gchar *property_name,
+ const gchar *gconf_key)
+{
+ GParamSpec *pspec;
+ GList *iter, *next;
+
+ g_return_if_fail (property_name != NULL);
+ g_return_if_fail (gconf_key != NULL);
+
+ pspec = shell_settings_pspec_for_key (property_name, gconf_key);
+ e_shell_settings_install_property (pspec);
+
+ for (iter = instances; iter != NULL; iter = iter->next)
+ g_object_freeze_notify (iter->data);
+
+ for (iter = instances; iter != NULL; iter = iter->next) {
+ EShellSettings *shell_settings;
+
+ shell_settings = E_SHELL_SETTINGS (iter->data);
+
+ gconf_bridge_bind_property (
+ gconf_bridge_get (), gconf_key,
+ G_OBJECT (shell_settings), property_name);
+ }
+
+ for (iter = instances; iter != NULL; iter = next) {
+ next = iter->next;
+ g_object_thaw_notify (iter->data);
+ }
+}
+
+/**
+ * e_shell_settings_enable_debug:
+ * @shell_settings: an #EShellSettings
+ *
+ * Print a debug message to standard output when a property value changes.
+ **/
+void
+e_shell_settings_enable_debug (EShellSettings *shell_settings)
+{
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+
+ shell_settings->priv->debug = TRUE;
+}
+
+/**
+ * e_shell_settings_get_boolean:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Return the contents of an #EShellSettings property of type
+ * #G_TYPE_BOOLEAN.
+ *
+ * Returns: boolean contents of @property_name
+ **/
+gboolean
+e_shell_settings_get_boolean (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gboolean v_boolean;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), FALSE);
+ g_return_val_if_fail (property_name != NULL, FALSE);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_object_get_property (object, property_name, &value);
+ v_boolean = g_value_get_boolean (&value);
+ g_value_unset (&value);
+
+ return v_boolean;
+}
+
+/**
+ * e_shell_settings_set_boolean:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_boolean: boolean value to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_BOOLEAN
+ * to @v_boolean. If @property_name is bound to a GConf key, the GConf key
+ * will also be set to @v_boolean.
+ **/
+void
+e_shell_settings_set_boolean (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gboolean v_boolean)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, v_boolean);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * e_shell_settings_get_int:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Returns the contents of an #EShellSettings property of type
+ * #G_TYPE_INT.
+ *
+ * Returns: integer contents of @property_name
+ **/
+gint
+e_shell_settings_get_int (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gint v_int;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), 0);
+ g_return_val_if_fail (property_name != NULL, 0);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_INT);
+ g_object_get_property (object, property_name, &value);
+ v_int = g_value_get_int (&value);
+ g_value_unset (&value);
+
+ return v_int;
+}
+
+/**
+ * e_shell_settings_set_int:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_int: integer value to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_INT
+ * to @v_int. If @property_name is bound to a GConf key, the GConf key
+ * will also be set to @v_int.
+ **/
+void
+e_shell_settings_set_int (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gint v_int)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_INT);
+ g_value_set_int (&value, v_int);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * e_shell_settings_get_string:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Returns the contents of an #EShellSettings property of type
+ * #G_TYPE_STRING. The returned string should be freed using g_free().
+ *
+ * Returns: string contents of @property_name
+ **/
+gchar *
+e_shell_settings_get_string (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gchar *v_string;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_STRING);
+ g_object_get_property (object, property_name, &value);
+ v_string = g_value_dup_string (&value);
+ g_value_unset (&value);
+
+ return v_string;
+}
+
+/**
+ * e_shell_settings_set_string:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_string: string to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_STRING
+ * to @v_string. If @property_name is bound to a GConf key, the GConf key
+ * will also be set to @v_string.
+ **/
+void
+e_shell_settings_set_string (EShellSettings *shell_settings,
+ const gchar *property_name,
+ const gchar *v_string)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, v_string);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * e_shell_settings_get_object:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Returns the contents of an #EShellSettings property of type
+ * #G_TYPE_OBJECT. The caller owns the reference to the returned
+ * object, and should call g_object_unref() when finished with it.
+ *
+ * Returns: a new reference to the object under @property_name
+ **/
+gpointer
+e_shell_settings_get_object (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gpointer v_object;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_OBJECT);
+ g_object_get_property (object, property_name, &value);
+ v_object = g_value_dup_object (&value);
+ g_value_unset (&value);
+
+ return v_object;
+}
+
+/**
+ * e_shell_settings_set_object:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_object: object to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_OBJECT
+ * to @v_object.
+ **/
+void
+e_shell_settings_set_object (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gpointer v_object)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_OBJECT);
+ g_value_set_object (&value, v_object);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * e_shell_settings_get_pointer:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ *
+ * Returns the contents of an #EShellSettings property of type
+ * #G_TYPE_POINTER.
+ *
+ * Returns: pointer contents of @property_name
+ **/
+gpointer
+e_shell_settings_get_pointer (EShellSettings *shell_settings,
+ const gchar *property_name)
+{
+ GObject *object;
+ GValue value = { 0, };
+ gpointer v_pointer;
+
+ g_return_val_if_fail (E_IS_SHELL_SETTINGS (shell_settings), NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_POINTER);
+ g_object_get_property (object, property_name, &value);
+ v_pointer = g_value_get_pointer (&value);
+ g_value_unset (&value);
+
+ return v_pointer;
+}
+
+/**
+ * e_shell_settings_set_pointer:
+ * @shell_settings: an #EShellSettings
+ * @property_name: an installed property name
+ * @v_pointer: pointer to be set
+ *
+ * Sets the contents of an #EShellSettings property of type #G_TYPE_POINTER
+ * to @v_pointer.
+ **/
+void
+e_shell_settings_set_pointer (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gpointer v_pointer)
+{
+ GObject *object;
+ GValue value = { 0, };
+
+ g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings));
+ g_return_if_fail (property_name != NULL);
+
+ object = G_OBJECT (shell_settings);
+ g_value_init (&value, G_TYPE_POINTER);
+ g_value_set_pointer (&value, v_pointer);
+ g_object_set_property (object, property_name, &value);
+ g_value_unset (&value);
+}
diff --git a/shell/e-shell-settings.h b/shell/e-shell-settings.h
new file mode 100644
index 0000000000..c1ac497dec
--- /dev/null
+++ b/shell/e-shell-settings.h
@@ -0,0 +1,114 @@
+/*
+ * e-shell-settings.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-settings
+ * @short_description: settings management
+ * @include: shell/e-shell-settings.h
+ **/
+
+#ifndef E_SHELL_SETTINGS_H
+#define E_SHELL_SETTINGS_H
+
+#include <shell/e-shell-common.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_SETTINGS \
+ (e_shell_settings_get_type ())
+#define E_SHELL_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_SETTINGS, EShellSettings))
+#define E_SHELL_SETTINGS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_SETTINGS, EShellSettingsClass))
+#define E_IS_SHELL_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_SETTINGS))
+#define E_IS_SHELL_SETTINGS_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL_SETTINGS))
+#define E_SHELL_SETTINGS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_SETTINGS, EShellSettingsClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EShellSettings EShellSettings;
+typedef struct _EShellSettingsClass EShellSettingsClass;
+typedef struct _EShellSettingsPrivate EShellSettingsPrivate;
+
+/**
+ * EShellSettings:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellSettings {
+ GObject parent;
+ EShellSettingsPrivate *priv;
+};
+
+struct _EShellSettingsClass {
+ GObjectClass parent_class;
+};
+
+GType e_shell_settings_get_type (void);
+void e_shell_settings_install_property
+ (GParamSpec *pspec);
+void e_shell_settings_install_property_for_key
+ (const gchar *property_name,
+ const gchar *gconf_key);
+void e_shell_settings_enable_debug (EShellSettings *shell_settings);
+
+/* Getters and setters for common EShellSettings property types.
+ * These are more convenient than g_object_get() / g_object_set().
+ * Add more types as needed. If GObject ever adds similar functions,
+ * kill these. */
+
+gboolean e_shell_settings_get_boolean (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_boolean (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gboolean v_boolean);
+gint e_shell_settings_get_int (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_int (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gint v_int);
+gchar * e_shell_settings_get_string (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_string (EShellSettings *shell_settings,
+ const gchar *property_name,
+ const gchar *v_string);
+gpointer e_shell_settings_get_object (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_object (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gpointer v_object);
+gpointer e_shell_settings_get_pointer (EShellSettings *shell_settings,
+ const gchar *property_name);
+void e_shell_settings_set_pointer (EShellSettings *shell_settings,
+ const gchar *property_name,
+ gpointer v_pointer);
+
+G_END_DECLS
+
+#endif /* E_SHELL_SETTINGS_H */
diff --git a/shell/e-shell-sidebar.c b/shell/e-shell-sidebar.c
new file mode 100644
index 0000000000..7763e64918
--- /dev/null
+++ b/shell/e-shell-sidebar.c
@@ -0,0 +1,683 @@
+/*
+ * e-shell-sidebar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-sidebar.h"
+
+#include <e-shell-view.h>
+
+#define E_SHELL_SIDEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_SIDEBAR, EShellSidebarPrivate))
+
+struct _EShellSidebarPrivate {
+
+ gpointer shell_view; /* weak pointer */
+
+ GtkWidget *event_box;
+ GtkWidget *image;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+ gchar *primary_text;
+ gchar *secondary_text;
+};
+
+enum {
+ PROP_0,
+ PROP_ICON_NAME,
+ PROP_PRIMARY_TEXT,
+ PROP_SECONDARY_TEXT,
+ PROP_SHELL_VIEW
+};
+
+static gpointer parent_class;
+
+static void
+shell_sidebar_set_shell_view (EShellSidebar *shell_sidebar,
+ EShellView *shell_view)
+{
+ g_return_if_fail (shell_sidebar->priv->shell_view == NULL);
+
+ shell_sidebar->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &shell_sidebar->priv->shell_view);
+}
+
+static void
+shell_sidebar_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ICON_NAME:
+ e_shell_sidebar_set_icon_name (
+ E_SHELL_SIDEBAR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_PRIMARY_TEXT:
+ e_shell_sidebar_set_primary_text (
+ E_SHELL_SIDEBAR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SECONDARY_TEXT:
+ e_shell_sidebar_set_secondary_text (
+ E_SHELL_SIDEBAR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SHELL_VIEW:
+ shell_sidebar_set_shell_view (
+ E_SHELL_SIDEBAR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_sidebar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ICON_NAME:
+ g_value_set_string (
+ value, e_shell_sidebar_get_icon_name (
+ E_SHELL_SIDEBAR (object)));
+ return;
+
+ case PROP_PRIMARY_TEXT:
+ g_value_set_string (
+ value, e_shell_sidebar_get_primary_text (
+ E_SHELL_SIDEBAR (object)));
+ return;
+
+ case PROP_SECONDARY_TEXT:
+ g_value_set_string (
+ value, e_shell_sidebar_get_secondary_text (
+ E_SHELL_SIDEBAR (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_shell_sidebar_get_shell_view (
+ E_SHELL_SIDEBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_sidebar_dispose (GObject *object)
+{
+ EShellSidebarPrivate *priv;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view), &priv->shell_view);
+ priv->shell_view = NULL;
+ }
+
+ if (priv->image != NULL) {
+ g_object_unref (priv->image);
+ priv->image = NULL;
+ }
+
+ if (priv->event_box != NULL) {
+ g_object_unref (priv->event_box);
+ priv->event_box = NULL;
+ }
+
+ if (priv->primary_label != NULL) {
+ g_object_unref (priv->primary_label);
+ priv->primary_label = NULL;
+ }
+
+ if (priv->secondary_label != NULL) {
+ g_object_unref (priv->secondary_label);
+ priv->secondary_label = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_sidebar_finalize (GObject *object)
+{
+ EShellSidebarPrivate *priv;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+ g_free (priv->primary_text);
+ g_free (priv->secondary_text);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_sidebar_constructed (GObject *object)
+{
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ GtkSizeGroup *size_group;
+ GtkAction *action;
+ GtkWidget *container;
+ GtkWidget *widget;
+ gchar *label;
+ gchar *icon_name;
+
+ shell_sidebar = E_SHELL_SIDEBAR (object);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ size_group = e_shell_view_get_size_group (shell_view);
+ action = e_shell_view_get_action (shell_view);
+
+ widget = shell_sidebar->priv->event_box;
+ gtk_size_group_add_widget (size_group, widget);
+
+ container = widget;
+
+ widget = gtk_hbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 6);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ shell_sidebar->priv->image = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ shell_sidebar->priv->primary_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ shell_sidebar->priv->secondary_label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_object_get (action, "icon-name", &icon_name, NULL);
+ e_shell_sidebar_set_icon_name (shell_sidebar, icon_name);
+ g_free (icon_name);
+
+ g_object_get (action, "label", &label, NULL);
+ e_shell_sidebar_set_primary_text (shell_sidebar, label);
+ g_free (label);
+}
+
+static void
+shell_sidebar_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ EShellSidebarPrivate *priv;
+ GtkRequisition child_requisition;
+ GtkWidget *child;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (widget);
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ gtk_widget_size_request (child, requisition);
+
+ child = priv->event_box;
+ gtk_widget_size_request (child, &child_requisition);
+ requisition->width = MAX (requisition->width, child_requisition.width);
+ requisition->height += child_requisition.height;
+}
+
+static void
+shell_sidebar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EShellSidebarPrivate *priv;
+ GtkAllocation child_allocation;
+ GtkRequisition child_requisition;
+ GtkWidget *child;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (widget);
+
+ widget->allocation = *allocation;
+
+ child = priv->event_box;
+ gtk_widget_size_request (child, &child_requisition);
+
+ child_allocation.x = allocation->x;
+ child_allocation.y = allocation->y;
+ child_allocation.width = allocation->width;
+ child_allocation.height = child_requisition.height;
+
+ gtk_widget_size_allocate (child, &child_allocation);
+
+ child_allocation.y += child_requisition.height;
+ child_allocation.height =
+ allocation->height - child_requisition.height;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_size_allocate (child, &child_allocation);
+}
+
+static void
+shell_sidebar_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ EShellSidebarPrivate *priv;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (container);
+
+ /* Look in the internal widgets first. */
+
+ if (widget == priv->event_box) {
+ gtk_widget_unparent (priv->event_box);
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ return;
+ }
+
+ /* Chain up to parent's remove() method. */
+ GTK_CONTAINER_CLASS (parent_class)->remove (container, widget);
+}
+
+static void
+shell_sidebar_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ EShellSidebarPrivate *priv;
+
+ priv = E_SHELL_SIDEBAR_GET_PRIVATE (container);
+
+ if (include_internals)
+ callback (priv->event_box, callback_data);
+
+ /* Chain up to parent's forall() method. */
+ GTK_CONTAINER_CLASS (parent_class)->forall (
+ container, include_internals, callback, callback_data);
+}
+
+static void
+shell_sidebar_class_init (EShellSidebarClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellSidebarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_sidebar_set_property;
+ object_class->get_property = shell_sidebar_get_property;
+ object_class->dispose = shell_sidebar_dispose;
+ object_class->finalize = shell_sidebar_finalize;
+ object_class->constructed = shell_sidebar_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->size_request = shell_sidebar_size_request;
+ widget_class->size_allocate = shell_sidebar_size_allocate;
+
+ container_class = GTK_CONTAINER_CLASS (class);
+ container_class->remove = shell_sidebar_remove;
+ container_class->forall = shell_sidebar_forall;
+
+ /**
+ * EShellSidebar:icon-name
+ *
+ * The named icon is displayed at the top of the sidebar.
+ */
+ g_object_class_install_property (
+ object_class,
+ PROP_ICON_NAME,
+ g_param_spec_string (
+ "icon-name",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellSidebar:primary-text
+ *
+ * The primary text is displayed in bold at the top of the sidebar.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_PRIMARY_TEXT,
+ g_param_spec_string (
+ "primary-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellSidebar:secondary-text
+ *
+ * The secondary text is displayed in a smaller font at the top of
+ * the sidebar.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SECONDARY_TEXT,
+ g_param_spec_string (
+ "secondary-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellSidebar:shell-view
+ *
+ * The #EShellView to which the sidebar widget belongs.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ NULL,
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+shell_sidebar_init (EShellSidebar *shell_sidebar)
+{
+ GtkStyle *style;
+ GtkWidget *widget;
+ const GdkColor *color;
+
+ shell_sidebar->priv = E_SHELL_SIDEBAR_GET_PRIVATE (shell_sidebar);
+
+ GTK_WIDGET_SET_FLAGS (shell_sidebar, GTK_NO_WINDOW);
+
+ widget = gtk_event_box_new ();
+ style = gtk_widget_get_style (widget);
+ color = &style->bg[GTK_STATE_ACTIVE];
+ gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, color);
+ gtk_widget_set_parent (widget, GTK_WIDGET (shell_sidebar));
+ shell_sidebar->priv->event_box = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Finish initialization once we have a shell view. */
+}
+
+GType
+e_shell_sidebar_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EShellSidebarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_sidebar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellSidebar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_sidebar_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_BIN, "EShellSidebar", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_sidebar_new:
+ * @shell_view: an #EShellView
+ *
+ * Creates a new #EShellSidebar instance belonging to @shell_view.
+ *
+ * Returns: a new #EShellSidebar instance
+ **/
+GtkWidget *
+e_shell_sidebar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_SHELL_SIDEBAR,
+ "shell-view", shell_view, NULL);
+}
+
+/**
+ * e_shell_sidebar_check_state:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * #EShellSidebar subclasses should implement the
+ * <structfield>check_state</structfield> method in #EShellSidebarClass
+ * to return a set of flags describing the current sidebar selection.
+ * Subclasses are responsible for defining their own flags. This is
+ * primarily used to assist shell views with updating actions (see
+ * e_shell_view_update_actions()).
+ *
+ * Returns: a set of flags describing the current @shell_sidebar selection
+ **/
+guint32
+e_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+ EShellSidebarClass *shell_sidebar_class;
+
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), 0);
+
+ shell_sidebar_class = E_SHELL_SIDEBAR_GET_CLASS (shell_sidebar);
+ g_return_val_if_fail (shell_sidebar_class->check_state != NULL, 0);
+
+ return shell_sidebar_class->check_state (shell_sidebar);
+}
+
+/**
+ * e_shell_sidebar_get_shell_view:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * Returns the #EShellView that was passed to e_shell_sidebar_new().
+ *
+ * Returns: the #EShellView to which @shell_sidebar belongs
+ **/
+EShellView *
+e_shell_sidebar_get_shell_view (EShellSidebar *shell_sidebar)
+{
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
+
+ return E_SHELL_VIEW (shell_sidebar->priv->shell_view);
+}
+
+/**
+ * e_shell_sidebar_get_icon_name:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * Returns the icon name displayed at the top of the sidebar.
+ *
+ * Returns: the icon name for @shell_sidebar
+ **/
+const gchar *
+e_shell_sidebar_get_icon_name (EShellSidebar *shell_sidebar)
+{
+ GtkImage *image;
+ const gchar *icon_name;
+
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
+
+ image = GTK_IMAGE (shell_sidebar->priv->image);
+ gtk_image_get_icon_name (image, &icon_name, NULL);
+
+ return icon_name;
+}
+
+/**
+ * e_shell_sidebar_set_icon_name:
+ * @shell_sidebar: an #EShellSidebar
+ * @icon_name: a themed icon name
+ *
+ * Sets the icon name displayed at the top of the sidebar.
+ **/
+void
+e_shell_sidebar_set_icon_name (EShellSidebar *shell_sidebar,
+ const gchar *icon_name)
+{
+ GtkImage *image;
+
+ g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
+
+ image = GTK_IMAGE (shell_sidebar->priv->image);
+ gtk_image_set_from_icon_name (image, icon_name, GTK_ICON_SIZE_MENU);
+
+ g_object_notify (G_OBJECT (shell_sidebar), "icon-name");
+}
+
+/**
+ * e_shell_sidebar_get_primary_text:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * Returns the primary text for @shell_sidebar.
+ *
+ * The primary text is displayed in bold at the top of the sidebar. It
+ * defaults to the shell view's label (as seen on the switcher button),
+ * but typically shows the name of the selected item in the sidebar.
+ *
+ * Returns: the primary text for @shell_sidebar
+ **/
+const gchar *
+e_shell_sidebar_get_primary_text (EShellSidebar *shell_sidebar)
+{
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
+
+ return shell_sidebar->priv->primary_text;
+}
+
+/**
+ * e_shell_sidebar_set_primary_text:
+ * @shell_sidebar: an #EShellSidebar
+ * @primary_text: text to be displayed in a bold font
+ *
+ * Sets the primary text for @shell_sidebar.
+ *
+ * The primary text is displayed in bold at the top of the sidebar. It
+ * defaults to the shell view's label (as seen on the switcher button),
+ * but typically shows the name of the selected item in the sidebar.
+ **/
+void
+e_shell_sidebar_set_primary_text (EShellSidebar *shell_sidebar,
+ const gchar *primary_text)
+{
+ GtkLabel *label;
+ gchar *markup;
+
+ g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
+
+ g_free (shell_sidebar->priv->primary_text);
+ shell_sidebar->priv->primary_text = g_strdup (primary_text);
+
+ if (primary_text == NULL)
+ primary_text = "";
+
+ label = GTK_LABEL (shell_sidebar->priv->primary_label);
+ markup = g_markup_printf_escaped ("<b>%s</b>", primary_text);
+ gtk_label_set_markup (label, markup);
+ g_free (markup);
+
+ gtk_widget_queue_resize (GTK_WIDGET (shell_sidebar));
+ g_object_notify (G_OBJECT (shell_sidebar), "primary-text");
+}
+
+/**
+ * e_shell_sidebar_get_secondary_text:
+ * @shell_sidebar: an #EShellSidebar
+ *
+ * Returns the secondary text for @shell_sidebar.
+ *
+ * The secondary text is displayed in a smaller font at the top of the
+ * sidebar. It typically shows information about the contents of the
+ * selected sidebar item, such as total number of items, number of
+ * selected items, etc.
+ *
+ * Returns: the secondary text for @shell_sidebar
+ **/
+const gchar *
+e_shell_sidebar_get_secondary_text (EShellSidebar *shell_sidebar)
+{
+ g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
+
+ return shell_sidebar->priv->secondary_text;
+}
+
+/**
+ * e_shell_sidebar_set_secondary_text:
+ * @shell_sidebar: an #EShellSidebar
+ * @secondary_text: text to be displayed in a smaller font
+ *
+ * Sets the secondary text for @shell_sidebar.
+ *
+ * The secondary text is displayed in a smaller font at the top of the
+ * sidebar. It typically shows information about the contents of the
+ * selected sidebar item, such as total number of items, number of
+ * selected items, etc.
+ **/
+void
+e_shell_sidebar_set_secondary_text (EShellSidebar *shell_sidebar,
+ const gchar *secondary_text)
+{
+ GtkLabel *label;
+ gchar *markup;
+
+ g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
+
+ g_free (shell_sidebar->priv->secondary_text);
+ shell_sidebar->priv->secondary_text = g_strdup (secondary_text);
+
+ if (secondary_text == NULL)
+ secondary_text = "";
+
+ label = GTK_LABEL (shell_sidebar->priv->secondary_label);
+ markup = g_markup_printf_escaped ("<small>%s</small>", secondary_text);
+ gtk_label_set_markup (label, markup);
+ g_free (markup);
+
+ gtk_widget_queue_resize (GTK_WIDGET (shell_sidebar));
+ g_object_notify (G_OBJECT (shell_sidebar), "secondary-text");
+}
diff --git a/shell/e-shell-sidebar.h b/shell/e-shell-sidebar.h
new file mode 100644
index 0000000000..5999aa9de2
--- /dev/null
+++ b/shell/e-shell-sidebar.h
@@ -0,0 +1,97 @@
+/*
+ * e-shell-sidebar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-sidebar
+ * @short_description: the left side of the main window
+ * @include: shell/e-shell-sidebar.h
+ **/
+
+#ifndef E_SHELL_SIDEBAR_H
+#define E_SHELL_SIDEBAR_H
+
+#include <shell/e-shell-common.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_SIDEBAR \
+ (e_shell_sidebar_get_type ())
+#define E_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_SIDEBAR, EShellSidebar))
+#define E_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_SIDEBAR, EShellSidebarClass))
+#define E_IS_SHELL_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_SIDEBAR))
+#define E_IS_SHELL_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_SHELL_SIDEBAR))
+#define E_SHELL_SIDEBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_SIDEBAR, EShellSidebarClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell-view.h>, because it includes us! */
+struct _EShellView;
+
+typedef struct _EShellSidebar EShellSidebar;
+typedef struct _EShellSidebarClass EShellSidebarClass;
+typedef struct _EShellSidebarPrivate EShellSidebarPrivate;
+
+/**
+ * EShellSidebar:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellSidebar {
+ GtkBin parent;
+ EShellSidebarPrivate *priv;
+};
+
+struct _EShellSidebarClass {
+ GtkBinClass parent_class;
+
+ guint32 (*check_state) (EShellSidebar *shell_sidebar);
+};
+
+GType e_shell_sidebar_get_type (void);
+GtkWidget * e_shell_sidebar_new (struct _EShellView *shell_view);
+guint32 e_shell_sidebar_check_state (EShellSidebar *shell_sidebar);
+struct _EShellView *
+ e_shell_sidebar_get_shell_view (EShellSidebar *shell_sidebar);
+const gchar * e_shell_sidebar_get_icon_name (EShellSidebar *shell_sidebar);
+void e_shell_sidebar_set_icon_name (EShellSidebar *shell_sidebar,
+ const gchar *icon_name);
+const gchar * e_shell_sidebar_get_primary_text(EShellSidebar *shell_sidebar);
+void e_shell_sidebar_set_primary_text(EShellSidebar *shell_sidebar,
+ const gchar *primary_text);
+const gchar * e_shell_sidebar_get_secondary_text
+ (EShellSidebar *shell_sidebar);
+void e_shell_sidebar_set_secondary_text
+ (EShellSidebar *shell_sidebar,
+ const gchar *secondary_text);
+
+G_END_DECLS
+
+#endif /* E_SHELL_SIDEBAR_H */
diff --git a/shell/e-shell-switcher.c b/shell/e-shell-switcher.c
new file mode 100644
index 0000000000..e1ed8606e5
--- /dev/null
+++ b/shell/e-shell-switcher.c
@@ -0,0 +1,700 @@
+/*
+ * e-shell-switcher.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-switcher.h"
+
+#include <glib/gi18n.h>
+
+#define E_SHELL_SWITCHER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcherPrivate))
+
+#define H_PADDING 6
+#define V_PADDING 6
+
+struct _EShellSwitcherPrivate {
+ GList *proxies;
+ gboolean style_set;
+ GtkToolbarStyle style;
+ GtkSettings *settings;
+ gulong settings_handler_id;
+ gboolean toolbar_visible;
+};
+
+enum {
+ PROP_0,
+ PROP_TOOLBAR_STYLE,
+ PROP_TOOLBAR_VISIBLE
+};
+
+enum {
+ STYLE_CHANGED,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static gint
+shell_switcher_layout_actions (EShellSwitcher *switcher)
+{
+ GtkAllocation *allocation;
+ gint num_btns = g_list_length (switcher->priv->proxies), btns_per_row;
+ GList **rows, *p;
+ gboolean icons_only;
+ gint row_number;
+ gint max_width = 0;
+ gint max_height = 0;
+ gint row_last;
+ gint x, y;
+ gint i;
+
+ allocation = &GTK_WIDGET (switcher)->allocation;
+ y = allocation->y + allocation->height;
+
+ if (num_btns == 0)
+ return allocation->height;
+
+ icons_only = (switcher->priv->style == GTK_TOOLBAR_ICONS);
+
+ /* Figure out the max width and height. */
+ for (p = switcher->priv->proxies; p != NULL; p = p->next) {
+ GtkWidget *widget = p->data;
+ GtkRequisition requisition;
+
+ gtk_widget_size_request (widget, &requisition);
+ max_height = MAX (max_height, requisition.height);
+ max_width = MAX (max_width, requisition.width);
+ }
+
+ /* Figure out how many rows and columns we'll use. */
+ btns_per_row = MAX (1, allocation->width / (max_width + H_PADDING));
+ if (!icons_only) {
+ /* If using text buttons, we want to try to have a
+ * completely filled-in grid, but if we can't, we want
+ * the odd row to have just a single button. */
+ while (num_btns % btns_per_row > 1)
+ btns_per_row--;
+ }
+
+ /* Assign buttons to rows. */
+ rows = g_new0 (GList *, num_btns / btns_per_row + 1);
+
+ if (!icons_only && num_btns % btns_per_row != 0) {
+ rows[0] = g_list_append (rows[0], switcher->priv->proxies->data);
+
+ p = switcher->priv->proxies->next;
+ row_number = p ? 1 : 0;
+ } else {
+ p = switcher->priv->proxies;
+ row_number = 0;
+ }
+
+ for (; p != NULL; p = p->next) {
+ GtkWidget *widget = p->data;
+
+ if (g_list_length (rows[row_number]) == btns_per_row)
+ row_number++;
+
+ rows[row_number] = g_list_append (rows[row_number], widget);
+ }
+
+ row_last = row_number;
+
+ /* Layout the buttons. */
+ for (i = row_last; i >= 0; i--) {
+ gint len, extra_width;
+
+ x = H_PADDING + allocation->x;
+ y -= max_height;
+ len = g_list_length (rows[i]);
+ if (!icons_only)
+ extra_width = (allocation->width - (len * max_width ) - (len * H_PADDING)) / len;
+ else
+ extra_width = 0;
+ for (p = rows [i]; p != NULL; p = p->next) {
+ GtkAllocation child_allocation;
+
+ child_allocation.x = x;
+ child_allocation.y = y;
+ child_allocation.width = max_width + extra_width;
+ child_allocation.height = max_height;
+
+ gtk_widget_size_allocate (GTK_WIDGET (p->data), &child_allocation);
+
+ x += child_allocation.width + H_PADDING;
+ }
+
+ y -= V_PADDING;
+ }
+
+ for (i = 0; i <= row_last; i ++)
+ g_list_free (rows [i]);
+ g_free (rows);
+
+ return y - allocation->y;
+}
+
+static void
+shell_switcher_toolbar_style_changed_cb (EShellSwitcher *switcher)
+{
+ if (!switcher->priv->style_set) {
+ switcher->priv->style_set = TRUE;
+ e_shell_switcher_unset_style (switcher);
+ }
+}
+
+static void
+shell_switcher_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TOOLBAR_STYLE:
+ e_shell_switcher_set_style (
+ E_SHELL_SWITCHER (object),
+ g_value_get_enum (value));
+ return;
+
+ case PROP_TOOLBAR_VISIBLE:
+ e_shell_switcher_set_visible (
+ E_SHELL_SWITCHER (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_switcher_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TOOLBAR_STYLE:
+ g_value_set_enum (
+ value, e_shell_switcher_get_style (
+ E_SHELL_SWITCHER (object)));
+ return;
+
+ case PROP_TOOLBAR_VISIBLE:
+ g_value_set_boolean (
+ value, e_shell_switcher_get_visible (
+ E_SHELL_SWITCHER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_switcher_dispose (GObject *object)
+{
+ EShellSwitcherPrivate *priv;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (object);
+
+ while (priv->proxies != NULL) {
+ GtkWidget *widget = priv->proxies->data;
+ gtk_container_remove (GTK_CONTAINER (object), widget);
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_switcher_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ EShellSwitcherPrivate *priv;
+ GtkWidget *child;
+ GList *iter;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (widget);
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_size_request (child, requisition);
+
+ if (!priv->toolbar_visible)
+ return;
+
+ for (iter = priv->proxies; iter != NULL; iter = iter->next) {
+ GtkWidget *widget = iter->data;
+ GtkRequisition child_requisition;
+
+ gtk_widget_size_request (widget, &child_requisition);
+
+ child_requisition.width += H_PADDING;
+ child_requisition.height += V_PADDING;
+
+ requisition->width = MAX (
+ requisition->width, child_requisition.width);
+ requisition->height += child_requisition.height;
+ }
+}
+
+static void
+shell_switcher_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EShellSwitcher *switcher;
+ GtkAllocation child_allocation;
+ GtkWidget *child;
+ gint height;
+
+ switcher = E_SHELL_SWITCHER (widget);
+
+ widget->allocation = *allocation;
+
+ if (switcher->priv->toolbar_visible)
+ height = shell_switcher_layout_actions (switcher);
+ else
+ height = allocation->height;
+
+ child_allocation.x = allocation->x;
+ child_allocation.y = allocation->y;
+ child_allocation.width = allocation->width;
+ child_allocation.height = height;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child != NULL)
+ gtk_widget_size_allocate (child, &child_allocation);
+}
+
+static void
+shell_switcher_screen_changed (GtkWidget *widget,
+ GdkScreen *previous_screen)
+{
+ EShellSwitcherPrivate *priv;
+ GtkSettings *settings;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (widget);
+
+ if (gtk_widget_has_screen (widget))
+ settings = gtk_widget_get_settings (widget);
+ else
+ settings = NULL;
+
+ if (settings == priv->settings)
+ return;
+
+ if (priv->settings != NULL) {
+ g_signal_handler_disconnect (
+ priv->settings, priv->settings_handler_id);
+ g_object_unref (priv->settings);
+ }
+
+ if (settings != NULL) {
+ priv->settings = g_object_ref (settings);
+ priv->settings_handler_id = g_signal_connect_swapped (
+ settings, "notify::gtk-toolbar-style",
+ G_CALLBACK (shell_switcher_toolbar_style_changed_cb),
+ widget);
+ } else
+ priv->settings = NULL;
+
+ shell_switcher_toolbar_style_changed_cb (E_SHELL_SWITCHER (widget));
+}
+
+static void
+shell_switcher_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ EShellSwitcherPrivate *priv;
+ GList *link;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (container);
+
+ /* Look in the internal widgets first. */
+
+ link = g_list_find (priv->proxies, widget);
+ if (link != NULL) {
+ GtkWidget *widget = link->data;
+
+ gtk_widget_unparent (widget);
+ priv->proxies = g_list_delete_link (priv->proxies, link);
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ return;
+ }
+
+ /* Chain up to parent's remove() method. */
+ GTK_CONTAINER_CLASS (parent_class)->remove (container, widget);
+}
+
+static void
+shell_switcher_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ EShellSwitcherPrivate *priv;
+
+ priv = E_SHELL_SWITCHER_GET_PRIVATE (container);
+
+ if (include_internals)
+ g_list_foreach (
+ priv->proxies, (GFunc) callback, callback_data);
+
+ /* Chain up to parent's forall() method. */
+ GTK_CONTAINER_CLASS (parent_class)->forall (
+ container, include_internals, callback, callback_data);
+}
+
+static void
+shell_switcher_style_changed (EShellSwitcher *switcher,
+ GtkToolbarStyle style)
+{
+ if (switcher->priv->style == style)
+ return;
+
+ switcher->priv->style = style;
+
+ g_list_foreach (
+ switcher->priv->proxies,
+ (GFunc) gtk_tool_item_toolbar_reconfigured, NULL);
+
+ gtk_widget_queue_resize (GTK_WIDGET (switcher));
+ g_object_notify (G_OBJECT (switcher), "toolbar-style");
+}
+
+static GtkIconSize
+shell_switcher_get_icon_size (GtkToolShell *shell)
+{
+ return GTK_ICON_SIZE_LARGE_TOOLBAR;
+}
+
+static GtkOrientation
+shell_switcher_get_orientation (GtkToolShell *shell)
+{
+ return GTK_ORIENTATION_HORIZONTAL;
+}
+
+static GtkToolbarStyle
+shell_switcher_get_style (GtkToolShell *shell)
+{
+ return e_shell_switcher_get_style (E_SHELL_SWITCHER (shell));
+}
+
+static GtkReliefStyle
+shell_switcher_get_relief_style (GtkToolShell *shell)
+{
+ return GTK_RELIEF_NORMAL;
+}
+
+static void
+shell_switcher_class_init (EShellSwitcherClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellSwitcherPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_switcher_set_property;
+ object_class->get_property = shell_switcher_get_property;
+ object_class->dispose = shell_switcher_dispose;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->size_request = shell_switcher_size_request;
+ widget_class->size_allocate = shell_switcher_size_allocate;
+ widget_class->screen_changed = shell_switcher_screen_changed;
+
+ container_class = GTK_CONTAINER_CLASS (class);
+ container_class->remove = shell_switcher_remove;
+ container_class->forall = shell_switcher_forall;
+
+ class->style_changed = shell_switcher_style_changed;
+
+ /**
+ * EShellSwitcher:toolbar-style
+ *
+ * The switcher's toolbar style.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_TOOLBAR_STYLE,
+ g_param_spec_enum (
+ "toolbar-style",
+ _("Toolbar Style"),
+ _("The switcher's toolbar style"),
+ GTK_TYPE_TOOLBAR_STYLE,
+ E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShellSwitcher:toolbar-visible
+ *
+ * Whether the switcher is visible.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_TOOLBAR_VISIBLE,
+ g_param_spec_boolean (
+ "toolbar-visible",
+ _("Toolbar Visible"),
+ _("Whether the switcher is visible"),
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShellSwitcher::style-changed
+ * @switcher: the #EShellSwitcher which emitted the signal
+ * @style: the new #GtkToolbarStyle of the switcher
+ *
+ * Emitted when the style of the switcher changes.
+ **/
+ signals[STYLE_CHANGED] = g_signal_new (
+ "style-changed",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EShellSwitcherClass, style_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_TOOLBAR_STYLE);
+}
+
+static void
+shell_switcher_init (EShellSwitcher *switcher)
+{
+ switcher->priv = E_SHELL_SWITCHER_GET_PRIVATE (switcher);
+
+ GTK_WIDGET_SET_FLAGS (switcher, GTK_NO_WINDOW);
+}
+
+static void
+shell_switcher_tool_shell_iface_init (GtkToolShellIface *iface)
+{
+ iface->get_icon_size = shell_switcher_get_icon_size;
+ iface->get_orientation = shell_switcher_get_orientation;
+ iface->get_style = shell_switcher_get_style;
+ iface->get_relief_style = shell_switcher_get_relief_style;
+}
+
+GType
+e_shell_switcher_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EShellSwitcherClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_switcher_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellSwitcher),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_switcher_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo tool_shell_info = {
+ (GInterfaceInitFunc) shell_switcher_tool_shell_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_BIN, "EShellSwitcher", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, GTK_TYPE_TOOL_SHELL, &tool_shell_info);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_switcher_new:
+ *
+ * Creates a new #EShellSwitcher instance.
+ *
+ * Returns: a new #EShellSwitcher instance
+ **/
+GtkWidget *
+e_shell_switcher_new (void)
+{
+ return g_object_new (E_TYPE_SHELL_SWITCHER, NULL);
+}
+
+/**
+ * e_shell_switcher_add_action:
+ * @switcher: an #EShellSwitcher
+ * @action: a #GtkAction
+ *
+ * Adds a button to @switcher that proxies for @action. Switcher buttons
+ * appear in the order they were added.
+ *
+ * #EShellWindow adds switcher actions in the order given by the
+ * <structfield>sort_order</structfield> field in #EShellBackendClass.
+ **/
+void
+e_shell_switcher_add_action (EShellSwitcher *switcher,
+ GtkAction *action)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ g_object_ref (action);
+ widget = gtk_action_create_tool_item (action);
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (widget), TRUE);
+ gtk_widget_show (widget);
+
+ switcher->priv->proxies = g_list_append (
+ switcher->priv->proxies, widget);
+
+ gtk_widget_set_parent (widget, GTK_WIDGET (switcher));
+ gtk_widget_queue_resize (GTK_WIDGET (switcher));
+}
+
+/**
+ * e_shell_switcher_get_style:
+ * @switcher: an #EShellSwitcher
+ *
+ * Returns whether @switcher has text, icons or both.
+ *
+ * Returns: the current style of @shell
+ **/
+GtkToolbarStyle
+e_shell_switcher_get_style (EShellSwitcher *switcher)
+{
+ g_return_val_if_fail (
+ E_IS_SHELL_SWITCHER (switcher),
+ E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE);
+
+ return switcher->priv->style;
+}
+
+/**
+ * e_shell_switcher_set_style:
+ * @switcher: an #EShellSwitcher
+ * @style: the new style for @switcher
+ *
+ * Alters the view of @switcher to display either icons only, text only,
+ * or both.
+ **/
+void
+e_shell_switcher_set_style (EShellSwitcher *switcher,
+ GtkToolbarStyle style)
+{
+ g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+ switcher->priv->style_set = TRUE;
+ g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style);
+}
+
+/**
+ * e_shell_switcher_unset_style:
+ * @switcher: an #EShellSwitcher
+ *
+ * Unsets a switcher style set with e_shell_switcher_set_style(), so
+ * that user preferences will be used to determine the switcher style.
+ **/
+void
+e_shell_switcher_unset_style (EShellSwitcher *switcher)
+{
+ GtkSettings *settings;
+ GtkToolbarStyle style;
+
+ g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+ if (!switcher->priv->style_set)
+ return;
+
+ settings = switcher->priv->settings;
+ if (settings != NULL)
+ g_object_get (settings, "gtk-toolbar-style", &style, NULL);
+ else
+ style = E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE;
+
+ if (style == GTK_TOOLBAR_BOTH)
+ style = GTK_TOOLBAR_BOTH_HORIZ;
+
+ if (style != switcher->priv->style)
+ g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style);
+
+ switcher->priv->style_set = FALSE;
+}
+
+/**
+ * e_shell_switcher_get_visible:
+ * @switcher: an #EShellSwitcher
+ *
+ * Returns %TRUE if the switcher buttons are visible.
+ *
+ * Note that switcher button visibility is different than
+ * @switcher<!-- -->'s GTK_VISIBLE flag, since #EShellSwitcher
+ * is actually a container widget for #EShellSidebar.
+ *
+ * Returns: %TRUE if the switcher buttons are visible
+ **/
+gboolean
+e_shell_switcher_get_visible (EShellSwitcher *switcher)
+{
+ g_return_val_if_fail (E_IS_SHELL_SWITCHER (switcher), FALSE);
+
+ return switcher->priv->toolbar_visible;
+}
+
+/**
+ * e_shell_switcher_set_visible:
+ * @switcher: an #EShellSwitcher
+ * @visible: whether the switcher buttons should be visible
+ *
+ * Sets the switcher button visiblity to @visible.
+ *
+ * Note that switcher button visibility is different than
+ * @switcher<!-- -->'s GTK_VISIBLE flag, since #EShellSwitcher
+ * is actually a container widget for #EShellSidebar.
+ **/
+void
+e_shell_switcher_set_visible (EShellSwitcher *switcher,
+ gboolean visible)
+{
+ GList *iter;
+
+ g_return_if_fail (E_IS_SHELL_SWITCHER (switcher));
+
+ switcher->priv->toolbar_visible = visible;
+
+ for (iter = switcher->priv->proxies; iter != NULL; iter = iter->next)
+ g_object_set (iter->data, "visible", visible, NULL);
+
+ gtk_widget_queue_resize (GTK_WIDGET (switcher));
+
+ g_object_notify (G_OBJECT (switcher), "toolbar-visible");
+}
diff --git a/shell/e-shell-switcher.h b/shell/e-shell-switcher.h
new file mode 100644
index 0000000000..1cc644595b
--- /dev/null
+++ b/shell/e-shell-switcher.h
@@ -0,0 +1,92 @@
+/*
+ * e-shell-switcher.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-switcher
+ * @short_description: buttons for switching views
+ * @include: shell/e-shell-switcher.h
+ **/
+
+#ifndef E_SHELL_SWITCHER_H
+#define E_SHELL_SWITCHER_H
+
+#include <e-shell-common.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_SWITCHER \
+ (e_shell_switcher_get_type ())
+#define E_SHELL_SWITCHER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcher))
+#define E_SHELL_SWITCHER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_SWITCHER, EShellSwitcherClass))
+#define E_IS_SHELL_SWITCHER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_SWITCHER))
+#define E_IS_SHELL_SWITCHER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_SHELL_SWITCHER))
+#define E_SHELL_SWITCHER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcherClass))
+
+#define E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH_HORIZ
+
+G_BEGIN_DECLS
+
+typedef struct _EShellSwitcher EShellSwitcher;
+typedef struct _EShellSwitcherClass EShellSwitcherClass;
+typedef struct _EShellSwitcherPrivate EShellSwitcherPrivate;
+
+/**
+ * EShellSwitcher:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellSwitcher {
+ GtkBin parent;
+ EShellSwitcherPrivate *priv;
+};
+
+struct _EShellSwitcherClass {
+ GtkBinClass parent_class;
+
+ void (*style_changed) (EShellSwitcher *switcher,
+ GtkToolbarStyle style);
+};
+
+GType e_shell_switcher_get_type (void);
+GtkWidget * e_shell_switcher_new (void);
+void e_shell_switcher_add_action (EShellSwitcher *switcher,
+ GtkAction *action);
+GtkToolbarStyle e_shell_switcher_get_style (EShellSwitcher *switcher);
+void e_shell_switcher_set_style (EShellSwitcher *switcher,
+ GtkToolbarStyle style);
+void e_shell_switcher_unset_style (EShellSwitcher *switcher);
+gboolean e_shell_switcher_get_visible (EShellSwitcher *switcher);
+void e_shell_switcher_set_visible (EShellSwitcher *switcher,
+ gboolean visible);
+
+G_END_DECLS
+
+#endif /* E_SHELL_SWITCHER_H */
diff --git a/shell/e-shell-taskbar.c b/shell/e-shell-taskbar.c
new file mode 100644
index 0000000000..61f27fbc79
--- /dev/null
+++ b/shell/e-shell-taskbar.c
@@ -0,0 +1,421 @@
+/*
+ * e-shell-taskbar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-taskbar.h"
+
+#include <e-shell-view.h>
+
+#include <widgets/misc/e-activity-proxy.h>
+
+#define E_SHELL_TASKBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_TASKBAR, EShellTaskbarPrivate))
+
+struct _EShellTaskbarPrivate {
+
+ gpointer shell_view; /* weak pointer */
+
+ GtkWidget *label;
+ GtkWidget *hbox;
+
+ GHashTable *proxy_table;
+};
+
+enum {
+ PROP_0,
+ PROP_MESSAGE,
+ PROP_SHELL_VIEW
+};
+
+static gpointer parent_class;
+
+static void
+shell_taskbar_activity_remove (EShellTaskbar *shell_taskbar,
+ EActivity *activity)
+{
+ GtkBox *box;
+ GtkWidget *proxy;
+ GHashTable *proxy_table;
+
+ box = GTK_BOX (shell_taskbar->priv->hbox);
+ proxy_table = shell_taskbar->priv->proxy_table;
+ proxy = g_hash_table_lookup (proxy_table, activity);
+ g_return_if_fail (proxy != NULL);
+
+ g_hash_table_remove (proxy_table, activity);
+ gtk_container_remove (GTK_CONTAINER (box), proxy);
+
+ if (box->children == NULL)
+ gtk_widget_hide (GTK_WIDGET (box));
+}
+
+static void
+shell_taskbar_activity_add (EShellTaskbar *shell_taskbar,
+ EActivity *activity)
+{
+ GtkBox *box;
+ GtkWidget *proxy;
+
+ proxy = e_activity_proxy_new (activity);
+ box = GTK_BOX (shell_taskbar->priv->hbox);
+ gtk_box_pack_start (box, proxy, TRUE, TRUE, 0);
+ gtk_box_reorder_child (box, proxy, 0);
+ gtk_widget_show (GTK_WIDGET (box));
+ gtk_widget_show (proxy);
+
+ g_hash_table_insert (
+ shell_taskbar->priv->proxy_table,
+ g_object_ref (activity), g_object_ref (proxy));
+
+ g_signal_connect_swapped (
+ activity, "cancelled",
+ G_CALLBACK (shell_taskbar_activity_remove), shell_taskbar);
+
+ g_signal_connect_swapped (
+ activity, "completed",
+ G_CALLBACK (shell_taskbar_activity_remove), shell_taskbar);
+}
+
+static void
+shell_taskbar_set_shell_view (EShellTaskbar *shell_taskbar,
+ EShellView *shell_view)
+{
+ g_return_if_fail (shell_taskbar->priv->shell_view == NULL);
+
+ shell_taskbar->priv->shell_view = shell_view;
+
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &shell_taskbar->priv->shell_view);
+}
+
+static void
+shell_taskbar_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MESSAGE:
+ e_shell_taskbar_set_message (
+ E_SHELL_TASKBAR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SHELL_VIEW:
+ shell_taskbar_set_shell_view (
+ E_SHELL_TASKBAR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_taskbar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MESSAGE:
+ g_value_set_string (
+ value, e_shell_taskbar_get_message (
+ E_SHELL_TASKBAR (object)));
+ return;
+
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value, e_shell_taskbar_get_shell_view (
+ E_SHELL_TASKBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_taskbar_dispose (GObject *object)
+{
+ EShellTaskbarPrivate *priv;
+
+ priv = E_SHELL_TASKBAR_GET_PRIVATE (object);
+
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view), &priv->shell_view);
+ priv->shell_view = NULL;
+ }
+
+ if (priv->label != NULL) {
+ g_object_unref (priv->label);
+ priv->label = NULL;
+ }
+
+ if (priv->hbox != NULL) {
+ g_object_unref (priv->hbox);
+ priv->hbox = NULL;
+ }
+
+ g_hash_table_remove_all (priv->proxy_table);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_taskbar_finalize (GObject *object)
+{
+ EShellTaskbarPrivate *priv;
+
+ priv = E_SHELL_TASKBAR_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->proxy_table);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_taskbar_constructed (GObject *object)
+{
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellTaskbar *shell_taskbar;
+
+ shell_taskbar = E_SHELL_TASKBAR (object);
+ shell_view = e_shell_taskbar_get_shell_view (shell_taskbar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ g_signal_connect_swapped (
+ shell_backend, "activity-added",
+ G_CALLBACK (shell_taskbar_activity_add), shell_taskbar);
+}
+
+static void
+shell_taskbar_class_init (EShellTaskbarClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellTaskbarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_taskbar_set_property;
+ object_class->get_property = shell_taskbar_get_property;
+ object_class->dispose = shell_taskbar_dispose;
+ object_class->finalize = shell_taskbar_finalize;
+ object_class->constructed = shell_taskbar_constructed;
+
+ /**
+ * EShellTaskbar:message
+ *
+ * The message to display in the taskbar.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_MESSAGE,
+ g_param_spec_string (
+ "message",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShellTaskbar:shell-view
+ *
+ * The #EShellView to which the taskbar widget belongs.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ NULL,
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+shell_taskbar_init (EShellTaskbar *shell_taskbar)
+{
+ GtkWidget *widget;
+ GHashTable *proxy_table;
+ gint height;
+
+ proxy_table = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) g_object_unref);
+
+ shell_taskbar->priv = E_SHELL_TASKBAR_GET_PRIVATE (shell_taskbar);
+ shell_taskbar->priv->proxy_table = proxy_table;
+
+ gtk_box_set_spacing (GTK_BOX (shell_taskbar), 12);
+
+ widget = gtk_label_new (NULL);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_box_pack_start (GTK_BOX (shell_taskbar), widget, TRUE, TRUE, 0);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ shell_taskbar->priv->label = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (shell_taskbar), widget, TRUE, TRUE, 0);
+ shell_taskbar->priv->hbox = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ /* Make the taskbar large enough to accomodate a small icon.
+ * XXX The "* 2" is a fudge factor to allow for some padding
+ * The true value is probably buried in a style property. */
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
+ gtk_widget_set_size_request (
+ GTK_WIDGET (shell_taskbar), -1, (height * 2));
+}
+
+GType
+e_shell_taskbar_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EShellTaskbarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_taskbar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellTaskbar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_taskbar_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HBOX, "EShellTaskbar", &type_info, 0);
+ }
+
+ return type;
+}
+
+/**
+ * e_shell_taskbar_new:
+ * @shell_view: an #EShellView
+ *
+ * Creates a new #EShellTaskbar instance belonging to @shell_view.
+ *
+ * Returns: a new #EShellTaskbar instance
+ **/
+GtkWidget *
+e_shell_taskbar_new (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return g_object_new (
+ E_TYPE_SHELL_TASKBAR, "shell-view", shell_view, NULL);
+}
+
+/**
+ * e_shell_taskbar_get_shell_view:
+ * @shell_taskbar: an #EShellTaskbar
+ *
+ * Returns the #EShellView that was passed to e_shell_taskbar_new().
+ *
+ * Returns: the #EShellView to which @shell_taskbar belongs
+ **/
+EShellView *
+e_shell_taskbar_get_shell_view (EShellTaskbar *shell_taskbar)
+{
+ g_return_val_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar), NULL);
+
+ return shell_taskbar->priv->shell_view;
+}
+
+/**
+ * e_shell_taskbar_get_message:
+ * @shell_taskbar: an #EShellTaskbar
+ *
+ * Returns the message currently shown in the taskbar, or an empty string
+ * if no message is shown. Taskbar messages are used primarily for menu
+ * tooltips.
+ *
+ * Returns: the current taskbar message
+ **/
+const gchar *
+e_shell_taskbar_get_message (EShellTaskbar *shell_taskbar)
+{
+ GtkWidget *label;
+
+ g_return_val_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar), NULL);
+
+ label = shell_taskbar->priv->label;
+
+ return gtk_label_get_text (GTK_LABEL (label));
+}
+
+/**
+ * e_shell_taskbar_set_message:
+ * @shell_taskbar: an #EShellTaskbar
+ * @message: the message to show
+ *
+ * Shows a message in the taskbar. If @message is %NULL or an empty string,
+ * the taskbar message is cleared. Taskbar messages are used primarily for
+ * menu tooltips.
+ **/
+void
+e_shell_taskbar_set_message (EShellTaskbar *shell_taskbar,
+ const gchar *message)
+{
+ GtkWidget *label;
+
+ g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar));
+
+ label = shell_taskbar->priv->label;
+ gtk_label_set_text (GTK_LABEL (label), message);
+
+ if (message != NULL && *message != '\0')
+ gtk_widget_show (label);
+ else
+ gtk_widget_hide (label);
+
+ g_object_notify (G_OBJECT (shell_taskbar), "message");
+}
+
+/**
+ * e_shell_taskbar_unset_message:
+ * @shell_taskbar: an #EShellTaskbar
+ *
+ * This is equivalent to passing a %NULL message to
+ * e_shell_taskbar_set_message().
+ **/
+void
+e_shell_taskbar_unset_message (EShellTaskbar *shell_taskbar)
+{
+ g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar));
+
+ e_shell_taskbar_set_message (shell_taskbar, NULL);
+}
diff --git a/shell/e-shell-taskbar.h b/shell/e-shell-taskbar.h
new file mode 100644
index 0000000000..3c3d40010e
--- /dev/null
+++ b/shell/e-shell-taskbar.h
@@ -0,0 +1,87 @@
+/*
+ * e-shell-taskbar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/**
+ * SECTION: e-shell-taskbar
+ * @short_description: the bottom of the main window
+ * @include: shell/e-shell-taskbar.h
+ **/
+
+#ifndef E_SHELL_TASKBAR_H
+#define E_SHELL_TASKBAR_H
+
+#include <shell/e-shell-common.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_TASKBAR \
+ (e_shell_taskbar_get_type ())
+#define E_SHELL_TASKBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_TASKBAR, EShellTaskbar))
+#define E_SHELL_TASKBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_TASKBAR, EShellTaskbarClass))
+#define E_IS_SHELL_TASKBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_TASKBAR))
+#define E_IS_SHELL_TASKBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL_TASKBAR))
+#define E_SHELL_TASKBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_TASKBAR, EShellTaskbarClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell-view.h>, because it includes us! */
+struct _EShellView;
+
+typedef struct _EShellTaskbar EShellTaskbar;
+typedef struct _EShellTaskbarClass EShellTaskbarClass;
+typedef struct _EShellTaskbarPrivate EShellTaskbarPrivate;
+
+/**
+ * EShellTaskbar:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EShellTaskbar {
+ GtkHBox parent;
+ EShellTaskbarPrivate *priv;
+};
+
+struct _EShellTaskbarClass {
+ GtkHBoxClass parent_class;
+};
+
+GType e_shell_taskbar_get_type (void);
+GtkWidget * e_shell_taskbar_new (struct _EShellView *shell_view);
+struct _EShellView *
+ e_shell_taskbar_get_shell_view (EShellTaskbar *shell_taskbar);
+const gchar * e_shell_taskbar_get_message (EShellTaskbar *shell_taskbar);
+void e_shell_taskbar_set_message (EShellTaskbar *shell_taskbar,
+ const gchar *message);
+void e_shell_taskbar_unset_message (EShellTaskbar *shell_taskbar);
+
+G_END_DECLS
+
+#endif /* E_SHELL_TASKBAR_H */
diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c
index 319a0d3c76..5808f9e027 100644
--- a/shell/e-shell-view.c
+++ b/shell/e-shell-view.c
@@ -1,5 +1,5 @@
/*
- * Helper class for evolution shells to setup a view
+ * e-shell-view.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,126 +15,1177 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "e-shell-view.h"
-#include <gtk/gtk.h>
+#include <string.h>
#include <glib/gi18n.h>
-#include "e-shell-view.h"
-#include "e-shell-window.h"
+#include "e-util/e-util.h"
+#include "e-util/e-plugin-ui.h"
+
+#include "e-shell-window-actions.h"
+
+#define E_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_VIEW, EShellViewPrivate))
-static BonoboObjectClass *parent_class = NULL;
+#define STATE_SAVE_TIMEOUT_SECONDS 3
struct _EShellViewPrivate {
- gint dummy;
+
+ gpointer shell_window; /* weak pointer */
+
+ GKeyFile *state_key_file;
+ guint state_save_source_id;
+
+ gchar *title;
+ gchar *view_id;
+ gint page_num;
+ guint merge_id;
+
+ GtkAction *action;
+ GtkSizeGroup *size_group;
+ GtkWidget *shell_content;
+ GtkWidget *shell_sidebar;
+ GtkWidget *shell_taskbar;
};
+enum {
+ PROP_0,
+ PROP_ACTION,
+ PROP_PAGE_NUM,
+ PROP_TITLE,
+ PROP_SHELL_BACKEND,
+ PROP_SHELL_CONTENT,
+ PROP_SHELL_SIDEBAR,
+ PROP_SHELL_TASKBAR,
+ PROP_SHELL_WINDOW,
+ PROP_VIEW_ID
+};
+
+enum {
+ TOGGLED,
+ UPDATE_ACTIONS,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static gulong signals[LAST_SIGNAL];
+
+static void
+shell_view_init_view_collection (EShellViewClass *class)
+{
+ EShellBackend *shell_backend;
+ const gchar *base_dir;
+ const gchar *backend_name;
+ gchar *system_dir;
+ gchar *local_dir;
+
+ shell_backend = class->shell_backend;
+ g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+ backend_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ base_dir = EVOLUTION_GALVIEWSDIR;
+ system_dir = g_build_filename (base_dir, backend_name, NULL);
+
+ base_dir = e_shell_backend_get_data_dir (shell_backend);
+ local_dir = g_build_filename (base_dir, "views", NULL);
+
+ /* The view collection is never destroyed. */
+ class->view_collection = gal_view_collection_new ();
+
+ gal_view_collection_set_title (
+ class->view_collection, class->label);
+
+ gal_view_collection_set_storage_directories (
+ class->view_collection, system_dir, local_dir);
+
+ g_free (system_dir);
+ g_free (local_dir);
+
+ /* This is all we can do. It's up to the subclasses to
+ * add the appropriate factories to the view collection. */
+}
+
static void
-impl_ShellView_setTitle(PortableServer_Servant _servant, const CORBA_char *id, const CORBA_char * title, CORBA_Environment * ev)
+shell_view_update_view_id (EShellView *shell_view,
+ GalViewInstance *view_instance)
{
- EShellView *esw = (EShellView *)bonobo_object_from_servant(_servant);
- /* To translators: This is the window title and %s is the
- component name. Most translators will want to keep it as is. */
- gchar *tmp = g_strdup_printf(_("%s - Evolution"), title);
+ gchar *view_id;
- e_shell_window_set_title(esw->window, id, tmp);
- g_free(tmp);
+ view_id = gal_view_instance_get_current_view_id (view_instance);
+ e_shell_view_set_view_id (shell_view, view_id);
+ g_free (view_id);
}
static void
-impl_ShellView_setComponent(PortableServer_Servant _servant, const CORBA_char *id, CORBA_Environment * ev)
+shell_view_load_state (EShellView *shell_view)
{
- EShellView *esw = (EShellView *)bonobo_object_from_servant(_servant);
+ EShellBackend *shell_backend;
+ GKeyFile *key_file;
+ const gchar *config_dir;
+ gchar *filename;
+ GError *error = NULL;
- e_shell_window_switch_to_component(esw->window, id);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ config_dir = e_shell_backend_get_config_dir (shell_backend);
+ filename = g_build_filename (config_dir, "state", NULL);
+
+ /* XXX Should do this asynchronously. */
+ key_file = shell_view->priv->state_key_file;
+ g_key_file_load_from_file (key_file, filename, 0, &error);
+
+ if (error == NULL)
+ goto exit;
+
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+ g_warning ("%s", error->message);
+
+ g_error_free (error);
+
+exit:
+ g_free (filename);
}
-struct change_icon_struct {
- const gchar *component_name;
- const gchar *icon_name;
-};
+static void
+shell_view_save_state (EShellView *shell_view)
+{
+ EShellBackend *shell_backend;
+ GKeyFile *key_file;
+ const gchar *config_dir;
+ gchar *contents;
+ gchar *filename;
+ GError *error = NULL;
+
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ config_dir = e_shell_backend_get_config_dir (shell_backend);
+ filename = g_build_filename (config_dir, "state", NULL);
+
+ /* XXX Should do this asynchronously. */
+ key_file = shell_view->priv->state_key_file;
+ contents = g_key_file_to_data (key_file, NULL, NULL);
+ g_file_set_contents (filename, contents, -1, &error);
+ g_free (contents);
+
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (filename);
+}
static gboolean
-change_button_icon_func (EShell *shell, EShellWindow *window, gpointer user_data)
+shell_view_state_timeout_cb (EShellView *shell_view)
{
- struct change_icon_struct *cis = (struct change_icon_struct*)user_data;
+ shell_view_save_state (shell_view);
+ shell_view->priv->state_save_source_id = 0;
- g_return_val_if_fail (window != NULL, FALSE);
- g_return_val_if_fail (cis != NULL, FALSE);
+ return FALSE;
+}
+
+static gboolean
+shell_view_register_ui_manager (EShellView *shell_view)
+{
+ EShellViewClass *shell_view_class;
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+ const gchar *id;
- e_shell_window_change_component_button_icon (window, cis->component_name, cis->icon_name);
+ /* This is a one-time, post-construction idle callback. */
- return TRUE;
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ id = shell_view_class->ui_manager_id;
+
+ e_plugin_ui_register_manager (ui_manager, id, shell_view);
+
+ if (e_shell_view_is_active (shell_view)) {
+ e_plugin_ui_enable_manager (ui_manager, id);
+ e_shell_view_update_actions (shell_view);
+ }
+
+ return FALSE;
+}
+
+static void
+shell_view_emit_toggled (EShellView *shell_view)
+{
+ g_signal_emit (shell_view, signals[TOGGLED], 0);
}
static void
-impl_ShellView_setButtonIcon (PortableServer_Servant _servant, const CORBA_char *id, const CORBA_char * iconName, CORBA_Environment * ev)
+shell_view_set_action (EShellView *shell_view,
+ GtkAction *action)
{
- EShellView *esw = (EShellView *)bonobo_object_from_servant(_servant);
- EShell *shell = e_shell_window_peek_shell (esw->window);
+ gchar *label;
+
+ g_return_if_fail (shell_view->priv->action == NULL);
- struct change_icon_struct cis;
- cis.component_name = id;
- cis.icon_name = iconName;
+ shell_view->priv->action = g_object_ref (action);
- e_shell_foreach_shell_window (shell, change_button_icon_func, &cis);
+ g_object_get (action, "label", &label, NULL);
+ e_shell_view_set_title (shell_view, label);
+ g_free (label);
+
+ g_signal_connect_swapped (
+ action, "toggled",
+ G_CALLBACK (shell_view_emit_toggled), shell_view);
}
static void
-impl_dispose (GObject *object)
+shell_view_set_shell_window (EShellView *shell_view,
+ GtkWidget *shell_window)
{
- /*EShellView *esv = (EShellView *)object;*/
+ g_return_if_fail (shell_view->priv->shell_window == NULL);
+
+ shell_view->priv->shell_window = shell_window;
- ((GObjectClass *)parent_class)->dispose(object);
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_window),
+ &shell_view->priv->shell_window);
}
static void
-impl_finalise (GObject *object)
+shell_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- ((GObjectClass *)parent_class)->finalize(object);
+ switch (property_id) {
+ case PROP_ACTION:
+ shell_view_set_action (
+ E_SHELL_VIEW (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_PAGE_NUM:
+ e_shell_view_set_page_num (
+ E_SHELL_VIEW (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_TITLE:
+ e_shell_view_set_title (
+ E_SHELL_VIEW (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SHELL_WINDOW:
+ shell_view_set_shell_window (
+ E_SHELL_VIEW (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_VIEW_ID:
+ e_shell_view_set_view_id (
+ E_SHELL_VIEW (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_shell_view_class_init (EShellViewClass *klass)
+shell_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTION:
+ g_value_set_object (
+ value, e_shell_view_get_action (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_PAGE_NUM:
+ g_value_set_int (
+ value, e_shell_view_get_page_num (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_TITLE:
+ g_value_set_string (
+ value, e_shell_view_get_title (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_SHELL_BACKEND:
+ g_value_set_object (
+ value, e_shell_view_get_shell_backend (
+ E_SHELL_VIEW (object)));
+
+ case PROP_SHELL_CONTENT:
+ g_value_set_object (
+ value, e_shell_view_get_shell_content (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_SHELL_SIDEBAR:
+ g_value_set_object (
+ value, e_shell_view_get_shell_sidebar (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_SHELL_TASKBAR:
+ g_value_set_object (
+ value, e_shell_view_get_shell_taskbar (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_SHELL_WINDOW:
+ g_value_set_object (
+ value, e_shell_view_get_shell_window (
+ E_SHELL_VIEW (object)));
+ return;
+
+ case PROP_VIEW_ID:
+ g_value_set_string (
+ value, e_shell_view_get_view_id (
+ E_SHELL_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+shell_view_dispose (GObject *object)
+{
+ EShellViewPrivate *priv;
+
+ priv = E_SHELL_VIEW_GET_PRIVATE (object);
+
+ /* Expedite any pending state saves. */
+ if (priv->state_save_source_id > 0) {
+ g_source_remove (priv->state_save_source_id);
+ priv->state_save_source_id = 0;
+ shell_view_save_state (E_SHELL_VIEW (object));
+ }
+
+ if (priv->shell_window != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_window), &priv->shell_window);
+ priv->shell_window = NULL;
+ }
+
+ if (priv->size_group != NULL) {
+ g_object_unref (priv->size_group);
+ priv->size_group = NULL;
+ }
+
+ if (priv->shell_content != NULL) {
+ g_object_unref (priv->shell_content);
+ priv->shell_content = NULL;
+ }
+
+ if (priv->shell_sidebar != NULL) {
+ g_object_unref (priv->shell_sidebar);
+ priv->shell_sidebar = NULL;
+ }
+
+ if (priv->shell_taskbar != NULL) {
+ g_object_unref (priv->shell_taskbar);
+ priv->shell_taskbar = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+shell_view_finalize (GObject *object)
+{
+ EShellViewPrivate *priv;
+
+ priv = E_SHELL_VIEW_GET_PRIVATE (object);
+
+ g_key_file_free (priv->state_key_file);
+
+ g_free (priv->title);
+ g_free (priv->view_id);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+shell_view_constructed (GObject *object)
+{
+ EShellViewClass *shell_view_class;
+ EShellView *shell_view;
+ GtkWidget *widget;
+
+ shell_view = E_SHELL_VIEW (object);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+
+ /* Defer EPluginUI registration to an idle callback to give the
+ * shell view subclass a chance to register its own actions and
+ * action groups. Registration will immediately load EPlugins
+ * that specify the shell view's GtkUIManager ID, and their
+ * initialization routines may require those actions or action
+ * groups that have not yet been added. */
+ g_idle_add ((GSourceFunc) shell_view_register_ui_manager, shell_view);
+
+ shell_view_load_state (shell_view);
+
+ /* Invoke factory methods. */
+
+ widget = shell_view_class->new_shell_content (shell_view);
+ shell_view->priv->shell_content = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+
+ widget = shell_view_class->new_shell_sidebar (shell_view);
+ shell_view->priv->shell_sidebar = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+
+ widget = shell_view_class->new_shell_taskbar (shell_view);
+ shell_view->priv->shell_taskbar = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+}
+
+static void
+shell_view_toggled (EShellView *shell_view)
+{
+ EShellViewPrivate *priv = shell_view->priv;
+ EShellViewClass *shell_view_class;
+ EShellWindow *shell_window;
+ GtkUIManager *ui_manager;
+ const gchar *basename, *id;
+ gboolean view_is_active;
+
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ view_is_active = e_shell_view_is_active (shell_view);
+ basename = shell_view_class->ui_definition;
+ id = shell_view_class->ui_manager_id;
+
+ if (view_is_active && priv->merge_id == 0) {
+ priv->merge_id = e_load_ui_definition (ui_manager, basename);
+ e_plugin_ui_enable_manager (ui_manager, id);
+
+ } else if (!view_is_active && priv->merge_id != 0) {
+ e_plugin_ui_disable_manager (ui_manager, id);
+ gtk_ui_manager_remove_ui (ui_manager, priv->merge_id);
+ priv->merge_id = 0;
+ }
+
+ gtk_ui_manager_ensure_update (ui_manager);
+}
+
+static void
+shell_view_class_init (EShellViewClass *class)
{
GObjectClass *object_class;
- POA_GNOME_Evolution_ShellView__epv *epv;
- parent_class = g_type_class_ref(bonobo_object_get_type());
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_view_set_property;
+ object_class->get_property = shell_view_get_property;
+ object_class->dispose = shell_view_dispose;
+ object_class->finalize = shell_view_finalize;
+ object_class->constructed = shell_view_constructed;
+
+ /* Default Factories */
+ class->new_shell_content = e_shell_content_new;
+ class->new_shell_sidebar = e_shell_sidebar_new;
+ class->new_shell_taskbar = e_shell_taskbar_new;
+
+ class->toggled = shell_view_toggled;
+
+ /**
+ * EShellView:action:
+ *
+ * The #GtkRadioAction registered with #EShellSwitcher.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTION,
+ g_param_spec_object (
+ "action",
+ _("Switcher Action"),
+ _("The switcher action for this shell view"),
+ GTK_TYPE_RADIO_ACTION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * EShellView:page-num
+ *
+ * The #GtkNotebook page number of the shell view.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_PAGE_NUM,
+ g_param_spec_int (
+ "page-num",
+ _("Page Number"),
+ _("The notebook page number of the shell view"),
+ -1,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellView:title
+ *
+ * The title of the shell view. Also serves as the #EShellWindow
+ * title when the shell view is active.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_TITLE,
+ g_param_spec_string (
+ "title",
+ _("Title"),
+ _("The title of the shell view"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellView::shell-backend
+ *
+ * The #EShellBackend for this shell view.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_BACKEND,
+ g_param_spec_object (
+ "shell-backend",
+ _("Shell Backend"),
+ _("The EShellBackend for this shell view"),
+ E_TYPE_SHELL_BACKEND,
+ G_PARAM_READABLE));
+
+ /**
+ * EShellView:shell-content
+ *
+ * The content widget appears in an #EShellWindow<!-- -->'s
+ * right pane.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_CONTENT,
+ g_param_spec_object (
+ "shell-content",
+ _("Shell Content Widget"),
+ _("The content widget appears in "
+ "a shell window's right pane"),
+ E_TYPE_SHELL_CONTENT,
+ G_PARAM_READABLE));
+
+ /**
+ * EShellView:shell-sidebar
+ *
+ * The sidebar widget appears in an #EShellWindow<!-- -->'s
+ * left pane.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_SIDEBAR,
+ g_param_spec_object (
+ "shell-sidebar",
+ _("Shell Sidebar Widget"),
+ _("The sidebar widget appears in "
+ "a shell window's left pane"),
+ E_TYPE_SHELL_SIDEBAR,
+ G_PARAM_READABLE));
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalise;
+ /**
+ * EShellView:shell-taskbar
+ *
+ * The taskbar widget appears at the bottom of an #EShellWindow.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_TASKBAR,
+ g_param_spec_object (
+ "shell-taskbar",
+ _("Shell Taskbar Widget"),
+ _("The taskbar widget appears at "
+ "the bottom of a shell window"),
+ E_TYPE_SHELL_TASKBAR,
+ G_PARAM_READABLE));
- epv = & klass->epv;
- epv->setTitle = impl_ShellView_setTitle;
- epv->setComponent = impl_ShellView_setComponent;
- epv->setButtonIcon = impl_ShellView_setButtonIcon;
+ /**
+ * EShellView:shell-window
+ *
+ * The #EShellWindow to which the shell view belongs.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_WINDOW,
+ g_param_spec_object (
+ "shell-window",
+ _("Shell Window"),
+ _("The window to which the shell view belongs"),
+ E_TYPE_SHELL_WINDOW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * EShellView:view-id
+ *
+ * The current #GalView ID.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_VIEW_ID,
+ g_param_spec_string (
+ "view-id",
+ _("Current View ID"),
+ _("The current GAL view ID"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellView::toggled
+ * @shell_view: the #EShellView which emitted the signal
+ *
+ * Emitted when @shell_view is activated or deactivated.
+ * Use e_shell_view_is_active() to find out which event has
+ * occurred. The shell view being deactivated is always
+ * notified before the shell view being activated.
+ *
+ * By default, #EShellView adds the UI definition file
+ * given in the <structfield>ui_definition</structfield>
+ * field of #EShellViewClass on activation, and removes the
+ * UI definition on deactivation.
+ **/
+ signals[TOGGLED] = g_signal_new (
+ "toggled",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EShellViewClass, toggled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * EShellView::update-actions
+ * @shell_view: the #EShellView which emitted the signal
+ *
+ * #EShellView subclasses should override the
+ * <structfield>update_actions</structfield> method in
+ * #EShellViewClass to update sensitivities, labels, or any
+ * other aspect of the #GtkAction<!-- -->s they have registered.
+ *
+ * Plugins can also connect to this signal to be notified
+ * when to update their own #GtkAction<!-- -->s.
+ **/
+ signals[UPDATE_ACTIONS] = g_signal_new (
+ "update-actions",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EShellViewClass, update_actions),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
-e_shell_view_init (EShellView *shell)
+shell_view_init (EShellView *shell_view,
+ EShellViewClass *class)
{
+ GtkSizeGroup *size_group;
+
+ if (class->view_collection == NULL)
+ shell_view_init_view_collection (class);
+
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
+
+ shell_view->priv = E_SHELL_VIEW_GET_PRIVATE (shell_view);
+ shell_view->priv->state_key_file = g_key_file_new ();
+ shell_view->priv->size_group = size_group;
}
-EShellView *e_shell_view_new(struct _EShellWindow *window)
+GType
+e_shell_view_get_type (void)
{
- EShellView *new = g_object_new (e_shell_view_get_type (), NULL);
+ static GType type = 0;
- /* TODO: listen to destroy? */
- new->window = window;
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_view_init,
+ NULL /* value_table */
+ };
- return new;
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EShellView",
+ &type_info, G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
}
-BONOBO_TYPE_FUNC_FULL (EShellView, GNOME_Evolution_ShellView, bonobo_object_get_type(), e_shell_view)
+/**
+ * e_shell_view_get_name:
+ * @shell_view: an #EShellView
+ *
+ * Returns the view name for @shell_view, which is also the name of
+ * the corresponding #EShellBackend (see the <structfield>name</structfield>
+ * field in #EShellBackendInfo).
+ *
+ * Returns: the view name for @shell_view
+ **/
+const gchar *
+e_shell_view_get_name (EShellView *shell_view)
+{
+ GtkAction *action;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ action = e_shell_view_get_action (shell_view);
+ /* Switcher actions have a secret "view-name" data value.
+ * This gets set in e_shell_window_create_switcher_actions(). */
+ return g_object_get_data (G_OBJECT (action), "view-name");
+}
+
+/**
+ * e_shell_view_get_action:
+ * @shell_view: an #EShellView
+ *
+ * Returns the switcher action for @shell_view.
+ *
+ * An #EShellWindow creates a #GtkRadioAction for each registered subclass
+ * of #EShellView. This action gets passed to the #EShellSwitcher, which
+ * displays a button that proxies the action. The icon at the top of the
+ * sidebar also proxies the action. When @shell_view is active, the
+ * action's icon becomes the #EShellWindow icon.
+ *
+ * Returns: the switcher action for @shell_view
+ **/
+GtkAction *
+e_shell_view_get_action (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->action;
+}
+
+/**
+ * e_shell_view_get_title:
+ * @shell_view: an #EShellView
+ *
+ * Returns the title for @shell_view. When @shell_view is active, the
+ * shell view's title becomes the #EShellWindow title.
+ *
+ * Returns: the title for @shell_view
+ **/
+const gchar *
+e_shell_view_get_title (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->title;
+}
+
+/**
+ * e_shell_view_set_title:
+ * @shell_view: an #EShellView
+ * @title: a title for @shell_view
+ *
+ * Sets the title for @shell_view. When @shell_view is active, the
+ * shell view's title becomes the #EShellWindow title.
+ **/
+void
+e_shell_view_set_title (EShellView *shell_view,
+ const gchar *title)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ if (title == NULL)
+ title = E_SHELL_VIEW_GET_CLASS (shell_view)->label;
+
+ if (g_strcmp0 (shell_view->priv->title, title) == 0)
+ return;
+
+ g_free (shell_view->priv->title);
+ shell_view->priv->title = g_strdup (title);
+
+ g_object_notify (G_OBJECT (shell_view), "title");
+}
+
+/**
+ * e_shell_view_get_view_id:
+ * @shell_view: an #EShellView
+ *
+ * Returns the ID of the currently selected #GalView.
+ *
+ * #EShellView subclasses are responsible for keeping this property in
+ * sync with their #GalViewInstance. #EShellView itself just provides
+ * a place to store the view ID, and emits a #GObject::notify signal
+ * when the property changes.
+ *
+ * Returns: the ID of the current #GalView
+ **/
+const gchar *
+e_shell_view_get_view_id (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->view_id;
+}
+
+/**
+ * e_shell_view_set_view_id:
+ * @shell_view: an #EShellView
+ * @view_id: a #GalView ID
+ *
+ * Selects the #GalView whose ID is equal to @view_id.
+ *
+ * #EShellView subclasses are responsible for keeping this property in
+ * sync with their #GalViewInstance. #EShellView itself just provides
+ * a place to store the view ID, and emits a #GObject::notify signal
+ * when the property changes.
+ **/
+void
+e_shell_view_set_view_id (EShellView *shell_view,
+ const gchar *view_id)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ if (g_strcmp0 (shell_view->priv->view_id, view_id) == 0)
+ return;
+
+ g_free (shell_view->priv->view_id);
+ shell_view->priv->view_id = g_strdup (view_id);
+
+ g_object_notify (G_OBJECT (shell_view), "view-id");
+}
+
+/**
+ * e_shell_view_get_shell_window:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #EShellWindow to which @shell_view belongs.
+ *
+ * Returns: the #EShellWindow to which @shell_view belongs
+ **/
+EShellWindow *
+e_shell_view_get_shell_window (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return E_SHELL_WINDOW (shell_view->priv->shell_window);
+}
+
+/**
+ * e_shell_view_is_active:
+ * @shell_view: an #EShellView
+ *
+ * Returns %TRUE if @shell_view is active. That is, if it's currently
+ * visible in its #EShellWindow. An #EShellWindow can only display one
+ * shell view at a time.
+ *
+ * Technically this just checks the #GtkToggleAction:active property of
+ * the shell view's switcher action. See e_shell_view_get_action().
+ *
+ * Returns: %TRUE if @shell_view is active
+ **/
+gboolean
+e_shell_view_is_active (EShellView *shell_view)
+{
+ GtkAction *action;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), FALSE);
+
+ action = e_shell_view_get_action (shell_view);
+
+ return gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+}
+
+/**
+ * e_shell_view_get_page_num:
+ * @shell_view: an #EShellView
+ *
+ * This function is only interesting to #EShellWindow. It returns the
+ * #GtkNotebook page number for @shell_view. The rest of the application
+ * should have no need for this.
+ *
+ * Returns: the notebook page number for @shell_view
+ **/
+gint
+e_shell_view_get_page_num (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), -1);
+
+ return shell_view->priv->page_num;
+}
+
+/**
+ * e_shell_view_set_page_num:
+ * @shell_view: an #EShellView
+ * @page_num: a notebook page number
+ *
+ * This function is only interesting to #EShellWindow. It sets the
+ * #GtkNotebook page number for @shell_view. The rest of the application
+ * must never call this because it could mess up shell view switching.
+ **/
+void
+e_shell_view_set_page_num (EShellView *shell_view,
+ gint page_num)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ shell_view->priv->page_num = page_num;
+
+ g_object_notify (G_OBJECT (shell_view), "page-num");
+}
+
+/**
+ * e_shell_view_get_size_group:
+ * @shell_view: an #EShellView
+ *
+ * Returns a #GtkSizeGroup that #EShellContent and #EShellSidebar use
+ * to keep the search bar and sidebar banner vertically aligned. The
+ * rest of the application should have no need for this.
+ *
+ * Returns: a #GtkSizeGroup for internal use
+ **/
+GtkSizeGroup *
+e_shell_view_get_size_group (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->size_group;
+}
+
+/**
+ * e_shell_view_get_shell_backend:
+ * @shell_view: an #EShellView
+ *
+ * Returns the corresponding #EShellBackend for @shell_view.
+ *
+ * Returns: the corresponding #EShellBackend for @shell_view
+ **/
+EShellBackend *
+e_shell_view_get_shell_backend (EShellView *shell_view)
+{
+ EShellViewClass *class;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ g_return_val_if_fail (class->shell_backend != NULL, NULL);
+
+ return class->shell_backend;
+}
+
+/**
+ * e_shell_view_get_shell_content:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #EShellContent instance for @shell_view.
+ *
+ * By default, #EShellView creates a plain #EShellContent during
+ * initialization. But #EShellView subclasses can override the
+ * <structfield>new_shell_content</structfield> factory method
+ * in #EShellViewClass to create a custom #EShellContent.
+ *
+ * Returns: the #EShellContent instance for @shell_view
+ **/
+EShellContent *
+e_shell_view_get_shell_content (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return E_SHELL_CONTENT (shell_view->priv->shell_content);
+}
+
+/**
+ * e_shell_view_get_shell_sidebar:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #EShellSidebar instance for @shell_view.
+ *
+ * By default, #EShellView creates a plain #EShellSidebar during
+ * initialization. But #EShellView subclasses can override the
+ * <structfield>new_shell_sidebar</structfield> factory method
+ * in #EShellViewClass to create a custom #EShellSidebar.
+ *
+ * Returns: the #EShellSidebar instance for @shell_view
+ **/
+EShellSidebar *
+e_shell_view_get_shell_sidebar (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return E_SHELL_SIDEBAR (shell_view->priv->shell_sidebar);
+}
+
+/**
+ * e_shell_view_get_shell_taskbar:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #EShellTaskbar instance for @shell_view.
+ *
+ * By default, #EShellView creates a plain #EShellTaskbar during
+ * initialization. But #EShellView subclasses can override the
+ * <structfield>new_shell_taskbar</structfield> factory method
+ * in #EShellViewClass to create a custom #EShellTaskbar.
+ *
+ * Returns: the #EShellTaskbar instance for @shell_view
+ **/
+EShellTaskbar *
+e_shell_view_get_shell_taskbar (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return E_SHELL_TASKBAR (shell_view->priv->shell_taskbar);
+}
+
+/**
+ * e_shell_view_get_state_key_file:
+ * @shell_view: an #EShellView
+ *
+ * Returns the #GKeyFile holding widget state data for @shell_view.
+ *
+ * Returns: the #GKeyFile for @shell_view
+ **/
+GKeyFile *
+e_shell_view_get_state_key_file (EShellView *shell_view)
+{
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ return shell_view->priv->state_key_file;
+}
+
+/**
+ * e_shell_view_set_state_dirty:
+ * @shell_view: an #EShellView
+ *
+ * Marks the widget state data as modified (or "dirty") and schedules it
+ * to be saved to disk after a short delay. The delay caps the frequency
+ * of saving to disk.
+ **/
+void
+e_shell_view_set_state_dirty (EShellView *shell_view)
+{
+ guint source_id;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ /* If a timeout is already scheduled, do nothing. */
+ if (shell_view->priv->state_save_source_id > 0)
+ return;
+
+ source_id = g_timeout_add_seconds (
+ STATE_SAVE_TIMEOUT_SECONDS, (GSourceFunc)
+ shell_view_state_timeout_cb, shell_view);
+
+ shell_view->priv->state_save_source_id = source_id;
+}
+
+/**
+ * e_shell_view_update_actions:
+ * @shell_view: an #EShellView
+ *
+ * Emits the #EShellView::update-actions signal.
+ *
+ * #EShellView subclasses should implement the
+ * <structfield>update_actions</structfield> method in #EShellViewClass
+ * to update the various #GtkAction<!-- -->s based on the current
+ * #EShellSidebar and #EShellContent selections. The
+ * #EShellView::update-actions signal is typically emitted just before
+ * showing a popup menu or just after the user selects an item in the
+ * shell view.
+ **/
+void
+e_shell_view_update_actions (EShellView *shell_view)
+{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ g_signal_emit (shell_view, signals[UPDATE_ACTIONS], 0);
+}
+
+/**
+ * e_shell_view_show_popup_menu:
+ * @shell_view: an #EShellView
+ * @widget_path: path in the UI definition
+ * @event: a #GdkEventButton
+ *
+ * Displays a context-sensitive (or "popup") menu that is described in
+ * the UI definition loaded into @shell_view<!-- -->'s user interface
+ * manager. The menu will be shown at the current mouse cursor position.
+ *
+ * The #EShellView::update-actions signal is emitted just prior to
+ * showing the menu to give @shell_view and any plugins that extend
+ * @shell_view a chance to update the menu's actions.
+ **/
+void
+e_shell_view_show_popup_menu (EShellView *shell_view,
+ const gchar *widget_path,
+ GdkEventButton *event)
+{
+ EShellWindow *shell_window;
+ GtkWidget *menu;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ e_shell_view_update_actions (shell_view);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ menu = e_shell_window_get_managed_widget (shell_window, widget_path);
+ g_return_if_fail (GTK_IS_MENU (menu));
+
+ if (event != NULL)
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ event->button, event->time);
+ else
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ 0, gtk_get_current_event_time ());
+}
+
+/**
+ * e_shell_view_new_view_instance:
+ * @shell_view: an #EShellView
+ * @instance_id: a name for the #GalViewInstance
+ *
+ * Creates a new #GalViewInstance and configures it to keep
+ * @shell_view<!-- -->'s #EShellView:view-id property up-to-date.
+ *
+ * Returns: a new #GalViewInstance
+ **/
+GalViewInstance *
+e_shell_view_new_view_instance (EShellView *shell_view,
+ const gchar *instance_id)
+{
+ EShellViewClass *class;
+ GalViewCollection *view_collection;
+ GalViewInstance *view_instance;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ class = E_SHELL_VIEW_GET_CLASS (shell_view);
+
+ view_collection = class->view_collection;
+ view_instance = gal_view_instance_new (view_collection, instance_id);
+
+ g_signal_connect_swapped (
+ view_instance, "changed",
+ G_CALLBACK (shell_view_update_view_id), shell_view);
+
+ return view_instance;
+}
diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h
index 1ca2656bb0..b9a12ab893 100644
--- a/shell/e-shell-view.h
+++ b/shell/e-shell-view.h
@@ -1,6 +1,5 @@
/*
- *
- * This is only a CORBA wrapper around e_shell_window.
+ * e-shell-view.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,46 +19,169 @@
*
*/
-#ifndef _E_SHELL_VIEW_H_
-#define _E_SHELL_VIEW_H_
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-object.h>
+/**
+ * SECTION: e-shell-view
+ * @short_description: views within the main window
+ * @include: shell/e-shell-view.h
+ **/
+
+#ifndef E_SHELL_VIEW_H
+#define E_SHELL_VIEW_H
+
+#include <shell/e-shell-common.h>
+#include <shell/e-shell-backend.h>
+#include <shell/e-shell-content.h>
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-taskbar.h>
+#include <shell/e-shell-window.h>
+
+#include <widgets/menus/gal-view-collection.h>
+#include <widgets/menus/gal-view-instance.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_VIEW \
+ (e_shell_view_get_type ())
+#define E_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_VIEW, EShellView))
+#define E_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_VIEW, EShellViewClass))
+#define E_IS_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_VIEW))
+#define E_IS_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL_VIEW))
+#define E_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_VIEW, EShellViewClass))
G_BEGIN_DECLS
-struct _EShell;
-
-typedef struct _EShellView EShellView;
+typedef struct _EShellView EShellView;
+typedef struct _EShellViewClass EShellViewClass;
typedef struct _EShellViewPrivate EShellViewPrivate;
-typedef struct _EShellViewClass EShellViewClass;
-
-#include "Evolution.h"
-
-#define E_TYPE_SHELL_VIEW (e_shell_view_get_type ())
-#define E_SHELL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL_VIEW, EShellView))
-#define E_SHELL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_VIEW, EShellViewClass))
-#define E_IS_SHELL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL_VIEW))
-#define E_IS_SHELL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_VIEW))
+/**
+ * EShellView:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
struct _EShellView {
- BonoboObject parent;
-
- struct _EShellWindow *window;
-
+ GObject parent;
EShellViewPrivate *priv;
};
+/**
+ * EShellViewClass:
+ * @parent_class: The parent class structure.
+ * @label: The initial value for the switcher action's
+ * #GtkAction:label property. See
+ * e_shell_view_get_action().
+ * @icon_name: The initial value for the switcher action's
+ * #GtkAction:icon-name property. See
+ * e_shell_view_get_action().
+ * @ui_definition: Base name of the UI definintion file to add
+ * when the shell view is activated.
+ * @ui_manager_id: The #GtkUIManager ID for #EPluginUI. Plugins
+ * should use to this ID in their "eplug" files to
+ * add menu and toolbar items to the shell view.
+ * @search_options: Widget path in the UI definition to the search
+ * options popup menu. The menu gets shown when the
+ * user clicks the "find" icon in the search entry.
+ * @search_rules: Base name of the XML file containing predefined
+ * search rules for this shell view. The XML files
+ * are usually named something like <filename>
+ * <emphasis>view</emphasis>types.xml</filename>.
+ * @view_collection: A unique #GalViewCollection instance is created
+ * for each subclass and shared across all instances
+ * of that subclass. That much is done automatically
+ * for subclasses, but subclasses are still responsible
+ * for adding the appropriate #GalView factories to the
+ * view collection.
+ * @shell_backend: The corresponding #EShellBackend for the shell view.
+ * @new_shell_content: Factory method for the shell view's #EShellContent.
+ * See e_shell_view_get_shell_content().
+ * @new_shell_sidebar: Factory method for the shell view's #EShellSidebar.
+ * See e_shell_view_get_shell_sidebar().
+ * @new_shell_taskbar: Factory method for the shell view's #EShellTaskbar.
+ * See e_shell_view_get_shell_taskbar().
+ * @toggled: Class method for the #EShellView::toggled signal.
+ * Subclasses should rarely need to override the
+ * default behavior.
+ * @update_actions: Class method for the #EShellView::update_actions
+ * signal. There is no default behavior; subclasses
+ * should override this.
+ *
+ * #EShellViewClass contains a number of important settings for subclasses.
+ **/
struct _EShellViewClass {
- BonoboObjectClass parent_class;
+ GObjectClass parent_class;
- POA_GNOME_Evolution_ShellView__epv epv;
+ /* Initial switcher action values. */
+ const gchar *label;
+ const gchar *icon_name;
+
+ /* Base name of the UI definition file. */
+ const gchar *ui_definition;
+
+ /* GtkUIManager identifier for use with EPluginUI.
+ * Usually "org.gnome.evolution.$(VIEW_NAME)". */
+ const gchar *ui_manager_id;
+
+ /* Widget path to the search options popup menu. */
+ const gchar *search_options;
+
+ /* Base name of the search rule definition file. */
+ const gchar *search_rules;
+
+ /* A unique instance is created for each subclass. */
+ GalViewCollection *view_collection;
+
+ /* This is set by the corresponding EShellBackend. */
+ EShellBackend *shell_backend;
+
+ /* Factory Methods */
+ GtkWidget * (*new_shell_content) (EShellView *shell_view);
+ GtkWidget * (*new_shell_sidebar) (EShellView *shell_view);
+ GtkWidget * (*new_shell_taskbar) (EShellView *shell_view);
+
+ /* Signals */
+ void (*toggled) (EShellView *shell_view);
+ void (*update_actions) (EShellView *shell_view);
};
-GType e_shell_view_get_type (void);
-EShellView *e_shell_view_new(struct _EShellWindow *window);
+GType e_shell_view_get_type (void);
+const gchar * e_shell_view_get_name (EShellView *shell_view);
+GtkAction * e_shell_view_get_action (EShellView *shell_view);
+const gchar * e_shell_view_get_title (EShellView *shell_view);
+void e_shell_view_set_title (EShellView *shell_view,
+ const gchar *title);
+const gchar * e_shell_view_get_view_id (EShellView *shell_view);
+void e_shell_view_set_view_id (EShellView *shell_view,
+ const gchar *view_id);
+gboolean e_shell_view_is_active (EShellView *shell_view);
+gint e_shell_view_get_page_num (EShellView *shell_view);
+void e_shell_view_set_page_num (EShellView *shell_view,
+ gint page_num);
+GtkSizeGroup * e_shell_view_get_size_group (EShellView *shell_view);
+EShellBackend * e_shell_view_get_shell_backend (EShellView *shell_view);
+EShellContent * e_shell_view_get_shell_content (EShellView *shell_view);
+EShellSidebar * e_shell_view_get_shell_sidebar (EShellView *shell_view);
+EShellTaskbar * e_shell_view_get_shell_taskbar (EShellView *shell_view);
+EShellWindow * e_shell_view_get_shell_window (EShellView *shell_view);
+GKeyFile * e_shell_view_get_state_key_file (EShellView *shell_view);
+void e_shell_view_set_state_dirty (EShellView *shell_view);
+void e_shell_view_update_actions (EShellView *shell_view);
+void e_shell_view_show_popup_menu (EShellView *shell_view,
+ const gchar *widget_path,
+ GdkEventButton *event);
+GalViewInstance *
+ e_shell_view_new_view_instance (EShellView *shell_view,
+ const gchar *instance_id);
G_END_DECLS
-#endif /* _E_SHELL_VIEW_H_ */
-
+#endif /* E_SHELL_VIEW_H */
diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c
new file mode 100644
index 0000000000..77e50c50d4
--- /dev/null
+++ b/shell/e-shell-window-actions.c
@@ -0,0 +1,2242 @@
+/*
+ * e-shell-window-actions.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-window-private.h"
+
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-error.h>
+#include <e-util/e-print.h>
+#include <gal-define-views-dialog.h>
+
+#include <libedataserverui/e-passwords.h>
+
+#include "e-shell-importer.h"
+
+#define EVOLUTION_COPYRIGHT \
+ "Copyright \xC2\xA9 1999 - 2008 Novell, Inc. and Others"
+
+#define EVOLUTION_FAQ \
+ "http://www.go-evolution.org/FAQ"
+
+#define EVOLUTION_WEBSITE \
+ "http://www.gnome.org/projects/evolution/"
+
+/* Authors and Documenters
+ *
+ * The names below must be in UTF-8. The breaking of escaped strings
+ * is so the hexadecimal sequences don't swallow too many characters.
+ *
+ * SO THAT MEANS, FOR 8-BIT CHARACTERS USE \xXX HEX ENCODING ONLY!
+ *
+ * Not all environments are UTF-8 and not all editors can handle it.
+ */
+static const gchar *authors[] = {
+ "Aaron Weber",
+ "Abel Cheung",
+ "Abhishek Parwal",
+ "Adam Weinberger",
+ "Adi Attar",
+ "Ahmad Riza H Nst",
+ "Aidan Delaney",
+ "Aishwarya K",
+ "Akagic Amila",
+ "Akhil Laddha",
+ "Akira Tagoh",
+ "Alastair McKinstry",
+ "Alastair Tse",
+ "Alejandro Andres",
+ "Alessandro Decina",
+ "Alex Graveley",
+ "Alex Jiang",
+ "Alex Jones",
+ "Alex Kloss",
+ "Alexander Shopov",
+ "Alfred Peng",
+ "Ali Abdin",
+ "Ali Akcaagac",
+ "Almer S. Tigelaar",
+ "Amish",
+ "Anand V M",
+ "Anders Carlsson",
+ "Andre Klapper",
+ "Andrea Campi",
+ "Andreas Henriksson",
+ "Andreas Hyden",
+ "Andreas J. Guelzow",
+ "Andreas K\xC3\xB6hler",
+ "Andreas Köhler",
+ "Andrew Ruthven",
+ "Andrew T. Veliath",
+ "Andrew Wu",
+ "Ankit Patel",
+ "Anna Marie Dirks",
+ "Antonio Xu",
+ "Arafat Medini",
+ "Arangel Angov",
+ "Archit Baweja",
+ "Ariel Rios",
+ "Arik Devens",
+ "Armin Bauer",
+ "Arturo Espinosa Aldama",
+ "Arulanandan P",
+ "Arun Prakash",
+ "Arvind Sundararajan",
+ "Arvind",
+ "Ashish",
+ "B S Srinidhi",
+ "Bastien Nocera",
+ "Behnam Esfahbod",
+ "Ben Gamari",
+ "Benjamin Berg",
+ "Benjamin Kahn",
+ "Benoît Dejean",
+ "Bernard Leach",
+ "Bertrand Guiheneuf",
+ "Bharath Acharya",
+ "Bill Zhu",
+ "Bj\xC3\xB6rn Torkelsson",
+ "Björn Lindqvist",
+ "Bob Doan",
+ "Bob Mauchin",
+ "Boby Wang",
+ "Bolian Yin",
+ "Brian Mury",
+ "Brian Pepple",
+ "Bruce Tao",
+ "Calvin Liu",
+ "Cantona Su",
+ "Carl Sun",
+ "Carlos Garcia Campos",
+ "Carlos Garnacho Parro",
+ "Carlos Perell\xC3\xB3" " Mar\xC3\xAD" "n",
+ "Carsten Guenther",
+ "Carsten Schaar",
+ "Changwoo Ryu",
+ "Chao-Hsiung Liao",
+ "Charles Zhang",
+ "Chema Celorio",
+ "Chenthill Palanisamy",
+ "Chpe",
+ "Chris Halls",
+ "Chris Heath",
+ "Chris Phelps",
+ "Chris Toshok",
+ "Christian Hammond",
+ "Christian Kellner",
+ "Christian Kirbach",
+ "Christian Krause",
+ "Christian Kreibich",
+ "Christian Neumair",
+ "Christophe Fergeau",
+ "Christophe Merlet",
+ "Christopher Blizzard",
+ "Christopher J. Lahey",
+ "Christopher R. Gabriel",
+ "Claude Paroz",
+ "Claudio Saavedra",
+ "Clifford R. Conover",
+ "Cody Russell",
+ "Colin Leroy",
+ "Craig Small",
+ "Dafydd Harries",
+ "Damian Ivereigh",
+ "Damien Carbery",
+ "Damon Chaplin",
+ "Dan Berger",
+ "Dan Damian",
+ "Dan Nguyen",
+ "Dan Winship",
+ "Daniel Gryniewicz",
+ "Daniel Nylander",
+ "Daniel van Eeden",
+ "Daniel Veillard",
+ "Daniel Yacob",
+ "Danilo \xC5\xA0" "egan",
+ "Danilo Segan",
+ "Darin Adler",
+ "Dave Benson",
+ "Dave Camp",
+ "Dave Fallon",
+ "Dave Malcolm",
+ "Dave West",
+ "David Farning",
+ "David Kaelbling",
+ "David Malcolm",
+ "David Moore",
+ "David Mosberger",
+ "David Richards",
+ "David Trowbridge",
+ "David Turner",
+ "David Woodhouse",
+ "Denis Washington",
+ "Devashish Sharma",
+ "Diego Escalante Urrelo",
+ "Diego Gonzalez",
+ "Diego Sevilla Ruiz",
+ "Dietmar Maurer",
+ "Dinesh Layek",
+ "Djihed Afifi",
+ "Dmitry Mastrukov",
+ "Dodji Seketeli",
+ "Duarte Loreto",
+ "Dulmandakh Sukhbaatar",
+ "Duncan Mak",
+ "Ebby Wiselyn",
+ "Ed Catmur",
+ "Edd Dumbill",
+ "Edgar Luna Díaz",
+ "Edward Rudd",
+ "Elijah Newren",
+ "Elizabeth Greene",
+ "Elliot Lee",
+ "Elliot Turner",
+ "Eneko Lacunza",
+ "Enver Altin",
+ "Erdal Ronahi",
+ "Eric Busboom",
+ "Eric Zhao",
+ "Eskil Heyn Olsen",
+ "Ettore Perazzoli",
+ "Evan Yan",
+ "Fatih Demir",
+ "Fazlu & Hannah",
+ "Federico Mena Quintero",
+ "Fernando Herrera",
+ "Francisco Javier F. Serrador",
+ "Frank Arnold",
+ "Frank Belew",
+ "Frederic Crozat",
+ "Frederic Peters",
+ "Funda Wang",
+ "Gabor Kelemen",
+ "Ganesh",
+ "Gareth Owen",
+ "Gary Coady",
+ "Gary Ekker",
+ "Gavin Scott",
+ "Gediminas Paulauskas",
+ "Gerg\xC5\x91 \xC3\x89rdi",
+ "George Lebl",
+ "Gerardo Marin",
+ "Gert Kulyk",
+ "Giancarlo Capella",
+ "Gil Osher",
+ "Gilbert Fang",
+ "Gilles Dartiguelongue",
+ "Grahame Bowland",
+ "Greg Hudson",
+ "Gregory Leblanc",
+ "Gregory McLean",
+ "Grzegorz Goawski",
+ "Gustavo Gir\xC3\x8E" "ldez",
+ "Gustavo Maciel Dias Vieira",
+ "H P Nadig",
+ "H\xC3\xA9" "ctor Garc\xC3\xAD" "a \xC3\x81" "lvarez",
+ "Hans Petter Jansson",
+ "Hao Sheng",
+ "Hari Prasad Nadig",
+ "Harish K",
+ "Harish Krishnaswamy",
+ "Harry Lu",
+ "Hasbullah Bin Pit",
+ "Havoc Pennington",
+ "Heath Harrelson",
+ "Hein-Pieter van Braam",
+ "Herbert V. Riedel",
+ "Hiroyuki Ikezoe",
+ "Iain Buchanan",
+ "Iain Holmes",
+ "Ian Campbell",
+ "Ilkka Tuohela",
+ "Irene Huang",
+ "Ismael Olea",
+ "Israel Escalante",
+ "Iv\xC3\xA1" "n Frade",
+ "Iván Frade",
+ "J.H.M. Dassen (Ray)",
+ "JP Rosevear",
+ "J\xC3\xBC" "rg Billeter",
+ "Jürg Billeter",
+ "Jack Jia",
+ "Jacob Ulysses Berkman",
+ "Jacob Berkman",
+ "Jaka Mocnik",
+ "Jakub Steiner",
+ "James Doc Livingston",
+ "James Bowes",
+ "James Henstridge",
+ "James Willcox",
+ "Jan Arne Petersen",
+ "Jan Tichavsky",
+ "Jan Van Buggenhout",
+ "Jared Moore",
+ "Jarkko Ranta",
+ "Jason Leach",
+ "Jason Tackaberry",
+ "Jayaradha",
+ "Jean-Noel Guiheneuf",
+ "Jedy Wang",
+ "Jeff Bailey",
+ "Jeff Cai",
+ "Jeff Garzik",
+ "Jeffrey Stedfast",
+ "Jens Granseuer",
+ "Jens Seidel",
+ "Jeremy Katz",
+ "Jeremy Wise",
+ "Jerome Lacoste",
+ "Jerry Yu",
+ "Jes\xC3\xBA" "s Bravo \xC3\x81" "lvarez",
+ "Jesse Pavel",
+ "Ji Lee",
+ "Joan Sanfeliu",
+ "Jody Goldberg",
+ "Joe Marcus Clarke",
+ "Joe Shaw",
+ "John Gotts",
+ "Johnny Jacob",
+ "Johnny",
+ "Jon Ander Hernandez",
+ "Jon K Hellan",
+ "Jon Oberheide",
+ "Jon Trowbridge",
+ "Jonas Borgstr",
+ "Jonathan Blandford",
+ "Jonathan Dieter",
+ "Jos Dehaes",
+ "Josselin Mouette",
+ "JP Rosvear",
+ "Jukka Zitting",
+ "Jules Colding",
+ "Julian Missig",
+ "Julio M. Merino Vidal",
+ "Jürg Billeter",
+ "Karl Eichwalder",
+ "Karl Relton",
+ "Karsten Br\xC3\xA4" "ckelmann",
+ "Kaushal Kumar",
+ "Kenneth Christiansen",
+ "Kenny Graunke",
+ "Keshav Upadhyaya",
+ "Kevin Breit",
+ "Kevin Piche",
+ "Kevin Vandersloot",
+ "Khasim Shaheed",
+ "Kidd Wang",
+ "Kjartan Maraas",
+ "Krishnan R",
+ "Krisztian Pifko",
+ "Kyle Ambroff",
+ "Larry Ewing",
+ "Laszlo (Laca) Peter",
+ "Laurent Dhima",
+ "Lauris Kaplinski",
+ "Leon Zhang",
+ "Li Yuan",
+ "Loïc Minier",
+ "Loïc Minier",
+ "Lorenzo Gil Sanchez",
+ "Luca Ferretti",
+ "Lucky Wankhede",
+ "Luis Villa",
+ "Lutz M",
+ "M Victor Aloysius J",
+ "Maciej Stachowiak",
+ "Makuchaku",
+ "Malcolm Tredinnick",
+ "Marco Pesenti Gritti",
+ "Marius Andreiana",
+ "Marius Vollmer",
+ "Mark Crichton",
+ "Mark G. Adams",
+ "Mark Gordon",
+ "Mark McLoughlin",
+ "Mark Moulder",
+ "Mark Tearle",
+ "Martha Burke",
+ "Martin Baulig",
+ "Martin Hicks",
+ "Martin Meyer",
+ "Martin Norb\xC3\xA4" "ck",
+ "Martyn Russell",
+ "Masahiro Sakai",
+ "Mathieu Lacage",
+ "Matias Mutchinick",
+ "Matt Bissiri",
+ "Matt Brown",
+ "Matt Loper",
+ "Matt Martin",
+ "Matt Wilson",
+ "Matthew Barnes",
+ "Matthew Daniel",
+ "Matthew Hall",
+ "Matthew Loper",
+ "Matthew Wilson",
+ "Matthias Clasen",
+ "Max Horn",
+ "Maxx Cao",
+ "Mayank Jain",
+ "Meilof Veeningen",
+ "Mengjie Yu",
+ "Michael Granger",
+ "Michael M. Morrison",
+ "Michael MacDonald",
+ "Michael Meeks",
+ "Michael Monreal",
+ "Michael Terry",
+ "Michael Zucchi",
+ "Michel Daenzer",
+ "Miguel Angel Lopez Hernandez",
+ "Miguel de Icaza",
+ "Mikael Hallendal",
+ "Mikael Nilsson",
+ "Mike Castle",
+ "Mike Kestner",
+ "Mike McEwan",
+ "Mikhail Zabaluev",
+ "Milan Crha",
+ "Miles Lane",
+ "Mohammad Damt",
+ "Morten Welinder",
+ "Mubeen Jukaku",
+ "Murray Cumming",
+ "Naba Kumar",
+ "Nagappan Alagappan",
+ "Nancy Cai",
+ "Nat Friedman",
+ "Nathan Owens",
+ "Nicel KM",
+ "Nicholas J Kreucher",
+ "Nicholas Miell",
+ "Nick Sukharev",
+ "Nickolay V. Shmyrev",
+ "Nike Gerdts",
+ "Noel",
+ "Nuno Ferreira",
+ "Nyall Dawson",
+ "Ondrej Jirman",
+ "Oswald Rodrigues",
+ "Owen Taylor",
+ "Oystein Gisnas",
+ "P Chenthill",
+ "P S Chakravarthi",
+ "Pablo Gonzalo del Campo",
+ "Pablo Saratxaga",
+ "Pamplona Hackers",
+ "Paolo Molaro",
+ "Parag Goel",
+ "Parthasarathi Susarla",
+ "Pascal Terjan",
+ "Patrick Ohly",
+ "Paul Bolle",
+ "Paul Lindner",
+ "Pavel Cisler",
+ "Pavel Roskin",
+ "Pavithran",
+ "Pawan Chitrakar",
+ "Pedro Villavicencio",
+ "Peter Pouliot",
+ "Peter Teichman",
+ "Peter Williams",
+ "Peteris Krisjanis",
+ "Petta Pietikainen",
+ "Phil Goembel",
+ "Philip Van Hoof",
+ "Philip Zhao",
+ "Poornima Nayak",
+ "Pratik V. Parikh",
+ "Praveen Kumar",
+ "Priit Laes",
+ "Priyanshu Raj",
+ "Radek Doul\xC3\xADk",
+ "Raghavendran R",
+ "Raja R Harinath",
+ "Rajeev Ramanathan",
+ "Rajesh Ranjan",
+ "Rakesh k.g",
+ "Ramiro Estrugo",
+ "Ranjan Somani",
+ "Ray Strode",
+ "Rhys Jones",
+ "Ricardo Markiewicz",
+ "Richard Boulton",
+ "Richard Hult",
+ "Richard Li",
+ "Rob Bradford",
+ "Robert Brady",
+ "Robert Sedak",
+ "Robin Slomkowski",
+ "Rodney Dawes",
+ "Rodrigo Moya",
+ "Rohini S",
+ "Rohini",
+ "Roland Illig",
+ "Ronald Kuetemeier",
+ "Roozbeh Pournader",
+ "Ross Burton",
+ "Rouslan Solomakhin",
+ "Runa Bhattacharjee",
+ "Russell Steinthal",
+ "Rusty Conover",
+ "Ryan P. Skadberg",
+ "S Antony Vincent Pandian",
+ "S N Tejasvi",
+ "S. \xC3\x87" "a\xC4\x9F" "lar Onur",
+ "S.Antony Vincent Pandian",
+ "S. Caglar Onur",
+ "Sam Creasey",
+ "Sam Yang",
+ "Sam\xC3\xBA" "el J\xC3\xB3" "n Gunnarsson",
+ "Sankar P",
+ "Sanlig Badral",
+ "Sanshao Jiang",
+ "Sarfraaz Ahmed",
+ "Sayamindu Dasgupta",
+ "Sean Atkinson",
+ "Sean Gao",
+ "Sebastian Rittau",
+ "Sebastian Wilhelmi",
+ "Sebastien Bacher",
+ "Sergey Panov",
+ "Seth Alves",
+ "Seth Nickell",
+ "Shakti Sen",
+ "Shi Pu",
+ "Shilpa C",
+ "Shree Krishnan",
+ "Shreyas Srinivasan",
+ "Simon Zheng",
+ "Simos Xenitellis",
+ "Sivaiah Nallagatla",
+ "Srinivasa Ragavan",
+ "Stanislav Brabec",
+ "Stanislav Visnovsky",
+ "Stéphane Raimbault",
+ "Stephen Cook",
+ "Steve Murphy",
+ "Steven Zhang",
+ "Stuart Parmenter",
+ "Subodh Soni",
+ "Suman Manjunath",
+ "Sunil Mohan Adapa",
+ "Suresh Chandrasekharan",
+ "Sushma Rai",
+ "Sven Herzberg",
+ "Szabolcs Ban",
+ "T\xC3\xB5" "ivo Leedj\xC3\xA4" "rv",
+ "Takao Fujiwara",
+ "Takayuki Kusano",
+ "Takeshi Aihana",
+ "Tambet Ingo",
+ "Taylor Hayward",
+ "Ted Percival",
+ "Theppitak Karoonboonyanan",
+ "Thomas Cataldo",
+ "Thomas Klausner",
+ "Thomas Mirlacher",
+ "Thouis R. Jones",
+ "Tim Wo",
+ "Tim Yamin",
+ "Timo Hoenig",
+ "Timo Sirainen",
+ "Timothy Lee",
+ "Timur Bakeyev",
+ "Tino Meinen",
+ "Tobias Mueller",
+ "Tõivo Leedjärv",
+ "Tom Tromey",
+ "Tomas Ogren",
+ "Tomasz K\xC5\x82" "oczko",
+ "Tomislav Vujec",
+ "Tommi Komulainen",
+ "Tommi Vainikainen",
+ "Tony Tsui",
+ "Tor Lillqvist",
+ "Trent Lloyd",
+ "Tuomas J. Lukka",
+ "Tuomas Kuosmanen",
+ "Ulrich Neumann",
+ "Umesh Tiwari",
+ "Umeshtej",
+ "Ushveen Kaur",
+ "V Ravi Kumar Raju",
+ "Vadim Strizhevsky",
+ "Valek Filippov",
+ "Vandana Shenoy .B",
+ "Vardhman Jain",
+ "Veerapuram Varadhan",
+ "Vincent Noel",
+ "Vincent van Adrighem",
+ "Viren",
+ "Vivek Jain",
+ "Vladimer Sichinava",
+ "Vladimir Vukicevic",
+ "Wadim Dziedzic",
+ "Wang Jian",
+ "Wang Xin",
+ "Wayne Davis",
+ "William Jon McCann",
+ "Wouter Bolsterlee",
+ "Xan Lopez",
+ "Xiurong Simon Zheng",
+ "Yanko Kaneti",
+ "Yi Jin",
+ "Yong Sun",
+ "Yu Mengjie",
+ "Yuedong Du",
+ "Yukihiro Nakai",
+ "Yuri Pankov",
+ "Yuri Syrota",
+ "Zach Frey",
+ "Zan Lynx",
+ "Zbigniew Chyla",
+ "\xC3\x98ystein Gisn\xC3\xA5s",
+ "\xC5\xBDygimantas Beru\xC4\x8Dka",
+ NULL
+};
+
+static const gchar *documenters[] = {
+ "Aaron Weber",
+ "Binika Preet",
+ "Dan Winship",
+ "David Trowbridge",
+ "Jessica Prabhakar",
+ "JP Rosevear",
+ "Radhika Nair",
+ NULL
+};
+
+/**
+ * E_SHELL_WINDOW_ACTION_ABOUT:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action displays the application's About dialog.
+ *
+ * Main menu item: Help -> About
+ **/
+static void
+action_about_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ gchar *translator_credits;
+
+ /* The translator-credits string is for translators to list
+ * per-language credits for translation, displayed in the
+ * about dialog. */
+ translator_credits = _("translator-credits");
+ if (strcmp (translator_credits, "translator-credits") == 0)
+ translator_credits = NULL;
+
+ gtk_show_about_dialog (
+ GTK_WINDOW (shell_window),
+ "program-name", "Evolution",
+ "version", VERSION,
+ "copyright", EVOLUTION_COPYRIGHT,
+ "comments", _("Groupware Suite"),
+ "website", EVOLUTION_WEBSITE,
+ "website-label", _("Evolution Website"),
+ "authors", authors,
+ "documenters", documenters,
+ "translator-credits", translator_credits,
+ "logo-icon-name", "evolution",
+ NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_CLOSE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action closes @window. If this is the last window,
+ * the application initiates shutdown.
+ *
+ * Main menu item: File -> Close
+ **/
+static void
+action_close_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ GtkWidget *widget = GTK_WIDGET (shell_window);
+ GdkEvent *event;
+
+ /* Synthesize a delete_event on this window. */
+ event = gdk_event_new (GDK_DELETE);
+ event->any.window = g_object_ref (widget->window);
+ event->any.send_event = TRUE;
+ gtk_main_do_event (event);
+ gdk_event_free (event);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_CONTENTS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the application's user manual.
+ *
+ * Main menu item: Help -> Contents
+ **/
+static void
+action_contents_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ e_display_help (GTK_WINDOW (shell_window), NULL);
+}
+
+static void
+action_custom_rule_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ FilterRule *rule;
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ rule = g_object_get_data (G_OBJECT (action), "rule");
+ g_return_if_fail (rule != NULL);
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ rule = g_object_get_data (G_OBJECT (action), "rule");
+ g_return_if_fail (IS_FILTER_RULE (rule));
+
+ e_shell_content_set_search_rule (shell_content, rule);
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_FAQ:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a web page with answers to frequently
+ * asked questions about this application.
+ *
+ * Main menu item: Help -> Evolution FAQ
+ **/
+static void
+action_faq_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ e_show_uri (GTK_WINDOW (shell_window), EVOLUTION_FAQ);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_FORGET_PASSWORDS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action deletes all stored passwords.
+ *
+ * Main menu item: File -> Forget Passwords
+ **/
+static void
+action_forget_passwords_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ gint response;
+
+ response = e_error_run (
+ GTK_WINDOW (shell_window), "shell:forget-passwords", NULL);
+
+ if (response == GTK_RESPONSE_OK)
+ e_passwords_forget_passwords ();
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_GAL_DEFINE_VIEWS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a dialog for editing GAL views for
+ * the current shell view.
+ *
+ * Main menu item: View -> Current View -> Define Views...
+ **/
+static void
+action_gal_define_views_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ GalViewCollection *view_collection;
+ GtkWidget *dialog;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ view_collection = shell_view_class->view_collection;
+ g_return_if_fail (view_collection != NULL);
+
+ dialog = gal_define_views_dialog_new (view_collection);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gal_view_collection_save (view_collection);
+ gtk_widget_destroy (dialog);
+
+ e_shell_window_update_view_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_GAL_CUSTOM_VIEW:
+ * @window: an #EShellWindow
+ *
+ * This radio action is selected when using a custom GAL view that has
+ * not been saved.
+ *
+ * Main menu item: View -> Current View -> Custom View
+ **/
+static void
+action_gal_view_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ const gchar *view_name;
+ const gchar *view_id;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ view_id = g_object_get_data (G_OBJECT (current), "view-id");
+ e_shell_view_set_view_id (shell_view, view_id);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_GAL_SAVE_CUSTOM_VIEW:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action saves a custom GAL view.
+ *
+ * Main menu item: View -> Current View -> Save Custom View...
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_IMPORT:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the Evolution Import Assistant.
+ *
+ * Main menu item: File -> Import...
+ **/
+static void
+action_import_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ e_shell_importer_start_import (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_NEW_WINDOW:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a new shell window.
+ *
+ * Main menu item: File -> New Window
+ **/
+static void
+action_new_window_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ const gchar *view_name;
+
+ shell = e_shell_window_get_shell (shell_window);
+ view_name = e_shell_window_get_active_view (shell_window);
+
+ e_shell_create_shell_window (shell, view_name);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_PAGE_SETUP:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the application's Page Setup dialog.
+ *
+ * Main menu item: File -> Page Setup...
+ **/
+static void
+action_page_setup_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ e_print_run_page_setup_dialog (GTK_WINDOW (shell_window));
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_PREFERENCES:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the application's Preferences window.
+ *
+ * Main menu item: Edit -> Preferences
+ **/
+static void
+action_preferences_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ GtkWidget *preferences_window;
+
+ shell = e_shell_window_get_shell (shell_window);
+ preferences_window = e_shell_get_preferences_window (shell);
+
+ gtk_window_set_transient_for (
+ GTK_WINDOW (preferences_window),
+ GTK_WINDOW (shell_window));
+ gtk_window_set_position (
+ GTK_WINDOW (preferences_window),
+ GTK_WIN_POS_CENTER_ON_PARENT);
+ gtk_window_present (GTK_WINDOW (preferences_window));
+
+ /* FIXME Switch to a page appropriate for the current view. */
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_QUICK_REFERENCE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a printable table of useful shortcut
+ * keys for this application.
+ *
+ * Main menu item: Help -> Quick Reference
+ **/
+static void
+action_quick_reference_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ const gchar * const *language_names;
+
+ language_names = g_get_language_names ();
+ while (*language_names != NULL) {
+ const gchar *language = *language_names++;
+ gchar *filename;
+
+ /* This must be a valid language AND a language with
+ * no encoding suffix. The next language should have
+ * no encoding suffix. */
+ if (language == NULL || strchr (language, '.') != NULL)
+ continue;
+
+ filename = g_build_filename (
+ EVOLUTION_HELPDIR, "quickref",
+ language, "quickref.pdf", NULL);
+
+ if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ GFile *file;
+ gchar *uri;
+ GError *error = NULL;
+
+ file = g_file_new_for_path (filename);
+ uri = g_file_get_uri (file);
+
+ g_app_info_launch_default_for_uri (uri, NULL, &error);
+
+ if (error != NULL) {
+ /* FIXME Show an error dialog. */
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_object_unref (file);
+ g_free (uri);
+ }
+
+ g_free (filename);
+ }
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_QUIT:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action initiates application shutdown.
+ *
+ * Main menu item: File -> Quit
+ **/
+static void
+action_quit_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+
+ shell = e_shell_window_get_shell (shell_window);
+ e_shell_quit (shell);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_ADVANCED:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens an Advanced Search dialog.
+ *
+ * Main menu item: Search -> Advanced Search...
+ **/
+static void
+action_search_advanced_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ e_shell_content_run_advanced_search_dialog (shell_content);
+ e_shell_window_update_search_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_CLEAR:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action clears the most recent search results.
+ *
+ * Main menu item: Search -> Clear
+ **/
+static void
+action_search_clear_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ e_shell_content_set_search_rule (shell_content, NULL);
+ e_shell_content_set_search_text (shell_content, NULL);
+
+ gtk_action_activate (ACTION (SEARCH_EXECUTE));
+
+ e_shell_window_update_search_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_EDIT:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens a dialog for editing saved searches.
+ *
+ * Main menu item: Search -> Edit Saved Searches...
+ **/
+static void
+action_search_edit_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ e_shell_content_run_edit_searches_dialog (shell_content);
+ e_shell_window_update_search_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action executes the current search conditions.
+ *
+ * Main menu item: Search -> Find Now
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action displays a menu of search options.
+ * This appears as a "find" icon in the window's search entry.
+ **/
+static void
+action_search_options_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ const gchar *view_name;
+ const gchar *widget_path;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+
+ widget_path = shell_view_class->search_options;
+ e_shell_view_show_popup_menu (shell_view, widget_path, NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEARCH_SAVE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action saves the current search conditions.
+ *
+ * Main menu item: Search -> Save Search...
+ **/
+static void
+action_search_save_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ const gchar *view_name;
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+
+ e_shell_content_run_save_search_dialog (shell_content);
+ e_shell_window_update_search_menu (shell_window);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SEND_RECEIVE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the Send &amp; Receive Mail dialog.
+ *
+ * Main menu item: File -> Send / Receive
+ **/
+static void
+action_send_receive_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+
+ shell = e_shell_window_get_shell (shell_window);
+ e_shell_send_receive (shell, GTK_WINDOW (shell_window));
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR:
+ * @window: an #EShellWindow
+ *
+ * This toggle action controls whether the side bar is visible.
+ *
+ * Main menu item: View -> Layout -> Show Side Bar
+ **/
+static void
+action_show_sidebar_cb (GtkToggleAction *action,
+ EShellWindow *shell_window)
+{
+ GtkPaned *paned;
+ GtkWidget *widget;
+ gboolean active;
+
+ paned = GTK_PANED (shell_window->priv->content_pane);
+
+ widget = gtk_paned_get_child1 (paned);
+ active = gtk_toggle_action_get_active (action);
+ g_object_set (widget, "visible", active, NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR:
+ * @window: an #EShellWindow
+ *
+ * This toggle action controls whether the status bar is visible.
+ *
+ * Main menu item: View -> Layout -> Show Status Bar
+ **/
+static void
+action_show_statusbar_cb (GtkToggleAction *action,
+ EShellWindow *shell_window)
+{
+ GtkWidget *widget;
+ gboolean active;
+
+ widget = shell_window->priv->status_area;
+ active = gtk_toggle_action_get_active (action);
+ g_object_set (widget, "visible", active, NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SHOW_SWITCHER:
+ * @window: an #EShellWindow
+ *
+ * This toggle action controls whether the switcher buttons are visible.
+ *
+ * Main menu item: View -> Switcher Appearance -> Show Buttons
+ **/
+static void
+action_show_switcher_cb (GtkToggleAction *action,
+ EShellWindow *shell_window)
+{
+ EShellSwitcher *switcher;
+ gboolean active;
+
+ switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
+ active = gtk_toggle_action_get_active (action);
+ e_shell_switcher_set_visible (switcher, active);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR:
+ * @window: an #EShellWindow
+ *
+ * This toggle action controls whether the tool bar is visible.
+ *
+ * Main menu item: View -> Layout -> Show Tool Bar
+ **/
+static void
+action_show_toolbar_cb (GtkToggleAction *action,
+ EShellWindow *shell_window)
+{
+ GtkWidget *widget;
+ gboolean active;
+
+ widget = shell_window->priv->main_toolbar;
+ active = gtk_toggle_action_get_active (action);
+ g_object_set (widget, "visible", active, NULL);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SUBMIT_BUG:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action allows users to report a bug using
+ * Bug Buddy.
+ *
+ * Main menu item: Help -> Submit Bug Report
+ **/
+static void
+action_submit_bug_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ const gchar *command_line;
+ GError *error = NULL;
+
+ command_line = "bug-buddy --package=Evolution";
+
+ g_debug ("Spawning: %s", command_line);
+ g_spawn_command_line_async (command_line, &error);
+
+ if (error != NULL) {
+ const gchar *message;
+
+ if (error->code == G_SPAWN_ERROR_NOENT)
+ message = _("Bug Buddy is not installed.");
+ else
+ message = _("Bug Buddy could not be run.");
+ e_notice (shell_window, GTK_MESSAGE_ERROR, message);
+ g_error_free (error);
+ }
+}
+
+static void
+action_switcher_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EShellWindow *shell_window)
+{
+ const gchar *view_name;
+
+ view_name = g_object_get_data (G_OBJECT (current), "view-name");
+ e_shell_window_switch_to_view (shell_window, view_name);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_BOTH:
+ * @window: an #EShellWindow
+ *
+ * This radio action displays switcher buttons with icons and text.
+ *
+ * Main menu item: View -> Switcher Appearance -> Icons and Text
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS:
+ * @window: an #EShellWindow
+ *
+ * This radio action displays switcher buttons with icons only.
+ *
+ * Main menu item: View -> Switcher Appearance -> Icons Only
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_TEXT:
+ * @window: an #EShellWindow
+ *
+ * This radio action displays switcher buttons with text only.
+ *
+ * Main menu item: View -> Switcher Appearance -> Text Only
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_USER:
+ * @window: an #EShellWindow
+ *
+ * This radio action displays switcher buttons according to the desktop
+ * toolbar setting.
+ *
+ * Main menu item: View -> Switcher Appearance -> Toolbar Style
+ **/
+static void
+action_switcher_style_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EShellWindow *shell_window)
+{
+ EShellSwitcher *switcher;
+ GtkToolbarStyle style;
+
+ switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
+ style = gtk_radio_action_get_current_value (action);
+
+ switch (style) {
+ case GTK_TOOLBAR_ICONS:
+ case GTK_TOOLBAR_TEXT:
+ case GTK_TOOLBAR_BOTH:
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ e_shell_switcher_set_style (switcher, style);
+ break;
+
+ default:
+ e_shell_switcher_unset_style (switcher);
+ break;
+ }
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_SYNC_OPTIONS:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action opens the Gnome Pilot settings.
+ *
+ * Main menu item: Edit -> Synchronization Options...
+ **/
+static void
+action_sync_options_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ const gchar *command_line;
+ GError *error = NULL;
+
+ command_line = "gpilotd-control-applet";
+
+ g_debug ("Spawning: %s", command_line);
+ g_spawn_command_line_async (command_line, &error);
+
+ if (error != NULL) {
+ const gchar *message;
+
+ if (error->code == G_SPAWN_ERROR_NOENT)
+ message = _("GNOME Pilot is not installed.");
+ else
+ message = _("GNOME Pilot could not be run.");
+ e_notice (shell_window, GTK_MESSAGE_ERROR, message);
+ g_error_free (error);
+ }
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_WORK_OFFLINE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action puts the application into offline mode.
+ *
+ * Main menu item: File -> Work Offline
+ **/
+static void
+action_work_offline_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_set_online (shell, FALSE);
+
+ /* XXX The sense of the setting is reversed. Would be more
+ * intuitive and less error-prone as "start-online". */
+ e_shell_settings_set_boolean (
+ shell_settings, "start-offline", TRUE);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_WORK_ONLINE:
+ * @window: an #EShellWindow
+ *
+ * Activation of this action puts the application into online mode.
+ *
+ * Main menu item: File -> Work Online
+ **/
+static void
+action_work_online_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_set_online (shell, TRUE);
+
+ /* XXX The sense of the setting is reversed. Would be more
+ * intuitive and less error-prone as "start-online". */
+ e_shell_settings_set_boolean (
+ shell_settings, "start-offline", FALSE);
+}
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_CUSTOM_RULES:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_GAL_VIEW:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_NEW_ITEM:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_NEW_SOURCE:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_SHELL:
+ * @window: an #EShellWindow
+ **/
+
+/**
+ * E_SHELL_WINDOW_ACTION_GROUP_SWITCHER:
+ * @window: an #EShellWindow
+ **/
+
+static GtkActionEntry shell_entries[] = {
+
+ { "about",
+ GTK_STOCK_ABOUT,
+ NULL,
+ NULL,
+ N_("Show information about Evolution"),
+ G_CALLBACK (action_about_cb) },
+
+ { "close",
+ GTK_STOCK_CLOSE,
+ N_("_Close Window"),
+ "<Control>w",
+ N_("Close this window"),
+ G_CALLBACK (action_close_cb) },
+
+ { "contents",
+ GTK_STOCK_HELP,
+ N_("_Contents"),
+ "F1",
+ N_("Open the Evolution User Guide"),
+ G_CALLBACK (action_contents_cb) },
+
+ { "faq",
+ "help-faq",
+ N_("Evolution _FAQ"),
+ NULL,
+ N_("Open the Frequently Asked Questions webpage"),
+ G_CALLBACK (action_faq_cb) },
+
+ { "forget-passwords",
+ NULL,
+ N_("_Forget Passwords"),
+ NULL,
+ N_("Forget all remembered passwords"),
+ G_CALLBACK (action_forget_passwords_cb) },
+
+ { "import",
+ "stock_mail-import",
+ N_("I_mport..."),
+ NULL,
+ N_("Import data from other programs"),
+ G_CALLBACK (action_import_cb) },
+
+ { "new-window",
+ "window-new",
+ N_("New _Window"),
+ "<Control><Shift>w",
+ N_("Create a new window displaying this view"),
+ G_CALLBACK (action_new_window_cb) },
+
+ { "preferences",
+ GTK_STOCK_PREFERENCES,
+ NULL,
+ "<Control><Shift>s",
+ N_("Configure Evolution"),
+ G_CALLBACK (action_preferences_cb) },
+
+ { "quick-reference",
+ NULL,
+ N_("_Quick Reference"),
+ NULL,
+ N_("Show Evolution's shortcut keys"),
+ G_CALLBACK (action_quick_reference_cb) },
+
+ { "quit",
+ GTK_STOCK_QUIT,
+ NULL,
+ NULL,
+ N_("Exit the program"),
+ G_CALLBACK (action_quit_cb) },
+
+ { "search-advanced",
+ NULL,
+ N_("_Advanced Search..."),
+ NULL,
+ N_("Construct a more advanced search"),
+ G_CALLBACK (action_search_advanced_cb) },
+
+ { "search-clear",
+ GTK_STOCK_CLEAR,
+ NULL,
+ "<Control><Shift>q",
+ N_("Clear the current search parameters"),
+ G_CALLBACK (action_search_clear_cb) },
+
+ { "search-edit",
+ NULL,
+ N_("_Edit Saved Searches..."),
+ NULL,
+ N_("Manage your saved searches"),
+ G_CALLBACK (action_search_edit_cb) },
+
+ { "search-execute",
+ GTK_STOCK_FIND,
+ N_("_Find Now"),
+ "", /* Block the default Ctrl+F. */
+ N_("Execute the current search parameters"),
+ NULL }, /* Handled by EShellContent and subclasses. */
+
+ { "search-options",
+ GTK_STOCK_FIND,
+ NULL,
+ NULL,
+ N_("Click here to change the search type"),
+ G_CALLBACK (action_search_options_cb) },
+
+ { "search-save",
+ NULL,
+ N_("_Save Search..."),
+ NULL,
+ N_("Save the current search parameters"),
+ G_CALLBACK (action_search_save_cb) },
+
+ { "send-receive",
+ "mail-send-receive",
+ N_("Send / _Receive"),
+ "F9",
+ N_("Send queued items and retrieve new items"),
+ G_CALLBACK (action_send_receive_cb) },
+
+ { "submit-bug",
+ NULL,
+ N_("Submit _Bug Report..."),
+ NULL,
+ N_("Submit a bug report using Bug Buddy"),
+ G_CALLBACK (action_submit_bug_cb) },
+
+ { "sync-options",
+ NULL,
+ N_("_Synchronization Options..."),
+ NULL,
+ N_("Set up Pilot configuration"),
+ G_CALLBACK (action_sync_options_cb) },
+
+ { "work-offline",
+ "stock_disconnect",
+ N_("_Work Offline"),
+ NULL,
+ N_("Put Evolution into offline mode"),
+ G_CALLBACK (action_work_offline_cb) },
+
+ { "work-online",
+ "stock_connect",
+ N_("_Work Online"),
+ NULL,
+ N_("Put Evolution into online mode"),
+ G_CALLBACK (action_work_online_cb) },
+
+ /*** Menus ***/
+
+ { "edit-menu",
+ NULL,
+ N_("_Edit"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "file-menu",
+ NULL,
+ N_("_File"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "help-menu",
+ NULL,
+ N_("_Help"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "layout-menu",
+ NULL,
+ N_("Lay_out"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "new-menu",
+ GTK_STOCK_NEW,
+ N_("_New"),
+ "",
+ NULL,
+ NULL },
+
+ { "search-menu",
+ NULL,
+ N_("_Search"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "switcher-menu",
+ NULL,
+ N_("_Switcher Appearance"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "view-menu",
+ NULL,
+ N_("_View"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "window-menu",
+ NULL,
+ N_("_Window"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static GtkToggleActionEntry shell_toggle_entries[] = {
+
+ { "show-sidebar",
+ NULL,
+ N_("Show Side _Bar"),
+ NULL,
+ N_("Show the side bar"),
+ G_CALLBACK (action_show_sidebar_cb),
+ TRUE },
+
+ { "show-statusbar",
+ NULL,
+ N_("Show _Status Bar"),
+ NULL,
+ N_("Show the status bar"),
+ G_CALLBACK (action_show_statusbar_cb),
+ TRUE },
+
+ { "show-switcher",
+ NULL,
+ N_("Show _Buttons"),
+ NULL,
+ N_("Show the switcher buttons"),
+ G_CALLBACK (action_show_switcher_cb),
+ TRUE },
+
+ { "show-toolbar",
+ NULL,
+ N_("Show _Tool Bar"),
+ NULL,
+ N_("Show the toolbar"),
+ G_CALLBACK (action_show_toolbar_cb),
+ TRUE }
+};
+
+static GtkRadioActionEntry shell_switcher_entries[] = {
+
+ /* This action represents the initial active shell view.
+ * It should not be visible in the UI, nor should it be
+ * possible to switch to it from another shell view. */
+ { "switcher-initial",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ -1 }
+};
+
+static GtkRadioActionEntry shell_switcher_style_entries[] = {
+
+ { "switcher-style-icons",
+ NULL,
+ N_("_Icons Only"),
+ NULL,
+ N_("Display window buttons with icons only"),
+ GTK_TOOLBAR_ICONS },
+
+ { "switcher-style-text",
+ NULL,
+ N_("_Text Only"),
+ NULL,
+ N_("Display window buttons with text only"),
+ GTK_TOOLBAR_TEXT },
+
+ { "switcher-style-both",
+ NULL,
+ N_("Icons _and Text"),
+ NULL,
+ N_("Display window buttons with icons and text"),
+ GTK_TOOLBAR_BOTH_HORIZ },
+
+ { "switcher-style-user",
+ NULL,
+ N_("Tool_bar Style"),
+ NULL,
+ N_("Display window buttons using the desktop toolbar setting"),
+ -1 }
+};
+
+static GtkActionEntry shell_gal_view_entries[] = {
+
+ { "gal-define-views",
+ NULL,
+ N_("Define Views..."),
+ NULL,
+ N_("Create or edit views"),
+ G_CALLBACK (action_gal_define_views_cb) },
+
+ { "gal-save-custom-view",
+ NULL,
+ N_("Save Custom View..."),
+ NULL,
+ N_("Save current custom view"),
+ NULL }, /* Handled by subclasses. */
+
+ /*** Menus ***/
+
+ { "gal-view-menu",
+ NULL,
+ N_("C_urrent View"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static GtkRadioActionEntry shell_gal_view_radio_entries[] = {
+
+ { "gal-custom-view",
+ NULL,
+ N_("Custom View"),
+ NULL,
+ N_("Current view is a customized view"),
+ -1 }
+};
+
+static GtkActionEntry shell_lockdown_print_setup_entries[] = {
+
+ { "page-setup",
+ GTK_STOCK_PAGE_SETUP,
+ NULL,
+ NULL,
+ N_("Change the page settings for your current printer"),
+ G_CALLBACK (action_page_setup_cb) }
+};
+
+static void
+shell_window_extract_actions (EShellWindow *shell_window,
+ GList **source_list,
+ GList **destination_list)
+{
+ const gchar *current_view;
+ GList *match_list = NULL;
+ GList *iter;
+
+ /* Pick out the actions from the source list that are tagged
+ * as belonging to the current EShellView and move them to the
+ * destination list. */
+
+ current_view = e_shell_window_get_active_view (shell_window);
+
+ /* Example: Suppose [A] and [C] are tagged for this EShellView.
+ *
+ * source_list = [A] -> [B] -> [C]
+ * ^ ^
+ * | |
+ * match_list = [ ] --------> [ ]
+ *
+ *
+ * destination_list = [1] -> [2] (other actions)
+ */
+ for (iter = *source_list; iter != NULL; iter = iter->next) {
+ GtkAction *action = iter->data;
+ const gchar *backend_name;
+
+ backend_name = g_object_get_data (
+ G_OBJECT (action), "backend-name");
+
+ if (strcmp (backend_name, current_view) != 0)
+ continue;
+
+ if (g_object_get_data (G_OBJECT (action), "primary"))
+ match_list = g_list_prepend (match_list, iter);
+ else
+ match_list = g_list_append (match_list, iter);
+ }
+
+ /* source_list = [B] match_list = [A] -> [C] */
+ for (iter = match_list; iter != NULL; iter = iter->next) {
+ GList *link = iter->data;
+
+ iter->data = link->data;
+ *source_list = g_list_delete_link (*source_list, link);
+ }
+
+ /* destination_list = [1] -> [2] -> [A] -> [C] */
+ *destination_list = g_list_concat (*destination_list, match_list);
+}
+
+void
+e_shell_window_actions_init (EShellWindow *shell_window)
+{
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+ e_load_ui_definition (ui_manager, "evolution-shell.ui");
+
+ /* Shell Actions */
+ action_group = ACTION_GROUP (SHELL);
+ gtk_action_group_add_actions (
+ action_group, shell_entries,
+ G_N_ELEMENTS (shell_entries), shell_window);
+ gtk_action_group_add_toggle_actions (
+ action_group, shell_toggle_entries,
+ G_N_ELEMENTS (shell_toggle_entries), shell_window);
+ gtk_action_group_add_radio_actions (
+ action_group, shell_switcher_style_entries,
+ G_N_ELEMENTS (shell_switcher_style_entries),
+ E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE,
+ G_CALLBACK (action_switcher_style_cb), shell_window);
+ gtk_action_group_add_actions (
+ action_group, shell_gal_view_entries,
+ G_N_ELEMENTS (shell_gal_view_entries), shell_window);
+ gtk_action_group_add_radio_actions (
+ action_group, shell_gal_view_radio_entries,
+ G_N_ELEMENTS (shell_gal_view_radio_entries),
+ 0, G_CALLBACK (action_gal_view_cb), shell_window);
+
+ /* Switcher Actions */
+ action_group = ACTION_GROUP (SWITCHER);
+ gtk_action_group_add_radio_actions (
+ action_group, shell_switcher_entries,
+ G_N_ELEMENTS (shell_switcher_entries),
+ -1, G_CALLBACK (action_switcher_cb), shell_window);
+
+ /* Lockdown Print Setup Actions */
+ action_group = ACTION_GROUP (LOCKDOWN_PRINT_SETUP);
+ gtk_action_group_add_actions (
+ action_group, shell_lockdown_print_setup_entries,
+ G_N_ELEMENTS (shell_lockdown_print_setup_entries),
+ shell_window);
+
+ /* Fine tuning. */
+
+ g_object_set (ACTION (SEND_RECEIVE), "is-important", TRUE, NULL);
+}
+
+GtkWidget *
+e_shell_window_create_new_menu (EShellWindow *shell_window)
+{
+ GtkActionGroup *action_group;
+ GList *new_item_actions;
+ GList *new_source_actions;
+ GList *iter, *list = NULL;
+ GtkWidget *menu;
+ GtkWidget *separator;
+
+ /* Get sorted lists of "new item" and "new source" actions. */
+
+ action_group = ACTION_GROUP (NEW_ITEM);
+
+ new_item_actions = g_list_sort (
+ gtk_action_group_list_actions (action_group),
+ (GCompareFunc) e_action_compare_by_label);
+
+ action_group = ACTION_GROUP (NEW_SOURCE);
+
+ new_source_actions = g_list_sort (
+ gtk_action_group_list_actions (action_group),
+ (GCompareFunc) e_action_compare_by_label);
+
+ /* Give priority to actions that belong to this shell view. */
+
+ shell_window_extract_actions (
+ shell_window, &new_item_actions, &list);
+
+ shell_window_extract_actions (
+ shell_window, &new_source_actions, &list);
+
+ /* Convert the actions to menu item proxy widgets. */
+
+ for (iter = list; iter != NULL; iter = iter->next)
+ iter->data = gtk_action_create_menu_item (iter->data);
+
+ for (iter = new_item_actions; iter != NULL; iter = iter->next)
+ iter->data = gtk_action_create_menu_item (iter->data);
+
+ for (iter = new_source_actions; iter != NULL; iter = iter->next)
+ iter->data = gtk_action_create_menu_item (iter->data);
+
+ /* Add menu separators. */
+
+ separator = gtk_separator_menu_item_new ();
+ new_item_actions = g_list_prepend (new_item_actions, separator);
+ gtk_widget_show (GTK_WIDGET (separator));
+
+ separator = gtk_separator_menu_item_new ();
+ new_source_actions = g_list_prepend (new_source_actions, separator);
+ gtk_widget_show (GTK_WIDGET (separator));
+
+ /* Merge everything into one list, reflecting the menu layout. */
+
+ list = g_list_concat (list, new_item_actions);
+ new_item_actions = NULL; /* just for clarity */
+
+ list = g_list_concat (list, new_source_actions);
+ new_source_actions = NULL; /* just for clarity */
+
+ /* And finally, build the menu. */
+
+ menu = gtk_menu_new ();
+
+ for (iter = list; iter != NULL; iter = iter->next)
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), iter->data);
+
+ g_list_free (list);
+
+ return menu;
+}
+
+void
+e_shell_window_create_switcher_actions (EShellWindow *shell_window)
+{
+ GSList *group = NULL;
+ GtkRadioAction *action;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ EShellSwitcher *switcher;
+ EShell *shell;
+ GList *list, *iter;
+ guint merge_id;
+ guint ii = 0;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ action_group = ACTION_GROUP (SWITCHER);
+ switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+ shell = e_shell_window_get_shell (shell_window);
+ list = e_shell_get_shell_backends (shell);
+
+ /* Construct a group of radio actions from the various EShellView
+ * subclasses and register them with the EShellSwitcher. These
+ * actions are manifested as switcher buttons and View->Window
+ * menu items. */
+
+ action = GTK_RADIO_ACTION (ACTION (SWITCHER_INITIAL));
+ gtk_radio_action_set_group (action, group);
+ group = gtk_radio_action_get_group (action);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EShellBackend *shell_backend = iter->data;
+ EShellBackendClass *backend_class;
+ EShellViewClass *class;
+ GType view_type;
+ const gchar *view_name;
+ gchar *accelerator;
+ gchar *action_name;
+ gchar *tooltip;
+
+ /* The backend name is also the view name. */
+ backend_class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
+ view_type = backend_class->shell_view_type;
+ view_name = backend_class->name;
+
+ if (!g_type_is_a (view_type, E_TYPE_SHELL_VIEW)) {
+ g_critical (
+ "%s is not a subclass of %s",
+ g_type_name (view_type),
+ g_type_name (E_TYPE_SHELL_VIEW));
+ continue;
+ }
+
+ class = g_type_class_ref (view_type);
+
+ if (class->label == NULL) {
+ g_critical (
+ "Label member not set on %s",
+ G_OBJECT_CLASS_NAME (class));
+ continue;
+ }
+
+ action_name = g_strdup_printf (SWITCHER_FORMAT, view_name);
+ tooltip = g_strdup_printf (_("Switch to %s"), class->label);
+
+ /* Note, we have to set "icon-name" separately because
+ * gtk_radio_action_new() expects a "stock-id". Sadly,
+ * GTK+ still distinguishes between the two. */
+
+ action = gtk_radio_action_new (
+ action_name, class->label,
+ tooltip, NULL, ii++);
+
+ g_object_set (
+ G_OBJECT (action),
+ "icon-name", class->icon_name, NULL);
+
+ g_object_set_data (
+ G_OBJECT (action),
+ "view-name", (gpointer) view_name);
+
+ gtk_radio_action_set_group (action, group);
+ group = gtk_radio_action_get_group (action);
+
+ /* The first nine views have accelerators Ctrl+(1-9). */
+ if (ii < 10)
+ accelerator = g_strdup_printf ("<Control>%d", ii);
+ else
+ accelerator = g_strdup ("");
+
+ gtk_action_group_add_action_with_accel (
+ action_group, GTK_ACTION (action), accelerator);
+
+ e_shell_switcher_add_action (switcher, GTK_ACTION (action));
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id,
+ "/main-menu/view-menu/window-menu",
+ action_name, action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ g_free (accelerator);
+ g_free (action_name);
+ g_free (tooltip);
+
+ g_type_class_unref (class);
+ }
+}
+
+void
+e_shell_window_update_view_menu (EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ GalViewCollection *view_collection;
+ GtkRadioAction *radio_action;
+ GtkAction *action;
+ GSList *radio_group;
+ gboolean visible;
+ const gchar *path;
+ const gchar *view_id;
+ const gchar *view_name;
+ guint merge_id;
+ gint count, ii;
+
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ g_return_if_fail (shell_view != NULL);
+
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ view_collection = shell_view_class->view_collection;
+ view_id = e_shell_view_get_view_id (shell_view);
+ g_return_if_fail (view_collection != NULL);
+
+ action_group = ACTION_GROUP (GAL_VIEW);
+ merge_id = shell_window->priv->gal_view_merge_id;
+
+ /* Unmerge the previous menu. */
+ gtk_ui_manager_remove_ui (ui_manager, merge_id);
+ e_action_group_remove_all_actions (action_group);
+
+ /* We have a view ID, so forge ahead. */
+ count = gal_view_collection_get_count (view_collection);
+ path = "/main-menu/view-menu/gal-view-menu/gal-view-list";
+
+ /* Prevent spurious activations. */
+ action = ACTION (GAL_CUSTOM_VIEW);
+ g_signal_handlers_block_matched (
+ action, G_SIGNAL_MATCH_FUNC, 0, 0,
+ NULL, action_gal_view_cb, NULL);
+
+ /* Default to "Custom View", unless we find our view ID. */
+ radio_action = GTK_RADIO_ACTION (ACTION (GAL_CUSTOM_VIEW));
+ gtk_radio_action_set_group (radio_action, NULL);
+ radio_group = gtk_radio_action_get_group (radio_action);
+ gtk_radio_action_set_current_value (radio_action, -1);
+
+ /* Add a menu item for each view collection item. */
+ for (ii = 0; ii < count; ii++) {
+ GalViewCollectionItem *item;
+ gchar *action_name;
+ gchar *tooltip;
+
+ item = gal_view_collection_get_view_item (view_collection, ii);
+
+ action_name = g_strdup_printf (
+ "gal-view-%s-%d", view_name, ii);
+ tooltip = g_strdup_printf ("Select view: %s", item->title);
+
+ radio_action = gtk_radio_action_new (
+ action_name, item->title, tooltip, NULL, ii);
+
+ action = GTK_ACTION (radio_action);
+ gtk_radio_action_set_group (radio_action, radio_group);
+ radio_group = gtk_radio_action_get_group (radio_action);
+
+ g_object_set_data_full (
+ G_OBJECT (radio_action), "view-id",
+ g_strdup (item->id), (GDestroyNotify) g_free);
+
+ if (view_id != NULL && strcmp (item->id, view_id) == 0)
+ gtk_radio_action_set_current_value (radio_action, ii);
+
+ gtk_action_group_add_action (action_group, action);
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id, path, action_name,
+ action_name, GTK_UI_MANAGER_AUTO, FALSE);
+
+ g_free (action_name);
+ g_free (tooltip);
+ }
+
+ /* Doesn't matter which radio action we check. */
+ visible = (gtk_radio_action_get_current_value (radio_action) < 0);
+
+ action = ACTION (GAL_CUSTOM_VIEW);
+ gtk_action_set_visible (action, visible);
+ g_signal_handlers_unblock_matched (
+ action, G_SIGNAL_MATCH_FUNC, 0, 0,
+ NULL, action_gal_view_cb, NULL);
+
+ action = ACTION (GAL_SAVE_CUSTOM_VIEW);
+ gtk_action_set_visible (action, visible);
+}
+
+void
+e_shell_window_update_search_menu (EShellWindow *shell_window)
+{
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ EShellViewClass *shell_view_class;
+ RuleContext *context;
+ FilterRule *rule;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ const gchar *source;
+ const gchar *view_name;
+ gboolean sensitive;
+ guint merge_id;
+ gint ii = 0;
+
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ context = e_shell_content_get_search_context (shell_content);
+ shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+ source = FILTER_SOURCE_INCOMING;
+
+ /* Update sensitivity of search actions. */
+
+ sensitive = (e_shell_content_get_search_rule (shell_content) != NULL);
+ gtk_action_set_sensitive (ACTION (SEARCH_CLEAR), sensitive);
+ gtk_action_set_sensitive (ACTION (SEARCH_SAVE), sensitive);
+
+ sensitive = (shell_view_class->search_options != NULL);
+ gtk_action_set_sensitive (ACTION (SEARCH_OPTIONS), sensitive);
+
+ /* Add custom rules to the Search menu. */
+
+ action_group = ACTION_GROUP (CUSTOM_RULES);
+ merge_id = shell_window->priv->custom_rule_merge_id;
+
+ /* Unmerge the previous menu. */
+ gtk_ui_manager_remove_ui (ui_manager, merge_id);
+ e_action_group_remove_all_actions (action_group);
+
+ rule = rule_context_next_rule (context, NULL, source);
+ while (rule != NULL) {
+ GtkAction *action;
+ gchar *action_name;
+ gchar *action_label;
+
+ action_name = g_strdup_printf ("custom-rule-%d", ii++);
+ if (ii < 10)
+ action_label = g_strdup_printf (
+ "_%d. %s", ii, rule->name);
+ else
+ action_label = g_strdup (rule->name);
+
+ action = gtk_action_new (
+ action_name, action_label,
+ _("Execute these search parameters"), NULL);
+
+ g_object_set_data_full (
+ G_OBJECT (action),
+ "rule", g_object_ref (rule),
+ (GDestroyNotify) g_object_unref);
+
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_custom_rule_cb), shell_window);
+
+ gtk_action_group_add_action (action_group, action);
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id,
+ "/main-menu/search-menu/custom-rules",
+ action_name, action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ g_free (action_name);
+ g_free (action_label);
+
+ rule = rule_context_next_rule (context, rule, source);
+ }
+}
diff --git a/shell/e-shell-window-actions.h b/shell/e-shell-window-actions.h
new file mode 100644
index 0000000000..3b8774a494
--- /dev/null
+++ b/shell/e-shell-window-actions.h
@@ -0,0 +1,123 @@
+/*
+ * e-shell-window-actions.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SHELL_WINDOW_ACTIONS_H
+#define E_SHELL_WINDOW_ACTIONS_H
+
+#define E_SHELL_WINDOW_ACTION(window, name) \
+ (e_shell_window_get_action (E_SHELL_WINDOW (window), (name)))
+
+#define E_SHELL_WINDOW_ACTION_GROUP(window, name) \
+ (e_shell_window_get_action_group (E_SHELL_WINDOW (window), (name)))
+
+/* Actions */
+#define E_SHELL_WINDOW_ACTION_ABOUT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "about")
+#define E_SHELL_WINDOW_ACTION_CLOSE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "close")
+#define E_SHELL_WINDOW_ACTION_CONTENTS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "contents")
+#define E_SHELL_WINDOW_ACTION_FAQ(window) \
+ E_SHELL_WINDOW_ACTION ((window), "faq")
+#define E_SHELL_WINDOW_ACTION_FORGET_PASSWORDS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "forget-passwords")
+#define E_SHELL_WINDOW_ACTION_GAL_CUSTOM_VIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "gal-custom-view")
+#define E_SHELL_WINDOW_ACTION_GAL_DEFINE_VIEWS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "gal-define-views")
+#define E_SHELL_WINDOW_ACTION_GAL_SAVE_CUSTOM_VIEW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "gal-save-custom-view")
+#define E_SHELL_WINDOW_ACTION_IMPORT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "import")
+#define E_SHELL_WINDOW_ACTION_NEW_WINDOW(window) \
+ E_SHELL_WINDOW_ACTION ((window), "new-window")
+#define E_SHELL_WINDOW_ACTION_PAGE_SETUP(window) \
+ E_SHELL_WINDOW_ACTION ((window), "page-setup")
+#define E_SHELL_WINDOW_ACTION_PREFERENCES(window) \
+ E_SHELL_WINDOW_ACTION ((window), "preferences")
+#define E_SHELL_WINDOW_ACTION_QUICK_REFERENCE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "quick-reference")
+#define E_SHELL_WINDOW_ACTION_QUIT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "quit")
+#define E_SHELL_WINDOW_ACTION_SEARCH_ADVANCED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-advanced")
+#define E_SHELL_WINDOW_ACTION_SEARCH_CLEAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-clear")
+#define E_SHELL_WINDOW_ACTION_SEARCH_EDIT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-edit")
+#define E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-execute")
+#define E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-options")
+#define E_SHELL_WINDOW_ACTION_SEARCH_SAVE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "search-save")
+#define E_SHELL_WINDOW_ACTION_SEND_RECEIVE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "send-receive")
+#define E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "show-sidebar")
+#define E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "show-statusbar")
+#define E_SHELL_WINDOW_ACTION_SHOW_SWITCHER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "show-switcher")
+#define E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "show-toolbar")
+#define E_SHELL_WINDOW_ACTION_SUBMIT_BUG(window) \
+ E_SHELL_WINDOW_ACTION ((window), "submit-bug")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_INITIAL(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-initial")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_BOTH(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-style-both")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-style-icons")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_TEXT(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-style-text")
+#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_USER(window) \
+ E_SHELL_WINDOW_ACTION ((window), "switcher-style-user")
+#define E_SHELL_WINDOW_ACTION_SYNC_OPTIONS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "sync-options")
+#define E_SHELL_WINDOW_ACTION_WORK_OFFLINE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "work-offline")
+#define E_SHELL_WINDOW_ACTION_WORK_ONLINE(window) \
+ E_SHELL_WINDOW_ACTION ((window), "work-online")
+
+/* Action Groups */
+#define E_SHELL_WINDOW_ACTION_GROUP_CUSTOM_RULES(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "custom-rules")
+#define E_SHELL_WINDOW_ACTION_GROUP_GAL_VIEW(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "gal-view")
+#define E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_APPLICATION_HANDLERS(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "lockdown-application-handlers")
+#define E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_PRINTING(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "lockdown-printing")
+#define E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_PRINT_SETUP(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "lockdown-print-setup")
+#define E_SHELL_WINDOW_ACTION_GROUP_LOCKDOWN_SAVE_TO_DISK(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "lockdown-save-to-disk")
+#define E_SHELL_WINDOW_ACTION_GROUP_NEW_ITEM(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "new-item")
+#define E_SHELL_WINDOW_ACTION_GROUP_NEW_SOURCE(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "new-source")
+#define E_SHELL_WINDOW_ACTION_GROUP_SHELL(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "shell")
+#define E_SHELL_WINDOW_ACTION_GROUP_SWITCHER(window) \
+ E_SHELL_WINDOW_ACTION_GROUP ((window), "switcher")
+
+#endif /* E_SHELL_WINDOW_ACTIONS_H */
diff --git a/shell/e-shell-window-commands.c b/shell/e-shell-window-commands.c
deleted file mode 100644
index 731f17b49b..0000000000
--- a/shell/e-shell-window-commands.c
+++ /dev/null
@@ -1,1388 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include <glib/gprintf.h>
-
-#include <glib/gi18n.h>
-
-#include <gio/gio.h>
-
-#include <bonobo/bonobo-ui-component.h>
-
-#include <libedataserverui/e-passwords.h>
-
-#include <gconf/gconf-client.h>
-
-#include "e-util/e-dialog-utils.h"
-#include "e-util/e-error.h"
-#include "e-util/e-icon-factory.h"
-#include "e-util/e-print.h"
-#include "e-util/e-util.h"
-#include "e-util/e-util-private.h"
-
-#include "e-shell-window-commands.h"
-#include "e-shell-window.h"
-#include "evolution-shell-component-utils.h"
-
-#include "e-shell-importer.h"
-
-#define EVOLUTION_COPYRIGHT \
- "Copyright \xC2\xA9 1999 - 2009 Novell, Inc. and Others"
-
-#define EVOLUTION_WEBSITE \
- "http://www.gnome.org/projects/evolution/"
-
-/* Utility functions. */
-
-static void
-launch_pilot_settings (void)
-{
- GError* error = NULL;
-
- gchar * args = g_find_program_in_path ("gpilotd-control-applet");
- if (args == NULL) {
- e_notice (NULL, GTK_MESSAGE_ERROR,
- _("The GNOME Pilot tools do not appear to be installed on this system."));
- return;
- }
-
- g_spawn_command_line_async (args, &error);
- g_free (args);
-
- if (error != NULL) {
- e_notice (NULL, GTK_MESSAGE_ERROR,
- _("Error executing %s. (%s)"), args, error->message);
- g_error_free (error);
- }
-}
-
-/* Command callbacks. */
-
-static void
-command_import (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_shell_importer_start_import (window);
-}
-
-static void
-command_page_setup (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_print_run_page_setup_dialog (GTK_WINDOW (window));
-}
-
-static void
-command_close (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- if (e_shell_request_close_window (e_shell_window_peek_shell (window), window))
- gtk_widget_destroy (GTK_WIDGET (window));
-}
-
-static void
-command_quit (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- EShell *shell = e_shell_window_peek_shell (window);
-
- e_shell_quit(shell);
-}
-
-static void
-command_submit_bug (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- const gchar *command_line;
- GError *error = NULL;
-
- command_line = "bug-buddy --sm-disable --package=Evolution";
-
- g_debug ("Spawning: %s", command_line);
-
- if (!g_spawn_command_line_async (command_line, &error)) {
- if (error->code == G_SPAWN_ERROR_NOENT)
- e_notice (NULL, GTK_MESSAGE_ERROR,
- _("Bug buddy is not installed."));
- else
- e_notice (NULL, GTK_MESSAGE_ERROR,
- _("Bug buddy could not be run."));
- g_error_free (error);
- }
-}
-
-/* must be in utf8, the weird breaking of escaped strings
- is so the hex escape strings dont swallow too many chars
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- So that means, 8 bit characters, use \xXX hex encoding ONLY
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- No all environments are utf8 and not all editors can handle it.
-*/
-static const gchar *authors[] = {
- "Aaron Weber",
- "Abel Cheung",
- "Abhishek Parwal",
- "Adam Weinberger",
- "Adi Attar",
- "Ahmad Riza H Nst",
- "Aidan Delaney",
- "Aishwarya K",
- "Akagic Amila",
- "Akhil Laddha",
- "Akira Tagoh",
- "Alastair McKinstry",
- "Alastair Tse",
- "Alejandro Andres",
- "Ales Nyakhaychyk",
- "Alessandro Decina",
- "Alessio Frusciante",
- "Alex Graveley",
- "Alex Jiang",
- "Alex Jones",
- "Alex Kloss",
- "Alex Rostovtsev",
- "Alexander Didebulidze",
- "Alexander Shopov",
- "Alexander Winston",
- "Alexandre Folle de Menezes",
- "Alfred Peng",
- "Ali Abdin",
- "Ali Akcaagac",
- "Alireza Kheirkhahan",
- "Almer S. Tigelaar",
- "Alp Toker",
- "Amanpreet Singh Alam",
- "Ambuj Chitranshi",
- "Amish",
- "Amitakhya Phukan",
- "Anand V M",
- "Anders Carlsson",
- "Andras Timar",
- "Andrea Campi",
- "Andreas Henriksson",
- "Andreas Hyden",
- "Andreas J. Guelzow",
- "Andreas Köhler",
- "Andrew Ruthven",
- "Andre Klapper",
- "Andrew T. Veliath",
- "Andrew V. Samoilov",
- "Andrew Wu",
- "Ani Peter",
- "Ankit Patel",
- "Anna Marie Dirks",
- "Antonio Xu",
- "Arafat Medini",
- "Arangel Angov",
- "Archit Baweja",
- "Ariel Rios",
- "Arik Devens",
- "Armin Bauer",
- "Arjan Scherpenisse",
- "Arkadiusz Lipiec",
- "Artis Trops",
- "Artur Flinta",
- "Arturo Espinosa Aldama",
- "Arulanandan P",
- "Arun Prakash",
- "Arvind Sundararajan",
- "Ashish Shrivastava",
- "Åsmund Skjæveland",
- "Audrey Simons",
- "Baptiste Mille-Mathias",
- "Baris Cicek",
- "Bastien Nocera",
- "Behnam Esfahbod",
- "Benedikt Roth",
- "Ben Gamari",
- "Benjamin Berg",
- "Benjamin Kahn",
- "Benoît Dejean",
- "Bernard Leach",
- "Bertrand Guiheneuf",
- "Bharath Acharya",
- "Bharat Kumar",
- "Bharathi Gauthaman",
- "Big Iain Holmes",
- "Bill Zhu",
- "Björn Torkelsson",
- "Björn Lindqvist",
- "Bob Doan",
- "Bob Mauchin",
- "Boby Wang",
- "Bolian Yin",
- "Borislav Aleksandrov",
- "Boulton",
- "Brian Mury",
- "Brian Pepple",
- "Brigitte Le Grand",
- "Bruce Tao",
- "B S Srinidhi",
- "Calvin Liu",
- "Cantona Su",
- "Carlos Garcia Campos",
- "Carlos Garnacho Parro",
- "Carlos Perelló Marín",
- "Carl Sun",
- "Carsten Guenther",
- "Carsten Schaar",
- "Changwoo Ryu",
- "Chao-Hsiung Liao",
- "Charles Zhang",
- "Chema Celorio",
- "Chenthill Palanisamy",
- "Christian Persch",
- "Chris Halls",
- "Chris Heath",
- "Chris Lahey",
- "Christian Hammond",
- "Christian Kellner",
- "Christian Kintner",
- "Christian Kirbach",
- "Christian Krause",
- "Christian Kreibich",
- "Christian Meyer",
- "Christian Neumair",
- "Christian Persch",
- "Christian Rose",
- "Christophe Fergeau",
- "Christophe Merlet",
- "Christopher Blizzard",
- "Christopher James Lahey",
- "Christopher R. Gabriel",
- "Chris Phelps",
- "Chris Toshok",
- "Clara Tattoni",
- "Claude Paroz",
- "Claudio Saavedra",
- "Clifford R. Conover",
- "Clytie Siddall",
- "Cody Russell",
- "Colin Leroy",
- "Craig Jeffares",
- "Craig Small",
- "Cyprien Le Pannérer",
- "Dafydd Harries",
- "Damian Ivereigh",
- "Damien Carbery",
- "Damon Chaplin",
- "Daniel Gryniewicz",
- "Daniel Nylander",
- "Daniel van Eeden",
- "Daniel Veillard",
- "Daniel Yacob",
- "Danilo Šegan",
- "Danishka Navin",
- "Dan Korostelev",
- "Danny Baumann",
- "Dan Berger",
- "Dan Damian",
- "Dan Nguyen",
- "Dan Williams",
- "Dan Winship",
- "Darin Adler",
- "Dave Benson",
- "Dave Camp",
- "Dave Fallon",
- "Dave Malcolm",
- "Dave West",
- "David Farning",
- "David Kaelbling",
- "David Lodge",
- "David Malcolm",
- "David Moore",
- "David Mosberger",
- "David O'Callaghan",
- "David Richards",
- "David Trowbridge",
- "David Turner",
- "David Woodhouse",
- "Denis Washington",
- "Devashish Sharma",
- "Diego Escalante Urrelo",
- "Diego Gonzalez",
- "Diego Sevilla Ruiz",
- "Dietmar Maurer",
- "Dinesh Layek",
- "Dirk-Jan C. Binnema",
- "Djihed Afifi",
- "Dmitrijs Ledkovs",
- "Dmitry Mastrukov",
- "Dodji Seketeli",
- "Duarte Loreto",
- "Dulmandakh Sukhbaatar",
- "Duncan Mak",
- "Ebby Wiselyn",
- "Ed Catmur",
- "Edd Dumbill",
- "Edgar Luna Díaz",
- "Edward Rudd",
- "Elijah Newren",
- "Elizabeth Greene",
- "Elliot Lee",
- "Elliot Turner",
- "Emil Hessman",
- "Eneko Lacunza",
- "Enver Altin",
- "Erdal Ronahi",
- "Erdi Gergo",
- "Eric Busboom",
- "Eric Zhao",
- "Eskild Hustvedt"
- "Eskil Heyn Olsen",
- "Espen Stefansen",
- "Ettore Perazzoli",
- "Evandro Fernandes Giovanini",
- "Evan Yan",
- "Fatih Demir",
- "Fazlu & Hannah",
- "Federico Mena Quintero",
- "Fernando Herrera",
- "Ferretti",
- "F. Priyadharshini",
- "Francisco Javier Fernandez Serrador",
- "Frank Arnold",
- "Frank Belew",
- "Frederic Crozat",
- "Frederic Peters",
- "Frederic Riss",
- "Fredrik Wendt",
- "Funda Wang",
- "Gabor Kelemen",
- "Ganesh",
- "Göran Uddeborg",
- "Gareth Owen",
- "Gary Coady",
- "Gary Ekker",
- "Gavin Scott",
- "Gediminas Paulauskas",
- "George Lebl",
- "Gerardo Marin",
- "Gergő Érdi",
- "Gert Kulyk",
- "Giancarlo Capella",
- "Gilbert Fang",
- "Gildas Guillemot",
- "Gil Forcada",
- "Gilles Dartiguelongue",
- "Gil Osher",
- "Gintautas Miliauskas",
- "Goran Rakić",
- "Grahame Bowland",
- "Greg Hudson",
- "Gregory Leblanc",
- "Gregory McLean",
- "Grzegorz Goawski",
- "Guilherme de S. Pastore",
- "Guntupalli Karunakar",
- "Gustavo GirÎldez",
- "Gustavo Maciel Dias Vieira",
- "Gustavo Noronha Silva",
- "Hamed Malek",
- "Hannah & Fazlu",
- "Hans Petter Jansson",
- "Hao Sheng",
- "Hari Prasad Nadig",
- "Harish Krishnaswamy",
- "Harry Lu",
- "Hasbullah Bin Pit",
- "Havoc Pennington",
- "Heath Harrelson",
- "Hein-Pieter van Braam",
- "Héctor García Álvarez",
- "Helgi Þormar Þorbjörnsson",
- "Hendrik Brandt",
- "Hendrik Richter",
- "Herbert V. Riedel",
- "Hessam M. Armandehi",
- "Hiroyuki Ikezoe",
- "Iain Buchanan",
- "Iain Holmes",
- "Ian Campbell",
- "Iassen Pramatarov",
- "Iestyn Pryce",
- "I.Felix",
- "Ignacio Casal Quinteiro",
- "Igor Nestorović",
- "Ihar Hrachyshka",
- "Ilkka Tuohela",
- "Imam Musthaqim",
- "Iñaki Larrañaga",
- "Inaki Larranaga Murgoitio",
- "Indu",
- "Irene Huang",
- "Ismael Olea",
- "Israel Escalante",
- "Ivan Stojmirov",
- "Ivar Smolin",
- "Ivelina Karcheva",
- "Iván Frade",
- "J.H.M. Dassen (Ray)",
- "Jaap A. Haitsma",
- "Jack Jia",
- "Jacob Berkman",
- "Jacob Brown",
- "Jacobo Tarrio Barreiro",
- "Jacob Ulysses Berkman",
- "Jaka Mocnik",
- "Jakub Friedl",
- "Jakub Steiner",
- "James Bowes",
- "James Doc Livingston",
- "James Henstridge",
- "James Westby",
- "James Willcox",
- "Jamil Ahmed",
- "Jan Arne Petersen",
- "Jan Tichavsky",
- "Jan Van Buggenhout",
- "J�rg Billeter",
- "Jared Moore",
- "Jarkko Ranta",
- "Jason Leach",
- "Jason Tackaberry",
- "Jayaradha",
- "Jean-Noel Guiheneuf",
- "Jedy Wang",
- "Jeff Bailey",
- "Jeff Cai",
- "Jeff Garzik",
- "Jeffrey Stedfast",
- "Jens Granseuer",
- "Jens Seidel",
- "Jeremy Katz",
- "Jeremy Messenger",
- "Jeremy Wise",
- "Jerome Lacoste",
- "Jerry Yu",
- "Jesse Pavel",
- "Jesus Bravo Alvarez",
- "Jesse Pavel",
- "Ji Lee",
- "Joan Sanfeliu",
- "João Vale",
- "Joaquim Fellmann",
- "Jody Goldberg",
- "Joe Man",
- "Joe Marcus Clarke",
- "Joe Shaw",
- "Johan Dahlin",
- "Johan Euphrosine",
- "John Gotts",
- "Johnny Jacob",
- "Jon Ander Hernandez",
- "Jonas Borgstr�m",
- "Jonathan Blandford",
- "Jonathan Dieter",
- "Jonathan Ernst",
- "Jonh Wendell",
- "Jon K Hellan",
- "Jon Oberheide",
- "Jon Trowbridge",
- "Jonas Borgstr",
- "Jonathan Blandford",
- "Jonathan Dieter",
- "Joop Stakenborg",
- "Jordi Mallach",
- "Jordi Mas",
- "Jorge Gonzalez",
- "Jörgen Scheibengruber",
- "Jos Dehaes",
- "Josep Puigdemont Casamajó",
- "Josselin Mouette",
- "Jovan Naumovski",
- "JP Rosevear",
- "Juan Manuel García Molina",
- "Juan Pizarro",
- "Jukka Zitting",
- "Jules Colding",
- "Julian Missig",
- "Julien Puydt",
- "Julio M. Merino Vidal",
- "Juraj Kubelka",
- "Jürg Billeter",
- "Justina Klingaitė",
- "Kai Lahmann",
- "Kang Jeong-Hee",
- "Karl Eichwalder",
- "Karl Relton",
- "Karsten Bräckelmann",
- "Kaushal Kumar",
- "Keith Packard",
- "Keld Simonsen",
- "Kenneth Christiansen",
- "Kenneth Nielsen",
- "Kenneth Rohde Christiansen",
- "Kenny Graunke",
- "Keshav Upadhyaya",
- "Kevin Breit",
- "Kevin Piche",
- "Kevin Vandersloot",
- "Khasim Shaheed",
- "Kidd Wang",
- "Kjartan Maraas",
- "Krishnan R",
- "Kostas Papadimas",
- "Krishna Babu K",
- "Krisztian Pifko",
- "Kyle Ambroff",
- "Larry Ewing",
- "Laszlo Dvornik",
- "Laszlo (Laca) Peter",
- "Laurent Dhima",
- "Lauris Kaplinski",
- "Leonardo Ferreira Fontenelle",
- "Leonid Kanter",
- "Leon Zhang",
- "Li Yuan",
- "Loïc Minier",
- "Lorenzo Gil Sanchez",
- "Luca Ferretti",
- "Lucas Rocha",
- "Lucian Langa",
- "Lucky Wankhede",
- "Luis Villa",
- "Lukas Novotny",
- "Lutz M",
- "Maciej Piechotka",
- "Maciej Stachowiak",
- "Makuchaku",
- "Malcolm Tredinnick",
- "Manuel A. Fernández Montecelo",
- "Manuel Borchers",
- "Marcel Telka",
- "Marco Ciampa",
- "Marco Pesenti Gritti",
- "Marius Andreiana",
- "Marius Vollmer",
- "Mark Crichton",
- "Mark G. Adams",
- "Mark Gordon",
- "Mark McLoughlin",
- "Mark Moulder",
- "Mark Tearle",
- "Martha Burke",
- "Martin Baulig",
- "Martin Hicks",
- "Martin Meyer",
- "Martin Norbäck",
- "Martin Willemoes Hansen",
- "Martyn Russell",
- "Masahiro Sakai",
- "Matej Urbančič",
- "Mathieu Lacage",
- "Matias Mutchinick",
- "Matic Žgur",
- "Matt Bissiri",
- "Matt Brown",
- "Matthew Barnes",
- "Matthew Daniel",
- "Matthew Hall",
- "Matthew Loper",
- "Matthew Wilson",
- "Matthias Braun",
- "Matthias Clasen",
- "Matthias Warkus",
- "Matt Loper",
- "Matt Martin",
- "Matt McCutchen",
- "Matt Wilson",
- "Max Horn",
- "Maxim Dziumanenko",
- "Maxx Cao",
- "Mayank Jain",
- "Meelad Zakaria",
- "Meilof Veeningen",
- "Mendel Mobach",
- "Mengjie Yu",
- "Metin Amiroff",
- "Michael Granger",
- "Michael M. Morrison",
- "Michael MacDonald",
- "Michael Meeks",
- "Michael Monreal",
- "Michael Terry",
- "Michael Zucchi",
- "Michal Bukovjan",
- "Michel Daenzer",
- "Miguel Angel Lopez Hernandez",
- "Miguel de Icaza",
- "Mikael Hallendal",
- "Mikael Nilsson",
- "Mike Castle",
- "Mike Kestner",
- "Mike McEwan",
- "Mikhail Zabaluev",
- "Milan Crha",
- "Miles Lane",
- "Miloslav Trmač",
- "MIMOS Open Source Development Group",
- "Mohammad Damt",
- "Moritz Mertinkat",
- "Morten Welinder",
- "Mubeen Jukaku",
- "Mugurel Tudor",
- "Murray Cumming",
- "M Victor Aloysius J",
- "Naba Kumar",
- "Nagappan Alagappan",
- "Nancy Cai",
- "Naresh N",
- "Nat Friedman",
- "Nathan Owens",
- "Nguyễn Thái Ngọc Duy",
- "Nicel KM",
- "Nicholas J Kreucher",
- "Nicholas Miell",
- "Nickolay V. Shmyrev",
- "Nick Sukharev",
- "Nike Gerdts",
- "Nikos Charonitakis",
- "Noel",
- "Nuno Ferreira",
- "Nyall Dawson",
- "Og Maciel",
- "Ole Laursen",
- "Ondrej Jirman",
- "Oswald Rodrigues",
- "Owen Taylor",
- "Øystein Gisnås",
- "Pablo Gonzalo del Campo",
- "Pablo Saratxaga",
- "Pamplona Hackers",
- "Pauli Virtanen",
- "Paolo Borelli",
- "Paolo Molaro",
- "Parag Goel",
- "Parthasarathi Susarla",
- "Pascal Terjan",
- "Patrick Ohly",
- "Paul Bolle",
- "Paul Duffy",
- "Paul Iadonisi",
- "Paul Lindner",
- "Paul Smith",
- "Paulo Gomes Vanzuita",
- "Pavel Cholakov",
- "Pavel Cisler",
- "Pavel Roskin",
- "Pavithran",
- "Pawan Chitrakar",
- "Pedro Villavicencio",
- "Pema Geyleg",
- "Peteris Krisjanis",
- "Peter Bach",
- "Peter Pouliot",
- "Peter Teichman",
- "Peter Williams",
- "Petr Kovar",
- "Petta Pietikainen",
- "Phil Goembel",
- "Philipp Kerling",
- "Philip Van Hoof",
- "Philip Withnall",
- "Philip Zhao",
- "Poornima Nayak",
- "Pramod",
- "Prasad Kandepu",
- "Pratik V. Parikh",
- "Praveen Arimbrathodiyil",
- "Praveen Kumar",
- "Priit Laes",
- "Priyanshu Raj",
- "P S Chakravarthi",
- "Radek Doulik",
- "Raghavendran R",
- "Rahul Bhalerao",
- "Raivis Dejus",
- "Raja R Harinath",
- "Rajeev Ramanathan",
- "Rajesh Ranjan",
- "Rakesh k.g",
- "Ramiro Estrugo",
- "Ranjan Somani",
- "Raphael Higino",
- "Ray Strode",
- "Reinout van Schouwen",
- "Rhys Jones",
- "Ricardo Markiewicz",
- "Richard Boulton",
- "Richard Hult",
- "Richard Li",
- "Rob Bradford",
- "Robert-André Mauchin",
- "Robert Brady",
- "Robert Sedak",
- "Robin Slomkowski",
- "Rodney Dawes",
- "Rodrigo Moya",
- "Roger Zauner",
- "Rohini S",
- "Roland Illig",
- "Ronald Kuetemeier",
- "Roozbeh Pournader",
- "Roshan Kumar Singh",
- "Ross Burton",
- "Rostislav Raykov",
- "Rouslan Solomakhin",
- "Roy-Magne Mo",
- "Runa Bhattacharjee",
- "Russell Steinthal",
- "Russian team",
- "Rusty Conover",
- "Ryan P. Skadberg",
- "Sam Creasey",
- "Sami Pesonen",
- "Samúel Jón Gunnarsson",
- "Sam Yang",
- "Sankar P",
- "Sanlig Badral",
- "Sanshao Jiang",
- "S.Antony Vincent Pandian",
- "Sarfraaz Ahmed",
- "Satoru SATOH",
- "Sayamindu Dasgupta",
- "S. Caglar Onur",
- "Sean Atkinson",
- "Seán de Búrca",
- "Sean Gao",
- "Sebastian Rittau",
- "Sebastian Wilhelmi",
- "Sebastien Bacher",
- "Sergey Panov",
- "Sergio Villar Senín",
- "Seth Alves",
- "Seth Nickell",
- "Shakti Sen",
- "Shankar Prasad",
- "Shi Pu",
- "Shilpa C",
- "Shree Krishnan",
- "Shreyas Srinivasan",
- "Shuai Liu",
- "Sigurd Gartmann",
- "Simon Zheng",
- "Simos Xenitellis",
- "Sitic Vulnerability Advisory",
- "Sivaiah Nallagatla",
- "Slobodan D. Sredojevic",
- "S N Tejasvi",
- "Spiros Papadimitriou",
- "Srinivasa Ragavan",
- "Stanislav Brabec",
- "Stanislav Slusny",
- "Stanislav Visnovsky",
- "Stéphane Raimbault",
- "Stephen Cook",
- "Steve Murphy",
- "Steven Zhang",
- "Stuart Parmenter",
- "Subhransu Behera",
- "Subodh Soni",
- "Suman Manjunath",
- "Sunil Mohan Adapa",
- "Supranee Thirawatthanasuk",
- "Suresh Chandrasekharan",
- "Sushma Rai",
- "Sven Herzberg",
- "Sweta Kothari",
- "Szabolcs Ban",
- "Takao Fujiwara",
- "Takayuki Kusano",
- "Takeshi Aihana",
- "Takuo Kitame",
- "Tambet Ingo",
- "Taylor Hayward",
- "Ted Percival",
- "Telsa Gwynne",
- "Terance Sola",
- "Theppitak Karoonboonyanan",
- "Thierry Moisan",
- "Thierry Randrianiriana",
- "Thomas Cataldo",
- "Thomas Klausner",
- "Thomas Mirlacher",
- "Thouis R. Jones",
- "Tiago Antao",
- "Timo Jyrinki",
- "Timur Bakeyev",
- "Tim Wo",
- "Tim Yamin",
- "Timo Hoenig",
- "Timo Sirainen",
- "Timothy Lee",
- "Timur Bakeyev",
- "Tino Meinen",
- "Tobias Mueller",
- "Tõivo Leedjärv",
- "Tom Tromey",
- "Tomas Ogren",
- "Tomasz Kłoczko",
- "Tomislav Vujec",
- "Tommi Komulainen",
- "Tommi Vainikainen",
- "Tony Tsui",
- "Tor Lillqvist",
- "Trent Lloyd",
- "Tristan Tarrant",
- "Tuomas J. Lukka",
- "Tuomas Kuosmanen",
- "Udomsak Chundang",
- "Ulrich Neumann",
- "Umeshtej",
- "Umesh Tiwari",
- "Ushveen Kaur",
- "Vadim Strizhevsky",
- "Valek Filippov",
- "Vandana Shenoy .B",
- "Vardhman Jain",
- "Vasiliy Faronov",
- "Veerapuram Varadhan",
- "Vincent Carriere",
- "Vincent Noel",
- "Vincent Renardias",
- "Vincent Untz",
- "Vincent van Adrighem",
- "Viren.L",
- "Vivek Jain",
- "Vladimer Sichinava",
- "Vladimir Petkov",
- "Vladimir Vukicevic",
- "Vladimir Melo",
- "V Ravi Kumar Raju",
- "Wadim Dziedzic",
- "Wang Jian",
- "Wang Li",
- "Wang Xin",
- "Washington Lins",
- "Wayne Davis",
- "William Jon McCann",
- "Woodman Tuen",
- "Wouter Bolsterlee",
- "Xan Lopez",
- "Xavier Conde Rueda",
- "Xiurong Simon Zheng",
- "Yair Hershkovitz",
- "Yanko Kaneti",
- "Yannig Marchegay",
- "Yavor Doganov",
- "Yi Jin",
- "Yong Sun",
- "Yuedong Du",
- "Yukihiro Nakai",
- "Yu Mengjie",
- "Yuri Pankov",
- "Yuri Syrota",
- "Yuriy Penkin",
- "Zach Frey",
- "Zan Lynx",
- "Zbigniew Chyla",
- "Zhe Su",
- "Zipeco",
- "Žygimantas Beručka",
- NULL
-};
-
-static const gchar *documentors[] = {
- "Aaron Weber",
- "Binika Preet",
- "Dan Winship",
- "David Trowbridge",
- "Jessica Prabhakar",
- "JP Rosevear",
- "Radhika Nair",
- NULL
-};
-
-static void
-command_about (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- gchar *translator_credits;
-
- /* The translator-credits string is for translators to list
- * per-language credits for translation, displayed in the
- * about dialog. */
- translator_credits = _("translator-credits");
- if (strcmp (translator_credits, "translator-credits") == 0)
- translator_credits = NULL;
-
- gtk_show_about_dialog (
- GTK_WINDOW (window),
- "program-name", "Evolution",
- "version", VERSION,
- "copyright", EVOLUTION_COPYRIGHT,
- "comments", _("Groupware Suite"),
- "website", EVOLUTION_WEBSITE,
- "website-label", _("Evolution Website"),
- "authors", authors,
- "documenters", documentors,
- "translator-credits", translator_credits,
- "logo-icon-name", "evolution",
- NULL);
-}
-
-static void
-command_open_faq (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- const gchar *uri;
-
- uri = "http://www.go-evolution.org/FAQ";
- e_show_uri (GTK_WINDOW (window), uri);
-}
-
-static void
-command_quick_reference (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- gchar *quickref;
- const gchar * const *language_names;
-
- language_names = g_get_language_names ();
- while (*language_names != NULL) {
- const gchar *lang = *language_names++;
-
- /* This has to be a valid language AND a language with
- * no encoding postfix. The language will come up without
- * encoding next */
- if (lang == NULL || strchr (lang, '.') != NULL)
- continue;
-
- quickref = g_build_filename (EVOLUTION_HELPDIR, "quickref", lang, "quickref.pdf", NULL);
- if (g_file_test (quickref, G_FILE_TEST_EXISTS)) {
- GFile *file = g_file_new_for_path (quickref);
-
- if (file) {
- GError *error = NULL;
- gchar *uri = g_file_get_uri (file);
-
- g_app_info_launch_default_for_uri (uri, NULL, &error);
-
- if (error) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_object_unref (file);
- g_free (uri);
- }
-
- g_free (quickref);
- return;
- }
-
- g_free (quickref);
- }
-}
-
-static void
-command_work_offline (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- EShell *shell;
-
- shell = e_shell_window_peek_shell (window);
- e_shell_set_line_status (shell, GNOME_Evolution_USER_OFFLINE);
-}
-
-static void
-command_work_online (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- EShell *shell;
-
- shell = e_shell_window_peek_shell (window);
- e_shell_set_line_status (shell, GNOME_Evolution_USER_ONLINE);
-}
-
-static void
-command_open_new_window (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_shell_create_window (e_shell_window_peek_shell (window),
- e_shell_window_peek_current_component_id (window),
- window);
-}
-
-/* Actions menu. */
-
-static void
-command_send_receive (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_shell_send_receive (e_shell_window_peek_shell (window));
-}
-
-static void
-command_forget_passwords (BonoboUIComponent *ui_component,
- gpointer data,
- const gchar *path)
-{
- if (e_error_run (NULL, "shell:forget-passwords", NULL) == GTK_RESPONSE_OK)
- e_passwords_forget_passwords();
-}
-
-/* Tools menu. */
-
-static void
-command_settings (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- e_shell_window_show_settings (window);
-}
-
-static void
-command_pilot_settings (BonoboUIComponent *uih,
- EShellWindow *window,
- const gchar *path)
-{
- launch_pilot_settings ();
-}
-
-static BonoboUIVerb file_verbs [] = {
- BONOBO_UI_VERB ("FileImporter", (BonoboUIVerbFn) command_import),
- BONOBO_UI_VERB ("FilePageSetup", (BonoboUIVerbFn) command_page_setup),
- BONOBO_UI_VERB ("FileClose", (BonoboUIVerbFn) command_close),
- BONOBO_UI_VERB ("FileExit", (BonoboUIVerbFn) command_quit),
-
- BONOBO_UI_VERB ("WorkOffline", (BonoboUIVerbFn) command_work_offline),
- BONOBO_UI_VERB ("WorkOnline", (BonoboUIVerbFn) command_work_online),
-
- BONOBO_UI_VERB_END
-};
-
-static BonoboUIVerb new_verbs [] = {
- BONOBO_UI_VERB ("OpenNewWindow", (BonoboUIVerbFn) command_open_new_window),
-
- BONOBO_UI_VERB_END
-};
-
-static BonoboUIVerb actions_verbs[] = {
- BONOBO_UI_VERB ("SendReceive", (BonoboUIVerbFn) command_send_receive),
- BONOBO_UI_VERB ("ForgetPasswords", command_forget_passwords),
-
- BONOBO_UI_VERB_END
-};
-
-static BonoboUIVerb tools_verbs[] = {
- BONOBO_UI_VERB ("Settings", (BonoboUIVerbFn) command_settings),
- BONOBO_UI_VERB ("PilotSettings", (BonoboUIVerbFn) command_pilot_settings),
-
- BONOBO_UI_VERB_END
-};
-
-static BonoboUIVerb help_verbs [] = {
- BONOBO_UI_VERB ("QuickReference", (BonoboUIVerbFn) command_quick_reference),
- BONOBO_UI_VERB ("HelpOpenFAQ", (BonoboUIVerbFn) command_open_faq),
- BONOBO_UI_VERB ("HelpSubmitBug", (BonoboUIVerbFn) command_submit_bug),
- BONOBO_UI_VERB ("HelpAbout", (BonoboUIVerbFn) command_about),
-
- BONOBO_UI_VERB_END
-};
-
-static EPixmap pixmaps [] = {
- E_PIXMAP ("/Toolbar/SendReceive", "mail-send-receive", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/menu/File/OpenNewWindow", "window-new", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/SendReceive", "mail-send-receive", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/FileImporter", "stock_mail-import", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/Print/FilePageSetup", "stock_print-setup", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/ToggleOffline", "stock_disconnect", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/FileClose", "window-close", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/File/FileExit", "application-exit", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/Edit/Settings", "preferences-desktop", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/menu/Help/HelpOpenFAQ", "help-faq", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP_END
-};
-
-static EPixmap offline_pixmaps [] = {
- E_PIXMAP ("/menu/File/ToggleOffline", "stock_disconnect", GTK_ICON_SIZE_MENU),
- E_PIXMAP_END
-};
-
-static EPixmap online_pixmaps [] = {
- E_PIXMAP ("/menu/File/ToggleOffline", "stock_connect", GTK_ICON_SIZE_MENU),
- E_PIXMAP_END
-};
-
-/* The Work Online / Work Offline menu item. */
-
-static void
-update_offline_menu_item (EShellWindow *shell_window,
- EShellLineStatus line_status)
-{
- BonoboUIComponent *ui_component;
-
- ui_component = e_shell_window_peek_bonobo_ui_component (shell_window);
-
- switch (line_status) {
- case E_SHELL_LINE_STATUS_OFFLINE:
- case E_SHELL_LINE_STATUS_FORCED_OFFLINE:
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "label", _("_Work Online"), NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "verb", "WorkOnline", NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/commands/ToggleOffline",
- "sensitive", "1", NULL);
- e_pixmaps_update (ui_component, online_pixmaps);
- break;
-
- case E_SHELL_LINE_STATUS_ONLINE:
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "label", _("_Work Offline"), NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "verb", "WorkOffline", NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/commands/ToggleOffline",
- "sensitive", "1", NULL);
- e_pixmaps_update (ui_component, offline_pixmaps);
- break;
-
- case E_SHELL_LINE_STATUS_GOING_OFFLINE:
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "label", _("Work Offline"), NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/menu/File/ToggleOffline",
- "verb", "WorkOffline", NULL);
- bonobo_ui_component_set_prop (ui_component,
- "/commands/ToggleOffline",
- "sensitive", "0", NULL);
- e_pixmaps_update (ui_component, offline_pixmaps);
- break;
-
- default:
- g_return_if_reached();
- }
-}
-
-static void
-shell_line_status_changed_cb (EShell *shell,
- EShellLineStatus new_status,
- EShellWindow *shell_window)
-{
- update_offline_menu_item (shell_window, new_status);
-}
-
-static void
-view_buttons_icontext_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
- e_sidebar_set_mode (sidebar, E_SIDEBAR_MODE_BOTH);
-}
-
-static void
-view_buttons_icon_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
- e_sidebar_set_mode (sidebar, E_SIDEBAR_MODE_ICON);
-}
-
-static void
-view_buttons_text_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
- e_sidebar_set_mode (sidebar, E_SIDEBAR_MODE_TEXT);
-}
-
-static void
-view_buttons_toolbar_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
- e_sidebar_set_mode (sidebar, E_SIDEBAR_MODE_TOOLBAR);
-}
-
-static void
-view_buttons_hide_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- ESidebar *sidebar;
- gboolean is_visible;
-
- sidebar = e_shell_window_peek_sidebar (shell_window);
-
- is_visible = state[0] == '0';
-
- e_sidebar_set_show_buttons (sidebar, is_visible);
-}
-
-static void
-view_toolbar_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- gboolean is_visible;
-
- is_visible = state[0] == '1';
-
- bonobo_ui_component_set_prop (ui_component, "/Toolbar",
- "hidden", is_visible ? "0" : "1", NULL);
-}
-
-static void
-view_statusbar_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- GtkWidget *status_bar = e_shell_window_peek_statusbar (shell_window);
- gboolean is_visible;
- GConfClient *gconf_client;
-
- is_visible = state[0] == '1';
- if (is_visible)
- gtk_widget_show (status_bar);
- else
- gtk_widget_hide (status_bar);
- gconf_client = gconf_client_get_default ();
- gconf_client_set_bool (gconf_client,"/apps/evolution/shell/view_defaults/statusbar_visible", is_visible, NULL);
- g_object_unref (gconf_client);
-}
-
-static void
-view_sidebar_item_toggled_handler (BonoboUIComponent *ui_component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- EShellWindow *shell_window)
-{
- GtkWidget *side_bar = GTK_WIDGET(e_shell_window_peek_sidebar (shell_window));
- gboolean is_visible;
- GConfClient *gconf_client;
-
- is_visible = state[0] == '1';
- if (is_visible)
- gtk_widget_show (side_bar);
- else
- gtk_widget_hide (side_bar);
- gconf_client = gconf_client_get_default ();
- gconf_client_set_bool (gconf_client_get_default (),"/apps/evolution/shell/view_defaults/sidebar_visible", is_visible, NULL);
- g_object_unref (gconf_client);
-}
-
-/* Public API. */
-
-void
-e_shell_window_commands_setup (EShellWindow *shell_window)
-{
- BonoboUIComponent *uic;
- EShell *shell;
-
- g_return_if_fail (shell_window != NULL);
- g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
-
- uic = e_shell_window_peek_bonobo_ui_component (shell_window);
- shell = e_shell_window_peek_shell (shell_window);
-
- bonobo_ui_component_add_verb_list_with_data (uic, file_verbs, shell_window);
- bonobo_ui_component_add_verb_list_with_data (uic, new_verbs, shell_window);
- bonobo_ui_component_add_verb_list_with_data (uic, actions_verbs, shell_window);
- bonobo_ui_component_add_verb_list_with_data (uic, tools_verbs, shell_window);
- bonobo_ui_component_add_verb_list_with_data (uic, help_verbs, shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsIconText",
- (BonoboUIListenerFn)view_buttons_icontext_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsIcon",
- (BonoboUIListenerFn)view_buttons_icon_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsText",
- (BonoboUIListenerFn)view_buttons_text_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsToolbar",
- (BonoboUIListenerFn)view_buttons_toolbar_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewButtonsHide",
- (BonoboUIListenerFn)view_buttons_hide_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewToolbar",
- (BonoboUIListenerFn)view_toolbar_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewStatusBar",
- (BonoboUIListenerFn)view_statusbar_item_toggled_handler,
- (gpointer)shell_window);
- bonobo_ui_component_add_listener (uic, "ViewSideBar",
- (BonoboUIListenerFn)view_sidebar_item_toggled_handler,
- (gpointer)shell_window);
-
- e_pixmaps_update (uic, pixmaps);
-
- /* Set up the work online / work offline menu item. */
- g_signal_connect_object (shell, "line_status_changed",
- G_CALLBACK (shell_line_status_changed_cb), shell_window, 0);
- update_offline_menu_item (shell_window, e_shell_get_line_status (shell));
-}
diff --git a/shell/e-shell-window-commands.h b/shell/e-shell-window-commands.h
deleted file mode 100644
index 0696a8a5d0..0000000000
--- a/shell/e-shell-window-commands.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_SHELL_WINDOW_COMMANDS_H_
-#define _E_SHELL_WINDOW_COMMANDS_H_
-
-#include "e-shell-window.h"
-
-void e_shell_window_commands_setup (EShellWindow *window);
-
-#endif /* _E_SHELL_WINDOW_COMMANDS_H_ */
diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c
new file mode 100644
index 0000000000..6ee997ddef
--- /dev/null
+++ b/shell/e-shell-window-private.c
@@ -0,0 +1,602 @@
+/*
+ * e-shell-window-private.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-shell-window-private.h"
+
+static void
+shell_window_save_switcher_style_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EShellWindow *shell_window)
+{
+ EShell *shell;
+ GConfClient *client;
+ GtkToolbarStyle style;
+ const gchar *key;
+ const gchar *string;
+ GError *error = NULL;
+
+ shell = e_shell_window_get_shell (shell_window);
+ client = e_shell_get_gconf_client (shell);
+
+ style = gtk_radio_action_get_current_value (action);
+ key = "/apps/evolution/shell/view_defaults/buttons_style";
+
+ switch (style) {
+ case GTK_TOOLBAR_ICONS:
+ string = "icons";
+ break;
+
+ case GTK_TOOLBAR_TEXT:
+ string = "text";
+ break;
+
+ case GTK_TOOLBAR_BOTH:
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ string = "both";
+ break;
+
+ default:
+ string = "toolbar";
+ break;
+ }
+
+ if (!gconf_client_set_string (client, key, string, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+shell_window_init_switcher_style (EShellWindow *shell_window)
+{
+ EShell *shell;
+ GtkAction *action;
+ GConfClient *client;
+ GtkToolbarStyle style;
+ const gchar *key;
+ gchar *string;
+ GError *error = NULL;
+
+ /* XXX GConfBridge doesn't let you convert between numeric properties
+ * and string keys, so we have to create the binding manually. */
+
+ shell = e_shell_window_get_shell (shell_window);
+ client = e_shell_get_gconf_client (shell);
+
+ action = ACTION (SWITCHER_STYLE_ICONS);
+ key = "/apps/evolution/shell/view_defaults/buttons_style";
+ string = gconf_client_get_string (client, key, &error);
+
+ if (string != NULL) {
+ if (strcmp (string, "icons") == 0)
+ style = GTK_TOOLBAR_ICONS;
+ else if (strcmp (string, "text") == 0)
+ style = GTK_TOOLBAR_TEXT;
+ else if (strcmp (string, "both") == 0)
+ style = GTK_TOOLBAR_BOTH_HORIZ;
+ else
+ style = -1;
+
+ gtk_radio_action_set_current_value (
+ GTK_RADIO_ACTION (action), style);
+ }
+
+ g_signal_connect (
+ action, "changed",
+ G_CALLBACK (shell_window_save_switcher_style_cb),
+ shell_window);
+}
+
+static void
+shell_window_menu_item_select_cb (EShellWindow *shell_window,
+ GtkWidget *menu_item)
+{
+ GtkAction *action;
+ GtkLabel *label;
+ gchar *tooltip = NULL;
+
+ action = g_object_get_data (G_OBJECT (menu_item), "action");
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ g_object_get (action, "tooltip", &tooltip, NULL);
+
+ if (tooltip == NULL)
+ return;
+
+ label = GTK_LABEL (shell_window->priv->tooltip_label);
+ gtk_label_set_text (label, tooltip);
+ g_free (tooltip);
+
+ gtk_widget_show (shell_window->priv->tooltip_label);
+ gtk_widget_hide (shell_window->priv->status_notebook);
+}
+
+static void
+shell_window_menu_item_deselect_cb (EShellWindow *shell_window)
+{
+ gtk_widget_hide (shell_window->priv->tooltip_label);
+ gtk_widget_show (shell_window->priv->status_notebook);
+}
+
+static void
+shell_window_connect_proxy_cb (EShellWindow *shell_window,
+ GtkAction *action,
+ GtkWidget *proxy)
+{
+ if (!GTK_IS_MENU_ITEM (proxy))
+ return;
+
+ g_object_set_data_full (
+ G_OBJECT (proxy),
+ "action", g_object_ref (action),
+ (GDestroyNotify) g_object_unref);
+
+ g_signal_connect_swapped (
+ proxy, "select",
+ G_CALLBACK (shell_window_menu_item_select_cb),
+ shell_window);
+
+ g_signal_connect_swapped (
+ proxy, "deselect",
+ G_CALLBACK (shell_window_menu_item_deselect_cb),
+ shell_window);
+}
+
+static void
+shell_window_online_button_clicked_cb (EOnlineButton *button,
+ EShellWindow *shell_window)
+{
+ if (e_online_button_get_online (button))
+ gtk_action_activate (ACTION (WORK_OFFLINE));
+ else
+ gtk_action_activate (ACTION (WORK_ONLINE));
+}
+
+void
+e_shell_window_private_init (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv = shell_window->priv;
+ GHashTable *loaded_views;
+ GArray *signal_handler_ids;
+ GtkAccelGroup *accel_group;
+ GtkToolItem *item;
+ GtkWidget *container;
+ GtkWidget *widget;
+ guint merge_id;
+ gint height;
+
+ loaded_views = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ signal_handler_ids = g_array_new (FALSE, FALSE, sizeof (gulong));
+
+ priv->ui_manager = gtk_ui_manager_new ();
+ priv->loaded_views = loaded_views;
+ priv->active_view = "unknown";
+ priv->signal_handler_ids = signal_handler_ids;
+
+ e_shell_window_add_action_group (shell_window, "shell");
+ e_shell_window_add_action_group (shell_window, "gal-view");
+ e_shell_window_add_action_group (shell_window, "new-item");
+ e_shell_window_add_action_group (shell_window, "new-source");
+ e_shell_window_add_action_group (shell_window, "custom-rules");
+ e_shell_window_add_action_group (shell_window, "switcher");
+ e_shell_window_add_action_group (shell_window, "lockdown-application-handlers");
+ e_shell_window_add_action_group (shell_window, "lockdown-printing");
+ e_shell_window_add_action_group (shell_window, "lockdown-print-setup");
+ e_shell_window_add_action_group (shell_window, "lockdown-save-to-disk");
+
+ merge_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
+ priv->custom_rule_merge_id = merge_id;
+
+ merge_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
+ priv->gal_view_merge_id = merge_id;
+
+ gtk_window_set_title (GTK_WINDOW (shell_window), _("Evolution"));
+
+ e_shell_window_actions_init (shell_window);
+
+ accel_group = gtk_ui_manager_get_accel_group (priv->ui_manager);
+ gtk_window_add_accel_group (GTK_WINDOW (shell_window), accel_group);
+
+ g_signal_connect_swapped (
+ priv->ui_manager, "connect-proxy",
+ G_CALLBACK (shell_window_connect_proxy_cb), shell_window);
+
+ /* Construct window widgets. */
+
+ widget = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (shell_window), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_shell_window_get_managed_widget (
+ shell_window, "/main-menu");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->main_menu = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = e_shell_window_get_managed_widget (
+ shell_window, "/main-toolbar");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->main_toolbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* XXX Having this separator in the UI definition doesn't work
+ * because GtkUIManager is unaware of the "New" button, so
+ * it makes the separator invisible. One possibility is to
+ * define a GtkAction subclass for which create_tool_item()
+ * returns an EMenuToolButton. Then both this separator
+ * and the "New" button could be added to the UI definition.
+ * Tempting, but the "New" button and its dynamically
+ * generated menu is already a complex beast, and I'm not
+ * convinced having it proxy some new type of GtkAction
+ * is worth the extra effort. */
+ item = gtk_separator_tool_item_new ();
+ gtk_toolbar_insert (GTK_TOOLBAR (widget), item, 0);
+ gtk_widget_show (GTK_WIDGET (item));
+
+ item = e_menu_tool_button_new (_("New"));
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
+ gtk_widget_add_accelerator (
+ GTK_WIDGET (item), "clicked",
+ gtk_ui_manager_get_accel_group (priv->ui_manager),
+ GDK_N, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+ gtk_toolbar_insert (GTK_TOOLBAR (widget), item, 0);
+ priv->menu_tool_button = g_object_ref (item);
+ gtk_widget_show (GTK_WIDGET (item));
+
+ widget = gtk_hpaned_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->content_pane = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->status_area = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Make the status area as large as the task bar. */
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
+ gtk_widget_set_size_request (widget, -1, (height * 2) + 6);
+
+ container = priv->content_pane;
+
+ widget = e_shell_switcher_new ();
+ gtk_paned_pack1 (GTK_PANED (container), widget, FALSE, FALSE);
+ priv->switcher = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, FALSE);
+ priv->content_notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = priv->switcher;
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ priv->sidebar_notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = priv->status_area;
+
+ widget = e_online_button_new ();
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (shell_window_online_button_clicked_cb),
+ shell_window);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
+ priv->online_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->tooltip_label = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->status_notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+}
+
+void
+e_shell_window_private_constructed (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv = shell_window->priv;
+ EShellSettings *shell_settings;
+ EShell *shell;
+ GConfBridge *bridge;
+ GtkAction *action;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ GObject *object;
+ const gchar *key;
+ const gchar *id;
+
+ shell = e_shell_window_get_shell (shell_window);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ e_shell_watch_window (shell, GTK_WINDOW (shell_window));
+
+ /* Create the switcher actions before we set the initial
+ * shell view, because the shell view relies on them for
+ * default settings during construction. */
+ e_shell_window_create_switcher_actions (shell_window);
+
+ /* Support lockdown. */
+
+ action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-printing",
+ G_OBJECT (action_group), "sensitive");
+
+ action_group = ACTION_GROUP (LOCKDOWN_PRINT_SETUP);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-print-setup",
+ G_OBJECT (action_group), "sensitive");
+
+ action_group = ACTION_GROUP (LOCKDOWN_SAVE_TO_DISK);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell_settings), "disable-save-to-disk",
+ G_OBJECT (action_group), "sensitive");
+
+ /* Bind GObject properties to GObject properties. */
+
+ action = ACTION (SEND_RECEIVE);
+
+ e_binding_new (
+ G_OBJECT (shell), "online",
+ G_OBJECT (action), "sensitive");
+
+ action = ACTION (WORK_OFFLINE);
+
+ e_binding_new (
+ G_OBJECT (shell), "online",
+ G_OBJECT (action), "visible");
+
+ e_binding_new (
+ G_OBJECT (shell), "network-available",
+ G_OBJECT (action), "sensitive");
+
+ action = ACTION (WORK_ONLINE);
+
+ e_binding_new_with_negation (
+ G_OBJECT (shell), "online",
+ G_OBJECT (action), "visible");
+
+ e_binding_new (
+ G_OBJECT (shell), "network-available",
+ G_OBJECT (action), "sensitive");
+
+ e_binding_new (
+ G_OBJECT (shell), "online",
+ G_OBJECT (priv->online_button), "online");
+
+ e_binding_new (
+ G_OBJECT (shell), "network-available",
+ G_OBJECT (priv->online_button), "sensitive");
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ key = "/apps/evolution/shell/view_defaults/window";
+ gconf_bridge_bind_window (
+ bridge, key, GTK_WINDOW (shell_window), TRUE, TRUE);
+
+ object = G_OBJECT (shell_window);
+ key = "/apps/evolution/shell/view_defaults/component_id";
+ gconf_bridge_bind_property (bridge, key, object, "active-view");
+
+ object = G_OBJECT (priv->content_pane);
+ key = "/apps/evolution/shell/view_defaults/folder_bar/width";
+ gconf_bridge_bind_property_delayed (bridge, key, object, "position");
+
+ object = G_OBJECT (ACTION (SHOW_SIDEBAR));
+ key = "/apps/evolution/shell/view_defaults/sidebar_visible";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (SHOW_STATUSBAR));
+ key = "/apps/evolution/shell/view_defaults/statusbar_visible";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (SHOW_SWITCHER));
+ key = "/apps/evolution/shell/view_defaults/buttons_visible";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ object = G_OBJECT (ACTION (SHOW_TOOLBAR));
+ key = "/apps/evolution/shell/view_defaults/toolbar_visible";
+ gconf_bridge_bind_property (bridge, key, object, "active");
+
+ shell_window_init_switcher_style (shell_window);
+
+ id = "org.gnome.evolution.shell";
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ e_plugin_ui_register_manager (ui_manager, id, shell_window);
+ e_plugin_ui_enable_manager (ui_manager, id);
+}
+
+void
+e_shell_window_private_dispose (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv = shell_window->priv;
+
+ /* Need to disconnect handlers before we unref the shell. */
+ if (priv->signal_handler_ids != NULL) {
+ GArray *array = priv->signal_handler_ids;
+ gulong handler_id;
+ guint ii;
+
+ for (ii = 0; ii < array->len; ii++) {
+ handler_id = g_array_index (array, gulong, ii);
+ g_signal_handler_disconnect (priv->shell, handler_id);
+ }
+
+ g_array_free (array, TRUE);
+ priv->signal_handler_ids = NULL;
+ }
+
+ if (priv->shell != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell), &priv->shell);
+ priv->shell = NULL;
+ }
+
+ DISPOSE (priv->ui_manager);
+
+ g_hash_table_remove_all (priv->loaded_views);
+
+ DISPOSE (priv->main_menu);
+ DISPOSE (priv->main_toolbar);
+ DISPOSE (priv->menu_tool_button);
+ DISPOSE (priv->content_pane);
+ DISPOSE (priv->content_notebook);
+ DISPOSE (priv->sidebar_notebook);
+ DISPOSE (priv->switcher);
+ DISPOSE (priv->status_area);
+ DISPOSE (priv->online_button);
+ DISPOSE (priv->tooltip_label);
+ DISPOSE (priv->status_notebook);
+
+ priv->destroyed = TRUE;
+}
+
+void
+e_shell_window_private_finalize (EShellWindow *shell_window)
+{
+ EShellWindowPrivate *priv = shell_window->priv;
+
+ g_hash_table_destroy (priv->loaded_views);
+}
+
+void
+e_shell_window_switch_to_view (EShellWindow *shell_window,
+ const gchar *view_name)
+{
+ GtkNotebook *notebook;
+ EShellView *shell_view;
+ gint page_num;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (view_name != NULL);
+
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+
+ page_num = e_shell_view_get_page_num (shell_view);
+ g_return_if_fail (page_num >= 0);
+
+ notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
+ gtk_notebook_set_current_page (notebook, page_num);
+
+ notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook);
+ gtk_notebook_set_current_page (notebook, page_num);
+
+ notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook);
+ gtk_notebook_set_current_page (notebook, page_num);
+
+ shell_window->priv->active_view = view_name;
+ g_object_notify (G_OBJECT (shell_window), "active-view");
+
+ e_shell_window_update_icon (shell_window);
+ e_shell_window_update_title (shell_window);
+ e_shell_window_update_new_menu (shell_window);
+ e_shell_window_update_view_menu (shell_window);
+ e_shell_window_update_search_menu (shell_window);
+
+ e_shell_view_update_actions (shell_view);
+}
+
+void
+e_shell_window_update_icon (EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ GtkAction *action;
+ const gchar *view_name;
+ gchar *icon_name = NULL;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+
+ action = e_shell_view_get_action (shell_view);
+ g_object_get (action, "icon-name", &icon_name, NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (shell_window), icon_name);
+ g_free (icon_name);
+}
+
+void
+e_shell_window_update_title (EShellWindow *shell_window)
+{
+ EShellView *shell_view;
+ const gchar *view_title;
+ const gchar *view_name;
+ gchar *window_title;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ view_name = e_shell_window_get_active_view (shell_window);
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ view_title = e_shell_view_get_title (shell_view);
+
+ /* Translators: This is used for the main window title. */
+ window_title = g_strdup_printf (_("%s - Evolution"), view_title);
+ gtk_window_set_title (GTK_WINDOW (shell_window), window_title);
+ g_free (window_title);
+}
+
+void
+e_shell_window_update_new_menu (EShellWindow *shell_window)
+{
+ GtkWidget *menu;
+ GtkWidget *widget;
+ const gchar *path;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+ /* Update the "File -> New" submenu. */
+ path = "/main-menu/file-menu/new-menu";
+ menu = e_shell_window_create_new_menu (shell_window);
+ widget = e_shell_window_get_managed_widget (shell_window, path);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
+ gtk_widget_show (widget);
+
+ /* Update the "New" menu tool button submenu. */
+ menu = e_shell_window_create_new_menu (shell_window);
+ widget = shell_window->priv->menu_tool_button;
+ gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (widget), menu);
+}
diff --git a/shell/e-shell-window-private.h b/shell/e-shell-window-private.h
new file mode 100644
index 0000000000..5314a3679f
--- /dev/null
+++ b/shell/e-shell-window-private.h
@@ -0,0 +1,128 @@
+/*
+ * e-shell-window-private.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SHELL_WINDOW_PRIVATE_H
+#define E_SHELL_WINDOW_PRIVATE_H
+
+#include "e-shell-window.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <e-util/e-util.h>
+#include <e-util/e-binding.h>
+#include <e-util/e-plugin-ui.h>
+#include <e-util/gconf-bridge.h>
+#include <widgets/misc/e-menu-tool-button.h>
+#include <widgets/misc/e-online-button.h>
+
+#include <e-shell.h>
+#include <e-shell-content.h>
+#include <e-shell-view.h>
+#include <e-shell-switcher.h>
+#include <e-shell-window-actions.h>
+
+#define E_SHELL_WINDOW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL_WINDOW, EShellWindowPrivate))
+
+/* Shorthand, requires a variable named "shell_window". */
+#define ACTION(name) \
+ (E_SHELL_WINDOW_ACTION_##name (shell_window))
+#define ACTION_GROUP(name) \
+ (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window))
+
+/* For use in dispose() methods. */
+#define DISPOSE(obj) \
+ G_STMT_START { \
+ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \
+ } G_STMT_END
+
+/* Format for switcher action names.
+ * The last part is the shell view name.
+ * (e.g. switch-to-mail, switch-to-calendar) */
+#define SWITCHER_FORMAT "switch-to-%s"
+
+G_BEGIN_DECLS
+
+struct _EShellWindowPrivate {
+
+ gpointer shell; /* weak pointer */
+
+ /*** UI Management ***/
+
+ GtkUIManager *ui_manager;
+ guint custom_rule_merge_id;
+ guint gal_view_merge_id;
+
+ /*** Shell Views ***/
+
+ GHashTable *loaded_views;
+ const gchar *active_view;
+
+ /*** Widgetry ***/
+
+ GtkWidget *main_menu;
+ GtkWidget *main_toolbar;
+ GtkWidget *menu_tool_button;
+ GtkWidget *content_pane;
+ GtkWidget *content_notebook;
+ GtkWidget *sidebar_notebook;
+ GtkWidget *switcher;
+ GtkWidget *status_area;
+ GtkWidget *online_button;
+ GtkWidget *tooltip_label;
+ GtkWidget *status_notebook;
+
+ /* Miscellaneous */
+
+ /* Shell signal handlers. */
+ GArray *signal_handler_ids;
+
+ guint destroyed : 1; /* XXX Do we still need this? */
+ guint safe_mode : 1;
+};
+
+void e_shell_window_private_init (EShellWindow *shell_window);
+void e_shell_window_private_constructed
+ (EShellWindow *shell_window);
+void e_shell_window_private_dispose (EShellWindow *shell_window);
+void e_shell_window_private_finalize (EShellWindow *shell_window);
+
+/* Private Utilities */
+
+void e_shell_window_actions_init (EShellWindow *shell_window);
+void e_shell_window_switch_to_view (EShellWindow *shell_window,
+ const gchar *view_name);
+GtkWidget * e_shell_window_create_new_menu (EShellWindow *shell_window);
+void e_shell_window_create_switcher_actions
+ (EShellWindow *shell_window);
+void e_shell_window_update_gal_view (EShellWindow *shell_window);
+void e_shell_window_update_icon (EShellWindow *shell_window);
+void e_shell_window_update_title (EShellWindow *shell_window);
+void e_shell_window_update_new_menu (EShellWindow *shell_window);
+void e_shell_window_update_view_menu (EShellWindow *shell_window);
+void e_shell_window_update_search_menu
+ (EShellWindow *shell_window);
+
+G_END_DECLS
+
+#endif /* E_SHELL_WINDOW_PRIVATE_H */
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index 69980dc5c5..19392094ee 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -1,4 +1,6 @@
/*
+ * e-shell-window.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,1248 +15,859 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-shell-window.h"
-#include "e-shell-view.h"
-
-#include "Evolution.h"
-
-#include "e-util/e-util-private.h"
-#include "widgets/misc/e-online-button.h"
-
-#include "e-component-registry.h"
-#include "e-shell-window-commands.h"
-#include "e-sidebar.h"
-#include "es-menu.h"
-#include "es-event.h"
-
-#include <gtk/gtk.h>
-
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-widget.h>
-
-#include <glib/gi18n.h>
+#include "e-shell-window-private.h"
#include <gconf/gconf-client.h>
-#include <string.h>
+#include <e-util/e-plugin-ui.h>
+#include <e-util/e-util-private.h>
-#if defined(NM_SUPPORT) && NM_SUPPORT
-gboolean e_shell_dbus_initialise (EShell *shell);
-#endif
-
-/* A view for each component. These are all created when EShellWindow is
- instantiated, but with the widget pointers to NULL and the page number set
- to -1. When the views are created the first time, the widget pointers as
- well as the notebook page value get set. */
-struct _ComponentView {
- gint button_id;
- gchar *component_id;
- gchar *component_alias;
-
- GNOME_Evolution_ComponentView component_view;
- gchar *title;
-
- GtkWidget *sidebar_widget;
- GtkWidget *view_widget;
- GtkWidget *statusbar_widget;
-
- gint notebook_page_num;
+enum {
+ PROP_0,
+ PROP_ACTIVE_VIEW,
+ PROP_SAFE_MODE,
+ PROP_SHELL,
+ PROP_UI_MANAGER
};
-typedef struct _ComponentView ComponentView;
-
-struct _EShellWindowPrivate {
- union {
- EShell *eshell;
- gpointer pointer;
- } shell;
-
- EShellView *shell_view; /* CORBA wrapper for this, just a placeholder */
-
- /* plugin menu manager */
- ESMenu *menu;
- /* All the ComponentViews. */
- GSList *component_views;
+static gpointer parent_class;
- /* The paned widget for the sidebar and component views */
- GtkWidget *paned;
-
- /* The sidebar. */
- GtkWidget *sidebar;
-
- /* Notebooks used to switch between components. */
- GtkWidget *sidebar_notebook;
- GtkWidget *view_notebook;
- GtkWidget *statusbar_notebook;
-
- /* Bonobo foo. */
- BonoboUIComponent *ui_component;
-
- /* The current view (can be NULL initially). */
- ComponentView *current_view;
-
- /* The status bar widgetry. */
- GtkWidget *status_bar;
- GtkWidget *offline_toggle;
- GtkWidget *menu_hint_label;
+static EShellView *
+shell_window_new_view (EShellBackend *shell_backend,
+ EShellWindow *shell_window)
+{
+ GHashTable *loaded_views;
+ EShellView *shell_view;
+ GtkNotebook *notebook;
+ GtkAction *action;
+ GtkWidget *widget;
+ const gchar *name;
+ gint page_num;
+ GType type;
- /* The timeout for saving the window size */
- guint store_window_gsizeimer;
- gboolean destroyed;
-};
+ name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+ type = E_SHELL_BACKEND_GET_CLASS (shell_backend)->shell_view_type;
-enum {
- COMPONENT_CHANGED,
- LAST_SIGNAL
-};
+ /* First off, start the shell backend. */
+ e_shell_backend_start (shell_backend);
-static guint signals[LAST_SIGNAL] = { 0 };
+ /* Determine the page number for the new shell view. */
+ notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
+ page_num = gtk_notebook_get_n_pages (notebook);
-G_DEFINE_TYPE (EShellWindow, e_shell_window, BONOBO_TYPE_WINDOW)
+ /* Get the switcher action for this view. */
+ action = e_shell_window_get_shell_view_action (shell_window, name);
-static gboolean store_window_size (GtkWidget* widget);
+ /* Create the shell view. */
+ shell_view = g_object_new (
+ type, "action", action, "page-num",page_num,
+ "shell-window", shell_window, NULL);
-/* ComponentView handling. */
+ /* Register the shell view. */
+ loaded_views = shell_window->priv->loaded_views;
+ g_hash_table_insert (loaded_views, g_strdup (name), shell_view);
-static ComponentView *
-component_view_new (const gchar *id, const gchar *alias, gint button_id)
-{
- ComponentView *view = g_new0 (ComponentView, 1);
+ /* Add pages to the various shell window notebooks. */
- view->component_id = g_strdup (id);
- view->component_alias = g_strdup (alias);
- view->button_id = button_id;
- view->notebook_page_num = -1;
+ /* We can't determine the shell view's page number until after the
+ * shell view is fully initialized because the shell view may load
+ * other shell views during initialization, and those other shell
+ * views will append their widgets to the notebooks before us. */
+ page_num = gtk_notebook_get_n_pages (notebook);
+ e_shell_view_set_page_num (shell_view, page_num);
- return view;
-}
+ notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
+ widget = GTK_WIDGET (e_shell_view_get_shell_content (shell_view));
+ gtk_notebook_append_page (notebook, widget, NULL);
-static void
-component_view_free (ComponentView *view)
-{
- if (view->component_view) {
- CORBA_Environment ev = { NULL };
+ notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook);
+ widget = GTK_WIDGET (e_shell_view_get_shell_sidebar (shell_view));
+ gtk_notebook_append_page (notebook, widget, NULL);
- CORBA_Object_release(view->component_view, &ev);
- CORBA_exception_free(&ev);
- }
+ notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook);
+ widget = GTK_WIDGET (e_shell_view_get_shell_taskbar (shell_view));
+ gtk_notebook_append_page (notebook, widget, NULL);
- g_free (view->component_id);
- g_free (view->component_alias);
- g_free (view->title);
- g_free (view);
-}
+ /* Listen for changes that affect the shell window. */
-static void
-component_view_deactivate (ComponentView *view)
-{
- BonoboControlFrame *view_control_frame;
- BonoboControlFrame *sidebar_control_frame;
+ g_signal_connect_swapped (
+ action, "notify::icon-name",
+ G_CALLBACK (e_shell_window_update_icon), shell_window);
- g_return_if_fail (view->sidebar_widget != NULL);
- g_return_if_fail (view->view_widget != NULL);
+ g_signal_connect_swapped (
+ shell_view, "notify::title",
+ G_CALLBACK (e_shell_window_update_title), shell_window);
- view_control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (view->view_widget));
- bonobo_control_frame_control_deactivate (view_control_frame);
+ g_signal_connect_swapped (
+ shell_view, "notify::view-id",
+ G_CALLBACK (e_shell_window_update_view_menu), shell_window);
- sidebar_control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (view->sidebar_widget));
- bonobo_control_frame_control_deactivate (sidebar_control_frame);
+ return shell_view;
}
static void
-component_view_activate (ComponentView *view)
+shell_window_update_close_action_cb (EShellWindow *shell_window)
{
- BonoboControlFrame *view_control_frame;
- BonoboControlFrame *sidebar_control_frame;
+ EShell *shell;
+ GList *watched_windows;
+ gint n_shell_windows = 0;
- g_return_if_fail (view->sidebar_widget != NULL);
- g_return_if_fail (view->view_widget != NULL);
+ shell = e_shell_window_get_shell (shell_window);
+ watched_windows = e_shell_get_watched_windows (shell);
- view_control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (view->view_widget));
- bonobo_control_frame_control_activate (view_control_frame);
+ /* Count the shell windows. */
+ while (watched_windows != NULL) {
+ if (E_IS_SHELL_WINDOW (watched_windows->data))
+ n_shell_windows++;
+ watched_windows = g_list_next (watched_windows);
+ }
- sidebar_control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (view->sidebar_widget));
- bonobo_control_frame_control_activate (sidebar_control_frame);
+ /* Disable Close Window if there's only one shell window.
+ * Helps prevent users from accidentally quitting. */
+ gtk_action_set_sensitive (ACTION (CLOSE), n_shell_windows > 1);
}
static void
-init_view (EShellWindow *window,
- ComponentView *view)
+shell_window_set_shell (EShellWindow *shell_window,
+ EShell *shell)
{
- EShellWindowPrivate *priv = window->priv;
- EComponentRegistry *registry = e_shell_peek_component_registry (window->priv->shell.eshell);
- GNOME_Evolution_Component component_iface;
- GNOME_Evolution_ComponentView component_view;
- Bonobo_UIContainer container;
- Bonobo_Control sidebar_control;
- Bonobo_Control view_control;
- Bonobo_Control statusbar_control;
- CORBA_boolean select_item;
- CORBA_Environment ev;
- gint sidebar_notebook_page_num;
- gint view_notebook_page_num;
-
- g_return_if_fail (view->view_widget == NULL);
- g_return_if_fail (view->sidebar_widget == NULL);
- g_return_if_fail (view->notebook_page_num == -1);
-
- select_item = !e_shell_get_crash_recovery (priv->shell.eshell);
- e_shell_set_crash_recovery (priv->shell.eshell, FALSE);
-
- CORBA_exception_init (&ev);
-
- /* 1. Activate component. (FIXME: Shouldn't do this here.) */
-
- component_iface = e_component_registry_activate (registry, view->component_id, &ev);
- if (BONOBO_EX (&ev) || component_iface == CORBA_OBJECT_NIL) {
- gchar *ex_text = bonobo_exception_get_text (&ev);
- g_warning ("Cannot activate component %s: %s", view->component_id, ex_text);
- g_free (ex_text);
- CORBA_exception_free (&ev);
- return;
- }
-
- /* 2. Set up view. */
-
- /* The rest of the code assumes that the component is valid and can create
- controls; if this fails something is really wrong in the component
- (e.g. methods not implemented)... So handle it as if there was no
- component at all. */
-
- component_view = GNOME_Evolution_Component_createView(component_iface, BONOBO_OBJREF(priv->shell_view), select_item, &ev);
- if (component_view == NULL || BONOBO_EX (&ev)) {
- g_warning ("Cannot create view for %s", view->component_id);
- bonobo_object_release_unref (component_iface, NULL);
- CORBA_exception_free (&ev);
- return;
- }
-
- GNOME_Evolution_ComponentView_getControls(component_view, &sidebar_control, &view_control, &statusbar_control, &ev);
- if (BONOBO_EX (&ev)) {
- g_warning ("Cannot create view for %s", view->component_id);
- bonobo_object_release_unref (component_iface, NULL);
- CORBA_exception_free (&ev);
- return;
- }
-
- view->component_view = component_view;
-
- CORBA_exception_free (&ev);
+ GArray *array;
+ gulong handler_id;
- container = bonobo_ui_component_get_container (priv->ui_component);
+ g_return_if_fail (shell_window->priv->shell == NULL);
- view->sidebar_widget = bonobo_widget_new_control_from_objref (sidebar_control, container);
- gtk_widget_show (view->sidebar_widget);
- bonobo_object_release_unref (sidebar_control, NULL);
+ shell_window->priv->shell = shell;
- view->view_widget = bonobo_widget_new_control_from_objref (view_control, container);
- gtk_widget_show (view->view_widget);
- bonobo_object_release_unref (view_control, NULL);
+ g_object_add_weak_pointer (
+ G_OBJECT (shell), &shell_window->priv->shell);
- view->statusbar_widget = bonobo_widget_new_control_from_objref (statusbar_control, container);
- gtk_widget_show (view->statusbar_widget);
- bonobo_object_release_unref (statusbar_control, NULL);
+ /* Need to disconnect these when the window is closing. */
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->sidebar_notebook), view->sidebar_widget, NULL);
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->view_notebook), view->view_widget, NULL);
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->statusbar_notebook), view->statusbar_widget, NULL);
+ array = shell_window->priv->signal_handler_ids;
- sidebar_notebook_page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->sidebar_notebook), view->sidebar_widget);
- view_notebook_page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->view_notebook), view->view_widget);
+ handler_id = g_signal_connect_swapped (
+ shell, "window-created",
+ G_CALLBACK (shell_window_update_close_action_cb),
+ shell_window);
- /* Since we always add a view page and a sidebar page at the same time... */
- g_return_if_fail (sidebar_notebook_page_num == view_notebook_page_num);
+ g_array_append_val (array, handler_id);
- view->notebook_page_num = view_notebook_page_num;
+ handler_id = g_signal_connect_swapped (
+ shell, "window-destroyed",
+ G_CALLBACK (shell_window_update_close_action_cb),
+ shell_window);
- /* 3. Switch to the new page. */
+ g_array_append_val (array, handler_id);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->view_notebook), view_notebook_page_num);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->sidebar_notebook), view_notebook_page_num);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->statusbar_notebook), view_notebook_page_num);
-
- if (priv->current_view != NULL)
- component_view_deactivate (priv->current_view);
- priv->current_view = view;
- component_view_activate (view);
-
- bonobo_object_release_unref (component_iface, NULL);
+ g_object_notify (G_OBJECT (shell), "online");
}
static void
-switch_view (EShellWindow *window, ComponentView *component_view)
+shell_window_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- EShellWindowPrivate *priv = window->priv;
- GConfClient *gconf_client = gconf_client_get_default ();
- EComponentRegistry *registry = e_shell_peek_component_registry (window->priv->shell.eshell);
- EComponentInfo *info = e_component_registry_peek_info (registry,
- ECR_FIELD_ID,
- component_view->component_id);
- gchar *title;
-
- if (component_view->sidebar_widget == NULL) {
- init_view (window, component_view);
- } else {
- if (priv->current_view != NULL)
- component_view_deactivate (priv->current_view);
- priv->current_view = component_view;
- component_view_activate (component_view);
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->view_notebook), component_view->notebook_page_num);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->sidebar_notebook), component_view->notebook_page_num);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->statusbar_notebook), component_view->notebook_page_num);
- }
-
- if (component_view->title == NULL) {
- /* To translators: This is the window title and %s is the
- component name. Most translators will want to keep it as is. */
- title = g_strdup_printf (_("%s - Evolution"), info->button_label);
- gtk_window_set_title (GTK_WINDOW (window), title);
- g_free (title);
- } else
- gtk_window_set_title (GTK_WINDOW (window), component_view->title);
-
- if (info->icon_name)
- gtk_window_set_icon_name (GTK_WINDOW (window), info->icon_name);
-
- gconf_client_set_string (gconf_client, "/apps/evolution/shell/view_defaults/component_id",
- (component_view->component_alias != NULL
- ? component_view->component_alias
- : component_view->component_id),
- NULL);
-
- g_object_unref (gconf_client);
-
- /** @Event: Shell component activated or switched to.
- * @Id: component.activated
- * @Target: ESEventTargetComponent
- *
- * This event is emitted whenever the shell successfully activates component
- * view.
- */
- e_event_emit ((EEvent *) es_event_peek (), "component.activated", (EEventTarget *) es_event_target_new_component (es_event_peek (), component_view->component_id));
-
- g_signal_emit (window, signals[COMPONENT_CHANGED], 0);
-}
+ switch (property_id) {
+ case PROP_ACTIVE_VIEW:
+ e_shell_window_set_active_view (
+ E_SHELL_WINDOW (object),
+ g_value_get_string (value));
+ return;
-/* Functions to update the sensitivity of buttons and menu items depending on the status. */
+ case PROP_SAFE_MODE:
+ e_shell_window_set_safe_mode (
+ E_SHELL_WINDOW (object),
+ g_value_get_boolean (value));
+ return;
-static void
-update_offline_toggle_status (EShellWindow *window)
-{
- EShellWindowPrivate *priv;
- GtkWidget *widget;
- const gchar *tooltip;
- gboolean online;
- gboolean sensitive;
- guint32 flags = 0;
- ESMenuTargetShell *t;
-
- priv = window->priv;
-
- switch (e_shell_get_line_status (priv->shell.eshell)) {
- case E_SHELL_LINE_STATUS_ONLINE:
- online = TRUE;
- sensitive = TRUE;
- tooltip = _("Evolution is currently online.\n"
- "Click on this button to work offline.");
- flags = ES_MENU_SHELL_ONLINE;
- break;
- case E_SHELL_LINE_STATUS_GOING_OFFLINE:
- online = TRUE;
- sensitive = FALSE;
- tooltip = _("Evolution is in the process of going offline.");
- flags = ES_MENU_SHELL_OFFLINE;
- break;
- case E_SHELL_LINE_STATUS_OFFLINE:
- case E_SHELL_LINE_STATUS_FORCED_OFFLINE:
- online = FALSE;
- sensitive = TRUE;
- tooltip = _("Evolution is currently offline.\n"
- "Click on this button to work online.");
- flags = ES_MENU_SHELL_OFFLINE;
- break;
- default:
- g_return_if_reached ();
+ case PROP_SHELL:
+ shell_window_set_shell (
+ E_SHELL_WINDOW (object),
+ g_value_get_object (value));
+ return;
}
- widget = window->priv->offline_toggle;
- gtk_widget_set_sensitive (widget, sensitive);
- gtk_widget_set_tooltip_text (widget, tooltip);
- e_online_button_set_online (E_ONLINE_BUTTON (widget), online);
-
- /* TODO: If we get more shell flags, this should be centralised */
- t = es_menu_target_new_shell(priv->menu, flags);
- t->target.widget = (GtkWidget *)window;
- e_menu_update_target((EMenu *)priv->menu, t);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-update_send_receive_sensitivity (EShellWindow *window)
+shell_window_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- if (e_shell_get_line_status (window->priv->shell.eshell) == E_SHELL_LINE_STATUS_OFFLINE ||
- e_shell_get_line_status (window->priv->shell.eshell) == E_SHELL_LINE_STATUS_FORCED_OFFLINE)
- bonobo_ui_component_set_prop (window->priv->ui_component,
- "/commands/SendReceive",
- "sensitive", "0", NULL);
- else
- bonobo_ui_component_set_prop (window->priv->ui_component,
- "/commands/SendReceive",
- "sensitive", "1", NULL);
-}
+ switch (property_id) {
+ case PROP_ACTIVE_VIEW:
+ g_value_set_string (
+ value, e_shell_window_get_active_view (
+ E_SHELL_WINDOW (object)));
+ return;
-/* Callbacks. */
+ case PROP_SAFE_MODE:
+ g_value_set_boolean (
+ value, e_shell_window_get_safe_mode (
+ E_SHELL_WINDOW (object)));
+ return;
-static ComponentView *
-get_component_view (EShellWindow *window, gint id)
-{
- GSList *p;
+ case PROP_SHELL:
+ g_value_set_object (
+ value, e_shell_window_get_shell (
+ E_SHELL_WINDOW (object)));
+ return;
- for (p = window->priv->component_views; p; p = p->next) {
- if (((ComponentView *) p->data)->button_id == id)
- return p->data;
+ case PROP_UI_MANAGER:
+ g_value_set_object (
+ value, e_shell_window_get_ui_manager (
+ E_SHELL_WINDOW (object)));
+ return;
}
- g_warning ("Unknown component button id %d", id);
- return NULL;
-}
-
-static void
-sidebar_button_selected_callback (ESidebar *sidebar,
- gint button_id,
- EShellWindow *window)
-{
- ComponentView *component_view;
-
- if ((component_view = get_component_view (window, button_id)))
- switch_view (window, component_view);
-}
-
-static gboolean
-sidebar_button_pressed_callback (ESidebar *sidebar,
- GdkEventButton *event,
- gint button_id,
- EShellWindow *window)
-{
- if (event->type == GDK_BUTTON_PRESS &&
- event->button == 2) {
- /* open it in a new window */
- ComponentView *component_view;
-
- if ((component_view = get_component_view (window, button_id))) {
- e_shell_create_window (window->priv->shell.eshell,
- component_view->component_id,
- window);
- }
- return TRUE;
- }
- return FALSE;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-offline_toggle_clicked_cb (EShellWindow *window)
+shell_window_dispose (GObject *object)
{
- EShell *shell;
- GNOME_Evolution_ShellState shell_state;
-
- shell = window->priv->shell.eshell;
-
- switch (e_shell_get_line_status (shell)) {
- case E_SHELL_LINE_STATUS_ONLINE:
- shell_state = GNOME_Evolution_USER_OFFLINE;
- break;
- case E_SHELL_LINE_STATUS_OFFLINE:
- case E_SHELL_LINE_STATUS_FORCED_OFFLINE:
- shell_state = GNOME_Evolution_USER_ONLINE;
- break;
- default:
- g_return_if_reached();
- }
+ e_shell_window_private_dispose (E_SHELL_WINDOW (object));
- e_shell_set_line_status (shell, shell_state);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-shell_line_status_changed_callback (EShell *shell,
- EShellLineStatus new_status,
- EShellWindow *window)
+shell_window_finalize (GObject *object)
{
- update_offline_toggle_status (window);
- update_send_receive_sensitivity (window);
-}
+ e_shell_window_private_finalize (E_SHELL_WINDOW (object));
-static void
-ui_engine_add_hint_callback (BonoboUIEngine *engine,
- const gchar *hint,
- EShellWindow *window)
-{
- gtk_label_set_text (GTK_LABEL (window->priv->menu_hint_label), hint);
- gtk_widget_show (window->priv->menu_hint_label);
- gtk_widget_hide (window->priv->statusbar_notebook);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-ui_engine_remove_hint_callback (BonoboUIEngine *engine,
- EShellWindow *window)
+shell_window_constructed (GObject *object)
{
- gtk_widget_hide (window->priv->menu_hint_label);
- gtk_widget_show (window->priv->statusbar_notebook);
+ e_shell_window_private_constructed (E_SHELL_WINDOW (object));
}
-/* Widgetry. */
-
static void
-setup_offline_toggle (EShellWindow *window)
+shell_window_class_init (EShellWindowClass *class)
{
- GtkWidget *widget;
+ GObjectClass *object_class;
- g_return_if_fail (window->priv->status_bar != NULL);
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellWindowPrivate));
- widget = e_online_button_new ();
- g_signal_connect_swapped (
- widget, "clicked",
- G_CALLBACK (offline_toggle_clicked_cb), window);
- gtk_box_pack_start (
- GTK_BOX (window->priv->status_bar),
- widget, FALSE, TRUE, 0);
- window->priv->offline_toggle = widget;
- gtk_widget_show (widget);
-
- update_offline_toggle_status (window);
-}
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_window_set_property;
+ object_class->get_property = shell_window_get_property;
+ object_class->dispose = shell_window_dispose;
+ object_class->finalize = shell_window_finalize;
+ object_class->constructed = shell_window_constructed;
-static void
-setup_menu_hint_label (EShellWindow *window)
-{
- EShellWindowPrivate *priv;
-
- priv = window->priv;
-
- priv->menu_hint_label = gtk_label_new ("");
- gtk_misc_set_alignment (GTK_MISC (priv->menu_hint_label), 0.0, 0.5);
-
- gtk_box_pack_start (GTK_BOX (priv->status_bar), priv->menu_hint_label, TRUE, TRUE, 0);
+ /**
+ * EShellWindow:active-view
+ *
+ * Name of the active #EShellView.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTIVE_VIEW,
+ g_param_spec_string (
+ "active-view",
+ _("Active Shell View"),
+ _("Name of the active shell view"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * EShellWindow:safe-mode
+ *
+ * Whether the shell window is in safe mode.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SAFE_MODE,
+ g_param_spec_boolean (
+ "safe-mode",
+ _("Safe Mode"),
+ _("Whether the shell window is in safe mode"),
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShellWindow:shell
+ *
+ * The #EShell singleton.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ _("Shell"),
+ _("The EShell singleton"),
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * EShellWindow:ui-manager
+ *
+ * The shell window's #GtkUIManager.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_UI_MANAGER,
+ g_param_spec_object (
+ "ui-manager",
+ _("UI Manager"),
+ _("The shell window's GtkUIManager"),
+ GTK_TYPE_UI_MANAGER,
+ G_PARAM_READABLE));
}
static void
-setup_statusbar_notebook (EShellWindow *window)
+shell_window_init (EShellWindow *shell_window)
{
- EShellWindowPrivate *priv;
-
- priv = window->priv;
+ shell_window->priv = E_SHELL_WINDOW_GET_PRIVATE (shell_window);
- priv->statusbar_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->statusbar_notebook), FALSE);
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->statusbar_notebook), FALSE);
-
- gtk_box_pack_start (GTK_BOX (priv->status_bar), priv->statusbar_notebook, TRUE, TRUE, 0);
- gtk_widget_show (priv->statusbar_notebook);
-}
-
-static void
-setup_nm_support (EShellWindow *window)
-{
-#if defined(NM_SUPPORT) && NM_SUPPORT
- e_shell_dbus_initialise (window->priv->shell.eshell);
-#endif
+ e_shell_window_private_init (shell_window);
}
-static void
-setup_status_bar (EShellWindow *window)
+GType
+e_shell_window_get_type (void)
{
- EShellWindowPrivate *priv;
- BonoboUIEngine *ui_engine;
- GConfClient *gconf_client;
- gint height;
-
- priv = window->priv;
-
- priv->status_bar = gtk_hbox_new (FALSE, 2);
+ static GType type = 0;
- /* Make the status bar as large as the task bar. */
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
- gtk_widget_set_size_request (GTK_WIDGET (priv->status_bar), -1, height * 2);
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellWindowClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_window_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShellWindow),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_window_init,
+ NULL /* value_table */
+ };
- gconf_client = gconf_client_get_default ();
- if (gconf_client_get_bool (gconf_client,"/apps/evolution/shell/view_defaults/statusbar_visible",NULL))
- gtk_widget_show (priv->status_bar);
- g_object_unref (gconf_client);
-
- /* setup dbus interface here*/
- setup_nm_support (window);
-
- setup_offline_toggle (window);
- setup_menu_hint_label (window);
- setup_statusbar_notebook (window);
-
- ui_engine = bonobo_window_get_ui_engine (BONOBO_WINDOW (window));
+ type = g_type_register_static (
+ GTK_TYPE_WINDOW, "EShellWindow", &type_info, 0);
+ }
- g_signal_connect (ui_engine, "add_hint", G_CALLBACK (ui_engine_add_hint_callback), window);
- g_signal_connect (ui_engine, "remove_hint", G_CALLBACK (ui_engine_remove_hint_callback), window);
+ return type;
}
-static void
-menu_component_selected (BonoboUIComponent *uic,
- EShellWindow *window,
- const gchar *path)
+/**
+ * e_shell_window_new:
+ * @shell: an #EShell
+ * @safe_mode: whether to initialize the window to "safe mode"
+ *
+ * Returns a new #EShellWindow.
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means, but the #EShell usually puts the initial
+ * #EShellWindow into "safe mode" if detects the previous Evolution
+ * session crashed.
+ *
+ * The initial view for the window is determined by GConf key
+ * <filename>/apps/evolution/shell/view_defaults/component_id</filename>.
+ * Or, if the GConf key is not set or can't be read, the first view
+ * in the switcher is used.
+ *
+ * Returns: a new #EShellWindow
+ **/
+GtkWidget *
+e_shell_window_new (EShell *shell,
+ gboolean safe_mode)
{
- gchar *component_id;
-
- component_id = strchr(path, '-');
- if (component_id)
- e_shell_window_switch_to_component (window, component_id+1);
+ return g_object_new (
+ E_TYPE_SHELL_WINDOW,
+ "shell", shell, "safe-mode", safe_mode, NULL);
}
-static GConfEnumStringPair button_styles[] = {
- { E_SIDEBAR_MODE_TEXT, "text" },
- { E_SIDEBAR_MODE_ICON, "icons" },
- { E_SIDEBAR_MODE_BOTH, "both" },
- { E_SIDEBAR_MODE_TOOLBAR, "toolbar" },
- { -1, NULL }
-};
-
-static void
-setup_widgets (EShellWindow *window)
+/**
+ * e_shell_window_get_shell:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns the #EShell that was passed to e_shell_window_new().
+ *
+ * Returns: the #EShell
+ **/
+EShell *
+e_shell_window_get_shell (EShellWindow *shell_window)
{
- EShellWindowPrivate *priv = window->priv;
- EComponentRegistry *registry = e_shell_peek_component_registry (priv->shell.eshell);
- GConfClient *gconf_client = gconf_client_get_default ();
- GtkWidget *contents_vbox;
- GSList *p;
- GString *xml;
- gint button_id;
- gboolean visible;
- gchar *style;
- gint mode;
-
- priv->paned = gtk_hpaned_new ();
- gtk_widget_show (priv->paned);
-
- priv->sidebar = e_sidebar_new ();
- g_signal_connect (priv->sidebar, "button_selected",
- G_CALLBACK (sidebar_button_selected_callback), window);
- g_signal_connect (priv->sidebar, "button_pressed",
- G_CALLBACK (sidebar_button_pressed_callback), window);
- gtk_paned_pack1 (GTK_PANED (priv->paned), priv->sidebar, FALSE, FALSE);
- gtk_widget_show (priv->sidebar);
-
- priv->sidebar_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->sidebar_notebook), FALSE);
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->sidebar_notebook), FALSE);
- e_sidebar_set_selection_widget (E_SIDEBAR (priv->sidebar), priv->sidebar_notebook);
- gtk_widget_show (priv->sidebar_notebook);
-
- priv->view_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->view_notebook), FALSE);
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->view_notebook), FALSE);
- gtk_paned_pack2 (GTK_PANED (priv->paned), priv->view_notebook, TRUE, FALSE);
- gtk_widget_show (priv->view_notebook);
-
- gtk_paned_set_position (GTK_PANED (priv->paned),
- gconf_client_get_int (gconf_client, "/apps/evolution/shell/view_defaults/folder_bar/width", NULL));
-
- /* The buttons */
- visible = gconf_client_get_bool (gconf_client,
- "/apps/evolution/shell/view_defaults/buttons_visible",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsHide",
- "state",
- visible ? "0" : "1",
- NULL);
-
- e_sidebar_set_show_buttons (E_SIDEBAR (priv->sidebar), visible);
-
- style = gconf_client_get_string (gconf_client,
- "/apps/evolution/shell/view_defaults/buttons_style",
- NULL);
-
- if (gconf_string_to_enum (button_styles, style, &mode)) {
- switch (mode) {
- case E_SIDEBAR_MODE_TEXT:
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsText",
- "state", "1", NULL);
- break;
- case E_SIDEBAR_MODE_ICON:
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsIcon",
- "state", "1", NULL);
- break;
- case E_SIDEBAR_MODE_BOTH:
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsIconText",
- "state", "1", NULL);
- break;
-
- case E_SIDEBAR_MODE_TOOLBAR:
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsToolbar",
- "state", "1", NULL);
- break;
- }
-
- e_sidebar_set_mode (E_SIDEBAR (priv->sidebar), mode);
- }
- g_free (style);
-
- /* Status Bar*/
- visible = gconf_client_get_bool (gconf_client,
- "/apps/evolution/shell/view_defaults/statusbar_visible",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewStatusBar",
- "state",
- visible ? "1" : "0",
- NULL);
-
- /* Side Bar*/
- visible = gconf_client_get_bool (gconf_client,
- "/apps/evolution/shell/view_defaults/sidebar_visible",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewSideBar",
- "state",
- visible ? "1" : "0",
- NULL);
-
- /* The tool bar */
- visible = gconf_client_get_bool (gconf_client,
- "/apps/evolution/shell/view_defaults/toolbar_visible",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewToolbar",
- "state",
- visible ? "1" : "0",
- NULL);
- bonobo_ui_component_set_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/Toolbar",
- "hidden",
- visible ? "0" : "1",
- NULL);
-
- button_id = 0;
- xml = g_string_new("");
- for (p = e_component_registry_peek_list (registry); p != NULL; p = p->next) {
- gchar *tmp, *tmp2;
- EComponentInfo *info = p->data;
- ComponentView *view = component_view_new (info->id, info->alias, button_id);
- GtkIconInfo *icon_info;
- gint width;
-
- window->priv->component_views = g_slist_prepend (window->priv->component_views, view);
-
- if (!info->button_label || !info->menu_label)
- continue;
- e_sidebar_add_button (E_SIDEBAR (priv->sidebar), info->button_label, info->button_tooltips, info->icon_name, button_id);
-
- g_string_printf(xml, "SwitchComponent-%s", info->alias);
- bonobo_ui_component_add_verb (e_shell_window_peek_bonobo_ui_component (window),
- xml->str,
- (BonoboUIVerbFn)menu_component_selected,
- window);
-
- g_string_printf(xml, "<submenu name=\"View\">"
- "<submenu name=\"Window\">"
- "<placeholder name=\"WindowComponent\">"
- "<menuitem name=\"SwitchComponent-%s\" "
- "verb=\"\" label=\"%s\" accel=\"%s\" tip=\"",
- info->alias,
- info->menu_label,
- info->menu_accelerator);
- tmp = g_strdup_printf (_("Switch to %s"), info->button_label);
- tmp2 = g_markup_escape_text (tmp, -1);
- g_string_append (xml, tmp2);
- g_free (tmp2);
- g_free (tmp);
-
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL);
- icon_info = gtk_icon_theme_lookup_icon (
- gtk_icon_theme_get_default (),
- info->icon_name, width, 0);
- g_string_append_printf(xml, "\" pixtype=\"filename\" pixname=\"%s\"/>"
- "</placeholder></submenu></submenu>\n",
- icon_info ? gtk_icon_info_get_filename (icon_info) : "");
- gtk_icon_info_free (icon_info);
- bonobo_ui_component_set_translate (e_shell_window_peek_bonobo_ui_component (window),
- "/menu",
- xml->str,
- NULL);
- g_string_printf(xml, "<cmd name=\"SwitchComponent-%s\"/>\n", info->alias);
- bonobo_ui_component_set_translate (e_shell_window_peek_bonobo_ui_component (window),
- "/commands",
- xml->str,
- NULL);
- button_id ++;
- }
- g_string_free(xml, TRUE);
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
- setup_status_bar (window);
-
- contents_vbox = gtk_vbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX (contents_vbox), priv->paned, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (contents_vbox), priv->status_bar, FALSE, TRUE, 0);
- gtk_widget_show (contents_vbox);
-
- /* We only display this when a menu item is actually selected. */
- gtk_widget_hide (priv->menu_hint_label);
-
- bonobo_window_set_contents (BONOBO_WINDOW (window), contents_vbox);
- g_object_unref (gconf_client);
+ return E_SHELL (shell_window->priv->shell);
}
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
+/**
+ * e_shell_window_get_shell_view:
+ * @shell_window: an #EShellWindow
+ * @view_name: name of a shell view
+ *
+ * Returns the #EShellView named @view_name (see the
+ * <structfield>name</structfield> field in #EShellBackendInfo). This
+ * will also instantiate the #EShellView the first time it's requested.
+ * To reduce resource consumption, Evolution tries to delay instantiating
+ * shell views until the user switches to them. So in general, only the
+ * active view name, as returned by e_shell_window_get_active_view(),
+ * should be requested.
+ *
+ * Returns: the requested #EShellView, or %NULL if no such view is
+ * registered
+ **/
+EShellView *
+e_shell_window_get_shell_view (EShellWindow *shell_window,
+ const gchar *view_name)
{
- EShellWindow *self = E_SHELL_WINDOW (object);
- EShellWindowPrivate *priv = self->priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ GHashTable *loaded_views;
- priv->destroyed = TRUE;
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (view_name != NULL, NULL);
- if (priv->shell.eshell != NULL) {
- g_object_remove_weak_pointer (G_OBJECT (priv->shell.eshell), &priv->shell.pointer);
- priv->shell.eshell = NULL;
- }
+ loaded_views = shell_window->priv->loaded_views;
+ shell_view = g_hash_table_lookup (loaded_views, view_name);
- if (priv->ui_component != NULL) {
- bonobo_object_unref (BONOBO_OBJECT (priv->ui_component));
- priv->ui_component = NULL;
- }
+ if (shell_view != NULL)
+ return shell_view;
- if (priv->store_window_gsizeimer) {
- g_source_remove (priv->store_window_gsizeimer);
- self->priv->store_window_gsizeimer = 0;
+ shell = e_shell_window_get_shell (shell_window);
+ shell_backend = e_shell_get_backend_by_name (shell, view_name);
- /* There was a timer. Let us store the settings.*/
- store_window_size (GTK_WIDGET (self));
+ if (shell_backend == NULL) {
+ g_critical ("Unknown shell view name: %s", view_name);
+ return NULL;
}
- (* G_OBJECT_CLASS (e_shell_window_parent_class)->dispose) (object);
+ return shell_window_new_view (shell_backend, shell_window);
}
-static void
-impl_finalize (GObject *object)
+/**
+ * e_shell_window_get_shell_view_action:
+ * @shell_window: an #EShellWindow
+ * @view_name: name of a shell view
+ *
+ * Returns the switcher action for @view_name.
+ *
+ * An #EShellWindow creates a #GtkRadioAction for each registered subclass
+ * of #EShellView. This action gets passed to the #EShellSwitcher, which
+ * displays a button that proxies the action. When the #EShellView named
+ * @view_name is active, the action's icon becomes the @shell_window icon.
+ *
+ * Returns: the switcher action for the #EShellView named @view_name,
+ * or %NULL if no such shell view exists
+ **/
+GtkAction *
+e_shell_window_get_shell_view_action (EShellWindow *shell_window,
+ const gchar *view_name)
{
- EShellWindowPrivate *priv = E_SHELL_WINDOW (object)->priv;
-
- g_slist_foreach (priv->component_views, (GFunc) component_view_free, NULL);
- g_slist_free (priv->component_views);
-
- g_object_unref(priv->menu);
+ GtkAction *action;
+ gchar *action_name;
- g_free (priv);
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (view_name != NULL, NULL);
- (* G_OBJECT_CLASS (e_shell_window_parent_class)->finalize) (object);
-}
+ action_name = g_strdup_printf (SWITCHER_FORMAT, view_name);
+ action = e_shell_window_get_action (shell_window, action_name);
+ g_free (action_name);
-/* GtkWidget methods */
-static void
-e_shell_window_remove_regsizeimer (EShellWindow* self)
-{
- if (self->priv->store_window_gsizeimer) {
- g_source_remove (self->priv->store_window_gsizeimer);
- self->priv->store_window_gsizeimer = 0;
- }
+ return action;
}
-static gboolean
-impl_window_state (GtkWidget *widget, GdkEventWindowState* ev)
+/**
+ * e_shell_window_get_ui_manager:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns @shell_window<!-- -->'s user interface manager, which
+ * manages the window's menus and toolbars via #GtkAction<!-- -->s.
+ * This is the mechanism by which shell views and plugins can extend
+ * Evolution's menus and toolbars.
+ *
+ * Returns: the #GtkUIManager for @shell_window
+ **/
+GtkUIManager *
+e_shell_window_get_ui_manager (EShellWindow *shell_window)
{
- gboolean retval = FALSE;
-
- /* store only if the window state really changed */
- if ((ev->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) != 0) {
- GConfClient* client = gconf_client_get_default ();
- gconf_client_set_bool (client, "/apps/evolution/shell/view_defaults/maximized",
- (ev->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0, NULL);
- g_object_unref(client);
- }
-
- if ((ev->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0) {
- e_shell_window_remove_regsizeimer (E_SHELL_WINDOW (widget));
- }
-
- if (GTK_WIDGET_CLASS (e_shell_window_parent_class)->window_state_event) {
- retval |= GTK_WIDGET_CLASS (e_shell_window_parent_class)->window_state_event (widget, ev);
- }
-
- return retval;
-}
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
-static gboolean
-store_window_size (GtkWidget* widget)
-{
- GConfClient* client = gconf_client_get_default ();
- gconf_client_set_int (client, "/apps/evolution/shell/view_defaults/width",
- widget->allocation.width, NULL);
- gconf_client_set_int (client, "/apps/evolution/shell/view_defaults/height",
- widget->allocation.height, NULL);
- g_object_unref(client);
-
- E_SHELL_WINDOW (widget)->priv->store_window_gsizeimer = 0;
- return FALSE; /* remove this timeout */
+ return shell_window->priv->ui_manager;
}
-static void
-impl_size_alloc (GtkWidget* widget, GtkAllocation* alloc)
+/**
+ * e_shell_window_get_action:
+ * @shell_window: an #EShellWindow
+ * @action_name: the name of an action
+ *
+ * Returns the #GtkAction named @action_name in @shell_window<!-- -->'s
+ * user interface manager, or %NULL if no such action exists.
+ *
+ * Returns: the #GtkAction named @action_name
+ **/
+GtkAction *
+e_shell_window_get_action (EShellWindow *shell_window,
+ const gchar *action_name)
{
- EShellWindow* self = E_SHELL_WINDOW (widget);
- e_shell_window_remove_regsizeimer(self);
-
- if (GTK_WIDGET_REALIZED(widget) && !(gdk_window_get_state(widget->window) & GDK_WINDOW_STATE_MAXIMIZED)) {
- /* update the size storage timer */
- self->priv->store_window_gsizeimer = g_timeout_add_seconds (1, (GSourceFunc)store_window_size, self);
- }
+ GtkUIManager *ui_manager;
- if (GTK_WIDGET_CLASS (e_shell_window_parent_class)->size_allocate) {
- GTK_WIDGET_CLASS (e_shell_window_parent_class)->size_allocate (widget, alloc);
- }
-}
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
-/* Initialization. */
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
-static void
-e_shell_window_class_init (EShellWindowClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- widget_class->window_state_event = impl_window_state;
- widget_class->size_allocate = impl_size_alloc;
-
- signals[COMPONENT_CHANGED] = g_signal_new ("component_changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EShellWindowClass, component_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ return e_lookup_action (ui_manager, action_name);
}
-static void
-e_shell_window_init (EShellWindow *shell_window)
+/**
+ * e_shell_window_get_action_group:
+ * @shell_window: an #EShellWindow
+ * @group_name: the name of an action group
+ *
+ * Returns the #GtkActionGroup named @group_name in
+ * @shell_window<!-- -->'s user interface manager, or %NULL if no
+ * such action group exists.
+ *
+ * Returns: the #GtkActionGroup named @group_name
+ **/
+GtkActionGroup *
+e_shell_window_get_action_group (EShellWindow *shell_window,
+ const gchar *group_name)
{
- EShellWindowPrivate *priv = g_new0 (EShellWindowPrivate, 1);
+ GtkUIManager *ui_manager;
- priv->shell_view = e_shell_view_new(shell_window);
- priv->destroyed = FALSE;
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
- shell_window->priv = priv;
-
- /** @HookPoint: Shell Main Menu
- * @Id: org.gnome.evolution.shell
- * @Type: ESMenu
- * @Target: ESMenuTargetShell
- *
- * This hook point is used to add bonobo menu's to the main
- * evolution shell window, used for global commands not
- * requiring a specific component.
- */
- priv->menu = es_menu_new("org.gnome.evolution.shell");
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ return e_lookup_action_group (ui_manager, group_name);
}
-/* Instantiation. */
-
+/**
+ * e_shell_window_get_managed_widget:
+ * @shell_window: an #EShellWindow
+ * @widget_path: path in the UI definintion
+ *
+ * Looks up a widget in @shell_window<!-- -->'s user interface manager by
+ * following a path. See gtk_ui_manager_get_widget() for more information
+ * about paths.
+ *
+ * Returns: the widget found by following the path, or %NULL if no widget
+ * was found
+ **/
GtkWidget *
-e_shell_window_new (EShell *shell,
- const gchar *component_id)
+e_shell_window_get_managed_widget (EShellWindow *shell_window,
+ const gchar *widget_path)
{
- EShellWindow *window = g_object_new (e_shell_window_get_type (), NULL);
- EShellWindowPrivate *priv = window->priv;
- GConfClient *gconf_client = gconf_client_get_default ();
- BonoboUIContainer *ui_container;
- gchar *default_component_id = NULL;
- gchar *xmlfile;
- gint width, height;
-
- if (bonobo_window_construct (BONOBO_WINDOW (window),
- bonobo_ui_container_new (),
- "evolution", "Evolution") == NULL) {
- g_object_unref (window);
- g_object_unref (gconf_client);
- return NULL;
- }
-
- window->priv->shell.eshell = shell;
- g_object_add_weak_pointer (G_OBJECT (shell), &window->priv->shell.pointer);
-
- /* FIXME TODO: Add system_exception signal handling and all the other
- stuff from e_shell_view_construct(). */
-
- ui_container = bonobo_window_get_ui_container (BONOBO_WINDOW (window));
-
- priv->ui_component = bonobo_ui_component_new ("evolution");
- bonobo_ui_component_set_container (priv->ui_component,
- bonobo_object_corba_objref (BONOBO_OBJECT (ui_container)),
- NULL);
-
- xmlfile = g_build_filename (EVOLUTION_UIDIR, "evolution.xml", NULL);
- bonobo_ui_util_set_ui (priv->ui_component,
- PREFIX,
- xmlfile,
- "evolution", NULL);
- g_free (xmlfile);
-
- e_shell_window_commands_setup (window);
- e_menu_activate((EMenu *)priv->menu, priv->ui_component, TRUE);
-
- setup_widgets (window);
-
- if (gconf_client_get_bool (gconf_client,"/apps/evolution/shell/view_defaults/sidebar_visible",NULL))
- gtk_widget_show (priv->sidebar);
- else
- gtk_widget_hide (priv->sidebar);
-
- update_send_receive_sensitivity (window);
- g_signal_connect_object (shell, "line_status_changed", G_CALLBACK (shell_line_status_changed_callback), window, 0);
-
- gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
+ GtkUIManager *ui_manager;
+ GtkWidget *widget;
- if (component_id == NULL) {
- component_id = default_component_id =
- gconf_client_get_string (gconf_client,
- "/apps/evolution/shell/view_defaults/component_id",
- NULL);
- if (component_id == NULL)
- component_id = "mail";
- }
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
+ g_return_val_if_fail (widget_path != NULL, NULL);
- e_shell_window_switch_to_component (window, component_id);
- g_free(default_component_id);
- g_object_unref (gconf_client);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ widget = gtk_ui_manager_get_widget (ui_manager, widget_path);
- width = gconf_client_get_int (gconf_client, "/apps/evolution/shell/view_defaults/width", NULL);
- height = gconf_client_get_int (gconf_client, "/apps/evolution/shell/view_defaults/height", NULL);
- gtk_window_set_default_size (GTK_WINDOW (window), (width >= 0) ? width : 0,
- (height >= 0) ? height : 0);
- if (gconf_client_get_bool (gconf_client, "/apps/evolution/shell/view_defaults/maximized", NULL)) {
- gtk_window_maximize (GTK_WINDOW (window));
- }
+ g_return_val_if_fail (widget != NULL, NULL);
- g_object_unref (gconf_client);
- return GTK_WIDGET (window);
+ return widget;
}
-void
-e_shell_window_switch_to_component (EShellWindow *window, const gchar *component_id)
+/**
+ * e_shell_window_get_active_view:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns the name of the active #EShellView.
+ *
+ * Returns: the name of the active view
+ **/
+const gchar *
+e_shell_window_get_active_view (EShellWindow *shell_window)
{
- EShellWindowPrivate *priv = window->priv;
- ComponentView *view = NULL;
- GSList *p;
-
- g_return_if_fail (E_IS_SHELL_WINDOW (window));
- g_return_if_fail (component_id != NULL);
-
- for (p = priv->component_views; p != NULL; p = p->next) {
- ComponentView *this_view = p->data;
-
- if (strcmp (this_view->component_id, component_id) == 0
- || (this_view->component_alias != NULL
- && strcmp (this_view->component_alias, component_id) == 0))
- {
- view = p->data;
- break;
- }
- }
-
- if (view == NULL) {
- g_warning ("Unknown component %s", component_id);
- return;
- }
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
- e_sidebar_select_button (E_SIDEBAR (priv->sidebar), view->button_id);
+ return shell_window->priv->active_view;
}
-const gchar *
-e_shell_window_peek_current_component_id (EShellWindow *window)
+/**
+ * e_shell_window_set_active_view:
+ * @shell_window: an #EShellWindow
+ * @view_name: the name of the shell view to switch to
+ *
+ * Switches @shell_window to the #EShellView named @view_name, causing
+ * the entire content of @shell_window to change. This is typically
+ * called as a result of the user clicking one of the switcher buttons.
+ *
+ * The name of the newly activated shell view is also written to GConf key
+ * <filename>/apps/evolution/shell/view_defaults/component_id</filename>.
+ * This makes the active shell view persistent across Evolution sessions.
+ * It also causes new shell windows created within the current Evolution
+ * session to open to the most recently selected shell view.
+ **/
+void
+e_shell_window_set_active_view (EShellWindow *shell_window,
+ const gchar *view_name)
{
- g_return_val_if_fail (E_IS_SHELL_WINDOW (window), NULL);
+ GtkAction *action;
+ EShellView *shell_view;
- if (window->priv->current_view == NULL)
- return NULL;
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (view_name != NULL);
- return window->priv->current_view->component_id;
+ shell_view = e_shell_window_get_shell_view (shell_window, view_name);
+ g_return_if_fail (shell_view != NULL);
+
+ action = e_shell_view_get_action (shell_view);
+ gtk_action_activate (action);
}
-EShell *
-e_shell_window_peek_shell (EShellWindow *window)
+/**
+ * e_shell_window_get_safe_mode:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns %TRUE if @shell_window is in "safe mode".
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means. The @shell_window simply manages the
+ * "safe mode" state.
+ *
+ * Returns: %TRUE if @shell_window is in "safe mode"
+ **/
+gboolean
+e_shell_window_get_safe_mode (EShellWindow *shell_window)
{
- g_return_val_if_fail (E_IS_SHELL_WINDOW (window), NULL);
+ g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
- return window->priv->shell.eshell;
+ return shell_window->priv->safe_mode;
}
-BonoboUIComponent *
-e_shell_window_peek_bonobo_ui_component (EShellWindow *window)
+/**
+ * e_shell_window_set_safe_mode:
+ * @shell_window: an #EShellWindow
+ * @safe_mode: whether to put @shell_window into "safe mode"
+ *
+ * If %TRUE, puts @shell_window into "safe mode".
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means. The @shell_window simply manages the
+ * "safe mode" state.
+ **/
+void
+e_shell_window_set_safe_mode (EShellWindow *shell_window,
+ gboolean safe_mode)
{
- g_return_val_if_fail (E_IS_SHELL_WINDOW (window), NULL);
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
- return window->priv->ui_component;
+ shell_window->priv->safe_mode = safe_mode;
+
+ g_object_notify (G_OBJECT (shell_window), "safe-mode");
}
-ESidebar *
-e_shell_window_peek_sidebar (EShellWindow *window)
+/**
+ * e_shell_window_add_action_group:
+ * @shell_window: an #EShellWindow
+ * @group_name: the name of the new action group
+ *
+ * Creates a new #GtkActionGroup and adds it to @shell_window<!-- -->'s
+ * user interface manager. This also takes care of details like setting
+ * the translation domain.
+ **/
+void
+e_shell_window_add_action_group (EShellWindow *shell_window,
+ const gchar *group_name)
{
- g_return_val_if_fail (E_IS_SHELL_WINDOW (window), NULL);
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ const gchar *domain;
- return E_SIDEBAR (window->priv->sidebar);
-}
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (group_name != NULL);
-GtkWidget *
-e_shell_window_peek_statusbar (EShellWindow *window)
-{
- return window->priv->status_bar;
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ domain = GETTEXT_PACKAGE;
+
+ action_group = gtk_action_group_new (group_name);
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
}
+/**
+ * e_shell_window_register_new_item_actions:
+ * @shell_window: an #EShellWindow
+ * @backend_name: name of an #EShellBackend
+ * @entries: an array of #GtkActionEntry<!-- -->s
+ * @n_entries: number of elements in the array
+ *
+ * Registers a list of #GtkAction<!-- -->s to appear in
+ * @shell_window<!-- -->'s "New" menu and toolbar button. This
+ * function should be called from an #EShell<!-- -->'s
+ * #EShell::window-created signal handler. The #EShellBackend calling
+ * this function should pass its own name for the @backend_name argument
+ * (i.e. the <structfield>name</structfield> field from its own
+ * #EShellBackendInfo).
+ *
+ * The registered #GtkAction<!-- -->s should be for creating individual
+ * items such as an email message or a calendar appointment. The action
+ * labels should be marked for translation with the "New" context using
+ * the NC_() macro.
+ **/
void
-e_shell_window_save_defaults (EShellWindow *window)
-{
- GConfClient *client = gconf_client_get_default ();
- gchar *prop;
- const gchar *style;
- gboolean visible;
-
- gconf_client_set_int (client, "/apps/evolution/shell/view_defaults/folder_bar/width",
- gtk_paned_get_position (GTK_PANED (window->priv->paned)), NULL);
-
- /* The button styles */
- if ((style = gconf_enum_to_string (button_styles, e_sidebar_get_mode (E_SIDEBAR (window->priv->sidebar))))) {
- gconf_client_set_string (client,
- "/apps/evolution/shell/view_defaults/buttons_style",
- style, NULL);
- }
+e_shell_window_register_new_item_actions (EShellWindow *shell_window,
+ const gchar *backend_name,
+ GtkActionEntry *entries,
+ guint n_entries)
+{
+ GtkActionGroup *action_group;
+ GtkAccelGroup *accel_group;
+ GtkUIManager *ui_manager;
+ guint ii;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (backend_name != NULL);
+ g_return_if_fail (entries != NULL);
+
+ action_group = ACTION_GROUP (NEW_ITEM);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ accel_group = gtk_ui_manager_get_accel_group (ui_manager);
+ backend_name = g_intern_string (backend_name);
+
+ /* XXX The action label translations are retrieved from the
+ * message context "New", but gtk_action_group_add_actions()
+ * does not support message contexts. So we have to fetch
+ * the label translations ourselves before adding them to
+ * the action group.
+ *
+ * gtk_action_group_set_translate_func() does not help here
+ * because the action tooltips do not use a message context
+ * (though I suppose they could). */
+ for (ii = 0; ii < n_entries; ii++)
+ entries[ii].label = g_dpgettext2 (
+ GETTEXT_PACKAGE, "New", entries[ii].label);
- /* Button hiding setting */
- prop = bonobo_ui_component_get_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewButtonsHide",
- "state",
- NULL);
- if (prop) {
- visible = prop[0] == '0';
- gconf_client_set_bool (client,
- "/apps/evolution/shell/view_defaults/buttons_visible",
- visible,
- NULL);
- g_free (prop);
- }
+ gtk_action_group_add_actions (
+ action_group, entries, n_entries, shell_window);
- /* Toolbar visibility setting */
- prop = bonobo_ui_component_get_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewToolbar",
- "state",
- NULL);
- if (prop) {
- visible = prop[0] == '1';
- gconf_client_set_bool (client,
- "/apps/evolution/shell/view_defaults/toolbar_visible",
- visible,
- NULL);
- g_free (prop);
- }
+ /* Tag each action with the name of the shell backend that
+ * registered it. This is used to help sort actions in the
+ * "New" menu. */
- /* SideBar visibility setting */
- prop = bonobo_ui_component_get_prop (e_shell_window_peek_bonobo_ui_component (window),
- "/commands/ViewSideBar",
- "state",
- NULL);
- if (prop) {
- visible = prop[0] == '1';
- gconf_client_set_bool (client,
- "/apps/evolution/shell/view_defaults/sidebar_visible",
- visible,
- NULL);
- g_free (prop);
- }
+ for (ii = 0; ii < n_entries; ii++) {
+ const gchar *action_name;
+ GtkAction *action;
- g_object_unref (client);
-}
+ action_name = entries[ii].name;
-void
-e_shell_window_show_settings (EShellWindow *window)
-{
- g_return_if_fail (E_IS_SHELL_WINDOW (window));
+ action = gtk_action_group_get_action (
+ action_group, action_name);
- e_shell_show_settings (window->priv->shell.eshell, window->priv->current_view ? window->priv->current_view->component_alias : NULL, window);
-}
+ gtk_action_set_accel_group (action, accel_group);
-void
-e_shell_window_set_title(EShellWindow *window, const gchar *component_id, const gchar *title)
-{
- EShellWindowPrivate *priv = window->priv;
- ComponentView *view = NULL;
- GSList *p;
-
- if (priv->destroyed)
- return;
-
- for (p = priv->component_views; p != NULL; p = p->next) {
- ComponentView *this_view = p->data;
-
- if (strcmp (this_view->component_id, component_id) == 0
- || (this_view->component_alias != NULL
- && strcmp (this_view->component_alias, component_id) == 0)) {
- view = p->data;
- break;
- }
- }
+ g_object_set_data (
+ G_OBJECT (action),
+ "backend-name", (gpointer) backend_name);
- if (view) {
- g_free(view->title);
- view->title = g_strdup(title);
- if (view->title && view == priv->current_view)
- gtk_window_set_title((GtkWindow *)window, title);
+ /* The first action becomes the first item in the "New"
+ * menu, and consequently its icon is shown in the "New"
+ * button when the shell backend's view is active. This
+ * is all sorted out in shell_window_extract_actions().
+ * Note, the data value just needs to be non-zero. */
+ if (ii == 0)
+ g_object_set_data (
+ G_OBJECT (action),
+ "primary", GINT_TO_POINTER (TRUE));
}
+
+ e_shell_window_update_new_menu (shell_window);
}
/**
- * e_shell_window_change_component_button_icon
- * Changes icon of components button at sidebar. For more info how this behaves see
- * info at @ref e_sidebar_change_button_icon.
- * @param window EShellWindow instance.
- * @param component_id ID of the component.
- * @param icon Icon buffer.
+ * e_shell_window_register_new_source_actions:
+ * @shell_window: an #EShellWindow
+ * @backend_name: name of an #EShellBackend
+ * @entries: an array of #GtkActionEntry<!-- -->s
+ * @n_entries: number of elements in the array
+ *
+ * Registers a list of #GtkAction<!-- -->s to appear in
+ * @shell_window<!-- -->'s "New" menu and toolbar button. This
+ * function should be called from an #EShell<!-- -->'s
+ * #EShell::window-created signal handler. The #EShellBackend calling
+ * this function should pass its own name for the @backend_name argument
+ * (i.e. the <structfield>name</structfield> field from its own
+ * #EShellBackendInfo).
+ *
+ * The registered #GtkAction<!-- -->s should be for creating item
+ * containers such as an email folder or a calendar. The action labels
+ * should be marked for translation with the "New" context using the
+ * NC_() macro.
**/
void
-e_shell_window_change_component_button_icon (EShellWindow *window, const gchar *component_id, const gchar *icon_name)
-{
- EShellWindowPrivate *priv;
- GSList *p;
+e_shell_window_register_new_source_actions (EShellWindow *shell_window,
+ const gchar *backend_name,
+ GtkActionEntry *entries,
+ guint n_entries)
+{
+ GtkActionGroup *action_group;
+ GtkAccelGroup *accel_group;
+ GtkUIManager *ui_manager;
+ guint ii;
+
+ g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+ g_return_if_fail (backend_name != NULL);
+ g_return_if_fail (entries != NULL);
+
+ action_group = ACTION_GROUP (NEW_SOURCE);
+ ui_manager = e_shell_window_get_ui_manager (shell_window);
+ accel_group = gtk_ui_manager_get_accel_group (ui_manager);
+ backend_name = g_intern_string (backend_name);
+
+ /* XXX The action label translations are retrieved from the
+ * message context "New", but gtk_action_group_add_actions()
+ * does not support message contexts. So we have to fetch
+ * the label translations ourselves before adding them to
+ * the action group.
+ *
+ * gtk_action_group_set_translate_func() does not help here
+ * because the action tooltips do not use a message context
+ * (though I suppose they could). */
+ for (ii = 0; ii < n_entries; ii++)
+ entries[ii].label = g_dpgettext2 (
+ GETTEXT_PACKAGE, "New", entries[ii].label);
+
+ gtk_action_group_add_actions (
+ action_group, entries, n_entries, shell_window);
- g_return_if_fail (window != NULL);
- g_return_if_fail (component_id != NULL);
+ /* Tag each action with the name of the shell backend that
+ * registered it. This is used to help sort actions in the
+ * "New" menu. */
- priv = window->priv;
+ for (ii = 0; ii < n_entries; ii++) {
+ const gchar *action_name;
+ GtkAction *action;
- if (priv->destroyed)
- return;
+ action_name = entries[ii].name;
- for (p = priv->component_views; p != NULL; p = p->next) {
- ComponentView *this_view = p->data;
+ action = gtk_action_group_get_action (
+ action_group, action_name);
- if (strcmp (this_view->component_id, component_id) == 0
- || (this_view->component_alias != NULL
- && strcmp (this_view->component_alias, component_id) == 0)) {
- e_sidebar_change_button_icon (E_SIDEBAR (priv->sidebar), icon_name, this_view->button_id);
- break;
- }
+ gtk_action_set_accel_group (action, accel_group);
+
+ g_object_set_data (
+ G_OBJECT (action),
+ "backend-name", (gpointer) backend_name);
}
+
+ e_shell_window_update_new_menu (shell_window);
}
diff --git a/shell/e-shell-window.h b/shell/e-shell-window.h
index 7c404fadc8..b867490afb 100644
--- a/shell/e-shell-window.h
+++ b/shell/e-shell-window.h
@@ -1,4 +1,5 @@
/*
+ * e-shell-window.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,63 +15,104 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _E_SHELL_WINDOW_H_
-#define _E_SHELL_WINDOW_H_
-
-#include <bonobo/bonobo-window.h>
-#include <bonobo/bonobo-ui-component.h>
-#include "e-sidebar.h"
-
-#define E_TYPE_SHELL_WINDOW (e_shell_window_get_type ())
-#define E_SHELL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL_WINDOW, EShellWindow))
-#define E_SHELL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_WINDOW, EShellWindowClass))
-#define E_IS_SHELL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL_WINDOW))
-#define E_IS_SHELL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_WINDOW))
-
-typedef struct _EShellWindow EShellWindow;
+/**
+ * SECTION: e-shell-window
+ * @short_description: the main window
+ * @include: shell/e-shell-window.h
+ **/
+
+#ifndef E_SHELL_WINDOW_H
+#define E_SHELL_WINDOW_H
+
+#include <shell/e-shell.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL_WINDOW \
+ (e_shell_window_get_type ())
+#define E_SHELL_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL_WINDOW, EShellWindow))
+#define E_SHELL_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL_WINDOW, EShellWindowClass))
+#define E_IS_SHELL_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL_WINDOW))
+#define E_IS_SHELL_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_SHELL_WINDOW))
+#define E_SHELL_WINDOW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL_WINDOW, EShellWindowClass))
+
+G_BEGIN_DECLS
+
+/* Avoid including <e-shell-view.h>, because it includes us! */
+struct _EShellView;
+
+typedef struct _EShellWindow EShellWindow;
+typedef struct _EShellWindowClass EShellWindowClass;
typedef struct _EShellWindowPrivate EShellWindowPrivate;
-typedef struct _EShellWindowClass EShellWindowClass;
+/**
+ * EShellWindow:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
struct _EShellWindow {
- BonoboWindow parent;
-
+ GtkWindow parent;
EShellWindowPrivate *priv;
};
struct _EShellWindowClass {
- BonoboWindowClass parent_class;
-
- void (* component_changed) (EShellWindow *window);
+ GtkWindowClass parent_class;
};
-#include "e-shell.h"
-
-GType e_shell_window_get_type (void);
-
-GtkWidget *e_shell_window_new (EShell *shell,
- const gchar *component_id);
-
-void e_shell_window_switch_to_component (EShellWindow *shell,
- const gchar *component_id);
-const gchar *e_shell_window_peek_current_component_id (EShellWindow *shell);
-
-EShell *e_shell_window_peek_shell (EShellWindow *window);
-BonoboUIComponent *e_shell_window_peek_bonobo_ui_component (EShellWindow *window);
-ESidebar *e_shell_window_peek_sidebar (EShellWindow *window);
-GtkWidget *e_shell_window_peek_statusbar (EShellWindow *window);
-
-void e_shell_window_set_title(EShellWindow *window, const gchar *component_id, const gchar *title);
-
-void e_shell_window_save_defaults (EShellWindow *window);
-void e_shell_window_show_settings (EShellWindow *window);
-
-void e_shell_window_change_component_button_icon (EShellWindow *window, const gchar *component_id, const gchar *icon_name);
-
-#endif /* _E_SHELL_WINDOW_H_ */
+GType e_shell_window_get_type (void);
+GtkWidget * e_shell_window_new (EShell *shell,
+ gboolean safe_mode);
+EShell * e_shell_window_get_shell (EShellWindow *shell_window);
+struct _EShellView *
+ e_shell_window_get_shell_view (EShellWindow *shell_window,
+ const gchar *view_name);
+GtkAction * e_shell_window_get_shell_view_action
+ (EShellWindow *shell_window,
+ const gchar *view_name);
+GtkUIManager * e_shell_window_get_ui_manager (EShellWindow *shell_window);
+GtkAction * e_shell_window_get_action (EShellWindow *shell_window,
+ const gchar *action_name);
+GtkActionGroup *e_shell_window_get_action_group (EShellWindow *shell_window,
+ const gchar *group_name);
+GtkWidget * e_shell_window_get_managed_widget
+ (EShellWindow *shell_window,
+ const gchar *widget_path);
+const gchar * e_shell_window_get_active_view (EShellWindow *shell_window);
+void e_shell_window_set_active_view (EShellWindow *shell_window,
+ const gchar *view_name);
+gboolean e_shell_window_get_safe_mode (EShellWindow *shell_window);
+void e_shell_window_set_safe_mode (EShellWindow *shell_window,
+ gboolean safe_mode);
+void e_shell_window_add_action_group (EShellWindow *shell_window,
+ const gchar *group_name);
+
+/* These should be called from the shell backend's window_created() handler. */
+
+void e_shell_window_register_new_item_actions
+ (EShellWindow *shell_window,
+ const gchar *backend_name,
+ GtkActionEntry *entries,
+ guint n_entries);
+void e_shell_window_register_new_source_actions
+ (EShellWindow *shell_window,
+ const gchar *backend_name,
+ GtkActionEntry *entries,
+ guint n_entries);
+
+G_END_DECLS
+
+#endif /* E_SHELL_WINDOW_H */
diff --git a/shell/e-shell.c b/shell/e-shell.c
index e4224f3207..4dd72e3747 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -1,4 +1,6 @@
/*
+ * e-shell.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,1411 +15,1533 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#include <config.h>
-
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <gtk/gtk.h>
-#include <glib/gstdio.h>
-
-#ifdef GDK_WINDOWING_X11
-#include <gdk/gdkprivate.h>
-#include <gdk/gdkx.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#elif defined (GDK_WINDOWING_WIN32)
-/* gdkwin32.h includes <windows.h> which stomps over the namespace */
-#undef DATADIR
-#define interface windows_interface
-#include <gdk/gdkwin32.h>
-#undef interface
-#endif
+#include "e-shell.h"
#include <glib/gi18n.h>
-
-#include <gconf/gconf-client.h>
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-moniker-util.h>
-
-#include <libedataserver/e-xml-utils.h>
#include <libedataserverui/e-passwords.h>
-#include "e-util/e-bconf-map.h"
-#include "e-util/e-dialog-utils.h"
-#include "e-util/e-error.h"
-#include "e-util/e-fsutils.h"
#include "e-util/e-util.h"
+#include "e-util/e-module.h"
+#include "smclient/eggsmclient.h"
+#include "widgets/misc/e-preferences-window.h"
-#include "Evolution.h"
-#include "e-shell-constants.h"
-#include "e-shell-settings-dialog.h"
-#include "e-shell.h"
-#include "e-shell-view.h"
-#include "es-event.h"
-#include "evolution-listener.h"
-#include "evolution-shell-component-utils.h"
-
-static void set_line_status_complete(EvolutionListener *el, gpointer data);
+#include "e-shell-backend.h"
+#include "e-shell-migrate.h"
+#include "e-shell-window.h"
-#define PARENT_TYPE bonobo_object_get_type ()
-static BonoboObjectClass *parent_class = NULL;
-static gboolean session_started = FALSE;
+#define E_SHELL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SHELL, EShellPrivate))
struct _EShellPrivate {
- /* IID for registering the object on OAF. */
- gchar *iid;
+ GList *watched_windows;
+ EShellSettings *settings;
+ GConfClient *gconf_client;
+ GtkWidget *preferences_window;
- GList *windows;
+ /* Shell Backends */
+ GList *loaded_backends;
+ GHashTable *backends_by_name;
+ GHashTable *backends_by_scheme;
- /* EUriSchemaRegistry *uri_schema_registry; FIXME */
- EComponentRegistry *component_registry;
+ gpointer preparing_for_line_change; /* weak pointer */
+ gpointer preparing_for_quit; /* weak pointer */
- /* Names for the types of the folders that have maybe crashed. */
- /* FIXME TODO */
- GList *crash_type_names; /* gchar * */
+ guint auto_reconnect : 1;
+ guint network_available : 1;
+ guint online : 1;
+ guint quit_cancelled : 1;
+ guint safe_mode : 1;
+};
- /* Line status and controllers */
- EShellLineStatus line_status;
- gint line_status_pending;
- EShellLineStatus line_status_working;
- EvolutionListener *line_status_listener;
+enum {
+ PROP_0,
+ PROP_NETWORK_AVAILABLE,
+ PROP_ONLINE,
+ PROP_SHELL_SETTINGS
+};
- /* Settings Dialog */
- union {
- GtkWidget *widget;
- gpointer pointer;
- } settings_dialog;
+enum {
+ EVENT,
+ HANDLE_URI,
+ PREPARE_FOR_OFFLINE,
+ PREPARE_FOR_ONLINE,
+ PREPARE_FOR_QUIT,
+ QUIT_REQUESTED,
+ SEND_RECEIVE,
+ WINDOW_CREATED,
+ WINDOW_DESTROYED,
+ LAST_SIGNAL
+};
- /* If we're quitting and things are still busy, a timeout handler */
- guint quit_timeout;
+enum {
+ DEBUG_KEY_SETTINGS = 1 << 0
+};
- /* Whether the shell is succesfully initialized. This is needed during
- the start-up sequence, to avoid CORBA calls to do make wrong things
- to happen while the shell is initializing. */
- guint is_initialized : 1;
+static GDebugKey debug_keys[] = {
+ { "settings", DEBUG_KEY_SETTINGS }
+};
- /* Wether the shell is working in "interactive" mode or not.
- (Currently, it's interactive IIF there is at least one active
- view.) */
- guint is_interactive : 1;
+EShell *default_shell = NULL;
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
- /* Whether quit has been requested, and the shell is now waiting for
- permissions from all the components to quit. */
- guint preparing_to_quit : 1;
+#if NM_SUPPORT
+gboolean e_shell_dbus_initialize (EShell *shell);
+#endif
- /* Whether we are recovering from a crash in the previous session. */
- guint crash_recovery : 1;
-};
+static void
+shell_parse_debug_string (EShell *shell)
+{
+ guint flags;
-/* Signals. */
+ flags = g_parse_debug_string (
+ g_getenv ("EVOLUTION_DEBUG"),
+ debug_keys, G_N_ELEMENTS (debug_keys));
-enum {
- NO_WINDOWS_LEFT,
- LINE_STATUS_CHANGED,
- NEW_WINDOW_CREATED,
- LAST_SIGNAL
-};
+ if (flags & DEBUG_KEY_SETTINGS)
+ e_shell_settings_enable_debug (shell->priv->settings);
+}
-static guint signals[LAST_SIGNAL] = { 0 };
+static void
+shell_notify_online_cb (EShell *shell)
+{
+ gboolean online;
-/* Utility functions. */
+ online = e_shell_get_online (shell);
+ e_passwords_set_online (online);
+}
static gboolean
-get_config_start_offline (void)
+shell_window_delete_event_cb (EShell *shell,
+ GtkWindow *window)
{
- GConfClient *client;
- gboolean value;
+ /* If other windows are open we can safely close this one. */
+ if (g_list_length (shell->priv->watched_windows) > 1)
+ return FALSE;
- client = gconf_client_get_default ();
+ /* Otherwise we initiate application quit. */
+ e_shell_quit (shell);
+
+ return TRUE;
+}
- value = gconf_client_get_bool (client, "/apps/evolution/shell/start_offline", NULL);
+static gboolean
+shell_window_focus_in_event_cb (EShell *shell,
+ GdkEventFocus *event,
+ GtkWindow *window)
+{
+ GList *list, *link;
+
+ /* Keep the watched windows list sorted by most recently focused,
+ * so the first item in the list should always be the currently
+ * focused window. */
+
+ list = shell->priv->watched_windows;
+ link = g_list_find (list, window);
+ g_return_val_if_fail (link != NULL, FALSE);
+
+ if (link != list) {
+ list = g_list_remove_link (list, link);
+ list = g_list_concat (link, list);
+ }
- g_object_unref (client);
+ shell->priv->watched_windows = list;
- return value;
+ return FALSE;
}
-/* Interactivity handling. */
+static void
+shell_window_weak_notify_cb (EShell *shell,
+ GObject *where_the_object_was)
+{
+ GList *list;
+
+ list = shell->priv->watched_windows;
+ list = g_list_remove (list, where_the_object_was);
+ shell->priv->watched_windows = list;
+
+ g_signal_emit (shell, signals[WINDOW_DESTROYED], 0);
+}
static void
-set_interactive (EShell *shell,
- gboolean interactive)
+shell_ready_for_offline (EShell *shell,
+ EActivity *activity,
+ gboolean is_last_ref)
{
- GSList *component_list;
- GSList *p;
- GList *first_element;
- gint num_windows;
- GtkWidget *view;
+ if (!is_last_ref)
+ return;
- g_return_if_fail (E_IS_SHELL (shell));
+ /* Increment the reference count so we can safely emit
+ * a signal without triggering the toggle reference. */
+ g_object_ref (activity);
- shell->priv->is_interactive = interactive;
+ e_activity_complete (activity);
- num_windows = g_list_length (shell->priv->windows);
+ g_object_remove_toggle_ref (
+ G_OBJECT (activity), (GToggleNotify)
+ shell_ready_for_offline, shell);
- /* We want to send the "interactive" message only when the first
- window is created */
- if (num_windows != 1)
- return;
+ /* Finalize the activity. */
+ g_object_unref (activity);
- first_element = g_list_first (shell->priv->windows);
- view = GTK_WIDGET (first_element->data);
+ shell->priv->online = FALSE;
+ g_object_notify (G_OBJECT (shell), "online");
- component_list = e_component_registry_peek_list (shell->priv->component_registry);
+ g_message ("Offline preparations complete.");
+}
- for (p = component_list; p != NULL; p = p->next) {
- EComponentInfo *info = p->data;
- CORBA_Environment ev;
+static void
+shell_prepare_for_offline (EShell *shell)
+{
+ /* Are preparations already in progress? */
+ if (shell->priv->preparing_for_line_change != NULL)
+ return;
- CORBA_exception_init (&ev);
+ g_message ("Preparing for offline mode...");
-#ifdef GDK_WINDOWING_X11
- GNOME_Evolution_Component_interactive (info->iface, interactive,GPOINTER_TO_INT (GDK_WINDOW_XWINDOW (view->window)), &ev);
-#elif defined (GDK_WINDOWING_WIN32)
- GNOME_Evolution_Component_interactive (info->iface, interactive,GPOINTER_TO_INT (GDK_WINDOW_HWND (view->window)), &ev);
-#else
-#error Port this to your windowing system
-#endif
+ shell->priv->preparing_for_line_change =
+ e_activity_new (_("Preparing to go offline..."));
- /* Ignore errors, the components can decide to not implement
- this interface. */
+ g_object_add_toggle_ref (
+ G_OBJECT (shell->priv->preparing_for_line_change),
+ (GToggleNotify) shell_ready_for_offline, shell);
- CORBA_exception_free (&ev);
- }
-}
+ g_object_add_weak_pointer (
+ G_OBJECT (shell->priv->preparing_for_line_change),
+ &shell->priv->preparing_for_line_change);
-/* CORBA interface implementation. */
+ g_signal_emit (
+ shell, signals[PREPARE_FOR_OFFLINE], 0,
+ shell->priv->preparing_for_line_change);
-static gboolean
-raise_exception_if_not_ready (PortableServer_Servant servant,
- CORBA_Environment *ev)
+ g_object_unref (shell->priv->preparing_for_line_change);
+}
+
+static void
+shell_ready_for_online (EShell *shell,
+ EActivity *activity,
+ gboolean is_last_ref)
{
- EShell *shell;
+ if (!is_last_ref)
+ return;
- shell = E_SHELL (bonobo_object_from_servant (servant));
+ /* Increment the reference count so we can safely emit
+ * a signal without triggering the toggle reference. */
+ g_object_ref (activity);
- if (! shell->priv->is_initialized) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Shell_NotReady, NULL);
- return TRUE;
- }
+ e_activity_complete (activity);
- return FALSE;
+ g_object_remove_toggle_ref (
+ G_OBJECT (activity), (GToggleNotify)
+ shell_ready_for_online, shell);
+
+ /* Finalize the activity. */
+ g_object_unref (activity);
+
+ shell->priv->online = TRUE;
+ g_object_notify (G_OBJECT (shell), "online");
+
+ g_message ("Online preparations complete.");
}
-static GNOME_Evolution_ShellView
-impl_Shell_createNewWindow (PortableServer_Servant servant,
- const CORBA_char *component_id,
- CORBA_Environment *ev)
+static void
+shell_prepare_for_online (EShell *shell)
{
- BonoboObject *bonobo_object;
- EShell *shell;
- EShellWindow *shell_window;
- EShellView *shell_view;
+ /* Are preparations already in progress? */
+ if (shell->priv->preparing_for_line_change != NULL)
+ return;
- if (raise_exception_if_not_ready (servant, ev))
- return CORBA_OBJECT_NIL;
+ g_message ("Preparing for online mode...");
- bonobo_object = bonobo_object_from_servant (servant);
- shell = E_SHELL (bonobo_object);
+ shell->priv->preparing_for_line_change =
+ e_activity_new (_("Preparing to go online..."));
- if (component_id[0] == '\0')
- component_id = NULL;
+ g_object_add_toggle_ref (
+ G_OBJECT (shell->priv->preparing_for_line_change),
+ (GToggleNotify) shell_ready_for_online, shell);
- shell_window = e_shell_create_window (shell, component_id, NULL);
- if (shell_window == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Shell_ComponentNotFound, NULL);
- return CORBA_OBJECT_NIL;
- }
+ g_object_add_weak_pointer (
+ G_OBJECT (shell->priv->preparing_for_line_change),
+ &shell->priv->preparing_for_line_change);
- /* refs?? */
- shell_view = e_shell_view_new(shell_window);
-
- return BONOBO_OBJREF(shell_view);
+ g_signal_emit (
+ shell, signals[PREPARE_FOR_ONLINE], 0,
+ shell->priv->preparing_for_line_change);
+ g_object_unref (shell->priv->preparing_for_line_change);
}
static void
-impl_Shell_handleURI (PortableServer_Servant servant,
- const CORBA_char *uri,
- CORBA_Environment *ev)
+shell_ready_for_quit (EShell *shell,
+ EActivity *activity,
+ gboolean is_last_ref)
{
- EShell *shell = E_SHELL (bonobo_object_from_servant (servant));
- EComponentInfo *component_info;
- gchar *schema, *p;
- gint show = FALSE;
-
- schema = g_alloca(strlen(uri)+1);
- strcpy(schema, uri);
- p = strchr(schema, ':');
- if (p)
- *p = 0;
-
- component_info = e_component_registry_peek_info(shell->priv->component_registry, ECR_FIELD_SCHEMA, schema);
- if (component_info == NULL) {
- show = TRUE;
- component_info = e_component_registry_peek_info(shell->priv->component_registry, ECR_FIELD_ALIAS, schema);
- }
+ GList *list;
- if (component_info == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_UnsupportedSchema, NULL);
+ if (!is_last_ref)
return;
- }
- if (show) {
- GtkWidget *shell_window;
+ /* Increment the reference count so we can safely emit
+ * a signal without triggering the toggle reference. */
+ g_object_ref (activity);
- shell_window = (GtkWidget *)e_shell_create_window (shell, component_info->id, NULL);
- if (shell_window == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_ComponentNotFound, NULL);
- return;
- }
- }
+ e_activity_complete (activity);
+
+ g_object_remove_toggle_ref (
+ G_OBJECT (activity), (GToggleNotify)
+ shell_ready_for_quit, shell);
+
+ /* Finalize the activity. */
+ g_object_ref (activity);
+
+ g_message ("Quit preparations complete.");
- GNOME_Evolution_Component_handleURI (component_info->iface, uri, ev);
- /* not an error not to implement it */
- if (ev->_id != NULL && strcmp(ev->_id, ex_CORBA_NO_IMPLEMENT) == 0)
- memset(ev, 0, sizeof(*ev));
+ /* Destroy all watched windows. Note, we iterate over a -copy-
+ * of the watched windows list because the act of destroying a
+ * watched window will modify the watched windows list, which
+ * would derail the iteration. */
+ list = g_list_copy (e_shell_get_watched_windows (shell));
+ g_list_foreach (list, (GFunc) gtk_widget_destroy, NULL);
+ g_list_free (list);
}
static void
-impl_Shell_setLineStatus (PortableServer_Servant servant,
- CORBA_boolean online,
- CORBA_Environment *ev)
+shell_prepare_for_quit (EShell *shell)
{
- BonoboObject *bonobo_object;
- EShell *shell;
+ GList *list, *iter;
- if (raise_exception_if_not_ready (servant, ev))
+ /* Are preparations already in progress? */
+ if (shell->priv->preparing_for_quit != NULL)
return;
- bonobo_object = bonobo_object_from_servant (servant);
- shell = E_SHELL (bonobo_object);
+ g_message ("Preparing to quit...");
- /* let the password manager know out online status */
- e_passwords_set_online(online);
+ shell->priv->preparing_for_quit =
+ e_activity_new (_("Preparing to quit..."));
- if (online)
- e_shell_set_line_status (shell, GNOME_Evolution_USER_ONLINE);
- else
- e_shell_set_line_status (shell, GNOME_Evolution_USER_OFFLINE);
-}
-/*
-static GNOME_Evolution_Component
-impl_Shell_findComponent(PortableServer_Servant servant,
- const CORBA_char *id,
- CORBA_Environment *ev)
-{
- EShell *shell;
- EComponentInfo *ci;
-
- if (raise_exception_if_not_ready (servant, ev))
- return CORBA_OBJECT_NIL;
-
- shell = (EShell *)bonobo_object_from_servant (servant);
- ci = e_component_registry_peek_info(shell->priv->component_registry, ECR_FIELD_ALIAS, id);
- if (ci == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_ComponentNotFound, NULL);
- return CORBA_OBJECT_NIL;
- } else if (ci->iface == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_NotReady, NULL);
- return CORBA_OBJECT_NIL;
- } else {
- return ci->iface;
- }
-}
-*/
+ g_object_add_toggle_ref (
+ G_OBJECT (shell->priv->preparing_for_quit),
+ (GToggleNotify) shell_ready_for_quit, shell);
-/* EShellWindow handling and bookkeeping. */
+ g_object_add_weak_pointer (
+ G_OBJECT (shell->priv->preparing_for_quit),
+ &shell->priv->preparing_for_quit);
-static gint
-window_delete_event_cb (GtkWidget *widget,
- GdkEventAny *ev,
- gpointer data)
-{
- EShell *shell;
+ g_signal_emit (
+ shell, signals[PREPARE_FOR_QUIT], 0,
+ shell->priv->preparing_for_quit);
- g_return_val_if_fail (E_IS_SHELL_WINDOW (widget), TRUE);
- shell = E_SHELL (data);
+ g_object_unref (shell->priv->preparing_for_quit);
- return ! e_shell_request_close_window (shell, E_SHELL_WINDOW (widget));
+ /* Desensitize all watched windows to prevent user action. */
+ list = e_shell_get_watched_windows (shell);
+ for (iter = list; iter != NULL; iter = iter->next)
+ gtk_widget_set_sensitive (GTK_WIDGET (iter->data), FALSE);
}
static gboolean
-notify_no_windows_left_idle_cb (gpointer data)
+shell_request_quit (EShell *shell)
{
- EShell *shell;
- EShellPrivate *priv;
+ /* Are preparations already in progress? */
+ if (shell->priv->preparing_for_quit != NULL)
+ return TRUE;
+
+ /* Give the application a chance to cancel quit. */
+ shell->priv->quit_cancelled = FALSE;
+ g_signal_emit (shell, signals[QUIT_REQUESTED], 0);
+
+ return !shell->priv->quit_cancelled;
+}
- shell = E_SHELL (data);
- priv = shell->priv;
+static void
+shell_load_modules (EShell *shell)
+{
+ GList *modules;
- set_interactive (shell, FALSE);
+ /* Load all shared library modules. */
+ modules = e_module_load_all_in_directory (EVOLUTION_MODULEDIR);
- g_signal_emit (shell, signals [NO_WINDOWS_LEFT], 0);
+ while (modules != NULL) {
+ g_type_module_unuse (G_TYPE_MODULE (modules->data));
+ modules = g_list_delete_link (modules, modules);
+ }
+}
- if (priv->iid != NULL)
- bonobo_activation_active_server_unregister (priv->iid,
- bonobo_object_corba_objref (BONOBO_OBJECT (shell)));
- bonobo_object_unref (BONOBO_OBJECT (shell));
+/* Helper for shell_process_backend() */
+static void
+shell_split_and_insert_items (GHashTable *hash_table,
+ const gchar *items,
+ EShellBackend *shell_backend)
+{
+ gpointer key;
+ gchar **strv;
+ gint ii;
- return FALSE;
+ strv = g_strsplit_set (items, ":", -1);
+
+ for (ii = 0; strv[ii] != NULL; ii++) {
+ key = (gpointer) g_intern_string (strv[ii]);
+ g_hash_table_insert (hash_table, key, shell_backend);
+ }
+
+ g_strfreev (strv);
}
static void
-window_weak_notify (gpointer data,
- GObject *where_the_object_was)
+shell_process_backend (EShell *shell,
+ EShellBackend *shell_backend)
{
- EShell *shell;
- gint num_windows;
+ EShellBackendClass *class;
+ GHashTable *backends_by_name;
+ GHashTable *backends_by_scheme;
+ const gchar *string;
- shell = E_SHELL (data);
+ shell->priv->loaded_backends = g_list_insert_sorted (
+ shell->priv->loaded_backends, shell_backend,
+ (GCompareFunc) e_shell_backend_compare);
- num_windows = g_list_length (shell->priv->windows);
+ /* Bookkeeping */
- /* If this is our last window, save settings now because in the callback
- for no_windows_left shell->priv->windows will be NULL and settings won't
- be saved because of that. */
- if (num_windows == 1)
- e_shell_save_settings (shell);
+ class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
+ backends_by_name = shell->priv->backends_by_name;
+ backends_by_scheme = shell->priv->backends_by_scheme;
- shell->priv->windows = g_list_remove (shell->priv->windows, where_the_object_was);
+ if ((string = class->name) != NULL)
+ g_hash_table_insert (
+ backends_by_name, (gpointer)
+ g_intern_string (string), shell_backend);
- if (shell->priv->windows == NULL) {
- bonobo_object_ref (BONOBO_OBJECT (shell));
- g_idle_add (notify_no_windows_left_idle_cb, shell);
- }
-}
+ if ((string = class->aliases) != NULL)
+ shell_split_and_insert_items (
+ backends_by_name, string, shell_backend);
-/* GObject methods. */
+ if ((string = class->schemes) != NULL)
+ shell_split_and_insert_items (
+ backends_by_scheme, string, shell_backend);
+}
static void
-impl_dispose (GObject *object)
+shell_create_backends (EShell *shell)
{
- EShell *shell;
- EShellPrivate *priv;
- GList *p;
+ GType *children;
+ guint ii, n_children;
- shell = E_SHELL (object);
- priv = shell->priv;
+ /* Create an instance of each EShellBackend subclass. */
+ children = g_type_children (E_TYPE_SHELL_BACKEND, &n_children);
- priv->is_initialized = FALSE;
+ for (ii = 0; ii < n_children; ii++) {
+ EShellBackend *shell_backend;
+ GType type = children[ii];
-#if 0 /* FIXME */
- if (priv->uri_schema_registry != NULL) {
- g_object_unref (priv->uri_schema_registry);
- priv->uri_schema_registry = NULL;
+ shell_backend = g_object_new (type, "shell", shell, NULL);
+ shell_process_backend (shell, shell_backend);
}
-#endif
- if (priv->component_registry != NULL) {
- g_object_unref (priv->component_registry);
- priv->component_registry = NULL;
- }
+ g_free (children);
+}
- if (priv->quit_timeout) {
- g_source_remove(priv->quit_timeout);
- priv->quit_timeout = 0;
- }
+static void
+shell_sm_quit_requested_cb (EShell *shell,
+ EggSMClient *sm_client)
+{
+ gboolean will_quit;
- for (p = priv->windows; p != NULL; p = p->next) {
- EShellWindow *window;
+ /* If preparations are already in progress then we have already
+ * committed ourselves to quitting, and can answer 'yes'. */
+ if (shell->priv->preparing_for_quit == NULL)
+ will_quit = shell_request_quit (shell);
+ else
+ will_quit = TRUE;
- window = E_SHELL_WINDOW (p->data);
+ egg_sm_client_will_quit (sm_client, will_quit);
+}
- g_signal_handlers_disconnect_by_func (window, G_CALLBACK (window_delete_event_cb), shell);
- g_object_weak_unref (G_OBJECT (window), window_weak_notify, shell);
+static void
+shell_sm_quit_cancelled_cb (EShell *shell,
+ EggSMClient *sm_client)
+{
+ /* Nothing to do. This is just to aid debugging. */
+}
- gtk_object_destroy (GTK_OBJECT (window));
+static void
+shell_sm_quit_cb (EShell *shell,
+ EggSMClient *sm_client)
+{
+ shell_prepare_for_quit (shell);
+}
+
+static void
+shell_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_NETWORK_AVAILABLE:
+ e_shell_set_network_available (
+ E_SHELL (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_ONLINE:
+ e_shell_set_online (
+ E_SHELL (object),
+ g_value_get_boolean (value));
+ return;
}
- g_list_free (priv->windows);
- priv->windows = NULL;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
- /* No unreffing for these as they are aggregate. */
- /* bonobo_object_unref (BONOBO_OBJECT (priv->corba_storage_registry)); */
+static void
+shell_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_NETWORK_AVAILABLE:
+ g_value_set_boolean (
+ value, e_shell_get_network_available (
+ E_SHELL (object)));
+ return;
- if (priv->settings_dialog.widget != NULL) {
- gtk_widget_destroy (priv->settings_dialog.widget);
- priv->settings_dialog.widget = NULL;
- }
+ case PROP_ONLINE:
+ g_value_set_boolean (
+ value, e_shell_get_online (
+ E_SHELL (object)));
+ return;
- if (priv->line_status_listener) {
- priv->line_status_listener->complete = NULL;
- bonobo_object_unref(BONOBO_OBJECT(priv->line_status_listener));
- priv->line_status_listener = NULL;
+ case PROP_SHELL_SETTINGS:
+ g_value_set_object (
+ value, e_shell_get_shell_settings (
+ E_SHELL (object)));
+ return;
}
- g_free (priv->iid);
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-impl_finalize (GObject *object)
+shell_dispose (GObject *object)
{
- EShell *shell;
EShellPrivate *priv;
- shell = E_SHELL (object);
- priv = shell->priv;
+ priv = E_SHELL_GET_PRIVATE (object);
- g_list_foreach (priv->crash_type_names, (GFunc) g_free, NULL);
- g_list_free (priv->crash_type_names);
+ if (priv->settings != NULL) {
+ g_object_unref (priv->settings);
+ priv->settings = NULL;
+ }
- g_free (priv);
+ if (priv->gconf_client != NULL) {
+ g_object_unref (priv->gconf_client);
+ priv->gconf_client = NULL;
+ }
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
+ if (priv->preferences_window != NULL) {
+ g_object_unref (priv->preferences_window);
+ priv->preferences_window = NULL;
+ }
-/* Initialization. */
+ g_list_foreach (priv->loaded_backends, (GFunc) g_object_unref, NULL);
+ g_list_free (priv->loaded_backends);
+ priv->loaded_backends = NULL;
-static void
-e_shell_class_init (EShellClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_Shell__epv *epv;
-
- parent_class = g_type_class_ref(PARENT_TYPE);
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- signals[NO_WINDOWS_LEFT] =
- g_signal_new ("no_windows_left",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EShellClass, no_windows_left),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[LINE_STATUS_CHANGED] =
- g_signal_new ("line_status_changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EShellClass, line_status_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- signals[NEW_WINDOW_CREATED] =
- g_signal_new ("new_window_created",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EShellClass, new_window_created),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
-
- epv = & klass->epv;
- epv->createNewWindow = impl_Shell_createNewWindow;
- epv->handleURI = impl_Shell_handleURI;
- epv->setLineStatus = impl_Shell_setLineStatus;
-/* epv->findComponent = impl_Shell_findComponent;*/
+ if (priv->preparing_for_line_change != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->preparing_for_line_change),
+ &priv->preparing_for_line_change);
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-e_shell_init (EShell *shell)
+shell_finalize (GObject *object)
{
EShellPrivate *priv;
- priv = g_new0 (EShellPrivate, 1);
- priv->line_status = E_SHELL_LINE_STATUS_OFFLINE;
- priv->component_registry = e_component_registry_new ();
+ priv = E_SHELL_GET_PRIVATE (object);
- shell->priv = priv;
+ g_hash_table_destroy (priv->backends_by_name);
+ g_hash_table_destroy (priv->backends_by_scheme);
- priv->line_status_listener = evolution_listener_new(set_line_status_complete, shell);
+ /* Indicates a clean shut down to the next session. */
+ if (!unique_app_is_running (UNIQUE_APP (object)))
+ e_file_lock_destroy ();
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-detect_version (GConfClient *gconf, gint *major, gint *minor, gint *revision)
+shell_constructed (GObject *object)
{
- gchar *val, *evolution_dir;
- struct stat st;
-
- evolution_dir = g_build_filename (g_get_home_dir (), "evolution", NULL);
-
- val = gconf_client_get_string(gconf, "/apps/evolution/version", NULL);
- if (val) {
- /* Since 1.4.0 We've been keeping the version key in gconf */
- sscanf(val, "%d.%d.%d", major, minor, revision);
- g_free(val);
- } else if (g_lstat (evolution_dir, &st) != 0 || !S_ISDIR (st.st_mode)) {
- /* If ~/evolution does not exit or is not a directory it must be a new installation */
- *major = 0;
- *minor = 0;
- *revision = 0;
- } else {
- xmlDocPtr config_doc;
- xmlNodePtr source;
- gchar *tmp;
-
- tmp = g_build_filename (evolution_dir, "config.xmldb", NULL);
- config_doc = e_xml_parse_file (tmp);
- g_free (tmp);
- tmp = NULL;
-
- if (config_doc
- && (source = e_bconf_get_path (config_doc, "/Shell"))
- && (tmp = e_bconf_get_value (source, "upgrade_from_1_0_to_1_2_performed"))
- && tmp[0] == '1' ) {
- *major = 1;
- *minor = 2;
- *revision = 0;
- } else {
- *major = 1;
- *minor = 0;
- *revision = 0;
- }
- g_free (tmp);
- if (config_doc)
- xmlFreeDoc (config_doc);
- }
+ /* The first EShell instance is the default. */
+ if (default_shell == NULL)
+ default_shell = g_object_ref (object);
+
+ /* UniqueApp will have by this point determined whether we're
+ * the only Evolution process running. If so, proceed normally.
+ * Otherwise we just issue commands to the other process. */
+ if (unique_app_is_running (UNIQUE_APP (object)))
+ return;
+
+ e_file_lock_create ();
- g_free (evolution_dir);
+ shell_load_modules (E_SHELL (object));
+ shell_create_backends (E_SHELL (object));
+
+ e_shell_migrate_attempt (E_SHELL (object));
}
-/* calls components to perform upgrade */
static gboolean
-attempt_upgrade (EShell *shell, gint major, gint minor, gint revision)
+shell_message_handle_new (EShell *shell,
+ UniqueMessageData *data)
{
- GSList *component_infos, *p;
- gboolean success;
- gint res;
-
- success = TRUE;
-
- component_infos = e_component_registry_peek_list (shell->priv->component_registry);
- for (p = component_infos; success && p != NULL; p = p->next) {
- const EComponentInfo *info = p->data;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Component_upgradeFromVersion (info->iface, major, minor, revision, &ev);
-
- if (BONOBO_EX (&ev)) {
- gchar *exception_text;
- CORBA_char *id = CORBA_exception_id(&ev);
-
- if (strcmp (id, ex_CORBA_NO_IMPLEMENT) == 0) {
- /* Ignore components that do not implement this version, it
- might just mean that they don't need an upgrade path. */
- } else if (strcmp (id, ex_GNOME_Evolution_Component_UpgradeFailed) == 0) {
- GNOME_Evolution_Component_UpgradeFailed *ex = CORBA_exception_value(&ev);
-
- res = e_error_run(NULL, "shell:upgrade-failed", ex->what, ex->why, NULL);
- if (res == GTK_RESPONSE_CANCEL)
- success = FALSE;
- } else if (strcmp (id, ex_GNOME_Evolution_Component_UnsupportedVersion) == 0) {
- /* This is non-fatal */
- /* DO WE CARE??? */
- printf("Upgrade of component failed, unsupported prior version\n");
- } else {
- exception_text = bonobo_exception_get_text (&ev);
- res = e_error_run(NULL, "shell:upgrade-failed", exception_text, _("Unknown system error."), NULL);
- g_free (exception_text);
- if (res == GTK_RESPONSE_CANCEL)
- success = FALSE;
- }
- }
- CORBA_exception_free (&ev);
- }
+ gchar *view_name;
+
+ view_name = unique_message_data_get_text (data);
+ e_shell_create_shell_window (shell, view_name);
+ g_free (view_name);
- return success;
+ return TRUE;
}
-/**
- * e_shell_construct:
- * @shell: An EShell object to construct
- * @iid: OAFIID for registering the shell into the name server
- * @startup_line_mode: How to set up the line mode (online or offline) initally.
- *
- * Construct @shell so that it uses the specified @corba_object.
- *
- * Return value: The result of the operation.
- **/
-EShellConstructResult
-e_shell_construct (EShell *shell,
- const gchar *iid,
- EShellStartupLineMode startup_line_mode)
+static gboolean
+shell_message_handle_open (EShell *shell,
+ UniqueMessageData *data)
{
- EShellPrivate *priv;
- CORBA_Object corba_object;
- gboolean start_online;
- GSList *component;
-
- g_return_val_if_fail (E_IS_SHELL (shell), E_SHELL_CONSTRUCT_RESULT_INVALIDARG);
- g_return_val_if_fail (startup_line_mode == E_SHELL_STARTUP_LINE_MODE_CONFIG
- || startup_line_mode == E_SHELL_STARTUP_LINE_MODE_ONLINE
- || startup_line_mode == E_SHELL_STARTUP_LINE_MODE_OFFLINE,
- E_SHELL_CONSTRUCT_RESULT_INVALIDARG);
-
- priv = shell->priv;
- priv->iid = g_strdup (iid);
-
- /* Now we can register into OAF. Notice that we shouldn't be
- registering into OAF until we are sure we can complete. */
-
- /* FIXME: Multi-display stuff. */
- corba_object = bonobo_object_corba_objref (BONOBO_OBJECT (shell));
- if (bonobo_activation_active_server_register (iid, corba_object) != Bonobo_ACTIVATION_REG_SUCCESS)
- return E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER;
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-
- /* activate all the components (peek list does this implictly) */
- /* Do we really need to assign the result of this to the list? */
- component = e_component_registry_peek_list (shell->priv->component_registry);
-
- e_shell_attempt_upgrade(shell);
-
- priv->is_initialized = TRUE;
-
- switch (startup_line_mode) {
- case E_SHELL_STARTUP_LINE_MODE_CONFIG:
- start_online = ! get_config_start_offline ();
- break;
- case E_SHELL_STARTUP_LINE_MODE_ONLINE:
- start_online = TRUE;
- break;
- case E_SHELL_STARTUP_LINE_MODE_OFFLINE:
- start_online = FALSE;
- break;
- default:
- start_online = FALSE; /* Make compiler happy. */
- g_return_val_if_reached(E_SHELL_CONSTRUCT_RESULT_OK);
- }
+ gchar **uris;
- e_passwords_set_online(start_online);
+ uris = unique_message_data_get_uris (data);
+ e_shell_handle_uris (shell, uris);
+ g_strfreev (uris);
- if (start_online)
- e_shell_set_line_status (shell, GNOME_Evolution_USER_ONLINE);
- else
- e_shell_set_line_status (shell, GNOME_Evolution_USER_OFFLINE);
+ return TRUE;
+}
+
+static gboolean
+shell_message_handle_close (EShell *shell,
+ UniqueMessageData *data)
+{
+ e_shell_quit (shell);
- return E_SHELL_CONSTRUCT_RESULT_OK;
+ return TRUE;
}
-/**
- * e_shell_new:
- * @start_online: Whether to start in on-line mode or not.
- * @construct_result_return: A pointer to an EShellConstructResult variable into
- * which the result of the operation will be stored.
- *
- * Create a new EShell.
- *
- * Return value:
- **/
-EShell *
-e_shell_new (EShellStartupLineMode startup_line_mode,
- EShellConstructResult *construct_result_return)
+static UniqueResponse
+shell_message_received (UniqueApp *app,
+ gint command,
+ UniqueMessageData *data,
+ guint time_)
{
- EShell *new;
- EShellConstructResult construct_result;
+ EShell *shell = E_SHELL (app);
- new = g_object_new (e_shell_get_type (), NULL);
+ switch (command) {
+ case UNIQUE_ACTIVATE:
+ break; /* use the default behavior */
- construct_result = e_shell_construct (new, E_SHELL_OAFIID, startup_line_mode);
+ case UNIQUE_NEW:
+ if (shell_message_handle_new (shell, data))
+ return UNIQUE_RESPONSE_OK;
+ break;
- if (construct_result != E_SHELL_CONSTRUCT_RESULT_OK) {
- *construct_result_return = construct_result;
- bonobo_object_unref (BONOBO_OBJECT (new));
- return NULL;
- }
+ case UNIQUE_OPEN:
+ if (shell_message_handle_open (shell, data))
+ return UNIQUE_RESPONSE_OK;
+ break;
- *construct_result_return = E_SHELL_CONSTRUCT_RESULT_OK;
- return new;
-}
+ case UNIQUE_CLOSE:
+ if (shell_message_handle_close (shell, data))
+ return UNIQUE_RESPONSE_OK;
+ break;
-static gint
-remove_dir(const gchar *root, const gchar *path)
-{
- GDir *dir;
- const gchar *dname;
- gint res = -1;
- gchar *new = NULL;
- struct stat st;
-
- dir = g_dir_open(path, 0, NULL);
- if (dir == NULL)
- return -1;
-
- while ( (dname = g_dir_read_name(dir)) ) {
- new = g_build_filename(path, dname, NULL);
- if (g_stat(new, &st) == -1)
- goto fail;
-
- /* make sure we're really removing something from evolution dir */
- g_return_val_if_fail (strlen(path) >= strlen(root)
- && strncmp(root, path, strlen(root)) == 0, -1);
-
- if (S_ISDIR(st.st_mode)) {
- if (remove_dir(root, new) == -1)
- goto fail;
- } else {
- if (g_unlink(new) == -1)
- goto fail;
- }
- g_free(new);
- new = NULL;
+ default:
+ break;
}
- res = g_rmdir(path);
-fail:
- g_free(new);
- g_dir_close(dir);
- return res;
+ /* Chain up to parent's message_received() method. */
+ return UNIQUE_APP_CLASS (parent_class)->
+ message_received (app, command, data, time_);
}
-/**
- * e_shell_attempt_upgrade:
- * @shell:
- *
- * Upgrade config and components from the currently installed version.
- *
- * Return value: %TRUE If it works. If it fails the application will exit.
- **/
-gboolean
-e_shell_attempt_upgrade (EShell *shell)
+static void
+shell_class_init (EShellClass *class)
{
- GConfClient *gconf_client;
- gint major = 0, minor = 0, revision = 0;
- gint lmajor, lminor, lrevision;
- gint cmajor, cminor, crevision;
- gchar *version_string, *last_version = NULL;
- gint done_upgrade = FALSE;
- gchar *oldpath;
- struct stat st;
- ESEvent *ese;
-
- gconf_client = gconf_client_get_default();
-
- oldpath = g_build_filename(g_get_home_dir(), "evolution", NULL);
-
- g_return_val_if_fail (sscanf(BASE_VERSION, "%u.%u", &cmajor, &cminor) == 2, TRUE);
- crevision = atoi(UPGRADE_REVISION);
-
- detect_version (gconf_client, &major, &minor, &revision);
-
- if (!(cmajor > major
- || (cmajor == major && cminor > minor)
- || (cminor == minor && crevision > revision)))
- goto check_old;
-
- /* if upgrading from < 1.5, we need to copy most data from ~/evolution to ~/.evolution */
- if (major == 1 && minor < 5) {
- long size, space;
-
- size = e_fsutils_usage(oldpath);
- space = e_fsutils_avail(g_get_home_dir());
- if (size != -1 && space != -1 && space < size) {
- gchar *required = g_strdup_printf(_("%ld KB"), size);
- gchar *have = g_strdup_printf(_("%ld KB"), space);
-
- e_error_run(NULL, "shell:upgrade-nospace", required, have, NULL);
- g_free(required);
- g_free(have);
- _exit(0);
- }
- }
+ GObjectClass *object_class;
+ UniqueAppClass *unique_app_class;
- if (!attempt_upgrade (shell, major, minor, revision))
- _exit(0);
-
- /* mark as upgraded */
- version_string = g_strdup_printf ("%s.%s", BASE_VERSION, UPGRADE_REVISION);
- gconf_client_set_string (gconf_client, "/apps/evolution/version", version_string, NULL);
- done_upgrade = TRUE;
-
-check_old:
- /* if the last upgraded version was old, check for stuff to remove */
- if (done_upgrade
- || (last_version = gconf_client_get_string (gconf_client, "/apps/evolution/last_version", NULL)) == NULL
- || sscanf(last_version, "%d.%d.%d", &lmajor, &lminor, &lrevision) != 3) {
- lmajor = major;
- lminor = minor;
- lrevision = revision;
- }
- g_free(last_version);
-
- if (lmajor == 1 && lminor < 5
- && g_stat(oldpath, &st) == 0
- && S_ISDIR(st.st_mode)) {
- gint res;
-
- last_version = g_strdup_printf("%d.%d.%d", lmajor, lminor, lrevision);
- res = e_error_run(NULL, "shell:upgrade-remove-1-4", last_version, NULL);
- g_free(last_version);
-
- switch (res) {
- case GTK_RESPONSE_OK: /* 'delete' */
- if (e_error_run(NULL, "shell:upgrade-remove-1-4-confirm", NULL) == GTK_RESPONSE_OK)
- remove_dir(oldpath, oldpath);
- else
- break;
- /* falls through */
- case GTK_RESPONSE_ACCEPT: /* 'keep' */
- lmajor = cmajor;
- lminor = cminor;
- lrevision = crevision;
- break;
- default:
- /* cancel - noop */
- break;
- }
- } else {
- /* otherwise 'last version' is now the same as current */
- lmajor = cmajor;
- lminor = cminor;
- lrevision = crevision;
- }
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EShellPrivate));
- last_version = g_strdup_printf("%d.%d.%d", lmajor, lminor, lrevision);
- gconf_client_set_string (gconf_client, "/apps/evolution/last_version", last_version, NULL);
- g_free(last_version);
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = shell_set_property;
+ object_class->get_property = shell_get_property;
+ object_class->dispose = shell_dispose;
+ object_class->finalize = shell_finalize;
+ object_class->constructed = shell_constructed;
- g_free(oldpath);
- g_object_unref (gconf_client);
+ unique_app_class = UNIQUE_APP_CLASS (class);
+ unique_app_class->message_received = shell_message_received;
- /** @Event: Shell attempted upgrade
- * @Id: upgrade.done
- * @Target: ESMenuTargetState
+ /**
+ * EShell:network-available
*
- * This event is emitted whenever the shell successfully attempts an upgrade.
+ * Whether the network is available.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_NETWORK_AVAILABLE,
+ g_param_spec_boolean (
+ "network-available",
+ _("Network Available"),
+ _("Whether the network is available"),
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShell:online
*
- */
- ese = es_event_peek();
- e_event_emit((EEvent *)ese, "upgrade.done", (EEventTarget *)es_event_target_new_upgrade(ese, cmajor, cminor, crevision));
-
- return TRUE;
+ * Whether the shell is online.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_ONLINE,
+ g_param_spec_boolean (
+ "online",
+ _("Online"),
+ _("Whether the shell is online"),
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * EShell:settings
+ *
+ * The #EShellSettings object stores application settings.
+ **/
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_SETTINGS,
+ g_param_spec_object (
+ "shell-settings",
+ _("Shell Settings"),
+ _("Application-wide settings"),
+ E_TYPE_SHELL_SETTINGS,
+ G_PARAM_READABLE));
+
+ /**
+ * EShell::event
+ * @shell: the #EShell which emitted the signal
+ * @event_data: data associated with the event
+ *
+ * This signal is used to broadcast custom events to the entire
+ * application. The nature of @event_data depends on the event
+ * being broadcast. The signal's detail denotes the event.
+ **/
+ signals[EVENT] = g_signal_new (
+ "event",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ /**
+ * EShell::handle-uri
+ * @shell: the #EShell which emitted the signal
+ * @uri: the URI to be handled
+ *
+ * Emitted when @shell receives a URI to be handled, usually by
+ * way of a command-line argument. An #EShellBackend should listen
+ * for this signal and try to handle the URI, usually by opening an
+ * editor window for the identified resource.
+ *
+ * Returns: %TRUE if the URI could be handled, %FALSE otherwise
+ **/
+ signals[HANDLE_URI] = g_signal_new (
+ "handle-uri",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, g_signal_accumulator_true_handled, NULL,
+ e_marshal_BOOLEAN__STRING,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_STRING);
+
+ /**
+ * EShell::prepare-for-offline
+ * @shell: the #EShell which emitted the signal
+ * @activity: the #EActivity for offline preparations
+ *
+ * Emitted when the user elects to work offline. An #EShellBackend
+ * should listen for this signal and make preparations for working
+ * in offline mode.
+ *
+ * If preparations for working offline cannot immediately be
+ * completed (such as when synchronizing with a remote server),
+ * the #EShellBackend should reference the @activity until
+ * preparations are complete, and then unreference the @activity.
+ * This will delay Evolution from actually going to offline mode
+ * until all backends have unreferenced @activity.
+ **/
+ signals[PREPARE_FOR_OFFLINE] = g_signal_new (
+ "prepare-for-offline",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACTIVITY);
+
+ /**
+ * EShell::prepare-for-online
+ * @shell: the #EShell which emitted the signal
+ * @activity: the #EActivity for offline preparations
+ *
+ * Emitted when the user elects to work online. An #EShellBackend
+ * should listen for this signal and make preparations for working
+ * in online mode.
+ *
+ * If preparations for working online cannot immediately be
+ * completed (such as when re-connecting to a remote server), the
+ * #EShellBackend should reference the @activity until preparations
+ * are complete, and then unreference the @activity. This will
+ * delay Evolution from actually going to online mode until all
+ * backends have unreferenced @activity.
+ **/
+ signals[PREPARE_FOR_ONLINE] = g_signal_new (
+ "prepare-for-online",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACTIVITY);
+
+ /**
+ * EShell::prepare-for-quit
+ * @shell: the #EShell which emitted the signal
+ * @activity: the #EActivity for quit preparations
+ *
+ * Emitted when the user elects to quit the application, after
+ * #EShell::quit-requested. An #EShellBackend should listen for
+ * this signal and make preparations for shutting down.
+ *
+ * If preparations for shutting down cannot immediately be completed
+ * (such as when there are uncompleted network operations), the
+ * #EShellBackend should reference the @activity until preparations
+ * are complete, and then unreference the @activity. This will
+ * delay Evolution from actually shutting down until all backends
+ * have unreferenced @activity.
+ **/
+ signals[PREPARE_FOR_QUIT] = g_signal_new (
+ "prepare-for-quit",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_ACTIVITY);
+
+ /**
+ * EShell::quit-requested
+ * @shell: the #EShell which emitted the signal
+ *
+ * Emitted when the user elects to quit the application, before
+ * #EShell::prepare-for-quit.
+ *
+ * #EShellBackend<!-- -->s and editor windows can listen for
+ * this signal to prompt the user to save changes or finish
+ * scheduled operations immediately (such as sending mail in
+ * Outbox). If the user elects to cancel, the signal handler
+ * should call e_shell_cancel_quit() to abort the quit.
+ **/
+ signals[QUIT_REQUESTED] = g_signal_new (
+ "quit-requested",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * EShell::send-receive
+ * @shell: the #EShell which emitted the signal
+ * @parent: a parent #GtkWindow
+ *
+ * Emitted when the user chooses the "Send / Receive" action.
+ * The parent window can be used for showing transient windows.
+ **/
+ signals[SEND_RECEIVE] = g_signal_new (
+ "send-receive",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_WINDOW);
+
+ /**
+ * EShell::window-created
+ * @shell: the #EShell which emitted the signal
+ * @window: the newly created #GtkWindow
+ *
+ * Emitted when @shell begins watching a newly created window.
+ **/
+ signals[WINDOW_CREATED] = g_signal_new (
+ "window-created",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_WINDOW);
+
+ /**
+ * EShell::window-destroyed
+ * @shell: the #EShell which emitted the signal
+ *
+ * Emitted when a watched is destroyed.
+ **/
+ signals[WINDOW_DESTROYED] = g_signal_new (
+ "window-destroyed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /* Install some application-wide settings. */
+
+ e_shell_settings_install_property (
+ g_param_spec_string (
+ "file-chooser-folder",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
}
-/**
- * e_shell_create_window:
- * @shell: The shell for which to create a new window.
- * @component_id: Id or alias of the component to display in the new window.
- * @template_window: Window from which to copy the window settings (can be %NULL).
- *
- * Create a new window for @uri.
- *
- * Return value: The new window.
- **/
-EShellWindow *
-e_shell_create_window (EShell *shell,
- const gchar *component_id,
- EShellWindow *template_window)
+static void
+shell_init (EShell *shell)
{
- EShellWindow *window;
+ GHashTable *backends_by_name;
+ GHashTable *backends_by_scheme;
+ EggSMClient *sm_client;
- /* FIXME need to actually copy settings from template_window. */
+ shell->priv = E_SHELL_GET_PRIVATE (shell);
- g_return_val_if_fail (shell != NULL, NULL);
- g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ backends_by_name = g_hash_table_new (g_str_hash, g_str_equal);
+ backends_by_scheme = g_hash_table_new (g_str_hash, g_str_equal);
- window = E_SHELL_WINDOW (e_shell_window_new (shell, component_id));
+ shell->priv->settings = g_object_new (E_TYPE_SHELL_SETTINGS, NULL);
+ shell->priv->gconf_client = gconf_client_get_default ();
+ shell->priv->preferences_window = e_preferences_window_new ();
+ shell->priv->backends_by_name = backends_by_name;
+ shell->priv->backends_by_scheme = backends_by_scheme;
+ shell->priv->safe_mode = e_file_lock_exists ();
- g_signal_connect (window, "delete_event", G_CALLBACK (window_delete_event_cb), shell);
- g_object_weak_ref (G_OBJECT (window), window_weak_notify, shell);
- shell->priv->windows = g_list_prepend (shell->priv->windows, window);
+ g_object_ref_sink (shell->priv->preferences_window);
- g_signal_emit (shell, signals[NEW_WINDOW_CREATED], 0, window);
+#if NM_SUPPORT
+ e_shell_dbus_initialize (shell);
+#endif
- gtk_widget_show (GTK_WIDGET (window));
+ shell_parse_debug_string (shell);
- e_error_default_parent((GtkWindow *)window);
+ g_signal_connect (
+ shell, "notify::online",
+ G_CALLBACK (shell_notify_online_cb), NULL);
- set_interactive (shell, TRUE);
+ /* XXX Do this after creating the EShellSettings instance,
+ * otherwise the GConf bindings will not get set up. */
- if (!session_started) {
- ESEvent *ese;
+ e_shell_settings_install_property_for_key (
+ "start-offline",
+ "/apps/evolution/shell/start_offline");
- session_started = TRUE;
- ese = es_event_peek();
- e_event_emit((EEvent *)ese, "started.done", (EEventTarget *)es_event_target_new_shell(ese, shell));
- }
- return window;
-}
+ e_shell_settings_install_property_for_key (
+ "disable-application-handlers",
+ "/desktop/gnome/lockdown/disable_application_handlers");
-gboolean
-e_shell_request_close_window (EShell *shell,
- EShellWindow *shell_window)
-{
- g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
- g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
+ e_shell_settings_install_property_for_key (
+ "disable-command-line",
+ "/desktop/gnome/lockdown/disable_command_line");
- e_shell_save_settings (shell);
+ e_shell_settings_install_property_for_key (
+ "disable-printing",
+ "/desktop/gnome/lockdown/disable_printing");
- if (g_list_length (shell->priv->windows) != 1) {
- /* Not the last window. */
- return TRUE;
+ e_shell_settings_install_property_for_key (
+ "disable-print-setup",
+ "/desktop/gnome/lockdown/disable_print_setup");
+
+ e_shell_settings_install_property_for_key (
+ "disable-save-to-disk",
+ "/desktop/gnome/lockdown/disable_save_to_disk");
+
+ /*** Session Management ***/
+
+ sm_client = egg_sm_client_get ();
+
+ /* Not participating in session saving yet. */
+ egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_NO_RESTART);
+
+ g_signal_connect_swapped (
+ sm_client, "quit-requested",
+ G_CALLBACK (shell_sm_quit_requested_cb), shell);
+
+ g_signal_connect_swapped (
+ sm_client, "quit-cancelled",
+ G_CALLBACK (shell_sm_quit_cancelled_cb), shell);
+
+ g_signal_connect_swapped (
+ sm_client, "quit",
+ G_CALLBACK (shell_sm_quit_cb), shell);
+}
+
+GType
+e_shell_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EShellClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) shell_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EShell),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) shell_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ UNIQUE_TYPE_APP, "EShell", &type_info, 0);
}
- return e_shell_quit(shell);
+ return type;
}
-#if 0 /* FIXME */
/**
- * e_shell_peek_uri_schema_registry:
- * @shell: An EShell object.
+ * e_shell_get_default:
*
- * Get the schema registry associated to @shell.
+ * Returns the #EShell created by <function>main()</function>.
*
- * Return value: A pointer to the EUriSchemaRegistry associated to @shell.
+ * Try to obtain the #EShell from elsewhere if you can. This function
+ * is intended as a temporary workaround for when that proves difficult.
+ *
+ * Returns: the #EShell singleton
**/
-EUriSchemaRegistry *
-e_shell_peek_uri_schema_registry (EShell *shell)
+EShell *
+e_shell_get_default (void)
{
- g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ /* Emit a warning if we call this too early. */
+ g_return_val_if_fail (default_shell != NULL, NULL);
- return shell->priv->uri_schema_registry;
+ return default_shell;
}
-#endif
/**
- * e_shell_peek_component_registry:
- * @shell:
+ * e_shell_get_shell_backends:
+ * @shell: an #EShell
*
- * Get the component registry associated to @shell.
+ * Returns a list of loaded #EShellBackend instances. The list is
+ * owned by @shell and should not be modified or freed.
*
- * Return value:
+ * Returns: a list of loaded #EShellBackend instances
**/
-EComponentRegistry *
-e_shell_peek_component_registry (EShell *shell)
+GList *
+e_shell_get_shell_backends (EShell *shell)
{
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- return shell->priv->component_registry;
+ return shell->priv->loaded_backends;
}
/**
- * e_shell_save_settings:
- * @shell:
+ * e_shell_get_canonical_name:
+ * @shell: an #EShell
+ * @name: the name or alias of an #EShellBackend
*
- * Save the settings for this shell.
+ * Returns the canonical name for the #EShellBackend whose name or alias
+ * is @name.
*
- * Return value: %TRUE if it worked, %FALSE otherwise. Even if %FALSE is
- * returned, it is possible that at least part of the settings for the windows
- * have been saved.
+ * Returns: the canonical #EShellBackend name
**/
-gboolean
-e_shell_save_settings (EShell *shell)
+const gchar *
+e_shell_get_canonical_name (EShell *shell,
+ const gchar *name)
{
- GConfClient *client;
- gboolean is_offline;
+ EShellBackend *shell_backend;
- is_offline = ( e_shell_get_line_status (shell) == E_SHELL_LINE_STATUS_OFFLINE );
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- client = gconf_client_get_default ();
- gconf_client_set_bool (client, "/apps/evolution/shell/start_offline", is_offline, NULL);
- g_object_unref (client);
+ /* Handle NULL name arguments silently. */
+ if (name == NULL)
+ return NULL;
- return TRUE;
+ shell_backend = e_shell_get_backend_by_name (shell, name);
+
+ if (shell_backend == NULL)
+ return NULL;
+
+ return E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
}
/**
- * e_shell_close_all_windows:
- * @shell:
+ * e_shell_get_backend_by_name:
+ * @shell: an #EShell
+ * @name: the name or alias of an #EShellBackend
+ *
+ * Returns the corresponding #EShellBackend for the given name or alias,
+ * or %NULL if @name is not recognized.
*
- * Destroy all the windows in @shell.
+ * Returns: the #EShellBackend named @name, or %NULL
**/
-void
-e_shell_close_all_windows (EShell *shell)
+EShellBackend *
+e_shell_get_backend_by_name (EShell *shell,
+ const gchar *name)
{
- EShellPrivate *priv;
- GList *p, *pnext;
-
- g_return_if_fail (shell != NULL);
- g_return_if_fail (E_IS_SHELL (shell));
+ GHashTable *hash_table;
- if (shell->priv->windows)
- e_shell_save_settings (shell);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
- priv = shell->priv;
- for (p = priv->windows; p != NULL; p = pnext) {
- pnext = p->next;
+ hash_table = shell->priv->backends_by_name;
- /* Note that this will also remove the window from the list... Hence the
- need for the pnext variable. */
- gtk_widget_destroy (GTK_WIDGET (p->data));
- }
+ return g_hash_table_lookup (hash_table, name);
}
/**
- * e_shell_get_line_status:
- * @shell: A pointer to an EShell object.
+ * e_shell_get_backend_by_scheme:
+ * @shell: an #EShell
+ * @scheme: a URI scheme
*
- * Get the line status for @shell.
+ * Returns the #EShellBackend that implements the given URI scheme,
+ * or %NULL if @scheme is not recognized.
*
- * Return value: The current line status for @shell.
+ * Returns: the #EShellBackend that implements @scheme, or %NULL
**/
-EShellLineStatus
-e_shell_get_line_status (EShell *shell)
+EShellBackend *
+e_shell_get_backend_by_scheme (EShell *shell,
+ const gchar *scheme)
{
- g_return_val_if_fail (shell != NULL, E_SHELL_LINE_STATUS_OFFLINE);
- g_return_val_if_fail (E_IS_SHELL (shell), E_SHELL_LINE_STATUS_OFFLINE);
+ GHashTable *hash_table;
- return shell->priv->line_status;
-}
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ g_return_val_if_fail (scheme != NULL, NULL);
-/* Offline/online handling. */
+ hash_table = shell->priv->backends_by_scheme;
-static void
-set_line_status_finished(EShell *shell)
+ return g_hash_table_lookup (hash_table, scheme);
+}
+/**
+ * e_shell_get_shell_settings:
+ * @shell: an #EShell
+ *
+ * Returns the #EShellSettings instance for @shell.
+ *
+ * Returns: the #EShellSettings instance for @shell
+ **/
+EShellSettings *
+e_shell_get_shell_settings (EShell *shell)
{
- EShellPrivate *priv = shell->priv;
- ESEvent *ese;
-
- priv->line_status = priv->line_status_working;
-
- e_passwords_set_online (priv->line_status == E_SHELL_LINE_STATUS_ONLINE);
- g_signal_emit (shell, signals[LINE_STATUS_CHANGED], 0, priv->line_status);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- /** @Event: Shell online state changed
- * @Id: state.changed
- * @Target: ESMenuTargetState
- *
- * This event is emitted whenever the shell online state changes.
- *
- * Only the online and offline states are emitted.
- */
- ese = es_event_peek();
- e_event_emit((EEvent *)ese, "state.changed", (EEventTarget *)es_event_target_new_state(ese, priv->line_status == E_SHELL_LINE_STATUS_ONLINE));
+ return shell->priv->settings;
}
-static void
-set_line_status_complete(EvolutionListener *el, gpointer data)
+/**
+ * e_shell_get_gconf_client:
+ * @shell: an #EShell
+ *
+ * Returns the default #GConfClient. This function is purely for
+ * convenience. The @shell owns the reference so you don't have to.
+ *
+ * Returns: the default #GConfClient
+ **/
+GConfClient *
+e_shell_get_gconf_client (EShell *shell)
{
- EShell *shell = data;
- EShellPrivate *priv = shell->priv;
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- if (priv->line_status_pending > 0) {
- priv->line_status_pending--;
- if (priv->line_status_pending == 0)
- set_line_status_finished(shell);
- }
+ return shell->priv->gconf_client;
}
-void
-e_shell_set_line_status (EShell *shell,
- GNOME_Evolution_ShellState shell_state)
+/**
+ * e_shell_create_shell_window:
+ * @shell: an #EShell
+ * @view_name: name of the initial shell view, or %NULL
+ *
+ * Creates a new #EShellWindow and emits the #EShell::window-created
+ * signal. Use this function instead of e_shell_window_new() so that
+ * @shell can track the window.
+ *
+ * Returns: a new #EShellWindow
+ **/
+GtkWidget *
+e_shell_create_shell_window (EShell *shell,
+ const gchar *view_name)
{
- EShellPrivate *priv;
- GSList *component_infos;
- GSList *p;
- CORBA_Environment ev;
- GConfClient *client;
- gboolean is_online;
- gboolean forced = FALSE;
-
- priv = shell->priv;
-
- if (shell_state == GNOME_Evolution_FORCED_OFFLINE || shell_state == GNOME_Evolution_USER_OFFLINE) {
- is_online = FALSE;
- if (shell_state == GNOME_Evolution_FORCED_OFFLINE)
- forced = TRUE;
- } else
- is_online = TRUE;
+ GtkWidget *shell_window;
+ UniqueMessageData *data;
+ UniqueApp *app;
- if ((is_online && priv->line_status == E_SHELL_LINE_STATUS_ONLINE)
- || (!is_online && priv->line_status == E_SHELL_LINE_STATUS_OFFLINE && !forced))
- return;
-
- /* we use 'going offline' to mean 'changing status' now */
- priv->line_status = E_SHELL_LINE_STATUS_GOING_OFFLINE;
- g_signal_emit (shell, signals[LINE_STATUS_CHANGED], 0, priv->line_status);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- client = gconf_client_get_default ();
- if (!forced)
- gconf_client_set_bool (client, "/apps/evolution/shell/start_offline", !is_online, NULL);
- g_object_unref (client);
+ app = UNIQUE_APP (shell);
- priv->line_status_working = is_online ? E_SHELL_LINE_STATUS_ONLINE: forced?E_SHELL_LINE_STATUS_FORCED_OFFLINE:E_SHELL_LINE_STATUS_OFFLINE;
- /* we start at 2: setLineStatus could recursively call back, we therefore
- `need to not complete till we're really complete */
- priv->line_status_pending += 2;
+ if (unique_app_is_running (app))
+ goto unique;
- component_infos = e_component_registry_peek_list (priv->component_registry);
- for (p = component_infos; p != NULL; p = p->next) {
- EComponentInfo *info = p->data;
+ view_name = e_shell_get_canonical_name (shell, view_name);
- CORBA_exception_init (&ev);
+ /* EShellWindow initializes its active view from a GConf key,
+ * so set the key ahead of time to control the intial view. */
+ if (view_name != NULL) {
+ GConfClient *client;
+ const gchar *key;
+ GError *error = NULL;
- GNOME_Evolution_Component_setLineStatus(info->iface, shell_state, bonobo_object_corba_objref((BonoboObject *)priv->line_status_listener), &ev);
- if (ev._major == CORBA_NO_EXCEPTION)
- priv->line_status_pending++;
+ client = e_shell_get_gconf_client (shell);
+ key = "/apps/evolution/shell/view_defaults/component_id";
+ gconf_client_set_string (client, key, view_name, &error);
- CORBA_exception_free (&ev);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
}
- priv->line_status_pending -= 2;
- if (priv->line_status_pending == 0)
- set_line_status_finished(shell);
-}
+ shell_window = e_shell_window_new (shell, shell->priv->safe_mode);
-gboolean
-e_shell_get_crash_recovery (EShell *shell)
-{
- g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+ gtk_widget_show (shell_window);
- return shell->priv->crash_recovery;
-}
+ return shell_window;
-void
-e_shell_set_crash_recovery (EShell *shell,
- gboolean crash_recovery)
-{
- g_return_if_fail (E_IS_SHELL (shell));
+unique: /* Send a message to the other Evolution process. */
+
+ /* XXX Do something with UniqueResponse? */
- shell->priv->crash_recovery = crash_recovery;
+ if (view_name != NULL) {
+ data = unique_message_data_new ();
+ unique_message_data_set_text (data, view_name, -1);
+ unique_app_send_message (app, UNIQUE_NEW, data);
+ unique_message_data_free (data);
+ } else
+ unique_app_send_message (app, UNIQUE_ACTIVATE, NULL);
+
+ return NULL;
}
-void
-e_shell_send_receive (EShell *shell)
+/**
+ * e_shell_handle_uris:
+ * @shell: an #EShell
+ * @uris: %NULL-terminated list of URIs
+ *
+ * Emits the #EShell::handle-uri signal for each URI.
+ *
+ * Returns: the number of URIs successfully handled
+ **/
+guint
+e_shell_handle_uris (EShell *shell,
+ gchar **uris)
{
- GSList *component_list;
- GSList *p;
+ UniqueApp *app;
+ UniqueMessageData *data;
+ guint n_handled = 0;
+ gint ii;
- g_return_if_fail (E_IS_SHELL (shell));
+ g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
+ g_return_val_if_fail (uris != NULL, FALSE);
- component_list = e_component_registry_peek_list (shell->priv->component_registry);
+ app = UNIQUE_APP (shell);
- for (p = component_list; p != NULL; p = p->next) {
- EComponentInfo *info = p->data;
- CORBA_Environment ev;
+ if (unique_app_is_running (app))
+ goto unique;
- CORBA_exception_init (&ev);
+ for (ii = 0; uris[ii] != NULL; ii++) {
+ gboolean handled;
- GNOME_Evolution_Component_sendAndReceive (info->iface, &ev);
+ g_signal_emit (
+ shell, signals[HANDLE_URI],
+ 0, uris[ii], &handled);
+ n_handled += handled ? 1 : 0;
+ }
- /* Ignore errors, the components can decide to not implement
- this interface. */
+ return n_handled;
- CORBA_exception_free (&ev);
- }
+unique: /* Send a message to the other Evolution process. */
+
+ /* XXX Do something with UniqueResponse? */
+
+ data = unique_message_data_new ();
+ unique_message_data_set_uris (data, uris);
+ unique_app_send_message (app, UNIQUE_OPEN, data);
+ unique_message_data_free (data);
+
+ /* As far as we're concerned, all URIs have been handled. */
+
+ return g_strv_length (uris);
}
+/**
+ * e_shell_watch_window:
+ * @shell: an #EShell
+ * @window: a #GtkWindow
+ *
+ * Makes @shell "watch" a newly created toplevel window, and emits the
+ * #EShell::window-created signal. All #EShellWindow<!-- -->s should be
+ * watched, along with any editor or viewer windows that may be shown in
+ * response to e_shell_handle_uris(). When the last watched window is
+ * closed, Evolution terminates.
+ **/
void
-e_shell_show_settings (EShell *shell,
- const gchar *type,
- EShellWindow *shell_window)
+e_shell_watch_window (EShell *shell,
+ GtkWindow *window)
{
- EShellPrivate *priv;
+ GList *list;
- g_return_if_fail (shell != NULL);
g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (GTK_IS_WINDOW (window));
- priv = shell->priv;
+ list = shell->priv->watched_windows;
- if (priv->settings_dialog.widget != NULL) {
- gdk_window_show (priv->settings_dialog.widget->window);
- gtk_widget_grab_focus (priv->settings_dialog.widget);
+ /* Ignore duplicates. */
+ if (g_list_find (list, window) != NULL)
return;
- }
- priv->settings_dialog.widget = e_shell_settings_dialog_new ();
+ list = g_list_prepend (list, window);
+ shell->priv->watched_windows = list;
- if (type != NULL)
- e_shell_settings_dialog_show_type (E_SHELL_SETTINGS_DIALOG (priv->settings_dialog.widget), type);
+ unique_app_watch_window (UNIQUE_APP (shell), window);
- g_object_add_weak_pointer (G_OBJECT (priv->settings_dialog.widget), &priv->settings_dialog.pointer);
+ g_signal_connect_swapped (
+ window, "delete-event",
+ G_CALLBACK (shell_window_delete_event_cb), shell);
- gtk_window_set_transient_for (GTK_WINDOW (priv->settings_dialog.widget), GTK_WINDOW (shell_window));
- gtk_widget_show (priv->settings_dialog.widget);
-}
+ g_signal_connect_swapped (
+ window, "focus-in-event",
+ G_CALLBACK (shell_window_focus_in_event_cb), shell);
-const gchar *
-e_shell_construct_result_to_string (EShellConstructResult result)
-{
- switch (result) {
- case E_SHELL_CONSTRUCT_RESULT_OK:
- return _("OK");
- case E_SHELL_CONSTRUCT_RESULT_INVALIDARG:
- return _("Invalid arguments");
- case E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER:
- return _("Cannot register on OAF");
- case E_SHELL_CONSTRUCT_RESULT_NOCONFIGDB:
- return _("Configuration Database not found");
- case E_SHELL_CONSTRUCT_RESULT_GENERICERROR:
- return _("Generic error");
- default:
- return _("Unknown error");
- }
+ g_object_weak_ref (
+ G_OBJECT (window), (GWeakNotify)
+ shell_window_weak_notify_cb, shell);
+
+ g_signal_emit (shell, signals[WINDOW_CREATED], 0, window);
}
-/* timeout handler, so returns TRUE if we can't quit yet */
-static gboolean
-es_run_quit(EShell *shell)
+/**
+ * e_shell_get_watched_windows:
+ * @shell: an #EShell
+ *
+ * Returns a list of windows being watched by @shell. The list is sorted
+ * by the most recently focused window, such that the first instance is the
+ * currently focused window. (Useful for choosing a parent for a transient
+ * window.) The list is owned by @shell and should not be modified or freed.
+ *
+ * Returns: a list of watched windows
+ **/
+GList *
+e_shell_get_watched_windows (EShell *shell)
{
- EShellPrivate *priv;
- GSList *component_infos;
- GSList *sp;
- CORBA_boolean done_quit;
-
- g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
-
- priv = shell->priv;
- priv->preparing_to_quit = TRUE;
-
- component_infos = e_component_registry_peek_list (priv->component_registry);
- done_quit = TRUE;
- for (sp = component_infos; sp != NULL; sp = sp->next) {
- EComponentInfo *info = sp->data;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- done_quit = GNOME_Evolution_Component_quit(info->iface, &ev);
- if (BONOBO_EX (&ev)) {
- /* The component might not implement the interface, in which case we assume we can quit. */
- done_quit = TRUE;
- }
-
- CORBA_exception_free (&ev);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- if (!done_quit)
- break;
- }
+ return shell->priv->watched_windows;
+}
- if (done_quit) {
- if (priv->quit_timeout) {
- g_source_remove(priv->quit_timeout);
- priv->quit_timeout = 0;
- }
- e_shell_close_all_windows(shell);
- } else if (priv->quit_timeout == 0) {
- priv->quit_timeout = g_timeout_add(500, (GSourceFunc)es_run_quit, shell);
- }
+/**
+ * e_shell_send_receive:
+ * @shell: an #EShell
+ * @parent: the parent #GtkWindow
+ *
+ * Emits the #EShell::send-receive signal.
+ **/
+void
+e_shell_send_receive (EShell *shell,
+ GtkWindow *parent)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (GTK_IS_WINDOW (parent));
- return !done_quit;
+ g_signal_emit (shell, signals[SEND_RECEIVE], 0, parent);
}
+/**
+ * e_shell_get_network_available:
+ * @shell: an #EShell
+ *
+ * Returns %TRUE if a network is available.
+ *
+ * Returns: %TRUE if a network is available
+ **/
gboolean
-e_shell_can_quit (EShell *shell)
+e_shell_get_network_available (EShell *shell)
{
- EShellPrivate *priv;
- GSList *component_infos;
- GSList *sp;
- CORBA_boolean can_quit;
-
g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
- priv = shell->priv;
-
- if (priv->preparing_to_quit)
- return FALSE;
-
- component_infos = e_component_registry_peek_list (priv->component_registry);
- can_quit = TRUE;
- for (sp = component_infos; sp != NULL; sp = sp->next) {
- EComponentInfo *info = sp->data;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
+ return shell->priv->network_available;
+}
- can_quit = GNOME_Evolution_Component_requestQuit (info->iface, &ev);
- if (BONOBO_EX (&ev)) {
- /* The component might not implement the interface, in which case we assume we can quit. */
- can_quit = TRUE;
- }
+/**
+ * e_shell_set_network_available:
+ * @shell: an #EShell
+ * @network_available: whether a network is available
+ *
+ * Sets whether a network is available. This is usually called in
+ * response to a status change signal from NetworkManager. If the
+ * network becomes unavailable while #EShell:online is %TRUE, the
+ * @shell will force #EShell:online to %FALSE until the network
+ * becomes available again.
+ **/
+void
+e_shell_set_network_available (EShell *shell,
+ gboolean network_available)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
- CORBA_exception_free (&ev);
+ if (network_available == shell->priv->network_available)
+ return;
- if (! can_quit)
- break;
+ shell->priv->network_available = network_available;
+ g_object_notify (G_OBJECT (shell), "network-available");
+
+ /* If we're being forced offline, perhaps due to a network outage,
+ * reconnect automatically when the network becomes available. */
+ if (!network_available && shell->priv->online) {
+ g_message ("Network disconnected. Forced offline.");
+ e_shell_set_online (shell, FALSE);
+ shell->priv->auto_reconnect = TRUE;
+ } else if (network_available && shell->priv->auto_reconnect) {
+ g_message ("Connection established. Going online.");
+ e_shell_set_online (shell, TRUE);
+ shell->priv->auto_reconnect = FALSE;
}
-
- return can_quit;
}
+/**
+ * e_shell_get_online:
+ * @shell: an #EShell
+ *
+ * Returns %TRUE if Evolution is online, %FALSE if Evolution is offline.
+ * Evolution may be offline because the user elected to work offline, or
+ * because the network has become unavailable.
+ *
+ * Returns: %TRUE if Evolution is online
+ **/
gboolean
-e_shell_do_quit (EShell *shell)
+e_shell_get_online (EShell *shell)
{
- EShellPrivate *priv;
- GList *p;
- gboolean can_quit;
-
g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
- priv = shell->priv;
-
- if (priv->preparing_to_quit)
- return FALSE;
-
- for (p = shell->priv->windows; p != NULL; p = p->next) {
- gtk_widget_set_sensitive (GTK_WIDGET (p->data), FALSE);
-
- if (p == shell->priv->windows)
- e_shell_window_save_defaults (p->data);
- }
+ return shell->priv->online;
+}
- can_quit = !es_run_quit (shell);
+/**
+ * e_shell_set_online:
+ * @shell: an #EShell
+ * @online: %TRUE to go online, %FALSE to go offline
+ *
+ * Asynchronously places Evolution in online or offline mode.
+ **/
+void
+e_shell_set_online (EShell *shell,
+ gboolean online)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
- /* Mark a safe quit by destroying the lock. */
- e_file_lock_destroy ();
+ if (online == shell->priv->online)
+ return;
- return can_quit;
+ if (online)
+ shell_prepare_for_online (shell);
+ else
+ shell_prepare_for_offline (shell);
}
-gboolean
-e_shell_quit (EShell *shell)
+/**
+ * e_shell_get_preferences_window:
+ * @shell: an #EShell
+ *
+ * Returns the Evolution Preferences window.
+ *
+ * Returns: the preferences window
+ **/
+GtkWidget *
+e_shell_get_preferences_window (EShell *shell)
{
- return e_shell_can_quit (shell) && e_shell_do_quit (shell);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ return shell->priv->preferences_window;
}
/**
- * gboolean (*EMainShellFunc) (EShell *shell, EShellWindow *window, gpointer user_data);
- * Function used in @ref e_shell_foreach_shell_window.
- * @param shell Pointer to EShell.
- * @param window Pointer to EShellWindow.
- * @param user_data User's data passed to @ref main_shell_foreach_shell_window.
- * @return TRUE if need to go to next window, FALSE when stop looking for next window.
+ * e_shell_event:
+ * @shell: an #EShell
+ * @event_name: the name of the event
+ * @event_data: data associated with the event
+ *
+ * The #EShell::event signal acts as a cheap mechanism for broadcasting
+ * events to the rest of the application, such as new mail arriving. The
+ * @event_name is used as the signal detail, and @event_data may point to
+ * an object or data structure associated with the event.
**/
+void
+e_shell_event (EShell *shell,
+ const gchar *event_name,
+ gpointer event_data)
+{
+ GQuark detail;
+
+ g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (event_name != NULL);
+
+ detail = g_quark_from_string (event_name);
+ g_signal_emit (shell, signals[EVENT], detail, event_data);
+}
-/**
- * e_shell_foreach_shell_window
- * This will call function callback for all known EShellWindow of main shell.
- * When there is no shell active, then this will do nothing.
- * @param shell EShell instance.
- * @param func Function to be called.
- * @param user_data User data to pass to func.
- **/
void
-e_shell_foreach_shell_window (EShell *shell, EMainShellFunc func, gpointer user_data)
+e_shell_quit (EShell *shell)
{
- EShellPrivate *priv;
- GList *p;
+ g_return_if_fail (E_IS_SHELL (shell));
- if (!shell)
+ if (!shell_request_quit (shell))
return;
- priv = shell->priv;
+ shell_prepare_for_quit (shell);
+}
- for (p = priv->windows; p != NULL; p = p->next) {
- EShellWindow *window;
+/**
+ * e_shell_cancel_quit:
+ * @shell: an #EShell
+ *
+ * This function may only be called from #EShell::quit-requested signal
+ * handlers to prevent Evolution from quitting. Calling this will stop
+ * further emission of the #EShell::quit-requested signal.
+ *
+ * Note: This function has no effect during a #EShell::prepare-for-quit
+ * signal emission.
+ **/
+void
+e_shell_cancel_quit (EShell *shell)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
- window = E_SHELL_WINDOW (p->data);
+ shell->priv->quit_cancelled = TRUE;
- if (window && !func (shell, window, user_data))
- break;
- }
+ g_signal_stop_emission (shell, signals[QUIT_REQUESTED], 0);
}
-
-BONOBO_TYPE_FUNC_FULL (EShell, GNOME_Evolution_Shell, PARENT_TYPE, e_shell)
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 00f4266562..818607e1fb 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -1,4 +1,6 @@
/*
+ * e-shell.h
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,126 +15,98 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _E_SHELL_H_
-#define _E_SHELL_H_
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-object.h>
+/**
+ * SECTION: e-shell
+ * @short_description: the backbone of Evolution
+ * @include: shell/e-shell.h
+ **/
+
+#ifndef E_SHELL_H
+#define E_SHELL_H
+
+#include <unique/unique.h>
+#include <gconf/gconf-client.h>
+#include <shell/e-shell-common.h>
+#include <shell/e-shell-backend.h>
+#include <shell/e-shell-settings.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SHELL \
+ (e_shell_get_type ())
+#define E_SHELL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SHELL, EShell))
+#define E_SHELL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SHELL, EShellClass))
+#define E_IS_SHELL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SHELL))
+#define E_IS_SHELL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SHELL))
+#define E_SHELL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SHELL, EShellClass))
G_BEGIN_DECLS
-typedef struct _EShell EShell;
+typedef struct _EShell EShell;
+typedef struct _EShellClass EShellClass;
typedef struct _EShellPrivate EShellPrivate;
-typedef struct _EShellClass EShellClass;
-
-#include "Evolution.h"
-
-#include "e-component-registry.h"
-#include "e-shell-window.h"
-
-#define E_TYPE_SHELL (e_shell_get_type ())
-#define E_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SHELL, EShell))
-#define E_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL, EShellClass))
-#define E_IS_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SHELL))
-#define E_IS_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL))
-
-enum _EShellLineStatus {
- E_SHELL_LINE_STATUS_ONLINE,
- E_SHELL_LINE_STATUS_GOING_OFFLINE, /* NB: really means changing state in either direction */
- E_SHELL_LINE_STATUS_OFFLINE,
- E_SHELL_LINE_STATUS_FORCED_OFFLINE
-};
-typedef enum _EShellLineStatus EShellLineStatus;
-
-enum _EShellStartupLineMode {
- E_SHELL_STARTUP_LINE_MODE_CONFIG,
- E_SHELL_STARTUP_LINE_MODE_ONLINE,
- E_SHELL_STARTUP_LINE_MODE_OFFLINE
-};
-typedef enum _EShellStartupLineMode EShellStartupLineMode;
+/**
+ * EShell:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
struct _EShell {
- BonoboObject parent;
-
+ UniqueApp parent;
EShellPrivate *priv;
};
struct _EShellClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Shell__epv epv;
-
- void (* no_windows_left) (EShell *shell);
- void (* line_status_changed) (EShell *shell, EShellLineStatus status);
- void (* new_window_created) (EShell *shell, EShellWindow *window);
+ UniqueAppClass parent_class;
};
-/* ID for registering the shell in the OAF name service. */
-#define E_SHELL_OAFIID "OAFIID:GNOME_Evolution_Shell:" BASE_VERSION
-
-enum _EShellConstructResult {
- E_SHELL_CONSTRUCT_RESULT_OK,
- E_SHELL_CONSTRUCT_RESULT_INVALIDARG,
- E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER,
- E_SHELL_CONSTRUCT_RESULT_NOCONFIGDB,
- E_SHELL_CONSTRUCT_RESULT_GENERICERROR
-};
-typedef enum _EShellConstructResult EShellConstructResult;
-
-GType e_shell_get_type (void);
-EShellConstructResult e_shell_construct (EShell *shell,
- const gchar *iid,
- EShellStartupLineMode startup_line_mode);
-EShell *e_shell_new (EShellStartupLineMode startup_line_mode,
- EShellConstructResult *construct_result_return);
-
-gboolean e_shell_attempt_upgrade (EShell *shell);
-
-EShellWindow *e_shell_create_window (EShell *shell,
- const gchar *component_id,
- EShellWindow *template_window);
-gboolean e_shell_request_close_window (EShell *shell,
- EShellWindow *window);
-
-#if 0
-EUriSchemaRegistry *e_shell_peek_uri_schema_registry (EShell *shell);
-#endif
-
-EComponentRegistry *e_shell_peek_component_registry (EShell *shell);
-
-gboolean e_shell_save_settings (EShell *shell);
-void e_shell_close_all_windows (EShell *shell);
-
-EShellLineStatus e_shell_get_line_status (EShell *shell);
-void e_shell_set_line_status (EShell *shell,
- GNOME_Evolution_ShellState shell_state);
-
-gboolean e_shell_get_crash_recovery (EShell *shell);
-void e_shell_set_crash_recovery (EShell *shell,
- gboolean crash_recovery);
-
-void e_shell_send_receive (EShell *shell);
-
-void e_shell_show_settings (EShell *shell,
- const gchar *type,
- EShellWindow *shell_window);
-
-gboolean e_shell_can_quit (EShell *shell);
-gboolean e_shell_do_quit (EShell *shell);
-gboolean e_shell_quit (EShell *shell);
-
-const gchar *e_shell_construct_result_to_string (EShellConstructResult result);
-
-typedef gboolean (*EMainShellFunc) (EShell *shell, EShellWindow *window, gpointer user_data);
-void e_shell_foreach_shell_window (EShell *shell, EMainShellFunc func, gpointer user_data);
+GType e_shell_get_type (void);
+EShell * e_shell_get_default (void);
+GList * e_shell_get_shell_backends (EShell *shell);
+const gchar * e_shell_get_canonical_name (EShell *shell,
+ const gchar *name);
+EShellBackend * e_shell_get_backend_by_name (EShell *shell,
+ const gchar *name);
+EShellBackend * e_shell_get_backend_by_scheme (EShell *shell,
+ const gchar *scheme);
+EShellSettings *e_shell_get_shell_settings (EShell *shell);
+GConfClient * e_shell_get_gconf_client (EShell *shell);
+GtkWidget * e_shell_create_shell_window (EShell *shell,
+ const gchar *view_name);
+guint e_shell_handle_uris (EShell *shell,
+ gchar **uris);
+void e_shell_watch_window (EShell *shell,
+ GtkWindow *window);
+GList * e_shell_get_watched_windows (EShell *shell);
+void e_shell_send_receive (EShell *shell,
+ GtkWindow *parent);
+gboolean e_shell_get_network_available (EShell *shell);
+void e_shell_set_network_available (EShell *shell,
+ gboolean network_available);
+gboolean e_shell_get_online (EShell *shell);
+void e_shell_set_online (EShell *shell,
+ gboolean online);
+GtkWidget * e_shell_get_preferences_window (EShell *shell);
+void e_shell_event (EShell *shell,
+ const gchar *event_name,
+ gpointer event_data);
+void e_shell_quit (EShell *shell);
+void e_shell_cancel_quit (EShell *shell);
G_END_DECLS
-#endif /* _E_SHELL_H_ */
+#endif /* E_SHELL_H */
diff --git a/shell/e-sidebar.c b/shell/e-sidebar.c
deleted file mode 100644
index 3942de727b..0000000000
--- a/shell/e-sidebar.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-sidebar.h"
-
-#include "e-util/e-util.h"
-
-#include <gconf/gconf-client.h>
-
-typedef struct {
- GtkWidget *button_widget;
- GtkWidget *label;
- GtkWidget *icon;
- GtkWidget *hbox;
- gchar *default_icon_name;
- gint id;
-} Button;
-
-struct _ESidebarPrivate {
- ESidebarMode mode;
- ESidebarMode toolbar_mode;
-
- gboolean show;
-
- GtkWidget *selection_widget;
- GSList *buttons;
-
- guint style_changed_id;
-
- gboolean in_toggle;
-};
-
-enum {
- BUTTON_SELECTED,
- BUTTON_PRESSED,
- NUM_SIGNALS
-};
-
-static guint signals[NUM_SIGNALS] = { 0 };
-
-G_DEFINE_TYPE (ESidebar, e_sidebar, GTK_TYPE_CONTAINER)
-
-#define INTERNAL_MODE(sidebar) (sidebar->priv->mode == E_SIDEBAR_MODE_TOOLBAR ? sidebar->priv->toolbar_mode : sidebar->priv->mode)
-#define H_PADDING 6
-#define V_PADDING 6
-
-/* Utility functions. */
-
-static Button *
-button_new (GtkWidget *button_widget,
- GtkWidget *label,
- GtkWidget *icon,
- GtkWidget *hbox,
- gint id)
-{
- Button *button = g_new (Button, 1);
- const gchar *icon_name;
-
- button->button_widget = button_widget;
- button->label = label;
- button->icon = icon;
- button->hbox = hbox;
- button->id = id;
-
- gtk_image_get_icon_name (GTK_IMAGE (icon), &icon_name, NULL);
- button->default_icon_name = g_strdup (icon_name);
-
- g_object_ref (button_widget);
- g_object_ref (label);
- g_object_ref (icon);
- g_object_ref (hbox);
-
- return button;
-}
-
-static void
-button_free (Button *button)
-{
- g_object_unref (button->button_widget);
- g_object_unref (button->label);
- g_object_unref (button->icon);
- g_object_unref (button->hbox);
- g_free (button->default_icon_name);
- g_free (button);
-}
-
-static void
-update_buttons (ESidebar *sidebar, gint new_selected_id)
-{
- GSList *p;
-
- sidebar->priv->in_toggle = TRUE;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (button->id == new_selected_id)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), TRUE);
- else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), FALSE);
- }
-
- sidebar->priv->in_toggle = FALSE;
-}
-
-/* Callbacks. */
-
-static void
-button_toggled_callback (GtkToggleButton *toggle_button,
- ESidebar *sidebar)
-{
- gint id = 0;
- gboolean is_active = FALSE;
- GSList *p;
-
- if (sidebar->priv->in_toggle)
- return;
-
- sidebar->priv->in_toggle = TRUE;
-
- if (gtk_toggle_button_get_active (toggle_button))
- is_active = TRUE;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (button->button_widget != GTK_WIDGET (toggle_button)) {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), FALSE);
- } else {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->button_widget), TRUE);
- id = button->id;
- }
- }
-
- sidebar->priv->in_toggle = FALSE;
-
- if (is_active)
- g_signal_emit (sidebar, signals[BUTTON_SELECTED], 0, id);
-}
-
-static gboolean
-button_pressed_callback (GtkToggleButton *toggle_button,
- GdkEventButton *event,
- ESidebar *sidebar)
-{
- gboolean return_val = FALSE;
- GSList *p;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (button->button_widget == GTK_WIDGET (toggle_button))
- g_signal_emit (sidebar, signals [BUTTON_PRESSED],
- 0, event, button->id, &return_val);
- }
-
- return return_val;
-}
-
-static gboolean
-button_query_tooltip (GtkWidget *widget,
- gint x,
- gint y,
- gboolean keyboard_mode,
- GtkTooltip *tooltip,
- ESidebar *sidebar)
-{
- /* Show the tooltip only if the label is hidden */
- if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_ICON) {
- gchar *tip;
-
- tip = g_object_get_data (G_OBJECT (widget),
- "ESidebar:button-tooltip");
- if (tip) {
- gtk_tooltip_set_text (tooltip, tip);
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* Layout. */
-
-static gint
-layout_buttons (ESidebar *sidebar)
-{
- GtkAllocation *allocation = & GTK_WIDGET (sidebar)->allocation;
- ESidebarMode mode;
- gboolean icons_only;
- gint num_btns = g_slist_length (sidebar->priv->buttons), btns_per_row;
- GSList **rows, *p;
- Button *button;
- gint row_number;
- gint max_btn_width = 0, max_btn_height = 0;
- gint row_last;
- gint x, y;
- gint i;
-
- y = allocation->y + allocation->height - V_PADDING - 1;
-
- if (num_btns == 0)
- return y;
-
- mode = INTERNAL_MODE (sidebar);
- icons_only = (mode == E_SIDEBAR_MODE_ICON);
-
- /* Figure out the max width and height */
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- GtkRequisition requisition;
-
- button = p->data;
- gtk_widget_size_request (GTK_WIDGET (button->button_widget), &requisition);
-
- max_btn_height = MAX (max_btn_height, requisition.height);
- max_btn_width = MAX (max_btn_width, requisition.width);
- }
-
- /* Figure out how many rows and columns we'll use. */
- btns_per_row = allocation->width / (max_btn_width + H_PADDING);
- if (!icons_only) {
- /* If using text buttons, we want to try to have a
- * completely filled-in grid, but if we can't, we want
- * the odd row to have just a single button.
- */
- while (num_btns % btns_per_row > 1)
- btns_per_row--;
- }
-
- /* Assign buttons to rows */
- rows = g_new0 (GSList *, num_btns / btns_per_row + 1);
-
- if (!icons_only && num_btns % btns_per_row != 0) {
- button = sidebar->priv->buttons->data;
- rows [0] = g_slist_append (rows [0], button->button_widget);
-
- p = sidebar->priv->buttons->next;
- row_number = p ? 1 : 0;
- } else {
- p = sidebar->priv->buttons;
- row_number = 0;
- }
-
- for (; p != NULL; p = p->next) {
- button = p->data;
-
- if (g_slist_length (rows [row_number]) == btns_per_row)
- row_number ++;
-
- rows [row_number] = g_slist_append (rows [row_number], button->button_widget);
- }
-
- row_last = row_number;
-
- /* Layout the buttons. */
- for (i = row_last; i >= 0; i --) {
- gint len, extra_width;
-
- y -= max_btn_height;
- x = H_PADDING + allocation->x;
- len = g_slist_length (rows[i]);
- if (mode == E_SIDEBAR_MODE_TEXT || mode == E_SIDEBAR_MODE_BOTH)
- extra_width = (allocation->width - (len * max_btn_width ) - (len * H_PADDING)) / len;
- else
- extra_width = 0;
- for (p = rows [i]; p != NULL; p = p->next) {
- GtkAllocation child_allocation;
-
- child_allocation.x = x;
- child_allocation.y = y;
- child_allocation.width = max_btn_width + extra_width;
- child_allocation.height = max_btn_height;
-
- gtk_widget_size_allocate (GTK_WIDGET (p->data), &child_allocation);
-
- x += child_allocation.width + H_PADDING;
- }
-
- y -= V_PADDING;
- }
-
- for (i = 0; i <= row_last; i ++)
- g_slist_free (rows [i]);
- g_free (rows);
-
- return y;
-}
-
-static void
-do_layout (ESidebar *sidebar)
-{
- GtkAllocation *allocation = & GTK_WIDGET (sidebar)->allocation;
- GtkAllocation child_allocation;
- gint y;
-
- if (sidebar->priv->show)
- y = layout_buttons (sidebar);
- else
- y = allocation->y + allocation->height;
-
- /* Place the selection widget. */
- child_allocation.x = allocation->x;
- child_allocation.y = allocation->y;
- child_allocation.width = allocation->width;
- child_allocation.height = y - allocation->y;
-
- gtk_widget_size_allocate (sidebar->priv->selection_widget, & child_allocation);
-}
-
-/* GtkContainer methods. */
-
-static void
-impl_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
-{
- ESidebar *sidebar = E_SIDEBAR (container);
- GSList *p;
-
- if (sidebar->priv->selection_widget != NULL)
- (* callback) (sidebar->priv->selection_widget, callback_data);
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- GtkWidget *widget = ((Button *) p->data)->button_widget;
- (* callback) (widget, callback_data);
- }
-}
-
-static void
-impl_remove (GtkContainer *container,
- GtkWidget *widget)
-{
- ESidebar *sidebar = E_SIDEBAR (container);
- GSList *p;
-
- if (widget == sidebar->priv->selection_widget) {
- e_sidebar_set_selection_widget (sidebar, NULL);
- return;
- }
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- GtkWidget *button_widget = ((Button *) p->data)->button_widget;
-
- if (button_widget == widget) {
- gtk_widget_unparent (button_widget);
- sidebar->priv->buttons = g_slist_remove_link (sidebar->priv->buttons, p);
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
- break;
- }
- }
-}
-
-/* GtkWidget methods. */
-
-static void
-impl_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- ESidebar *sidebar = E_SIDEBAR (widget);
- GSList *p;
-
- if (sidebar->priv->selection_widget == NULL) {
- requisition->width = 2 * H_PADDING;
- requisition->height = 2 * V_PADDING;
- } else {
- gtk_widget_size_request (sidebar->priv->selection_widget, requisition);
- }
-
- if (!sidebar->priv->show)
- return;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
- GtkRequisition button_requisition;
-
- gtk_widget_size_request (button->button_widget, &button_requisition);
-
- requisition->width = MAX (requisition->width, button_requisition.width + 2 * H_PADDING);
- requisition->height += button_requisition.height + V_PADDING;
- }
-}
-
-static void
-impl_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- widget->allocation = *allocation;
-
- do_layout (E_SIDEBAR (widget));
-}
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- ESidebarPrivate *priv = E_SIDEBAR (object)->priv;
- GConfClient *gconf_client = gconf_client_get_default ();
-
- g_slist_foreach (priv->buttons, (GFunc) button_free, NULL);
- g_slist_free (priv->buttons);
- priv->buttons = NULL;
-
- if (priv->style_changed_id) {
- gconf_client_notify_remove (gconf_client, priv->style_changed_id);
- priv->style_changed_id = 0;
- }
-
- g_object_unref (gconf_client);
-
- (* G_OBJECT_CLASS (e_sidebar_parent_class)->dispose) (object);
-}
-
-static gboolean
-boolean_handled_accumulator (GSignalInvocationHint *ihint,
- GValue *return_accu,
- const GValue *handler_return,
- gpointer dummy)
-{
- gboolean handled;
-
- handled = g_value_get_boolean (handler_return);
- g_value_set_boolean (return_accu, handled);
-
- return !handled;
-}
-
-static void
-impl_finalize (GObject *object)
-{
- ESidebarPrivate *priv = E_SIDEBAR (object)->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_sidebar_parent_class)->finalize) (object);
-}
-
-/* Initialization. */
-
-static void
-e_sidebar_class_init (ESidebarClass *klass)
-{
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- container_class->forall = impl_forall;
- container_class->remove = impl_remove;
-
- widget_class->size_request = impl_size_request;
- widget_class->size_allocate = impl_size_allocate;
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- signals[BUTTON_SELECTED]
- = g_signal_new ("button_selected",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (ESidebarClass, button_selected),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
- signals[BUTTON_PRESSED]
- = g_signal_new ("button_pressed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESidebarClass, button_pressed),
- boolean_handled_accumulator, NULL,
- e_marshal_NONE__POINTER_INT,
- G_TYPE_BOOLEAN, 2,
- G_TYPE_POINTER, G_TYPE_INT);
-}
-
-static void
-e_sidebar_init (ESidebar *sidebar)
-{
- ESidebarPrivate *priv;
-
- GTK_WIDGET_SET_FLAGS (sidebar, GTK_NO_WINDOW);
-
- priv = g_new0 (ESidebarPrivate, 1);
- sidebar->priv = priv;
-
- priv->mode = E_SIDEBAR_MODE_TEXT;
-}
-
-GtkWidget *
-e_sidebar_new (void)
-{
- ESidebar *sidebar = g_object_new (e_sidebar_get_type (), NULL);
-
- return GTK_WIDGET (sidebar);
-}
-
-void
-e_sidebar_set_selection_widget (ESidebar *sidebar, GtkWidget *widget)
-{
- if (sidebar->priv->selection_widget != NULL)
- gtk_widget_unparent (sidebar->priv->selection_widget);
-
- sidebar->priv->selection_widget = widget;
-
- if (widget != NULL)
- gtk_widget_set_parent (widget, GTK_WIDGET (sidebar));
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-}
-
-void
-e_sidebar_add_button (ESidebar *sidebar,
- const gchar *label,
- const gchar *tooltips,
- const gchar *icon_name,
- gint id)
-{
- GtkWidget *button_widget;
- GtkWidget *hbox;
- GtkWidget *icon_widget;
- GtkWidget *label_widget;
-
- button_widget = gtk_toggle_button_new ();
- if (sidebar->priv->show)
- gtk_widget_show (button_widget);
- g_signal_connect (button_widget, "toggled", G_CALLBACK (button_toggled_callback), sidebar);
- g_signal_connect (button_widget, "button_press_event",
- G_CALLBACK (button_pressed_callback), sidebar);
-
- hbox = gtk_hbox_new (FALSE, 3);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
- gtk_widget_show (hbox);
-
- icon_widget = gtk_image_new_from_icon_name (
- icon_name, GTK_ICON_SIZE_BUTTON);
- gtk_widget_show (icon_widget);
-
- label_widget = gtk_label_new (label);
- gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
- gtk_widget_show (label_widget);
-
- g_object_set_data_full (G_OBJECT (button_widget),
- "ESidebar:button-tooltip",
- g_strdup (tooltips),
- g_free);
- gtk_widget_set_has_tooltip (button_widget, TRUE);
- g_signal_connect (button_widget, "query-tooltip",
- G_CALLBACK (button_query_tooltip), sidebar);
-
- switch (INTERNAL_MODE (sidebar)) {
- case E_SIDEBAR_MODE_TEXT:
- gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0);
- break;
- case E_SIDEBAR_MODE_ICON:
- gtk_box_pack_start (GTK_BOX (hbox), icon_widget, TRUE, TRUE, 0);
- break;
- case E_SIDEBAR_MODE_BOTH:
- default:
- gtk_box_pack_start (GTK_BOX (hbox), icon_widget, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0);
- break;
- }
-
- gtk_container_add (GTK_CONTAINER (button_widget), hbox);
-
- sidebar->priv->buttons = g_slist_append (sidebar->priv->buttons, button_new (button_widget, label_widget, icon_widget, hbox, id));
- gtk_widget_set_parent (button_widget, GTK_WIDGET (sidebar));
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-}
-
-/**
- * e_sidebar_change_button_icon
- * @sidebar: an #ESidebar
- * @icon_name: button icon name, or %NULL
- * @button_id: component's button ID, for which change the icon.
- *
- * This will change icon in icon_widget of the button of known component.
- * You cannot change icon as in a stack, only one default icon will be stored.
- **/
-void
-e_sidebar_change_button_icon (ESidebar *sidebar, const gchar *icon_name, gint button_id)
-{
- GSList *p;
-
- g_return_if_fail (sidebar != NULL);
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (button->id == button_id) {
- if (!button->icon)
- break;
-
- if (icon_name == NULL)
- icon_name = button->default_icon_name;
-
- gtk_image_set_from_icon_name (
- GTK_IMAGE (button->icon),
- icon_name, GTK_ICON_SIZE_BUTTON);
-
- break;
- }
- }
-}
-
-void
-e_sidebar_select_button (ESidebar *sidebar, gint id)
-{
- update_buttons (sidebar, id);
-
- g_signal_emit (sidebar, signals[BUTTON_SELECTED], 0, id);
-}
-
-ESidebarMode
-e_sidebar_get_mode (ESidebar *sidebar)
-{
- return sidebar->priv->mode;
-}
-
-static GConfEnumStringPair toolbar_styles[] = {
- { E_SIDEBAR_MODE_TEXT, "text" },
- { E_SIDEBAR_MODE_ICON, "icons" },
- { E_SIDEBAR_MODE_BOTH, "both" },
- { E_SIDEBAR_MODE_BOTH, "both-horiz" },
- { E_SIDEBAR_MODE_BOTH, "both_horiz" },
- { -1, NULL }
-};
-
-static void
-set_mode_internal (ESidebar *sidebar, ESidebarMode mode )
-{
- GSList *p;
-
- if (mode == INTERNAL_MODE (sidebar))
- return;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- switch (mode) {
- case E_SIDEBAR_MODE_TEXT:
- gtk_container_remove (GTK_CONTAINER (button->hbox), button->icon);
- if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_ICON) {
- gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, TRUE, 0);
- gtk_widget_show (button->label);
- }
- break;
- case E_SIDEBAR_MODE_ICON:
- gtk_container_remove(GTK_CONTAINER (button->hbox), button->label);
- if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_TEXT) {
- gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, TRUE, TRUE, 0);
- gtk_widget_show (button->icon);
- } else
- gtk_container_child_set (GTK_CONTAINER (button->hbox), button->icon,
- "expand", TRUE,
- NULL);
- break;
- case E_SIDEBAR_MODE_BOTH:
- if (INTERNAL_MODE (sidebar) == E_SIDEBAR_MODE_TEXT) {
- gtk_container_remove (GTK_CONTAINER (button->hbox), button->label);
- gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, FALSE, TRUE, 0);
- gtk_widget_show (button->icon);
- } else {
- gtk_container_child_set (GTK_CONTAINER (button->hbox), button->icon,
- "expand", FALSE,
- NULL);
- }
-
- gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, TRUE, 0);
- gtk_widget_show (button->label);
- break;
- default:
- break;
- }
- }
-}
-
-static void
-style_changed_notify (GConfClient *gconf, guint id, GConfEntry *entry, gpointer data)
-{
- ESidebar *sidebar = data;
- gchar *val;
- gint mode;
-
- val = gconf_client_get_string (gconf, "/desktop/gnome/interface/toolbar_style", NULL);
- if (val == NULL || !gconf_string_to_enum (toolbar_styles, val, &mode))
- mode = E_SIDEBAR_MODE_BOTH;
- g_free(val);
-
- set_mode_internal (E_SIDEBAR (sidebar), mode);
- sidebar->priv->toolbar_mode = mode;
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-}
-
-void
-e_sidebar_set_mode (ESidebar *sidebar, ESidebarMode mode)
-{
- GConfClient *gconf_client = gconf_client_get_default ();
-
- if (sidebar->priv->mode == mode)
- return;
-
- if (sidebar->priv->mode == E_SIDEBAR_MODE_TOOLBAR) {
- if (sidebar->priv->style_changed_id) {
- gconf_client_notify_remove (gconf_client, sidebar->priv->style_changed_id);
- sidebar->priv->style_changed_id = 0;
- }
- }
-
- if (mode != E_SIDEBAR_MODE_TOOLBAR) {
- set_mode_internal (sidebar, mode);
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
- } else {
- /* This is a little bit tricky, toolbar mode is more
- * of a meta-mode where the actual mode is dictated by
- * the gnome toolbar setting, so that is why we have
- * the is_toolbar_mode bool - it tracks the toolbar
- * mode while the mode member is the actual look and
- * feel */
- sidebar->priv->style_changed_id = gconf_client_notify_add (gconf_client,
- "/desktop/gnome/interface/toolbar_style",
- style_changed_notify, sidebar, NULL, NULL);
- style_changed_notify (gconf_client, 0, NULL, sidebar);
- }
-
- g_object_unref (gconf_client);
-
- sidebar->priv->mode = mode;
-}
-
-void
-e_sidebar_set_show_buttons (ESidebar *sidebar, gboolean show)
-{
- GSList *p;
-
- if (sidebar->priv->show == show)
- return;
-
- for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
- Button *button = p->data;
-
- if (show)
- gtk_widget_show (button->button_widget);
- else
- gtk_widget_hide (button->button_widget);
- }
-
- sidebar->priv->show = show;
-
- gtk_widget_queue_resize (GTK_WIDGET (sidebar));
-}
-
-gboolean
-e_sidebar_get_show_buttons (ESidebar *sidebar)
-{
- return sidebar->priv->show;
-}
diff --git a/shell/e-sidebar.h b/shell/e-sidebar.h
deleted file mode 100644
index 9e450f8e7b..0000000000
--- a/shell/e-sidebar.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_SIDEBAR_H_
-#define _E_SIDEBAR_H_
-
-#include <gtk/gtk.h>
-
-#define E_TYPE_SIDEBAR (e_sidebar_get_type ())
-#define E_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SIDEBAR, ESidebar))
-#define E_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SIDEBAR, ESidebarClass))
-#define E_IS_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SIDEBAR))
-#define E_IS_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SIDEBAR))
-
-typedef struct _ESidebar ESidebar;
-typedef struct _ESidebarPrivate ESidebarPrivate;
-typedef struct _ESidebarClass ESidebarClass;
-
-typedef enum {
- E_SIDEBAR_MODE_TEXT,
- E_SIDEBAR_MODE_ICON,
- E_SIDEBAR_MODE_BOTH,
- E_SIDEBAR_MODE_TOOLBAR
-} ESidebarMode;
-
-struct _ESidebar {
- GtkContainer parent;
-
- ESidebarPrivate *priv;
-};
-
-struct _ESidebarClass {
- GtkContainerClass parent_class;
-
- /* signals */
- void (* button_selected) (ESidebar *sidebar, gint id);
- void (* button_pressed) (ESidebar *sidebar, GdkEventButton *event, gint id);
-};
-
-GType e_sidebar_get_type (void);
-GtkWidget *e_sidebar_new (void);
-
-void e_sidebar_set_selection_widget (ESidebar *sidebar,
- GtkWidget *widget);
-
-void e_sidebar_add_button (ESidebar *sidebar,
- const gchar *label,
- const gchar *tooltips,
- const gchar *icon_name,
- gint id);
-
-void e_sidebar_select_button (ESidebar *sidebar,
- gint id);
-
-void e_sidebar_change_button_icon (ESidebar *sidebar,
- const gchar *icon_name,
- gint button_id);
-
-ESidebarMode e_sidebar_get_mode (ESidebar *sidebar);
-void e_sidebar_set_mode (ESidebar *sidebar, ESidebarMode mode);
-
-void e_sidebar_set_show_buttons (ESidebar *sidebar, gboolean show);
-gboolean e_sidebar_get_show_buttons (ESidebar *sidebar);
-
-#endif /* _E_SIDEBAR_H_ */
diff --git a/shell/e-user-creatable-items-handler.c b/shell/e-user-creatable-items-handler.c
deleted file mode 100644
index 6fef2b7309..0000000000
--- a/shell/e-user-creatable-items-handler.c
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-user-creatable-items-handler.h"
-#include <e-util/e-icon-factory.h>
-#include "Evolution.h"
-
-#include "e-util/e-corba-utils.h"
-#include "misc/e-combo-button.h"
-
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-control.h>
-
-#include <gtk/gtk.h>
-#include <glib/gi18n-lib.h>
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-
-#include <gconf/gconf-client.h>
-
-struct _Component {
- gchar *id, *alias;
- GNOME_Evolution_Component component;
- GNOME_Evolution_CreatableItemTypeList *type_list;
-};
-typedef struct _Component Component;
-
-/* Representation of a single menu item. */
-struct _MenuItem {
- const gchar *label;
- gchar shortcut;
- gchar *verb;
- gchar *tooltip;
- gchar *component;
- GdkPixbuf *icon;
- GdkPixbuf *icon_toolbar;
-};
-typedef struct _MenuItem MenuItem;
-
-struct _EUserCreatableItemsHandlerPrivate {
- /* This component's alias */
- gchar *this_component;
-
- /* For creating items on the view */
- EUserCreatableItemsHandlerCreate create_local;
- gpointer create_data;
-
- /* The components that register user creatable items. */
- GSList *components; /* Component */
-
- /* The "New ..." menu items. */
- GSList *objects; /* MenuItem */
- GSList *folders; /* MenuItem */
-
- /* The default item (the mailer's "message" item). To be used when the
- component in the view we are in doesn't provide a default user
- creatable type. This pointer always points to one of the menu items
- in ->objects. */
- const MenuItem *fallback_menu_item;
- const MenuItem *default_menu_item;
-
- gchar *menu_xml;
- GtkWidget *new_button, *new_menu;
- BonoboControl *new_control;
- GtkAccelGroup *accel_group;
-};
-
-enum {
- PROP_THIS_COMPONENT = 1,
- LAST_PROP
-};
-
-G_DEFINE_TYPE (EUserCreatableItemsHandler, e_user_creatable_items_handler, G_TYPE_OBJECT)
-
-/* Component struct handling. */
-
-static Component *
-component_new (const gchar *id,
- const gchar *component_alias,
- GNOME_Evolution_Component component)
-{
- CORBA_Environment ev;
- Component *new;
-
- CORBA_exception_init (&ev);
-
- new = g_new (Component, 1);
- new->id = g_strdup (id);
- new->alias = g_strdup (component_alias);
-
- new->type_list = GNOME_Evolution_Component__get_userCreatableItems (component, &ev);
- if (BONOBO_EX (&ev))
- new->type_list = NULL;
-
- new->component = component;
- Bonobo_Unknown_ref (new->component, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- new->type_list = NULL;
-
- CORBA_exception_free (&ev);
-
- return new;
-}
-
-static void
-component_free (Component *component)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- Bonobo_Unknown_unref (component->component, &ev);
-
- g_free (component->id);
- g_free (component->alias);
-
- if (component->type_list != NULL)
- CORBA_free (component->type_list);
-
- CORBA_exception_free (&ev);
-
- g_free (component);
-}
-
-static const gchar *component_query =
- "repo_ids.has ('IDL:GNOME/Evolution/Component:" BASE_VERSION "')";
-
-static void
-get_components_from_bonobo (EUserCreatableItemsHandler *handler)
-{
- Bonobo_ServerInfoList *info_list;
- Bonobo_ActivationProperty *property;
- CORBA_Environment ev;
- const gchar *alias;
- gchar *iid;
- GNOME_Evolution_Component corba_component;
- Component *component;
- gint i;
-
- CORBA_exception_init (&ev);
- info_list = bonobo_activation_query (component_query, NULL, &ev);
- if (BONOBO_EX (&ev)) {
- gchar *ex_text = bonobo_exception_get_text (&ev);
- g_warning ("Cannot query for components: %s\n", ex_text);
- g_free (ex_text);
- CORBA_exception_free (&ev);
- return;
- }
-
- for (i = 0; i < info_list->_length; i++) {
- iid = info_list->_buffer[i].iid;
- corba_component = bonobo_activation_activate_from_id (iid, Bonobo_ACTIVATION_FLAG_EXISTING_ONLY, NULL, &ev);
- if (BONOBO_EX (&ev)) {
- CORBA_exception_free (&ev);
- continue;
- }
-
- property = bonobo_server_info_prop_find (&info_list->_buffer[i],
- "evolution:component_alias");
- alias = property ? property->v._u.value_string : "unknown";
-
- component = component_new (iid, alias, corba_component);
- handler->priv->components = g_slist_prepend (handler->priv->components, component);
- }
-
- CORBA_free (info_list);
-}
-
-/* Helper functions. */
-
-static gboolean
-item_is_default (const MenuItem *item,
- const gchar *component)
-{
- if (component == NULL)
- return FALSE;
-
- if (strcmp (item->component, component) == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static gchar *
-create_verb (EUserCreatableItemsHandler *handler, gint component_num, const gchar *comp, const gchar *type_id)
-{
- return g_strdup_printf ("EUserCreatableItemsHandler-%s:%d:%s", comp, component_num, type_id);
-}
-
-/* Setting up menu items for the "File -> New" submenu and the "New" toolbar
- button. */
-
-static void
-ensure_menu_items (EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- GSList *objects, *folders;
- GSList *p;
- gint component_num;
- const gchar *default_verb;
-
- priv = handler->priv;
- if (priv->objects != NULL)
- return;
-
- objects = folders = NULL;
- component_num = 0;
- default_verb = NULL;
- for (p = priv->components; p != NULL; p = p->next) {
- const Component *component;
- gint i;
-
- component = (const Component *) p->data;
- if (component->type_list != NULL) {
- for (i = 0; i < component->type_list->_length; i ++) {
- const GNOME_Evolution_CreatableItemType *corba_item;
- MenuItem *item;
-
- corba_item = (const GNOME_Evolution_CreatableItemType *) component->type_list->_buffer + i;
-
- item = g_new (MenuItem, 1);
- item->label = corba_item->menuDescription;
- item->shortcut = corba_item->menuShortcut;
- item->verb = create_verb (handler, component_num, component->alias, corba_item->id);
- item->tooltip = corba_item->tooltip;
- item->component = g_strdup (component->alias);
-
- if (strcmp (item->component, "mail") == 0
- && strcmp (corba_item->id, "message") == 0)
- default_verb = item->verb;
-
- if (corba_item->iconName == NULL || *corba_item->iconName == '\0') {
- item->icon = NULL;
- item->icon_toolbar = NULL;
- } else {
- item->icon = e_icon_factory_get_icon (corba_item->iconName, GTK_ICON_SIZE_MENU);
- if (item_is_default (item, component->alias))
- item->icon_toolbar = e_icon_factory_get_icon (corba_item->iconName, GTK_ICON_SIZE_LARGE_TOOLBAR);
- else
- item->icon_toolbar = NULL;
- }
-
- if (corba_item->type == GNOME_Evolution_CREATABLE_OBJECT)
- objects = g_slist_prepend (objects, item);
- else
- folders = g_slist_prepend (folders, item);
- }
- }
-
- component_num ++;
- }
-
- priv->objects = g_slist_reverse (objects);
- priv->folders = g_slist_reverse (folders);
-
- priv->fallback_menu_item = NULL;
- if (default_verb != NULL) {
- for (p = priv->objects; p != NULL; p = p->next) {
- const MenuItem *item;
-
- item = (const MenuItem *) p->data;
- if (strcmp (item->verb, default_verb) == 0)
- priv->fallback_menu_item = item;
- }
- }
-}
-
-static void
-free_menu_items (GSList *menu_items)
-{
- GSList *p;
-
- if (menu_items == NULL)
- return;
-
- for (p = menu_items; p != NULL; p = p->next) {
- MenuItem *item;
-
- item = (MenuItem *) p->data;
- g_free (item->verb);
-
- if (item->icon != NULL)
- g_object_unref (item->icon);
-
- if (item->icon_toolbar != NULL)
- g_object_unref (item->icon_toolbar);
-
- g_free (item->component);
- g_free (item);
- }
-
- g_slist_free (menu_items);
-}
-
-static const MenuItem *
-get_default_action_for_view (EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- const GSList *p;
-
- priv = handler->priv;
-
- for (p = priv->objects; p != NULL; p = p->next) {
- const MenuItem *item;
-
- item = (const MenuItem *) p->data;
- if (item_is_default (item, priv->this_component))
- return item;
- }
-
- return priv->fallback_menu_item;
-}
-
-/* Verb handling. */
-
-static void
-execute_verb (EUserCreatableItemsHandler *handler,
- const gchar *verb_name)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- const Component *component;
- gint component_number;
- const gchar *p;
- const gchar *id;
- GSList *component_list_item;
- gint i;
-
- priv = handler->priv;
-
- p = strchr (verb_name, ':');
- g_return_if_fail (p != NULL);
- component_number = atoi (p + 1);
-
- p = strchr (p + 1, ':');
- g_return_if_fail (p != NULL);
- id = p + 1;
-
- component_list_item = g_slist_nth (priv->components, component_number);
- g_return_if_fail (component_list_item != NULL);
-
- component = (const Component *) component_list_item->data;
-
- if (component->type_list == NULL)
- return;
-
- /* TODO: why do we actually iterate this? Is it just to check we have it in the menu? The
- search isn't used otherwise */
- for (i = 0; i < component->type_list->_length; i ++) {
- if (strcmp (component->type_list->_buffer[i].id, id) == 0) {
- if (priv->create_local && priv->this_component && strcmp(priv->this_component, component->alias) == 0) {
- priv->create_local(handler, id, priv->create_data);
- } else {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Component_requestCreateItem (component->component, id, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_warning ("Error in requestCreateItem -- %s", BONOBO_EX_REPOID (&ev));
-
- CORBA_exception_free (&ev);
- }
- return;
- }
- }
-}
-
-static void
-verb_fn (BonoboUIComponent *ui_component,
- gpointer data,
- const gchar *verb_name)
-{
- EUserCreatableItemsHandler *handler=
- E_USER_CREATABLE_ITEMS_HANDLER (data);
-
- execute_verb (handler, verb_name);
-}
-
-static void
-add_verbs (EUserCreatableItemsHandler *handler,
- BonoboUIComponent *ui_component)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- gint component_num;
- GSList *p;
-
- priv = handler->priv;
-
- component_num = 0;
- for (p = priv->components; p != NULL; p = p->next) {
- const Component *component;
- gint i;
-
- component = (const Component *) p->data;
-
- if (component->type_list != NULL) {
- for (i = 0; i < component->type_list->_length; i ++) {
- gchar *verb_name;
-
- verb_name = create_verb (handler,
- component_num,
- component->alias,
- component->type_list->_buffer[i].id);
-
- bonobo_ui_component_add_verb (ui_component, verb_name, verb_fn, handler);
-
- g_free (verb_name);
- }
- }
-
- component_num ++;
- }
-}
-
-/* Generic menu construction code */
-
-static gint
-item_types_sort_func (gconstpointer a,
- gconstpointer b)
-{
- const MenuItem *item_a;
- const MenuItem *item_b;
- const gchar *p1, *p2;
-
- item_a = (const MenuItem *) a;
- item_b = (const MenuItem *) b;
-
- p1 = item_a->label;
- p2 = item_b->label;
-
- while (*p1 != '\0' && *p2 != '\0') {
- if (*p1 == '_') {
- p1 ++;
- continue;
- }
-
- if (*p2 == '_') {
- p2 ++;
- continue;
- }
-
- if (toupper ((gint) *p1) < toupper ((gint) *p2))
- return -1;
- else if (toupper ((gint) *p1) > toupper ((gint) *p2))
- return +1;
-
- p1 ++, p2 ++;
- }
-
- if (*p1 == '\0') {
- if (*p2 == '\0')
- return 0;
- else
- return -1;
- } else {
- return +1;
- }
-}
-
-typedef void (*EUserCreatableItemsHandlerMenuItemFunc) (EUserCreatableItemsHandler *, gpointer, MenuItem *, gboolean);
-typedef void (*EUserCreatableItemsHandlerSeparatorFunc) (EUserCreatableItemsHandler *, gpointer, gint);
-
-static void
-construct_menu (EUserCreatableItemsHandler *handler, gpointer menu,
- EUserCreatableItemsHandlerMenuItemFunc menu_item_func,
- EUserCreatableItemsHandlerSeparatorFunc separator_func)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- MenuItem *item;
- GSList *p, *items;
- gboolean first = TRUE;
-
- priv = handler->priv;
-
- /* First add the current component's creatable objects */
- for (p = priv->objects; p != NULL; p = p->next) {
- item = p->data;
- if (item_is_default (item, priv->this_component)) {
- menu_item_func (handler, menu, item, first);
- first = FALSE;
- }
- }
-
- /* Then its creatable folders */
- for (p = priv->folders; p != NULL; p = p->next) {
- item = p->data;
- if (item_is_default (item, priv->this_component))
- menu_item_func (handler, menu, item, FALSE);
- }
-
- /* Then a separator */
- separator_func (handler, menu, 1);
-
- /* Then the objects from other components. */
- items = NULL;
- for (p = priv->objects; p != NULL; p = p->next) {
- item = p->data;
- if (! item_is_default (item, priv->this_component))
- items = g_slist_prepend (items, item);
- }
-
- items = g_slist_sort (items, item_types_sort_func);
- for (p = items; p != NULL; p = p->next)
- menu_item_func (handler, menu, p->data, FALSE);
- g_slist_free (items);
-
- /* Another separator */
- separator_func (handler, menu, 2);
-
- /* And finally the folders from other components */
- items = NULL;
- for (p = priv->folders; p != NULL; p = p->next) {
- item = p->data;
- if (! item_is_default (item, priv->this_component))
- items = g_slist_prepend (items, item);
- }
-
- items = g_slist_sort (items, item_types_sort_func);
- for (p = items; p != NULL; p = p->next)
- menu_item_func (handler, menu, p->data, FALSE);
- g_slist_free (items);
-}
-
-/* The XML description for "File -> New". */
-
-static void
-xml_menu_item_func (EUserCreatableItemsHandler *handler, gpointer menu,
- MenuItem *item, gboolean first)
-{
- GString *xml = menu;
- gchar *encoded_label;
- gchar *encoded_tooltip;
-
- encoded_label = bonobo_ui_util_encode_str (item->label);
- g_string_append_printf (xml, "<menuitem name=\"New:%s\" verb=\"%s\" label=\"%s\"",
- item->verb, item->verb, encoded_label);
-
- if (first)
- g_string_append_printf (xml, " accel=\"*Control*N\"");
- else if (item->shortcut != '\0')
- g_string_append_printf (xml, " accel=\"*Control**Shift*%c\"", item->shortcut);
-
- if (item->icon != NULL) {
- gchar *icon_xml;
-
- icon_xml = bonobo_ui_util_pixbuf_to_xml (item->icon);
- g_string_append_printf (xml, " pixtype=\"pixbuf\" pixname=\"%s\"", icon_xml);
- g_free (icon_xml);
- }
-
- encoded_tooltip = bonobo_ui_util_encode_str (item->tooltip);
- g_string_append_printf (xml, " tip=\"%s\"", encoded_tooltip);
-
- g_string_append (xml, "/> ");
-
- g_free (encoded_label);
- g_free (encoded_tooltip);
-}
-
-static void
-xml_separator_func (EUserCreatableItemsHandler *handler, gpointer menu, gint nth)
-{
- GString *xml = menu;
-
- g_string_append_printf (xml, "<separator f=\"\" name=\"EUserCreatableItemsHandlerSeparator%d\"/>", nth);
-}
-
-static void
-create_menu_xml (EUserCreatableItemsHandler *handler)
-{
- GString *xml;
-
- xml = g_string_new ("<placeholder name=\"NewMenu\">");
- construct_menu (handler, xml, xml_menu_item_func, xml_separator_func);
- g_string_append (xml, "</placeholder>");
-
- handler->priv->menu_xml = xml->str;
- g_string_free (xml, FALSE);
-}
-
-/* The GtkMenu for the toolbar button. */
-
-static void
-menuitem_activate (GtkMenuItem *item, gpointer data)
-{
- EUserCreatableItemsHandler *handler = data;
- const gchar *verb;
-
- verb = g_object_get_data (G_OBJECT (item), "EUserCreatableItemsHandler:verb");
- execute_verb (handler, verb);
-}
-
-static void
-default_activate (EComboButton *combo_button, gpointer data)
-{
- EUserCreatableItemsHandler *handler = data;
-
- execute_verb (handler, handler->priv->default_menu_item->verb);
-}
-
-static void
-gtk_menu_item_func (EUserCreatableItemsHandler *handler, gpointer menu,
- MenuItem *item, gboolean first)
-{
- GtkWidget *menuitem, *icon;
-
- menuitem = gtk_image_menu_item_new_with_mnemonic (item->label);
-
- if (item->icon) {
- icon = gtk_image_new_from_pixbuf (item->icon);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
- icon);
- }
-
- if (first) {
- gtk_widget_add_accelerator (menuitem, "activate",
- handler->priv->accel_group,
- 'n', GDK_CONTROL_MASK,
- GTK_ACCEL_VISIBLE);
- } else if (item->shortcut != '\0') {
- gtk_widget_add_accelerator (menuitem, "activate",
- handler->priv->accel_group,
- item->shortcut,
- GDK_CONTROL_MASK | GDK_SHIFT_MASK,
- GTK_ACCEL_VISIBLE);
- }
-
- g_object_set_data (G_OBJECT (menuitem), "EUserCreatableItemsHandler:verb", item->verb);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (menuitem_activate), handler);
-
- gtk_menu_shell_append (menu, menuitem);
-}
-
-static void
-gtk_separator_func (EUserCreatableItemsHandler *handler, gpointer menu, gint nth)
-{
- gtk_menu_shell_append (menu, gtk_separator_menu_item_new ());
-}
-
-static void
-set_combo_button_style (EComboButton *button, const gchar *style, GdkPixbuf *icon)
-{
- if (!g_ascii_strcasecmp (style,"both-horiz")) {
- e_combo_button_pack_hbox (button);
- e_combo_button_set_label (button, _("New"));
- e_combo_button_set_icon (button, icon);
- }
- else if (!g_ascii_strcasecmp (style,"icons")) {
- e_combo_button_pack_hbox (button);
- e_combo_button_set_icon (button, icon);
- e_combo_button_set_label (button, "");
- }
- else if (!g_ascii_strcasecmp(style,"text")) {
- e_combo_button_pack_hbox (button);
- e_combo_button_set_label (button, _("New"));
- e_combo_button_set_icon (button, NULL);
- } else { /* Default to both */
- e_combo_button_pack_vbox (button);
- e_combo_button_set_icon (button, icon);
- e_combo_button_set_label (button, _("New"));
- }
-}
-
-static void
-new_button_change (GConfClient *gconf,
- guint connection_id,
- GConfEntry *entry,
- EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- gchar *val;
-
- priv = handler->priv;
- val = gconf_client_get_string (gconf, "/desktop/gnome/interface/toolbar_style", NULL);
-
- set_combo_button_style (E_COMBO_BUTTON (priv->new_button),
- val, priv->default_menu_item->icon_toolbar ? priv->default_menu_item->icon_toolbar : priv->default_menu_item->icon);
-
- g_free (val);
- gtk_widget_show (priv->new_button);
-}
-
-static void
-setup_toolbar_button (EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
- GConfClient *gconf = gconf_client_get_default ();
- gchar *val;
-
- priv = handler->priv;
- val = gconf_client_get_string (gconf, "/desktop/gnome/interface/toolbar_style", NULL);
-
- priv->new_button = e_combo_button_new ();
- priv->new_menu = gtk_menu_new ();
- priv->accel_group = gtk_accel_group_new ();
- construct_menu (handler, priv->new_menu,
- gtk_menu_item_func, gtk_separator_func);
- gtk_widget_show_all (priv->new_menu);
- e_combo_button_set_menu (E_COMBO_BUTTON (priv->new_button),
- GTK_MENU (priv->new_menu));
-
- g_signal_connect (priv->new_button, "activate_default",
- G_CALLBACK (default_activate), handler);
-
- priv->new_control = bonobo_control_new (priv->new_button);
-
- priv->default_menu_item = get_default_action_for_view (handler);
- if (!priv->default_menu_item) {
- gtk_widget_set_sensitive (priv->new_button, FALSE);
- g_object_unref (gconf);
- return;
- }
-
- gtk_widget_set_sensitive (priv->new_button, TRUE);
-
- set_combo_button_style (E_COMBO_BUTTON (priv->new_button),
- val, priv->default_menu_item->icon_toolbar ? priv->default_menu_item->icon_toolbar : priv->default_menu_item->icon);
-
- gconf_client_notify_add(gconf,"/desktop/gnome/interface/toolbar_style",
- (GConfClientNotifyFunc)new_button_change, handler, NULL, NULL);
-
- gtk_widget_set_tooltip_text (priv->new_button,
- priv->default_menu_item->tooltip);
- gtk_widget_show (priv->new_button);
-
- g_free (val);
- g_object_unref (gconf);
-}
-
-/* GObject methods. */
-
-static void
-impl_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- EUserCreatableItemsHandler *handler =
- E_USER_CREATABLE_ITEMS_HANDLER (object);
-
- switch (prop_id) {
- case PROP_THIS_COMPONENT:
- handler->priv->this_component = g_value_dup_string (value);
-
- get_components_from_bonobo (handler);
- ensure_menu_items (handler);
- break;
- default:
- break;
- }
-}
-
-static void
-impl_dispose (GObject *object)
-{
- EUserCreatableItemsHandler *handler;
- EUserCreatableItemsHandlerPrivate *priv;
- GSList *p;
-
- handler = E_USER_CREATABLE_ITEMS_HANDLER (object);
- priv = handler->priv;
-
- for (p = priv->components; p != NULL; p = p->next)
- component_free ((Component *) p->data);
-
- g_slist_free (priv->components);
- priv->components = NULL;
-
- if (priv->new_control) {
- bonobo_object_unref (priv->new_control);
- priv->new_control = NULL;
- }
-
- if (priv->accel_group) {
- g_object_unref (priv->accel_group);
- priv->accel_group = NULL;
- }
-
- (* G_OBJECT_CLASS (e_user_creatable_items_handler_parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- EUserCreatableItemsHandler *handler;
- EUserCreatableItemsHandlerPrivate *priv;
-
- handler = E_USER_CREATABLE_ITEMS_HANDLER (object);
- priv = handler->priv;
-
- g_free (priv->this_component);
-
- free_menu_items (priv->objects);
- free_menu_items (priv->folders);
-
- g_free (priv->menu_xml);
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_user_creatable_items_handler_parent_class)->finalize) (object);
-}
-
-static void
-e_user_creatable_items_handler_class_init (EUserCreatableItemsHandlerClass *klass)
-{
- GObjectClass *object_class;
-
- bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
- object_class->set_property = impl_set_property;
-
- g_object_class_install_property (
- object_class, PROP_THIS_COMPONENT,
- g_param_spec_string ("this_component", "Component alias",
- "The component_alias of this component",
- NULL,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void
-e_user_creatable_items_handler_init (EUserCreatableItemsHandler *handler)
-{
- EUserCreatableItemsHandlerPrivate *priv;
-
- priv = g_new0 (EUserCreatableItemsHandlerPrivate, 1);
-
- handler->priv = priv;
-}
-
-EUserCreatableItemsHandler *
-e_user_creatable_items_handler_new (const gchar *component_alias,
- EUserCreatableItemsHandlerCreate create_local, gpointer data)
-{
- EUserCreatableItemsHandler *handler;
-
- handler = g_object_new (e_user_creatable_items_handler_get_type (),
- "this_component", component_alias,
- NULL);
- handler->priv->create_local = create_local;
- handler->priv->create_data = data;
-
- return handler;
-}
-
-/**
- * e_user_creatable_items_handler_activate:
- * @handler: the #EUserCreatableItemsHandler
- * @ui_component: the #BonoboUIComponent to attach to
- *
- * Set up the menus and toolbar items for @ui_component.
- **/
-void
-e_user_creatable_items_handler_activate (EUserCreatableItemsHandler *handler,
- BonoboUIComponent *ui_component)
-{
- EUserCreatableItemsHandlerPrivate *priv;
-
- g_return_if_fail (E_IS_USER_CREATABLE_ITEMS_HANDLER (handler));
- g_return_if_fail (BONOBO_IS_UI_COMPONENT (ui_component));
-
- priv = handler->priv;
-
- if (!priv->menu_xml) {
- create_menu_xml (handler);
- setup_toolbar_button (handler);
- add_verbs (handler, ui_component);
- }
-
- bonobo_ui_component_set (ui_component, "/menu/File/New",
- priv->menu_xml, NULL);
-
- bonobo_ui_component_object_set (ui_component,
- "/Toolbar/NewComboButton",
- BONOBO_OBJREF (priv->new_control),
- NULL);
-}
diff --git a/shell/e-user-creatable-items-handler.h b/shell/e-user-creatable-items-handler.h
deleted file mode 100644
index cb978bdb37..0000000000
--- a/shell/e-user-creatable-items-handler.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_USER_CREATABLE_ITEMS_HANDLER_H_
-#define _E_USER_CREATABLE_ITEMS_HANDLER_H_
-
-#include <glib-object.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <bonobo/bonobo-window.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_USER_CREATABLE_ITEMS_HANDLER (e_user_creatable_items_handler_get_type ())
-#define E_USER_CREATABLE_ITEMS_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_USER_CREATABLE_ITEMS_HANDLER, EUserCreatableItemsHandler))
-#define E_USER_CREATABLE_ITEMS_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_USER_CREATABLE_ITEMS_HANDLER, EUserCreatableItemsHandlerClass))
-#define E_IS_USER_CREATABLE_ITEMS_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_USER_CREATABLE_ITEMS_HANDLER))
-#define E_IS_USER_CREATABLE_ITEMS_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_USER_CREATABLE_ITEMS_HANDLER))
-
-typedef struct _EUserCreatableItemsHandler EUserCreatableItemsHandler;
-typedef struct _EUserCreatableItemsHandlerPrivate EUserCreatableItemsHandlerPrivate;
-typedef struct _EUserCreatableItemsHandlerClass EUserCreatableItemsHandlerClass;
-
-typedef void (*EUserCreatableItemsHandlerCreate)(EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data);
-
-struct _EUserCreatableItemsHandler {
- GObject parent;
-
- EUserCreatableItemsHandlerPrivate *priv;
-};
-
-struct _EUserCreatableItemsHandlerClass {
- GObjectClass parent_class;
-};
-
-GType e_user_creatable_items_handler_get_type (void);
-EUserCreatableItemsHandler *e_user_creatable_items_handler_new (const gchar *component_alias,
- EUserCreatableItemsHandlerCreate create_local, gpointer data);
-
-void e_user_creatable_items_handler_activate (EUserCreatableItemsHandler *handler,
- BonoboUIComponent *ui_component);
-
-G_END_DECLS
-
-#endif /* _E_USER_CREATABLE_ITEMS_HANDLER_H_ */
diff --git a/shell/es-event.c b/shell/es-event.c
index 5740d585c7..c647827586 100644
--- a/shell/es-event.c
+++ b/shell/es-event.c
@@ -91,11 +91,10 @@ es_event_get_type(void)
/**
* es_event_peek:
- * @void:
*
* Get the singular instance of the shell event handler.
*
- * Return value:
+ * Return: the shell event handler
**/
ESEvent *es_event_peek(void)
{
@@ -112,6 +111,14 @@ ESEvent *es_event_peek(void)
return es_event;
}
+ESEventTargetShell *
+es_event_target_new (ESEvent *eme)
+{
+ return e_event_target_new (
+ &eme->event, ES_EVENT_TARGET_SHELL,
+ sizeof (ESEventTargetShell));
+}
+
ESEventTargetState *
es_event_target_new_state(ESEvent *eme, gint state)
{
@@ -130,16 +137,6 @@ es_event_target_new_state(ESEvent *eme, gint state)
return t;
}
-ESEventTargetShell *
-es_event_target_new_shell(ESEvent *eme, EShell *shell)
-{
- ESEventTargetShell *t = e_event_target_new(&eme->event, ES_EVENT_TARGET_SHELL, sizeof(*t));
-
- t->shell = shell;
-
- return t;
-}
-
ESEventTargetUpgrade *
es_event_target_new_upgrade(ESEvent *eme, gint major, gint minor, gint revision)
{
diff --git a/shell/es-event.h b/shell/es-event.h
index b422151a56..7bb9fcd781 100644
--- a/shell/es-event.h
+++ b/shell/es-event.h
@@ -30,8 +30,6 @@
G_BEGIN_DECLS
-struct _EShell; /* Avoid including "e-shell.h" */
-
typedef struct _ESEvent ESEvent;
typedef struct _ESEventClass ESEventClass;
@@ -56,8 +54,6 @@ typedef struct _ESEventTargetComponent ESEventTargetComponent;
struct _ESEventTargetShell {
EEventTarget target;
-
- struct _EShell *shell;
};
struct _ESEventTargetState {
@@ -97,8 +93,8 @@ GType es_event_get_type(void);
ESEvent *es_event_peek(void);
+ESEventTargetShell *es_event_target_new(ESEvent *eme);
ESEventTargetState *es_event_target_new_state(ESEvent *emp, gint state);
-ESEventTargetShell *es_event_target_new_shell(ESEvent *eme, struct _EShell *shell);
ESEventTargetUpgrade *es_event_target_new_upgrade(ESEvent *emp, gint major, gint minor, gint revision);
ESEventTargetComponent *es_event_target_new_component(ESEvent *eme, const gchar *id);
diff --git a/shell/es-menu.c b/shell/es-menu.c
deleted file mode 100644
index d272d613be..0000000000
--- a/shell/es-menu.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include "es-menu.h"
-
-static GObjectClass *esm_parent;
-
-static void
-esm_init(GObject *o)
-{
- /*ESMenu *esm = (ESMenu *)o; */
-}
-
-static void
-esm_finalise(GObject *o)
-{
- ((GObjectClass *)esm_parent)->finalize(o);
-}
-
-static void
-esm_target_free(EMenu *ep, EMenuTarget *t)
-{
- switch (t->type) {
- case ES_MENU_TARGET_SHELL: {
- ESMenuTargetShell *s = (ESMenuTargetShell *)t;
-
- s = s;
- break; }
- }
-
- ((EMenuClass *)esm_parent)->target_free(ep, t);
-}
-
-static void
-esm_class_init(GObjectClass *klass)
-{
- klass->finalize = esm_finalise;
- ((EMenuClass *)klass)->target_free = esm_target_free;
-}
-
-GType
-es_menu_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(ESMenuClass),
- NULL, NULL,
- (GClassInitFunc)esm_class_init,
- NULL, NULL,
- sizeof(ESMenu), 0,
- (GInstanceInitFunc)esm_init
- };
- esm_parent = g_type_class_ref(e_menu_get_type());
- type = g_type_register_static(e_menu_get_type(), "ESMenu", &info, 0);
- }
-
- return type;
-}
-
-ESMenu *es_menu_new(const gchar *menuid)
-{
- ESMenu *esm = g_object_new(es_menu_get_type(), NULL);
-
- e_menu_construct(&esm->menu, menuid);
-
- return esm;
-}
-
-/**
- * es_menu_target_new_shell:
- * @esm:
- * @flags:
- *
- * Create a new menu target for the shell.
- *
- * Return value:
- **/
-ESMenuTargetShell *
-es_menu_target_new_shell(ESMenu *esm, guint32 flags)
-{
- ESMenuTargetShell *t = e_menu_target_new(&esm->menu, ES_MENU_TARGET_SHELL, sizeof(*t));
- guint32 mask = ~0;
-
- mask &= ~ flags;
- t->target.mask = mask;
-
- return t;
-}
-
-/* ********************************************************************** */
-
-static gpointer esph_parent_class;
-#define esph ((ESMenuHook *)eph)
-
-static const EMenuHookTargetMask esph_shell_masks[] = {
- { "online", ES_MENU_SHELL_ONLINE },
- { "offline", ES_MENU_SHELL_OFFLINE },
- { NULL }
-};
-
-static const EMenuHookTargetMap esph_targets[] = {
- { "shell", ES_MENU_TARGET_SHELL, esph_shell_masks },
- { NULL }
-};
-
-static void
-esph_finalise(GObject *o)
-{
- /*EPluginHook *eph = (EPluginHook *)o;*/
-
- ((GObjectClass *)esph_parent_class)->finalize(o);
-}
-
-static void
-esph_class_init(EPluginHookClass *klass)
-{
- gint i;
-
- /** @HookClass: Shell Main Menu
- * @Id: org.gnome.evolution.shell.bonobomenu:1.0
- * @Target: ESMenuTargetShell
- *
- * A hook for the main menus from the shell component.
- *
- * These menu's will be available from all components, but
- * will have no context for the current component.
- **/
-
- ((GObjectClass *)klass)->finalize = esph_finalise;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.shell.bonobomenu:1.0";
-
- for (i=0;esph_targets[i].type;i++)
- e_menu_hook_class_add_target_map((EMenuHookClass *)klass, &esph_targets[i]);
-
- /* FIXME: leaks parent set class? */
- ((EMenuHookClass *)klass)->menu_class = g_type_class_ref(es_menu_get_type());
-}
-
-GType
-es_menu_hook_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(ESMenuHookClass), NULL, NULL, (GClassInitFunc) esph_class_init, NULL, NULL,
- sizeof(ESMenuHook), 0, (GInstanceInitFunc) NULL,
- };
-
- esph_parent_class = g_type_class_ref(e_menu_hook_get_type());
- type = g_type_register_static(e_menu_hook_get_type(), "ESMenuHook", &info, 0);
- }
-
- return type;
-}
diff --git a/shell/es-menu.h b/shell/es-menu.h
deleted file mode 100644
index d8ac21a567..0000000000
--- a/shell/es-menu.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michel Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __ES_MENU_H__
-#define __ES_MENU_H__
-
-#include <glib-object.h>
-
-#include "e-util/e-menu.h"
-
-G_BEGIN_DECLS
-
-typedef struct _ESMenu ESMenu;
-typedef struct _ESMenuClass ESMenuClass;
-
-/* Current target description */
-/* Types of popup tagets */
-enum _es_menu_target_t {
- ES_MENU_TARGET_SHELL
-};
-
-/* Flags that describe a TARGET_SHELL */
-enum {
- ES_MENU_SHELL_ONLINE = 1<<0,
- ES_MENU_SHELL_OFFLINE = 1<<1
-};
-
-typedef struct _ESMenuTargetShell ESMenuTargetShell;
-
-struct _ESMenuTargetShell {
- EMenuTarget target;
-
- /* current component?? */
-};
-
-typedef struct _EMenuItem ESMenuItem;
-
-/* The object */
-struct _ESMenu {
- EMenu menu;
-
- struct _ESMenuPrivate *priv;
-};
-
-struct _ESMenuClass {
- EMenuClass menu_class;
-};
-
-GType es_menu_get_type(void);
-
-ESMenu *es_menu_new(const gchar *menuid);
-
-ESMenuTargetShell *es_menu_target_new_shell(ESMenu *emp, guint32 flags);
-
-/* ********************************************************************** */
-
-typedef struct _ESMenuHook ESMenuHook;
-typedef struct _ESMenuHookClass ESMenuHookClass;
-
-struct _ESMenuHook {
- EMenuHook hook;
-};
-
-struct _ESMenuHookClass {
- EMenuHookClass hook_class;
-};
-
-GType es_menu_hook_get_type(void);
-
-G_END_DECLS
-
-#endif /* __ES_MENU_H__ */
diff --git a/shell/evolution-component.h b/shell/evolution-component.h
deleted file mode 100644
index 302263a657..0000000000
--- a/shell/evolution-component.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *
- * Abstract class wrapper for EvolutionComponent
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _EVOLUTION_COMPONENT_H_
-#define _EVOLUTION_COMPONENT_H_
-
-#include <bonobo/bonobo-object.h>
-#include "shell/Evolution.h"
-
-typedef struct _EvolutionComponent EvolutionComponent;
-typedef struct _EvolutionComponentClass EvolutionComponentClass;
-
-struct _EvolutionComponent {
- BonoboObject parent;
-};
-
-struct _EvolutionComponentClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Component__epv epv;
-};
-
-GType evolution_component_get_type(void);
-
-#endif /* _EVOLUTION_COMPONENT_H_ */
diff --git a/shell/evolution-config-control.c b/shell/evolution-config-control.c
deleted file mode 100644
index a0d3f473a2..0000000000
--- a/shell/evolution-config-control.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-config-control.h"
-
-#include <e-util/e-util.h>
-
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-event-source.h>
-
-
-#define PARENT_TYPE BONOBO_OBJECT_TYPE
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionConfigControlPrivate {
- BonoboControl *control;
- BonoboEventSource *event_source;
-};
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- EvolutionConfigControl *config_control;
- EvolutionConfigControlPrivate *priv;
-
- config_control = EVOLUTION_CONFIG_CONTROL (object);
- priv = config_control->priv;
-
- if (priv->control != NULL) {
- bonobo_object_unref (BONOBO_OBJECT (priv->control));
- priv->control = NULL;
- }
-
- if (priv->event_source != NULL) {
- bonobo_object_unref (BONOBO_OBJECT (priv->event_source));
- priv->event_source = NULL;
- }
-
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- EvolutionConfigControl *config_control;
- EvolutionConfigControlPrivate *priv;
-
- config_control = EVOLUTION_CONFIG_CONTROL (object);
- priv = config_control->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-
-/* Evolution::ConfigControl CORBA methods. */
-
-static Bonobo_Control
-impl__get_control (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionConfigControl *config_control;
- EvolutionConfigControlPrivate *priv;
-
- config_control = EVOLUTION_CONFIG_CONTROL (bonobo_object_from_servant (servant));
- priv = config_control->priv;
-
- bonobo_object_ref (BONOBO_OBJECT (priv->control));
-
- return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (priv->control)), ev);
-}
-
-static Bonobo_EventSource
-impl__get_eventSource (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionConfigControl *config_control;
- EvolutionConfigControlPrivate *priv;
-
- config_control = EVOLUTION_CONFIG_CONTROL (bonobo_object_from_servant (servant));
- priv = config_control->priv;
-
- bonobo_object_ref (BONOBO_OBJECT (priv->event_source));
-
- return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (priv->event_source)), ev);
-}
-
-
-static void
-evolution_config_control_class_init (EvolutionConfigControlClass *class)
-{
- POA_GNOME_Evolution_ConfigControl__epv *epv;
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-
- epv = &class->epv;
- epv->_get_control = impl__get_control;
- epv->_get_eventSource = impl__get_eventSource;
-
- parent_class = g_type_class_ref (PARENT_TYPE);
-}
-
-static void
-evolution_config_control_init (EvolutionConfigControl *config_control)
-{
- EvolutionConfigControlPrivate *priv;
-
- priv = g_new (EvolutionConfigControlPrivate, 1);
- priv->control = NULL;
- priv->event_source = bonobo_event_source_new ();
-
- config_control->priv = priv;
-}
-
-
-void
-evolution_config_control_construct (EvolutionConfigControl *control,
- GtkWidget *widget)
-{
- EvolutionConfigControlPrivate *priv;
-
- g_return_if_fail (EVOLUTION_IS_CONFIG_CONTROL (control));
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- priv = control->priv;
-
- priv->control = bonobo_control_new (widget);
-}
-
-EvolutionConfigControl *
-evolution_config_control_new (GtkWidget *widget)
-{
- EvolutionConfigControl *new;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- new = g_object_new (evolution_config_control_get_type (), NULL);
- evolution_config_control_construct (new, widget);
-
- return new;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionConfigControl,
- GNOME_Evolution_ConfigControl,
- PARENT_TYPE,
- evolution_config_control)
diff --git a/shell/evolution-config-control.h b/shell/evolution-config-control.h
deleted file mode 100644
index 59d7aba210..0000000000
--- a/shell/evolution-config-control.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_CONFIG_CONTROL_H
-#define EVOLUTION_CONFIG_CONTROL_H
-
-#include "Evolution.h"
-
-#include <bonobo/bonobo-object.h>
-#include <gtk/gtk.h>
-
-#ifdef cplusplus
-extern "C" {
-#pragma }
-#endif /* cplusplus */
-
-#define EVOLUTION_TYPE_CONFIG_CONTROL (evolution_config_control_get_type ())
-#define EVOLUTION_CONFIG_CONTROL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_CONFIG_CONTROL, EvolutionConfigControl))
-#define EVOLUTION_CONFIG_CONTROL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_CONFIG_CONTROL, EvolutionConfigControlClass))
-#define EVOLUTION_IS_CONFIG_CONTROL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_CONFIG_CONTROL))
-#define EVOLUTION_IS_CONFIG_CONTROL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_CONFIG_CONTROL))
-
-typedef struct _EvolutionConfigControl EvolutionConfigControl;
-typedef struct _EvolutionConfigControlPrivate EvolutionConfigControlPrivate;
-typedef struct _EvolutionConfigControlClass EvolutionConfigControlClass;
-
-struct _EvolutionConfigControl {
- BonoboObject parent;
-
- EvolutionConfigControlPrivate *priv;
-};
-
-struct _EvolutionConfigControlClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_ConfigControl__epv epv;
-};
-
-
-GType evolution_config_control_get_type (void);
-EvolutionConfigControl *evolution_config_control_new (GtkWidget *widget);
-void evolution_config_control_construct (EvolutionConfigControl *control,
- GtkWidget *widget);
-
-#endif /* EVOLUTION_CONFIG_CONTROL_H */
diff --git a/shell/evolution-listener.c b/shell/evolution-listener.c
deleted file mode 100644
index 3209450134..0000000000
--- a/shell/evolution-listener.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-listener.h"
-
-#define PARENT_TYPE bonobo_object_get_type ()
-
-static BonoboObjectClass *parent_class = NULL;
-
-/* Evolution.Listener */
-static void
-impl_complete(PortableServer_Servant _servant, CORBA_Environment * ev)
-{
- EvolutionListener *el = (EvolutionListener *)bonobo_object_from_servant(_servant);
-
- if (el->complete)
- el->complete(el, el->data);
-}
-
-static void
-evolution_listener_class_init (EvolutionListenerClass *klass)
-{
- POA_GNOME_Evolution_Listener__epv *epv = &klass->epv;
-
- parent_class = g_type_class_peek_parent (klass);
-
- epv->complete = impl_complete;
-}
-
-static void
-evolution_listener_init(EvolutionListener *emf, EvolutionListenerClass *klass)
-{
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionListener, GNOME_Evolution_Listener, PARENT_TYPE, evolution_listener)
-
-EvolutionListener *
-evolution_listener_new(EvolutionListenerFunc complete, gpointer data)
-{
- EvolutionListener *el;
-
- el = g_object_new(evolution_listener_get_type(), NULL);
- el->complete = complete;
- el->data = data;
-
- return el;
-}
diff --git a/shell/evolution-listener.h b/shell/evolution-listener.h
deleted file mode 100644
index 9637342099..0000000000
--- a/shell/evolution-listener.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * Abstract class wrapper for EvolutionListener
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _EVOLUTION_LISTENER_H_
-#define _EVOLUTION_LISTENER_H_
-
-#include <bonobo/bonobo-object.h>
-#include "shell/Evolution.h"
-
-typedef struct _EvolutionListener EvolutionListener;
-typedef struct _EvolutionListenerClass EvolutionListenerClass;
-
-typedef void (*EvolutionListenerFunc)(EvolutionListener *, gpointer );
-
-struct _EvolutionListener {
- BonoboObject parent;
-
- /* we dont need signals, so why bother wasting resources on it */
- EvolutionListenerFunc complete;
- gpointer data;
-};
-
-struct _EvolutionListenerClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Listener__epv epv;
-};
-
-GType evolution_listener_get_type(void);
-EvolutionListener *evolution_listener_new(EvolutionListenerFunc complete, gpointer data);
-
-#endif /* _EVOLUTION_LISTENER_H_ */
diff --git a/shell/evolution-shell-component-utils.c b/shell/evolution-shell-component-utils.c
deleted file mode 100644
index 7301a3741b..0000000000
--- a/shell/evolution-shell-component-utils.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-shell-component-utils.h"
-#include <e-util/e-icon-factory.h>
-#include "e-util/e-dialog-utils.h"
-
-#include <string.h>
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo-activation/bonobo-activation.h>
-
-static void free_pixmaps (void);
-static GSList *inited_arrays = NULL;
-
-void e_pixmaps_update (BonoboUIComponent *uic, EPixmap *pixcache)
-{
- static gint done_init = 0;
- gint i;
-
- if (!done_init) {
- g_atexit (free_pixmaps);
- done_init = 1;
- }
-
- if (g_slist_find (inited_arrays, pixcache) == NULL)
- inited_arrays = g_slist_prepend (inited_arrays, pixcache);
-
- for (i = 0; pixcache [i].path; i++) {
- if (!pixcache [i].pixbuf) {
- GdkPixbuf *pixbuf;
-
- pixbuf = e_icon_factory_get_icon (pixcache [i].name, pixcache [i].size);
- pixcache [i].pixbuf = bonobo_ui_util_pixbuf_to_xml (pixbuf);
- g_object_unref (pixbuf);
- bonobo_ui_component_set_prop (uic,
- pixcache [i].path, "pixname",
- pixcache [i].pixbuf, NULL);
- } else {
- bonobo_ui_component_set_prop (uic, pixcache [i].path,
- "pixname",
- pixcache [i].pixbuf,
- NULL);
- }
- }
-}
-
-static void
-free_pixmaps (void)
-{
- gint i;
- GSList *li;
-
- for (li = inited_arrays; li != NULL; li = li->next) {
- EPixmap *pixcache = li->data;
- for (i = 0; pixcache [i].path; i++)
- g_free (pixcache [i].pixbuf);
- }
-
- g_slist_free (inited_arrays);
-}
-
-/**
- * e_get_activation_failure_msg:
- * @ev: An exception returned by an oaf_activate call.
- *
- * Get a descriptive error message from @ev.
- *
- * Return value: A newly allocated string with the printable error message.
- **/
-gchar *
-e_get_activation_failure_msg (CORBA_Environment *ev)
-{
- g_return_val_if_fail (ev != NULL, NULL);
-
- if (CORBA_exception_id (ev) == NULL)
- return NULL;
-
- if (strcmp (CORBA_exception_id (ev), ex_Bonobo_GeneralError) != 0) {
- return bonobo_exception_get_text (ev);
- } else {
- const Bonobo_GeneralError *oaf_general_error;
-
- oaf_general_error = CORBA_exception_value (ev);
- return g_strdup (oaf_general_error->description);
- }
-}
diff --git a/shell/evolution-shell-component-utils.h b/shell/evolution-shell-component-utils.h
deleted file mode 100644
index 1c2412e230..0000000000
--- a/shell/evolution-shell-component-utils.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EVOLUTION_SHELL_COMPONENT_UTILS_H__
-#define __EVOLUTION_SHELL_COMPONENT_UTILS_H__
-
-#include <bonobo/bonobo-ui-component.h>
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-typedef struct _EPixmap {
- const gchar *path;
- const gchar *name;
- GtkIconSize size;
- gchar *pixbuf;
-} EPixmap;
-
-#define E_PIXMAP(path,name,size) { (path), (name), (size), NULL }
-#define E_PIXMAP_END { NULL, NULL, 0, NULL }
-
-/* Takes an array of pixmaps, terminated by E_PIXMAP_END, and loads into uic */
-void e_pixmaps_update (BonoboUIComponent *uic, EPixmap *pixcache);
-
-gchar *e_get_activation_failure_msg (CORBA_Environment *ev);
-
-G_END_DECLS
-
-#endif /* __EVOLUTION_SHELL_COMPONENT_UTILS_H__ */
diff --git a/shell/import.glade b/shell/import.glade
deleted file mode 100644
index 389d2feee3..0000000000
--- a/shell/import.glade
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkWindow" id="importwizard">
- <property name="title" translatable="yes">Evolution Import Assistant</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
-
- <child>
- <widget class="GnomeDruid" id="druid1">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="show_help">False</property>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="page0">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_START</property>
- <property name="title" translatable="yes">Evolution Import Assistant</property>
- <property name="text" translatable="yes">Welcome to the Evolution Import Assistant.
-With this assistant you will be guided through the process of
-importing external files into Evolution.</property>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page1">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Importer Type</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox2">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page2-file">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Select a File</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox1">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page3-file">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Import Location</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox3">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page2-intelligent">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Select Information to Import</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox3">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="page4">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_FINISH</property>
- <property name="title" translatable="yes">Import File</property>
- <property name="text" translatable="yes">Click &quot;Import&quot; to begin importing the file into Evolution. </property>
- </widget>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/shell/importer/GNOME_Evolution_Importer.idl b/shell/importer/GNOME_Evolution_Importer.idl
deleted file mode 100644
index e33ca150ae..0000000000
--- a/shell/importer/GNOME_Evolution_Importer.idl
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Interfaces for the importer framework.
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- */
-
-#include <Bonobo.idl>
-
-module GNOME {
-module Evolution {
- interface ImporterListener : Bonobo::Unknown {
- enum ImporterResult {
- OK,
- UNSUPPORTED_OPERATION,
- NOT_READY,
- BUSY,
- UNKNOWN_DATA,
- BAD_DATA,
- BAD_FILE
- };
-
- /**
- * notifyResult:
- * @result: The result of the import.
- * @more_items: Are there any more items to be processed?
- *
- * Notifies the listener of the result and whether there are
- * any more items to be imported.
- */
- oneway void notifyResult (in ImporterResult result,
- in boolean more_items);
- };
-
- interface Importer : Bonobo::Unknown {
-
- /**
- * processItem:
- * @listener: The ImporterListener that will be notified of the
- * progress.
- *
- * Processes the next item.
- *
- */
- oneway void processItem (in ImporterListener listener);
-
- /**
- * getError:
- *
- * Retrieve a detailed explaination of the error.
- *
- * Returns: A string.
- */
- string getError ();
-
- void createControl (out Bonobo::Control control);
-
- /**
- * supportFormat:
- * @filename: The filename of the file.
- *
- * Checks if the importer created by this factory can
- * import the file specified.
- *
- * Returns: A boolean, TRUE if it can import the file,
- * FALSE otherwise.
- */
- boolean supportFormat (in string filename);
-
- /**
- * loadFile:
- * @filename: The filename of the file.
- * @folderpath: The full pathname to the folder.
- * @foldertpe: The type of the folder to import to.
- *
- * Loads the file and prepares an Importer object that can
- * process files of this type.
- *
- * Returns: An Importer object.
- */
- boolean loadFile (in string filename);
- };
-
- interface IntelligentImporter : Bonobo::Unknown {
-
- readonly attribute string importername;
- readonly attribute string message;
-
- boolean canImport ();
-
- void importData ();
- };
-};
-};
diff --git a/shell/importer/Makefile.am b/shell/importer/Makefile.am
deleted file mode 100644
index 06735179af..0000000000
--- a/shell/importer/Makefile.am
+++ /dev/null
@@ -1,68 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/shell \
- -I$(top_builddir)/shell \
- -DG_LOG_DOMAIN=\"Evolution-Importer\" \
- -DEVOLUTION_GLADEDIR="\"$(gladedir)\"" \
- $(SHELL_CFLAGS)
-
-privlib_LTLIBRARIES = libevolution-importer.la
-
-
-# IDL stuff
-
-IDLS = GNOME_Evolution_Importer.idl
-
-IDL_GENERATED_H = \
- GNOME_Evolution_Importer.h
-
-IDL_GENERATED_C = \
- GNOME_Evolution_Importer-common.c \
- GNOME_Evolution_Importer-skels.c \
- GNOME_Evolution_Importer-stubs.c
-
-IDL_GENERATED = $(IDL_GENERATED_H) $(IDL_GENERATED_C)
-
-$(IDL_GENERATED_H): $(IDLS)
- $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) $(srcdir)/GNOME_Evolution_Importer.idl
-
-$(IDL_GENERATED_C): $(IDL_GENERATED_H)
-
-idl_DATA = $(IDLS)
-
-
-# Component
-
-libevolution_importerincludedir = $(privincludedir)/importer
-libevolution_importer_la_SOURCES = \
- $(IDL_GENERATED) \
- evolution-intelligent-importer.c \
- evolution-importer-client.c \
- evolution-importer-listener.c \
- evolution-importer.c \
- intelligent.c \
- intelligent.h
-
-libevolution_importerinclude_HEADERS = \
- GNOME_Evolution_Importer.h \
- evolution-intelligent-importer.h \
- evolution-importer-client.h \
- evolution-importer-listener.h \
- evolution-importer.h
-
-libevolution_importer_la_LIBADD = \
- $(top_builddir)/e-util/libeutil.la \
- $(SHELL_LIBS)
-
-glade_DATA = import.glade
-
-EXTRA_DIST = $(glade_DATA) $(IDLS)
-
-BUILT_SOURCES= $(IDL_GENERATED)
-CLEANFILES = $(BUILT_SOURCES)
-
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
-
-
--include $(top_srcdir)/git.mk
diff --git a/shell/importer/evolution-importer-client.c b/shell/importer/evolution-importer-client.c
deleted file mode 100644
index 66a82836e3..0000000000
--- a/shell/importer/evolution-importer-client.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Based on evolution-shell-component-client.c by Ettore Perazzoli
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-importer-client.h"
-
-#include <glib.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-widget.h>
-#include <bonobo/bonobo-exception.h>
-
-#include "GNOME_Evolution_Importer.h"
-
-G_DEFINE_TYPE (EvolutionImporterClient, evolution_importer_client, G_TYPE_OBJECT)
-
-
-static void
-finalise (GObject *object)
-{
- /* FIXME: should this unref the client->objref?? */
-
- (* G_OBJECT_CLASS (evolution_importer_client_parent_class)->finalize) (object);
-}
-
-static void
-evolution_importer_client_class_init (EvolutionImporterClientClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = finalise;
-}
-
-static void
-evolution_importer_client_init (EvolutionImporterClient *client)
-{
-}
-
-/**
- * evolution_importer_client_new:
- * @objref: The CORBA_Object to make a client for.
- *
- * Makes a client for @objref. @objref should be an Evolution_Importer.
- *
- * Returns: A newly created EvolutionImporterClient.
- */
-EvolutionImporterClient *
-evolution_importer_client_new (const CORBA_Object objref)
-{
- EvolutionImporterClient *client;
-
- g_return_val_if_fail (objref != CORBA_OBJECT_NIL, NULL);
-
- client = g_object_new (evolution_importer_client_get_type (), NULL);
- client->objref = objref;
-
- return client;
-}
-
-/**
- * evolution_importer_client_new_from_id:
- * @id: The oafiid of the component to make a client for.
- *
- * Makes a client for the object returned by activating @id.
- *
- * Returns: A newly created EvolutionImporterClient.
- */
-EvolutionImporterClient *
-evolution_importer_client_new_from_id (const gchar *id)
-{
- CORBA_Environment ev;
- CORBA_Object objref;
-
- g_return_val_if_fail (id != NULL, NULL);
-
- CORBA_exception_init (&ev);
- objref = bonobo_activation_activate_from_id ((gchar *) id, 0, NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
- g_warning ("Could not start %s.", id);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
- if (objref == CORBA_OBJECT_NIL) {
- g_warning ("Could not activate component %s", id);
- return NULL;
- }
-
- return evolution_importer_client_new (objref);
-}
-
-/* API */
-GtkWidget *
-evolution_importer_client_create_control (EvolutionImporterClient *client)
-{
- GNOME_Evolution_Importer corba_importer;
- GtkWidget *widget = NULL;
- Bonobo_Control control;
- CORBA_Environment ev;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), NULL);
-
- CORBA_exception_init (&ev);
- corba_importer = client->objref;
- GNOME_Evolution_Importer_createControl (corba_importer, &control, &ev);
-
- if (!BONOBO_EX (&ev)) {
- /* FIXME Pass in container? */
- widget = bonobo_widget_new_control_from_objref (control, NULL);
- gtk_widget_show (widget);
- }
-
- CORBA_exception_free (&ev);
-
- return widget;
-}
-
-/**
- * evolution_importer_client_support_format:
- * @client: The EvolutionImporterClient.
- * @filename: Name of the file to check.
- *
- * Checks whether @client is able to import @filename.
- *
- * Returns: TRUE if @client can import @filename, FALSE otherwise.
- */
-gboolean
-evolution_importer_client_support_format (EvolutionImporterClient *client,
- const gchar *filename)
-{
- GNOME_Evolution_Importer corba_importer;
- gboolean result;
- CORBA_Environment ev;
-
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), FALSE);
- g_return_val_if_fail (filename != NULL, FALSE);
-
- CORBA_exception_init (&ev);
- corba_importer = client->objref;
- result = GNOME_Evolution_Importer_supportFormat (corba_importer,
- filename, &ev);
- CORBA_exception_free (&ev);
-
- return result;
-}
-
-/**
- * evolution_importer_client_load_file:
- * @client: The EvolutionImporterClient.
- * @filename: The file to load.
- * @physical_uri: The physical URI of the folder to import data into.
- * @folder_type: The type of the folder represented by @physical_uri.
- *
- * Loads and initialises the importer.
- *
- * Returns: TRUE on sucess, FALSE on failure.
- */
-gboolean
-evolution_importer_client_load_file (EvolutionImporterClient *client, const gchar *filename)
-{
- GNOME_Evolution_Importer corba_importer;
- gboolean result;
- CORBA_Environment ev;
-
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), FALSE);
- g_return_val_if_fail (filename != NULL, FALSE);
-
- CORBA_exception_init (&ev);
- corba_importer = client->objref;
- result = GNOME_Evolution_Importer_loadFile (corba_importer, filename, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Oh there *WAS* an exception.\nIt was %s",
- CORBA_exception_id (&ev));
- CORBA_exception_free (&ev);
- return FALSE;
- }
- CORBA_exception_free (&ev);
-
- return result;
-}
-
-/**
- * evolution_importer_client_process_item:
- * @client: The EvolutionImporterClient.
- * @listener: The EvolutionImporterListener.
- *
- * Starts importing the next item in the file. @listener will be notified
- * when the item has finished.
- */
-void
-evolution_importer_client_process_item (EvolutionImporterClient *client,
- EvolutionImporterListener *listener)
-{
- GNOME_Evolution_Importer corba_importer;
- GNOME_Evolution_ImporterListener corba_listener;
- CORBA_Environment ev;
-
- g_return_if_fail (client != NULL);
- g_return_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client));
- g_return_if_fail (listener != NULL);
- g_return_if_fail (EVOLUTION_IS_IMPORTER_LISTENER (listener));
-
- CORBA_exception_init (&ev);
-
- corba_importer = client->objref;
- corba_listener = bonobo_object_corba_objref (BONOBO_OBJECT (listener));
- GNOME_Evolution_Importer_processItem (corba_importer,
- corba_listener, &ev);
- CORBA_exception_free (&ev);
-}
-
-/**
- * evolution_importer_client_get_error:
- * @client: The EvolutionImporterClient.
- *
- * Gets the error as a string.
- *
- * Returns: The error as a string. If there is no error NULL is returned.
- * Importers need not support this method and if so, NULL is also returned.
- */
-const gchar *
-evolution_importer_client_get_error (EvolutionImporterClient *client)
-{
- GNOME_Evolution_Importer corba_importer;
- CORBA_char *str;
- CORBA_Environment ev;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), NULL);
-
- corba_importer = client->objref;
-
- CORBA_exception_init (&ev);
- str = GNOME_Evolution_Importer_getError (corba_importer, &ev);
-
- return str;
-}
diff --git a/shell/importer/evolution-importer-client.h b/shell/importer/evolution-importer-client.h
deleted file mode 100644
index e94584216d..0000000000
--- a/shell/importer/evolution-importer-client.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_IMPORTER_CLIENT_H
-#define EVOLUTION_IMPORTER_CLIENT_H
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <importer/evolution-importer.h>
-#include <importer/evolution-importer-listener.h>
-
-G_BEGIN_DECLS
-
-#define EVOLUTION_TYPE_IMPORTER_CLIENT (evolution_importer_client_get_type ())
-#define EVOLUTION_IMPORTER_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_IMPORTER_CLIENT, EvolutionImporterClient))
-#define EVOLUTION_IMPORTER_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_IMPORTER_CLIENT, EvolutionImporterClientClass))
-#define EVOLUTION_IS_IMPORTER_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_IMPORTER_CLIENT))
-#define EVOLUTION_IS_IMPORTER_CLIENT_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE ((klass), EVOLUTION_TYPE_IMPORTER_CLIENT))
-
-
-typedef struct _EvolutionImporterClient EvolutionImporterClient;
-typedef struct _EvolutionImporterClientClass EvolutionImporterClientClass;
-
-struct _EvolutionImporterClient {
- GObject parent_type;
-
- GNOME_Evolution_Importer objref;
-};
-
-struct _EvolutionImporterClientClass {
- GObjectClass parent_class;
-};
-
-GType evolution_importer_client_get_type (void);
-
-EvolutionImporterClient *evolution_importer_client_new (const CORBA_Object objref);
-EvolutionImporterClient *evolution_importer_client_new_from_id (const gchar *id);
-
-GtkWidget *evolution_importer_client_create_control (EvolutionImporterClient *client);
-gboolean evolution_importer_client_support_format (EvolutionImporterClient *client,
- const gchar *filename);
-gboolean evolution_importer_client_load_file (EvolutionImporterClient *client,
- const gchar *filename);
-void evolution_importer_client_process_item (EvolutionImporterClient *client,
- EvolutionImporterListener *listener);
-const gchar *evolution_importer_client_get_error (EvolutionImporterClient *client);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/importer/evolution-importer-listener.c b/shell/importer/evolution-importer-listener.c
deleted file mode 100644
index ffac2d3ab4..0000000000
--- a/shell/importer/evolution-importer-listener.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-importer-listener.h"
-
-#include <bonobo/bonobo-object.h>
-#include <e-util/e-util.h>
-
-#include "GNOME_Evolution_Importer.h"
-#define PARENT_TYPE BONOBO_OBJECT_TYPE
-
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionImporterListenerPrivate {
- EvolutionImporterListenerCallback callback;
-
- gpointer closure;
-};
-
-#if 0
-static POA_GNOME_Evolution_ImporterListener__vepv Listener_vepv;
-
-static POA_GNOME_Evolution_ImporterListener *
-create_servant (void)
-{
- POA_GNOME_Evolution_ImporterListener *servant;
- CORBA_Environment ev;
-
- servant = (POA_GNOME_Evolution_ImporterListener *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &Listener_vepv;
-
- CORBA_exception_init (&ev);
- POA_GNOME_Evolution_ImporterListener__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- return servant;
-}
-#endif
-
-static EvolutionImporterResult
-corba_result_to_evolution (GNOME_Evolution_ImporterListener_ImporterResult corba_result)
-{
- switch (corba_result) {
- case GNOME_Evolution_ImporterListener_OK:
- return EVOLUTION_IMPORTER_OK;
- case GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION:
- return EVOLUTION_IMPORTER_UNSUPPORTED_OPERATION;
- case GNOME_Evolution_ImporterListener_UNKNOWN_DATA:
- return EVOLUTION_IMPORTER_UNKNOWN_DATA;
- case GNOME_Evolution_ImporterListener_BAD_DATA:
- return EVOLUTION_IMPORTER_BAD_DATA;
- case GNOME_Evolution_ImporterListener_BAD_FILE:
- return EVOLUTION_IMPORTER_BAD_FILE;
- case GNOME_Evolution_ImporterListener_NOT_READY:
- return EVOLUTION_IMPORTER_NOT_READY;
- case GNOME_Evolution_ImporterListener_BUSY:
- return EVOLUTION_IMPORTER_BUSY;
- default:
- return EVOLUTION_IMPORTER_UNKNOWN_ERROR;
- }
-}
-
-static inline EvolutionImporterListener *
-evolution_importer_listener_from_servant (PortableServer_Servant servant)
-{
- return EVOLUTION_IMPORTER_LISTENER (bonobo_object_from_servant (servant));
-}
-
-static void
-impl_GNOME_Evolution_ImporterListener_notifyResult (PortableServer_Servant servant,
- GNOME_Evolution_ImporterListener_ImporterResult result,
- CORBA_boolean more_items,
- CORBA_Environment *ev)
-{
- EvolutionImporterListener *listener;
- EvolutionImporterListenerPrivate *priv;
- EvolutionImporterResult out_result;
-
- listener = evolution_importer_listener_from_servant (servant);
- priv = listener->priv;
-
- out_result = corba_result_to_evolution (result);
- if (priv->callback) {
- (priv->callback) (listener, out_result, more_items,
- priv->closure);
- }
-
- return;
-}
-
-
-/* GObject methods */
-static void
-finalise (GObject *object)
-{
- EvolutionImporterListener *listener;
- EvolutionImporterListenerPrivate *priv;
-
- listener = EVOLUTION_IMPORTER_LISTENER (object);
- priv = listener->priv;
-
- if (priv == NULL)
- return;
-
- g_free (priv);
- listener->priv = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize(object);
-}
-
-#if 0
-static void
-corba_class_init (void)
-{
- POA_GNOME_Evolution_ImporterListener__vepv *vepv;
- POA_GNOME_Evolution_ImporterListener__epv *epv;
- PortableServer_ServantBase__epv *base_epv;
-
- base_epv = g_new0 (PortableServer_ServantBase__epv, 1);
- base_epv->_private = NULL;
- base_epv->finalize = NULL;
- base_epv->default_POA = NULL;
-
- epv = g_new0 (POA_GNOME_Evolution_ImporterListener__epv, 1);
- epv->notifyResult = impl_GNOME_Evolution_ImporterListener_notifyResult;
-
- vepv = &Listener_vepv;
- vepv->_base_epv = base_epv;
- vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
- vepv->GNOME_Evolution_ImporterListener_epv = epv;
-}
-#endif
-
-static void
-evolution_importer_listener_class_init (EvolutionImporterListenerClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_ImporterListener__epv *epv = &klass->epv;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = finalise;
-
- parent_class = g_type_class_ref(PARENT_TYPE);
- epv->notifyResult = impl_GNOME_Evolution_ImporterListener_notifyResult;
-}
-
-static void
-evolution_importer_listener_init (EvolutionImporterListener *listener)
-{
- EvolutionImporterListenerPrivate *priv;
-
- priv = g_new0 (EvolutionImporterListenerPrivate, 1);
- listener->priv = priv;
-}
-
-static void
-evolution_importer_listener_construct (EvolutionImporterListener *listener,
- EvolutionImporterListenerCallback callback,
- gpointer closure)
-{
- EvolutionImporterListenerPrivate *priv;
-
- g_return_if_fail (listener != NULL);
- g_return_if_fail (EVOLUTION_IS_IMPORTER_LISTENER (listener));
- g_return_if_fail (callback != NULL);
-
- priv = listener->priv;
- priv->callback = callback;
- priv->closure = closure;
-}
-
-/**
- * evolution_importer_listener_new
- * @callback: The #EvolutionImporterListenerCallback callback.
- * @closure: The data that will be passed to that callback.
- *
- * Creates a new #EvolutionImporterListener object which calls @callback when
- * something happens.
- * Returns: A newly allocated #EvolutionImporterListener.
- */
-EvolutionImporterListener *
-evolution_importer_listener_new (EvolutionImporterListenerCallback callback,
- gpointer closure)
-{
- EvolutionImporterListener *listener;
-
- listener = g_object_new (evolution_importer_listener_get_type (), NULL);
-
- evolution_importer_listener_construct (listener, callback, closure);
- return listener;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionImporterListener,
- GNOME_Evolution_ImporterListener,
- PARENT_TYPE, evolution_importer_listener);
diff --git a/shell/importer/evolution-importer-listener.h b/shell/importer/evolution-importer-listener.h
deleted file mode 100644
index 39bf2a0493..0000000000
--- a/shell/importer/evolution-importer-listener.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_IMPORTER_LISTENER_H
-#define EVOLUTION_IMPORTER_LISTENER_H
-
-#include <glib.h>
-#include <bonobo/bonobo-object.h>
-#include <importer/GNOME_Evolution_Importer.h>
-#include "evolution-importer.h"
-
-G_BEGIN_DECLS
-
-#define EVOLUTION_TYPE_IMPORTER_LISTENER (evolution_importer_listener_get_type ())
-#define EVOLUTION_IMPORTER_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_IMPORTER_LISTENER, EvolutionImporterListener))
-#define EVOLUTION_IMPORTER_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_IMPORTER_LISTENER, EvolutionImporterListenerClass))
-#define EVOLUTION_IS_IMPORTER_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_IMPORTER_LISTENER))
-#define EVOLUTION_IS_IMPORTER_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_IMPORTER_LISTENER))
-
-typedef struct _EvolutionImporterListener EvolutionImporterListener;
-typedef struct _EvolutionImporterListenerPrivate EvolutionImporterListenerPrivate;
-typedef struct _EvolutionImporterListenerClass EvolutionImporterListenerClass;
-
-typedef void (* EvolutionImporterListenerCallback) (EvolutionImporterListener *listener,
- EvolutionImporterResult result,
- gboolean more_items,
- gpointer closure);
-struct _EvolutionImporterListener {
- BonoboObject parent;
-
- EvolutionImporterListenerPrivate *priv;
-};
-
-struct _EvolutionImporterListenerClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_ImporterListener__epv epv;
-};
-
-GType evolution_importer_listener_get_type (void);
-
-EvolutionImporterListener *evolution_importer_listener_new (EvolutionImporterListenerCallback callback,
- gpointer closure);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/importer/evolution-importer.c b/shell/importer/evolution-importer.c
deleted file mode 100644
index 17e118094b..0000000000
--- a/shell/importer/evolution-importer.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-importer.h"
-
-#include <bonobo/bonobo-object.h>
-#include <e-util/e-util.h>
-
-#include "GNOME_Evolution_Importer.h"
-
-#define PARENT_TYPE BONOBO_OBJECT_TYPE
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionImporterPrivate {
- EvolutionImporterCreateControlFn create_control_fn;
- EvolutionImporterLoadFileFn load_file_fn;
- EvolutionImporterSupportFormatFn support_format_fn;
- EvolutionImporterProcessItemFn process_item_fn;
- EvolutionImporterGetErrorFn get_error_fn;
-
- gpointer closure;
-};
-
-
-static inline EvolutionImporter *
-evolution_importer_from_servant (PortableServer_Servant servant)
-{
- return EVOLUTION_IMPORTER (bonobo_object_from_servant (servant));
-}
-
-static void
-impl_GNOME_Evolution_Importer_createControl (PortableServer_Servant servant,
- Bonobo_Control *control,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->create_control_fn != NULL)
- (priv->create_control_fn) (importer, control, priv->closure);
- else
- CORBA_exception_set_system (ev, ex_CORBA_NO_IMPLEMENT, CORBA_COMPLETED_NO);
-}
-
-static CORBA_boolean
-impl_GNOME_Evolution_Importer_supportFormat (PortableServer_Servant servant,
- const CORBA_char *filename,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->support_format_fn != NULL)
- return (priv->support_format_fn) (importer, filename,
- priv->closure);
- else
- return FALSE;
-}
-
-static CORBA_boolean
-impl_GNOME_Evolution_Importer_loadFile (PortableServer_Servant servant,
- const CORBA_char *filename,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->load_file_fn != NULL)
- return (priv->load_file_fn) (importer, filename, priv->closure);
- else
- return FALSE;
-}
-
-static void
-impl_GNOME_Evolution_Importer_processItem (PortableServer_Servant servant,
- GNOME_Evolution_ImporterListener listener,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->process_item_fn != NULL)
- (priv->process_item_fn) (importer, listener, priv->closure, ev);
- else
- GNOME_Evolution_ImporterListener_notifyResult (listener,
- GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION, FALSE, ev);
-}
-
-static CORBA_char *
-impl_GNOME_Evolution_Importer_getError (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
- CORBA_char *out_str;
-
- importer = evolution_importer_from_servant (servant);
- priv = importer->priv;
-
- if (priv->get_error_fn != NULL) {
- out_str = (priv->get_error_fn) (importer, priv->closure);
- return CORBA_string_dup (out_str ? out_str : "");
- } else
- return CORBA_string_dup ("");
-}
-
-
-static void
-finalise (GObject *object)
-{
- EvolutionImporter *importer;
- EvolutionImporterPrivate *priv;
-
- importer = EVOLUTION_IMPORTER (object);
- priv = importer->priv;
-
- if (priv == NULL)
- return;
-
- g_free (priv);
- importer->priv = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-evolution_importer_class_init (EvolutionImporterClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_Importer__epv *epv = &klass->epv;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = finalise;
-
- parent_class = g_type_class_ref(PARENT_TYPE);
- epv->createControl = impl_GNOME_Evolution_Importer_createControl;
- epv->supportFormat = impl_GNOME_Evolution_Importer_supportFormat;
- epv->loadFile = impl_GNOME_Evolution_Importer_loadFile;
- epv->processItem = impl_GNOME_Evolution_Importer_processItem;
- epv->getError = impl_GNOME_Evolution_Importer_getError;
-}
-
-static void
-evolution_importer_init (EvolutionImporter *importer)
-{
- EvolutionImporterPrivate *priv;
-
- priv = g_new0 (EvolutionImporterPrivate, 1);
-
- importer->priv = priv;
-}
-
-
-
-static void
-evolution_importer_construct (EvolutionImporter *importer,
- EvolutionImporterCreateControlFn create_control_fn,
- EvolutionImporterSupportFormatFn support_format_fn,
- EvolutionImporterLoadFileFn load_file_fn,
- EvolutionImporterProcessItemFn process_item_fn,
- EvolutionImporterGetErrorFn get_error_fn,
- gpointer closure)
-{
- EvolutionImporterPrivate *priv;
-
- g_return_if_fail (importer != NULL);
- g_return_if_fail (EVOLUTION_IS_IMPORTER (importer));
- g_return_if_fail (support_format_fn != NULL);
- g_return_if_fail (load_file_fn != NULL);
- g_return_if_fail (process_item_fn != NULL);
-
- priv = importer->priv;
- priv->create_control_fn = create_control_fn;
- priv->support_format_fn = support_format_fn;
- priv->load_file_fn = load_file_fn;
- priv->process_item_fn = process_item_fn;
- priv->get_error_fn = get_error_fn;
-
- priv->closure = closure;
-}
-
-/**
- * evolution_importer_new:
- * @support_format_fn: The function to be called by the supportFormat method.
- * @load_file_fn: The function to be called by the loadFile method.
- * @process_item_fn: The function to be called by the processItem method.
- * @get_error_fn: The function to be called by the getError method.
- * @closure: The data to be passed to all of the above functions.
- *
- * Creates a new EvolutionImporter object. Of the parameters only
- * @get_error_function and @closure may be #NULL.
- *
- * Returns: A newly created EvolutionImporter object.
- */
-EvolutionImporter *
-evolution_importer_new (EvolutionImporterCreateControlFn create_control_fn,
- EvolutionImporterSupportFormatFn support_format_fn,
- EvolutionImporterLoadFileFn load_file_fn,
- EvolutionImporterProcessItemFn process_item_fn,
- EvolutionImporterGetErrorFn get_error_fn,
- gpointer closure)
-{
- EvolutionImporter *importer;
-
- importer = g_object_new(evolution_importer_get_type (), NULL);
- evolution_importer_construct (importer, create_control_fn, support_format_fn, load_file_fn,
- process_item_fn, get_error_fn, closure);
- return importer;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionImporter,
- GNOME_Evolution_Importer,
- PARENT_TYPE,
- evolution_importer);
diff --git a/shell/importer/evolution-importer.h b/shell/importer/evolution-importer.h
deleted file mode 100644
index 05eae39b43..0000000000
--- a/shell/importer/evolution-importer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_IMPORTER_H
-#define EVOLUTION_IMPORTER_H
-
-#include <glib.h>
-#include <bonobo/bonobo-object.h>
-#include <importer/GNOME_Evolution_Importer.h>
-
-G_BEGIN_DECLS
-
-#define EVOLUTION_TYPE_IMPORTER (evolution_importer_get_type ())
-#define EVOLUTION_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_IMPORTER, EvolutionImporter))
-#define EVOLUTION_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_IMPORTER, EvolutionImporterClass))
-#define EVOLUTION_IS_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_IMPORTER))
-#define EVOLUTION_IS_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_IMPORTER))
-
-typedef struct _EvolutionImporter EvolutionImporter;
-typedef struct _EvolutionImporterPrivate EvolutionImporterPrivate;
-typedef struct _EvolutionImporterClass EvolutionImporterClass;
-
-typedef void (* EvolutionImporterCreateControlFn) (EvolutionImporter *importer,
- Bonobo_Control *control,
- gpointer closure);
-
-typedef gboolean (* EvolutionImporterSupportFormatFn) (EvolutionImporter *importer,
- const gchar *filename,
- gpointer closure);
-typedef gboolean (* EvolutionImporterLoadFileFn) (EvolutionImporter *importer,
- const gchar *filename,
- gpointer closure);
-typedef void (* EvolutionImporterProcessItemFn) (EvolutionImporter *importer,
- CORBA_Object listener,
- gpointer closure,
- CORBA_Environment *ev);
-typedef gchar *(* EvolutionImporterGetErrorFn) (EvolutionImporter *importer,
- gpointer closure);
-
-typedef enum {
- EVOLUTION_IMPORTER_OK,
- EVOLUTION_IMPORTER_UNSUPPORTED_OPERATION,
- EVOLUTION_IMPORTER_INTERRUPTED,
- EVOLUTION_IMPORTER_BUSY,
- EVOLUTION_IMPORTER_NOT_READY,
- EVOLUTION_IMPORTER_UNKNOWN_DATA,
- EVOLUTION_IMPORTER_BAD_DATA,
- EVOLUTION_IMPORTER_BAD_FILE,
- EVOLUTION_IMPORTER_UNKNOWN_ERROR
-} EvolutionImporterResult;
-
-struct _EvolutionImporter {
- BonoboObject parent;
-
- EvolutionImporterPrivate *priv;
-};
-
-struct _EvolutionImporterClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Importer__epv epv;
-};
-
-GType evolution_importer_get_type (void);
-
-EvolutionImporter *evolution_importer_new (EvolutionImporterCreateControlFn create_control_fn,
- EvolutionImporterSupportFormatFn support_format_fn,
- EvolutionImporterLoadFileFn load_file_fn,
- EvolutionImporterProcessItemFn process_item_fn,
- EvolutionImporterGetErrorFn get_error_fn,
- void *closure);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/importer/evolution-intelligent-importer.c b/shell/importer/evolution-intelligent-importer.c
deleted file mode 100644
index 48c767cfde..0000000000
--- a/shell/importer/evolution-intelligent-importer.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "evolution-intelligent-importer.h"
-
-#include <bonobo/bonobo-object.h>
-
-#include "GNOME_Evolution_Importer.h"
-
-#define PARENT_TYPE BONOBO_OBJECT_TYPE
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionIntelligentImporterPrivate {
- EvolutionIntelligentImporterCanImportFn can_import_fn;
- EvolutionIntelligentImporterImportDataFn import_data_fn;
-
- gchar *importername;
- gchar *message;
- gpointer closure;
-};
-
-
-static inline EvolutionIntelligentImporter *
-evolution_intelligent_importer_from_servant (PortableServer_Servant servant)
-{
- return EVOLUTION_INTELLIGENT_IMPORTER (bonobo_object_from_servant (servant));
-}
-
-static CORBA_char *
-impl_GNOME_Evolution_IntelligentImporter__get_importername (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionIntelligentImporter *ii;
-
- ii = evolution_intelligent_importer_from_servant (servant);
-
- return CORBA_string_dup (ii->priv->importername ?
- ii->priv->importername : "");
-}
-
-static CORBA_char *
-impl_GNOME_Evolution_IntelligentImporter__get_message (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionIntelligentImporter *ii;
-
- ii = evolution_intelligent_importer_from_servant (servant);
-
- return CORBA_string_dup (ii->priv->message ?
- ii->priv->message : "");
-}
-
-static CORBA_boolean
-impl_GNOME_Evolution_IntelligentImporter_canImport (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionIntelligentImporter *ii;
- EvolutionIntelligentImporterPrivate *priv;
-
- ii = evolution_intelligent_importer_from_servant (servant);
- priv = ii->priv;
-
- if (priv->can_import_fn != NULL)
- return (priv->can_import_fn) (ii, priv->closure);
- else
- return FALSE;
-}
-
-static void
-impl_GNOME_Evolution_IntelligentImporter_importData (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EvolutionIntelligentImporter *ii;
- EvolutionIntelligentImporterPrivate *priv;
-
- ii = evolution_intelligent_importer_from_servant (servant);
- priv = ii->priv;
-
- if (priv->import_data_fn)
- (priv->import_data_fn) (ii, priv->closure);
-}
-
-
-static void
-finalise (GObject *object)
-{
- EvolutionIntelligentImporter *ii;
-
- ii = EVOLUTION_INTELLIGENT_IMPORTER (object);
-
- if (ii->priv == NULL)
- return;
-
- g_free (ii->priv->importername);
- g_free (ii->priv);
- ii->priv = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-evolution_intelligent_importer_class_init (EvolutionIntelligentImporterClass *klass)
-{
- GObjectClass *object_class;
- POA_GNOME_Evolution_IntelligentImporter__epv *epv = &klass->epv;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = finalise;
-
- parent_class = g_type_class_ref(PARENT_TYPE);
- epv->_get_importername = impl_GNOME_Evolution_IntelligentImporter__get_importername;
- epv->_get_message = impl_GNOME_Evolution_IntelligentImporter__get_message;
- epv->canImport = impl_GNOME_Evolution_IntelligentImporter_canImport;
- epv->importData = impl_GNOME_Evolution_IntelligentImporter_importData;
-}
-
-static void
-evolution_intelligent_importer_init (EvolutionIntelligentImporter *ii)
-{
- ii->priv = g_new0 (EvolutionIntelligentImporterPrivate, 1);
-}
-
-
-static void
-evolution_intelligent_importer_construct (EvolutionIntelligentImporter *ii,
- EvolutionIntelligentImporterCanImportFn can_import_fn,
- EvolutionIntelligentImporterImportDataFn import_data_fn,
- const gchar *importername,
- const gchar *message,
- gpointer closure)
-{
- g_return_if_fail (ii != NULL);
- ii->priv->importername = g_strdup (importername);
- ii->priv->message = g_strdup (message);
-
- ii->priv->can_import_fn = can_import_fn;
- ii->priv->import_data_fn = import_data_fn;
- ii->priv->closure = closure;
-}
-
-/**
- * evolution_intelligent_importer_new:
- * can_import_fn: The function that will be called to see if this importer can do
- * anything.
- * import_data_fn: The function that will be called when the importer should
- * import the data.
- * importername: The name of this importer.
- * message: The message that will be displayed when the importer can import.
- * closure: The data to be passed to @can_import_fn and @import_data_fn.
- *
- * Creates a new IntelligentImporter.
- *
- * Returns: A newly allocated EvolutionIntelligentImporter.
- */
-EvolutionIntelligentImporter *
-evolution_intelligent_importer_new (EvolutionIntelligentImporterCanImportFn can_import_fn,
- EvolutionIntelligentImporterImportDataFn import_data_fn,
- const gchar *importername,
- const gchar *message,
- gpointer closure)
-{
- EvolutionIntelligentImporter *ii;
-
- ii = g_object_new (evolution_intelligent_importer_get_type (), NULL);
- evolution_intelligent_importer_construct (ii, can_import_fn,
- import_data_fn, importername,
- message, closure);
- return ii;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionIntelligentImporter,
- GNOME_Evolution_IntelligentImporter,
- PARENT_TYPE,
- evolution_intelligent_importer);
diff --git a/shell/importer/evolution-intelligent-importer.h b/shell/importer/evolution-intelligent-importer.h
deleted file mode 100644
index d9613d3f66..0000000000
--- a/shell/importer/evolution-intelligent-importer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EVOLUTION_INTELLIGENT_IMPORTER_H
-#define EVOLUTION_INTELLIGENT_IMPORTER_H
-
-#include <glib.h>
-#include <bonobo/bonobo-object.h>
-#include <importer/GNOME_Evolution_Importer.h>
-
-G_BEGIN_DECLS
-
-#define EVOLUTION_TYPE_INTELLIGENT_IMPORTER (evolution_intelligent_importer_get_type ())
-#define EVOLUTION_INTELLIGENT_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TYPE_INTELLIGENT_IMPORTER, EvolutionIntelligentImporter))
-#define EVOLUTION_INTELLIGENT_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_INTELLIGENT_IMPORTER, EvolutionIntelligentImporterClass))
-#define EVOLUTION_IS_INTELLIGENT_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TYPE_INTELLIGENT_IMPORTER))
-#define EVOLUTION_IS_INTELLIGENT_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_INTELLIGENT_IMPORTER))
-
-typedef struct _EvolutionIntelligentImporter EvolutionIntelligentImporter;
-typedef struct _EvolutionIntelligentImporterPrivate EvolutionIntelligentImporterPrivate;
-typedef struct _EvolutionIntelligentImporterClass EvolutionIntelligentImporterClass;
-
-typedef gboolean (* EvolutionIntelligentImporterCanImportFn) (EvolutionIntelligentImporter *ii,
- gpointer closure);
-typedef void (* EvolutionIntelligentImporterImportDataFn) (EvolutionIntelligentImporter *ii,
- gpointer closure);
-
-struct _EvolutionIntelligentImporter {
- BonoboObject parent;
-
- EvolutionIntelligentImporterPrivate *priv;
-};
-
-struct _EvolutionIntelligentImporterClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_IntelligentImporter__epv epv;
-};
-
-GType evolution_intelligent_importer_get_type (void);
-
-EvolutionIntelligentImporter *evolution_intelligent_importer_new (EvolutionIntelligentImporterCanImportFn can_import_fn,
- EvolutionIntelligentImporterImportDataFn import_data_fn,
- const gchar *importername,
- const gchar *message,
- gpointer closure);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/importer/import.glade b/shell/importer/import.glade
deleted file mode 100644
index 389d2feee3..0000000000
--- a/shell/importer/import.glade
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkWindow" id="importwizard">
- <property name="title" translatable="yes">Evolution Import Assistant</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
-
- <child>
- <widget class="GnomeDruid" id="druid1">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="show_help">False</property>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="page0">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_START</property>
- <property name="title" translatable="yes">Evolution Import Assistant</property>
- <property name="text" translatable="yes">Welcome to the Evolution Import Assistant.
-With this assistant you will be guided through the process of
-importing external files into Evolution.</property>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page1">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Importer Type</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox2">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page2-file">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Select a File</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox1">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page3-file">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Import Location</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox3">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageStandard" id="page2-intelligent">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Select Information to Import</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="druid-vbox3">
- <property name="border_width">16</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GnomeDruidPageEdge" id="page4">
- <property name="visible">True</property>
- <property name="position">GNOME_EDGE_FINISH</property>
- <property name="title" translatable="yes">Import File</property>
- <property name="text" translatable="yes">Click &quot;Import&quot; to begin importing the file into Evolution. </property>
- </widget>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/shell/importer/intelligent.c b/shell/importer/intelligent.c
deleted file mode 100644
index 8b7ebaa743..0000000000
--- a/shell/importer/intelligent.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Iain Holmes <iain@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "intelligent.h"
-
-#include <gtk/gtk.h>
-
-#include <libgnome/gnome-config.h>
-#include <glib/gi18n.h>
-
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-widget.h>
-
-#include "intelligent.h"
-#include "GNOME_Evolution_Importer.h"
-
-/* Prototypes */
-
-void intelligent_importer_init (void);
-
-/* End prototypes */
-
-typedef struct {
- CORBA_Object object;
- Bonobo_Control control;
- GtkWidget *widget;
-
- gchar *name;
- gchar *blurb;
- gchar *iid;
-} IntelligentImporterData;
-
-typedef struct {
- GtkWidget *dialog;
- GtkWidget *placeholder;
- GtkWidget *clist;
- BonoboWidget *current;
-
- GList *importers;
-
- gint running;
-} IntelligentImporterDialog;
-
-typedef struct {
- CORBA_Object importer;
- gchar *iid;
-} SelectedImporterData;
-
-static void
-free_importer_dialog (IntelligentImporterDialog *d)
-{
- GList *l;
-
- for (l = d->importers; l; l = l->next) {
- CORBA_Environment ev;
- IntelligentImporterData *data;
-
- data = l->data;
-
- CORBA_exception_init (&ev);
- if (data->object != CORBA_OBJECT_NIL)
- bonobo_object_release_unref (data->object, &ev);
-
- g_free (data->iid);
- g_free (data->name);
- g_free (data->blurb);
- g_free (data);
- }
-
- g_list_free (d->importers);
- gtk_widget_destroy (d->dialog);
- g_free (d);
-}
-
-static void
-start_importers (GList *selected)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- for (; selected; selected = selected->next) {
- SelectedImporterData *selection = selected->data;
-
- GNOME_Evolution_IntelligentImporter_importData (selection->importer, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Error importing %s\n%s", selection->iid,
- CORBA_exception_id (&ev));
- }
- }
- CORBA_exception_free (&ev);
-}
-
-static GList *
-get_intelligent_importers (void)
-{
- Bonobo_ServerInfoList *info_list;
- GList *iids_ret = NULL;
- CORBA_Environment ev;
- gint i;
-
- CORBA_exception_init (&ev);
- info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/IntelligentImporter:" BASE_VERSION "')", NULL, &ev);
- CORBA_exception_free (&ev);
-
- for (i = 0; i < info_list->_length; i++) {
- const Bonobo_ServerInfo *info;
-
- info = info_list->_buffer + i;
- iids_ret = g_list_prepend (iids_ret, g_strdup (info->iid));
- }
-
- return iids_ret;
-}
-
-static void
-select_row_cb (GtkCList *clist,
- gint row,
- gint column,
- GdkEvent *ev,
- IntelligentImporterDialog *d)
-{
- gtk_notebook_set_current_page (GTK_NOTEBOOK (d->placeholder), row);
-}
-
-static void
-unselect_row_cb (GtkCList *clist,
- gint row,
- gint column,
- GdkEvent *ev,
- IntelligentImporterDialog *d)
-{
- gtk_notebook_set_current_page (GTK_NOTEBOOK (d->placeholder), d->running);
-}
-
-static IntelligentImporterDialog *
-create_gui (GList *importers)
-{
- GtkWidget *dialog, *clist, *sw, *label;
- GtkWidget *hbox, *vbox, *dummy;
- IntelligentImporterDialog *d;
- GList *l;
- gint running = 0;
-
- d = g_new (IntelligentImporterDialog, 1);
- d->dialog = dialog = gtk_dialog_new();
- gtk_dialog_set_has_separator ((GtkDialog *) dialog, FALSE);
- gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *)dialog)->vbox, 0);
- gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *)dialog)->action_area, 12);
-
- gtk_window_set_title((GtkWindow *)dialog, _("Importers"));
- dummy = gtk_button_new_from_stock(GTK_STOCK_CONVERT);
- gtk_button_set_label((GtkButton *)dummy, _("Import"));
- gtk_dialog_add_action_widget((GtkDialog *)dialog, dummy, GTK_RESPONSE_ACCEPT);
-
- dummy = gtk_button_new_from_stock(GTK_STOCK_NO);
- gtk_button_set_label((GtkButton *)dummy, _("Do not import"));
- gtk_dialog_add_action_widget((GtkDialog *)dialog, dummy, GTK_RESPONSE_REJECT);
-
- dummy = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
- gtk_button_set_label((GtkButton *)dummy, _("Do not ask me again"));
- gtk_dialog_add_action_widget((GtkDialog *)dialog, dummy, GTK_RESPONSE_CANCEL);
- d->importers = NULL;
- d->current = NULL;
-
- d->clist = clist = gtk_clist_new (1);
- gtk_clist_set_selection_mode (GTK_CLIST (d->clist), GTK_SELECTION_MULTIPLE);
-
- label = gtk_label_new (_("Evolution can import data from the following files:"));
- gtk_misc_set_alignment(GTK_MISC(label), 0, .5);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label,
- TRUE, TRUE, 0);
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
-
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
- TRUE, TRUE, 0);
-
- sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
- gtk_widget_set_size_request (sw, 300, 150);
- gtk_container_add (GTK_CONTAINER (sw), clist);
- gtk_box_pack_start (GTK_BOX (hbox), sw, TRUE, TRUE, 0);
-
- vbox = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
- gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
-
- d->placeholder = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (d->placeholder), FALSE);
- gtk_box_pack_start (GTK_BOX (vbox), d->placeholder, TRUE, TRUE, 0);
-
- for (l = importers; l; l = l->next) {
- IntelligentImporterData *data;
- CORBA_Environment ev;
- gboolean dontaskagain, can_run;
- gchar *text[1], *prefix;
-
- /* Check if we want to show this one again */
- prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", g_get_home_dir ());
- gnome_config_push_prefix (prefix);
- g_free (prefix);
-
- dontaskagain = gnome_config_get_bool (l->data);
- gnome_config_pop_prefix ();
-
- if (dontaskagain)
- continue;
-
- data = g_new0 (IntelligentImporterData, 1);
- data->iid = g_strdup (l->data);
-
- CORBA_exception_init (&ev);
- data->object = bonobo_activation_activate_from_id ((gchar *) data->iid, 0,
- NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not start %s: %s", data->iid,
- CORBA_exception_id (&ev));
- CORBA_exception_free (&ev);
-
- /* Clean up the IntelligentImporterData */
- g_free (data->iid);
- g_free (data);
- continue;
- }
-
- CORBA_exception_free (&ev);
- if (data->object == CORBA_OBJECT_NIL) {
- g_warning ("Could not activate_component %s", data->iid);
- g_free (data->iid);
- g_free (data);
- continue;
- }
-
- CORBA_exception_init (&ev);
- can_run = GNOME_Evolution_IntelligentImporter_canImport (data->object,
- &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not get canImport(%s): %s",
- data->iid, CORBA_exception_id (&ev));
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data);
- continue;
- }
- CORBA_exception_free (&ev);
-
- if (can_run == FALSE) {
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data);
- continue;
- }
-
- running++;
-
- data->name = g_strdup (GNOME_Evolution_IntelligentImporter__get_importername (data->object, &ev));
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not get name(%s): %s",
- data->iid, CORBA_exception_id (&ev));
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data);
- continue;
- }
-
- data->blurb = g_strdup (GNOME_Evolution_IntelligentImporter__get_message (data->object, &ev));
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not get message(%s): %s",
- data->iid, CORBA_exception_id (&ev));
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data->name);
- g_free (data);
- continue;
- }
-
- data->control = Bonobo_Unknown_queryInterface (data->object,
- "IDL:Bonobo/Control:1.0", &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Could not QI for Bonobo/Control:1.0 %s:%s",
- data->iid, CORBA_exception_id (&ev));
- bonobo_object_release_unref (data->object, &ev);
- CORBA_exception_free (&ev);
- g_free (data->iid);
- g_free (data->name);
- g_free (data->blurb);
- continue;
- }
- if (data->control != CORBA_OBJECT_NIL) {
- data->widget = bonobo_widget_new_control_from_objref (data->control, CORBA_OBJECT_NIL);
- /* Ref this widget so even if we remove it from the
- containers it will always have an extra ref. */
- gtk_widget_show (data->widget);
- g_object_ref (data->widget);
- } else {
- data->widget = gtk_label_new ("");
- }
-
- CORBA_exception_free (&ev);
-
- d->importers = g_list_prepend (d->importers, data);
- gtk_notebook_prepend_page (GTK_NOTEBOOK (d->placeholder),
- data->widget, NULL);
- text[0] = data->name;
- gtk_clist_prepend (GTK_CLIST (clist), text);
- }
-
- d->running = running;
- dummy = gtk_drawing_area_new ();
- gtk_widget_show (dummy);
- gtk_notebook_append_page (GTK_NOTEBOOK (d->placeholder),
- dummy, NULL);
- /* Set the start to the blank page */
- gtk_notebook_set_current_page (GTK_NOTEBOOK (d->placeholder), running);
-
- g_signal_connect((clist), "select-row",
- G_CALLBACK (select_row_cb), d);
- g_signal_connect((clist), "unselect-row",
- G_CALLBACK (unselect_row_cb), d);
-
- gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
- return d;
-}
-
-void
-intelligent_importer_init (void)
-{
- GList *importers, *l, *selected = NULL;
- IntelligentImporterDialog *d;
- gchar *prefix;
- gboolean dontaskagain;
- gint resp;
-
- prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", g_get_home_dir());
- gnome_config_push_prefix (prefix);
- g_free (prefix);
-
- dontaskagain = gnome_config_get_bool ("Dontaskagain=False");
- gnome_config_pop_prefix ();
-
- if (dontaskagain) {
- return;
- }
-
- importers = get_intelligent_importers ();
- if (importers == NULL)
- return; /* No intelligent importers. Easy :) */
-
- d = create_gui (importers);
- if (d->running == 0) {
- free_importer_dialog (d);
- return; /* No runnable intelligent importers. */
- }
-
- resp = gtk_dialog_run((GtkDialog *)d->dialog);
- gtk_widget_destroy(d->dialog);
- switch (resp) {
- case GTK_RESPONSE_ACCEPT:
- /* Make a list of the importers */
-
- /* FIXME: Sort this list and don't do it a slow way */
- for (l = GTK_CLIST (d->clist)->selection; l; l = l->next) {
- IntelligentImporterData *data;
- SelectedImporterData *new_data;
- CORBA_Environment ev;
- gchar *iid;
-
- data = g_list_nth_data (d->importers, GPOINTER_TO_INT (l->data));
- iid = g_strdup (data->iid);
-
- new_data = g_new (SelectedImporterData, 1);
- new_data->iid = iid;
-
- /* Reference the remote object, and duplicate the
- local one. */
- CORBA_exception_init (&ev);
- new_data->importer = bonobo_object_dup_ref (data->object, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Error duplicating %s\n%s", iid,
- CORBA_exception_id (&ev));
- g_free (iid);
- CORBA_exception_free (&ev);
- g_free (new_data);
- continue;
- }
- CORBA_exception_free (&ev);
-
- selected = g_list_prepend (selected, new_data);
- }
-
- /* Now destroy all the importers, as we've kept references to
- the ones we need */
- free_importer_dialog (d);
-
- if (selected != NULL) {
- /* Restart the selected ones */
- start_importers (selected);
-
- /* Free the selected list */
- for (l = selected; l; l = l->next) {
- CORBA_Environment ev;
- SelectedImporterData *selection = l->data;
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (selection->importer, &ev);
- CORBA_exception_free (&ev);
-
- g_free (selection->iid);
- g_free (selection);
- }
- g_list_free (selected);
- }
-
- break;
-
- case GTK_RESPONSE_CANCEL: /* Dont ask again */
- prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", g_get_home_dir());
- gnome_config_push_prefix (prefix);
- g_free (prefix);
-
- gnome_config_set_bool ("Dontaskagain", TRUE);
- gnome_config_pop_prefix ();
-
- gnome_config_sync ();
- gnome_config_drop_all ();
- g_print ("Not asking again");
- free_importer_dialog (d);
- break;
-
- default:
- case GTK_RESPONSE_REJECT: /* No button */
- free_importer_dialog (d);
- break;
- }
-
- g_list_free (importers);
-}
diff --git a/shell/main.c b/shell/main.c
index 21cc278c7f..72333c17f7 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -23,6 +23,7 @@
#include <config.h>
#include <gtk/gtk.h>
+#include <gdk/gdkx.h> /* for copied UniqueApp code */
#include <glib/gstdio.h>
#ifdef G_OS_WIN32
@@ -40,12 +41,10 @@
#include "e-util/e-bconf-map.h"
#include <e-util/e-icon-factory.h>
-#include "e-shell-constants.h"
#include "e-util/e-profile-event.h"
#include "e-util/e-util.h"
#include "e-shell.h"
-#include "es-menu.h"
#include "es-event.h"
#include "e-util/e-util-private.h"
@@ -57,22 +56,13 @@
#include <gconf/gconf-client.h>
#include <glib/gi18n.h>
-#include <libgnome/gnome-sound.h>
-#include <libgnomeui/gnome-ui-init.h>
-#include <libgnomeui/gnome-client.h>
-
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <bonobo/bonobo-exception.h>
-
-#include <bonobo-activation/bonobo-activation.h>
+#include <libedataserver/e-categories.h>
#include <libedataserverui/e-passwords.h>
#include <glade/glade.h>
#include "e-config-upgrade.h"
-#include "Evolution-DataServer.h"
#include <misc/e-cursors.h>
#include "e-util/e-error.h"
@@ -98,13 +88,11 @@
#define DEVELOPMENT 1
#endif
-static EShell *shell = NULL;
-
/* Command-line options. */
static gboolean start_online = FALSE;
static gboolean start_offline = FALSE;
static gboolean setup_only = FALSE;
-static gboolean killev = FALSE;
+static gboolean force_shutdown = FALSE;
#ifdef DEVELOPMENT
static gboolean force_migrate = FALSE;
#endif
@@ -112,84 +100,43 @@ static gboolean disable_eplugin = FALSE;
static gboolean disable_preview = FALSE;
static gboolean idle_cb (gchar **uris);
-static gchar *default_component_id = NULL;
+static gchar *requested_view = NULL;
static gchar *evolution_debug_log = NULL;
static gchar **remaining_args;
-static void
-no_windows_left_cb (EShell *shell, gpointer data)
-{
- bonobo_object_unref (BONOBO_OBJECT (shell));
- bonobo_main_quit ();
-}
-
-static void
-shell_weak_notify (gpointer data,
- GObject *where_the_object_was)
-{
- bonobo_main_quit ();
-}
-
-#ifdef KILL_PROCESS_CMD
+/* Defined in <e-shell.h> */
+extern EShell *default_shell;
static void
-kill_dataserver (void)
+categories_icon_theme_hack (void)
{
- g_message ("Killing old version of evolution-data-server...");
-
- system (KILL_PROCESS_CMD " -9 lt-evolution-data-server 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.0 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.2 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.4 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.6 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.8 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.10 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-data-server-1.12 2> /dev/null");
-
- system (KILL_PROCESS_CMD " -9 lt-evolution-alarm-notify 2> /dev/null");
- system (KILL_PROCESS_CMD " -9 evolution-alarm-notify 2> /dev/null");
+ GtkIconTheme *icon_theme;
+ const gchar *category_name;
+ const gchar *filename;
+ gchar *dirname;
+
+ /* XXX Allow the category icons to be referenced as named
+ * icons, since GtkAction does not support GdkPixbufs. */
+
+ /* Get the icon file for some default category. Doesn't matter
+ * which, so long as it has an icon. We're just interested in
+ * the directory components. */
+ category_name = _("Birthday");
+ filename = e_categories_get_icon_file_for (category_name);
+ g_return_if_fail (filename != NULL && *filename != '\0');
+
+ /* Extract the directory components. */
+ dirname = g_path_get_dirname (filename);
+
+ /* Add it to the icon theme's search path. This relies on
+ * GtkIconTheme's legacy feature of using image files found
+ * directly in the search path. */
+ icon_theme = gtk_icon_theme_get_default ();
+ gtk_icon_theme_append_search_path (icon_theme, dirname);
+
+ g_free (dirname);
}
-static void
-kill_old_dataserver (void)
-{
- GNOME_Evolution_DataServer_InterfaceCheck iface;
- CORBA_Environment ev;
- CORBA_char *version;
-
- CORBA_exception_init (&ev);
-
- /* FIXME Should we really kill it off? We also shouldn't hard code the version */
- iface = bonobo_activation_activate_from_id (
- (Bonobo_ActivationID) "OAFIID:GNOME_Evolution_DataServer_InterfaceCheck", 0, NULL, &ev);
- if (BONOBO_EX (&ev) || iface == CORBA_OBJECT_NIL) {
- kill_dataserver ();
- CORBA_exception_free (&ev);
- return;
- }
-
- version = GNOME_Evolution_DataServer_InterfaceCheck__get_interfaceVersion (iface, &ev);
- if (BONOBO_EX (&ev)) {
- kill_dataserver ();
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
- return;
- }
-
- if (strcmp (version, DATASERVER_VERSION) != 0) {
- CORBA_free (version);
- kill_dataserver ();
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_free (version);
- CORBA_Object_release (iface, &ev);
- CORBA_exception_free (&ev);
-}
-#endif
-
#ifdef DEVELOPMENT
/* Warning dialog to scare people off a little bit. */
@@ -269,8 +216,6 @@ show_development_warning(void)
gtk_widget_destroy (warning_dialog);
- idle_cb (NULL);
-
return skip;
}
@@ -291,124 +236,26 @@ destroy_config (GConfClient *client)
#endif /* DEVELOPMENT */
-static void
-open_uris (GNOME_Evolution_Shell corba_shell, gchar **uris)
-{
- CORBA_Environment ev;
- guint n_uris, ii;
-
- g_return_if_fail (uris != NULL);
- n_uris = g_strv_length (uris);
-
- CORBA_exception_init (&ev);
-
- for (ii = 0; ii < n_uris; ii++) {
- GNOME_Evolution_Shell_handleURI (corba_shell, uris[ii], &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Invalid URI: %s", uris[ii]);
- CORBA_exception_free (&ev);
- }
- }
-
- CORBA_exception_free (&ev);
-}
-
/* This is for doing stuff that requires the GTK+ loop to be running already. */
static gboolean
idle_cb (gchar **uris)
{
- GNOME_Evolution_Shell corba_shell;
- CORBA_Environment ev;
- EShellConstructResult result;
- EShellStartupLineMode startup_line_mode;
-
- g_return_val_if_fail (uris == NULL || g_strv_length (uris) > 0, FALSE);
-
-#ifdef KILL_PROCESS_CMD
- kill_old_dataserver ();
-#endif
+ EShell *shell;
- CORBA_exception_init (&ev);
-
- if (! start_online && ! start_offline)
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_CONFIG;
- else if (start_online)
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_ONLINE;
- else
- startup_line_mode = E_SHELL_STARTUP_LINE_MODE_OFFLINE;
-
- shell = e_shell_new (startup_line_mode, &result);
-
- switch (result) {
- case E_SHELL_CONSTRUCT_RESULT_OK:
- e_shell_set_crash_recovery (shell, e_file_lock_exists ());
- g_signal_connect (shell, "no_windows_left", G_CALLBACK (no_windows_left_cb), NULL);
- g_object_weak_ref (G_OBJECT (shell), shell_weak_notify, NULL);
- corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell));
- corba_shell = CORBA_Object_duplicate (corba_shell, &ev);
- break;
-
- case E_SHELL_CONSTRUCT_RESULT_CANNOTREGISTER:
- corba_shell = bonobo_activation_activate_from_id (
- (Bonobo_ActivationID) E_SHELL_OAFIID, 0, NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION || corba_shell == CORBA_OBJECT_NIL) {
- e_error_run(NULL, "shell:noshell", NULL);
- CORBA_exception_free (&ev);
- bonobo_main_quit ();
- return FALSE;
- }
- break;
+ shell = e_shell_get_default ();
- default:
- e_error_run(NULL, "shell:noshell-reason",
- e_shell_construct_result_to_string(result), NULL);
- CORBA_exception_free (&ev);
- bonobo_main_quit ();
- return FALSE;
+ /* These calls do the right thing when another Evolution
+ * process is running. */
+ if (uris != NULL && *uris != NULL) {
+ if (e_shell_handle_uris (shell, uris) == 0)
+ gtk_main_quit ();
+ } else
+ e_shell_create_shell_window (shell, requested_view);
- }
-
- if (shell != NULL) {
- if (uris != NULL)
- open_uris (corba_shell, uris);
- else {
- e_file_lock_create ();
- e_shell_create_window (shell, default_component_id, NULL);
- }
- } else {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- if (uris != NULL)
- open_uris (corba_shell, uris);
- else
- if (default_component_id == NULL)
- GNOME_Evolution_Shell_createNewWindow (corba_shell, "", &ev);
- else
- GNOME_Evolution_Shell_createNewWindow (corba_shell, default_component_id, &ev);
-
- CORBA_exception_free (&ev);
- }
-
- CORBA_Object_release (corba_shell, &ev);
-
- CORBA_exception_free (&ev);
-
- if (shell == NULL) {
- /*there is another instance but because we don't open any windows
- we must notify the startup was complete manually*/
- gdk_notify_startup_complete ();
- bonobo_main_quit ();
- }
-
- /* This must be done after Bonobo has created all the components. For
- * example the mail component makes the global variable `session` which
- * is being used by several EPlugins */
-
- if (!disable_eplugin) {
- e_plugin_load_plugins_with_missing_symbols ();
- }
+ /* If another Evolution process is running, we're done. */
+ if (unique_app_is_running (UNIQUE_APP (shell)))
+ gtk_main_quit ();
return FALSE;
}
@@ -470,27 +317,15 @@ setup_segv_redirect (void)
#define setup_segv_redirect() (void)0
#endif
-static gint
-gnome_master_client_save_yourself_cb (GnomeClient *client, GnomeSaveStyle save_style, gint shutdown, GnomeInteractStyle interact_style, gint fast, gpointer user_data)
-{
- return !shell || e_shell_can_quit (shell);
-}
-
-static void
-gnome_master_client_die_cb (GnomeClient *client)
-{
- e_shell_do_quit (shell);
-}
-
-static const GOptionEntry options[] = {
- { "component", 'c', 0, G_OPTION_ARG_STRING, &default_component_id,
+static GOptionEntry entries[] = {
+ { "component", 'c', 0, G_OPTION_ARG_STRING, &requested_view,
N_("Start Evolution activating the specified component"), NULL },
{ "offline", '\0', 0, G_OPTION_ARG_NONE, &start_offline,
N_("Start in offline mode"), NULL },
{ "online", '\0', 0, G_OPTION_ARG_NONE, &start_online,
N_("Start in online mode"), NULL },
#ifdef KILL_PROCESS_CMD
- { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &killev,
+ { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &force_shutdown,
N_("Forcibly shut down all Evolution components"), NULL },
#endif
#ifdef DEVELOPMENT
@@ -514,8 +349,7 @@ static void
set_paths (void)
{
/* Set PATH to include the Evolution executable's folder
- * and the lib/evolution/$(BASE_VERSION)/components folder.
- */
+ * and the lib/evolution/$(BASE_VERSION)/components folder. */
wchar_t exe_filename[MAX_PATH];
wchar_t *p;
gchar *exe_folder_utf8;
@@ -536,60 +370,99 @@ set_paths (void)
*p = L'\0';
top_folder_utf8 = g_utf16_to_utf8 (exe_filename, -1, NULL, NULL, NULL);
- components_folder_utf8 =
- g_strconcat (top_folder_utf8,
- "/lib/evolution/" BASE_VERSION "/components",
- NULL);
-
- path = g_build_path (";",
- exe_folder_utf8,
- components_folder_utf8,
- g_getenv ("PATH"),
- NULL);
+ components_folder_utf8 = g_strconcat (
+ top_folder_utf8, "/lib/evolution/"
+ BASE_VERSION "/components", NULL);
+
+ path = g_build_path (
+ ";", exe_folder_utf8,
+ components_folder_utf8, g_getenv ("PATH"), NULL);
if (!g_setenv ("PATH", path, TRUE))
- g_warning ("Could not set PATH for Evolution and its child processes");
+ g_warning ("Could not set PATH for Evolution "
+ "and its child processes");
g_free (path);
g_free (exe_folder_utf8);
g_free (components_folder_utf8);
- /* Set BONOBO_ACTIVATION_PATH */
- if (g_getenv ("BONOBO_ACTIVATION_PATH" ) == NULL) {
- path = g_build_filename (top_folder_utf8,
- "lib/bonobo/servers",
- NULL);
- if (!g_setenv ("BONOBO_ACTIVATION_PATH", path, TRUE))
- g_warning ("Could not set BONOBO_ACTIVATION_PATH");
- g_free (path);
- }
g_free (top_folder_utf8);
}
#endif
+static void
+shell_window_destroyed_cb (EShell *shell)
+{
+ if (e_shell_get_watched_windows (shell) == NULL)
+ gtk_main_quit ();
+}
+
+static void
+create_default_shell (void)
+{
+ EShell *shell;
+ GConfClient *client;
+ gboolean online = TRUE;
+ GError *error = NULL;
+
+ client = gconf_client_get_default ();
+
+ if (start_online)
+ online = TRUE;
+ else if (start_offline)
+ online = FALSE;
+ else {
+ const gchar *key;
+ gboolean value;
+
+ key = "/apps/evolution/shell/start_offline";
+ value = gconf_client_get_bool (client, key, &error);
+ if (error == NULL)
+ online = !value;
+ else {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+ }
+
+ shell = g_object_new (
+ E_TYPE_SHELL,
+ "name", "org.gnome.evolution",
+ "online", online,
+ NULL);
+
+ g_signal_connect (
+ shell, "window-destroyed",
+ G_CALLBACK (shell_window_destroyed_cb), NULL);
+
+ g_object_unref (client);
+
+ /* EShell keeps its own reference to the first instance for use
+ * in e_shell_get_default(), so it's safe to unreference here. */
+ g_object_unref (shell);
+
+ g_idle_add ((GSourceFunc) idle_cb, remaining_args);
+}
+
gint
main (gint argc, gchar **argv)
{
#ifdef G_OS_WIN32
- if (fileno (stdout) != -1 &&
- _get_osfhandle (fileno (stdout)) != -1)
- {
- /* stdout is fine, presumably redirected to a file or pipe */
- }
- else
- {
- typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
+ if (fileno (stdout) != -1 && _get_osfhandle (fileno (stdout)) != -1) {
+ /* stdout is fine, presumably redirected to a file or pipe */
+ } else {
+ typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
- AttachConsole_t p_AttachConsole =
- (AttachConsole_t) GetProcAddress (GetModuleHandle ("kernel32.dll"), "AttachConsole");
+ AttachConsole_t p_AttachConsole =
+ (AttachConsole_t) GetProcAddress (
+ GetModuleHandle ("kernel32.dll"), "AttachConsole");
- if (p_AttachConsole != NULL && p_AttachConsole (ATTACH_PARENT_PROCESS))
+ if (p_AttachConsole != NULL && p_AttachConsole (ATTACH_PARENT_PROCESS))
{
- freopen ("CONOUT$", "w", stdout);
- dup2 (fileno (stdout), 1);
- freopen ("CONOUT$", "w", stderr);
- dup2 (fileno (stderr), 2);
-
- }
+ freopen ("CONOUT$", "w", stdout);
+ dup2 (fileno (stdout), 1);
+ freopen ("CONOUT$", "w", stderr);
+ dup2 (fileno (stderr), 2);
+ }
}
extern void link_shutdown (void);
@@ -599,10 +472,8 @@ main (gint argc, gchar **argv)
#ifdef DEVELOPMENT
gboolean skip_warning_dialog;
#endif
- GnomeProgram *program;
- GnomeClient *master_client;
- GOptionContext *context;
gchar *filename;
+ GError *error = NULL;
/* Make ElectricFence work. */
free (malloc (10));
@@ -611,21 +482,19 @@ main (gint argc, gchar **argv)
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
- context = g_option_context_new (_("- The Evolution PIM and Email Client"));
-
- g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
-
- g_option_context_set_translation_domain(context, GETTEXT_PACKAGE);
-
#ifdef G_OS_WIN32
set_paths ();
#endif
- program = gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv,
- GNOME_PROGRAM_STANDARD_PROPERTIES,
- GNOME_PARAM_GOPTION_CONTEXT, context,
- GNOME_PARAM_HUMAN_READABLE_NAME, _("Evolution"),
- NULL);
+ gtk_init_with_args (
+ &argc, &argv,
+ _("- The Evolution PIM and Email Client"),
+ entries, (gchar *) GETTEXT_PACKAGE, &error);
+ if (error != NULL) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ exit (1);
+ }
#ifdef G_OS_WIN32
if (strcmp (gettext (""), "") == 0) {
@@ -639,15 +508,14 @@ main (gint argc, gchar **argv)
}
#endif
if (start_online && start_offline) {
- fprintf (stderr, _("%s: --online and --offline cannot be used together.\n Use %s --help for more information.\n"),
+ g_printerr (_("%s: --online and --offline cannot be used together.\n Use %s --help for more information.\n"),
argv[0], argv[0]);
exit (1);
}
- if (killev) {
- filename = g_build_filename (EVOLUTION_TOOLSDIR,
- "killev",
- NULL);
+ if (force_shutdown) {
+ filename = g_build_filename (
+ EVOLUTION_TOOLSDIR, "killev", NULL);
execl (filename, "killev", NULL);
/* Not reached */
exit (0);
@@ -656,11 +524,10 @@ main (gint argc, gchar **argv)
client = gconf_client_get_default ();
#ifdef DEVELOPMENT
-
- if (force_migrate) {
+ if (force_migrate)
destroy_config (client);
- }
#endif
+
if (disable_preview) {
gconf_client_set_bool (client, "/apps/evolution/mail/display/show_preview", FALSE, NULL);
gconf_client_set_bool (client, "/apps/evolution/mail/display/safe_list", TRUE, NULL);
@@ -682,37 +549,19 @@ main (gint argc, gchar **argv)
g_warning ("Could not set up debugging output file.");
}
- master_client = gnome_master_client ();
-
- g_signal_connect (G_OBJECT (master_client), "save_yourself", G_CALLBACK (gnome_master_client_save_yourself_cb), NULL);
- g_signal_connect (G_OBJECT (master_client), "die", G_CALLBACK (gnome_master_client_die_cb), NULL);
-
glade_init ();
e_cursors_init ();
e_icon_factory_init ();
- e_passwords_init();
+ e_passwords_init ();
gtk_window_set_default_icon_name ("evolution");
if (setup_only)
exit (0);
- gnome_sound_init ("localhost");
+ categories_icon_theme_hack ();
gtk_accel_map_load (e_get_accels_filename ());
- if (!disable_eplugin) {
- e_plugin_register_type(e_plugin_lib_get_type());
- e_plugin_hook_register_type(es_menu_hook_get_type());
- e_plugin_hook_register_type(es_event_hook_get_type());
-#ifdef ENABLE_PROFILING
- e_plugin_hook_register_type(e_profile_event_hook_get_type());
-#endif
- e_plugin_hook_register_type(e_plugin_type_hook_get_type());
- e_plugin_hook_register_type(e_import_hook_get_type());
- e_plugin_hook_register_type(E_TYPE_PLUGIN_UI_HOOK);
- e_plugin_load_plugins ();
- }
-
#ifdef DEVELOPMENT
skip_warning_dialog = gconf_client_get_bool (
client, SKIP_WARNING_DIALOG_KEY, NULL);
@@ -721,24 +570,41 @@ main (gint argc, gchar **argv)
gconf_client_set_bool (
client, SKIP_WARNING_DIALOG_KEY,
show_development_warning (), NULL);
- else
- g_idle_add ((GSourceFunc) idle_cb, remaining_args);
-
-#else
- g_idle_add ((GSourceFunc) idle_cb, remaining_args);
#endif
+
g_object_unref (client);
- bonobo_main ();
+ create_default_shell ();
+
+ if (!disable_eplugin) {
+ /* Register built-in plugin hook types. */
+ es_event_hook_get_type ();
+#ifdef ENABLE_PROFILING
+ e_profile_event_hook_get_type ();
+#endif
+ e_import_hook_get_type ();
+ e_plugin_ui_hook_get_type ();
+
+ /* All EPlugin and EPluginHook subclasses should be
+ * registered in GType now, so load plugins now. */
+ e_plugin_load_plugins ();
+ }
+
+ gtk_main ();
+
+ /* Drop what should be the last reference to the shell.
+ * Emit a warning if references are leaking somewhere. */
+ g_object_unref (default_shell);
+ if (E_IS_SHELL (default_shell))
+ g_warning ("Shell not finalized on exit");
gtk_accel_map_save (e_get_accels_filename ());
e_icon_factory_shutdown ();
- g_object_unref (program);
- gnome_sound_shutdown ();
e_cursors_shutdown ();
#ifdef G_OS_WIN32
link_shutdown ();
#endif
+
return 0;
}
diff --git a/shell/shell.error.xml b/shell/shell.error.xml
index 7ae57dec58..603d5ed955 100644
--- a/shell/shell.error.xml
+++ b/shell/shell.error.xml
@@ -16,9 +16,8 @@ You will need to make more space available in your home directory before you can
</error>
<error id="upgrade-failed" type="error">
- <_primary>Upgrade from previous version failed:
-{0}</_primary>
- <_secondary xml:space="preserve">{1}
+ <_primary>Upgrade from previous version failed:</_primary>
+ <_secondary xml:space="preserve">{0}
If you choose to continue, you may not have access to some of your old data.
</_secondary>
@@ -51,28 +50,6 @@ Once deleted, you cannot downgrade to the previous version of Evolution without
<button stock="gtk-delete" response="GTK_RESPONSE_OK"/>
</error>
- <error id="noshell" type="error">
- <_title>Cannot start Evolution</_title>
- <_primary>Evolution can not start.</_primary>
- <_secondary xml:space="preserve">Your system configuration does not match your Evolution configuration.
-
-Click help for details</_secondary>
- <help uri="http://go-evolution.org/FAQ#What_does_.22Your_system_configuration_does_not_match_your_Evolution_configuration.22_mean.3F"/>
- <button stock="gtk-quit" response="GTK_RESPONSE_CANCEL"/>
- </error>
-
- <error id="noshell-reason" type="error">
- <_title>Cannot start Evolution</_title>
- <_primary>Evolution can not start.</_primary>
- <_secondary xml:space="preserve">Your system configuration does not match your Evolution configuration:
-
-{0}
-
-Click help for details.</_secondary>
- <help uri="http://go-evolution.org/FAQ#What_does_.22Your_system_configuration_does_not_match_your_Evolution_configuration.22_mean.3F"/>
- <button stock="gtk-quit" response="GTK_RESPONSE_CANCEL"/>
- </error>
-
<error id="forget-passwords" type="question" default="GTK_RESPONSE_CANCEL">
<_primary>Are you sure you want to forget all remembered passwords?</_primary>
<_secondary xml:space="preserve">Forgetting your passwords will clear all remembered passwords. You will be reprompted next time they are needed.</_secondary>
diff --git a/shell/test/GNOME_Evolution_Test.server.in.in b/shell/test/GNOME_Evolution_Test.server.in.in
deleted file mode 100644
index ef0db8b1ac..0000000000
--- a/shell/test/GNOME_Evolution_Test.server.in.in
+++ /dev/null
@@ -1,39 +0,0 @@
-<oaf_info>
-
- <!-- (factory) -->
- <oaf_server iid="OAFIID:GNOME_Evolution_Test_Factory:@VERSION@"
- type="shlib"
- location="@COMPONENTDIR_IN_SERVER_FILE@/libevolution-test@SOEXT@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Test"/>
- </oaf_server>
-
- <!-- Component Interface -->
-
- <oaf_server iid="OAFIID:GNOME_Evolution_Test_Component:@VERSION@"
- type="factory"
- location="OAFIID:GNOME_Evolution_Test_Factory:@VERSION@">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Component:@VERSION@"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string" _value="Evolution Test component"/>
-
- <oaf_attribute name="evolution:component_alias" type="string" value="test"/>
-
- <oaf_attribute name="evolution:button_label" type="string" _value="Test"/>
- <oaf_attribute name="evolution:button_sort_order" type="string" value="-1"/>
- <oaf_attribute name="evolution:button_icon" type="string" value="stock_mail"/>
-
- <oaf_attribute name="evolution:component_icon" type="string" value="stock_mail"/>
- <oaf_attribute name="evolution:component_display_order" type="number" value="1"/>
-
- </oaf_server>
-
-</oaf_info>
diff --git a/shell/test/Makefile.am b/shell/test/Makefile.am
index 8a2efd8a4a..10b1bfb81b 100644
--- a/shell/test/Makefile.am
+++ b/shell/test/Makefile.am
@@ -1,37 +1,27 @@
-component_LTLIBRARIES = libevolution-test.la
+module_LTLIBRARIES = libevolution-module-test.la
AM_CPPFLAGS = \
+ -I$(top_srcdir) \
-I$(top_srcdir)/shell \
+ -I$(top_srcdir)/widgets \
+ -I$(top_srcdir)/widgets/menus \
-I$(top_srcdir)/widgets/misc \
-I$(top_builddir)/shell \
-DG_LOG_DOMAIN=\"evolution-test\" \
$(EVOLUTION_TEST_CFLAGS)
-libevolution_test_la_SOURCES = \
- evolution-test-component.c \
- evolution-test-component.h
+libevolution_module_test_la_SOURCES = \
+ evolution-module-test.c \
+ e-test-shell-backend.c \
+ e-test-shell-backend.h \
+ e-test-shell-view.c \
+ e-test-shell-view.h
-libevolution_test_la_LIBADD = \
+libevolution_module_test_la_LIBADD = \
$(top_builddir)/shell/libeshell.la \
$(EVOLUTION_TEST_LIBS)
-libevolution_test_la_LDFLAGS = \
+libevolution_module_test_la_LDFLAGS = \
-avoid-version -module $(NO_UNDEFINED)
-testserver_in_files = GNOME_Evolution_Test.server.in.in
-testserver_DATA = $(testserver_in_files:.server.in.in=.server)
-testserverdir = $(serverdir)
-@EVO_SERVER_RULE@
-@INTLTOOL_SERVER_RULE@
-
-BUILT_SOURCES = $(testserver_DATA)
-CLEANFILES = $(BUILT_SOURCES)
-
-EXTRA_DIST = \
- $(testserver_in_files) \
- GNOME_Evolution_Test.server.in.in
-
-dist-hook:
- cd $(distdir); rm -f $(BUILD_SOURCES)
-
-include $(top_srcdir)/git.mk
diff --git a/shell/test/e-test-shell-backend.c b/shell/test/e-test-shell-backend.c
new file mode 100644
index 0000000000..6a6c03bddd
--- /dev/null
+++ b/shell/test/e-test-shell-backend.c
@@ -0,0 +1,222 @@
+/*
+ * e-test-shell-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-test-shell-backend.h"
+
+#include <glib/gi18n.h>
+
+#include "shell/e-shell.h"
+#include "shell/e-shell-window.h"
+
+#include "e-test-shell-view.h"
+
+#define E_TEST_SHELL_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TEST_SHELL_BACKEND, ETestShellBackendPrivate))
+
+struct _ETestShellBackendPrivate {
+ gint placeholder;
+};
+
+static gpointer parent_class;
+static GType test_shell_backend_type;
+
+static void
+action_test_item_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ g_debug ("%s", G_STRFUNC);
+}
+
+static void
+action_test_source_new_cb (GtkAction *action,
+ EShellWindow *shell_window)
+{
+ g_debug ("%s", G_STRFUNC);
+}
+
+static GtkActionEntry item_entries[] = {
+
+ { "test-item-new",
+ "document-new",
+ NC_("New", "_Test Item"),
+ NULL,
+ N_("Create a new test item"),
+ G_CALLBACK (action_test_item_new_cb) }
+};
+
+static GtkActionEntry source_entries[] = {
+
+ { "test-source-new",
+ "folder-new",
+ NC_("New", "Test _Source"),
+ NULL,
+ N_("Create a new test source"),
+ G_CALLBACK (action_test_source_new_cb) }
+};
+
+static void
+test_shell_backend_start (EShellBackend *shell_backend)
+{
+ g_debug ("%s", G_STRFUNC);
+}
+
+static gboolean
+test_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ g_debug ("%s (from %d.%d.%d)", G_STRFUNC, major, minor, micro);
+
+ return TRUE;
+}
+
+static gboolean
+test_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
+ const gchar *uri)
+{
+ g_debug ("%s (uri=%s)", G_STRFUNC, uri);
+
+ return FALSE;
+}
+
+static void
+test_shell_backend_send_receive_cb (EShellBackend *shell_backend,
+ GtkWindow *parent_window)
+{
+ g_debug ("%s (window=%p)", G_STRFUNC, parent_window);
+}
+
+static void
+test_shell_backend_window_created_cb (EShellBackend *shell_backend,
+ GtkWindow *window)
+{
+ const gchar *backend_name;
+
+ g_debug ("%s (%s)", G_STRFUNC, G_OBJECT_TYPE_NAME (window));
+
+ if (!E_IS_SHELL_WINDOW (window))
+ return;
+
+ backend_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+
+ e_shell_window_register_new_item_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ item_entries, G_N_ELEMENTS (item_entries));
+
+ e_shell_window_register_new_source_actions (
+ E_SHELL_WINDOW (window), backend_name,
+ source_entries, G_N_ELEMENTS (source_entries));
+}
+
+static void
+test_shell_backend_window_destroyed_cb (EShellBackend *shell_backend)
+{
+ g_debug ("%s", G_STRFUNC);
+}
+
+static void
+test_shell_backend_constructed (GObject *object)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell_backend = E_SHELL_BACKEND (object);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "handle-uri",
+ G_CALLBACK (test_shell_backend_handle_uri_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "send-receive",
+ G_CALLBACK (test_shell_backend_send_receive_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "window-created",
+ G_CALLBACK (test_shell_backend_window_created_cb),
+ shell_backend);
+
+ g_signal_connect_swapped (
+ shell, "window-destroyed",
+ G_CALLBACK (test_shell_backend_window_destroyed_cb),
+ shell_backend);
+}
+
+static void
+test_shell_backend_class_init (ETestShellBackendClass *class)
+{
+ GObjectClass *object_class;
+ EShellBackendClass *shell_backend_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETestShellBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = test_shell_backend_constructed;
+
+ shell_backend_class = E_SHELL_BACKEND_CLASS (class);
+ shell_backend_class->shell_view_type = E_TYPE_TEST_SHELL_VIEW;
+ shell_backend_class->name = "test";
+ shell_backend_class->aliases = "monkey";
+ shell_backend_class->schemes = "";
+ shell_backend_class->sort_order = 100;
+ shell_backend_class->start = test_shell_backend_start;
+ shell_backend_class->migrate = test_shell_backend_migrate;
+}
+
+static void
+test_shell_backend_init (ETestShellBackend *test_shell_backend)
+{
+ test_shell_backend->priv =
+ E_TEST_SHELL_BACKEND_GET_PRIVATE (test_shell_backend);
+}
+
+GType
+e_test_shell_backend_get_type (void)
+{
+ return test_shell_backend_type;
+}
+
+void
+e_test_shell_backend_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (ETestShellBackendClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) test_shell_backend_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ETestShellBackend),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) test_shell_backend_init,
+ NULL /* value_table */
+ };
+
+ test_shell_backend_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_BACKEND,
+ "ETestShellBackend", &type_info, 0);
+}
diff --git a/shell/test/e-test-shell-backend.h b/shell/test/e-test-shell-backend.h
new file mode 100644
index 0000000000..0d342bfbcc
--- /dev/null
+++ b/shell/test/e-test-shell-backend.h
@@ -0,0 +1,67 @@
+/*
+ * e-test-shell-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TEST_SHELL_BACKEND_H
+#define E_TEST_SHELL_BACKEND_H
+
+#include <shell/e-shell-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TEST_SHELL_BACKEND \
+ (e_test_shell_backend_get_type ())
+#define E_TEST_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TEST_SHELL_BACKEND, ETestShellBackend))
+#define E_TEST_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TEST_SHELL_BACKEND, ETestShellBackendClass))
+#define E_IS_TEST_SHELL_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TEST_SHELL_BACKEND))
+#define E_IS_TEST_SHELL_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TEST_SHELL_BACKEND))
+#define E_TEST_SHELL_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TEST_SHELL_BACKEND, ETestShellBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETestShellBackend ETestShellBackend;
+typedef struct _ETestShellBackendClass ETestShellBackendClass;
+typedef struct _ETestShellBackendPrivate ETestShellBackendPrivate;
+
+struct _ETestShellBackend {
+ EShellBackend parent;
+ ETestShellBackendPrivate *priv;
+};
+
+struct _ETestShellBackendClass {
+ EShellBackendClass parent_class;
+};
+
+GType e_test_shell_backend_get_type (void);
+void e_test_shell_backend_register_type
+ (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_TEST_SHELL_BACKEND_H */
diff --git a/shell/test/e-test-shell-view.c b/shell/test/e-test-shell-view.c
new file mode 100644
index 0000000000..b4464cc68f
--- /dev/null
+++ b/shell/test/e-test-shell-view.c
@@ -0,0 +1,155 @@
+/*
+ * e-test-shell-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-test-shell-view.h"
+
+#include "shell/e-shell-content.h"
+#include "shell/e-shell-sidebar.h"
+
+#define E_TEST_SHELL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TEST_SHELL_VIEW, ETestShellViewPrivate))
+
+struct _ETestShellViewPrivate {
+ EActivity *activity;
+};
+
+static gpointer parent_class;
+static GType test_shell_view_type;
+
+static void
+test_shell_view_toggled (EShellView *shell_view)
+{
+#if 0
+ gboolean is_active;
+ const gchar *active;
+
+ is_active = e_shell_view_is_active (shell_view);
+ active = is_active ? "active" : "inactive";
+ g_debug ("%s (now %s)", G_STRFUNC, active);
+#endif
+}
+
+static void
+test_shell_view_dispose (GObject *object)
+{
+ ETestShellViewPrivate *priv;
+
+ priv = E_TEST_SHELL_VIEW_GET_PRIVATE (object);
+
+ if (priv->activity != NULL) {
+ e_activity_complete (priv->activity);
+ g_object_unref (priv->activity);
+ priv->activity = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+test_shell_view_constructed (GObject *object)
+{
+ ETestShellViewPrivate *priv;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EShellBackend *shell_backend;
+ EShellView *shell_view;
+ EActivity *activity;
+ GtkWidget *widget;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ priv = E_TEST_SHELL_VIEW_GET_PRIVATE (object);
+
+ shell_view = E_SHELL_VIEW (object);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ widget = gtk_label_new ("Content Widget");
+ gtk_container_add (GTK_CONTAINER (shell_content), widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new ("Sidebar Widget");
+ gtk_container_add (GTK_CONTAINER (shell_sidebar), widget);
+ gtk_widget_show (widget);
+
+ activity = e_activity_new ("Test Activity");
+ e_activity_set_allow_cancel (activity, TRUE);
+ e_shell_backend_add_activity (shell_backend, activity);
+ priv->activity = activity;
+}
+
+static void
+test_shell_view_class_init (ETestShellViewClass *class,
+ GTypeModule *type_module)
+{
+ GObjectClass *object_class;
+ EShellViewClass *shell_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETestShellViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = test_shell_view_dispose;
+ object_class->constructed = test_shell_view_constructed;
+
+ shell_view_class = E_SHELL_VIEW_CLASS (class);
+ shell_view_class->label = "Test";
+ shell_view_class->icon_name = "face-monkey";
+ shell_view_class->toggled = test_shell_view_toggled;
+}
+
+static void
+test_shell_view_init (ETestShellView *test_shell_view)
+{
+ test_shell_view->priv =
+ E_TEST_SHELL_VIEW_GET_PRIVATE (test_shell_view);
+}
+
+GType
+e_test_shell_view_get_type (void)
+{
+ return test_shell_view_type;
+}
+
+void
+e_test_shell_view_register_type (GTypeModule *type_module)
+{
+ const GTypeInfo type_info = {
+ sizeof (ETestShellViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) test_shell_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ type_module,
+ sizeof (ETestShellView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) test_shell_view_init,
+ NULL /* value_table */
+ };
+
+ test_shell_view_type = g_type_module_register_type (
+ type_module, E_TYPE_SHELL_VIEW,
+ "ETestShellView", &type_info, 0);
+}
diff --git a/shell/test/e-test-shell-view.h b/shell/test/e-test-shell-view.h
new file mode 100644
index 0000000000..85c33bfb39
--- /dev/null
+++ b/shell/test/e-test-shell-view.h
@@ -0,0 +1,66 @@
+/*
+ * e-test-shell-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TEST_SHELL_VIEW_H
+#define E_TEST_SHELL_VIEW_H
+
+#include <shell/e-shell-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TEST_SHELL_VIEW \
+ (e_test_shell_view_get_type ())
+#define E_TEST_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TEST_SHELL_VIEW, ETestShellView))
+#define E_TEST_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TEST_SHELL_VIEW, ETestShellViewClass))
+#define E_IS_TEST_SHELL_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TEST_SHELL_VIEW))
+#define E_IS_TEST_SHELL_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TEST_SHELL_VIEW))
+#define E_TEST_SHELL_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TEST_SHELL_VIEW, ETestShellViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETestShellView ETestShellView;
+typedef struct _ETestShellViewClass ETestShellViewClass;
+typedef struct _ETestShellViewPrivate ETestShellViewPrivate;
+
+struct _ETestShellView {
+ EShellView parent;
+ ETestShellViewPrivate *priv;
+};
+
+struct _ETestShellViewClass {
+ EShellViewClass parent_class;
+};
+
+GType e_test_shell_view_get_type (void);
+void e_test_shell_view_register_type (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_TEST_SHELL_VIEW_H */
diff --git a/shell/test/evolution-module-test.c b/shell/test/evolution-module-test.c
new file mode 100644
index 0000000000..1fe3c7c0d0
--- /dev/null
+++ b/shell/test/evolution-module-test.c
@@ -0,0 +1,41 @@
+/*
+ * evolution-module-test.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-test-shell-backend.h"
+#include "e-test-shell-view.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
+
+ e_test_shell_backend_register_type (type_module);
+ e_test_shell_view_register_type (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/shell/test/evolution-test-component.c b/shell/test/evolution-test-component.c
deleted file mode 100644
index aaca1339c7..0000000000
--- a/shell/test/evolution-test-component.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-shlib-factory.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-exception.h>
-#include <gtk/gtk.h>
-#include "e-task-bar.h"
-#include "evolution-test-component.h"
-
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Test_Factory:" BASE_VERSION
-#define TEST_COMPONENT_ID "OAFIID:GNOME_Evolution_Test_Component:" BASE_VERSION
-#define CREATE_TEST_ID "test"
-
-#define PARENT_TYPE bonobo_object_get_type ()
-
-static BonoboObjectClass *parent_class = NULL;
-
-struct _EvolutionTestComponentPrivate {
- BonoboControl *view_control;
- BonoboControl *sidebar_control;
- BonoboControl *status_control;
-};
-
-/* GObject methods */
-
-static void
-impl_dispose (GObject *object)
-{
- EvolutionTestComponentPrivate *priv;
-
- priv = EVOLUTION_TEST_COMPONENT (object)->priv;
-
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- EvolutionTestComponentPrivate *priv = EVOLUTION_TEST_COMPONENT (object)->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-/* Evolution::Component CORBA methods */
-
-static void
-impl_upgradeFromVersion (PortableServer_Servant servant,
- const CORBA_short major,
- const CORBA_short minor,
- const CORBA_short revision,
- CORBA_Environment *ev)
-{
- EvolutionTestComponent *component = EVOLUTION_TEST_COMPONENT (bonobo_object_from_servant (servant));
- EvolutionTestComponentPrivate *priv;
-
- priv = component->priv;
-
- g_message ("Upgrading from %d.%d.%d", major, minor, revision);
-}
-
-static GNOME_Evolution_CreatableItemTypeList *
-impl__get_userCreatableItems (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
-
- list->_length = 1;
- list->_maximum = list->_length;
- list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
-
- CORBA_sequence_set_release (list, FALSE);
-
- list->_buffer[0].id = CREATE_TEST_ID;
- list->_buffer[0].description = _("New Test");
- list->_buffer[0].menuDescription = (gchar *) C_("New", "_Test");
- list->_buffer[0].tooltip = _("Create a new test item");
- list->_buffer[0].menuShortcut = 'i';
- list->_buffer[0].iconName = "";
-
- return list;
-}
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
- const CORBA_char *item_type_name,
- CORBA_Environment *ev)
-{
- EvolutionTestComponent *evolution_test_component = EVOLUTION_TEST_COMPONENT (bonobo_object_from_servant (servant));
- EvolutionTestComponentPrivate *priv;
-
- priv = evolution_test_component->priv;
-
- if (strcmp (item_type_name, CREATE_TEST_ID) == 0) {
- g_message ("Creating test item");
- } else {
- bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType);
- return;
- }
-}
-
-/* Initialization */
-
-static void
-evolution_test_component_class_init (EvolutionTestComponentClass *klass)
-{
- POA_GNOME_Evolution_Component__epv *epv = &klass->epv;
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- epv->upgradeFromVersion = impl_upgradeFromVersion;
- epv->_get_userCreatableItems = impl__get_userCreatableItems;
- epv->requestCreateItem = impl_requestCreateItem;
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-}
-
-static void
-evolution_test_component_init (EvolutionTestComponent *component, EvolutionTestComponentClass *klass)
-{
- EvolutionTestComponentPrivate *priv;
-
- priv = g_new0 (EvolutionTestComponentPrivate, 1);
-
- component->priv = priv;
-}
-
-BONOBO_TYPE_FUNC_FULL (EvolutionTestComponent, GNOME_Evolution_Component, PARENT_TYPE, evolution_test_component)
-
-static BonoboObject *
-factory (BonoboGenericFactory *factory,
- const gchar *component_id,
- gpointer closure)
-{
- if (strcmp (component_id, TEST_COMPONENT_ID) == 0) {
- BonoboObject *object = BONOBO_OBJECT (g_object_new (EVOLUTION_TEST_TYPE_COMPONENT, NULL));
- bonobo_object_ref (object);
- return object;
- }
-
- g_warning (FACTORY_ID ": Don't know what to do with %s", component_id);
-
- return NULL;
-}
-
-BONOBO_ACTIVATION_SHLIB_FACTORY (FACTORY_ID, "Evolution Calendar component factory", factory, NULL)
diff --git a/shell/test/evolution-test-component.h b/shell/test/evolution-test-component.h
deleted file mode 100644
index 5809348321..0000000000
--- a/shell/test/evolution-test-component.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * JP Rosevear <jpr@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _EVOLUTION_TEST_COMPONENT_H_
-#define _EVOLUTION_TEST_COMPONENT_H_
-
-#include <bonobo/bonobo-object.h>
-#include "Evolution.h"
-
-#define EVOLUTION_TEST_TYPE_COMPONENT (evolution_test_component_get_type ())
-#define EVOLUTION_TEST_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EVOLUTION_TEST_TYPE_COMPONENT, EvolutionTestComponent))
-#define EVOLUTION_TEST_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EVOLUTION_TEST_TYPE_COMPONENT, EvolutionTestComponentClass))
-#define EVOLUTION_TEST_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVOLUTION_TEST_TYPE_COMPONENT))
-#define EVOLUTION_TEST_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EVOLUTION_TEST_TYPE_COMPONENT))
-
-typedef struct _EvolutionTestComponent EvolutionTestComponent;
-typedef struct _EvolutionTestComponentPrivate EvolutionTestComponentPrivate;
-typedef struct _EvolutionTestComponentClass EvolutionTestComponentClass;
-
-struct _EvolutionTestComponent {
- BonoboObject parent;
-
- EvolutionTestComponentPrivate *priv;
-};
-
-struct _EvolutionTestComponentClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Component__epv epv;
-};
-
-GType evolution_test_component_get_type (void);
-
-#endif /* _EVOLUTION_TEST_COMPONENT_H_ */
diff --git a/smclient/Makefile.am b/smclient/Makefile.am
new file mode 100644
index 0000000000..4d5c63f0fc
--- /dev/null
+++ b/smclient/Makefile.am
@@ -0,0 +1,44 @@
+if OS_WIN32
+platform_sources = eggsmclient-win32.c
+platform_logout_test_ldflags = -mwindows
+else
+platform_defines = -DEGG_SM_CLIENT_BACKEND_XSMP
+platform_ltlibraries = libeggdesktopfile.la
+platform_libs = libeggdesktopfile.la -lSM -lICE
+platform_sources = eggsmclient-xsmp.c
+endif
+
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\""EggSMClient"\" \
+ $(platform_defines) \
+ $(EGG_SMCLIENT_CFLAGS)
+
+noinst_LTLIBRARIES = \
+ libeggsmclient.la \
+ $(platform_ltlibraries)
+
+libeggsmclient_la_LIBADD = \
+ $(EGG_SMCLIENT_LIBS) \
+ $(platform_libs)
+
+libeggsmclient_la_LDFLAGS = \
+ $(platform_ldflags)
+
+libeggsmclient_la_SOURCES = \
+ eggsmclient.c \
+ eggsmclient.h \
+ eggsmclient-private.h \
+ $(platform_sources)
+
+libeggdesktopfile_la_LIBADD = \
+ $(EGG_SMCLIENT_LIBS)
+
+libeggdesktopfile_la_SOURCES = \
+ eggdesktopfile.c \
+ eggdesktopfile.h
+
+EXTRA_DIST = \
+ eggsmclient-win32.c \
+ eggsmclient-xsmp.c
+
+-include $(top_srcdir)/git.mk
diff --git a/smclient/README b/smclient/README
new file mode 100644
index 0000000000..73f51e553c
--- /dev/null
+++ b/smclient/README
@@ -0,0 +1,2 @@
+These files are copied from libegg for session management support.
+Delete this when the functionality finally lands in GTK+ or GLib.
diff --git a/smclient/eggdesktopfile.c b/smclient/eggdesktopfile.c
new file mode 100644
index 0000000000..9f18be1dc6
--- /dev/null
+++ b/smclient/eggdesktopfile.c
@@ -0,0 +1,1508 @@
+/* eggdesktopfile.c - Freedesktop.Org Desktop Files
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * Based on gnome-desktop-item.c
+ * Copyright (C) 1999, 2000 Red Hat Inc.
+ * Copyright (C) 2001 George Lebl
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place -
+ * Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "eggdesktopfile.h"
+
+#include <string.h>
+#include <unistd.h>
+
+#include <glib/gi18n.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+struct EggDesktopFile {
+ GKeyFile *key_file;
+ gchar *source;
+
+ gchar *name, *icon;
+ EggDesktopFileType type;
+ gchar document_code;
+};
+
+/**
+ * egg_desktop_file_new:
+ * @desktop_file_path: path to a Freedesktop-style Desktop file
+ * @error: error pointer
+ *
+ * Creates a new #EggDesktopFile for @desktop_file.
+ *
+ * Return value: the new #EggDesktopFile, or %NULL on error.
+ **/
+EggDesktopFile *
+egg_desktop_file_new (const gchar *desktop_file_path, GError **error)
+{
+ GKeyFile *key_file;
+
+ key_file = g_key_file_new ();
+ if (!g_key_file_load_from_file (key_file, desktop_file_path, 0, error))
+ {
+ g_key_file_free (key_file);
+ return NULL;
+ }
+
+ return egg_desktop_file_new_from_key_file (key_file, desktop_file_path,
+ error);
+}
+
+/**
+ * egg_desktop_file_new_from_data_dirs:
+ * @desktop_file_path: relative path to a Freedesktop-style Desktop file
+ * @error: error pointer
+ *
+ * Looks for @desktop_file_path in the paths returned from
+ * g_get_user_data_dir() and g_get_system_data_dirs(), and creates
+ * a new #EggDesktopFile from it.
+ *
+ * Return value: the new #EggDesktopFile, or %NULL on error.
+ **/
+EggDesktopFile *
+egg_desktop_file_new_from_data_dirs (const gchar *desktop_file_path,
+ GError **error)
+{
+ EggDesktopFile *desktop_file;
+ GKeyFile *key_file;
+ gchar *full_path;
+
+ key_file = g_key_file_new ();
+ if (!g_key_file_load_from_data_dirs (key_file, desktop_file_path,
+ &full_path, 0, error))
+ {
+ g_key_file_free (key_file);
+ return NULL;
+ }
+
+ desktop_file = egg_desktop_file_new_from_key_file (key_file,
+ full_path,
+ error);
+ g_free (full_path);
+ return desktop_file;
+}
+
+/**
+ * egg_desktop_file_new_from_dirs:
+ * @desktop_file_path: relative path to a Freedesktop-style Desktop file
+ * @search_dirs: NULL-terminated array of directories to search
+ * @error: error pointer
+ *
+ * Looks for @desktop_file_path in the paths returned from
+ * g_get_user_data_dir() and g_get_system_data_dirs(), and creates
+ * a new #EggDesktopFile from it.
+ *
+ * Return value: the new #EggDesktopFile, or %NULL on error.
+ **/
+EggDesktopFile *
+egg_desktop_file_new_from_dirs (const gchar *desktop_file_path,
+ const gchar **search_dirs,
+ GError **error)
+{
+ EggDesktopFile *desktop_file;
+ GKeyFile *key_file;
+ gchar *full_path;
+
+ key_file = g_key_file_new ();
+ if (!g_key_file_load_from_dirs (key_file, desktop_file_path, search_dirs,
+ &full_path, 0, error))
+ {
+ g_key_file_free (key_file);
+ return NULL;
+ }
+
+ desktop_file = egg_desktop_file_new_from_key_file (key_file,
+ full_path,
+ error);
+ g_free (full_path);
+ return desktop_file;
+}
+
+/**
+ * egg_desktop_file_new_from_key_file:
+ * @key_file: a #GKeyFile representing a desktop file
+ * @source: the path or URI that @key_file was loaded from, or %NULL
+ * @error: error pointer
+ *
+ * Creates a new #EggDesktopFile for @key_file. Assumes ownership of
+ * @key_file (on success or failure); you should consider @key_file to
+ * be freed after calling this function.
+ *
+ * Return value: the new #EggDesktopFile, or %NULL on error.
+ **/
+EggDesktopFile *
+egg_desktop_file_new_from_key_file (GKeyFile *key_file,
+ const gchar *source,
+ GError **error)
+{
+ EggDesktopFile *desktop_file;
+ gchar *version, *type;
+
+ if (!g_key_file_has_group (key_file, EGG_DESKTOP_FILE_GROUP))
+ {
+ g_set_error (error, EGG_DESKTOP_FILE_ERROR,
+ EGG_DESKTOP_FILE_ERROR_INVALID,
+ _("File is not a valid .desktop file"));
+ g_key_file_free (key_file);
+ return NULL;
+ }
+
+ version = g_key_file_get_value (key_file, EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_VERSION,
+ NULL);
+ if (version)
+ {
+ double version_num;
+ gchar *end;
+
+ version_num = g_ascii_strtod (version, &end);
+ if (*end)
+ {
+ g_warning ("Invalid Version string '%s' in %s",
+ version, source ? source : "(unknown)");
+ }
+ else if (version_num > 1.0)
+ {
+ g_set_error (error, EGG_DESKTOP_FILE_ERROR,
+ EGG_DESKTOP_FILE_ERROR_INVALID,
+ _("Unrecognized desktop file Version '%s'"), version);
+ g_free (version);
+ g_key_file_free (key_file);
+ return NULL;
+ }
+ g_free (version);
+ }
+
+ desktop_file = g_new0 (EggDesktopFile, 1);
+ desktop_file->key_file = key_file;
+
+ if (g_path_is_absolute (source))
+ desktop_file->source = g_filename_to_uri (source, NULL, NULL);
+ else
+ desktop_file->source = g_strdup (source);
+
+ desktop_file->name = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_NAME, error);
+ if (!desktop_file->name)
+ {
+ egg_desktop_file_free (desktop_file);
+ return NULL;
+ }
+
+ type = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_TYPE, error);
+ if (!type)
+ {
+ egg_desktop_file_free (desktop_file);
+ return NULL;
+ }
+
+ if (!strcmp (type, "Application"))
+ {
+ gchar *exec, *p;
+
+ desktop_file->type = EGG_DESKTOP_FILE_TYPE_APPLICATION;
+
+ exec = g_key_file_get_string (key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_EXEC,
+ error);
+ if (!exec)
+ {
+ egg_desktop_file_free (desktop_file);
+ g_free (type);
+ return NULL;
+ }
+
+ /* See if it takes paths or URIs or neither */
+ for (p = exec; *p; p++)
+ {
+ if (*p == '%')
+ {
+ if (p[1] == '\0' || strchr ("FfUu", p[1]))
+ {
+ desktop_file->document_code = p[1];
+ break;
+ }
+ p++;
+ }
+ }
+
+ g_free (exec);
+ }
+ else if (!strcmp (type, "Link"))
+ {
+ gchar *url;
+
+ desktop_file->type = EGG_DESKTOP_FILE_TYPE_LINK;
+
+ url = g_key_file_get_string (key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_URL,
+ error);
+ if (!url)
+ {
+ egg_desktop_file_free (desktop_file);
+ g_free (type);
+ return NULL;
+ }
+ g_free (url);
+ }
+ else if (!strcmp (type, "Directory"))
+ desktop_file->type = EGG_DESKTOP_FILE_TYPE_DIRECTORY;
+ else
+ desktop_file->type = EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED;
+
+ g_free (type);
+
+ /* Check the Icon key */
+ desktop_file->icon = g_key_file_get_string (key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_ICON,
+ NULL);
+ if (desktop_file->icon && !g_path_is_absolute (desktop_file->icon))
+ {
+ gchar *ext;
+
+ /* Lots of .desktop files still get this wrong */
+ ext = strrchr (desktop_file->icon, '.');
+ if (ext && (!strcmp (ext, ".png") ||
+ !strcmp (ext, ".xpm") ||
+ !strcmp (ext, ".svg")))
+ {
+ g_warning ("Desktop file '%s' has malformed Icon key '%s'"
+ "(should not include extension)",
+ source ? source : "(unknown)",
+ desktop_file->icon);
+ *ext = '\0';
+ }
+ }
+
+ return desktop_file;
+}
+
+/**
+ * egg_desktop_file_free:
+ * @desktop_file: an #EggDesktopFile
+ *
+ * Frees @desktop_file.
+ **/
+void
+egg_desktop_file_free (EggDesktopFile *desktop_file)
+{
+ g_key_file_free (desktop_file->key_file);
+ g_free (desktop_file->source);
+ g_free (desktop_file->name);
+ g_free (desktop_file->icon);
+ g_free (desktop_file);
+}
+
+/**
+ * egg_desktop_file_get_source:
+ * @desktop_file: an #EggDesktopFile
+ *
+ * Gets the URI that @desktop_file was loaded from.
+ *
+ * Return value: @desktop_file's source URI
+ **/
+const gchar *
+egg_desktop_file_get_source (EggDesktopFile *desktop_file)
+{
+ return desktop_file->source;
+}
+
+/**
+ * egg_desktop_file_get_desktop_file_type:
+ * @desktop_file: an #EggDesktopFile
+ *
+ * Gets the desktop file type of @desktop_file.
+ *
+ * Return value: @desktop_file's type
+ **/
+EggDesktopFileType
+egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file)
+{
+ return desktop_file->type;
+}
+
+/**
+ * egg_desktop_file_get_name:
+ * @desktop_file: an #EggDesktopFile
+ *
+ * Gets the (localized) value of @desktop_file's "Name" key.
+ *
+ * Return value: the application/link name
+ **/
+const gchar *
+egg_desktop_file_get_name (EggDesktopFile *desktop_file)
+{
+ return desktop_file->name;
+}
+
+/**
+ * egg_desktop_file_get_icon:
+ * @desktop_file: an #EggDesktopFile
+ *
+ * Gets the value of @desktop_file's "Icon" key.
+ *
+ * If the icon string is a full path (that is, if g_path_is_absolute()
+ * returns %TRUE when called on it), it points to a file containing an
+ * unthemed icon. If the icon string is not a full path, it is the
+ * name of a themed icon, which can be looked up with %GtkIconTheme,
+ * or passed directly to a theme-aware widget like %GtkImage or
+ * %GtkCellRendererPixbuf.
+ *
+ * Return value: the icon path or name
+ **/
+const gchar *
+egg_desktop_file_get_icon (EggDesktopFile *desktop_file)
+{
+ return desktop_file->icon;
+}
+
+gboolean
+egg_desktop_file_has_key (EggDesktopFile *desktop_file,
+ const gchar *key,
+ GError **error)
+{
+ return g_key_file_has_key (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP, key,
+ error);
+}
+
+gchar *
+egg_desktop_file_get_string (EggDesktopFile *desktop_file,
+ const gchar *key,
+ GError **error)
+{
+ return g_key_file_get_string (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP, key,
+ error);
+}
+
+gchar *
+egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
+ const gchar *key,
+ const gchar *locale,
+ GError **error)
+{
+ return g_key_file_get_locale_string (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP, key, locale,
+ error);
+}
+
+gboolean
+egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
+ const gchar *key,
+ GError **error)
+{
+ return g_key_file_get_boolean (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP, key,
+ error);
+}
+
+gdouble
+egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
+ const gchar *key,
+ GError **error)
+{
+ return g_key_file_get_double (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP, key,
+ error);
+}
+
+gchar **
+egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
+ const gchar *key,
+ gsize *length,
+ GError **error)
+{
+ return g_key_file_get_string_list (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP, key, length,
+ error);
+}
+
+gchar **
+egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
+ const gchar *key,
+ const gchar *locale,
+ gsize *length,
+ GError **error)
+{
+ return g_key_file_get_locale_string_list (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP, key,
+ locale, length,
+ error);
+}
+
+/**
+ * egg_desktop_file_can_launch:
+ * @desktop_file: an #EggDesktopFile
+ * @desktop_environment: the name of the running desktop environment,
+ * or %NULL
+ *
+ * Tests if @desktop_file can/should be launched in the current
+ * environment. If @desktop_environment is non-%NULL, @desktop_file's
+ * "OnlyShowIn" and "NotShowIn" keys are checked to make sure that
+ * this desktop_file is appropriate for the named environment.
+ *
+ * Furthermore, if @desktop_file has type
+ * %EGG_DESKTOP_FILE_TYPE_APPLICATION, its "TryExec" key (if any) is
+ * also checked, to make sure the binary it points to exists.
+ *
+ * egg_desktop_file_can_launch() does NOT check the value of the
+ * "Hidden" key.
+ *
+ * Return value: %TRUE if @desktop_file can be launched
+ **/
+gboolean
+egg_desktop_file_can_launch (EggDesktopFile *desktop_file,
+ const gchar *desktop_environment)
+{
+ gchar *try_exec, *found_program;
+ gchar **only_show_in, **not_show_in;
+ gboolean found;
+ gint i;
+
+ if (desktop_file->type != EGG_DESKTOP_FILE_TYPE_APPLICATION &&
+ desktop_file->type != EGG_DESKTOP_FILE_TYPE_LINK)
+ return FALSE;
+
+ if (desktop_environment)
+ {
+ only_show_in = g_key_file_get_string_list (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN,
+ NULL, NULL);
+ if (only_show_in)
+ {
+ for (i = 0, found = FALSE; only_show_in[i] && !found; i++)
+ {
+ if (!strcmp (only_show_in[i], desktop_environment))
+ found = TRUE;
+ }
+
+ g_strfreev (only_show_in);
+
+ if (!found)
+ return FALSE;
+ }
+
+ not_show_in = g_key_file_get_string_list (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN,
+ NULL, NULL);
+ if (not_show_in)
+ {
+ for (i = 0, found = FALSE; not_show_in[i] && !found; i++)
+ {
+ if (!strcmp (not_show_in[i], desktop_environment))
+ found = TRUE;
+ }
+
+ g_strfreev (not_show_in);
+
+ if (found)
+ return FALSE;
+ }
+ }
+
+ if (desktop_file->type == EGG_DESKTOP_FILE_TYPE_APPLICATION)
+ {
+ try_exec = g_key_file_get_string (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_TRY_EXEC,
+ NULL);
+ if (try_exec)
+ {
+ found_program = g_find_program_in_path (try_exec);
+ g_free (try_exec);
+
+ if (!found_program)
+ return FALSE;
+ g_free (found_program);
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * egg_desktop_file_accepts_documents:
+ * @desktop_file: an #EggDesktopFile
+ *
+ * Tests if @desktop_file represents an application that can accept
+ * documents on the command line.
+ *
+ * Return value: %TRUE or %FALSE
+ **/
+gboolean
+egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file)
+{
+ return desktop_file->document_code != 0;
+}
+
+/**
+ * egg_desktop_file_accepts_multiple:
+ * @desktop_file: an #EggDesktopFile
+ *
+ * Tests if @desktop_file can accept multiple documents at once.
+ *
+ * If this returns %FALSE, you can still pass multiple documents to
+ * egg_desktop_file_launch(), but that will result in multiple copies
+ * of the application being launched. See egg_desktop_file_launch()
+ * for more details.
+ *
+ * Return value: %TRUE or %FALSE
+ **/
+gboolean
+egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file)
+{
+ return (desktop_file->document_code == 'F' ||
+ desktop_file->document_code == 'U');
+}
+
+/**
+ * egg_desktop_file_accepts_uris:
+ * @desktop_file: an #EggDesktopFile
+ *
+ * Tests if @desktop_file can accept (non-"file:") URIs as documents to
+ * open.
+ *
+ * Return value: %TRUE or %FALSE
+ **/
+gboolean
+egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file)
+{
+ return (desktop_file->document_code == 'U' ||
+ desktop_file->document_code == 'u');
+}
+
+static void
+append_quoted_word (GString *str,
+ const gchar *s,
+ gboolean in_single_quotes,
+ gboolean in_double_quotes)
+{
+ const gchar *p;
+
+ if (!in_single_quotes && !in_double_quotes)
+ g_string_append_c (str, '\'');
+ else if (!in_single_quotes && in_double_quotes)
+ g_string_append (str, "\"'");
+
+ if (!strchr (s, '\''))
+ g_string_append (str, s);
+ else
+ {
+ for (p = s; *p != '\0'; p++)
+ {
+ if (*p == '\'')
+ g_string_append (str, "'\\''");
+ else
+ g_string_append_c (str, *p);
+ }
+ }
+
+ if (!in_single_quotes && !in_double_quotes)
+ g_string_append_c (str, '\'');
+ else if (!in_single_quotes && in_double_quotes)
+ g_string_append (str, "'\"");
+}
+
+static void
+do_percent_subst (EggDesktopFile *desktop_file,
+ gchar code,
+ GString *str,
+ GSList **documents,
+ gboolean in_single_quotes,
+ gboolean in_double_quotes)
+{
+ GSList *d;
+ gchar *doc;
+
+ switch (code)
+ {
+ case '%':
+ g_string_append_c (str, '%');
+ break;
+
+ case 'F':
+ case 'U':
+ for (d = *documents; d; d = d->next)
+ {
+ doc = d->data;
+ g_string_append (str, " ");
+ append_quoted_word (str, doc, in_single_quotes, in_double_quotes);
+ }
+ *documents = NULL;
+ break;
+
+ case 'f':
+ case 'u':
+ if (*documents)
+ {
+ doc = (*documents)->data;
+ g_string_append (str, " ");
+ append_quoted_word (str, doc, in_single_quotes, in_double_quotes);
+ *documents = (*documents)->next;
+ }
+ break;
+
+ case 'i':
+ if (desktop_file->icon)
+ {
+ g_string_append (str, "--icon ");
+ append_quoted_word (str, desktop_file->icon,
+ in_single_quotes, in_double_quotes);
+ }
+ break;
+
+ case 'c':
+ if (desktop_file->name)
+ {
+ append_quoted_word (str, desktop_file->name,
+ in_single_quotes, in_double_quotes);
+ }
+ break;
+
+ case 'k':
+ if (desktop_file->source)
+ {
+ append_quoted_word (str, desktop_file->source,
+ in_single_quotes, in_double_quotes);
+ }
+ break;
+
+ case 'D':
+ case 'N':
+ case 'd':
+ case 'n':
+ case 'v':
+ case 'm':
+ /* Deprecated; skip */
+ break;
+
+ default:
+ g_warning ("Unrecognized %%-code '%%%c' in Exec", code);
+ break;
+ }
+}
+
+static gchar *
+parse_exec (EggDesktopFile *desktop_file,
+ GSList **documents,
+ GError **error)
+{
+ gchar *exec, *p, *command;
+ gboolean escape, single_quot, double_quot;
+ GString *gs;
+
+ exec = g_key_file_get_string (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_EXEC,
+ error);
+ if (!exec)
+ return NULL;
+
+ /* Build the command */
+ gs = g_string_new (NULL);
+ escape = single_quot = double_quot = FALSE;
+
+ for (p = exec; *p != '\0'; p++)
+ {
+ if (escape)
+ {
+ escape = FALSE;
+ g_string_append_c (gs, *p);
+ }
+ else if (*p == '\\')
+ {
+ if (!single_quot)
+ escape = TRUE;
+ g_string_append_c (gs, *p);
+ }
+ else if (*p == '\'')
+ {
+ g_string_append_c (gs, *p);
+ if (!single_quot && !double_quot)
+ single_quot = TRUE;
+ else if (single_quot)
+ single_quot = FALSE;
+ }
+ else if (*p == '"')
+ {
+ g_string_append_c (gs, *p);
+ if (!single_quot && !double_quot)
+ double_quot = TRUE;
+ else if (double_quot)
+ double_quot = FALSE;
+ }
+ else if (*p == '%' && p[1])
+ {
+ do_percent_subst (desktop_file, p[1], gs, documents,
+ single_quot, double_quot);
+ p++;
+ }
+ else
+ g_string_append_c (gs, *p);
+ }
+
+ g_free (exec);
+ command = g_string_free (gs, FALSE);
+
+ /* Prepend "xdg-terminal " if needed (FIXME: use gvfs) */
+ if (g_key_file_has_key (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_TERMINAL,
+ NULL))
+ {
+ GError *terminal_error = NULL;
+ gboolean use_terminal =
+ g_key_file_get_boolean (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_TERMINAL,
+ &terminal_error);
+ if (terminal_error)
+ {
+ g_free (command);
+ g_propagate_error (error, terminal_error);
+ return NULL;
+ }
+
+ if (use_terminal)
+ {
+ gs = g_string_new ("xdg-terminal ");
+ append_quoted_word (gs, command, FALSE, FALSE);
+ g_free (command);
+ command = g_string_free (gs, FALSE);
+ }
+ }
+
+ return command;
+}
+
+static GSList *
+translate_document_list (EggDesktopFile *desktop_file, GSList *documents)
+{
+ gboolean accepts_uris = egg_desktop_file_accepts_uris (desktop_file);
+ GSList *ret, *d;
+
+ for (d = documents, ret = NULL; d; d = d->next)
+ {
+ const gchar *document = d->data;
+ gboolean is_uri = !g_path_is_absolute (document);
+ gchar *translated;
+
+ if (accepts_uris)
+ {
+ if (is_uri)
+ translated = g_strdup (document);
+ else
+ translated = g_filename_to_uri (document, NULL, NULL);
+ }
+ else
+ {
+ if (is_uri)
+ translated = g_filename_from_uri (document, NULL, NULL);
+ else
+ translated = g_strdup (document);
+ }
+
+ if (translated)
+ ret = g_slist_prepend (ret, translated);
+ }
+
+ return g_slist_reverse (ret);
+}
+
+static void
+free_document_list (GSList *documents)
+{
+ GSList *d;
+
+ for (d = documents; d; d = d->next)
+ g_free (d->data);
+ g_slist_free (documents);
+}
+
+/**
+ * egg_desktop_file_parse_exec:
+ * @desktop_file: a #EggDesktopFile
+ * @documents: a list of document paths or URIs
+ * @error: error pointer
+ *
+ * Parses @desktop_file's Exec key, inserting @documents into it, and
+ * returns the result.
+ *
+ * If @documents contains non-file: URIs and @desktop_file does not
+ * accept URIs, those URIs will be ignored. Likewise, if @documents
+ * contains more elements than @desktop_file accepts, the extra
+ * documents will be ignored.
+ *
+ * Return value: the parsed Exec string
+ **/
+gchar *
+egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
+ GSList *documents,
+ GError **error)
+{
+ GSList *translated, *docs;
+ gchar *command;
+
+ docs = translated = translate_document_list (desktop_file, documents);
+ command = parse_exec (desktop_file, &docs, error);
+ free_document_list (translated);
+
+ return command;
+}
+
+static gboolean
+parse_link (EggDesktopFile *desktop_file,
+ EggDesktopFile **app_desktop_file,
+ GSList **documents,
+ GError **error)
+{
+ gchar *url;
+ GKeyFile *key_file;
+
+ url = g_key_file_get_string (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_URL,
+ error);
+ if (!url)
+ return FALSE;
+ *documents = g_slist_prepend (NULL, url);
+
+ /* FIXME: use gvfs */
+ key_file = g_key_file_new ();
+ g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_NAME,
+ "xdg-open");
+ g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_TYPE,
+ "Application");
+ g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_EXEC,
+ "xdg-open %u");
+ *app_desktop_file = egg_desktop_file_new_from_key_file (key_file, NULL, NULL);
+ return TRUE;
+}
+
+#if GTK_CHECK_VERSION (2, 12, 0)
+static gchar *
+start_startup_notification (GdkDisplay *display,
+ EggDesktopFile *desktop_file,
+ const gchar *argv0,
+ gint screen,
+ gint workspace,
+ guint32 launch_time)
+{
+ static gint sequence = 0;
+ gchar *startup_id;
+ gchar *description, *wmclass;
+ gchar *screen_str, *workspace_str;
+
+ if (g_key_file_has_key (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY,
+ NULL))
+ {
+ if (!g_key_file_get_boolean (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY,
+ NULL))
+ return NULL;
+ wmclass = NULL;
+ }
+ else
+ {
+ wmclass = g_key_file_get_string (desktop_file->key_file,
+ EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS,
+ NULL);
+ if (!wmclass)
+ return NULL;
+ }
+
+ if (launch_time == (guint32)-1)
+ launch_time = gdk_x11_display_get_user_time (display);
+ startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu",
+ g_get_prgname (),
+ (unsigned long)getpid (),
+ g_get_host_name (),
+ argv0,
+ sequence++,
+ (unsigned long)launch_time);
+
+ description = g_strdup_printf (_("Starting %s"), desktop_file->name);
+ screen_str = g_strdup_printf ("%d", screen);
+ workspace_str = workspace == -1 ? NULL : g_strdup_printf ("%d", workspace);
+
+ gdk_x11_display_broadcast_startup_message (display, "new",
+ "ID", startup_id,
+ "NAME", desktop_file->name,
+ "SCREEN", screen_str,
+ "BIN", argv0,
+ "ICON", desktop_file->icon,
+ "DESKTOP", workspace_str,
+ "DESCRIPTION", description,
+ "WMCLASS", wmclass,
+ NULL);
+
+ g_free (description);
+ g_free (wmclass);
+ g_free (screen_str);
+ g_free (workspace_str);
+
+ return startup_id;
+}
+
+static void
+end_startup_notification (GdkDisplay *display,
+ const gchar *startup_id)
+{
+ gdk_x11_display_broadcast_startup_message (display, "remove",
+ "ID", startup_id,
+ NULL);
+}
+
+#define EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH (30 /* seconds */)
+
+typedef struct {
+ GdkDisplay *display;
+ gchar *startup_id;
+} StartupNotificationData;
+
+static gboolean
+startup_notification_timeout (gpointer data)
+{
+ StartupNotificationData *sn_data = data;
+
+ end_startup_notification (sn_data->display, sn_data->startup_id);
+ g_object_unref (sn_data->display);
+ g_free (sn_data->startup_id);
+ g_free (sn_data);
+
+ return FALSE;
+}
+
+static void
+set_startup_notification_timeout (GdkDisplay *display,
+ const gchar *startup_id)
+{
+ StartupNotificationData *sn_data;
+
+ sn_data = g_new (StartupNotificationData, 1);
+ sn_data->display = g_object_ref (display);
+ sn_data->startup_id = g_strdup (startup_id);
+
+ g_timeout_add_seconds (EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH,
+ startup_notification_timeout, sn_data);
+}
+#endif /* GTK 2.12 */
+
+static GPtrArray *
+array_putenv (GPtrArray *env, gchar *variable)
+{
+ guint i, keylen;
+
+ if (!env)
+ {
+ gchar **envp;
+
+ env = g_ptr_array_new ();
+
+ envp = g_listenv ();
+ for (i = 0; envp[i]; i++)
+ {
+ const gchar *value;
+
+ value = g_getenv (envp[i]);
+ g_ptr_array_add (env, g_strdup_printf ("%s=%s", envp[i],
+ value ? value : ""));
+ }
+ g_strfreev (envp);
+ }
+
+ keylen = strcspn (variable, "=");
+
+ /* Remove old value of key */
+ for (i = 0; i < env->len; i++)
+ {
+ gchar *envvar = env->pdata[i];
+
+ if (!strncmp (envvar, variable, keylen) && envvar[keylen] == '=')
+ {
+ g_free (envvar);
+ g_ptr_array_remove_index_fast (env, i);
+ break;
+ }
+ }
+
+ /* Add new value */
+ g_ptr_array_add (env, g_strdup (variable));
+
+ return env;
+}
+
+static gboolean
+egg_desktop_file_launchv (EggDesktopFile *desktop_file,
+ GSList *documents, va_list args,
+ GError **error)
+{
+ EggDesktopFileLaunchOption option;
+ GSList *translated_documents = NULL, *docs = NULL;
+ gchar *command, **argv;
+ gint argc, i, screen_num;
+ gboolean success, current_success;
+ GdkDisplay *display;
+ gchar *startup_id;
+
+ GPtrArray *env = NULL;
+ gchar **variables = NULL;
+ GdkScreen *screen = NULL;
+ gint workspace = -1;
+ const gchar *directory = NULL;
+ guint32 launch_time = (guint32)-1;
+ GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
+ GSpawnChildSetupFunc setup_func = NULL;
+ gpointer setup_data = NULL;
+
+ GPid *ret_pid = NULL;
+ gint *ret_stdin = NULL, *ret_stdout = NULL, *ret_stderr = NULL;
+ gchar **ret_startup_id = NULL;
+
+ if (documents && desktop_file->document_code == 0)
+ {
+ g_set_error (error, EGG_DESKTOP_FILE_ERROR,
+ EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
+ _("Application does not accept documents on command line"));
+ return FALSE;
+ }
+
+ /* Read the options: technically it's incorrect for the caller to
+ * NULL-terminate the list of options (rather than 0-terminating
+ * it), but NULL-terminating lets us use G_GNUC_NULL_TERMINATED,
+ * it's more consistent with other glib/gtk methods, and it will
+ * work as long as sizeof (gint) <= sizeof (NULL), and NULL is
+ * represented as 0. (Which is true everywhere we care about.)
+ */
+ while ((option = va_arg (args, EggDesktopFileLaunchOption)))
+ {
+ switch (option)
+ {
+ case EGG_DESKTOP_FILE_LAUNCH_CLEARENV:
+ if (env)
+ g_ptr_array_free (env, TRUE);
+ env = g_ptr_array_new ();
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_PUTENV:
+ variables = va_arg (args, gchar **);
+ for (i = 0; variables[i]; i++)
+ env = array_putenv (env, variables[i]);
+ break;
+
+ case EGG_DESKTOP_FILE_LAUNCH_SCREEN:
+ screen = va_arg (args, GdkScreen *);
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_WORKSPACE:
+ workspace = va_arg (args, gint);
+ break;
+
+ case EGG_DESKTOP_FILE_LAUNCH_DIRECTORY:
+ directory = va_arg (args, const gchar *);
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_TIME:
+ launch_time = va_arg (args, guint32);
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_FLAGS:
+ flags |= va_arg (args, GSpawnFlags);
+ /* Make sure they didn't set any flags that don't make sense. */
+ flags &= ~G_SPAWN_FILE_AND_ARGV_ZERO;
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC:
+ setup_func = va_arg (args, GSpawnChildSetupFunc);
+ setup_data = va_arg (args, gpointer);
+ break;
+
+ case EGG_DESKTOP_FILE_LAUNCH_RETURN_PID:
+ ret_pid = va_arg (args, GPid *);
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE:
+ ret_stdin = va_arg (args, gint *);
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE:
+ ret_stdout = va_arg (args, gint *);
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE:
+ ret_stderr = va_arg (args, gint *);
+ break;
+ case EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID:
+ ret_startup_id = va_arg (args, gchar **);
+ break;
+
+ default:
+ g_set_error (error, EGG_DESKTOP_FILE_ERROR,
+ EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION,
+ _("Unrecognized launch option: %d"),
+ GPOINTER_TO_INT (option));
+ success = FALSE;
+ goto out;
+ }
+ }
+
+ if (screen)
+ {
+ gchar *display_name = gdk_screen_make_display_name (screen);
+ gchar *display_env = g_strdup_printf ("DISPLAY=%s", display_name);
+ env = array_putenv (env, display_env);
+ g_free (display_name);
+ g_free (display_env);
+
+ display = gdk_screen_get_display (screen);
+ }
+ else
+ {
+ display = gdk_display_get_default ();
+ screen = gdk_display_get_default_screen (display);
+ }
+ screen_num = gdk_screen_get_number (screen);
+
+ translated_documents = translate_document_list (desktop_file, documents);
+ docs = translated_documents;
+
+ success = FALSE;
+
+ do
+ {
+ command = parse_exec (desktop_file, &docs, error);
+ if (!command)
+ goto out;
+
+ if (!g_shell_parse_argv (command, &argc, &argv, error))
+ {
+ g_free (command);
+ goto out;
+ }
+ g_free (command);
+
+#if GTK_CHECK_VERSION (2, 12, 0)
+ startup_id = start_startup_notification (display, desktop_file,
+ argv[0], screen_num,
+ workspace, launch_time);
+ if (startup_id)
+ {
+ gchar *startup_id_env = g_strdup_printf ("DESKTOP_STARTUP_ID=%s",
+ startup_id);
+ env = array_putenv (env, startup_id_env);
+ g_free (startup_id_env);
+ }
+#else
+ startup_id = NULL;
+#endif /* GTK 2.12 */
+
+ if (env != NULL)
+ g_ptr_array_add (env, NULL);
+
+ current_success =
+ g_spawn_async_with_pipes (directory,
+ argv,
+ env ? (gchar **)(env->pdata) : NULL,
+ flags,
+ setup_func, setup_data,
+ ret_pid,
+ ret_stdin, ret_stdout, ret_stderr,
+ error);
+ g_strfreev (argv);
+
+ if (startup_id)
+ {
+#if GTK_CHECK_VERSION (2, 12, 0)
+ if (current_success)
+ {
+ set_startup_notification_timeout (display, startup_id);
+
+ if (ret_startup_id)
+ *ret_startup_id = startup_id;
+ else
+ g_free (startup_id);
+ }
+ else
+#endif /* GTK 2.12 */
+ g_free (startup_id);
+ }
+ else if (ret_startup_id)
+ *ret_startup_id = NULL;
+
+ if (current_success)
+ {
+ /* If we successfully launch any instances of the app, make
+ * sure we return TRUE and don't set @error.
+ */
+ success = TRUE;
+ error = NULL;
+
+ /* Also, only set the output params on the first one */
+ ret_pid = NULL;
+ ret_stdin = ret_stdout = ret_stderr = NULL;
+ ret_startup_id = NULL;
+ }
+ }
+ while (docs && current_success);
+
+ out:
+ if (env)
+ {
+ g_ptr_array_foreach (env, (GFunc)g_free, NULL);
+ g_ptr_array_free (env, TRUE);
+ }
+ free_document_list (translated_documents);
+
+ return success;
+}
+
+/**
+ * egg_desktop_file_launch:
+ * @desktop_file: an #EggDesktopFile
+ * @documents: a list of URIs or paths to documents to open
+ * @error: error pointer
+ * @...: additional options
+ *
+ * Launches @desktop_file with the given arguments. Additional options
+ * can be specified as follows:
+ *
+ * %EGG_DESKTOP_FILE_LAUNCH_CLEARENV: (no arguments)
+ * clears the environment in the child process
+ * %EGG_DESKTOP_FILE_LAUNCH_PUTENV: (gchar **variables)
+ * adds the NAME=VALUE strings in the given %NULL-terminated
+ * array to the child process's environment
+ * %EGG_DESKTOP_FILE_LAUNCH_SCREEN: (GdkScreen *screen)
+ * causes the application to be launched on the given screen
+ * %EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: (gint workspace)
+ * causes the application to be launched on the given workspace
+ * %EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: (gchar *dir)
+ * causes the application to be launched in the given directory
+ * %EGG_DESKTOP_FILE_LAUNCH_TIME: (guint32 launch_time)
+ * sets the "launch time" for the application. If the user
+ * interacts with another window after @launch_time but before
+ * the launched application creates its first window, the window
+ * manager may choose to not give focus to the new application.
+ * Passing 0 for @launch_time will explicitly request that the
+ * application not receive focus.
+ * %EGG_DESKTOP_FILE_LAUNCH_FLAGS (GSpawnFlags flags)
+ * Sets additional #GSpawnFlags to use. See g_spawn_async() for
+ * more details.
+ * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC (GSpawnChildSetupFunc, gpointer)
+ * Sets the child setup callback and the data to pass to it.
+ * (See g_spawn_async() for more details.)
+ *
+ * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID (GPid **pid)
+ * On a successful launch, sets *@pid to the PID of the launched
+ * application.
+ * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID (gchar **startup_id)
+ * On a successful launch, sets *@startup_id to the Startup
+ * Notification "startup id" of the launched application.
+ * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE (gint *fd)
+ * On a successful launch, sets *@fd to the file descriptor of
+ * a pipe connected to the application's stdin.
+ * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE (gint *fd)
+ * On a successful launch, sets *@fd to the file descriptor of
+ * a pipe connected to the application's stdout.
+ * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE (gint *fd)
+ * On a successful launch, sets *@fd to the file descriptor of
+ * a pipe connected to the application's stderr.
+ *
+ * The options should be terminated with a single %NULL.
+ *
+ * If @documents contains multiple documents, but
+ * egg_desktop_file_accepts_multiple() returns %FALSE for
+ * @desktop_file, then egg_desktop_file_launch() will actually launch
+ * multiple instances of the application. In that case, the return
+ * value (as well as any values passed via
+ * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, etc) will only reflect the
+ * first instance of the application that was launched (but the
+ * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC will be called for each
+ * instance).
+ *
+ * Return value: %TRUE if the application was successfully launched.
+ **/
+gboolean
+egg_desktop_file_launch (EggDesktopFile *desktop_file,
+ GSList *documents, GError **error,
+ ...)
+{
+ va_list args;
+ gboolean success;
+ EggDesktopFile *app_desktop_file;
+
+ switch (desktop_file->type)
+ {
+ case EGG_DESKTOP_FILE_TYPE_APPLICATION:
+ va_start (args, error);
+ success = egg_desktop_file_launchv (desktop_file, documents,
+ args, error);
+ va_end (args);
+ break;
+
+ case EGG_DESKTOP_FILE_TYPE_LINK:
+ if (documents)
+ {
+ g_set_error (error, EGG_DESKTOP_FILE_ERROR,
+ EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
+ _("Can't pass document URIs to a 'Type=Link' desktop entry"));
+ return FALSE;
+ }
+
+ if (!parse_link (desktop_file, &app_desktop_file, &documents, error))
+ return FALSE;
+
+ va_start (args, error);
+ success = egg_desktop_file_launchv (app_desktop_file, documents,
+ args, error);
+ va_end (args);
+
+ egg_desktop_file_free (app_desktop_file);
+ free_document_list (documents);
+ break;
+
+ case EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED:
+ case EGG_DESKTOP_FILE_TYPE_DIRECTORY:
+ default:
+ g_set_error (error, EGG_DESKTOP_FILE_ERROR,
+ EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
+ _("Not a launchable item"));
+ success = FALSE;
+ break;
+ }
+
+ return success;
+}
+
+GQuark
+egg_desktop_file_error_quark (void)
+{
+ return g_quark_from_static_string ("egg-desktop_file-error-quark");
+}
+
+G_LOCK_DEFINE_STATIC (egg_desktop_file);
+static EggDesktopFile *egg_desktop_file;
+
+static void
+egg_set_desktop_file_internal (const gchar *desktop_file_path,
+ gboolean set_defaults)
+{
+ GError *error = NULL;
+
+ G_LOCK (egg_desktop_file);
+ if (egg_desktop_file)
+ egg_desktop_file_free (egg_desktop_file);
+
+ egg_desktop_file = egg_desktop_file_new (desktop_file_path, &error);
+ if (error)
+ {
+ g_warning ("Could not load desktop file '%s': %s",
+ desktop_file_path, error->message);
+ g_error_free (error);
+ }
+
+ if (set_defaults && egg_desktop_file != NULL) {
+ /* Set localized application name and default window icon */
+ if (egg_desktop_file->name)
+ g_set_application_name (egg_desktop_file->name);
+ if (egg_desktop_file->icon)
+ {
+ if (g_path_is_absolute (egg_desktop_file->icon))
+ gtk_window_set_default_icon_from_file (egg_desktop_file->icon, NULL);
+ else
+ gtk_window_set_default_icon_name (egg_desktop_file->icon);
+ }
+ }
+
+ G_UNLOCK (egg_desktop_file);
+}
+
+/**
+ * egg_set_desktop_file:
+ * @desktop_file_path: path to the application's desktop file
+ *
+ * Creates an #EggDesktopFile for the application from the data at
+ * @desktop_file_path. This will also call g_set_application_name()
+ * with the localized application name from the desktop file, and
+ * gtk_window_set_default_icon_name() or
+ * gtk_window_set_default_icon_from_file() with the application's
+ * icon. Other code may use additional information from the desktop
+ * file.
+ * See egg_set_desktop_file_without_defaults() for a variant of this
+ * function that does not set the application name and default window
+ * icon.
+ *
+ * Note that for thread safety reasons, this function can only
+ * be called once, and is mutually exclusive with calling
+ * egg_set_desktop_file_without_defaults().
+ **/
+void
+egg_set_desktop_file (const gchar *desktop_file_path)
+{
+ egg_set_desktop_file_internal (desktop_file_path, TRUE);
+}
+
+/**
+ * egg_set_desktop_file_without_defaults:
+ * @desktop_file_path: path to the application's desktop file
+ *
+ * Creates an #EggDesktopFile for the application from the data at
+ * @desktop_file_path.
+ * See egg_set_desktop_file() for a variant of this function that
+ * sets the application name and default window icon from the information
+ * in the desktop file.
+ *
+ * Note that for thread safety reasons, this function can only
+ * be called once, and is mutually exclusive with calling
+ * egg_set_desktop_file().
+ **/
+void
+egg_set_desktop_file_without_defaults (const gchar *desktop_file_path)
+{
+ egg_set_desktop_file_internal (desktop_file_path, FALSE);
+}
+
+/**
+ * egg_get_desktop_file:
+ *
+ * Gets the application's #EggDesktopFile, as set by
+ * egg_set_desktop_file().
+ *
+ * Return value: the #EggDesktopFile, or %NULL if it hasn't been set.
+ **/
+EggDesktopFile *
+egg_get_desktop_file (void)
+{
+ EggDesktopFile *retval;
+
+ G_LOCK (egg_desktop_file);
+ retval = egg_desktop_file;
+ G_UNLOCK (egg_desktop_file);
+
+ return retval;
+}
diff --git a/smclient/eggdesktopfile.h b/smclient/eggdesktopfile.h
new file mode 100644
index 0000000000..2c99705d87
--- /dev/null
+++ b/smclient/eggdesktopfile.h
@@ -0,0 +1,158 @@
+/* eggdesktopfile.h - Freedesktop.Org Desktop Files
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place -
+ * Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_DESKTOP_FILE_H__
+#define __EGG_DESKTOP_FILE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct EggDesktopFile EggDesktopFile;
+
+typedef enum {
+ EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
+
+ EGG_DESKTOP_FILE_TYPE_APPLICATION,
+ EGG_DESKTOP_FILE_TYPE_LINK,
+ EGG_DESKTOP_FILE_TYPE_DIRECTORY
+} EggDesktopFileType;
+
+EggDesktopFile *egg_desktop_file_new (const gchar *desktop_file_path,
+ GError **error);
+
+EggDesktopFile *egg_desktop_file_new_from_data_dirs (const gchar *desktop_file_path,
+ GError **error);
+EggDesktopFile *egg_desktop_file_new_from_dirs (const gchar *desktop_file_path,
+ const gchar **search_dirs,
+ GError **error);
+EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file,
+ const gchar *source,
+ GError **error);
+
+void egg_desktop_file_free (EggDesktopFile *desktop_file);
+
+const gchar *egg_desktop_file_get_source (EggDesktopFile *desktop_file);
+
+EggDesktopFileType egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file);
+
+const gchar *egg_desktop_file_get_name (EggDesktopFile *desktop_file);
+const gchar *egg_desktop_file_get_icon (EggDesktopFile *desktop_file);
+
+gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file,
+ const gchar *desktop_environment);
+
+gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file);
+gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file);
+gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file);
+
+gchar *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
+ GSList *documents,
+ GError **error);
+
+gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file,
+ GSList *documents,
+ GError **error,
+ ...) G_GNUC_NULL_TERMINATED;
+
+typedef enum {
+ EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
+ EGG_DESKTOP_FILE_LAUNCH_PUTENV,
+ EGG_DESKTOP_FILE_LAUNCH_SCREEN,
+ EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
+ EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
+ EGG_DESKTOP_FILE_LAUNCH_TIME,
+ EGG_DESKTOP_FILE_LAUNCH_FLAGS,
+ EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
+ EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
+ EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
+ EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
+ EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
+ EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
+} EggDesktopFileLaunchOption;
+
+/* Standard Keys */
+#define EGG_DESKTOP_FILE_GROUP "Desktop Entry"
+
+#define EGG_DESKTOP_FILE_KEY_TYPE "Type"
+#define EGG_DESKTOP_FILE_KEY_VERSION "Version"
+#define EGG_DESKTOP_FILE_KEY_NAME "Name"
+#define EGG_DESKTOP_FILE_KEY_GENERIC_NAME "GenericName"
+#define EGG_DESKTOP_FILE_KEY_NO_DISPLAY "NoDisplay"
+#define EGG_DESKTOP_FILE_KEY_COMMENT "Comment"
+#define EGG_DESKTOP_FILE_KEY_ICON "Icon"
+#define EGG_DESKTOP_FILE_KEY_HIDDEN "Hidden"
+#define EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN "OnlyShowIn"
+#define EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN "NotShowIn"
+#define EGG_DESKTOP_FILE_KEY_TRY_EXEC "TryExec"
+#define EGG_DESKTOP_FILE_KEY_EXEC "Exec"
+#define EGG_DESKTOP_FILE_KEY_PATH "Path"
+#define EGG_DESKTOP_FILE_KEY_TERMINAL "Terminal"
+#define EGG_DESKTOP_FILE_KEY_MIME_TYPE "MimeType"
+#define EGG_DESKTOP_FILE_KEY_CATEGORIES "Categories"
+#define EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY "StartupNotify"
+#define EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS "StartupWMClass"
+#define EGG_DESKTOP_FILE_KEY_URL "URL"
+
+/* Accessors */
+gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file,
+ const gchar *key,
+ GError **error);
+gchar *egg_desktop_file_get_string (EggDesktopFile *desktop_file,
+ const gchar *key,
+ GError **error) G_GNUC_MALLOC;
+gchar *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
+ const gchar *key,
+ const gchar *locale,
+ GError **error) G_GNUC_MALLOC;
+gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
+ const gchar *key,
+ GError **error);
+gdouble egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
+ const gchar *key,
+ GError **error);
+gchar **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
+ const gchar *key,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+gchar **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
+ const gchar *key,
+ const gchar *locale,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+
+/* Errors */
+#define EGG_DESKTOP_FILE_ERROR egg_desktop_file_error_quark()
+
+GQuark egg_desktop_file_error_quark (void);
+
+typedef enum {
+ EGG_DESKTOP_FILE_ERROR_INVALID,
+ EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
+ EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
+} EggDesktopFileError;
+
+/* Global application desktop file */
+void egg_set_desktop_file (const gchar *desktop_file_path);
+void egg_set_desktop_file_without_defaults (const gchar *desktop_file_path);
+EggDesktopFile *egg_get_desktop_file (void);
+
+G_END_DECLS
+
+#endif /* __EGG_DESKTOP_FILE_H__ */
diff --git a/smclient/eggsmclient-private.h b/smclient/eggsmclient-private.h
new file mode 100644
index 0000000000..47fda7f2eb
--- /dev/null
+++ b/smclient/eggsmclient-private.h
@@ -0,0 +1,52 @@
+/* eggsmclient-private.h
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_SM_CLIENT_PRIVATE_H__
+#define __EGG_SM_CLIENT_PRIVATE_H__
+
+#include <gdkconfig.h>
+#include "eggsmclient.h"
+
+G_BEGIN_DECLS
+
+GKeyFile *egg_sm_client_save_state (EggSMClient *client);
+void egg_sm_client_quit_requested (EggSMClient *client);
+void egg_sm_client_quit_cancelled (EggSMClient *client);
+void egg_sm_client_quit (EggSMClient *client);
+
+#if defined (GDK_WINDOWING_X11)
+# ifdef EGG_SM_CLIENT_BACKEND_XSMP
+GType egg_sm_client_xsmp_get_type (void);
+EggSMClient *egg_sm_client_xsmp_new (void);
+# endif
+# ifdef EGG_SM_CLIENT_BACKEND_DBUS
+GType egg_sm_client_dbus_get_type (void);
+EggSMClient *egg_sm_client_dbus_new (void);
+# endif
+#elif defined (GDK_WINDOWING_WIN32)
+GType egg_sm_client_win32_get_type (void);
+EggSMClient *egg_sm_client_win32_new (void);
+#elif defined (GDK_WINDOWING_QUARTZ)
+GType egg_sm_client_osx_get_type (void);
+EggSMClient *egg_sm_client_osx_new (void);
+#endif
+
+G_END_DECLS
+
+#endif /* __EGG_SM_CLIENT_PRIVATE_H__ */
diff --git a/smclient/eggsmclient-win32.c b/smclient/eggsmclient-win32.c
new file mode 100644
index 0000000000..91a257154a
--- /dev/null
+++ b/smclient/eggsmclient-win32.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* EggSMClientWin32
+ *
+ * For details on the Windows XP logout process, see:
+ * http://msdn.microsoft.com/en-us/library/aa376876.aspx.
+ *
+ * Vista adds some new APIs which EggSMClient does not make use of; see
+ * http://msdn.microsoft.com/en-us/library/ms700677(VS.85).aspx
+ *
+ * When shutting down, Windows sends every top-level window a
+ * WM_QUERYENDSESSION event, which the application must respond to
+ * synchronously, saying whether or not it will quit. To avoid main
+ * loop re-entrancy problems (and to avoid having to muck about too
+ * much with the guts of the gdk-win32 main loop), we watch for this
+ * event in a separate thread, which then signals the main thread and
+ * waits for the main thread to handle the event. Since we don't want
+ * to require g_thread_init() to be called, we do this all using
+ * Windows-specific thread methods.
+ *
+ * After the application handles the WM_QUERYENDSESSION event,
+ * Windows then sends it a WM_ENDSESSION event with a TRUE or FALSE
+ * parameter indicating whether the session is or is not actually
+ * going to end now. We handle this from the other thread as well.
+ *
+ * As mentioned above, Vista introduces several additional new APIs
+ * that don't fit into the (current) EggSMClient API. Windows also has
+ * an entirely separate shutdown-notification scheme for non-GUI apps,
+ * which we also don't handle here.
+ */
+
+#include "config.h"
+
+#include "eggsmclient-private.h"
+#include <gdk/gdk.h>
+
+#define WIN32_LEAN_AND_MEAN
+#define UNICODE
+#include <windows.h>
+#include <process.h>
+
+#define EGG_TYPE_SM_CLIENT_WIN32 (egg_sm_client_win32_get_type ())
+#define EGG_SM_CLIENT_WIN32(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_WIN32, EggSMClientWin32))
+#define EGG_SM_CLIENT_WIN32_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_WIN32, EggSMClientWin32Class))
+#define EGG_IS_SM_CLIENT_WIN32(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_WIN32))
+#define EGG_IS_SM_CLIENT_WIN32_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_WIN32))
+#define EGG_SM_CLIENT_WIN32_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_WIN32, EggSMClientWin32Class))
+
+typedef struct _EggSMClientWin32 EggSMClientWin32;
+typedef struct _EggSMClientWin32Class EggSMClientWin32Class;
+
+struct _EggSMClientWin32 {
+ EggSMClient parent;
+
+ HANDLE message_event, response_event;
+
+ volatile GSourceFunc event;
+ volatile gboolean will_quit;
+};
+
+struct _EggSMClientWin32Class
+{
+ EggSMClientClass parent_class;
+
+};
+
+static void sm_client_win32_startup (EggSMClient *client,
+ const char *client_id);
+static void sm_client_win32_will_quit (EggSMClient *client,
+ gboolean will_quit);
+static gboolean sm_client_win32_end_session (EggSMClient *client,
+ EggSMClientEndStyle style,
+ gboolean request_confirmation);
+
+static GSource *g_win32_handle_source_add (HANDLE handle, GSourceFunc callback,
+ gpointer user_data);
+static gboolean got_message (gpointer user_data);
+static void sm_client_thread (gpointer data);
+
+G_DEFINE_TYPE (EggSMClientWin32, egg_sm_client_win32, EGG_TYPE_SM_CLIENT)
+
+static void
+egg_sm_client_win32_init (EggSMClientWin32 *win32)
+{
+ ;
+}
+
+static void
+egg_sm_client_win32_class_init (EggSMClientWin32Class *klass)
+{
+ EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
+
+ sm_client_class->startup = sm_client_win32_startup;
+ sm_client_class->will_quit = sm_client_win32_will_quit;
+ sm_client_class->end_session = sm_client_win32_end_session;
+}
+
+EggSMClient *
+egg_sm_client_win32_new (void)
+{
+ return g_object_new (EGG_TYPE_SM_CLIENT_WIN32, NULL);
+}
+
+static void
+sm_client_win32_startup (EggSMClient *client,
+ const char *client_id)
+{
+ EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
+
+ win32->message_event = CreateEvent (NULL, FALSE, FALSE, NULL);
+ win32->response_event = CreateEvent (NULL, FALSE, FALSE, NULL);
+ g_win32_handle_source_add (win32->message_event, got_message, win32);
+ _beginthread (sm_client_thread, 0, client);
+}
+
+static void
+sm_client_win32_will_quit (EggSMClient *client,
+ gboolean will_quit)
+{
+ EggSMClientWin32 *win32 = (EggSMClientWin32 *)client;
+
+ win32->will_quit = will_quit;
+ SetEvent (win32->response_event);
+}
+
+static gboolean
+sm_client_win32_end_session (EggSMClient *client,
+ EggSMClientEndStyle style,
+ gboolean request_confirmation)
+{
+ UINT uFlags = EWX_LOGOFF;
+
+ switch (style)
+ {
+ case EGG_SM_CLIENT_END_SESSION_DEFAULT:
+ case EGG_SM_CLIENT_LOGOUT:
+ uFlags = EWX_LOGOFF;
+ break;
+ case EGG_SM_CLIENT_REBOOT:
+ uFlags = EWX_REBOOT;
+ break;
+ case EGG_SM_CLIENT_SHUTDOWN:
+ uFlags = EWX_POWEROFF;
+ break;
+ }
+
+ /* There's no way to make ExitWindowsEx() show a logout dialog, so
+ * we ignore @request_confirmation.
+ */
+
+#ifdef SHTDN_REASON_FLAG_PLANNED
+ ExitWindowsEx (uFlags, SHTDN_REASON_FLAG_PLANNED);
+#else
+ ExitWindowsEx (uFlags, 0);
+#endif
+
+ return TRUE;
+}
+
+
+/* callbacks from logout-listener thread */
+
+static gboolean
+emit_quit_requested (gpointer smclient)
+{
+ gdk_threads_enter ();
+ egg_sm_client_quit_requested (smclient);
+ gdk_threads_leave ();
+
+ return FALSE;
+}
+
+static gboolean
+emit_quit (gpointer smclient)
+{
+ EggSMClientWin32 *win32 = smclient;
+
+ gdk_threads_enter ();
+ egg_sm_client_quit (smclient);
+ gdk_threads_leave ();
+
+ SetEvent (win32->response_event);
+ return FALSE;
+}
+
+static gboolean
+emit_quit_cancelled (gpointer smclient)
+{
+ EggSMClientWin32 *win32 = smclient;
+
+ gdk_threads_enter ();
+ egg_sm_client_quit_cancelled (smclient);
+ gdk_threads_leave ();
+
+ SetEvent (win32->response_event);
+ return FALSE;
+}
+
+static gboolean
+got_message (gpointer smclient)
+{
+ EggSMClientWin32 *win32 = smclient;
+
+ win32->event (win32);
+ return TRUE;
+}
+
+/* Windows HANDLE GSource */
+
+typedef struct {
+ GSource source;
+ GPollFD pollfd;
+} GWin32HandleSource;
+
+static gboolean
+g_win32_handle_source_prepare (GSource *source, gint *timeout)
+{
+ *timeout = -1;
+ return FALSE;
+}
+
+static gboolean
+g_win32_handle_source_check (GSource *source)
+{
+ GWin32HandleSource *hsource = (GWin32HandleSource *)source;
+
+ return hsource->pollfd.revents;
+}
+
+static gboolean
+g_win32_handle_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
+{
+ return (*callback) (user_data);
+}
+
+static void
+g_win32_handle_source_finalize (GSource *source)
+{
+ ;
+}
+
+GSourceFuncs g_win32_handle_source_funcs = {
+ g_win32_handle_source_prepare,
+ g_win32_handle_source_check,
+ g_win32_handle_source_dispatch,
+ g_win32_handle_source_finalize
+};
+
+static GSource *
+g_win32_handle_source_add (HANDLE handle, GSourceFunc callback, gpointer user_data)
+{
+ GWin32HandleSource *hsource;
+ GSource *source;
+
+ source = g_source_new (&g_win32_handle_source_funcs, sizeof (GWin32HandleSource));
+ hsource = (GWin32HandleSource *)source;
+ hsource->pollfd.fd = (int)handle;
+ hsource->pollfd.events = G_IO_IN;
+ hsource->pollfd.revents = 0;
+ g_source_add_poll (source, &hsource->pollfd);
+
+ g_source_set_callback (source, callback, user_data, NULL);
+ g_source_attach (source, NULL);
+ return source;
+}
+
+/* logout-listener thread */
+
+LRESULT CALLBACK
+sm_client_win32_window_procedure (HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ EggSMClientWin32 *win32 =
+ (EggSMClientWin32 *)GetWindowLongPtr (hwnd, GWLP_USERDATA);
+
+ switch (message)
+ {
+ case WM_QUERYENDSESSION:
+ win32->event = emit_quit_requested;
+ SetEvent (win32->message_event);
+
+ WaitForSingleObject (win32->response_event, INFINITE);
+ return win32->will_quit;
+
+ case WM_ENDSESSION:
+ if (wParam)
+ {
+ /* The session is ending */
+ win32->event = emit_quit;
+ }
+ else
+ {
+ /* Nope, the session *isn't* ending */
+ win32->event = emit_quit_cancelled;
+ }
+
+ SetEvent (win32->message_event);
+ WaitForSingleObject (win32->response_event, INFINITE);
+
+ return 0;
+
+ default:
+ return DefWindowProc (hwnd, message, wParam, lParam);
+ }
+}
+
+static void
+sm_client_thread (gpointer smclient)
+{
+ HINSTANCE instance;
+ WNDCLASSEXW wcl;
+ ATOM klass;
+ HWND window;
+ MSG msg;
+
+ instance = GetModuleHandle (NULL);
+
+ memset (&wcl, 0, sizeof (WNDCLASSEX));
+ wcl.cbSize = sizeof (WNDCLASSEX);
+ wcl.lpfnWndProc = sm_client_win32_window_procedure;
+ wcl.hInstance = instance;
+ wcl.lpszClassName = L"EggSmClientWindow";
+ klass = RegisterClassEx (&wcl);
+
+ window = CreateWindowEx (0, MAKEINTRESOURCE (klass),
+ L"EggSmClientWindow", 0,
+ 10, 10, 50, 50, GetDesktopWindow (),
+ NULL, instance, NULL);
+ SetWindowLongPtr (window, GWLP_USERDATA, (LONG_PTR)smclient);
+
+ /* main loop */
+ while (GetMessage (&msg, NULL, 0, 0))
+ DispatchMessage (&msg);
+}
diff --git a/smclient/eggsmclient-xsmp.c b/smclient/eggsmclient-xsmp.c
new file mode 100644
index 0000000000..e709f6dd6d
--- /dev/null
+++ b/smclient/eggsmclient-xsmp.c
@@ -0,0 +1,1370 @@
+/*
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * Inspired by various other pieces of code including GsmClient (C)
+ * 2001 Havoc Pennington, GnomeClient (C) 1998 Carsten Schaar, and twm
+ * session code (C) 1998 The Open Group.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "eggsmclient.h"
+#include "eggsmclient-private.h"
+
+#include "eggdesktopfile.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <X11/SM/SMlib.h>
+
+#include <gdk/gdk.h>
+
+#define EGG_TYPE_SM_CLIENT_XSMP (egg_sm_client_xsmp_get_type ())
+#define EGG_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMP))
+#define EGG_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass))
+#define EGG_IS_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_XSMP))
+#define EGG_IS_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_XSMP))
+#define EGG_SM_CLIENT_XSMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass))
+
+typedef struct _EggSMClientXSMP EggSMClientXSMP;
+typedef struct _EggSMClientXSMPClass EggSMClientXSMPClass;
+
+/* These mostly correspond to the similarly-named states in section
+ * 9.1 of the XSMP spec. Some of the states there aren't represented
+ * here, because we don't need them. SHUTDOWN_CANCELLED is slightly
+ * different from the spec; we use it when the client is IDLE after a
+ * ShutdownCancelled message, but the application is still interacting
+ * and doesn't know the shutdown has been cancelled yet.
+ */
+typedef enum
+{
+ XSMP_STATE_IDLE,
+ XSMP_STATE_SAVE_YOURSELF,
+ XSMP_STATE_INTERACT_REQUEST,
+ XSMP_STATE_INTERACT,
+ XSMP_STATE_SAVE_YOURSELF_DONE,
+ XSMP_STATE_SHUTDOWN_CANCELLED,
+ XSMP_STATE_CONNECTION_CLOSED
+} EggSMClientXSMPState;
+
+static const gchar *state_names[] = {
+ "idle",
+ "save-yourself",
+ "interact-request",
+ "interact",
+ "save-yourself-done",
+ "shutdown-cancelled",
+ "connection-closed"
+};
+
+#define EGG_SM_CLIENT_XSMP_STATE(xsmp) (state_names[(xsmp)->state])
+
+struct _EggSMClientXSMP
+{
+ EggSMClient parent;
+
+ SmcConn connection;
+ gchar *client_id;
+
+ EggSMClientXSMPState state;
+ gchar **restart_command;
+ gboolean set_restart_command;
+ gint restart_style;
+
+ guint idle;
+
+ /* Current SaveYourself state */
+ guint expecting_initial_save_yourself : 1;
+ guint need_save_state : 1;
+ guint need_quit_requested : 1;
+ guint interact_errors : 1;
+ guint shutting_down : 1;
+
+ /* Todo list */
+ guint waiting_to_set_initial_properties : 1;
+ guint waiting_to_emit_quit : 1;
+ guint waiting_to_emit_quit_cancelled : 1;
+ guint waiting_to_save_myself : 1;
+
+};
+
+struct _EggSMClientXSMPClass
+{
+ EggSMClientClass parent_class;
+
+};
+
+static void sm_client_xsmp_startup (EggSMClient *client,
+ const gchar *client_id);
+static void sm_client_xsmp_set_restart_command (EggSMClient *client,
+ gint argc,
+ const gchar **argv);
+static void sm_client_xsmp_will_quit (EggSMClient *client,
+ gboolean will_quit);
+static gboolean sm_client_xsmp_end_session (EggSMClient *client,
+ EggSMClientEndStyle style,
+ gboolean request_confirmation);
+
+static void xsmp_save_yourself (SmcConn smc_conn,
+ SmPointer client_data,
+ gint save_style,
+ Bool shutdown,
+ gint interact_style,
+ Bool fast);
+static void xsmp_die (SmcConn smc_conn,
+ SmPointer client_data);
+static void xsmp_save_complete (SmcConn smc_conn,
+ SmPointer client_data);
+static void xsmp_shutdown_cancelled (SmcConn smc_conn,
+ SmPointer client_data);
+static void xsmp_interact (SmcConn smc_conn,
+ SmPointer client_data);
+
+static SmProp *array_prop (const gchar *name,
+ ...);
+static SmProp *ptrarray_prop (const gchar *name,
+ GPtrArray *values);
+static SmProp *string_prop (const gchar *name,
+ const gchar *value);
+static SmProp *card8_prop (const gchar *name,
+ guchar value);
+
+static void set_properties (EggSMClientXSMP *xsmp, ...);
+static void delete_properties (EggSMClientXSMP *xsmp, ...);
+
+static GPtrArray *generate_command (gchar **restart_command,
+ const gchar *client_id,
+ const gchar *state_file);
+
+static void save_state (EggSMClientXSMP *xsmp);
+static void do_save_yourself (EggSMClientXSMP *xsmp);
+static void update_pending_events (EggSMClientXSMP *xsmp);
+
+static void ice_init (void);
+static gboolean process_ice_messages (IceConn ice_conn);
+static void smc_error_handler (SmcConn smc_conn,
+ Bool swap,
+ gint offending_minor_opcode,
+ unsigned long offending_sequence,
+ gint error_class,
+ gint severity,
+ SmPointer values);
+
+G_DEFINE_TYPE (EggSMClientXSMP, egg_sm_client_xsmp, EGG_TYPE_SM_CLIENT)
+
+static void
+egg_sm_client_xsmp_init (EggSMClientXSMP *xsmp)
+{
+ xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
+ xsmp->connection = NULL;
+ xsmp->restart_style = SmRestartIfRunning;
+}
+
+static void
+egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass)
+{
+ EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
+
+ sm_client_class->startup = sm_client_xsmp_startup;
+ sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command;
+ sm_client_class->will_quit = sm_client_xsmp_will_quit;
+ sm_client_class->end_session = sm_client_xsmp_end_session;
+}
+
+EggSMClient *
+egg_sm_client_xsmp_new (void)
+{
+ if (!g_getenv ("SESSION_MANAGER"))
+ return NULL;
+
+ return g_object_new (EGG_TYPE_SM_CLIENT_XSMP, NULL);
+}
+
+static gboolean
+sm_client_xsmp_set_initial_properties (gpointer user_data)
+{
+ EggSMClientXSMP *xsmp = user_data;
+ EggDesktopFile *desktop_file;
+ GPtrArray *clone, *restart;
+ gchar pid_str[64];
+
+ if (xsmp->idle)
+ {
+ g_source_remove (xsmp->idle);
+ xsmp->idle = 0;
+ }
+ xsmp->waiting_to_set_initial_properties = FALSE;
+
+ if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART)
+ xsmp->restart_style = SmRestartNever;
+
+ /* Parse info out of desktop file */
+ desktop_file = egg_get_desktop_file ();
+ if (desktop_file)
+ {
+ GError *err = NULL;
+ gchar *cmdline, **argv;
+ gint argc;
+
+ if (xsmp->restart_style == SmRestartIfRunning)
+ {
+ if (egg_desktop_file_get_boolean (desktop_file,
+ "X-GNOME-AutoRestart", NULL))
+ xsmp->restart_style = SmRestartImmediately;
+ }
+
+ if (!xsmp->set_restart_command)
+ {
+ cmdline = egg_desktop_file_parse_exec (desktop_file, NULL, &err);
+ if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err))
+ {
+ egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp),
+ argc, (const gchar **)argv);
+ g_strfreev (argv);
+ }
+ else
+ {
+ g_warning ("Could not parse Exec line in desktop file: %s",
+ err->message);
+ g_error_free (err);
+ }
+ g_free (cmdline);
+ }
+ }
+
+ if (!xsmp->set_restart_command)
+ xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1);
+
+ clone = generate_command (xsmp->restart_command, NULL, NULL);
+ restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL);
+
+ g_debug ("Setting initial properties");
+
+ /* Program, CloneCommand, RestartCommand, and UserID are required.
+ * ProcessID isn't required, but the SM may be able to do something
+ * useful with it.
+ */
+ g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ());
+ set_properties (xsmp,
+ string_prop (SmProgram, g_get_prgname ()),
+ ptrarray_prop (SmCloneCommand, clone),
+ ptrarray_prop (SmRestartCommand, restart),
+ string_prop (SmUserID, g_get_user_name ()),
+ string_prop (SmProcessID, pid_str),
+ card8_prop (SmRestartStyleHint, xsmp->restart_style),
+ NULL);
+ g_ptr_array_free (clone, TRUE);
+ g_ptr_array_free (restart, TRUE);
+
+ if (desktop_file)
+ {
+ set_properties (xsmp,
+ string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)),
+ NULL);
+ }
+
+ update_pending_events (xsmp);
+ return FALSE;
+}
+
+/* This gets called from two different places: xsmp_die() (when the
+ * server asks us to disconnect) and process_ice_messages() (when the
+ * server disconnects unexpectedly).
+ */
+static void
+sm_client_xsmp_disconnect (EggSMClientXSMP *xsmp)
+{
+ SmcConn connection;
+
+ if (!xsmp->connection)
+ return;
+
+ g_debug ("Disconnecting");
+
+ connection = xsmp->connection;
+ xsmp->connection = NULL;
+ SmcCloseConnection (connection, 0, NULL);
+ xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
+
+ xsmp->waiting_to_save_myself = FALSE;
+ update_pending_events (xsmp);
+}
+
+static void
+sm_client_xsmp_startup (EggSMClient *client,
+ const gchar *client_id)
+{
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+ SmcCallbacks callbacks;
+ gchar *ret_client_id;
+ gchar error_string_ret[256];
+
+ xsmp->client_id = g_strdup (client_id);
+
+ ice_init ();
+ SmcSetErrorHandler (smc_error_handler);
+
+ callbacks.save_yourself.callback = xsmp_save_yourself;
+ callbacks.die.callback = xsmp_die;
+ callbacks.save_complete.callback = xsmp_save_complete;
+ callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
+
+ callbacks.save_yourself.client_data = xsmp;
+ callbacks.die.client_data = xsmp;
+ callbacks.save_complete.client_data = xsmp;
+ callbacks.shutdown_cancelled.client_data = xsmp;
+
+ client_id = NULL;
+ error_string_ret[0] = '\0';
+ xsmp->connection =
+ SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor,
+ SmcSaveYourselfProcMask | SmcDieProcMask |
+ SmcSaveCompleteProcMask |
+ SmcShutdownCancelledProcMask,
+ &callbacks,
+ xsmp->client_id, &ret_client_id,
+ sizeof (error_string_ret), error_string_ret);
+
+ if (!xsmp->connection)
+ {
+ g_warning ("Failed to connect to the session manager: %s\n",
+ error_string_ret[0] ?
+ error_string_ret : "no error message given");
+ xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
+ return;
+ }
+
+ /* We expect a pointless initial SaveYourself if either (a) we
+ * didn't have an initial client ID, or (b) we DID have an initial
+ * client ID, but the server rejected it and gave us a new one.
+ */
+ if (!xsmp->client_id ||
+ (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0))
+ xsmp->expecting_initial_save_yourself = TRUE;
+
+ if (ret_client_id)
+ {
+ g_free (xsmp->client_id);
+ xsmp->client_id = g_strdup (ret_client_id);
+ free (ret_client_id);
+
+ gdk_threads_enter ();
+ gdk_set_sm_client_id (xsmp->client_id);
+ gdk_threads_leave ();
+
+ g_debug ("Got client ID \"%s\"", xsmp->client_id);
+ }
+
+ xsmp->state = XSMP_STATE_IDLE;
+
+ /* Do not set the initial properties until we reach the main loop,
+ * so that the application has a chance to call
+ * egg_set_desktop_file(). (This may also help the session manager
+ * have a better idea of when the application is fully up and
+ * running.)
+ */
+ xsmp->waiting_to_set_initial_properties = TRUE;
+ xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client);
+}
+
+static void
+sm_client_xsmp_set_restart_command (EggSMClient *client,
+ gint argc,
+ const gchar **argv)
+{
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+ gint i;
+
+ g_strfreev (xsmp->restart_command);
+
+ xsmp->restart_command = g_new (gchar *, argc + 1);
+ for (i = 0; i < argc; i++)
+ xsmp->restart_command[i] = g_strdup (argv[i]);
+ xsmp->restart_command[i] = NULL;
+
+ xsmp->set_restart_command = TRUE;
+}
+
+static void
+sm_client_xsmp_will_quit (EggSMClient *client,
+ gboolean will_quit)
+{
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+
+ if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED)
+ {
+ /* The session manager has already exited! Schedule a quit
+ * signal.
+ */
+ xsmp->waiting_to_emit_quit = TRUE;
+ update_pending_events (xsmp);
+ return;
+ }
+ else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
+ {
+ /* We received a ShutdownCancelled message while the application
+ * was interacting; Schedule a quit_cancelled signal.
+ */
+ xsmp->waiting_to_emit_quit_cancelled = TRUE;
+ update_pending_events (xsmp);
+ return;
+ }
+
+ g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT);
+
+ g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True");
+ SmcInteractDone (xsmp->connection, !will_quit);
+
+ if (will_quit && xsmp->need_save_state)
+ save_state (xsmp);
+
+ g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False");
+ SmcSaveYourselfDone (xsmp->connection, will_quit);
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
+}
+
+static gboolean
+sm_client_xsmp_end_session (EggSMClient *client,
+ EggSMClientEndStyle style,
+ gboolean request_confirmation)
+{
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+ gint save_type;
+
+ /* To end the session via XSMP, we have to send a
+ * SaveYourselfRequest. We aren't allowed to do that if anything
+ * else is going on, but we don't want to expose this fact to the
+ * application. So we do our best to patch things up here...
+ *
+ * In the worst case, this method might block for some length of
+ * time in process_ice_messages, but the only time that code path is
+ * honestly likely to get hit is if the application tries to end the
+ * session as the very first thing it does, in which case it
+ * probably won't actually block anyway. It's not worth gunking up
+ * the API to try to deal nicely with the other 0.01% of cases where
+ * this happens.
+ */
+
+ while (xsmp->state != XSMP_STATE_IDLE ||
+ xsmp->expecting_initial_save_yourself)
+ {
+ /* If we're already shutting down, we don't need to do anything. */
+ if (xsmp->shutting_down)
+ return TRUE;
+
+ switch (xsmp->state)
+ {
+ case XSMP_STATE_CONNECTION_CLOSED:
+ return FALSE;
+
+ case XSMP_STATE_SAVE_YOURSELF:
+ /* Trying to log out from the save_state callback? Whatever.
+ * Abort the save_state.
+ */
+ SmcSaveYourselfDone (xsmp->connection, FALSE);
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
+ break;
+
+ case XSMP_STATE_INTERACT_REQUEST:
+ case XSMP_STATE_INTERACT:
+ case XSMP_STATE_SHUTDOWN_CANCELLED:
+ /* Already in a shutdown-related state, just ignore
+ * the new shutdown request...
+ */
+ return TRUE;
+
+ case XSMP_STATE_IDLE:
+ if (xsmp->waiting_to_set_initial_properties)
+ sm_client_xsmp_set_initial_properties (xsmp);
+
+ if (!xsmp->expecting_initial_save_yourself)
+ break;
+ /* else fall through */
+
+ case XSMP_STATE_SAVE_YOURSELF_DONE:
+ /* We need to wait for some response from the server.*/
+ process_ice_messages (SmcGetIceConnection (xsmp->connection));
+ break;
+
+ default:
+ /* Hm... shouldn't happen */
+ return FALSE;
+ }
+ }
+
+ /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and
+ * the user chooses to save the session. But gnome-session will do
+ * the wrong thing if we pass SmSaveBoth and the user chooses NOT to
+ * save the session... Sigh.
+ */
+ if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session"))
+ save_type = SmSaveBoth;
+ else
+ save_type = SmSaveGlobal;
+
+ g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : "");
+ SmcRequestSaveYourself (xsmp->connection,
+ save_type,
+ True, /* shutdown */
+ SmInteractStyleAny,
+ !request_confirmation, /* fast */
+ True /* global */);
+ return TRUE;
+}
+
+static gboolean
+idle_do_pending_events (gpointer data)
+{
+ EggSMClientXSMP *xsmp = data;
+ EggSMClient *client = data;
+
+ gdk_threads_enter ();
+
+ xsmp->idle = 0;
+
+ if (xsmp->waiting_to_emit_quit)
+ {
+ xsmp->waiting_to_emit_quit = FALSE;
+ egg_sm_client_quit (client);
+ goto out;
+ }
+
+ if (xsmp->waiting_to_emit_quit_cancelled)
+ {
+ xsmp->waiting_to_emit_quit_cancelled = FALSE;
+ egg_sm_client_quit_cancelled (client);
+ xsmp->state = XSMP_STATE_IDLE;
+ }
+
+ if (xsmp->waiting_to_save_myself)
+ {
+ xsmp->waiting_to_save_myself = FALSE;
+ do_save_yourself (xsmp);
+ }
+
+ out:
+ gdk_threads_leave ();
+ return FALSE;
+}
+
+static void
+update_pending_events (EggSMClientXSMP *xsmp)
+{
+ gboolean want_idle =
+ xsmp->waiting_to_emit_quit ||
+ xsmp->waiting_to_emit_quit_cancelled ||
+ xsmp->waiting_to_save_myself;
+
+ if (want_idle)
+ {
+ if (xsmp->idle == 0)
+ xsmp->idle = g_idle_add (idle_do_pending_events, xsmp);
+ }
+ else
+ {
+ if (xsmp->idle != 0)
+ g_source_remove (xsmp->idle);
+ xsmp->idle = 0;
+ }
+}
+
+static void
+fix_broken_state (EggSMClientXSMP *xsmp, const gchar *message,
+ gboolean send_interact_done,
+ gboolean send_save_yourself_done)
+{
+ g_warning ("Received XSMP %s message in state %s: client or server error",
+ message, EGG_SM_CLIENT_XSMP_STATE (xsmp));
+
+ /* Forget any pending SaveYourself plans we had */
+ xsmp->waiting_to_save_myself = FALSE;
+ update_pending_events (xsmp);
+
+ if (send_interact_done)
+ SmcInteractDone (xsmp->connection, False);
+ if (send_save_yourself_done)
+ SmcSaveYourselfDone (xsmp->connection, True);
+
+ xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE;
+}
+
+/* SM callbacks */
+
+static void
+xsmp_save_yourself (SmcConn smc_conn,
+ SmPointer client_data,
+ gint save_type,
+ Bool shutdown,
+ gint interact_style,
+ Bool fast)
+{
+ EggSMClientXSMP *xsmp = client_data;
+ gboolean wants_quit_requested;
+
+ g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s",
+ save_type == SmSaveLocal ? "SmSaveLocal" :
+ save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth",
+ shutdown ? "Shutdown" : "!Shutdown",
+ interact_style == SmInteractStyleAny ? "SmInteractStyleAny" :
+ interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" :
+ "SmInteractStyleNone", fast ? "Fast" : "!Fast",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
+
+ if (xsmp->state != XSMP_STATE_IDLE &&
+ xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED)
+ {
+ fix_broken_state (xsmp, "SaveYourself", FALSE, TRUE);
+ return;
+ }
+
+ if (xsmp->waiting_to_set_initial_properties)
+ sm_client_xsmp_set_initial_properties (xsmp);
+
+ /* If this is the initial SaveYourself, ignore it; we've already set
+ * properties and there's no reason to actually save state too.
+ */
+ if (xsmp->expecting_initial_save_yourself)
+ {
+ xsmp->expecting_initial_save_yourself = FALSE;
+
+ if (save_type == SmSaveLocal &&
+ interact_style == SmInteractStyleNone &&
+ !shutdown && !fast)
+ {
+ g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself");
+ SmcSaveYourselfDone (xsmp->connection, True);
+ /* As explained in the comment at the end of
+ * do_save_yourself(), SAVE_YOURSELF_DONE is the correct
+ * state here, not IDLE.
+ */
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
+ return;
+ }
+ else
+ g_warning ("First SaveYourself was not the expected one!");
+ }
+
+ /* Even ignoring the "fast" flag completely, there are still 18
+ * different combinations of save_type, shutdown and interact_style.
+ * We interpret them as follows:
+ *
+ * Type Shutdown Interact Interpretation
+ * G F A/E/N do nothing (1)
+ * G T N do nothing (1)*
+ * G T A/E quit_requested (2)
+ * L/B F A/E/N save_state (3)
+ * L/B T N save_state (3)*
+ * L/B T A/E quit_requested, then save_state (4)
+ *
+ * 1. Do nothing, because the SM asked us to do something
+ * uninteresting (save open files, but then don't quit
+ * afterward) or rude (save open files without asking the user
+ * for confirmation).
+ *
+ * 2. Request interaction and then emit ::quit_requested. This
+ * perhaps isn't quite correct for the SmInteractStyleErrors
+ * case, but we don't care.
+ *
+ * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these
+ * rows essentially get demoted to SmSaveLocal, because their
+ * Global halves correspond to "do nothing".
+ *
+ * 4. Request interaction, emit ::quit_requested, and then emit
+ * ::save_state after interacting. This is the SmSaveBoth
+ * equivalent of #2, but we also promote SmSaveLocal shutdown
+ * SaveYourselfs to SmSaveBoth here, because we want to give
+ * the user a chance to save open files before quitting.
+ *
+ * (* It would be nice if we could do something useful when the
+ * session manager sends a SaveYourself with shutdown True and
+ * SmInteractStyleNone. But we can't, so we just pretend it didn't
+ * even tell us it was shutting down. The docs for ::quit mention
+ * that it might not always be preceded by ::quit_requested.)
+ */
+
+ /* As an optimization, we don't actually request interaction and
+ * emit ::quit_requested if the application isn't listening to the
+ * signal.
+ */
+ wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT), 0, FALSE);
+
+ xsmp->need_save_state = (save_type != SmSaveGlobal);
+ xsmp->need_quit_requested = (shutdown && wants_quit_requested &&
+ interact_style != SmInteractStyleNone);
+ xsmp->interact_errors = (interact_style == SmInteractStyleErrors);
+
+ xsmp->shutting_down = shutdown;
+
+ do_save_yourself (xsmp);
+}
+
+static void
+do_save_yourself (EggSMClientXSMP *xsmp)
+{
+ if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
+ {
+ /* The SM cancelled a previous SaveYourself, but we haven't yet
+ * had a chance to tell the application, so we can't start
+ * processing this SaveYourself yet.
+ */
+ xsmp->waiting_to_save_myself = TRUE;
+ update_pending_events (xsmp);
+ return;
+ }
+
+ if (xsmp->need_quit_requested)
+ {
+ xsmp->state = XSMP_STATE_INTERACT_REQUEST;
+
+ g_debug ("Sending InteractRequest(%s)",
+ xsmp->interact_errors ? "Error" : "Normal");
+ SmcInteractRequest (xsmp->connection,
+ xsmp->interact_errors ? SmDialogError : SmDialogNormal,
+ xsmp_interact,
+ xsmp);
+ return;
+ }
+
+ if (xsmp->need_save_state)
+ {
+ save_state (xsmp);
+
+ /* Though unlikely, the client could have been disconnected
+ * while the application was saving its state.
+ */
+ if (!xsmp->connection)
+ return;
+ }
+
+ g_debug ("Sending SaveYourselfDone(True)");
+ SmcSaveYourselfDone (xsmp->connection, True);
+
+ /* The client state diagram in the XSMP spec says that after a
+ * non-shutdown SaveYourself, we go directly back to "idle". But
+ * everything else in both the XSMP spec and the libSM docs
+ * disagrees.
+ */
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
+}
+
+static void
+save_state (EggSMClientXSMP *xsmp)
+{
+ GKeyFile *state_file;
+ gchar *state_file_path, *data;
+ EggDesktopFile *desktop_file;
+ GPtrArray *restart;
+ gint offset, fd;
+
+ /* We set xsmp->state before emitting save_state, but our caller is
+ * responsible for setting it back afterward.
+ */
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF;
+
+ state_file = egg_sm_client_save_state ((EggSMClient *)xsmp);
+ if (!state_file)
+ {
+ restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL);
+ set_properties (xsmp,
+ ptrarray_prop (SmRestartCommand, restart),
+ NULL);
+ g_ptr_array_free (restart, TRUE);
+ delete_properties (xsmp, SmDiscardCommand, NULL);
+ return;
+ }
+
+ desktop_file = egg_get_desktop_file ();
+ if (desktop_file)
+ {
+ GKeyFile *merged_file;
+ gchar *desktop_file_path;
+
+ merged_file = g_key_file_new ();
+ desktop_file_path =
+ g_filename_from_uri (egg_desktop_file_get_source (desktop_file),
+ NULL, NULL);
+ if (desktop_file_path &&
+ g_key_file_load_from_file (merged_file, desktop_file_path,
+ G_KEY_FILE_KEEP_COMMENTS |
+ G_KEY_FILE_KEEP_TRANSLATIONS, NULL))
+ {
+ guint g, k, i;
+ gchar **groups, **keys, *value, *exec;
+
+ groups = g_key_file_get_groups (state_file, NULL);
+ for (g = 0; groups[g]; g++)
+ {
+ keys = g_key_file_get_keys (state_file, groups[g], NULL, NULL);
+ for (k = 0; keys[k]; k++)
+ {
+ value = g_key_file_get_value (state_file, groups[g],
+ keys[k], NULL);
+ if (value)
+ {
+ g_key_file_set_value (merged_file, groups[g],
+ keys[k], value);
+ g_free (value);
+ }
+ }
+ g_strfreev (keys);
+ }
+ g_strfreev (groups);
+
+ g_key_file_free (state_file);
+ state_file = merged_file;
+
+ /* Update Exec key using "--sm-client-state-file %k" */
+ restart = generate_command (xsmp->restart_command,
+ NULL, "%k");
+ for (i = 0; i < restart->len; i++)
+ restart->pdata[i] = g_shell_quote (restart->pdata[i]);
+ g_ptr_array_add (restart, NULL);
+ exec = g_strjoinv (" ", (gchar **)restart->pdata);
+ g_strfreev ((gchar **)restart->pdata);
+ g_ptr_array_free (restart, FALSE);
+
+ g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_EXEC,
+ exec);
+ g_free (exec);
+ }
+ else
+ desktop_file = NULL;
+
+ g_free (desktop_file_path);
+ }
+
+ /* Now write state_file to disk. (We can't use mktemp(), because
+ * that requires the filename to end with "XXXXXX", and we want
+ * it to end with ".desktop".)
+ */
+
+ data = g_key_file_to_data (state_file, NULL, NULL);
+ g_key_file_free (state_file);
+
+ offset = 0;
+ while (1)
+ {
+ state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s",
+ g_get_user_config_dir (),
+ G_DIR_SEPARATOR, G_DIR_SEPARATOR,
+ g_get_prgname (),
+ (long)time (NULL) + offset,
+ desktop_file ? "desktop" : "state");
+
+ fd = open (state_file_path, O_WRONLY | O_CREAT | O_EXCL, 0644);
+ if (fd == -1)
+ {
+ if (errno == EEXIST)
+ {
+ offset++;
+ g_free (state_file_path);
+ continue;
+ }
+ else if (errno == ENOTDIR || errno == ENOENT)
+ {
+ gchar *sep = strrchr (state_file_path, G_DIR_SEPARATOR);
+
+ *sep = '\0';
+ if (g_mkdir_with_parents (state_file_path, 0755) != 0)
+ {
+ g_warning ("Could not create directory '%s'",
+ state_file_path);
+ g_free (state_file_path);
+ state_file_path = NULL;
+ break;
+ }
+
+ continue;
+ }
+
+ g_warning ("Could not create file '%s': %s",
+ state_file_path, g_strerror (errno));
+ g_free (state_file_path);
+ state_file_path = NULL;
+ break;
+ }
+
+ close (fd);
+ g_file_set_contents (state_file_path, data, -1, NULL);
+ break;
+ }
+ g_free (data);
+
+ restart = generate_command (xsmp->restart_command, xsmp->client_id,
+ state_file_path);
+ set_properties (xsmp,
+ ptrarray_prop (SmRestartCommand, restart),
+ NULL);
+ g_ptr_array_free (restart, TRUE);
+
+ if (state_file_path)
+ {
+ set_properties (xsmp,
+ array_prop (SmDiscardCommand,
+ "/bin/rm", "-rf", state_file_path,
+ NULL),
+ NULL);
+ g_free (state_file_path);
+ }
+}
+
+static void
+xsmp_interact (SmcConn smc_conn,
+ SmPointer client_data)
+{
+ EggSMClientXSMP *xsmp = client_data;
+ EggSMClient *client = client_data;
+
+ g_debug ("Received Interact message in state %s",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
+
+ if (xsmp->state != XSMP_STATE_INTERACT_REQUEST)
+ {
+ fix_broken_state (xsmp, "Interact", TRUE, TRUE);
+ return;
+ }
+
+ xsmp->state = XSMP_STATE_INTERACT;
+ egg_sm_client_quit_requested (client);
+}
+
+static void
+xsmp_die (SmcConn smc_conn,
+ SmPointer client_data)
+{
+ EggSMClientXSMP *xsmp = client_data;
+ EggSMClient *client = client_data;
+
+ g_debug ("Received Die message in state %s",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
+
+ sm_client_xsmp_disconnect (xsmp);
+ egg_sm_client_quit (client);
+}
+
+static void
+xsmp_save_complete (SmcConn smc_conn,
+ SmPointer client_data)
+{
+ EggSMClientXSMP *xsmp = client_data;
+
+ g_debug ("Received SaveComplete message in state %s",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
+
+ if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
+ xsmp->state = XSMP_STATE_IDLE;
+ else
+ fix_broken_state (xsmp, "SaveComplete", FALSE, FALSE);
+}
+
+static void
+xsmp_shutdown_cancelled (SmcConn smc_conn,
+ SmPointer client_data)
+{
+ EggSMClientXSMP *xsmp = client_data;
+ EggSMClient *client = client_data;
+
+ g_debug ("Received ShutdownCancelled message in state %s",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
+
+ xsmp->shutting_down = FALSE;
+
+ if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
+ {
+ /* We've finished interacting and now the SM has agreed to
+ * cancel the shutdown.
+ */
+ xsmp->state = XSMP_STATE_IDLE;
+ egg_sm_client_quit_cancelled (client);
+ }
+ else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
+ {
+ /* Hm... ok, so we got a shutdown SaveYourself, which got
+ * cancelled, but the application was still interacting, so we
+ * didn't tell it yet, and then *another* SaveYourself arrived,
+ * which we must still be waiting to tell the app about, except
+ * that now that SaveYourself has been cancelled too! Dizzy yet?
+ */
+ xsmp->waiting_to_save_myself = FALSE;
+ update_pending_events (xsmp);
+ }
+ else
+ {
+ g_debug ("Sending SaveYourselfDone(False)");
+ SmcSaveYourselfDone (xsmp->connection, False);
+
+ if (xsmp->state == XSMP_STATE_INTERACT)
+ {
+ /* The application is currently interacting, so we can't
+ * tell it about the cancellation yet; we will wait until
+ * after it calls egg_sm_client_will_quit().
+ */
+ xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED;
+ }
+ else
+ {
+ /* The shutdown was cancelled before the application got a
+ * chance to interact.
+ */
+ xsmp->state = XSMP_STATE_IDLE;
+ }
+ }
+}
+
+/* Utilities */
+
+/* Create a restart/clone/Exec command based on @restart_command.
+ * If @client_id is non-%NULL, add "--sm-client-id @client_id".
+ * If @state_file is non-%NULL, add "--sm-client-state-file @state_file".
+ *
+ * None of the input strings are g_strdup()ed; the caller must keep
+ * them around until it is done with the returned GPtrArray, and must
+ * then free the array, but not its contents.
+ */
+static GPtrArray *
+generate_command (gchar **restart_command, const gchar *client_id,
+ const gchar *state_file)
+{
+ GPtrArray *cmd;
+ gint i;
+
+ cmd = g_ptr_array_new ();
+ g_ptr_array_add (cmd, restart_command[0]);
+
+ if (client_id)
+ {
+ g_ptr_array_add (cmd, (gchar *)"--sm-client-id");
+ g_ptr_array_add (cmd, (gchar *)client_id);
+ }
+
+ if (state_file)
+ {
+ g_ptr_array_add (cmd, (gchar *)"--sm-client-state-file");
+ g_ptr_array_add (cmd, (gchar *)state_file);
+ }
+
+ for (i = 1; restart_command[i]; i++)
+ g_ptr_array_add (cmd, restart_command[i]);
+
+ return cmd;
+}
+
+/* Takes a NULL-terminated list of SmProp * values, created by
+ * array_prop, ptrarray_prop, string_prop, card8_prop, sets them, and
+ * frees them.
+ */
+static void
+set_properties (EggSMClientXSMP *xsmp, ...)
+{
+ GPtrArray *props;
+ SmProp *prop;
+ va_list ap;
+ guint i;
+
+ props = g_ptr_array_new ();
+
+ va_start (ap, xsmp);
+ while ((prop = va_arg (ap, SmProp *)))
+ g_ptr_array_add (props, prop);
+ va_end (ap);
+
+ if (xsmp->connection)
+ {
+ SmcSetProperties (xsmp->connection, props->len,
+ (SmProp **)props->pdata);
+ }
+
+ for (i = 0; i < props->len; i++)
+ {
+ prop = props->pdata[i];
+ g_free (prop->vals);
+ g_free (prop);
+ }
+ g_ptr_array_free (props, TRUE);
+}
+
+/* Takes a NULL-terminated list of property names and deletes them. */
+static void
+delete_properties (EggSMClientXSMP *xsmp, ...)
+{
+ GPtrArray *props;
+ gchar *prop;
+ va_list ap;
+
+ if (!xsmp->connection)
+ return;
+
+ props = g_ptr_array_new ();
+
+ va_start (ap, xsmp);
+ while ((prop = va_arg (ap, gchar *)))
+ g_ptr_array_add (props, prop);
+ va_end (ap);
+
+ SmcDeleteProperties (xsmp->connection, props->len,
+ (gchar **)props->pdata);
+
+ g_ptr_array_free (props, TRUE);
+}
+
+/* Takes an array of strings and creates a LISTofARRAY8 property. The
+ * strings are neither dupped nor freed; they need to remain valid
+ * until you're done with the SmProp.
+ */
+static SmProp *
+array_prop (const gchar *name, ...)
+{
+ SmProp *prop;
+ SmPropValue pv;
+ GArray *vals;
+ gchar *value;
+ va_list ap;
+
+ prop = g_new (SmProp, 1);
+ prop->name = (gchar *)name;
+ prop->type = (gchar *)SmLISTofARRAY8;
+
+ vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue));
+
+ va_start (ap, name);
+ while ((value = va_arg (ap, gchar *)))
+ {
+ pv.length = strlen (value);
+ pv.value = value;
+ g_array_append_val (vals, pv);
+ }
+
+ prop->num_vals = vals->len;
+ prop->vals = (SmPropValue *)vals->data;
+
+ g_array_free (vals, FALSE);
+
+ return prop;
+}
+
+/* Takes a GPtrArray of strings and creates a LISTofARRAY8 property.
+ * The array contents are neither dupped nor freed; they need to
+ * remain valid until you're done with the SmProp.
+ */
+static SmProp *
+ptrarray_prop (const gchar *name, GPtrArray *values)
+{
+ SmProp *prop;
+ SmPropValue pv;
+ GArray *vals;
+ guint i;
+
+ prop = g_new (SmProp, 1);
+ prop->name = (gchar *)name;
+ prop->type = (gchar *)SmLISTofARRAY8;
+
+ vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue));
+
+ for (i = 0; i < values->len; i++)
+ {
+ pv.length = strlen (values->pdata[i]);
+ pv.value = values->pdata[i];
+ g_array_append_val (vals, pv);
+ }
+
+ prop->num_vals = vals->len;
+ prop->vals = (SmPropValue *)vals->data;
+
+ g_array_free (vals, FALSE);
+
+ return prop;
+}
+
+/* Takes a string and creates an ARRAY8 property. The string is
+ * neither dupped nor freed; it needs to remain valid until you're
+ * done with the SmProp.
+ */
+static SmProp *
+string_prop (const gchar *name, const gchar *value)
+{
+ SmProp *prop;
+
+ prop = g_new (SmProp, 1);
+ prop->name = (gchar *)name;
+ prop->type = (gchar *)SmARRAY8;
+
+ prop->num_vals = 1;
+ prop->vals = g_new (SmPropValue, 1);
+
+ prop->vals[0].length = strlen (value);
+ prop->vals[0].value = (gchar *)value;
+
+ return prop;
+}
+
+/* Takes a gchar and creates a CARD8 property. */
+static SmProp *
+card8_prop (const gchar *name, guchar value)
+{
+ SmProp *prop;
+ gchar *card8val;
+
+ /* To avoid having to allocate and free prop->vals[0], we cheat and
+ * make vals a 2-element-long array and then use the second element
+ * to store value.
+ */
+
+ prop = g_new (SmProp, 1);
+ prop->name = (gchar *)name;
+ prop->type = (gchar *)SmCARD8;
+
+ prop->num_vals = 1;
+ prop->vals = g_new (SmPropValue, 2);
+ card8val = (gchar *)(&prop->vals[1]);
+ card8val[0] = value;
+
+ prop->vals[0].length = 1;
+ prop->vals[0].value = card8val;
+
+ return prop;
+}
+
+/* ICE code. This makes no effort to play nice with anyone else trying
+ * to use libICE. Fortunately, no one uses libICE for anything other
+ * than SM. (DCOP uses ICE, but it has its own private copy of
+ * libICE.)
+ *
+ * When this moves to gtk, it will need to be cleverer, to avoid
+ * tripping over old apps that use GnomeClient or that use libSM
+ * directly.
+ */
+
+#include <X11/ICE/ICElib.h>
+#include <fcntl.h>
+
+static void ice_error_handler (IceConn ice_conn,
+ Bool swap,
+ gint offending_minor_opcode,
+ unsigned long offending_sequence,
+ gint error_class,
+ gint severity,
+ IcePointer values);
+static void ice_io_error_handler (IceConn ice_conn);
+static void ice_connection_watch (IceConn ice_conn,
+ IcePointer client_data,
+ Bool opening,
+ IcePointer *watch_data);
+
+static void
+ice_init (void)
+{
+ IceSetIOErrorHandler (ice_io_error_handler);
+ IceSetErrorHandler (ice_error_handler);
+ IceAddConnectionWatch (ice_connection_watch, NULL);
+}
+
+static gboolean
+process_ice_messages (IceConn ice_conn)
+{
+ IceProcessMessagesStatus status;
+
+ gdk_threads_enter ();
+ status = IceProcessMessages (ice_conn, NULL, NULL);
+ gdk_threads_leave ();
+
+ switch (status)
+ {
+ case IceProcessMessagesSuccess:
+ return TRUE;
+
+ case IceProcessMessagesIOError:
+ sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn));
+ return FALSE;
+
+ case IceProcessMessagesConnectionClosed:
+ return FALSE;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static gboolean
+ice_iochannel_watch (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer client_data)
+{
+ return process_ice_messages (client_data);
+}
+
+static void
+ice_connection_watch (IceConn ice_conn,
+ IcePointer client_data,
+ Bool opening,
+ IcePointer *watch_data)
+{
+ guint watch_id;
+
+ if (opening)
+ {
+ GIOChannel *channel;
+ gint fd = IceConnectionNumber (ice_conn);
+
+ fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
+ channel = g_io_channel_unix_new (fd);
+ watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR,
+ ice_iochannel_watch, ice_conn);
+ g_io_channel_unref (channel);
+
+ *watch_data = GUINT_TO_POINTER (watch_id);
+ }
+ else
+ {
+ watch_id = GPOINTER_TO_UINT (*watch_data);
+ g_source_remove (watch_id);
+ }
+}
+
+static void
+ice_error_handler (IceConn ice_conn,
+ Bool swap,
+ gint offending_minor_opcode,
+ unsigned long offending_sequence,
+ gint error_class,
+ gint severity,
+ IcePointer values)
+{
+ /* Do nothing */
+}
+
+static void
+ice_io_error_handler (IceConn ice_conn)
+{
+ /* Do nothing */
+}
+
+static void
+smc_error_handler (SmcConn smc_conn,
+ Bool swap,
+ gint offending_minor_opcode,
+ unsigned long offending_sequence,
+ gint error_class,
+ gint severity,
+ SmPointer values)
+{
+ /* Do nothing */
+}
diff --git a/smclient/eggsmclient.c b/smclient/eggsmclient.c
new file mode 100644
index 0000000000..e17d98c3a9
--- /dev/null
+++ b/smclient/eggsmclient.c
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include "eggsmclient.h"
+#include "eggsmclient-private.h"
+
+static void egg_sm_client_debug_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data);
+
+enum {
+ SAVE_STATE,
+ QUIT_REQUESTED,
+ QUIT_CANCELLED,
+ QUIT,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+struct _EggSMClientPrivate {
+ GKeyFile *state_file;
+};
+
+#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate))
+
+G_DEFINE_TYPE (EggSMClient, egg_sm_client, G_TYPE_OBJECT)
+
+static EggSMClient *global_client;
+static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL;
+
+static void
+egg_sm_client_init (EggSMClient *client)
+{
+ ;
+}
+
+static void
+egg_sm_client_class_init (EggSMClientClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (EggSMClientPrivate));
+
+ /**
+ * EggSMClient::save_state:
+ * @client: the client
+ * @state_file: a #GKeyFile to save state information into
+ *
+ * Emitted when the session manager has requested that the
+ * application save information about its current state. The
+ * application should save its state into @state_file, and then the
+ * session manager may then restart the application in a future
+ * session and tell it to initialize itself from that state.
+ *
+ * You should not save any data into @state_file's "start group"
+ * (ie, the %NULL group). Instead, applications should save their
+ * data into groups with names that start with the application name,
+ * and libraries that connect to this signal should save their data
+ * into groups with names that start with the library name.
+ *
+ * Alternatively, rather than (or in addition to) using @state_file,
+ * the application can save its state by calling
+ * egg_sm_client_set_restart_command() during the processing of this
+ * signal (eg, to include a list of files to open).
+ **/
+ signals[SAVE_STATE] =
+ g_signal_new ("save_state",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggSMClientClass, save_state),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1, G_TYPE_POINTER);
+
+ /**
+ * EggSMClient::quit_requested:
+ * @client: the client
+ *
+ * Emitted when the session manager requests that the application
+ * exit (generally because the user is logging out). The application
+ * should decide whether or not it is willing to quit (perhaps after
+ * asking the user what to do with documents that have unsaved
+ * changes) and then call egg_sm_client_will_quit(), passing %TRUE
+ * or %FALSE to give its answer to the session manager. (It does not
+ * need to give an answer before returning from the signal handler;
+ * it can interact with the user asynchronously and then give its
+ * answer later on.) If the application does not connect to this
+ * signal, then #EggSMClient will automatically return %TRUE on its
+ * behalf.
+ *
+ * The application should not save its session state as part of
+ * handling this signal; if the user has requested that the session
+ * be saved when logging out, then ::save_state will be emitted
+ * separately.
+ *
+ * If the application agrees to quit, it should then wait for either
+ * the ::quit_cancelled or ::quit signals to be emitted.
+ **/
+ signals[QUIT_REQUESTED] =
+ g_signal_new ("quit_requested",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * EggSMClient::quit_cancelled:
+ * @client: the client
+ *
+ * Emitted when the session manager decides to cancel a logout after
+ * the application has already agreed to quit. After receiving this
+ * signal, the application can go back to what it was doing before
+ * receiving the ::quit_requested signal.
+ **/
+ signals[QUIT_CANCELLED] =
+ g_signal_new ("quit_cancelled",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * EggSMClient::quit:
+ * @client: the client
+ *
+ * Emitted when the session manager wants the application to quit
+ * (generally because the user is logging out). The application
+ * should exit as soon as possible after receiving this signal; if
+ * it does not, the session manager may choose to forcibly kill it.
+ *
+ * Normally a GUI application would only be sent a ::quit if it
+ * agreed to quit in response to a ::quit_requested signal. However,
+ * this is not guaranteed; in some situations the session manager
+ * may decide to end the session without giving applications a
+ * chance to object.
+ **/
+ signals[QUIT] =
+ g_signal_new ("quit",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggSMClientClass, quit),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+}
+
+static gboolean sm_client_disable = FALSE;
+static gchar *sm_client_state_file = NULL;
+static gchar *sm_client_id = NULL;
+static gchar *sm_config_prefix = NULL;
+
+static gboolean
+sm_client_post_parse_func (GOptionContext *context,
+ GOptionGroup *group,
+ gpointer data,
+ GError **error)
+{
+ EggSMClient *client = egg_sm_client_get ();
+
+ if (sm_client_id == NULL)
+ {
+ const gchar *desktop_autostart_id;
+
+ desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+
+ if (desktop_autostart_id != NULL)
+ sm_client_id = g_strdup (desktop_autostart_id);
+ }
+
+ /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
+ * use the same client id. */
+ g_unsetenv ("DESKTOP_AUTOSTART_ID");
+
+ if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
+ EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
+ return TRUE;
+}
+
+/**
+ * egg_sm_client_get_option_group:
+ *
+ * Creates a %GOptionGroup containing the session-management-related
+ * options. You should add this group to the application's
+ * %GOptionContext if you want to use #EggSMClient.
+ *
+ * Return value: the %GOptionGroup
+ **/
+GOptionGroup *
+egg_sm_client_get_option_group (void)
+{
+ const GOptionEntry entries[] = {
+ { "sm-client-disable", 0, 0,
+ G_OPTION_ARG_NONE, &sm_client_disable,
+ N_("Disable connection to session manager"), NULL },
+ { "sm-client-state-file", 0, 0,
+ G_OPTION_ARG_FILENAME, &sm_client_state_file,
+ N_("Specify file containing saved configuration"), N_("FILE") },
+ { "sm-client-id", 0, 0,
+ G_OPTION_ARG_STRING, &sm_client_id,
+ N_("Specify session management ID"), N_("ID") },
+ /* GnomeClient compatibility option */
+ { "sm-disable", 0, G_OPTION_FLAG_HIDDEN,
+ G_OPTION_ARG_NONE, &sm_client_disable,
+ NULL, NULL },
+ /* GnomeClient compatibility option. This is a dummy option that only
+ * exists so that sessions saved by apps with GnomeClient can be restored
+ * later when they've switched to EggSMClient. See bug #575308.
+ */
+ { "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN,
+ G_OPTION_ARG_STRING, &sm_config_prefix,
+ NULL, NULL },
+ { NULL }
+ };
+ GOptionGroup *group;
+
+ /* Use our own debug handler for the "EggSMClient" domain. */
+ g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
+ egg_sm_client_debug_handler, NULL);
+
+ group = g_option_group_new ("sm-client",
+ _("Session management options:"),
+ _("Show session management options"),
+ NULL, NULL);
+ g_option_group_add_entries (group, entries);
+ g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
+
+ return group;
+}
+
+/**
+ * egg_sm_client_set_mode:
+ * @mode: an #EggSMClient mode
+ *
+ * Sets the "mode" of #EggSMClient as follows:
+ *
+ * %EGG_SM_CLIENT_MODE_DISABLED: Session management is completely
+ * disabled. The application will not even connect to the session
+ * manager. (egg_sm_client_get() will still return an #EggSMClient,
+ * but it will just be a dummy object.)
+ *
+ * %EGG_SM_CLIENT_MODE_NO_RESTART: The application will connect to
+ * the session manager (and thus will receive notification when the
+ * user is logging out, etc), but will request to not be
+ * automatically restarted with saved state in future sessions.
+ *
+ * %EGG_SM_CLIENT_MODE_NORMAL: The default. #EggSMCLient will
+ * function normally.
+ *
+ * This must be called before the application's main loop begins.
+ **/
+void
+egg_sm_client_set_mode (EggSMClientMode mode)
+{
+ global_client_mode = mode;
+}
+
+/**
+ * egg_sm_client_get_mode:
+ *
+ * Gets the global #EggSMClientMode. See egg_sm_client_set_mode()
+ * for details.
+ *
+ * Return value: the global #EggSMClientMode
+ **/
+EggSMClientMode
+egg_sm_client_get_mode (void)
+{
+ return global_client_mode;
+}
+
+/**
+ * egg_sm_client_get:
+ *
+ * Returns the master #EggSMClient for the application.
+ *
+ * On platforms that support saved sessions (ie, POSIX/X11), the
+ * application will only request to be restarted by the session
+ * manager if you call egg_set_desktop_file() to set an application
+ * desktop file. In particular, if the desktop file contains the key
+ * "X
+ *
+ * Return value: the master #EggSMClient.
+ **/
+EggSMClient *
+egg_sm_client_get (void)
+{
+ if (!global_client)
+ {
+ if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
+ !sm_client_disable)
+ {
+#if defined (GDK_WINDOWING_WIN32)
+ global_client = egg_sm_client_win32_new ();
+#elif defined (GDK_WINDOWING_QUARTZ)
+ global_client = egg_sm_client_osx_new ();
+#else
+ /* If both D-Bus and XSMP are compiled in, try XSMP first
+ * (since it supports state saving) and fall back to D-Bus
+ * if XSMP isn't available.
+ */
+# ifdef EGG_SM_CLIENT_BACKEND_XSMP
+ global_client = egg_sm_client_xsmp_new ();
+# endif
+# ifdef EGG_SM_CLIENT_BACKEND_DBUS
+ if (!global_client)
+ global_client = egg_sm_client_dbus_new ();
+# endif
+#endif
+ }
+
+ /* Fallback: create a dummy client, so that callers don't have
+ * to worry about a %NULL return value.
+ */
+ if (!global_client)
+ global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
+ }
+
+ return global_client;
+}
+
+/**
+ * egg_sm_client_is_resumed:
+ * @client: the client
+ *
+ * Checks whether or not the current session has been resumed from
+ * a previous saved session. If so, the application should call
+ * egg_sm_client_get_state_file() and restore its state from the
+ * returned #GKeyFile.
+ *
+ * Return value: %TRUE if the session has been resumed
+ **/
+gboolean
+egg_sm_client_is_resumed (EggSMClient *client)
+{
+ g_return_val_if_fail (client == global_client, FALSE);
+
+ return sm_client_state_file != NULL;
+}
+
+/**
+ * egg_sm_client_get_state_file:
+ * @client: the client
+ *
+ * If the application was resumed by the session manager, this will
+ * return the #GKeyFile containing its state from the previous
+ * session.
+ *
+ * Note that other libraries and #EggSMClient itself may also store
+ * state in the key file, so if you call egg_sm_client_get_groups(),
+ * on it, the return value will likely include groups that you did not
+ * put there yourself. (It is also not guaranteed that the first
+ * group created by the application will still be the "start group"
+ * when it is resumed.)
+ *
+ * Return value: the #GKeyFile containing the application's earlier
+ * state, or %NULL on error. You should not free this key file; it
+ * is owned by @client.
+ **/
+GKeyFile *
+egg_sm_client_get_state_file (EggSMClient *client)
+{
+ EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
+ gchar *state_file_path;
+ GError *err = NULL;
+
+ g_return_val_if_fail (client == global_client, NULL);
+
+ if (!sm_client_state_file)
+ return NULL;
+ if (priv->state_file)
+ return priv->state_file;
+
+ if (!strncmp (sm_client_state_file, "file://", 7))
+ state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
+ else
+ state_file_path = g_strdup (sm_client_state_file);
+
+ priv->state_file = g_key_file_new ();
+ if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err))
+ {
+ g_warning ("Could not load SM state file '%s': %s",
+ sm_client_state_file, err->message);
+ g_clear_error (&err);
+ g_key_file_free (priv->state_file);
+ priv->state_file = NULL;
+ }
+
+ g_free (state_file_path);
+ return priv->state_file;
+}
+
+/**
+ * egg_sm_client_set_restart_command:
+ * @client: the client
+ * @argc: the length of @argv
+ * @argv: argument vector
+ *
+ * Sets the command used to restart @client if it does not have a
+ * .desktop file that can be used to find its restart command.
+ *
+ * This can also be used when handling the ::save_state signal, to
+ * save the current state via an updated command line. (Eg, providing
+ * a list of filenames to open when the application is resumed.)
+ **/
+void
+egg_sm_client_set_restart_command (EggSMClient *client,
+ gint argc,
+ const gchar **argv)
+{
+ g_return_if_fail (EGG_IS_SM_CLIENT (client));
+
+ if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command)
+ EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv);
+}
+
+/**
+ * egg_sm_client_will_quit:
+ * @client: the client
+ * @will_quit: whether or not the application is willing to quit
+ *
+ * This MUST be called in response to the ::quit_requested signal, to
+ * indicate whether or not the application is willing to quit. The
+ * application may call it either directly from the signal handler, or
+ * at some later point (eg, after asynchronously interacting with the
+ * user).
+ *
+ * If the application does not connect to ::quit_requested,
+ * #EggSMClient will call this method on its behalf (passing %TRUE
+ * for @will_quit).
+ *
+ * After calling this method, the application should wait to receive
+ * either ::quit_cancelled or ::quit.
+ **/
+void
+egg_sm_client_will_quit (EggSMClient *client,
+ gboolean will_quit)
+{
+ g_return_if_fail (EGG_IS_SM_CLIENT (client));
+
+ if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit)
+ EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit);
+}
+
+/**
+ * egg_sm_client_end_session:
+ * @style: a hint at how to end the session
+ * @request_confirmation: whether or not the user should get a chance
+ * to confirm the action
+ *
+ * Requests that the session manager end the current session. @style
+ * indicates how the session should be ended, and
+ * @request_confirmation indicates whether or not the user should be
+ * given a chance to confirm the logout/reboot/shutdown. Both of these
+ * flags are merely hints though; the session manager may choose to
+ * ignore them.
+ *
+ * Return value: %TRUE if the request was sent; %FALSE if it could not
+ * be (eg, because it could not connect to the session manager).
+ **/
+gboolean
+egg_sm_client_end_session (EggSMClientEndStyle style,
+ gboolean request_confirmation)
+{
+ EggSMClient *client = egg_sm_client_get ();
+
+ g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE);
+
+ if (EGG_SM_CLIENT_GET_CLASS (client)->end_session)
+ {
+ return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
+ request_confirmation);
+ }
+ else
+ return FALSE;
+}
+
+/* Signal-emitting callbacks from platform-specific code */
+
+GKeyFile *
+egg_sm_client_save_state (EggSMClient *client)
+{
+ GKeyFile *state_file;
+ gchar *group;
+
+ g_return_val_if_fail (client == global_client, NULL);
+
+ state_file = g_key_file_new ();
+
+ g_debug ("Emitting save_state");
+ g_signal_emit (client, signals[SAVE_STATE], 0, state_file);
+ g_debug ("Done emitting save_state");
+
+ group = g_key_file_get_start_group (state_file);
+ if (group)
+ {
+ g_free (group);
+ return state_file;
+ }
+ else
+ {
+ g_key_file_free (state_file);
+ return NULL;
+ }
+}
+
+void
+egg_sm_client_quit_requested (EggSMClient *client)
+{
+ g_return_if_fail (client == global_client);
+
+ if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE))
+ {
+ g_debug ("Not emitting quit_requested because no one is listening");
+ egg_sm_client_will_quit (client, TRUE);
+ return;
+ }
+
+ g_debug ("Emitting quit_requested");
+ g_signal_emit (client, signals[QUIT_REQUESTED], 0);
+ g_debug ("Done emitting quit_requested");
+}
+
+void
+egg_sm_client_quit_cancelled (EggSMClient *client)
+{
+ g_return_if_fail (client == global_client);
+
+ g_debug ("Emitting quit_cancelled");
+ g_signal_emit (client, signals[QUIT_CANCELLED], 0);
+ g_debug ("Done emitting quit_cancelled");
+}
+
+void
+egg_sm_client_quit (EggSMClient *client)
+{
+ g_return_if_fail (client == global_client);
+
+ g_debug ("Emitting quit");
+ g_signal_emit (client, signals[QUIT], 0);
+ g_debug ("Done emitting quit");
+
+ /* FIXME: should we just call gtk_main_quit() here? */
+}
+
+static void
+egg_sm_client_debug_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ static gint debug = -1;
+
+ if (debug < 0)
+ debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
+
+ if (debug)
+ g_log_default_handler (log_domain, log_level, message, NULL);
+}
diff --git a/smclient/eggsmclient.h b/smclient/eggsmclient.h
new file mode 100644
index 0000000000..5efc486df0
--- /dev/null
+++ b/smclient/eggsmclient.h
@@ -0,0 +1,116 @@
+/* eggsmclient.h
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_SM_CLIENT_H__
+#define __EGG_SM_CLIENT_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_SM_CLIENT (egg_sm_client_get_type ())
+#define EGG_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT, EggSMClient))
+#define EGG_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT, EggSMClientClass))
+#define EGG_IS_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT))
+#define EGG_IS_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT))
+#define EGG_SM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT, EggSMClientClass))
+
+typedef struct _EggSMClient EggSMClient;
+typedef struct _EggSMClientClass EggSMClientClass;
+typedef struct _EggSMClientPrivate EggSMClientPrivate;
+
+typedef enum {
+ EGG_SM_CLIENT_END_SESSION_DEFAULT,
+ EGG_SM_CLIENT_LOGOUT,
+ EGG_SM_CLIENT_REBOOT,
+ EGG_SM_CLIENT_SHUTDOWN
+} EggSMClientEndStyle;
+
+typedef enum {
+ EGG_SM_CLIENT_MODE_DISABLED,
+ EGG_SM_CLIENT_MODE_NO_RESTART,
+ EGG_SM_CLIENT_MODE_NORMAL
+} EggSMClientMode;
+
+struct _EggSMClient
+{
+ GObject parent;
+
+};
+
+struct _EggSMClientClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*save_state) (EggSMClient *client,
+ GKeyFile *state_file);
+
+ void (*quit_requested) (EggSMClient *client);
+ void (*quit_cancelled) (EggSMClient *client);
+ void (*quit) (EggSMClient *client);
+
+ /* virtual methods */
+ void (*startup) (EggSMClient *client,
+ const gchar *client_id);
+ void (*set_restart_command) (EggSMClient *client,
+ gint argc,
+ const gchar **argv);
+ void (*will_quit) (EggSMClient *client,
+ gboolean will_quit);
+ gboolean (*end_session) (EggSMClient *client,
+ EggSMClientEndStyle style,
+ gboolean request_confirmation);
+
+ /* Padding for future expansion */
+ void (*_egg_reserved1) (void);
+ void (*_egg_reserved2) (void);
+ void (*_egg_reserved3) (void);
+ void (*_egg_reserved4) (void);
+};
+
+GType egg_sm_client_get_type (void) G_GNUC_CONST;
+
+GOptionGroup *egg_sm_client_get_option_group (void);
+
+/* Initialization */
+void egg_sm_client_set_mode (EggSMClientMode mode);
+EggSMClientMode egg_sm_client_get_mode (void);
+EggSMClient *egg_sm_client_get (void);
+
+/* Resuming a saved session */
+gboolean egg_sm_client_is_resumed (EggSMClient *client);
+GKeyFile *egg_sm_client_get_state_file (EggSMClient *client);
+
+/* Alternate means of saving state */
+void egg_sm_client_set_restart_command (EggSMClient *client,
+ gint argc,
+ const gchar **argv);
+
+/* Handling "quit_requested" signal */
+void egg_sm_client_will_quit (EggSMClient *client,
+ gboolean will_quit);
+
+/* Initiate a logout/reboot/shutdown */
+gboolean egg_sm_client_end_session (EggSMClientEndStyle style,
+ gboolean request_confirmation);
+
+G_END_DECLS
+
+#endif /* __EGG_SM_CLIENT_H__ */
diff --git a/smime/gui/Makefile.am b/smime/gui/Makefile.am
index 16b907e70c..a6a595ea93 100644
--- a/smime/gui/Makefile.am
+++ b/smime/gui/Makefile.am
@@ -6,6 +6,8 @@ AM_CPPFLAGS = \
-I$(top_builddir)/smime/lib \
-I$(top_srcdir)/shell \
-I$(top_builddir)/shell \
+ -I$(top_srcdir)/widgets \
+ -I$(top_builddir)/widgets \
-DEVOLUTION_DATADIR=\""$(datadir)"\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
@@ -33,10 +35,11 @@ libevolution_smime_la_SOURCES = \
component.h
-libevolution_smime_la_LIBADD = \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/shell/libeshell.la \
- $(top_builddir)/smime/lib/libessmime.la \
+libevolution_smime_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/shell/libeshell.la \
+ $(top_builddir)/smime/lib/libessmime.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
$(CERT_UI_LIBS)
libevolution_smime_la_LDFLAGS = $(NO_UNDEFINED)
diff --git a/smime/gui/certificate-manager.c b/smime/gui/certificate-manager.c
index 8026ba1472..030946e3cb 100644
--- a/smime/gui/certificate-manager.c
+++ b/smime/gui/certificate-manager.c
@@ -32,7 +32,6 @@
#include <glib/gi18n.h>
#include <glade/glade.h>
-#include "evolution-config-control.h"
#include "ca-trust-dialog.h"
#include "cert-trust-dialog.h"
#include "certificate-manager.h"
@@ -49,7 +48,9 @@
#include <pkcs11.h>
#include <pk11func.h>
+#include "shell/e-shell.h"
#include "e-util/e-util-private.h"
+#include "widgets/misc/e-preferences-window.h"
typedef struct {
GladeXML *gui;
@@ -987,13 +988,16 @@ populate_ui (CertificateManagerData *cfm)
gtk_tree_view_expand_all (GTK_TREE_VIEW (cfm->contactcerts_treeview));
}
-EvolutionConfigControl*
-certificate_manager_config_control_new (void)
+void
+certificate_manager_config_init (EShell *shell)
{
CertificateManagerData *cfm_data;
- GtkWidget *control_widget;
+ GtkWidget *preferences_window;
+ GtkWidget *widget;
gchar *gladefile;
+ g_return_if_fail (E_IS_SHELL (shell));
+
/* We need to peek the db here to make sure it (and NSS) are fully initialized. */
e_cert_db_peek ();
@@ -1031,14 +1035,20 @@ certificate_manager_config_control_new (void)
populate_ui (cfm_data);
- control_widget = glade_xml_get_widget (cfm_data->gui, "cert-manager-notebook");
- g_object_ref (control_widget);
+ widget = glade_xml_get_widget (cfm_data->gui, "cert-manager-notebook");
+ g_object_ref (widget);
- gtk_container_remove (GTK_CONTAINER (control_widget->parent), control_widget);
+ gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
/* FIXME: remove when implemented */
gtk_widget_set_sensitive(cfm_data->backup_your_button, FALSE);
gtk_widget_set_sensitive(cfm_data->backup_all_your_button, FALSE);
- return evolution_config_control_new (control_widget);
+ preferences_window = e_shell_get_preferences_window (shell);
+ e_preferences_window_add_page (
+ E_PREFERENCES_WINDOW (preferences_window),
+ "certificates",
+ "preferences-certificates",
+ _("Certificates"),
+ widget, 700);
}
diff --git a/smime/gui/certificate-manager.h b/smime/gui/certificate-manager.h
index 73d3688859..9107e203de 100644
--- a/smime/gui/certificate-manager.h
+++ b/smime/gui/certificate-manager.h
@@ -23,8 +23,13 @@
#ifndef _CERTIFICATE_MANAGER_H_
#define _CERTIFICATE_MANAGER_H
-#include "evolution-config-control.h"
+#include <glib.h>
+#include <shell/e-shell.h>
-EvolutionConfigControl* certificate_manager_config_control_new (void);
+G_BEGIN_DECLS
+
+void certificate_manager_config_init (EShell *shell);
+
+G_END_DECLS
#endif /* _CERTIFICATE_MANAGER_H_ */
diff --git a/tools/killev.c b/tools/killev.c
index a978fea0d8..f272602ac2 100644
--- a/tools/killev.c
+++ b/tools/killev.c
@@ -204,17 +204,7 @@ main (gint argc, gchar **argv)
(GDestroyNotify) NULL,
(GDestroyNotify) kill_component);
- add_matching_repo_id ("IDL:GNOME/Evolution/Shell:" BASE_VERSION);
- g_hash_table_remove_all (components);
-
- add_matching_repo_id ("IDL:GNOME/Evolution/Component:" BASE_VERSION);
- add_matching_repo_id ("IDL:GNOME/Evolution/DataServer/CalFactory:" DATASERVER_API_VERSION);
- add_matching_repo_id ("IDL:GNOME/Evolution/DataServer/BookFactory:" DATASERVER_API_VERSION);
- add_matching_repo_id ("IDL:GNOME/Evolution/Importer:" BASE_VERSION);
- add_matching_repo_id ("IDL:GNOME/Evolution/IntelligentImporter:" BASE_VERSION);
-
add_matching_iid ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify_Factory:" BASE_VERSION);
- add_matching_iid ("OAFIID:GNOME_GtkHTML_Editor_Factory:3.1");
g_hash_table_remove_all (components);
g_hash_table_destroy (components);
diff --git a/ui/Makefile.am b/ui/Makefile.am
index 40a5ad2d3e..a57b470dca 100644
--- a/ui/Makefile.am
+++ b/ui/Makefile.am
@@ -1,18 +1,16 @@
-XML_FILES = \
- evolution.xml \
- evolution-addressbook.xml \
- evolution-calendar.xml \
- evolution-mail-message.xml \
- evolution-mail-list.xml \
- evolution-mail-global.xml \
- evolution-mail-messagedisplay.xml \
- evolution-memos.xml \
- evolution-tasks.xml
+UI_FILES = \
+ evolution-calendars.ui \
+ evolution-contacts.ui \
+ evolution-mail.ui \
+ evolution-mail-reader.ui \
+ evolution-memos.ui \
+ evolution-shell.ui \
+ evolution-tasks.ui
-evolutionui_DATA = $(XML_FILES)
+evolutionui_DATA = $(UI_FILES)
EXTRA_DIST = \
- $(XML_FILES) \
+ $(UI_FILES) \
ChangeLog.pre-1-4
-include $(top_srcdir)/git.mk
diff --git a/ui/evolution-addressbook.xml b/ui/evolution-addressbook.xml
deleted file mode 100644
index f28172e436..0000000000
--- a/ui/evolution-addressbook.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<Root>
- <commands>
-
- <cmd name="ContactDelete"
- _tip="Delete selected contacts"
- accel="*Control*d" pixtype="pixbuf"/>
-
- <cmd name="ContactsPrint"
- _tip="Print selected contacts"
- accel="*Control*p" pixtype="pixbuf"/>
-
- <cmd name="ContactsPrintPreview"
- _tip="Previews the contacts to be printed"
- pixtype="pixbuf"/>
-
- <cmd name="ContactsView"
- _tip="View the current contact"
- accel="*Control*o"/>
-
- <cmd name="ContactStop"
- _tip="Stop Loading"
- pixtype="stock" pixname="gtk-stop"/>
-
- <cmd name="ContactsCut" _label="Cut"
- _tip="Cut the selection"
- accel="*Control*x" pixtype="pixbuf"/>
-
- <cmd name="ContactsCopy" _label="Copy"
- _tip="Copy the selection"
- accel="*Control*c" pixtype="pixbuf"/>
-
- <cmd name="ContactsPaste" _label="Paste"
- _tip="Paste the clipboard"
- accel="*Control*v" pixtype="pixbuf"/>
-
- <cmd name="ContactsSelectAll" _label="Select All"
- _tip="Select all contacts" accel="*Control*a"
- pixtype="stock" pixname="gtk-select-all"/>
-
- <cmd name="ContactsSaveAsVCard" _label="Save as VCard..."
- _tip="Save selected contacts as a VCard"
- accel="*Control*s" pixtype="pixbuf"/>
-
- <cmd name="ContactsSendContactToOther" _label="Forward Contact"
- _tip="Send selected contacts to another person"
- pixtype="pixbuf"/>
-
- <cmd name="ContactsSendMessageToContact" _label="Send message to contact"
- _tip="Send a message to the selected contacts"
- pixtype="pixbuf"/>
-
- <cmd name="ContactsCopyToFolder" _label="Copy to Folder..."
- _tip="Copy selected contacts to another folder"
- accel="*Control**Shift*y"/>
-
- <cmd name="ContactsMoveToFolder" _label="Move to Folder..."
- _tip="Move selected contacts to another folder"
- accel="*Control**Shift*v"/>
-
- <cmd name="ContactsViewPreview" _label="Contact _Preview"
- _tip="Show contact preview window"
- accel="*Control*m"
- type="toggle"/>
-
- <cmd name="FolderCreate" _label="_New"
- _tip="Create a new address book folder"
- pixtype="pixbuf"/>
-
- <cmd name="FolderCopy" _label="_Copy Folder Contacts To"
- _tip="Copy the contacts of the selected folder into another folder"
- pixtype="pixbuf"/>
-
- <cmd name="FolderMove" _label="_Move Folder Contacts To"
- _tip="Move the contacts of the selected folder into another folder"
- pixtype="pixbuf"/>
-
- <cmd name="FolderSave" _label="_Save Folder Contacts As VCard"
- _tip="Save the contacts of the selected folder as VCard"
- pixtype="pixbuf"/>
-
- <cmd name="FolderDelete" _label="_Delete"
- _tip="Delete the selected folder"
- pixtype="pixbuf"/>
-
- <cmd name="FolderRename" _label="_Rename"
- _tip="Rename the selected folder"
- pixtype="pixbuf"
- accel="F2"/>
-
- <cmd name="ChangeFolderProperties" _label="_Properties"
- _tip="Change the properties of the selected folder"
- pixtype="pixbuf"/>
-
- </commands>
-
- <menu>
- <submenu name="File">
- <placeholder name="FileOps">
- <menuitem name="ContactsView"
- verb="" _label="_Open"/>
- <menuitem name="ContactsSaveAsVCard"
- verb="" _label="_Save Contact as VCard..."/>
- <menuitem name="FolderSave"
- verb="" _label="S_ave Address Book As VCard"/>
- </placeholder>
-
- <placeholder name="Print">
- <menuitem name="ContactsPrintPreview" verb="" _label="Print Pre_view"/>
- <menuitem name="ContactsPrint" verb="" _label="_Print..."/>
- </placeholder>
-
- </submenu>
-
- <submenu name="View" _label="_View">
- <menuitem name="ContactsViewPreview" verb="" _label="Contact _Preview"/>
- </submenu>
-
- <submenu name="Edit" _label="_Edit">
- <placeholder name="EditPlaceholder">
- <menuitem name="ContactsSelectAll" verb="" _label="Select _All"/>
-
- <separator f="" name="eadbk2"/>
-
- <menuitem name="ContactsCut" verb="" _label="C_ut"/>
-
- <menuitem name="ContactsCopy" verb="" _label="_Copy"/>
-
- <menuitem name="ContactsPaste" verb="" _label="_Paste"/>
-
- <separator f="" name="eadbk6"/>
-
- <menuitem name="ContactDelete" verb="" _label="_Delete Contact"/>
-
- <menuitem name="FolderDelete" verb="" _label="Del_ete Address Book"/>
- </placeholder>
- </submenu>
-
- <placeholder name="FolderPlaceholder">
- </placeholder>
-
- <placeholder name="ActionsPlaceholder">
- <submenu name="Actions" _label="_Actions">
- <menuitem name="ContactsSendContactToOther"
- _label="_Forward Contact..." verb=""/>
-
- <menuitem name="ContactsSendMessageToContact"
- _label="_Send Message to Contact..." verb=""/>
- <menuitem name="ContactActionStop" verb="ContactStop" _label="St_op"/>
-
- <separator f="" name="eadbk5"/>
-
- <menuitem name="ContactsCopyToFolder" _label="_Copy Contact to..." verb=""/>
- <menuitem name="ContactsMoveToFolder" _label="_Move Contact to..." verb=""/>
-
- <separator f="" name="eadbk4"/>
-
- <menuitem name="FolderCopy" verb="" _label="Co_py All Contacts To..."/>
-
- <menuitem name="FolderMove" verb="" _label="Mo_ve All Contacts To..."/>
-
- <separator f="" name="eadbk3"/>
-
- <menuitem name="ChangeFolderProperties" verb="" _label="Address _Book Properties"/>
-
- </submenu>
- </placeholder>
-
- </menu>
-
- <dockitem name="Toolbar">
- <toolitem name="ContactsPrint" verb=""
- _label="Print" pixtype="pixbuf"/>
-
- <toolitem name="ContactDelete" verb=""
- _label="Delete" pixtype="pixbuf"/>
-
- <toolitem name="ContactStop" verb=""
- _label="Stop"/>
-
- </dockitem>
-
- <keybindings>
- <accel name="Delete" verb="ContactDelete"/>
- <accel name="BackSpace" verb="ContactDelete"/>
- <accel name="F16" verb="ContactsCopy"/>
- <accel name="F18" verb="ContactsPaste"/>
- <accel name="F20" verb="ContactsCut"/>
- </keybindings>
-
-</Root>
diff --git a/ui/evolution-calendar.xml b/ui/evolution-calendar.xml
deleted file mode 100644
index 36aa0df0ef..0000000000
--- a/ui/evolution-calendar.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-<Root>
- <commands>
- <cmd name="EventOpen" _tip="View the current appointment" accel="*Control*o"/>
- <cmd name="CalendarPrint" _tip="Print this calendar" pixtype="pixbuf"
- accel="*Control*p"/>
- <cmd name="CalendarPrintPreview" _tip="Previews the calendar to be printed" pixtype="pixbuf"/>
-
- <cmd name="CalendarPrev" _tip="Go back" pixtype="pixbuf"/>
- <cmd name="CalendarToday" _tip="Select today" pixtype="pixbuf"/>
- <cmd name="CalendarNext" _tip="Go forward" pixtype="pixbuf"/>
- <cmd name="CalendarGoto" _tip="Select a specific date" pixtype="pixbuf"/>
-
- <cmd name="ShowDayView" _tip="Show one day" pixtype="pixbuf"/>
- <cmd name="ShowWorkWeekView" _tip="Show the working week" pixtype="pixbuf"/>
- <cmd name="ShowWeekView" _tip="Show one week" pixtype="pixbuf"/>
- <cmd name="ShowMonthView" _tip="Show one month" pixtype="pixbuf"/>
- <cmd name="ShowListView" _tip="Show as list" pixtype="pixbuf"/>
-
- <cmd name="Cut" _tip="Cut the selection" accel="*Control*x" pixtype="pixbuf"/>
- <cmd name="Copy" _tip="Copy the selection" accel="*Control*c" pixtype="pixbuf"/>
- <cmd name="Paste" _tip="Paste the clipboard" accel="*Control*v" pixtype="pixbuf"/>
-
- <cmd name="Delete" _tip="Delete the appointment" accel="*Control*d" pixtype="pixbuf"/>
- <cmd name="DeleteOccurrence" _tip="Delete this occurrence" pixtype="pixbuf"/>
- <cmd name="DeleteAllOccurrences" _tip="Delete all occurrences" pixtype="pixbuf"/>
-
- <cmd name="CalendarPurge" _label="Purg_e" _tip="Purge old appointments and meetings" accel="*Control*e"/>
- <cmd name="HelpDebug" _tip="View the debug console for log messages"/>
- </commands>
-
- <menu>
- <submenu name="File">
- <placeholder name="FileOps">
- <menuitem name="EventOpen" verb="EventOpen" _label="_Open Appointment"/>
- </placeholder>
- <placeholder name="Print">
- <menuitem name="PrintPreview" verb="CalendarPrintPreview"
- _label="Print Pre_view"/>
-
- <menuitem name="Print" verb="CalendarPrint" accel="*Control*p"
- _label="_Print..."/>
- </placeholder>
-
- </submenu>
-
- <submenu name="Edit" _label="_Edit">
- <placeholder name="EditPlaceholder">
- <menuitem name="Cut" verb="" _label="C_ut"/>
- <menuitem name="Copy" verb="" _label="_Copy"/>
- <menuitem name="Paste" verb="" _label="_Paste"/>
-
- <separator/>
-
- <menuitem name="Delete" verb="" _label="_Delete"/>
- <menuitem name="DeleteOccurrence" verb="" _label="Delete this _Occurrence"/>
- <menuitem name="DeleteAllOccurrences" verb="" _label="Delete _all Occurrences"/>
- </placeholder>
- </submenu>
-
- <submenu name="View">
- <placeholder name="ViewBegin">
- <menuitem name="Today" verb="CalendarToday" _label="Select _Today"
- accel="*Control*t"/>
- <menuitem name="Goto" verb="CalendarGoto" _label="Select _Date" accel="*Control*g"/>
- <separator f="" name="ecal"/>
- </placeholder>
-
- </submenu>
-
- <placeholder name="ActionsPlaceholder">
- <submenu name="Actions" _label="_Actions">
- <menuitem name="CalendarPurge" verb=""/>
- </submenu>
- </placeholder>
- <submenu name="Help" _label="_Help">
- <placeholder name="PlaceHolderDebug">
- <menuitem name="HelpDebug" verb="" _label="_Debug Logs"/>
- </placeholder>
- </submenu>
- </menu>
-
- <dockitem name="Toolbar">
-
- <toolitem name="Print" verb="CalendarPrint" _label="Print" pixtype="pixbuf"/>
- <toolitem name="Delete" verb="" _label="Delete" pixtype="pixbuf"/>
-
- <separator f="" name="ecal2"/>
-
- <toolitem name="Prev" verb="CalendarPrev" _label="Previous" pixtype="pixbuf"/>
- <toolitem name="Today" verb="CalendarToday" _label="Today" pixtype="pixbuf"/>
- <toolitem name="Next" verb="CalendarNext" _label="Next" pixtype="pixbuf"/>
-
- <separator f="" name="ecal3"/>
-
- <toolitem name="Goto" verb="CalendarGoto" _label="Go To" priority="1" pixtype="pixbuf"/>
-
- <separator f="" name="ecal4"/>
-
- <toolitem name="DayView" verb="ShowDayView" _label="Day" priority="1" pixtype="pixbuf"/>
- <toolitem name="WorkWeekView" verb="ShowWorkWeekView" _label="Work Week" priority="1" pixtype="pixbuf"/>
- <toolitem name="WeekView" verb="ShowWeekView" _label="Week" priority="1" pixtype="pixbuf"/>
- <toolitem name="MonthView" verb="ShowMonthView" _label="Month" priority="1" pixtype="pixbuf"/>
- <toolitem name="ListView" verb="ShowListView" _label="List" priority="1" pixtype="pixbuf"/>
-
- </dockitem>
-
-</Root>
diff --git a/ui/evolution-calendars.ui b/ui/evolution-calendars.ui
new file mode 100644
index 0000000000..267d6f07b1
--- /dev/null
+++ b/ui/evolution-calendars.ui
@@ -0,0 +1,137 @@
+<ui>
+ <menubar name='main-menu'>
+ <menu action='file-menu'>
+ <placeholder name='file-actions'>
+ <menuitem action='event-open'/>
+ </placeholder>
+ <placeholder name='print-actions'>
+ <menuitem action='calendar-print-preview'/>
+ <menuitem action='calendar-print'/>
+ </placeholder>
+ </menu>
+ <menu action='edit-menu'>
+ <placeholder name='edit-actions'>
+ <menuitem action='event-clipboard-cut'/>
+ <menuitem action='event-clipboard-copy'/>
+ <menuitem action='event-clipboard-paste'/>
+ <separator/>
+ <menuitem action='event-delete'/>
+ <menuitem action='event-delete-occurrence'/>
+ <menuitem action='event-delete-occurrence-all'/>
+ </placeholder>
+ </menu>
+ <menu action='view-menu'>
+ <menuitem action='calendar-go-today'/>
+ <menuitem action='calendar-jump-to'/>
+ </menu>
+ <placeholder name='custom-menus'>
+ <menu action='calendar-actions-menu'>
+ <menuitem action='calendar-purge'/>
+ </menu>
+ </placeholder>
+ </menubar>
+ <toolbar name='main-toolbar'>
+ <toolitem action='calendar-print'/>
+ <toolitem action='event-delete'/>
+ <separator/>
+ <toolitem action='calendar-go-back'/>
+ <toolitem action='calendar-go-today'/>
+ <toolitem action='calendar-go-forward'/>
+ <separator/>
+ <toolitem action='calendar-jump-to'/>
+ <separator/>
+ <toolitem action='calendar-view-day'/>
+ <toolitem action='calendar-view-workweek'/>
+ <toolitem action='calendar-view-week'/>
+ <toolitem action='calendar-view-month'/>
+ <toolitem action='calendar-view-list'/>
+ </toolbar>
+ <popup name='calendar-popup'>
+ <menuitem action='calendar-new'/>
+ <menuitem action='calendar-popup-copy'/>
+ <menuitem action='calendar-popup-rename'/>
+ <separator/>
+ <menuitem action='calendar-popup-delete'/>
+ <menuitem action='calendar-popup-select-one'/>
+ <separator/>
+ <menuitem action='calendar-popup-properties'/>
+ </popup>
+ <popup name='calendar-empty-popup'>
+ <menuitem action='event-new'/>
+ <menuitem action='event-all-day-new'/>
+ <menuitem action='event-meeting-new'/>
+ <menuitem action='task-new'/>
+ <separator/>
+ <menuitem action='event-popup-print'/>
+ <separator/>
+ <menuitem action='event-popup-clipboard-paste'/>
+ <separator/>
+ <menuitem action='gal-view-menu'/>
+ <menuitem action='calendar-popup-go-today'/>
+ <menuitem action='calendar-popup-jump-to'/>
+ </popup>
+ <popup name='calendar-event-popup'>
+ <menuitem action='event-popup-open'/>
+ <menuitem action='event-popup-save-as'/>
+ <menuitem action='event-popup-print'/>
+ <separator/>
+ <menuitem action='event-popup-clipboard-cut'/>
+ <menuitem action='event-popup-clipboard-copy'/>
+ <menuitem action='event-popup-clipboard-paste'/>
+ <separator/>
+ <menuitem action='event-popup-copy'/>
+ <menuitem action='event-popup-move'/>
+ <menuitem action='event-popup-delegate'/>
+ <menuitem action='event-popup-schedule'/>
+ <menuitem action='event-popup-forward'/>
+ <menuitem action='event-popup-reply'/>
+ <menuitem action='event-popup-reply-all'/>
+ <separator/>
+ <menuitem action='event-popup-occurrence-movable'/>
+ <menuitem action='event-popup-delete'/>
+ <menuitem action='event-popup-delete-occurrence'/>
+ <menuitem action='event-popup-delete-occurrence-all'/>
+ </popup>
+ <popup name='calendar-memopad-popup'>
+ <menuitem action='calendar-memopad-new'/>
+ <separator/>
+ <menuitem action='calendar-memopad-open'/>
+ <menuitem action='calendar-memopad-open-url'/>
+ <menuitem action='calendar-memopad-save-as'/>
+ <menuitem action='calendar-memopad-print'/>
+ <separator/>
+ <menuitem action='calendar-memopad-clipboard-cut'/>
+ <menuitem action='calendar-memopad-clipboard-copy'/>
+ <menuitem action='calendar-memopad-clipboard-paste'/>
+ <separator/>
+ <menuitem action='calendar-memopad-forward'/>
+ <separator/>
+ <menuitem action='calendar-memopad-delete'/>
+ </popup>
+ <popup name='calendar-taskpad-popup'>
+ <menuitem action='calendar-taskpad-new'/>
+ <separator/>
+ <menuitem action='calendar-taskpad-open'/>
+ <menuitem action='calendar-taskpad-open-url'/>
+ <menuitem action='calendar-taskpad-save-as'/>
+ <menuitem action='calendar-taskpad-print'/>
+ <separator/>
+ <menuitem action='calendar-taskpad-clipboard-cut'/>
+ <menuitem action='calendar-taskpad-clipboard-copy'/>
+ <menuitem action='calendar-taskpad-clipboard-paste'/>
+ <separator/>
+ <menuitem action='calendar-taskpad-assign'/>
+ <menuitem action='calendar-taskpad-forward'/>
+ <menuitem action='calendar-taskpad-mark-complete'/>
+ <menuitem action='calendar-taskpad-mark-incomplete'/>
+ <separator/>
+ <menuitem action='calendar-taskpad-delete'/>
+ </popup>
+ <popup name='calendar-search-options'>
+ <menuitem action='calendar-search-summary-contains'/>
+ <menuitem action='calendar-search-description-contains'/>
+ <menuitem action='calendar-search-any-field-contains'/>
+ <separator/>
+ <menuitem action='search-advanced'/>
+ </popup>
+</ui>
diff --git a/ui/evolution-contacts.ui b/ui/evolution-contacts.ui
new file mode 100644
index 0000000000..cf95acd4a0
--- /dev/null
+++ b/ui/evolution-contacts.ui
@@ -0,0 +1,92 @@
+<ui>
+ <menubar name='main-menu'>
+ <menu action='file-menu'>
+ <placeholder name='file-actions'>
+ <menuitem action='contact-open'/>
+ <menuitem action='contact-save-as'/>
+ <menuitem action='address-book-save-as'/>
+ </placeholder>
+ <placeholder name='print-actions'>
+ <menuitem action='contact-print-preview'/>
+ <menuitem action='contact-print'/>
+ </placeholder>
+ </menu>
+ <menu action='edit-menu'>
+ <placeholder name='edit-actions'>
+ <menuitem action='contact-select-all'/>
+ <separator/>
+ <menuitem action='contact-clipboard-cut'/>
+ <menuitem action='contact-clipboard-copy'/>
+ <menuitem action='contact-clipboard-paste'/>
+ <separator/>
+ <menuitem action='contact-delete'/>
+ <menuitem action='address-book-delete'/>
+ </placeholder>
+ </menu>
+ <menu action='view-menu'>
+ <placeholder name='view-custom-menus'>
+ <menu action='contact-preview-menu'>
+ <menuitem action='contact-preview'/>
+ <separator/>
+ <menuitem action='contact-view-classic'/>
+ <menuitem action='contact-view-vertical'/>
+ </menu>
+ </placeholder>
+ </menu>
+ <placeholder name='custom-menus'>
+ <menu action='contact-actions-menu'>
+ <menuitem action='contact-forward'/>
+ <menuitem action='contact-send-message'/>
+ <menuitem action='address-book-stop'/>
+ <separator/>
+ <menuitem action='contact-copy'/>
+ <menuitem action='contact-move'/>
+ <separator/>
+ <menuitem action='address-book-copy'/>
+ <menuitem action='address-book-move'/>
+ <separator/>
+ <menuitem action='address-book-properties'/>
+ </menu>
+ </placeholder>
+ </menubar>
+ <toolbar name='main-toolbar'>
+ <toolitem action='contact-print'/>
+ <toolitem action='contact-delete'/>
+ <toolitem action='address-book-stop'/>
+ </toolbar>
+ <popup name='address-book-popup'>
+ <menuitem action='address-book-new'/>
+ <menuitem action='address-book-popup-rename'/>
+ <menuitem action='address-book-popup-save-as'/>
+ <separator/>
+ <menuitem action='address-book-popup-delete'/>
+ <separator/>
+ <menuitem action='address-book-popup-properties'/>
+ </popup>
+ <popup name='contact-popup'>
+ <menuitem action='contact-popup-open'/>
+ <separator/>
+ <menuitem action='contact-new'/>
+ <menuitem action='contact-new-list'/>
+ <separator/>
+ <menuitem action='contact-popup-save-as'/>
+ <menuitem action='contact-popup-forward'/>
+ <menuitem action='contact-popup-send-message'/>
+ <menuitem action='contact-popup-print'/>
+ <separator/>
+ <menuitem action='contact-popup-copy'/>
+ <menuitem action='contact-popup-move'/>
+ <separator/>
+ <menuitem action='contact-popup-clipboard-cut'/>
+ <menuitem action='contact-popup-clipboard-copy'/>
+ <menuitem action='contact-popup-clipboard-paste'/>
+ <menuitem action='contact-popup-delete'/>
+ </popup>
+ <popup name='contact-search-options'>
+ <menuitem action='contact-search-name-contains'/>
+ <menuitem action='contact-search-email-begins-with'/>
+ <menuitem action='contact-search-any-field-contains'/>
+ <separator/>
+ <menuitem action='search-advanced'/>
+ </popup>
+</ui>
diff --git a/ui/evolution-mail-global.xml b/ui/evolution-mail-global.xml
deleted file mode 100644
index c582cd6b62..0000000000
--- a/ui/evolution-mail-global.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-<Root>
-
- <commands> <!-- Alphabetical by name, yo -->
-
- <cmd name="EmptyTrash"
- _tip="Permanently remove all deleted messages from all folders"/>
-
- <cmd name="MailStop"
- _tip="Cancel the current mail operation"
- pixtype="stock" pixname="gtk-stop"/>
-
- <cmd name="FolderCreate"
- _tip="Create a new folder for storing mail"
- pixtype="pixbuf"/>
-
- <cmd name="FolderCopy"
- _tip="Copy the selected folder into another folder"
- pixtype="pixbuf"/>
-
- <cmd name="FolderMove"
- _tip="Move the selected folder into another folder"
- pixtype="pixbuf"/>
-
- <cmd name="ToolsFilters"
- _tip="Create or edit rules for filtering new mail"/>
-
- <cmd name="ToolsSubscriptions"
- _tip="Subscribe or unsubscribe to folders on remote servers"/>
-
- <cmd name="ToolsVFolders"
- _tip="Create or edit Search Folder definitions"/>
-
- <cmd name="ViewPreview"
- _tip="Show message preview window"
- accel="*Control*m"
- type="toggle"/>
-
- <cmd name="ViewBelow" _label="_Classic View"
- type="radio" group="preview_display" _tip="Show message preview below the message list"/>
-
- <cmd name="ViewAfter" _label="_Vertical View"
- type="radio" group="preview_display" _tip="Show message preview side-by-side with the message list"/>
-
- <cmd name="PrepareForOffline" _label="_Download Messages for Offline Usage" _tip="Download messages of accounts/folders marked for offline"/>
- <cmd name="HelpDebug" _tip="View the debug console for log messages"/>
-
- </commands>
-
- <keybindings>
- <accel name="slash" id="FocusSearch"/>
- </keybindings>
-
- <menu>
-
- <submenu name="File">
- <placeholder name="EmptyTrashPlaceholder">
- <menuitem name="EmptyTrash" verb="" _label="Empty _Trash"/>
- <menuitem name="PrepareForOffline" verb="" _label="_Download Messages for Offline Usage"/>
- </placeholder>
- </submenu>
-
- <submenu name="View" _label="_View">
- <placeholder name="ViewPreview">
- <submenu name="Preview" _label="_Preview">
- <menuitem name="ViewPreview" verb="" _label="Show Message _Preview"/>
- <separator name="previewsep"/>
- <menuitem name="ViewBelow" id="ViewBelow" _label="_Classic View"/>
- <menuitem name="ViewAfter" id="ViewAfter" _label="_Vertical View"/>
- </submenu>
- </placeholder>
- <separator f="" name="emailglobal"/>
- <placeholder name="MailMessageFilter"/>
- <placeholder name="MailMessageView"/>
-
-<!-- This is the menu we want to replace "Current View" with
- <submenu name="ViewAs" _label="Message _List As">
- <placeholder name="CurrentView"/>
- </submenu>
--->
-
- <placeholder name="MailViewType">
- <separator f="" name="MailViewOps"/>
- </placeholder>
-
- <placeholder name="MailMessageZoom"/>
- <placeholder name="MailListView"/>
- </submenu>
-
- <submenu name="Edit">
- <placeholder name="EditPlaceholder">
- <placeholder name="MailListEdit"/>
- <placeholder name="MailMessageEdit"/>
- <placeholder name="MailListEditFlags"/>
- </placeholder>
-
- <placeholder name="MailFilterTools">
- <menuitem name="ToolsFilters" verb="" _label="_Message Filters"/>
- </placeholder>
-
- <placeholder name="MailVFolderTools">
- <menuitem name="ToolsVFolders" verb="" _label="Search F_olders"/>
- </placeholder>
- </submenu>
-
- <placeholder name="FolderPlaceholder">
- <submenu name="Folder" _label="F_older">
-
- <menuitem name="FolderCreate" verb="" _label="_New..."/>
-<!--
- <menuitem name="CreateVFolder" verb="CreateVFolder" _label="_New Search _Folder (FIXME)"/>
--->
- <menuitem name="ToolsSubscriptions" verb="" _label="_Subscriptions..."/>
-
- <separator f="" name="Folder1"/>
-
- <menuitem name="FolderCopy" verb="" _label="_Copy Folder To..."/>
- <menuitem name="FolderMove" verb="" _label="_Move Folder To..."/>
-
- <separator f="" name="Folder2"/>
-
- <placeholder name="MessagesInFolder"/>
-
- <separator f="" name="Folder3"/>
-
- <placeholder name="FolderOps"/>
-
- </submenu>
- </placeholder>
- <submenu name="Help" _label="_Help">
- <placeholder name="PlaceHolderDebug">
- <menuitem name="HelpDebug" verb="" _label="_Debug Logs"/>
- </placeholder>
- </submenu>
- </menu>
-
- <dockitem name="Toolbar">
-
- <placeholder name="MailMessageToolbar"/>
-
- <toolitem name="MailStop" verb=""
- _label="Cancel"/>
-
- <separator f="" name="emailglobal1"/>
-
- <placeholder name="MailNextButtons"/>
-
- </dockitem>
-
-</Root>
diff --git a/ui/evolution-mail-list.xml b/ui/evolution-mail-list.xml
deleted file mode 100644
index 95b62eb996..0000000000
--- a/ui/evolution-mail-list.xml
+++ /dev/null
@@ -1,154 +0,0 @@
-<Root>
-
- <commands> <!-- Alphabetical by name, yo -->
-
- <cmd name="EditCut"
- _tip="Cut selected message(s) to the clipboard"
- accel="*Control*x" pixtype="pixbuf"/>
-
- <cmd name="EditCopy"
- _tip="Copy selected message(s) to the clipboard"
- accel="*Control*c" pixtype="pixbuf"/>
-
- <cmd name="EditPaste"
- _tip="Paste message(s) from the clipboard"
- accel="*Control*v" pixtype="pixbuf"/>
-
- <cmd name="EditInvertSelection"
- _tip="Select all and only the messages that are not currently selected"
- accel="*Control**Shift*i"/>
-
- <cmd name="EditSelectAll"
- _tip="Select all visible messages"
- accel="*Control*a"/>
-
- <cmd name="EditSelectSubthread"
- _tip="Select all replies to the currently selected message"
- accel="*Control**Shift*h"/>
-
- <cmd name="EditSelectThread"
- _tip="Select all messages in the same thread as the selected message"
- accel="*Control*h"/>
-
- <cmd name="MessageMarkAllAsRead"
- _tip="Mark all messages in the folder as read" accel="*Control*slash"
- pixtype="pixbuf"/>
-
- <cmd name="ChangeFolderProperties"
- _tip="Change the properties of this folder"
- pixtype="pixbuf"/>
-
- <cmd name="FolderExpunge"
- _tip="Permanently remove all deleted messages from this folder"
- accel="*Control*e"/>
-
- <cmd name="FolderDelete"
- _tip="Permanently remove this folder"
- pixtype="stock" pixname="gtk-delete"/>
-
- <cmd name="FolderRename"
- _tip="Change the name of this folder" accel="F2"/>
-
- <cmd name="FolderRefresh"
- _tip="Refresh the folder" accel="F5"
- pixtype="stock" pixname="gtk-refresh"/>
-
-
- <cmd name="HideDeleted" _tip="Hide deleted messages rather than displaying them with a line through them"
- type="toggle" />
-
- <cmd name="ViewHideRead" _tip="Temporarily hide all messages that have already been read"
- pixtype="pixbuf" />
-
- <cmd name="ViewHideSelected" _tip="Temporarily hide the selected messages"
- pixtype="pixbuf" />
-
- <cmd name="ViewShowAll" _tip="Show messages that have been temporarily hidden"
- pixtype="pixbuf" />
-
- <cmd name="ViewThreaded"
- _tip="Threaded Message list"
- accel="*Control*t"
- type="toggle" />
-
- <cmd name="ViewThreadsCollapseAll"
- _tip="Collapse all message threads" accel="*Control**Shift*b"/>
-
- <cmd name="ViewThreadsExpandAll"
- _tip="Expand all message threads"/>
-
- </commands>
-
- <keybindings>
-
- </keybindings>
-
- <menu>
-
- <submenu name="View">
-
- <placeholder name="MailMessageView">
- <menuitem name="ViewThreaded" verb="" _label="_Group By Threads"/>
- <menuitem name="ViewThreadsExpandAll" verb="" _label="E_xpand All Threads"/>
- <menuitem name="ViewThreadsCollapseAll" verb="" _label="Collapse All _Threads"/>
- <separator f="" name="emaillist"/>
- <menuitem name="HideDeleted" verb="" _label="Hide _Deleted Messages"/>
- <menuitem name="ViewHideSelected" verb="" _label="Hide S_elected Messages"/>
- <menuitem name="ViewHideRead" verb="" _label="Hide _Read Messages"/>
- <menuitem name="ViewShowAll" verb="" _label="Show Hidde_n Messages"/>
- </placeholder>
-
- </submenu>
-
- <placeholder name="MessagePlaceholder">
- <submenu name="Message" _label="_Message">
- <placeholder name="MessageTopActions"/>
-
- <separator f="" name="emailglobal"/>
-
- <placeholder name="MessageNavigation"/>
- <placeholder name="MailListActions"/>
- <placeholder name="MailMessageActions"/>
-
- <separator f="" name="emaillist5"/>
-
- <placeholder name="MessageRuleCreate"/>
-
- </submenu>
- </placeholder>
-
- <placeholder name="FolderPlaceholder">
- <submenu name="Folder" _label="F_older">
-
- <placeholder name="MessagesInFolder">
- <menuitem name="EditSelectAll" verb="" _label="Select _All Messages"/>
- <menuitem name="EditSelectThread" verb="" _label="Select Message _Thread"/>
- <menuitem name="EditSelectSubthread" verb="" _label="Select Message S_ubthread"/>
- <menuitem name="MessageMarkAllAsRead" verb="" _label="Mar_k All Messages as Read"/>
- <menuitem name="FolderExpunge" verb="" _label="E_xpunge"/>
- </placeholder>
-
- <placeholder name="FolderOps">
- <menuitem name="FolderRename" verb="" _label="_Rename..."/>
- <menuitem name="FolderRefresh" verb="" _label="Re_fresh"/>
- <menuitem name="FolderDelete" verb="" _label="_Delete"/>
-
- <separator f="" name="FolderOps1"/>
- <menuitem name="ChangeFolderProperties" verb="" _label="_Properties"/>
- </placeholder>
-
- </submenu>
- </placeholder>
-
-<!--
- <submenu name="Actions" _label="_Actions">
- <placeholder name="ComponentActionsPlaceholder">
- <placeholder name="MailListActions">
- </placeholder>
- </placeholder>
- </submenu>
--->
-
- </menu>
-
-</Root>
diff --git a/ui/evolution-mail-message.xml b/ui/evolution-mail-message.xml
deleted file mode 100644
index f90e737c24..0000000000
--- a/ui/evolution-mail-message.xml
+++ /dev/null
@@ -1,426 +0,0 @@
-<Root>
-
- <commands> <!-- Alphabetical by name, yo -->
-
- <cmd name="AddSenderToAddressbook"
- _tip="Add Sender to Address Book"/>
-
- <cmd name="CaretMode"
- _tip="Show a blinking cursor in the body of displayed messages"
- type="toggle" state="0" accel="F7"/>
-
- <cmd name="EditCut"
- _tip="Cut selected messages to the clipboard"
- accel="*Control*x" pixtype="pixbuf"/>
-
- <cmd name="EditCopy"
- _tip="Copy selected messages to the clipboard"
- accel="*Control*c" pixtype="pixbuf"/>
-
- <cmd name="EditPaste"
- _tip="Paste messages from the clipboard"
- accel="*Control*v" pixtype="pixbuf"/>
-
- <cmd name="MailNext"
- _tip="Display the next message"
- accel="*Control*Page_Down"/>
-
- <cmd name="MailNextFlagged"
- _tip="Display the next important message"/>
-
- <cmd name="MailNextUnread"
- _tip="Display the next unread message"
- accel="*Control*bracketright"/>
-
- <cmd name="MailNextThread"
- _tip="Display the next thread"/>
-
- <cmd name="MailPrevious"
- _tip="Display the previous message"
- accel="*Control*Page_Up"/>
-
- <cmd name="MailPreviousFlagged"
- _tip="Display the previous important message"/>
-
- <cmd name="MailPreviousUnread"
- _tip="Display the previous unread message"
- accel="*Control*bracketleft"/>
-
- <cmd name="MessageApplyFilters"
- _tip="Apply filter rules to the selected messages"
- accel="*Control*y"
- pixtype="pixbuf"/>
-
- <cmd name="MessageCopy"
- _tip="Copy selected messages to another folder"
- accel="*Control**Shift*y"
- pixtype="pixbuf"/>
-
- <cmd name="MessageDelete"
- _tip="Mark the selected messages for deletion"
- pixtype="pixbuf"/>
-
- <cmd name="MessageFollowUpFlag"
- _tip="Flag selected messages for follow-up"
- accel="*Control**Shift*G"
- pixtype="pixbuf"/>
-
- <cmd name="MessageForward"
- _tip="Forward the selected message to someone"
- accel="*Control*f"
- pixtype="pixbuf"/>
-
- <cmd name="MessageForwardAttached"
- _tip="Forward the selected message to someone as an attachment"/>
-
- <cmd name="MessageForwardInline"
- _tip="Forward the selected message in the body of a new message"/>
-
- <cmd name="MessageForwardQuoted"
- _tip="Forward the selected message quoted like a reply"/>
-
- <cmd name="MessageMarkAsRead"
- _tip="Mark the selected messages as having been read"
- accel="*Control*k"
- pixtype="pixbuf"/>
-
- <cmd name="MessageMarkAsUnRead"
- _tip="Mark the selected messages as not having been read"
- accel="*Control**Shift*k"
- pixtype="pixbuf"/>
-
- <cmd name="MessageMarkAsImportant"
- _tip="Mark the selected messages as important"
- pixtype="pixbuf"/>
-
- <cmd name="MessageMarkAsUnimportant"
- _tip="Mark the selected messages as unimportant"/>
-
- <cmd name="MessageMarkAsJunk"
- _tip="Mark the selected messages as junk"
- accel="*Control*j"
- pixtype="pixbuf"/>
-
- <cmd name="MessageMarkAsNotJunk"
- _tip="Mark the selected messages as not being junk"
- accel="*Control**Shift*j"
- pixtype="pixbuf"/>
-
- <cmd name="MessageFilterJunk"
- _tip="Filter the selected messages for junk status"
- pixtype="pixbuf"/>
-
- <cmd name="MailCompose"
- _tip="Open a window for composing a mail message"
- pixtype="pixbuf"
- accel="*Control**Shift*m"/>
-
- <cmd name="MessageMove"
- _tip="Move selected messages to another folder"
- accel="*Control**Shift*v"
- pixtype="pixbuf"/>
-
- <cmd name="MessageEdit"
- _tip="Open the selected messages in the composer for editing"/>
-
- <cmd name="MessageOpen"
- _tip="Open the selected messages in a new window"
- accel="*Control*o"/>
-
- <cmd name="MessageRedirect"
- _tip="Redirect (bounce) the selected message to someone"
- accel=""/>
-
- <cmd name="MessageReplyAll"
- _tip="Compose a reply to all of the recipients of the selected message"
- accel="*Control**Shift*r"
- pixtype="pixbuf"/>
-
- <cmd name="MessageReplyList"
- _tip="Compose a reply to the mailing list of the selected message"
- accel="*Control*l"/>
-
- <cmd name="MessageReplySender"
- _tip="Compose a reply to the sender of the selected message"
- accel="*Control*r"
- pixtype="pixbuf"/>
-
- <cmd name="MessageSaveAs"
- _tip="Save the selected messages as a text file"
- accel="*Control*s"
- pixtype="pixbuf"/>
-
- <cmd name="MessageSearch"
- _tip="Search for text in the body of the displayed message"
- accel="*Control**Shift*f"
- pixtype="pixbuf"/>
-
- <cmd name="MessageUndelete"
- _tip="Undelete the selected messages"
- accel="*Control**Shift*d"/>
-
- <cmd name="PrintMessage"
- _tip="Print this message"
- accel="*Control*p"
- pixtype="pixbuf"/>
-
- <cmd name="PrintPreviewMessage"
- _tip="Preview the message to be printed"
- pixtype="pixbuf"/>
-
- <cmd name="PrintSetup"
- _tip="Set up the page settings for your current printer"/>
-
- <cmd name="SelectAllText"
- _tip="Select all the text in a message"
- accel="*Control**Shift*x"/>
-
- <cmd name="ToolsFilterMailingList"
- _tip="Create a rule to filter messages to this mailing list"/>
-
- <cmd name="ToolsFilterRecipient"
- _tip="Create a rule to filter messages to these recipients"/>
-
- <cmd name="ToolsFilterSender"
- _tip="Create a rule to filter messages from this sender"/>
-
- <cmd name="ToolsFilterSubject"
- _tip="Create a rule to filter messages with this subject"/>
-
- <cmd name="ToolsVFolderMailingList"
- _tip="Create a Search Folder for this mailing list"/>
-
- <cmd name="ToolsVFolderRecipient"
- _tip="Create a Search Folder for these recipients"/>
-
- <cmd name="ToolsVFolderSender"
- _tip="Create a Search Folder for this sender"/>
-
- <cmd name="ToolsVFolderSubject"
- _tip="Create a Search Folder for this subject"/>
-
- <cmd name="ViewFullHeaders"
- _tip="Show messages with all email headers"
- type="toggle" state="0"/>
-
- <cmd name="ViewLoadImages"
- _tip="Force images in HTML mail to be loaded"
- accel="*Control*i" pixtype="pixbuf"/>
-
- <cmd name="ViewSource"
- _tip="Show the raw email source of the message"
- accel="*Control*u"/>
-
- <cmd name="TextZoomIn"
- _tip="Increase the text size"
- accel="*Control*plus" pixtype="pixbuf"/>
-
- <cmd name="TextZoomOut"
- _tip="Decrease the text size"
- accel="*Control*minus" pixtype="pixbuf"/>
-
- <cmd name="TextZoomReset"
- _tip="Reset the text to its original size"
- accel="*Control*0" pixtype="pixbuf"/>
-
- </commands>
-
- <keybindings>
- <accel verb="MailPreviousUnread" name="*Control*comma"/>
- <accel verb="MailPreviousUnread" name="comma"/>
- <accel verb="MailPreviousUnread" name="bracketleft"/>
- <accel verb="MailNextUnread" name="*Control*period"/>
- <accel verb="MailNextUnread" name="period"/>
- <accel verb="MailNextUnread" name="bracketright"/>
- <accel verb="MessageDeleteKey" name="Delete"/>
- <accel verb="MessageDeleteKey" name="KP_Delete"/>
- <accel verb="MessageDeleteKey" name="*Control*d"/>
- </keybindings>
-
- <menu>
-
- <submenu name="File">
- <placeholder name="FileOps">
- <menuitem name="MessageSaveAs" verb="" _label="_Save Message..."/>
- </placeholder>
-
- <placeholder name="Print">
- <menuitem name="PrintPreviewMessage" verb="" _label="Print Pre_view"/>
- <menuitem name="PrintMessage" verb="" _label="_Print..."/>
- </placeholder>
- </submenu>
-
- <submenu name="Edit">
- <placeholder name="EditPlaceholder">
- <placeholder name="MailMessageEdit">
- <menuitem name="EditCopy" verb="" _label="_Copy"/>
-
- <separator f="" name="emaillist1"/>
-
- <menuitem name="SelectAllText" verb="" _label="Select _All Text"/>
-
- <separator f="" name="emaillist2"/>
-
- <menuitem name="MessageDelete" verb="" _label="_Delete Message"/>
- <menuitem name="MessageUndelete" verb="" _label="_Undelete Message"/>
-
- <separator f="" name="emaillist3"/>
-
- <menuitem name="MessageSearch" verb="" _label="_Find in Message..."/>
- </placeholder>
- </placeholder>
- </submenu>
-
- <submenu name="View">
- <placeholder name="MailMessageZoom">
- <submenu name="zoom" _label="_Zoom">
- <menuitem name="TextZoomIn" verb="" _label="_Zoom In"/>
- <menuitem name="TextZoomOut" verb="" _label="Zoom _Out"/>
- <menuitem name="TextZoomReset" verb="" _label="_Normal Size"/>
- </submenu>
- </placeholder>
-
- <placeholder name="MailViewType">
- <menuitem name="ViewLoadImages" verb="" _label="_Load Images"/>
- <menuitem name="ViewFullHeaders" verb="" _label="All Message _Headers"/>
- <menuitem name="CaretMode" verb="" _label="_Caret Mode"/>
- <menuitem name="ViewSource" verb="" _label="_Message Source"/>
-
- </placeholder>
-
- </submenu>
-
- <placeholder name="MessagePlaceholder">
- <submenu name="Message" _label="_Message">
- <placeholder name="MessageTopActions">
- <menuitem name="ActionCompose" verb="MailCompose" _label="Compose _New Message"/>
- <menuitem name="MessageOpen" verb="" _label="_Open in New Window"/>
- <menuitem name="MessageEdit" verb="" _label="_Edit as New Message..."/>
- <menuitem name="AddSenderToAddressbook" verb="" _label="A_dd Sender to Address Book"/>
- </placeholder>
-
- <placeholder name="MessageNavigation">
- <submenu name="GoTo" _label="_Go To" pixtype="pixbuf">
- <menuitem name="MailNext" verb="" _label="_Next Message"/>
- <menuitem name="MailNextUnread" verb="" _label="Next _Unread Message"/>
- <menuitem name="MailNextFlagged" verb="" _label="Next _Important Message"/>
- <menuitem name="MailNextThread" verb="" _label="Next _Thread"/>
- <separator f="" name="emaillist"/>
- <menuitem name="MailPrevious" verb="" _label="_Previous Message"/>
- <menuitem name="MailPreviousUnread" verb="" _label="P_revious Unread Message"/>
- <menuitem name="MailPreviousFlagged" verb="" _label="Pr_evious Important Message"/>
- </submenu>
- </placeholder>
-
- <placeholder name="MailMessageActions">
-
- <menuitem name="MessageReplySender" verb="" _label="_Reply to Sender"/>
- <menuitem name="MessageReplyList" verb="" _label="Reply to _List"/>
- <menuitem name="MessageReplyAll" verb="" _label="Reply to _All"/>
- <menuitem name="MessageForward" verb="" _label="_Forward"/>
- <submenu name="ForwardAs" _label="F_orward As...">
- <menuitem verb="MessageForwardAttached" _label="_Attached"/>
- <menuitem verb="MessageForwardInline" _label="_Inline"/>
- <menuitem verb="MessageForwardQuoted" _label="_Quoted"/>
- <separator f="" name="forwardlist1"/>
- <menuitem verb="MessageRedirect" _label="Re_direct"/>
- </submenu>
-
- <separator f="" name="emaillist3"/>
-
- <menuitem name="MessageMove" verb="" _label="_Move to Folder"/>
- <menuitem name="MessageCopy" verb="" _label="_Copy to Folder"/>
-
- <separator f="" name="emaillist4"/>
-
- <submenu name="MessageMarkAs" _label="Mar_k as">
- <!-- Translators: "Read" as in "has been read" (evolution-mail-message.xml) -->
- <menuitem name="MessageMarkAsRead" verb="" _label="_Read"/>
- <menuitem name="MessageMarkAsUnRead" verb="" _label="_Unread"/>
-
- <separator f="" name="emailmark1"/>
-
- <menuitem name="MessageMarkAsImportant" verb="" _label="_Important"/>
- <menuitem name="MessageMarkAsUnimportant" verb="" _label="Uni_mportant"/>
-
- <separator f="" name="emailmark2"/>
-
- <menuitem name="MessageMarkAsJunk" verb="" _label="_Junk"/>
- <menuitem name="MessageMarkAsNotJunk" verb="" _label="_Not Junk"/>
-
- <separator f="" name="emaillist2"/>
-
- <menuitem name="MessageFollowUpFlag" verb="" _label="Follow _Up..."/>
- <menuitem name="MessageFollowUpClear" verb="" _label="_Clear Flag"/>
- <menuitem name="MessageFollowUpComplete" verb="" _label="_Flag Completed"/>
-
- </submenu>
- <menuitem name="MessageApplyFilters" verb="" _label="A_pply Filters"/>
- <menuitem name="MessageFilterJunk" verb="" _label="Check for _Junk"/>
- </placeholder>
-
- <placeholder name="MessageRuleCreate">
- <submenu name="CreateRule" _label="Create R_ule">
- <menuitem name="ToolsVFolderSubject" verb="" _label="Search Folder from S_ubject..."/>
- <menuitem name="ToolsVFolderSender" verb="" _label="Search Folder from Sen_der..."/>
- <menuitem name="ToolsVFolderRecipient" verb="" _label="Search Folder from Recipien_ts..."/>
- <menuitem name="ToolsVFolderMailingList" verb="" _label="Search Folder from Mailing _List..."/>
-
- <separator f="" name="RuleSeparator"/>
-
- <menuitem name="ToolsFilterSubject" verb="" _label="Filter on _Subject..."/>
- <menuitem name="ToolsFilterSender" verb="" _label="Filter on Se_nder..."/>
- <menuitem name="ToolsFilterRecipient" verb="" _label="Filter on _Recipients..."/>
- <menuitem name="ToolsFilterMailingList" verb="" _label="Filter on Mailing _List..."/>
-
- </submenu>
- </placeholder>
- </submenu>
- </placeholder>
- </menu>
-
- <dockitem name="Toolbar">
-
- <placeholder name="MailMessageToolbar">
- <toolitem name="MessageReplySender" verb=""
- _label="Reply" priority="1"
- pixtype="pixbuf"/>
-
- <toolitem name="MessageReplyAll" verb=""
- _label="Reply to All" priority="1"
- pixtype="pixbuf"/>
-
- <toolitem name="MessageForward" verb=""
- _label="Forward" priority="1"
- pixtype="pixbuf"/>
-
- <separator f="" name="emaillist2"/>
-
- <toolitem name="PrintMessage" verb=""
- _label="Print"
- pixtype="pixbuf"/>
-
- <toolitem name="MessageDelete" verb=""
- _label="Delete"
- pixtype="pixbuf"/>
-
- <toolitem name="MessageMarkAsJunk" verb=""
- _label="Junk"
- pixtype="pixbuf"/>
- <toolitem name="MessageMarkAsNotJunk" verb=""
- _label="Not Junk"
- pixtype="pixbuf"/>
- </placeholder>
-
- <placeholder name="MailNextButtons">
- <toolitem name="MailPrevious" verb=""
- _label="Previous"
- pixtype="pixbuf"/>
-
- <toolitem name="MailNext" verb=""
- _label="Next"
- pixtype="pixbuf"/>
- </placeholder>
- </dockitem>
-
-</Root>
diff --git a/ui/evolution-mail-messagedisplay.xml b/ui/evolution-mail-messagedisplay.xml
deleted file mode 100644
index 7e4fcf30a9..0000000000
--- a/ui/evolution-mail-messagedisplay.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<Root>
- <commands>
- <cmd name="MessageBrowserClose" _label="Close" _tip="Close this window"
- pixtype="stock" pixname="Close" accel="*Control*w"/>
- </commands>
-
- <menu>
- <submenu name="File" _label="_File">
- <placeholder name="FileOps"/>
-
- <separator f="" name="emailmessage1"/>
-
- <placeholder name="Print"/>
-
- <separator f="" name="emailmessage2"/>
-
- <menuitem name="MessageBrowserClose" verb=""
- _label="_Close"/>
-
- </submenu>
-
- <submenu name="Edit" _label="_Edit">
- <placeholder name="EditPlaceholder"/>
- </submenu>
-
- <submenu name="View" _label="_View">
- <placeholder name="MailViewType"/>
-
- <placeholder name="MailMessageZoom"/>
- <separator f="" name="CharsetSeparator"/>
- </submenu>
-
- <placeholder name="MessagePlaceholder">
- <submenu name="Message" _label="_Message">
- <placeholder name="MessageTopActions"/>
-
- <separator f="" name="emailglobal"/>
-
- <placeholder name="MessageNavigation"/>
-
- <placeholder name="MailListActions"/>
-
- <placeholder name="MailMessageActions"/>
-
- <separator f="" name="emaillist5"/>
-
- <placeholder name="MessageRuleCreate"/>
-
- </submenu>
- </placeholder>
-
-
-<!--
- <placeholder name="MessagePlaceholder">
- <submenu name="Message" _label="_Message">
-
- <placeholder name="ComponentActionsPlaceholder">
- <placeholder name="MailMessageActions"/>
- </placeholder>
- </submenu>
- </placeholder>
--->
-
- </menu>
-
- <dockitem name="Toolbar"
- relief="none"
- behavior="exclusive"
- _tip="Main toolbar">
- <placeholder name="MailMessageToolbar"/>
- <separator f="" name="emailmessage"/>
- <placeholder name="MailNextButtons"/>
- </dockitem>
-</Root>
diff --git a/ui/evolution-mail-reader.ui b/ui/evolution-mail-reader.ui
new file mode 100644
index 0000000000..374db8f8e4
--- /dev/null
+++ b/ui/evolution-mail-reader.ui
@@ -0,0 +1,138 @@
+<ui>
+ <menubar name='main-menu'>
+ <menu action='file-menu'>
+ <placeholder name='file-actions'>
+ <menuitem action='mail-save-as'/>
+ </placeholder>
+ <placeholder name='print-actions'>
+ <menuitem action='mail-print-preview'/>
+ <menuitem action='mail-print'/>
+ </placeholder>
+ </menu>
+ <menu action='edit-menu'>
+ <placeholder name='edit-actions'>
+ <menuitem action='mail-clipboard-copy'/>
+ <separator/>
+ <menuitem action='mail-select-all'/>
+ <separator/>
+ <menuitem action='mail-delete'/>
+ <menuitem action='mail-undelete'/>
+ <separator/>
+ <menuitem action='mail-find'/>
+ </placeholder>
+ </menu>
+ <menu action='view-menu'>
+ <separator/>
+ <placeholder name='mail-message-list-actions'/>
+ <separator/>
+ <placeholder name='mail-message-view-actions'>
+ <menuitem action='mail-load-images'/>
+ <menuitem action='mail-show-all-headers'/>
+ <menuitem action='mail-caret-mode'/>
+ <menuitem action='mail-show-source'/>
+ <menu action='mail-zoom-menu'>
+ <menuitem action='mail-zoom-in'/>
+ <menuitem action='mail-zoom-out'/>
+ <menuitem action='mail-zoom-100'/>
+ </menu>
+ <separator/>
+ <menu action='mail-encoding-menu'>
+ <menuitem action='mail-charset-default'/>
+ <separator/>
+ </menu>
+ </placeholder>
+ </menu>
+ <placeholder name='custom-menus'>
+ <menu action='mail-message-menu'>
+ <menuitem action='mail-message-new'/>
+ <menuitem action='mail-message-open'/>
+ <menuitem action='mail-message-edit'/>
+ <menuitem action='mail-add-sender'/>
+ <separator/>
+ <menu action='mail-goto-menu'>
+ <menuitem action='mail-next'/>
+ <menuitem action='mail-next-unread'/>
+ <menuitem action='mail-next-important'/>
+ <menuitem action='mail-next-thread'/>
+ <separator/>
+ <menuitem action='mail-previous'/>
+ <menuitem action='mail-previous-unread'/>
+ <menuitem action='mail-previous-important'/>
+ </menu>
+ <menuitem action='mail-reply-sender'/>
+ <menuitem action='mail-reply-list'/>
+ <menuitem action='mail-reply-all'/>
+ <menuitem action='mail-forward'/>
+ <menu action='mail-forward-as-menu'>
+ <menuitem action='mail-forward-attached'/>
+ <menuitem action='mail-forward-inline'/>
+ <menuitem action='mail-forward-quoted'/>
+ <separator/>
+ <menuitem action='mail-redirect'/>
+ </menu>
+ <separator/>
+ <menuitem action='mail-copy'/>
+ <menuitem action='mail-move'/>
+ <separator/>
+ <menu action='mail-mark-as-menu'>
+ <menuitem action="mail-mark-read"/>
+ <menuitem action="mail-mark-unread"/>
+ <separator/>
+ <menuitem action="mail-mark-important"/>
+ <menuitem action="mail-mark-unimportant"/>
+ <separator/>
+ <menuitem action="mail-mark-junk"/>
+ <menuitem action="mail-mark-notjunk"/>
+ <separator/>
+ <menuitem action="mail-flag-for-followup"/>
+ <menuitem action="mail-flag-clear"/>
+ <menuitem action="mail-flag-completed"/>
+ </menu>
+ <menuitem action='mail-filters-apply'/>
+ <menuitem action='mail-check-for-junk'/>
+ <separator/>
+ <menu action='mail-create-rule-menu'>
+ <menuitem action='mail-filter-on-subject'/>
+ <menuitem action='mail-filter-on-sender'/>
+ <menuitem action='mail-filter-on-recipients'/>
+ <menuitem action='mail-filter-on-mailing-list'/>
+ <separator/>
+ <menuitem action='mail-search-folder-from-subject'/>
+ <menuitem action='mail-search-folder-from-sender'/>
+ <menuitem action='mail-search-folder-from-recipients'/>
+ <menuitem action='mail-search-folder-from-mailing-list'/>
+ </menu>
+ <separator/>
+ <placeholder name='mail-message-actions'/>
+ </menu>
+ </placeholder>
+ </menubar>
+ <toolbar name='main-toolbar'>
+ <placeholder name='mail-toolbar-common'>
+ <toolitem action='mail-reply-sender'/>
+ <toolitem action='mail-reply-all'/>
+ <toolitem action='mail-forward'/>
+ <separator/>
+ <toolitem action='mail-print'/>
+ <toolitem action='mail-delete'/>
+ <toolitem action='mail-mark-junk'/>
+ <toolitem action='mail-mark-notjunk'/>
+ </placeholder>
+ <separator/>
+ <placeholder name='mail-toolbar-navigation'>
+ <toolitem action='mail-previous'/>
+ <toolitem action='mail-next'/>
+ </placeholder>
+ </toolbar>
+ <popup name='mail-message-popup'>
+ <placeholder name='mail-message-popup-common-actions'>
+ <menuitem action='mail-popup-reply-sender'/>
+ <menuitem action='mail-popup-reply-all'/>
+ <menuitem action='mail-popup-forward'/>
+ <separator/>
+ <menuitem action='mail-popup-message-edit'/>
+ <menuitem action='mail-popup-save-as'/>
+ <menuitem action='mail-popup-print'/>
+ </placeholder>
+ </popup>
+</ui>
diff --git a/ui/evolution-mail.ui b/ui/evolution-mail.ui
new file mode 100644
index 0000000000..4c607c9fa5
--- /dev/null
+++ b/ui/evolution-mail.ui
@@ -0,0 +1,127 @@
+<ui>
+ <menubar name='main-menu'>
+ <menu action='file-menu'>
+ <placeholder name='long-running-actions'>
+ <menuitem action='mail-empty-trash'/>
+ <menuitem action='mail-download'/>
+ </placeholder>
+ </menu>
+ <menu action='edit-menu'>
+ <placeholder name='administrative-actions'>
+ <menuitem action='mail-tools-filters'/>
+ <menuitem action='mail-tools-search-folders'/>
+ </placeholder>
+ </menu>
+ <menu action='view-menu'>
+ <placeholder name='view-custom-menus'>
+ <menu action='mail-preview-menu'>
+ <menuitem action='mail-preview'/>
+ <separator/>
+ <menuitem action='mail-view-classic'/>
+ <menuitem action='mail-view-vertical'/>
+ </menu>
+ </placeholder>
+ <separator/>
+ <placeholder name='mail-message-list-actions'>
+ <menuitem action='mail-threads-group-by'/>
+ <menuitem action='mail-threads-expand-all'/>
+ <menuitem action='mail-threads-collapse-all'/>
+ <separator/>
+ <menuitem action='mail-hide-deleted'/>
+ <menuitem action='mail-hide-selected'/>
+ <menuitem action='mail-hide-read'/>
+ <menuitem action='mail-show-hidden'/>
+ </placeholder>
+ </menu>
+ <placeholder name='custom-menus'>
+ <menu action='mail-folder-menu'>
+ <menuitem action='mail-folder-new'/>
+ <menuitem action='mail-tools-subscriptions'/>
+ <menuitem action='mail-folder-unsubscribe'/>
+ <separator/>
+ <menuitem action='mail-folder-copy'/>
+ <menuitem action='mail-folder-move'/>
+ <separator/>
+ <menuitem action='mail-folder-select-all'/>
+ <menuitem action='mail-folder-select-thread'/>
+ <menuitem action='mail-folder-select-subthread'/>
+ <menuitem action='mail-folder-mark-all-as-read'/>
+ <menuitem action='mail-folder-expunge'/>
+ <separator/>
+ <menuitem action='mail-folder-rename'/>
+ <menuitem action='mail-folder-refresh'/>
+ <menuitem action='mail-folder-delete'/>
+ <separator/>
+ <menuitem action='mail-folder-properties'/>
+ </menu>
+ </placeholder>
+ <menu action='search-menu'>
+ <placeholder name='search-actions'>
+ <menuitem action='mail-create-search-folder'/>
+ </placeholder>
+ </menu>
+ </menubar>
+ <toolbar name='main-toolbar'>
+ <placeholder name='mail-toolbar-common'/>
+ <toolitem action='mail-stop'/>
+ <separator/>
+ <placeholder name='mail-toolbar-navigation'/>
+ </toolbar>
+ <popup name='mail-folder-popup'>
+ <placeholder name='mail-folder-popup-actions'/>
+ <separator/>
+ <menuitem action='mail-popup-folder-new'/>
+ <menuitem action='mail-popup-folder-copy'/>
+ <menuitem action='mail-popup-folder-move'/>
+ <separator/>
+ <menuitem action='mail-popup-folder-delete'/>
+ <separator/>
+ <menuitem action='mail-popup-folder-rename'/>
+ <menuitem action='mail-popup-folder-refresh'/>
+ <menuitem action='mail-popup-flush-outbox'/>
+ <menuitem action='mail-popup-empty-trash'/>
+ <menuitem action='mail-popup-account-disable'/>
+ <separator/>
+ <menuitem action='mail-popup-folder-unsubscribe'/>
+ <separator/>
+ <menuitem action='mail-popup-folder-properties'/>
+ </popup>
+ <popup name='mail-message-popup'>
+ <placeholder name='mail-message-popup-common-actions'/>
+ <separator/>
+ <menuitem action='mail-popup-delete'/>
+ <menuitem action='mail-popup-undelete'/>
+ <menuitem action='mail-popup-copy'/>
+ <menuitem action='mail-popup-move'/>
+ <separator/>
+ <menuitem action='mail-popup-mark-read'/>
+ <menuitem action='mail-popup-mark-unread'/>
+ <menuitem action='mail-popup-mark-important'/>
+ <menuitem action='mail-popup-mark-unimportant'/>
+ <menuitem action='mail-popup-mark-junk'/>
+ <menuitem action='mail-popup-mark-notjunk'/>
+ <menuitem action='mail-popup-flag-for-followup'/>
+ <menu action='mail-label-menu'>
+ <menuitem action='mail-label-none'/>
+ <separator/>
+ <placeholder name='mail-label-actions'/>
+ <separator/>
+ <menuitem action='mail-label-new'/>
+ </menu>
+ <separator/>
+ <placeholder name='mail-message-templates'/>
+ <separator/>
+ <placeholder name='mail-message-popup-actions'/>
+ </popup>
+ <popup name='mail-search-options'>
+ <menuitem action='mail-search-subject-or-sender-contains'/>
+ <menuitem action='mail-search-subject-or-recipients-contains'/>
+ <menuitem action='mail-search-recipients-contain'/>
+ <menuitem action='mail-search-message-contains'/>
+ <menuitem action='mail-search-subject-contains'/>
+ <menuitem action='mail-search-sender-contains'/>
+ <menuitem action='mail-search-body-contains'/>
+ <separator/>
+ <menuitem action='search-advanced'/>
+ </popup>
+</ui>
diff --git a/ui/evolution-memos.ui b/ui/evolution-memos.ui
new file mode 100644
index 0000000000..f4d4129371
--- /dev/null
+++ b/ui/evolution-memos.ui
@@ -0,0 +1,75 @@
+<ui>
+ <menubar name='main-menu'>
+ <menu action='file-menu'>
+ <placeholder name='file-actions'>
+ <menuitem action='memo-open'/>
+ </placeholder>
+ <placeholder name='print-actions'>
+ <menuitem action='memo-list-print-preview'/>
+ <menuitem action='memo-list-print'/>
+ </placeholder>
+ </menu>
+ <menu action='edit-menu'>
+ <placeholder name='edit-actions'>
+ <menuitem action='memo-clipboard-cut'/>
+ <menuitem action='memo-clipboard-copy'/>
+ <menuitem action='memo-clipboard-paste'/>
+ <separator/>
+ <menuitem action='memo-delete'/>
+ </placeholder>
+ </menu>
+ <menu action='view-menu'>
+ <placeholder name='view-custom-menus'>
+ <menu action='memo-preview-menu'>
+ <menuitem action='memo-preview'/>
+ <separator/>
+ <menuitem action='memo-view-classic'/>
+ <menuitem action='memo-view-vertical'/>
+ </menu>
+ </placeholder>
+ </menu>
+ </menubar>
+ <toolbar name='main-toolbar'>
+ <placeholder name='toolbar-actions'>
+ <toolitem action='memo-clipboard-cut'/>
+ <toolitem action='memo-clipboard-copy'/>
+ <toolitem action='memo-clipboard-paste'/>
+ <separator/>
+ <toolitem action='memo-list-print'/>
+ <toolitem action='memo-delete'/>
+ </placeholder>
+ </toolbar>
+ <popup name='memo-popup'>
+ <menuitem action='memo-new'/>
+ <separator/>
+ <menuitem action='memo-popup-open'/>
+ <menuitem action='memo-popup-open-url'/>
+ <menuitem action='memo-popup-save-as'/>
+ <menuitem action='memo-popup-print'/>
+ <separator/>
+ <menuitem action='memo-popup-clipboard-cut'/>
+ <menuitem action='memo-popup-clipboard-copy'/>
+ <menuitem action='memo-popup-clipboard-paste'/>
+ <separator/>
+ <menuitem action='memo-popup-forward'/>
+ <separator/>
+ <menuitem action='memo-popup-delete'/>
+ </popup>
+ <popup name='memo-list-popup'>
+ <menuitem action='memo-list-new'/>
+ <menuitem action='memo-list-popup-copy'/>
+ <menuitem action='memo-list-popup-rename'/>
+ <separator/>
+ <menuitem action='memo-list-popup-delete'/>
+ <menuitem action='memo-list-popup-select-one'/>
+ <separator/>
+ <menuitem action='memo-list-popup-properties'/>
+ </popup>
+ <popup name='memo-search-options'>
+ <menuitem action='memo-search-summary-contains'/>
+ <menuitem action='memo-search-description-contains'/>
+ <menuitem action='memo-search-any-field-contains'/>
+ <separator/>
+ <menuitem action='search-advanced'/>
+ </popup>
+</ui>
diff --git a/ui/evolution-memos.xml b/ui/evolution-memos.xml
deleted file mode 100644
index 9a132d2add..0000000000
--- a/ui/evolution-memos.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<Root>
- <commands>
- <cmd name="MemosOpenMemo" _tip="View the selected memo" accel="*Control*o"/>
- <cmd name="MemosPrint" _tip="Print the list of memos" pixtype="pixbuf"
- accel="*Control*p"/>
- <cmd name="MemosPrintPreview" _tip="Previews the list of memos to be printed" pixtype="pixbuf"/>
-
- <cmd name="MemosCut" _tip="Cut selected memo" accel="*Control*x" pixtype="pixbuf"/>
- <cmd name="MemosCopy" _tip="Copy selected memo" accel="*Control*c" pixtype="pixbuf"/>
- <cmd name="MemosPaste" _tip="Paste memo from the clipboard" accel="*Control*v" pixtype="pixbuf"/>
- <cmd name="MemosDelete" _tip="Delete selected memos" accel="*Control*d" sensitive="0"
- pixtype="pixbuf"/>
-
- </commands>
-
- <menu>
- <submenu name="File">
- <placeholder name="FileOps">
- <menuitem name="OpenMemo" verb="MemosOpenMemo" _label="_Open Memo"/>
- </placeholder>
- <placeholder name="Print">
- <menuitem name="PrintPreview" verb="MemosPrintPreview" _label="Print Pre_view"/>
-
- <menuitem name="Print" verb="MemosPrint" accel="*Control*p" _label="_Print..."/>
- </placeholder>
-
- </submenu>
-
- <submenu name="Edit" _label="_Edit">
- <placeholder name="EditPlaceholder">
- <menuitem name="MemosCut" verb="" _label="C_ut"/>
- <menuitem name="MemosCopy" verb="" _label="_Copy"/>
- <menuitem name="MemosPaste" verb="" _label="_Paste"/>
-
- <separator/>
-
- <menuitem name="MemosDelete" verb="" _label="_Delete"/>
- </placeholder>
- </submenu>
-
- </menu>
-
- <dockitem name="Toolbar">
- <toolitem name="Cut" _label="Cut" verb="MemosCut" pixtype="pixbuf"/>
- <toolitem name="Copy" _label="Copy" verb="MemosCopy" pixtype="pixbuf"/>
- <toolitem name="Paste" _label="Paste" verb="MemosPaste" pixtype="pixbuf"/>
-
- <separator/>
-
- <toolitem name="Print" _label="Print" verb="MemosPrint" pixtype="pixbuf"/>
-
- <toolitem name="Delete" _label="Delete" verb="MemosDelete" pixtype="pixbuf"/>
-
- </dockitem>
-
-</Root>
diff --git a/ui/evolution-shell.ui b/ui/evolution-shell.ui
new file mode 100644
index 0000000000..7a89e11adc
--- /dev/null
+++ b/ui/evolution-shell.ui
@@ -0,0 +1,82 @@
+<ui>
+ <menubar name='main-menu'>
+ <menu action='file-menu'>
+ <menu action='new-menu'/>
+ <menuitem action='new-window'/>
+ <separator/>
+ <menuitem action='send-receive'/>
+ <placeholder name='file-actions'/>
+ <separator/>
+ <menuitem action='import'/>
+ <separator/>
+ <menuitem action='page-setup'/>
+ <placeholder name='print-actions'/>
+ <separator/>
+ <placeholder name='long-running-actions'/>
+ <menuitem action='forget-passwords'/>
+ <menuitem action='work-online'/>
+ <menuitem action='work-offline'/>
+ <menuitem action='close'/>
+ <menuitem action='quit'/>
+ </menu>
+ <menu action='edit-menu'>
+ <placeholder name='edit-actions'/>
+ <separator/>
+ <menuitem action='sync-options'/>
+ <placeholder name='administrative-actions'/>
+ <menuitem action='preferences'/>
+ </menu>
+ <menu action='view-menu'>
+ <menu action='gal-view-menu'>
+ <placeholder name='gal-view-list'/>
+ <separator/>
+ <menuitem action='gal-custom-view'/>
+ <menuitem action='gal-save-custom-view'/>
+ <separator/>
+ <menuitem action='gal-define-views'/>
+ </menu>
+ <menu action='window-menu'/>
+ <menu action='layout-menu'>
+ <menuitem action='show-toolbar'/>
+ <menuitem action='show-statusbar'/>
+ <menuitem action='show-sidebar'/>
+ </menu>
+ <placeholder name='view-custom-menus'/>
+ <menu action='switcher-menu'>
+ <menuitem action='switcher-style-both'/>
+ <menuitem action='switcher-style-icons'/>
+ <menuitem action='switcher-style-text'/>
+ <menuitem action='switcher-style-user'/>
+ <separator/>
+ <menuitem action='show-switcher'/>
+ </menu>
+ </menu>
+ <placeholder name='custom-menus'/>
+ <menu action='search-menu'>
+ <menuitem action='search-execute'/>
+ <menuitem action='search-clear'/>
+ <menuitem action='search-advanced'/>
+ <separator/>
+ <menuitem action='search-save'/>
+ <menuitem action='search-edit'/>
+ <separator/>
+ <placeholder name='search-actions'/>
+ <separator/>
+ <placeholder name='custom-rules'/>
+ </menu>
+ <menu action='help-menu'>
+ <menuitem action='contents'/>
+ <menuitem action='quick-reference'/>
+ <separator/>
+ <menuitem action='faq'/>
+ <menuitem action='submit-bug'/>
+ <separator/>
+ <menuitem action='about'/>
+ </menu>
+ </menubar>
+ <toolbar name='main-toolbar'>
+ <toolitem action='send-receive'/>
+ <separator/>
+ <placeholder name='toolbar-actions'/>
+ </toolbar>
+</ui>
diff --git a/ui/evolution-tasks.ui b/ui/evolution-tasks.ui
new file mode 100644
index 0000000000..e8d6f768eb
--- /dev/null
+++ b/ui/evolution-tasks.ui
@@ -0,0 +1,86 @@
+<ui>
+ <menubar name='main-menu'>
+ <menu action='file-menu'>
+ <placeholder name='file-actions'>
+ <menuitem action='task-open'/>
+ </placeholder>
+ <placeholder name='print-actions'>
+ <menuitem action='task-list-print-preview'/>
+ <menuitem action='task-list-print'/>
+ </placeholder>
+ </menu>
+ <menu action='edit-menu'>
+ <placeholder name='edit-actions'>
+ <menuitem action='task-clipboard-cut'/>
+ <menuitem action='task-clipboard-copy'/>
+ <menuitem action='task-clipboard-paste'/>
+ <separator/>
+ <menuitem action='task-delete'/>
+ <separator/>
+ <menuitem action='task-mark-complete'/>
+ <menuitem action='task-mark-incomplete'/>
+ </placeholder>
+ </menu>
+ <menu action='view-menu'>
+ <placeholder name='view-custom-menus'>
+ <menu action='task-preview-menu'>
+ <menuitem action='task-preview'/>
+ <separator/>
+ <menuitem action='task-view-classic'/>
+ <menuitem action='task-view-vertical'/>
+ </menu>
+ </placeholder>
+ </menu>
+ <placeholder name='custom-menus'>
+ <menu action='task-actions-menu'>
+ <menuitem action='task-purge'/>
+ <menuitem action='task-assign'/>
+ <menuitem action='task-forward'/>
+ </menu>
+ </placeholder>
+ </menubar>
+ <toolbar name='main-toolbar'>
+ <toolitem action='task-clipboard-cut'/>
+ <toolitem action='task-clipboard-copy'/>
+ <toolitem action='task-clipboard-paste'/>
+ <separator/>
+ <toolitem action='task-print'/>
+ <toolitem action='task-delete'/>
+ </toolbar>
+ <popup name='task-popup'>
+ <menuitem action='task-new'/>
+ <separator/>
+ <menuitem action='task-popup-open'/>
+ <menuitem action='task-popup-open-url'/>
+ <menuitem action='task-popup-save-as'/>
+ <menuitem action='task-popup-print'/>
+ <separator/>
+ <menuitem action='task-popup-clipboard-cut'/>
+ <menuitem action='task-popup-clipboard-copy'/>
+ <menuitem action='task-popup-clipboard-paste'/>
+ <separator/>
+ <menuitem action='task-popup-assign'/>
+ <menuitem action='task-popup-forward'/>
+ <menuitem action='task-popup-mark-complete'/>
+ <menuitem action='task-popup-mark-incomplete'/>
+ <separator/>
+ <menuitem action='task-popup-delete'/>
+ </popup>
+ <popup name='task-list-popup'>
+ <menuitem action='task-list-new'/>
+ <menuitem action='task-list-popup-copy'/>
+ <menuitem action='task-list-popup-rename'/>
+ <separator/>
+ <menuitem action='task-list-popup-delete'/>
+ <menuitem action='task-list-popup-select-one'/>
+ <separator/>
+ <menuitem action='task-list-popup-properties'/>
+ </popup>
+ <popup name='task-search-options'>
+ <menuitem action='task-search-summary-contains'/>
+ <menuitem action='task-search-description-contains'/>
+ <menuitem action='task-search-any-field-contains'/>
+ <separator/>
+ <menuitem action='search-advanced'/>
+ </popup>
+</ui>
diff --git a/ui/evolution-tasks.xml b/ui/evolution-tasks.xml
deleted file mode 100644
index e0902b6806..0000000000
--- a/ui/evolution-tasks.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<Root>
- <commands>
- <cmd name="TasksOpenTask" _tip="View the selected task" accel="*Control*o"/>
- <cmd name="TasksPrint" _tip="Print the list of tasks" pixtype="pixbuf"
- accel="*Control*p"/>
- <cmd name="TasksPrintPreview" _tip="Previews the list of tasks to be printed" pixtype="pixbuf"/>
-
- <cmd name="TasksCut" _tip="Cut selected tasks" accel="*Control*x" pixtype="pixbuf"/>
- <cmd name="TasksCopy" _tip="Copy selected tasks" accel="*Control*c" pixtype="pixbuf"/>
- <cmd name="TasksPaste" _tip="Paste tasks from the clipboard" accel="*Control*v" pixtype="pixbuf"/>
- <cmd name="TasksDelete" _tip="Delete selected tasks" accel="*Control*d" sensitive="0"
- pixtype="pixbuf"/>
- <cmd name="TasksMarkComplete" _tip="Mark selected tasks as complete" accel="*Control*k" sensitive="0"/>
-
- <cmd name="TasksPurge" _label="Purg_e" _tip="Delete completed tasks" accel="*Control*e"/>
- <cmd name="TasksAssign" _label="_Assign Task"/>
- <cmd name="TasksForward" _label="_Forward as iCalendar" accel="*Control*f" pixtype="pixbuf"/>
-
- <cmd name="ViewPreview" _tip="Show task preview window" accel="*Control*m" type="toggle"/>
-
- </commands>
-
- <menu>
- <submenu name="File">
- <placeholder name="FileOps">
- <menuitem name="OpenTask" verb="TasksOpenTask" _label="_Open Task"/>
- </placeholder>
- <placeholder name="Print">
- <menuitem name="PrintPreview" verb="TasksPrintPreview" _label="Print Pre_view"/>
-
- <menuitem name="Print" verb="TasksPrint" accel="*Control*p" _label="_Print..."/>
- </placeholder>
-
- </submenu>
-
- <submenu name="Edit" _label="_Edit">
- <placeholder name="EditPlaceholder">
- <menuitem name="TasksCut" verb="" _label="C_ut"/>
- <menuitem name="TasksCopy" verb="" _label="_Copy"/>
- <menuitem name="TasksPaste" verb="" _label="_Paste"/>
-
- <separator/>
-
- <menuitem name="TasksDelete" verb="" _label="_Delete"/>
-
- <separator/>
-
- <menuitem name="TasksMarkComplete" verb="" _label="Mar_k as Complete"/>
- </placeholder>
- </submenu>
-
- <submenu name="View" _label="_View">
- <placeholder name="ViewPreview">
- <menuitem name="ViewPreview" verb="" _label="Task _Preview"/>
- </placeholder>
- </submenu>
-
- <placeholder name="ActionsPlaceholder">
- <submenu name="Actions" _label="_Actions">
- <menuitem name="TasksPurge" verb=""/>
- <menuitem name="TasksAssign" verb=""/>
- <menuitem name="TasksForward" verb=""/>
- </submenu>
- </placeholder>
-
- </menu>
-
- <dockitem name="Toolbar">
- <toolitem name="Cut" _label="Cut" verb="TasksCut" pixtype="pixbuf"/>
- <toolitem name="Copy" _label="Copy" verb="TasksCopy" pixtype="pixbuf"/>
- <toolitem name="Paste" _label="Paste" verb="TasksPaste" pixtype="pixbuf"/>
-
- <separator/>
-
- <toolitem name="Print" _label="Print" verb="TasksPrint" pixtype="pixbuf"/>
-
- <toolitem name="Delete" _label="Delete" verb="TasksDelete" pixtype="pixbuf"/>
-
- </dockitem>
-
-</Root>
diff --git a/ui/evolution.xml b/ui/evolution.xml
deleted file mode 100644
index 2b4ee71d3b..0000000000
--- a/ui/evolution.xml
+++ /dev/null
@@ -1,199 +0,0 @@
-<Root>
- <commands>
- <cmd name="OpenNewWindow" _label="New _Window"
- _tip="Create a new window displaying this folder"
- accel="*Control**Shift*w"/>
-
- <cmd name="FilePageSetup" _label="Page Set_up..." _tip="Set up the page settings for your current printer"/>
-
- <cmd name="FileClose" _label="_Close Window" _tip="Close this window"
- accel="*Control*w"/>
-
- <cmd name="FileExit" _label="_Quit" _tip="Exit the program"
- accel="*Control*q"/>
-
- <cmd name="ViewButtonsIconText" _label="Icons _and Text"
- type="radio" group="button_display" _tip="Display window buttons with icons and text"/>
-
- <cmd name="ViewButtonsIcon" _label="_Icons Only"
- type="radio" group="button_display" _tip="Display window buttons with icons only"/>
-
- <cmd name="ViewButtonsText" _label="_Text Only"
- type="radio" group="button_display" _tip="Display window buttons with text only"/>
-
- <cmd name="ViewButtonsToolbar" _label="Tool_bar Style"
- type="radio" group="button_display" _tip="Display window buttons using the desktop toolbar setting"/>
-
- <cmd name="ViewButtonsHide" _label="_Hide Buttons"
- type="toggle" _tip="Hide window buttons"/>
-
- <cmd name="ViewToolbar" _label="Show _Toolbar" type="toggle"
- _tip="Change the visibility of the toolbar" state="1"/>
-
- <cmd name="ViewStatusBar" _label="Show _Status Bar" type="toggle"
- _tip="View/Hide the Status Bar" state="1"/>
-
- <cmd name="ViewSideBar" _label="Show Side _Bar" type="toggle"
- _tip="View/Hide the Side Bar" state="1"/>
-
- <cmd name="HelpSubmitBug" _label="Submit Bug Report"
- _tip="Submit a bug report using Bug Buddy"/>
-
- <cmd name="HelpOpenFAQ" _label="_Frequently Asked Questions"
- _tip="Open the Frequently Asked Questions webpage"/>
-
- <cmd name="SendReceive"
- _tip="Send queued items and retrieve new items"
- pixtype="pixbuf"/>
-
- <cmd name="ForgetPasswords"
- _tip="Forget remembered passwords so you will be prompted for them again"/>
-
- <cmd name="Settings" pixtype="stock" pixname="gtk-preferences"/>
-
- <cmd name="ToggleOffline"
- _label="Work _Offline"
- _tip="Toggle whether we are working offline."/>
-
- <cmd name="HelpAbout" _label="About Evolution..."
- _tip="Show information about Evolution"
- pixtype="stock" pixname="gtk-about"/>
- </commands>
-
- <menu>
- <submenu name="File" _label="_File">
- <submenu name="New" _label="_New" pixtype="stock" pixname="gtk-new">
- <placeholder name="ComponentItems"/>
- </submenu>
-
- <menuitem name="OpenNewWindow" verb="" pixtype="pixbuf"/>
-
- <separator f="" name="eshell4"/>
-
- <menuitem name="SendReceive" verb="" _label="Send / _Receive"
- pixtype="pixbuf" accel="F9"/>
-
- <placeholder name="FileOps"/>
-
- <separator f="" name="eshell1"/>
-
- <menuitem name="FileImporter" verb=""
- _label="I_mport..."
- _tip="Import data from other programs"
- pixtype="pixbuf"/>
-
- <placeholder name="Print" delimit="top">
- <menuitem name="FilePageSetup" verb="" pixtype="pixbuf"/>
- </placeholder>
-
-<!--
- <placeholder name="ComponentPlaceholder"/>
--->
-
- <separator f="" name="eshell5"/>
-
- <placeholder name="EmptyTrashPlaceholder"/>
-
-
- <menuitem name="ForgetPasswords" verb="" _label="_Forget Passwords"/>
-
- <menuitem name="ToggleOffline" verb=""
- _label="_Work Offline"
- pixtype="pixbuf"/>
-
- <menuitem name="FileClose" verb=""
- _label="_Close Window"
- pixtype="pixbuf"/>
-
- <menuitem name="FileExit" verb="FileExit"
- pixtype="pixbuf"/>
- </submenu>
-
- <submenu name="Edit" _label="_Edit">
- <placeholder name="EditPlaceholder"/>
- <separator/>
- <menuitem name="PilotSettings" verb="" _label="_Synchronization Options..." _tip="Set up Pilot configuration"/>
- <placeholder name="MailFilterTools"/>
- <placeholder name="MailVFolderTools"/>
-
- <placeholder name="PluginManagerPlaceholder"/>
-
- <menuitem name="Settings" verb="" _label="Prefere_nces" _tip="Change Evolution's settings" accel="*Control**Shift*s"/>
- </submenu>
-
- <submenu name="View" _label="_View">
- <placeholder name="ViewBegin"/>
- <submenu name="Window" _label="_Window"/>
- <submenu name="layout" _label="Lay_out">
- <menuitem name="ViewToolbar" id="ViewToolbar" verb=""/>
- <menuitem name="ViewStatusBar" id="ViewStatusBar"/>
- <menuitem name="ViewSideBar" id="ViewSideBar"/>
- </submenu>
- <placeholder name="ViewPreview"/>
- <submenu name="Buttons" _label="_Switcher Appearance">
- <menuitem name="ViewButtonsIconText" id="ViewButtonsIconText" verb=""/>
- <menuitem name="ViewButtonsIcon" id="ViewButtonsIcon" verb=""/>
- <menuitem name="ViewButtonsText" id="ViewButtonsText" verb=""/>
- <menuitem name="ViewButtonsGnome" id="ViewButtonsToolbar" verb=""/>
- <separator f="" name="Switcher1"/>
- <menuitem name="ViewButtonsHide" id="ViewButtonsHide" verb=""/>
- </submenu>
- <placeholder name="ViewAfterControl"/>
- </submenu>
-
- <placeholder name="FolderPlaceholder">
- </placeholder>
-
- <placeholder name="MessagePlaceholder">
- </placeholder>
-
- <placeholder name="ActionsPlaceholder">
- </placeholder>
-
- <placeholder name="SearchPlaceholder">
- </placeholder>
-
- <submenu name="Help" _label="_Help">
-
- <placeholder name="BuiltMenuItems"/>
-
- <menuitem name="QuickReference" verb=""
- _label="_Quick Reference"/>
-
- <separator f="" name="eshell2"/>
- <placeholder name="PlaceHolderDebug"/>
-
- <menuitem name="HelpOpenFAQ" verb=""
- _label="Evolution _FAQ"
- pixtype="pixbuf"/>
-
- <menuitem name="HelpSubmitBug" verb=""
- _label="Submit _Bug Report"/>
-
- <separator f="" name="eshell4"/>
-
- <menuitem name="HelpAbout" verb=""
- _label="_About"/>
-
- </submenu>
- </menu>
-
- <dockitem name="Toolbar" relief="none" behavior="exclusive" config="0" _tip="Main toolbar" look="system">
- <control name="NewComboButton"/>
- <separator f="" name="eshell4"/>
-
- <toolitem name="SendReceive" verb="SendReceive"
- _label="Send / Receive" priority="1"
- pixtype="pixbuf"/>
-
- <separator f="" name="global1"/>
-
- </dockitem>
-
- <popups>
- <popup name="NewPopup">
- <placeholder name="ComponentItems"/>
- </popup>
- </popups>
-
-</Root>
diff --git a/widgets/Makefile.am b/widgets/Makefile.am
index 347c0f7c66..99305b844e 100644
--- a/widgets/Makefile.am
+++ b/widgets/Makefile.am
@@ -1,9 +1,9 @@
SUBDIRS = \
- table \
- text \
misc \
+ text \
e-timezone-dialog \
+ table \
menus
EXTRA_DIST = \
diff --git a/widgets/e-timezone-dialog/e-timezone-dialog.c b/widgets/e-timezone-dialog/e-timezone-dialog.c
index 22eaabfc3a..8f22695916 100644
--- a/widgets/e-timezone-dialog/e-timezone-dialog.c
+++ b/widgets/e-timezone-dialog/e-timezone-dialog.c
@@ -349,7 +349,7 @@ get_local_timezone(void)
location = e_cal_system_timezone_get_location ();
if (location)
- zone = icaltimezone_get_builtin_timezone (location);
+ zone = icaltimezone_get_builtin_timezone (location);
g_free (location);
diff --git a/widgets/menus/Makefile.am b/widgets/menus/Makefile.am
index f67a07370c..f07ae41d14 100644
--- a/widgets/menus/Makefile.am
+++ b/widgets/menus/Makefile.am
@@ -8,7 +8,6 @@ AM_CPPFLAGS = \
$(E_UTIL_CFLAGS)
libmenus_la_SOURCES = \
- gal-view-menus.c \
gal-define-views-dialog.c \
gal-define-views-model.c \
gal-view-collection.c \
@@ -18,8 +17,7 @@ libmenus_la_SOURCES = \
gal-view-instance-save-as-dialog.c \
gal-view-instance.c \
gal-view-new-dialog.c \
- gal-view.c \
- gal-view-menus.h
+ gal-view.c
glade_DATA = \
gal-define-views.glade \
diff --git a/widgets/menus/gal-view-collection.c b/widgets/menus/gal-view-collection.c
index 801a941ba4..5719e17f6b 100644
--- a/widgets/menus/gal-view-collection.c
+++ b/widgets/menus/gal-view-collection.c
@@ -33,7 +33,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "e-util/e-xml-utils.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "gal-view-collection.h"
diff --git a/widgets/menus/gal-view-instance.c b/widgets/menus/gal-view-instance.c
index b539965abc..bd93b64034 100644
--- a/widgets/menus/gal-view-instance.c
+++ b/widgets/menus/gal-view-instance.c
@@ -38,7 +38,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "e-util/e-xml-utils.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "gal-define-views-dialog.h"
#include "gal-view-instance.h"
@@ -46,9 +46,6 @@
G_DEFINE_TYPE (GalViewInstance, gal_view_instance, G_TYPE_OBJECT)
-static const EPopupMenu separator = E_POPUP_SEPARATOR;
-static const EPopupMenu terminator = E_POPUP_TERMINATOR;
-
#define d(x)
enum {
@@ -466,140 +463,3 @@ gal_view_instance_exists (GalViewInstance *instance)
return FALSE;
}
-
-typedef struct {
- GalViewInstance *instance;
- gchar *id;
-} ListenerClosure;
-
-static void
-view_item_cb (GtkWidget *widget,
- gpointer user_data)
-{
- ListenerClosure *closure = user_data;
-
- if (GTK_CHECK_MENU_ITEM (widget)->active) {
- gal_view_instance_set_current_view_id (closure->instance, closure->id);
- }
-}
-
-static void
-add_popup_radio_item (EPopupMenu *menu_item,
- const gchar *title,
- GCallback fn,
- gpointer closure,
- gboolean value)
-{
- EPopupMenu menu_item_struct =
- E_POPUP_RADIO_ITEM_CC (title,
- fn,
- closure,
- 0,
- 0);
- menu_item_struct.is_active = value;
-
- e_popup_menu_copy_1 (menu_item, &menu_item_struct);
-}
-
-static void
-add_popup_menu_item (EPopupMenu *menu_item,
- const gchar *title,
- GCallback fn,
- gpointer closure)
-{
- EPopupMenu menu_item_struct =
- E_POPUP_ITEM_CC (title,
- fn,
- closure,
- 0);
-
- e_popup_menu_copy_1 (menu_item, &menu_item_struct);
-}
-
-static void
-define_views_dialog_response(GtkWidget *dialog, gint id, GalViewInstance *instance)
-{
- if (id == GTK_RESPONSE_OK) {
- gal_view_collection_save(instance->collection);
- }
- gtk_widget_destroy (dialog);
-}
-
-static void
-define_views_cb(GtkWidget *widget,
- GalViewInstance *instance)
-{
- GtkWidget *dialog = gal_define_views_dialog_new(instance->collection);
- g_signal_connect(dialog, "response",
- G_CALLBACK(define_views_dialog_response), instance);
- gtk_widget_show(dialog);
-}
-
-static void
-save_current_view_cb(GtkWidget *widget,
- GalViewInstance *instance)
-{
- gal_view_instance_save_as (instance);
-}
-
-EPopupMenu *
-gal_view_instance_get_popup_menu (GalViewInstance *instance)
-{
- EPopupMenu *ret_val;
- gint length;
- gint i;
- gboolean found = FALSE;
- gchar *id;
-
- length = gal_view_collection_get_count(instance->collection);
- id = gal_view_instance_get_current_view_id (instance);
-
- ret_val = g_new (EPopupMenu, length + 6);
-
- for (i = 0; i < length; i++) {
- gboolean value = FALSE;
- GalViewCollectionItem *item = gal_view_collection_get_view_item(instance->collection, i);
- ListenerClosure *closure;
-
- closure = g_new (ListenerClosure, 1);
- closure->instance = instance;
- closure->id = item->id;
- g_object_ref (closure->instance);
-
- if (!found && id && !strcmp (id, item->id)) {
- found = TRUE;
- value = TRUE;
- }
-
- add_popup_radio_item (ret_val + i, item->title, G_CALLBACK (view_item_cb), closure, value);
- }
-
- if (!found) {
- e_popup_menu_copy_1 (ret_val + i++, &separator);
-
- add_popup_radio_item (ret_val + i++, N_("Custom View"), NULL, NULL, TRUE);
- add_popup_menu_item (ret_val + i++, N_("Save Custom View"), G_CALLBACK (save_current_view_cb), instance);
- }
-
- e_popup_menu_copy_1 (ret_val + i++, &separator);
- add_popup_menu_item (ret_val + i++, N_("Define Views..."), G_CALLBACK (define_views_cb), instance);
- e_popup_menu_copy_1 (ret_val + i++, &terminator);
-
- if (id)
- g_free (id);
-
- return ret_val;
-}
-
-void
-gal_view_instance_free_popup_menu (GalViewInstance *instance, EPopupMenu *menu)
-{
- gint i;
- /* This depends on the first non-custom closure to be a separator or a terminator. */
- for (i = 0; menu[i].name && *(menu[i].name); i++) {
- g_object_unref (((ListenerClosure *)(menu[i].closure))->instance);
- g_free (menu[i].closure);
- }
-
- e_popup_menu_free (menu);
-}
diff --git a/widgets/menus/gal-view-instance.h b/widgets/menus/gal-view-instance.h
index 65aea4b0fd..00f5065d35 100644
--- a/widgets/menus/gal-view-instance.h
+++ b/widgets/menus/gal-view-instance.h
@@ -26,7 +26,6 @@
#include <glib-object.h>
#include <widgets/menus/gal-view-collection.h>
-#include <misc/e-popup-menu.h>
G_BEGIN_DECLS
@@ -106,10 +105,6 @@ const gchar *gal_view_instance_get_default_view (GalViewInstance *ins
void gal_view_instance_set_default_view (GalViewInstance *instance,
const gchar *id);
-EPopupMenu *gal_view_instance_get_popup_menu (GalViewInstance *instance);
-void gal_view_instance_free_popup_menu (GalViewInstance *instance,
- EPopupMenu *menu);
-
G_END_DECLS
#endif /* _GAL_VIEW_INSTANCE_H_ */
diff --git a/widgets/menus/gal-view-menus.c b/widgets/menus/gal-view-menus.c
deleted file mode 100644
index de51da49c1..0000000000
--- a/widgets/menus/gal-view-menus.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * gal-view-menus.c: Deploy a GalViewCollection in the menus.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "gal-view-menus.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-#include <glib/gi18n.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <e-util/e-util.h>
-#include <e-util/e-xml-utils.h>
-#include <widgets/menus/gal-define-views-dialog.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <libedataserver/e-list.h>
-
-struct _GalViewMenusPrivate {
- GalViewInstance *instance;
- gint collection_changed_id;
- gint instance_changed_id;
- BonoboUIComponent *component;
- EList *listenerClosures;
- GtkWidget *define_views_dialog;
-
- guint show_define_views : 1;
-};
-
-typedef struct {
- GalViewInstance *instance;
- gchar *id;
- gint ref_count;
-} ListenerClosure;
-
-static void collection_changed (GalViewCollection *collection,
- GalViewMenus *gvm);
-static void instance_changed (GalViewInstance *instance,
- GalViewMenus *gvm);
-
-#define d(x)
-#define CURRENT_VIEW_PATH "/menu/View/ViewBegin/CurrentView"
-
-G_DEFINE_TYPE(GalViewMenus, gal_view_menus, G_TYPE_OBJECT)
-
-static void
-closure_free (gpointer data, gpointer user_data)
-{
- ListenerClosure *closure = data;
- GalViewMenus *gvm = user_data;
-
- closure->ref_count --;
- if (closure->ref_count == 0) {
- g_object_unref (closure->instance);
-
- bonobo_ui_component_remove_listener (gvm->priv->component, closure->id);
- g_free (closure);
- }
-}
-
-static gpointer
-closure_copy (gconstpointer data, gpointer user_data)
-{
- ListenerClosure *closure = (gpointer) data;
-
- closure->ref_count ++;
- return closure;
-}
-
-static void
-remove_listeners (GalViewMenus *gvm)
-{
- if (gvm->priv->listenerClosures)
- g_object_unref (gvm->priv->listenerClosures);
-
- gvm->priv->listenerClosures = NULL;
-}
-
-static void
-remove_xml (GalViewMenus *gvm)
-{
-}
-
-static void
-remove_instance (GalViewMenus *gvm)
-{
- if (gvm->priv->instance) {
- if (gvm->priv->instance_changed_id != 0)
- g_signal_handler_disconnect (gvm->priv->instance, gvm->priv->instance_changed_id);
-
- if (gvm->priv->instance->collection && gvm->priv->collection_changed_id != 0)
- g_signal_handler_disconnect (gvm->priv->instance->collection, gvm->priv->collection_changed_id);
- }
-
- gvm->priv->instance_changed_id = 0;
- gvm->priv->collection_changed_id = 0;
-
- if (gvm->priv->instance) {
- g_object_unref (gvm->priv->instance);
- gvm->priv->instance = NULL;
- }
-
- remove_listeners(gvm);
- remove_xml(gvm);
-}
-
-static void
-add_instance (GalViewMenus *gvm,
- GalViewInstance *instance)
-{
- g_object_ref (instance);
-
- if (gvm->priv->instance != NULL)
- remove_instance (gvm);
-
- gvm->priv->instance = instance;
-
- gal_view_instance_load (gvm->priv->instance);
-
- gvm->priv->instance_changed_id = g_signal_connect (instance, "changed",
- G_CALLBACK (instance_changed), gvm);
- gvm->priv->collection_changed_id = g_signal_connect (instance->collection, "changed",
- G_CALLBACK (collection_changed), gvm);
-}
-
-static void
-clear_define_views_dialog (gpointer data,
- GObject *where_the_object_was)
-{
- GalViewMenus *gvm = GAL_VIEW_MENUS (data);
- gvm->priv->define_views_dialog = NULL;
-}
-
-static void
-gal_view_menus_finalize (GObject *object)
-{
- GalViewMenus *gvm = GAL_VIEW_MENUS (object);
-
- remove_instance (gvm);
-
- gal_view_menus_unmerge (gvm, NULL);
-
- if (gvm->priv->component)
- bonobo_object_unref (gvm->priv->component);
-
- if (gvm->priv->define_views_dialog)
- g_object_weak_unref (G_OBJECT (gvm->priv->define_views_dialog), clear_define_views_dialog, gvm);
-
- g_free(gvm->priv);
-
- (* G_OBJECT_CLASS (gal_view_menus_parent_class)->finalize) (object);
-}
-
-static void
-gal_view_menus_class_init (GalViewMenusClass *gvm_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (gvm_class);
-
- object_class->finalize = gal_view_menus_finalize;
-}
-
-static void
-gal_view_menus_init (GalViewMenus *gvm)
-{
- gvm->priv = g_new(GalViewMenusPrivate, 1);
- gvm->priv->instance = NULL;
- gvm->priv->collection_changed_id = 0;
- gvm->priv->instance_changed_id = 0;
- gvm->priv->component = NULL;
- gvm->priv->listenerClosures = NULL;
- gvm->priv->define_views_dialog = NULL;
- gvm->priv->show_define_views = TRUE;
-}
-
-GalViewMenus *
-gal_view_menus_new (GalViewInstance *instance)
-{
- GalViewMenus *gvm;
-
- g_return_val_if_fail (instance != NULL, NULL);
- g_return_val_if_fail (GAL_IS_VIEW_INSTANCE (instance), NULL);
-
- gvm = g_object_new (GAL_VIEW_MENUS_TYPE, NULL);
- gal_view_menus_construct(gvm, instance);
-
- return gvm;
-}
-
-GalViewMenus *
-gal_view_menus_construct (GalViewMenus *gvm,
- GalViewInstance *instance)
-{
- g_return_val_if_fail (gvm != NULL, NULL);
- g_return_val_if_fail (GAL_IS_VIEW_MENUS (gvm), NULL);
- g_return_val_if_fail (instance != NULL, NULL);
- g_return_val_if_fail (GAL_IS_VIEW_INSTANCE (instance), NULL);
-
- add_instance (gvm, instance);
-
- return gvm;
-}
-
-static void
-dialog_response(GtkWidget *dialog, gint id, GalViewMenus *menus)
-{
- if (id == GTK_RESPONSE_OK) {
- gal_view_collection_save(menus->priv->instance->collection);
- }
- gtk_widget_destroy(dialog);
-}
-
-static void
-define_views(BonoboUIComponent *component,
- GalViewMenus *menus,
- gchar *cname)
-{
- if (menus->priv->define_views_dialog) {
- gdk_window_raise (menus->priv->define_views_dialog->window);
- } else {
- GtkWidget *dialog = gal_define_views_dialog_new(menus->priv->instance->collection);
-
- g_signal_connect (dialog, "response", G_CALLBACK (dialog_response), menus);
- menus->priv->define_views_dialog = dialog;
- g_object_weak_ref (G_OBJECT (dialog), clear_define_views_dialog, menus);
- gtk_widget_show(dialog);
- }
-}
-
-static void
-save_current_view(BonoboUIComponent *component,
- GalViewMenus *menus,
- gchar *cname)
-{
- gal_view_instance_save_as (menus->priv->instance);
-}
-
-static void
-toggled_cb (BonoboUIComponent *component,
- const gchar *path,
- Bonobo_UIComponent_EventType type,
- const gchar *state,
- gpointer user_data)
-{
- ListenerClosure *closure = user_data;
-
- /* do nothing on state change to untoggled */
- if (!strcmp (state, "0"))
- return;
-
- g_print ("%s\n", path);
-
- gal_view_instance_set_current_view_id (closure->instance, closure->id);
-}
-
-static gchar *
-build_menus(GalViewMenus *menus)
-{
- BonoboUINode *root, *menu, *submenu, *place, *menuitem, *commands, *command;
- gchar *xml;
- gint length;
- gint i;
- GalViewInstance *instance = menus->priv->instance;
- GalViewCollection *collection = instance->collection;
- gchar *id;
- gboolean found = FALSE;
-
- root = bonobo_ui_node_new("Root");
- menu = bonobo_ui_node_new_child(root, "menu");
- commands = bonobo_ui_node_new_child (root, "commands");
-
- submenu = bonobo_ui_node_new_child(menu, "submenu");
- bonobo_ui_node_set_attr(submenu, "name", "View");
-
- place = bonobo_ui_node_new_child(submenu, "placeholder");
- bonobo_ui_node_set_attr(place, "name", "ViewBegin");
-
- submenu = bonobo_ui_node_new_child(place, "submenu");
- bonobo_ui_node_set_attr(submenu, "name", "CurrentView");
- bonobo_ui_node_set_attr(submenu, "_label", N_("C_urrent View"));
-
- id = gal_view_instance_get_current_view_id (instance);
-
- length = gal_view_collection_get_count(collection);
-
- menus->priv->listenerClosures = e_list_new (closure_copy, closure_free, menus);
-
- for (i = 0; i < length; i++) {
- GalViewCollectionItem *item = gal_view_collection_get_view_item(collection, i);
- ListenerClosure *closure;
- gchar *label;
- gchar *tip;
-
- menuitem = bonobo_ui_node_new_child(submenu, "menuitem");
- bonobo_ui_node_set_attr(menuitem, "name", item->id);
- bonobo_ui_node_set_attr(menuitem, "id", item->id);
- bonobo_ui_node_set_attr(menuitem, "group", "GalViewMenus");
- bonobo_ui_node_set_attr(menuitem, "type", "radio");
-
- command = bonobo_ui_node_new_child (commands, "cmd");
- bonobo_ui_node_set_attr(command, "name", item->id);
- bonobo_ui_node_set_attr(command, "group", "GalViewMenus");
- tip = g_strdup_printf (_("Select View: %s"), item->id);
- bonobo_ui_node_set_attr(command, "_tip", tip);
- g_free (tip);
-
- label = bonobo_ui_util_encode_str (item->title);
- bonobo_ui_node_set_attr(menuitem, "label", label);
- g_free (label);
-
- closure = g_new (ListenerClosure, 1);
- closure->instance = instance;
- closure->id = item->id;
- closure->ref_count = 1;
-
- if (!found && id && !strcmp (item->id, id)) {
- found = TRUE;
- }
-
- g_object_ref (closure->instance);
-
- bonobo_ui_component_add_listener (menus->priv->component, item->id, toggled_cb, closure);
- e_list_append (menus->priv->listenerClosures, closure);
-
- closure_free (closure, menus);
- }
-
- if (menus->priv->show_define_views) {
- if (!found) {
-
- menuitem = bonobo_ui_node_new_child(submenu, "separator");
- bonobo_ui_node_set_attr(menuitem, "name", "GalView:first_sep");
- bonobo_ui_node_set_attr(menuitem, "f", "");
-
- menuitem = bonobo_ui_node_new_child(submenu, "menuitem");
- bonobo_ui_node_set_attr(menuitem, "name", "custom_view");
- bonobo_ui_node_set_attr(menuitem, "id", "custom_view");
- bonobo_ui_node_set_attr(menuitem, "group", "GalViewMenus");
- bonobo_ui_node_set_attr(menuitem, "type", "radio");
- /* bonobo displays this string so it must be in locale */
- bonobo_ui_node_set_attr(menuitem, "_label", N_("Custom View"));
-
- command = bonobo_ui_node_new_child (commands, "cmd");
- bonobo_ui_node_set_attr(command, "name", "custom_view");
- bonobo_ui_node_set_attr(command, "group", "GalViewMenus");
- bonobo_ui_node_set_attr(command, "_tip", N_("Current view is a customized view"));
-
- menuitem = bonobo_ui_node_new_child(submenu, "menuitem");
- bonobo_ui_node_set_attr(menuitem, "name", "SaveCurrentView");
- bonobo_ui_node_set_attr(menuitem, "_label", N_("Save Custom View..."));
- bonobo_ui_node_set_attr(menuitem, "verb", "");
-
- command = bonobo_ui_node_new_child(commands, "cmd");
- bonobo_ui_node_set_attr(command, "name", "SaveCurrentView");
- bonobo_ui_node_set_attr(command, "_tip", N_("Save current custom view"));
- }
-
- menuitem = bonobo_ui_node_new_child(submenu, "separator");
- bonobo_ui_node_set_attr(menuitem, "name", "GalView:second_sep");
- bonobo_ui_node_set_attr(menuitem, "f", "");
-
- menuitem = bonobo_ui_node_new_child(submenu, "menuitem");
- bonobo_ui_node_set_attr(menuitem, "name", "DefineViews");
- bonobo_ui_node_set_attr(menuitem, "_label", N_("Define Views..."));
- bonobo_ui_node_set_attr(menuitem, "verb", "");
-
- command = bonobo_ui_node_new_child(commands, "cmd");
- bonobo_ui_node_set_attr(command, "name", "DefineViews");
- bonobo_ui_node_set_attr(command, "_tip", N_("Create or edit views"));
- }
-
- xml = bonobo_ui_node_to_string(root, TRUE);
-
- bonobo_ui_node_free(root);
-
- g_free (id);
-
- /* d(g_print (xml));*/
-
- return xml;
-}
-
-static BonoboUIVerb verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("DefineViews", define_views),
- BONOBO_UI_UNSAFE_VERB ("SaveCurrentView", save_current_view),
- BONOBO_UI_VERB_END
-};
-
-static void
-set_state (GalViewMenus *gvm, const gchar *path, CORBA_Environment *ev)
-{
- gchar *full_path = g_strdup_printf ("/commands/%s", path);
-
- bonobo_ui_component_set_prop (gvm->priv->component, full_path, "state", "1", ev);
- g_free (full_path);
-}
-
-static void
-set_radio (GalViewMenus *gvm,
- CORBA_Environment *ev)
-{
- gchar *id;
-
- id = gal_view_instance_get_current_view_id (gvm->priv->instance);
-
- if (id) {
- set_state (gvm, id, ev);
- } else {
- set_state (gvm, "custom_view", ev);
- }
- g_free (id);
-}
-
-static void
-build_stuff (GalViewMenus *gvm,
- CORBA_Environment *ev)
-{
- gchar *xml;
-
- g_object_ref (gvm);
-
- gal_view_menus_unmerge (gvm, ev);
-
- remove_listeners(gvm);
- remove_xml(gvm);
- xml = build_menus(gvm);
- bonobo_ui_component_set_translate(gvm->priv->component, "/", xml, ev);
- g_free(xml);
-
- bonobo_ui_component_add_verb_list_with_data(gvm->priv->component, verbs, gvm);
-
- set_radio (gvm, ev);
-
- g_object_unref (gvm);
-}
-
-void
-gal_view_menus_set_show_define_views (GalViewMenus *gvm,
- gboolean show_define_views)
-{
- if (gvm->priv->show_define_views == show_define_views)
- return;
-
- gvm->priv->show_define_views = show_define_views;
-
- if (gvm->priv->component) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- build_stuff(gvm, &ev);
- CORBA_exception_free (&ev);
- }
-}
-
-void
-gal_view_menus_apply (GalViewMenus *gvm,
- BonoboUIComponent *component,
- CORBA_Environment *opt_ev)
-{
- if (gvm->priv == NULL)
- return;
-
- if (component != gvm->priv->component) {
- if (component)
- bonobo_object_ref (BONOBO_OBJECT (component));
-
- if (gvm->priv->component)
- bonobo_object_unref (BONOBO_OBJECT (gvm->priv->component));
- }
-
- gvm->priv->component = component;
-
- build_stuff (gvm, opt_ev);
-}
-
-void
-gal_view_menus_unmerge (GalViewMenus *gvm,
- CORBA_Environment *opt_ev)
-{
- d(g_print ("%s:\n", G_STRFUNC));
- if (bonobo_ui_component_get_container (gvm->priv->component) != NULL
- && bonobo_ui_component_path_exists (gvm->priv->component, CURRENT_VIEW_PATH, opt_ev)) {
- d(g_print ("%s: Removing path\n", G_STRFUNC));
- bonobo_ui_component_rm (gvm->priv->component, CURRENT_VIEW_PATH, opt_ev);
- }
-}
-
-static void
-collection_changed (GalViewCollection *collection,
- GalViewMenus *gvm)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- build_stuff(gvm, &ev);
- CORBA_exception_free (&ev);
-}
-
-static void
-instance_changed (GalViewInstance *instance,
- GalViewMenus *gvm)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- build_stuff(gvm, &ev);
- CORBA_exception_free (&ev);
-}
-
-void
-gal_view_menus_set_instance (GalViewMenus *gvm,
- GalViewInstance *instance)
-{
- remove_instance (gvm);
- add_instance (gvm, instance);
- instance_changed (instance, gvm);
-}
diff --git a/widgets/menus/gal-view-menus.h b/widgets/menus/gal-view-menus.h
deleted file mode 100644
index f565d07613..0000000000
--- a/widgets/menus/gal-view-menus.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _GAL_VIEW_MENUS_H_
-#define _GAL_VIEW_MENUS_H_
-
-#include <libxml/tree.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <widgets/menus/gal-view-instance.h>
-
-#include <glib-object.h>
-
-#define GAL_VIEW_MENUS_TYPE (gal_view_menus_get_type ())
-#define GAL_VIEW_MENUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GAL_VIEW_MENUS_TYPE, GalViewMenus))
-#define GAL_VIEW_MENUS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GAL_VIEW_MENUS_TYPE, GalViewMenusClass))
-#define GAL_IS_VIEW_MENUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GAL_VIEW_MENUS_TYPE))
-#define GAL_IS_VIEW_MENUS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GAL_VIEW_MENUS_TYPE))
-
-typedef struct _GalViewMenusPrivate GalViewMenusPrivate;
-
-typedef struct {
- GObject base;
- GalViewMenusPrivate *priv;
-} GalViewMenus;
-
-typedef struct {
- GObjectClass parent_class;
-} GalViewMenusClass;
-
-GType gal_view_menus_get_type (void);
-GalViewMenus *gal_view_menus_new (GalViewInstance *instance);
-GalViewMenus *gal_view_menus_construct (GalViewMenus *menus,
- GalViewInstance *instance);
-
-void gal_view_menus_set_show_define_views (GalViewMenus *menus,
- gboolean show_define_views);
-
-void gal_view_menus_apply (GalViewMenus *menus,
- BonoboUIComponent *component,
- CORBA_Environment *opt_ev);
-void gal_view_menus_unmerge (GalViewMenus *gvm,
- CORBA_Environment *opt_ev);
-void gal_view_menus_set_instance (GalViewMenus *gvm,
- GalViewInstance *instance);
-
-#endif /* _GAL_VIEW_MENUS_H_ */
diff --git a/widgets/menus/gal-view-new-dialog.c b/widgets/menus/gal-view-new-dialog.c
index e2f62c7e99..da90fb024d 100644
--- a/widgets/menus/gal-view-new-dialog.c
+++ b/widgets/menus/gal-view-new-dialog.c
@@ -27,7 +27,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "e-util/e-util-private.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "gal-define-views-model.h"
#include "gal-view-new-dialog.h"
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index d6689ef73f..29607758e5 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -4,7 +4,7 @@ endif
AM_CPPFLAGS = \
-I$(top_srcdir) \
- -I$(top_srcdir)/a11y/widgets \
+ -I$(top_srcdir)/filter \
-I$(top_srcdir)/widgets \
-DEVOLUTION_IMAGES=\""$(imagesdir)"\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
@@ -13,8 +13,7 @@ AM_CPPFLAGS = \
$(GNOME_PLATFORM_CFLAGS)
privsolib_LTLIBRARIES = \
- libemiscwidgets.la \
- libefilterbar.la
+ libemiscwidgets.la
widgetsincludedir = $(privincludedir)/misc
filterbarincludedir = $(privincludedir)/misc
@@ -32,7 +31,12 @@ glade_DATA = e-send-options.glade
widgetsinclude_HEADERS = \
$(pilot_headers) \
e-account-combo-box.h \
- e-activity-handler.h \
+ e-account-manager.h \
+ e-account-tree-view.h \
+ e-action-combo-box.h \
+ e-activity.h \
+ e-activity-proxy.h \
+ e-alert-activity.h \
e-attachment.h \
e-attachment-button.h \
e-attachment-dialog.h \
@@ -44,54 +48,59 @@ widgetsinclude_HEADERS = \
e-attachment-store.h \
e-attachment-tree-view.h \
e-attachment-view.h \
- e-spinner.c \
- e-spinner.h \
e-calendar.h \
e-calendar-item.h \
- e-cell-date-edit.h \
- e-cell-percent.h \
- e-cell-renderer-combo.h \
- e-charset-picker.h \
- e-combo-cell-editable.h \
- e-config-page.h \
- e-combo-button.h \
- e-dateedit.h \
- e-dropdown-button.h \
- e-icon-entry.h \
- e-image-chooser.h \
- e-info-label.h \
- e-map.h \
- e-multi-config-dialog.h \
- e-online-button.h \
- e-search-bar.h \
- e-task-bar.h \
- e-task-widget.h \
- e-send-options.h \
- e-url-entry.h \
+ e-canvas.h \
e-canvas-background.h \
e-canvas-utils.h \
e-canvas-vbox.h \
- e-canvas.h \
+ e-cell-renderer-combo.h \
+ e-charset-combo-box.h \
+ e-colors.h \
+ e-combo-cell-editable.h \
e-cursors.h \
+ e-dateedit.h \
e-gui-utils.h \
+ e-hinted-entry.h \
e-hsv-utils.h \
+ e-image-chooser.h \
+ e-map.h \
+ e-menu-tool-button.h \
+ e-online-button.h \
+ e-paned.h \
+ e-popup-action.h \
e-popup-menu.h \
+ e-preferences-window.h \
e-printable.h \
- e-reflow-model.h \
- e-reflow.h \
+ e-selection-model.h \
e-selection-model-array.h \
e-selection-model-simple.h \
- e-selection-model.h \
+ e-send-options.h \
e-signature-combo-box.h \
- e-unicode.h \
- e-colors.h
+ e-signature-editor.h \
+ e-signature-manager.h \
+ e-signature-preview.h \
+ e-signature-script-dialog.h \
+ e-signature-tree-view.h \
+ e-spinner.c \
+ e-spinner.h \
+ e-timeout-activity.h \
+ e-url-entry.h \
+ ea-calendar-cell.h \
+ ea-calendar-item.h \
+ ea-cell-table.h \
+ ea-widgets.h
libemiscwidgets_la_SOURCES = \
$(widgetsinclude_HEADERS) \
$(pilot_sources) \
e-account-combo-box.c \
- e-activity-handler.c \
- e-calendar.c \
+ e-account-manager.c \
+ e-account-tree-view.c \
+ e-action-combo-box.c \
+ e-activity.c \
+ e-activity-proxy.c \
+ e-alert-activity.c \
e-attachment.c \
e-attachment-button.c \
e-attachment-dialog.c \
@@ -103,78 +112,62 @@ libemiscwidgets_la_SOURCES = \
e-attachment-store.c \
e-attachment-tree-view.c \
e-attachment-view.c \
+ e-calendar.c \
e-calendar-item.c \
- e-cell-date-edit.c \
- e-cell-percent.c \
- e-cell-renderer-combo.c \
- e-charset-picker.c \
- e-combo-cell-editable.c \
- e-config-page.c \
- e-combo-button.c \
- e-dateedit.c \
- e-dropdown-button.c \
- e-icon-entry.c \
- e-image-chooser.c \
- e-info-label.c \
- e-map.c \
- e-multi-config-dialog.c \
- e-online-button.c \
- e-search-bar.c \
- e-task-bar.c \
- e-task-widget.c \
- e-send-options.c \
- e-url-entry.c \
+ e-canvas.c \
e-canvas-background.c \
e-canvas-utils.c \
e-canvas-vbox.c \
- e-canvas.c \
+ e-cell-renderer-combo.c \
+ e-charset-combo-box.c \
+ e-colors.c \
+ e-combo-cell-editable.c \
e-cursors.c \
+ e-dateedit.c \
e-gui-utils.c \
+ e-hinted-entry.c \
e-hsv-utils.c \
+ e-image-chooser.c \
+ e-map.c \
+ e-menu-tool-button.c \
+ e-online-button.c \
+ e-paned.c \
+ e-popup-action.c \
e-popup-menu.c \
+ e-preferences-window.c \
e-printable.c \
- e-reflow-model.c \
- e-reflow.c \
+ e-selection-model.c \
e-selection-model-array.c \
e-selection-model-simple.c \
- e-selection-model.c \
+ e-send-options.c \
e-signature-combo-box.c \
- e-unicode.c \
- e-colors.c
-
+ e-signature-editor.c \
+ e-signature-manager.c \
+ e-signature-preview.c \
+ e-signature-script-dialog.c \
+ e-signature-tree-view.c \
+ e-timeout-activity.c \
+ e-url-entry.c \
+ ea-calendar-cell.c \
+ ea-calendar-item.c \
+ ea-cell-table.c \
+ ea-widgets.c
libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED)
-libemiscwidgets_la_LIBADD = $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/widgets/table/libetable.la \
- $(top_builddir)/widgets/text/libetext.la \
- $(top_builddir)/a11y/widgets/libevolution-widgets-a11y.la \
- $(top_builddir)/a11y/libevolution-a11y.la \
- $(EVOLUTION_MAIL_LIBS) \
- $(GNOME_PLATFORM_LIBS) \
- $(EVOLUTON_MAIL_LIBS) \
+libemiscwidgets_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/filter/libfilter.la \
+ $(top_builddir)/a11y/libevolution-a11y.la \
+ $(EVOLUTION_MAIL_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(MATH_LIB) \
$(ICONV_LIBS)
-filterbarinclude_HEADERS = e-filter-bar.h
-
-libefilterbar_la_SOURCES = \
- e-filter-bar.c \
- $(filterbarinclude_HEADERS)
-
-libefilterbar_la_LDFLAGS = $(NO_UNDEFINED)
-
-libefilterbar_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- libemiscwidgets.la \
- $(E_WIDGETS_LIBS)
-
noinst_PROGRAMS = \
test-calendar \
test-dateedit \
- test-dropdown-button \
- test-multi-config-dialog \
- test-info-label
+ test-preferences-window
# test-calendar
@@ -184,6 +177,7 @@ test_calendar_SOURCES = \
test_calendar_LDADD = \
libemiscwidgets.la \
$(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/filter/libfilter.la \
$(E_WIDGETS_LIBS)
# test-dateedit
@@ -194,36 +188,18 @@ test_dateedit_SOURCES = \
test_dateedit_LDADD = \
libemiscwidgets.la \
$(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/filter/libfilter.la \
$(E_WIDGETS_LIBS)
-# test-dropdown-button
-
-test_dropdown_button_SOURCES = \
- test-dropdown-button.c
-
-test_dropdown_button_LDADD = \
- libemiscwidgets.la \
- $(top_builddir)/e-util/libeutil.la \
- $(E_WIDGETS_LIBS)
-
-# test-multi-config-dialog
-
-test_multi_config_dialog_SOURCES = \
- test-multi-config-dialog.c
-
-test_multi_config_dialog_LDADD = \
- libemiscwidgets.la \
- $(top_builddir)/e-util/libeutil.la \
- $(E_WIDGETS_LIBS)
-
-# test-info-label
+# test-preferences-window
-test_info_label_SOURCES = \
- test-info-label.c
+test_preferences_window_SOURCES = \
+ test-preferences-window.c
-test_info_label_LDADD = \
+test_preferences_window_LDADD = \
libemiscwidgets.la \
$(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/filter/libfilter.la \
$(E_WIDGETS_LIBS)
diff --git a/widgets/misc/e-account-combo-box.c b/widgets/misc/e-account-combo-box.c
index a0d02bcd80..0ded393e72 100644
--- a/widgets/misc/e-account-combo-box.c
+++ b/widgets/misc/e-account-combo-box.c
@@ -1,4 +1,5 @@
/*
+ * e-account-combo-box.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/widgets/misc/e-account-combo-box.h b/widgets/misc/e-account-combo-box.h
index b163278dcd..12d4be6c72 100644
--- a/widgets/misc/e-account-combo-box.h
+++ b/widgets/misc/e-account-combo-box.h
@@ -1,4 +1,5 @@
/*
+ * e-account-combo-box.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/widgets/misc/e-account-manager.c b/widgets/misc/e-account-manager.c
new file mode 100644
index 0000000000..8d3d2d211b
--- /dev/null
+++ b/widgets/misc/e-account-manager.c
@@ -0,0 +1,454 @@
+/*
+ * e-account-manager.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-account-manager.h"
+
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include "e-util/e-binding.h"
+#include "e-account-tree-view.h"
+
+#define E_ACCOUNT_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ACCOUNT_MANAGER, EAccountManagerPrivate))
+
+struct _EAccountManagerPrivate {
+ EAccountList *account_list;
+
+ GtkWidget *tree_view;
+ GtkWidget *add_button;
+ GtkWidget *edit_button;
+ GtkWidget *delete_button;
+ GtkWidget *default_button;
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT_LIST
+};
+
+enum {
+ ADD_ACCOUNT,
+ EDIT_ACCOUNT,
+ DELETE_ACCOUNT,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+account_manager_default_clicked_cb (EAccountManager *manager)
+{
+ EAccountTreeView *tree_view;
+ EAccountList *account_list;
+ EAccount *account;
+
+ tree_view = e_account_manager_get_tree_view (manager);
+ account_list = e_account_manager_get_account_list (manager);
+ account = e_account_tree_view_get_selected (tree_view);
+ g_return_if_fail (account != NULL);
+
+ e_account_list_set_default (account_list, account);
+
+ /* This signals the tree view to refresh. */
+ e_account_list_change (account_list, account);
+}
+
+static gboolean
+account_manager_key_press_event_cb (EAccountManager *manager,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_Delete) {
+ e_account_manager_delete_account (manager);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+account_manager_selection_changed_cb (EAccountManager *manager,
+ GtkTreeSelection *selection)
+{
+ EAccountTreeView *tree_view;
+ EAccountList *account_list;
+ EAccount *default_account;
+ EAccount *account;
+ GtkWidget *add_button;
+ GtkWidget *edit_button;
+ GtkWidget *delete_button;
+ GtkWidget *default_button;
+ gboolean sensitive;
+
+ add_button = manager->priv->add_button;
+ edit_button = manager->priv->edit_button;
+ delete_button = manager->priv->delete_button;
+ default_button = manager->priv->default_button;
+
+ tree_view = e_account_manager_get_tree_view (manager);
+ account = e_account_tree_view_get_selected (tree_view);
+ account_list = e_account_tree_view_get_account_list (tree_view);
+
+ if (account == NULL)
+ gtk_widget_grab_focus (add_button);
+
+ /* XXX EAccountList misuses const */
+ default_account = (EAccount *)
+ e_account_list_get_default (account_list);
+
+ sensitive = (account != NULL);
+ gtk_widget_set_sensitive (edit_button, sensitive);
+
+ sensitive = (account != NULL);
+ gtk_widget_set_sensitive (delete_button, sensitive);
+
+ sensitive = (account != NULL && account != default_account);
+ gtk_widget_set_sensitive (default_button, sensitive);
+}
+
+static void
+account_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_LIST:
+ e_account_manager_set_account_list (
+ E_ACCOUNT_MANAGER (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+account_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_LIST:
+ g_value_set_object (
+ value,
+ e_account_manager_get_account_list (
+ E_ACCOUNT_MANAGER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+account_manager_dispose (GObject *object)
+{
+ EAccountManagerPrivate *priv;
+
+ priv = E_ACCOUNT_MANAGER_GET_PRIVATE (object);
+
+ if (priv->account_list != NULL) {
+ g_object_unref (priv->account_list);
+ priv->account_list = NULL;
+ }
+
+ if (priv->tree_view != NULL) {
+ g_object_unref (priv->tree_view);
+ priv->tree_view = NULL;
+ }
+
+ if (priv->add_button != NULL) {
+ g_object_unref (priv->add_button);
+ priv->add_button = NULL;
+ }
+
+ if (priv->edit_button != NULL) {
+ g_object_unref (priv->edit_button);
+ priv->edit_button = NULL;
+ }
+
+ if (priv->delete_button != NULL) {
+ g_object_unref (priv->delete_button);
+ priv->delete_button = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+account_manager_class_init (EAccountManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EAccountManagerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = account_manager_set_property;
+ object_class->get_property = account_manager_get_property;
+ object_class->dispose = account_manager_dispose;
+
+ /* XXX If we moved the account editor to /widgets/misc we
+ * could handle adding and editing accounts directly. */
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_LIST,
+ g_param_spec_object (
+ "account-list",
+ "Account List",
+ NULL,
+ E_TYPE_ACCOUNT_LIST,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[ADD_ACCOUNT] = g_signal_new (
+ "add-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EAccountManagerClass, add_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[EDIT_ACCOUNT] = g_signal_new (
+ "edit-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EAccountManagerClass, edit_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DELETE_ACCOUNT] = g_signal_new (
+ "delete-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EAccountManagerClass, delete_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+account_manager_init (EAccountManager *manager)
+{
+ GtkTreeSelection *selection;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ manager->priv = E_ACCOUNT_MANAGER_GET_PRIVATE (manager);
+
+ gtk_table_resize (GTK_TABLE (manager), 1, 2);
+ gtk_table_set_col_spacings (GTK_TABLE (manager), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (manager), 12);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_table_attach (
+ GTK_TABLE (container), widget, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_account_tree_view_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ manager->priv->tree_view = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_mutual_binding_new (
+ G_OBJECT (manager), "account-list",
+ G_OBJECT (widget), "account-list");
+
+ g_signal_connect_swapped (
+ widget, "key-press-event",
+ G_CALLBACK (account_manager_key_press_event_cb),
+ manager);
+
+ g_signal_connect_swapped (
+ widget, "row-activated",
+ G_CALLBACK (e_account_manager_edit_account),
+ manager);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (account_manager_selection_changed_cb),
+ manager);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_vbutton_box_new ();
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (widget), 6);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 0, 2, 0, GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->add_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_account_manager_add_account), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->edit_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_account_manager_edit_account), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->delete_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_account_manager_delete_account), manager);
+
+ widget = gtk_button_new_with_mnemonic (_("De_fault"));
+ gtk_button_set_image (
+ GTK_BUTTON (widget), gtk_image_new_from_icon_name (
+ "emblem-default", GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->default_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (account_manager_default_clicked_cb), manager);
+}
+
+GType
+e_account_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EAccountManagerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) account_manager_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_init */
+ sizeof (EAccountManager),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) account_manager_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "EAccountManager", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_account_manager_new (EAccountList *account_list)
+{
+ g_return_val_if_fail (E_IS_ACCOUNT_LIST (account_list), NULL);
+
+ return g_object_new (
+ E_TYPE_ACCOUNT_MANAGER,
+ "account-list", account_list, NULL);
+}
+
+void
+e_account_manager_add_account (EAccountManager *manager)
+{
+ g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[ADD_ACCOUNT], 0);
+}
+
+void
+e_account_manager_edit_account (EAccountManager *manager)
+{
+ g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[EDIT_ACCOUNT], 0);
+}
+
+void
+e_account_manager_delete_account (EAccountManager *manager)
+{
+ g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[DELETE_ACCOUNT], 0);
+}
+
+EAccountList *
+e_account_manager_get_account_list (EAccountManager *manager)
+{
+ g_return_val_if_fail (E_IS_ACCOUNT_MANAGER (manager), NULL);
+
+ return manager->priv->account_list;
+}
+
+void
+e_account_manager_set_account_list (EAccountManager *manager,
+ EAccountList *account_list)
+{
+ g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager));
+
+ if (account_list != NULL) {
+ g_return_if_fail (E_IS_ACCOUNT_LIST (account_list));
+ g_object_ref (account_list);
+ }
+
+ if (manager->priv->account_list != NULL)
+ g_object_unref (manager->priv->account_list);
+
+ manager->priv->account_list = account_list;
+
+ g_object_notify (G_OBJECT (manager), "account-list");
+}
+
+EAccountTreeView *
+e_account_manager_get_tree_view (EAccountManager *manager)
+{
+ g_return_val_if_fail (E_IS_ACCOUNT_MANAGER (manager), NULL);
+
+ return E_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
+}
diff --git a/widgets/misc/e-account-manager.h b/widgets/misc/e-account-manager.h
new file mode 100644
index 0000000000..dab8b2832f
--- /dev/null
+++ b/widgets/misc/e-account-manager.h
@@ -0,0 +1,82 @@
+/*
+ * e-account-manager.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_ACCOUNT_MANAGER_H
+#define E_ACCOUNT_MANAGER_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/e-account-list.h>
+#include <misc/e-account-tree-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ACCOUNT_MANAGER \
+ (e_account_manager_get_type ())
+#define E_ACCOUNT_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ACCOUNT_MANAGER, EAccountManager))
+#define E_ACCOUNT_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ACCOUNT_MANAGER, EAccountManagerClass))
+#define E_IS_ACCOUNT_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ACCOUNT_MANAGER))
+#define E_IS_ACCOUNT_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ACCOUNT_MANAGER))
+#define E_ACCOUNT_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ACCOUNT_MANAGER, EAccountManagerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EAccountManager EAccountManager;
+typedef struct _EAccountManagerClass EAccountManagerClass;
+typedef struct _EAccountManagerPrivate EAccountManagerPrivate;
+
+struct _EAccountManager {
+ GtkTable parent;
+ EAccountManagerPrivate *priv;
+};
+
+struct _EAccountManagerClass {
+ GtkTableClass parent_class;
+
+ void (*add_account) (EAccountManager *manager);
+ void (*edit_account) (EAccountManager *manager);
+ void (*delete_account) (EAccountManager *manager);
+};
+
+GType e_account_manager_get_type (void);
+GtkWidget * e_account_manager_new (EAccountList *account_list);
+void e_account_manager_add_account (EAccountManager *manager);
+void e_account_manager_edit_account (EAccountManager *manager);
+void e_account_manager_delete_account(EAccountManager *manager);
+EAccountList * e_account_manager_get_account_list
+ (EAccountManager *manager);
+void e_account_manager_set_account_list
+ (EAccountManager *manager,
+ EAccountList *account_list);
+EAccountTreeView *
+ e_account_manager_get_tree_view (EAccountManager *manager);
+
+G_END_DECLS
+
+#endif /* E_ACCOUNT_MANAGER_H */
diff --git a/widgets/misc/e-account-tree-view.c b/widgets/misc/e-account-tree-view.c
new file mode 100644
index 0000000000..8e57dfcf66
--- /dev/null
+++ b/widgets/misc/e-account-tree-view.c
@@ -0,0 +1,632 @@
+/*
+ * e-account-tree-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-account-tree-view.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-url.h>
+
+#define E_ACCOUNT_TREE_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeViewPrivate))
+
+enum {
+ COLUMN_ACCOUNT,
+ COLUMN_DEFAULT,
+ COLUMN_ENABLED,
+ COLUMN_NAME,
+ COLUMN_PROTOCOL
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT_LIST,
+ PROP_SELECTED
+};
+
+enum {
+ ENABLE_ACCOUNT,
+ DISABLE_ACCOUNT,
+ REFRESHED,
+ LAST_SIGNAL
+};
+
+struct _EAccountTreeViewPrivate {
+ EAccountList *account_list;
+ GHashTable *index;
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+account_tree_view_refresh_cb (EAccountList *account_list,
+ EAccount *account,
+ EAccountTreeView *tree_view)
+{
+ GtkListStore *store;
+ GtkTreeModel *model;
+ GtkTreeIter tree_iter;
+ EIterator *account_iter;
+ EAccount *default_account;
+ GHashTable *index;
+ GList *list = NULL;
+ GList *iter;
+
+ store = gtk_list_store_new (
+ 5, E_TYPE_ACCOUNT, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_STRING, G_TYPE_STRING);
+ model = GTK_TREE_MODEL (store);
+ index = tree_view->priv->index;
+
+ g_hash_table_remove_all (index);
+
+ if (account_list == NULL)
+ goto skip;
+
+ /* XXX EAccountList misuses const. */
+ default_account = (EAccount *)
+ e_account_list_get_default (account_list);
+
+ /* Build a list of EAccounts to display. */
+ account_iter = e_list_get_iterator (E_LIST (account_list));
+ while (e_iterator_is_valid (account_iter)) {
+
+ /* XXX EIterator misuses const. */
+ account = (EAccount *) e_iterator_get (account_iter);
+ list = g_list_prepend (list, account);
+ e_iterator_next (account_iter);
+ }
+ g_object_unref (account_iter);
+
+ list = g_list_reverse (list);
+
+ /* Populate the list store and index. */
+ for (iter = list; iter != NULL; iter = iter->next) {
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
+ CamelURL *url = NULL;
+ gboolean is_default;
+ const gchar *protocol;
+
+ account = iter->data;
+
+ /* Skip proxy accounts. */
+ if (account->parent_uid != NULL)
+ continue;
+
+ is_default = (account == default_account);
+
+ if (account->source != NULL && account->source->url != NULL)
+ url = camel_url_new (account->source->url, NULL);
+
+ if (url != NULL && url->protocol != NULL)
+ protocol = url->protocol;
+ else
+ protocol = _("None");
+
+ gtk_list_store_append (store, &tree_iter);
+ gtk_list_store_set (
+ store, &tree_iter,
+ COLUMN_ACCOUNT, account,
+ COLUMN_DEFAULT, is_default,
+ COLUMN_ENABLED, account->enabled,
+ COLUMN_NAME, account->name,
+ COLUMN_PROTOCOL, protocol, -1);
+
+ path = gtk_tree_model_get_path (model, &tree_iter);
+ reference = gtk_tree_row_reference_new (model, path);
+ g_hash_table_insert (index, account, reference);
+ gtk_tree_path_free (path);
+
+ if (url != NULL)
+ camel_url_free (url);
+ }
+
+skip:
+ /* Restore the previously selected account. */
+ account = e_account_tree_view_get_selected (tree_view);
+ if (account != NULL)
+ g_object_ref (account);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model);
+ e_account_tree_view_set_selected (tree_view, account);
+ if (account != NULL)
+ g_object_unref (account);
+
+ g_signal_emit (tree_view, signals[REFRESHED], 0);
+}
+
+static void
+account_tree_view_enabled_toggled_cb (EAccountTreeView *tree_view,
+ gchar *path_string,
+ GtkCellRendererToggle *renderer)
+{
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+
+ /* Change the selection first so we enable or disable the
+ * correct account. */
+ path = gtk_tree_path_new_from_string (path_string);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+
+ if (gtk_cell_renderer_toggle_get_active (renderer))
+ e_account_tree_view_disable_account (tree_view);
+ else
+ e_account_tree_view_enable_account (tree_view);
+}
+
+static void
+account_tree_view_selection_changed_cb (EAccountTreeView *tree_view)
+{
+ g_object_notify (G_OBJECT (tree_view), "selected");
+}
+
+static GObject *
+account_tree_view_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *object;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ /* Chain up to parent's constructor() method. */
+ object = G_OBJECT_CLASS (parent_class)->constructor (
+ type, n_construct_properties, construct_properties);
+
+ tree_view = GTK_TREE_VIEW (object);
+ gtk_tree_view_set_headers_visible (tree_view, TRUE);
+
+ /* Column: Enabled */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, FALSE);
+ gtk_tree_view_column_set_title (column, _("Enabled"));
+
+ renderer = gtk_cell_renderer_toggle_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+
+ g_signal_connect_swapped (
+ renderer, "toggled",
+ G_CALLBACK (account_tree_view_enabled_toggled_cb),
+ tree_view);
+
+ gtk_tree_view_column_add_attribute (
+ column, renderer, "active", COLUMN_ENABLED);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ /* Column: Account Name */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_column_set_title (column, _("Account Name"));
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+
+ gtk_tree_view_column_add_attribute (
+ column, renderer, "text", COLUMN_NAME);
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "text", _("Default"), NULL);
+ gtk_tree_view_column_pack_end (column, renderer, FALSE);
+
+ gtk_tree_view_column_add_attribute (
+ column, renderer, "visible", COLUMN_DEFAULT);
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (
+ renderer, "icon-name", "emblem-default",
+ "stock-size", GTK_ICON_SIZE_MENU, NULL);
+ gtk_tree_view_column_pack_end (column, renderer, FALSE);
+
+ gtk_tree_view_column_add_attribute (
+ column, renderer, "visible", COLUMN_DEFAULT);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ /* Column: Protocol */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_expand (column, FALSE);
+ gtk_tree_view_column_set_title (column, _("Protocol"));
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+
+ gtk_tree_view_column_add_attribute (
+ column, renderer, "text", COLUMN_PROTOCOL);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ return object;
+}
+
+static void
+account_tree_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_LIST:
+ e_account_tree_view_set_account_list (
+ E_ACCOUNT_TREE_VIEW (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SELECTED:
+ e_account_tree_view_set_selected (
+ E_ACCOUNT_TREE_VIEW (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+account_tree_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_LIST:
+ g_value_set_object (
+ value,
+ e_account_tree_view_get_account_list (
+ E_ACCOUNT_TREE_VIEW (object)));
+ return;
+
+ case PROP_SELECTED:
+ g_value_set_object (
+ value,
+ e_account_tree_view_get_selected (
+ E_ACCOUNT_TREE_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+account_tree_view_dispose (GObject *object)
+{
+ EAccountTreeViewPrivate *priv;
+
+ priv = E_ACCOUNT_TREE_VIEW_GET_PRIVATE (object);
+
+ if (priv->account_list != NULL) {
+ g_signal_handlers_disconnect_by_func (
+ priv->account_list,
+ account_tree_view_refresh_cb, object);
+ g_object_unref (priv->account_list);
+ priv->account_list = NULL;
+ }
+
+ g_hash_table_remove_all (priv->index);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+account_tree_view_finalize (GObject *object)
+{
+ EAccountTreeViewPrivate *priv;
+
+ priv = E_ACCOUNT_TREE_VIEW_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->index);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+account_tree_view_enable_account (EAccountTreeView *tree_view)
+{
+ EAccountList *account_list;
+ EAccount *account;
+
+ account = e_account_tree_view_get_selected (tree_view);
+ if (account == NULL || account->enabled)
+ return;
+
+ account_list = e_account_tree_view_get_account_list (tree_view);
+ g_return_if_fail (account_list != NULL);
+
+ account->enabled = TRUE;
+ e_account_list_change (account_list, account);
+
+ e_account_list_save (account_list);
+}
+
+static void
+account_tree_view_disable_account (EAccountTreeView *tree_view)
+{
+ EAccountList *account_list;
+ EAccount *account;
+
+ account = e_account_tree_view_get_selected (tree_view);
+ if (account == NULL || !account->enabled)
+ return;
+
+ account_list = e_account_tree_view_get_account_list (tree_view);
+ g_return_if_fail (account_list != NULL);
+
+ account->enabled = FALSE;
+ e_account_list_change (account_list, account);
+
+ e_account_list_save (account_list);
+}
+
+static void
+account_tree_view_class_init (EAccountTreeViewClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EAccountTreeViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructor = account_tree_view_constructor;
+ object_class->set_property = account_tree_view_set_property;
+ object_class->get_property = account_tree_view_get_property;
+ object_class->dispose = account_tree_view_dispose;
+ object_class->finalize = account_tree_view_finalize;
+
+ class->enable_account = account_tree_view_enable_account;
+ class->disable_account = account_tree_view_disable_account;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTED,
+ g_param_spec_object (
+ "selected",
+ "Selected Account",
+ NULL,
+ E_TYPE_ACCOUNT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_LIST,
+ g_param_spec_object (
+ "account-list",
+ "Account List",
+ NULL,
+ E_TYPE_ACCOUNT_LIST,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[ENABLE_ACCOUNT] = g_signal_new (
+ "enable-account",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAccountTreeViewClass, enable_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DISABLE_ACCOUNT] = g_signal_new (
+ "disable-account",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAccountTreeViewClass, disable_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[REFRESHED] = g_signal_new (
+ "refreshed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAccountTreeViewClass, refreshed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+account_tree_view_init (EAccountTreeView *tree_view)
+{
+ GHashTable *index;
+ GtkTreeSelection *selection;
+
+ /* Reverse-lookup index */
+ index = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) gtk_tree_row_reference_free);
+
+ tree_view->priv = E_ACCOUNT_TREE_VIEW_GET_PRIVATE (tree_view);
+ tree_view->priv->index = index;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (account_tree_view_selection_changed_cb),
+ tree_view);
+}
+
+GType
+e_account_tree_view_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EAccountTreeViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) account_tree_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EAccountTreeView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) account_tree_view_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TREE_VIEW, "EAccountTreeView",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_account_tree_view_new (void)
+{
+ return g_object_new (E_TYPE_ACCOUNT_TREE_VIEW, NULL);
+}
+
+void
+e_account_tree_view_enable_account (EAccountTreeView *tree_view)
+{
+ g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+ g_signal_emit (tree_view, signals[ENABLE_ACCOUNT], 0);
+}
+
+void
+e_account_tree_view_disable_account (EAccountTreeView *tree_view)
+{
+ g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+ g_signal_emit (tree_view, signals[DISABLE_ACCOUNT], 0);
+}
+
+EAccountList *
+e_account_tree_view_get_account_list (EAccountTreeView *tree_view)
+{
+ g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), NULL);
+
+ return tree_view->priv->account_list;
+}
+
+void
+e_account_tree_view_set_account_list (EAccountTreeView *tree_view,
+ EAccountList *account_list)
+{
+ EAccountTreeViewPrivate *priv;
+
+ g_return_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view));
+
+ if (account_list != NULL)
+ g_return_if_fail (E_IS_ACCOUNT_LIST (account_list));
+
+ priv = E_ACCOUNT_TREE_VIEW_GET_PRIVATE (tree_view);
+
+ if (priv->account_list != NULL) {
+ g_signal_handlers_disconnect_by_func (
+ priv->account_list,
+ account_tree_view_refresh_cb, tree_view);
+ g_object_unref (priv->account_list);
+ priv->account_list = NULL;
+ }
+
+ if (account_list != NULL) {
+ priv->account_list = g_object_ref (account_list);
+
+ /* Listen for changes to the account list. */
+ g_signal_connect (
+ priv->account_list, "account-added",
+ G_CALLBACK (account_tree_view_refresh_cb),
+ tree_view);
+ g_signal_connect (
+ priv->account_list, "account-changed",
+ G_CALLBACK (account_tree_view_refresh_cb),
+ tree_view);
+ g_signal_connect (
+ priv->account_list, "account-removed",
+ G_CALLBACK (account_tree_view_refresh_cb),
+ tree_view);
+ }
+
+ account_tree_view_refresh_cb (account_list, NULL, tree_view);
+
+ g_object_notify (G_OBJECT (tree_view), "account-list");
+}
+
+EAccount *
+e_account_tree_view_get_selected (EAccountTreeView *tree_view)
+{
+ EAccount *account;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), NULL);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COLUMN_ACCOUNT, &account, -1);
+
+ return account;
+}
+
+gboolean
+e_account_tree_view_set_selected (EAccountTreeView *tree_view,
+ EAccount *account)
+{
+ GtkTreeRowReference *reference;
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+
+ g_return_val_if_fail (E_IS_ACCOUNT_TREE_VIEW (tree_view), FALSE);
+
+ if (account != NULL)
+ g_return_val_if_fail (E_IS_ACCOUNT (account), FALSE);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ /* NULL means clear the selection. */
+ if (account == NULL) {
+ gtk_tree_selection_unselect_all (selection);
+ return TRUE;
+ }
+
+ /* Lookup the tree row reference for the account. */
+ reference = g_hash_table_lookup (tree_view->priv->index, account);
+ if (reference == NULL)
+ return FALSE;
+
+ /* Select the referenced path. */
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+
+ g_object_notify (G_OBJECT (tree_view), "selected");
+
+ return TRUE;
+}
diff --git a/widgets/misc/e-account-tree-view.h b/widgets/misc/e-account-tree-view.h
new file mode 100644
index 0000000000..ea13dc3902
--- /dev/null
+++ b/widgets/misc/e-account-tree-view.h
@@ -0,0 +1,84 @@
+/*
+ * e-account-tree-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_ACCOUNT_TREE_VIEW_H
+#define E_ACCOUNT_TREE_VIEW_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ACCOUNT_TREE_VIEW \
+ (e_account_tree_view_get_type ())
+#define E_ACCOUNT_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeView))
+#define E_ACCOUNT_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeViewClass))
+#define E_IS_ACCOUNT_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ACCOUNT_TREE_VIEW))
+#define E_IS_ACCOUNT_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ACCOUNT_TREE_VIEW))
+#define E_ACCOUNT_TREE_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ACCOUNT_TREE_VIEW, EAccountTreeViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EAccountTreeView EAccountTreeView;
+typedef struct _EAccountTreeViewClass EAccountTreeViewClass;
+typedef struct _EAccountTreeViewPrivate EAccountTreeViewPrivate;
+
+struct _EAccountTreeView {
+ GtkTreeView parent;
+ EAccountTreeViewPrivate *priv;
+};
+
+struct _EAccountTreeViewClass {
+ GtkTreeViewClass parent_class;
+
+ void (*enable_account) (EAccountTreeView *tree_view);
+ void (*disable_account) (EAccountTreeView *tree_view);
+ void (*refreshed) (EAccountTreeView *tree_view);
+};
+
+GType e_account_tree_view_get_type (void);
+GtkWidget * e_account_tree_view_new (void);
+void e_account_tree_view_enable_account
+ (EAccountTreeView *tree_view);
+void e_account_tree_view_disable_account
+ (EAccountTreeView *tree_view);
+EAccountList * e_account_tree_view_get_account_list
+ (EAccountTreeView *tree_view);
+void e_account_tree_view_set_account_list
+ (EAccountTreeView *tree_view,
+ EAccountList *account_list);
+EAccount * e_account_tree_view_get_selected(EAccountTreeView *tree_view);
+gboolean e_account_tree_view_set_selected(EAccountTreeView *tree_view,
+ EAccount *account);
+
+G_END_DECLS
+
+#endif /* E_ACCOUNT_TREE_VIEW_H */
diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c
new file mode 100644
index 0000000000..e8a9be51ed
--- /dev/null
+++ b/widgets/misc/e-action-combo-box.c
@@ -0,0 +1,582 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-action-combo-box.c
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "e-action-combo-box.h"
+
+#include <glib/gi18n.h>
+
+#define E_ACTION_COMBO_BOX_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxPrivate))
+
+enum {
+ COLUMN_ACTION,
+ COLUMN_SORT
+};
+
+enum {
+ PROP_0,
+ PROP_ACTION
+};
+
+struct _EActionComboBoxPrivate {
+ GtkRadioAction *action;
+ GtkActionGroup *action_group;
+ GHashTable *index;
+ guint changed_handler_id; /* action::changed */
+ guint group_sensitive_handler_id; /* action-group::sensitive */
+ guint group_visible_handler_id; /* action-group::visible */
+ gboolean group_has_icons : 1;
+};
+
+static gpointer parent_class;
+
+static void
+action_combo_box_action_changed_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EActionComboBox *combo_box)
+{
+ GtkTreeRowReference *reference;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gboolean valid;
+
+ reference = g_hash_table_lookup (
+ combo_box->priv->index, GINT_TO_POINTER (
+ gtk_radio_action_get_current_value (current)));
+ g_return_if_fail (reference != NULL);
+
+ model = gtk_tree_row_reference_get_model (reference);
+ path = gtk_tree_row_reference_get_path (reference);
+ valid = gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+ g_return_if_fail (valid);
+
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter);
+}
+
+static void
+action_combo_box_action_group_notify_cb (GtkActionGroup *action_group,
+ GParamSpec *pspec,
+ EActionComboBox *combo_box)
+{
+ g_object_set (
+ combo_box, "sensitive",
+ gtk_action_group_get_sensitive (action_group), "visible",
+ gtk_action_group_get_visible (action_group), NULL);
+}
+
+static void
+action_combo_box_render_pixbuf (GtkCellLayout *layout,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ EActionComboBox *combo_box)
+{
+ GtkRadioAction *action;
+ gchar *icon_name;
+ gchar *stock_id;
+ gboolean sensitive;
+ gboolean visible;
+ gint width;
+
+ gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1);
+
+ /* Do any of the actions have an icon? */
+ if (!combo_box->priv->group_has_icons)
+ return;
+
+ /* A NULL action means the row is a separator. */
+ if (action == NULL)
+ return;
+
+ g_object_get (
+ G_OBJECT (action),
+ "icon-name", &icon_name,
+ "sensitive", &sensitive,
+ "stock-id", &stock_id,
+ "visible", &visible,
+ NULL);
+
+ /* Keep the pixbuf renderer a fixed size for proper alignment. */
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL);
+
+ /* We can't set both "icon-name" and "stock-id" because setting
+ * one unsets the other. So pick the one that has a non-NULL
+ * value. If both are non-NULL, "stock-id" wins. */
+
+ if (stock_id != NULL)
+ g_object_set (
+ G_OBJECT (renderer),
+ "sensitive", sensitive,
+ "stock-id", stock_id,
+ "stock-size", GTK_ICON_SIZE_MENU,
+ "visible", visible,
+ "width", width,
+ NULL);
+ else
+ g_object_set (
+ G_OBJECT (renderer),
+ "icon-name", icon_name,
+ "sensitive", sensitive,
+ "stock-size", GTK_ICON_SIZE_MENU,
+ "visible", visible,
+ "width", width,
+ NULL);
+
+ g_free (icon_name);
+ g_free (stock_id);
+}
+
+static void
+action_combo_box_render_text (GtkCellLayout *layout,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ EActionComboBox *combo_box)
+{
+ GtkRadioAction *action;
+ gchar **strv;
+ gchar *label;
+ gboolean sensitive;
+ gboolean visible;
+ gint xpad;
+
+ gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1);
+
+ /* A NULL action means the row is a separator. */
+ if (action == NULL)
+ return;
+
+ g_object_get (
+ G_OBJECT (action),
+ "label", &label,
+ "sensitive", &sensitive,
+ "visible", &visible,
+ NULL);
+
+ /* Strip out underscores. */
+ strv = g_strsplit (label, "_", -1);
+ g_free (label);
+ label = g_strjoinv (NULL, strv);
+ g_strfreev (strv);
+
+ xpad = combo_box->priv->group_has_icons ? 3 : 0;
+
+ g_object_set (
+ G_OBJECT (renderer),
+ "sensitive", sensitive,
+ "text", label,
+ "visible", visible,
+ "xpad", xpad,
+ NULL);
+
+ g_free (label);
+}
+
+static gboolean
+action_combo_box_is_row_separator (GtkTreeModel *model,
+ GtkTreeIter *iter)
+{
+ GtkAction *action;
+ gboolean separator;
+
+ /* NULL actions are rendered as separators. */
+ gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1);
+ separator = (action == NULL);
+ if (action != NULL)
+ g_object_unref (action);
+
+ return separator;
+}
+
+static void
+action_combo_box_update_model (EActionComboBox *combo_box)
+{
+ GtkListStore *list_store;
+ GSList *list;
+
+ g_hash_table_remove_all (combo_box->priv->index);
+
+ if (combo_box->priv->action == NULL) {
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), NULL);
+ return;
+ }
+
+ /* We store values in the sort column as floats so that we can
+ * insert separators in between consecutive integer values and
+ * still maintain the proper ordering. */
+ list_store = gtk_list_store_new (
+ 2, GTK_TYPE_RADIO_ACTION, G_TYPE_FLOAT);
+
+ list = gtk_radio_action_get_group (combo_box->priv->action);
+ combo_box->priv->group_has_icons = FALSE;
+
+ while (list != NULL) {
+ GtkTreeRowReference *reference;
+ GtkRadioAction *action = list->data;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gchar *icon_name;
+ gchar *stock_id;
+ gint value;
+
+ g_object_get (
+ action, "icon-name", &icon_name,
+ "stock-id", &stock_id, NULL);
+ combo_box->priv->group_has_icons |=
+ (icon_name != NULL || stock_id != NULL);
+ g_free (icon_name);
+ g_free (stock_id);
+
+ gtk_list_store_append (list_store, &iter);
+ g_object_get (G_OBJECT (action), "value", &value, NULL);
+ gtk_list_store_set (
+ list_store, &iter, COLUMN_ACTION,
+ list->data, COLUMN_SORT, (gfloat) value, -1);
+
+ path = gtk_tree_model_get_path (
+ GTK_TREE_MODEL (list_store), &iter);
+ reference = gtk_tree_row_reference_new (
+ GTK_TREE_MODEL (list_store), path);
+ g_hash_table_insert (
+ combo_box->priv->index,
+ GINT_TO_POINTER (value), reference);
+ gtk_tree_path_free (path);
+
+ list = g_slist_next (list);
+ }
+
+ gtk_tree_sortable_set_sort_column_id (
+ GTK_TREE_SORTABLE (list_store),
+ COLUMN_SORT, GTK_SORT_ASCENDING);
+ gtk_combo_box_set_model (
+ GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (list_store));
+
+ action_combo_box_action_changed_cb (
+ combo_box->priv->action,
+ combo_box->priv->action,
+ combo_box);
+}
+
+static void
+action_combo_box_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTION:
+ e_action_combo_box_set_action (
+ E_ACTION_COMBO_BOX (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+action_combo_box_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTION:
+ g_value_set_object (
+ value, e_action_combo_box_get_action (
+ E_ACTION_COMBO_BOX (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+action_combo_box_dispose (GObject *object)
+{
+ EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX_GET_PRIVATE (object);
+
+ if (priv->action != NULL) {
+ g_object_unref (priv->action);
+ priv->action = NULL;
+ }
+
+ if (priv->action_group != NULL) {
+ g_object_unref (priv->action_group);
+ priv->action_group = NULL;
+ }
+
+ g_hash_table_remove_all (priv->index);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+action_combo_box_finalize (GObject *object)
+{
+ EActionComboBoxPrivate *priv = E_ACTION_COMBO_BOX_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->index);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+action_combo_box_changed (GtkComboBox *combo_box)
+{
+ GtkRadioAction *action;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gint value;
+
+ /* This method is virtual, so no need to chain up. */
+
+ if (!gtk_combo_box_get_active_iter (combo_box, &iter))
+ return;
+
+ model = gtk_combo_box_get_model (combo_box);
+ gtk_tree_model_get (model, &iter, COLUMN_ACTION, &action, -1);
+ g_object_get (G_OBJECT (action), "value", &value, NULL);
+ gtk_radio_action_set_current_value (action, value);
+}
+
+static void
+action_combo_box_class_init (EActionComboBoxClass *class)
+{
+ GObjectClass *object_class;
+ GtkComboBoxClass *combo_box_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EActionComboBoxPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = action_combo_box_set_property;
+ object_class->get_property = action_combo_box_get_property;
+ object_class->dispose = action_combo_box_dispose;
+ object_class->finalize = action_combo_box_finalize;
+
+ combo_box_class = GTK_COMBO_BOX_CLASS (class);
+ combo_box_class->changed = action_combo_box_changed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTION,
+ g_param_spec_object (
+ "action",
+ _("Action"),
+ _("A GtkRadioAction"),
+ GTK_TYPE_RADIO_ACTION,
+ G_PARAM_READWRITE));
+}
+
+static void
+action_combo_box_init (EActionComboBox *combo_box)
+{
+ GtkCellRenderer *renderer;
+
+ combo_box->priv = E_ACTION_COMBO_BOX_GET_PRIVATE (combo_box);
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (
+ GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
+ gtk_cell_layout_set_cell_data_func (
+ GTK_CELL_LAYOUT (combo_box), renderer,
+ (GtkCellLayoutDataFunc) action_combo_box_render_pixbuf,
+ combo_box, NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (
+ GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
+ gtk_cell_layout_set_cell_data_func (
+ GTK_CELL_LAYOUT (combo_box), renderer,
+ (GtkCellLayoutDataFunc) action_combo_box_render_text,
+ combo_box, NULL);
+
+ gtk_combo_box_set_row_separator_func (
+ GTK_COMBO_BOX (combo_box), (GtkTreeViewRowSeparatorFunc)
+ action_combo_box_is_row_separator, NULL, NULL);
+
+ combo_box->priv->index = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) gtk_tree_row_reference_free);
+}
+
+GType
+e_action_combo_box_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EActionComboBoxClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) action_combo_box_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EActionComboBox),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) action_combo_box_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_COMBO_BOX, "EActionComboBox",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_action_combo_box_new (void)
+{
+ return e_action_combo_box_new_with_action (NULL);
+}
+
+GtkWidget *
+e_action_combo_box_new_with_action (GtkRadioAction *action)
+{
+ return g_object_new (E_TYPE_ACTION_COMBO_BOX, "action", action, NULL);
+}
+
+GtkRadioAction *
+e_action_combo_box_get_action (EActionComboBox *combo_box)
+{
+ g_return_val_if_fail (E_ACTION_IS_COMBO_BOX (combo_box), NULL);
+
+ return combo_box->priv->action;
+}
+
+void
+e_action_combo_box_set_action (EActionComboBox *combo_box,
+ GtkRadioAction *action)
+{
+ g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box));
+
+ if (action != NULL)
+ g_return_if_fail (GTK_IS_RADIO_ACTION (action));
+
+ if (combo_box->priv->action != NULL) {
+ g_signal_handler_disconnect (
+ combo_box->priv->action,
+ combo_box->priv->changed_handler_id);
+ g_object_unref (combo_box->priv->action);
+ }
+
+ if (combo_box->priv->action_group != NULL) {
+ g_signal_handler_disconnect (
+ combo_box->priv->action_group,
+ combo_box->priv->group_sensitive_handler_id);
+ g_signal_handler_disconnect (
+ combo_box->priv->action_group,
+ combo_box->priv->group_visible_handler_id);
+ g_object_unref (combo_box->priv->action_group);
+ combo_box->priv->action_group = NULL;
+ }
+
+ if (action != NULL)
+ g_object_get (
+ g_object_ref (action), "action-group",
+ &combo_box->priv->action_group, NULL);
+ combo_box->priv->action = action;
+ action_combo_box_update_model (combo_box);
+
+ if (combo_box->priv->action != NULL)
+ combo_box->priv->changed_handler_id = g_signal_connect (
+ combo_box->priv->action, "changed",
+ G_CALLBACK (action_combo_box_action_changed_cb),
+ combo_box);
+
+ if (combo_box->priv->action_group != NULL) {
+ combo_box->priv->group_sensitive_handler_id =
+ g_signal_connect (
+ combo_box->priv->action_group,
+ "notify::sensitive", G_CALLBACK (
+ action_combo_box_action_group_notify_cb),
+ combo_box);
+ combo_box->priv->group_visible_handler_id =
+ g_signal_connect (
+ combo_box->priv->action_group,
+ "notify::visible", G_CALLBACK (
+ action_combo_box_action_group_notify_cb),
+ combo_box);
+ }
+}
+
+gint
+e_action_combo_box_get_current_value (EActionComboBox *combo_box)
+{
+ g_return_val_if_fail (E_ACTION_IS_COMBO_BOX (combo_box), 0);
+ g_return_val_if_fail (combo_box->priv->action != NULL, 0);
+
+ return gtk_radio_action_get_current_value (combo_box->priv->action);
+}
+
+void
+e_action_combo_box_set_current_value (EActionComboBox *combo_box,
+ gint current_value)
+{
+ g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box));
+ g_return_if_fail (combo_box->priv->action != NULL);
+
+ gtk_radio_action_set_current_value (
+ combo_box->priv->action, current_value);
+}
+
+void
+e_action_combo_box_add_separator_before (EActionComboBox *combo_box,
+ gint action_value)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box));
+
+ /* NULL actions are rendered as separators. */
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter, COLUMN_ACTION,
+ NULL, COLUMN_SORT, (gfloat) action_value - 0.5, -1);
+}
+
+void
+e_action_combo_box_add_separator_after (EActionComboBox *combo_box,
+ gint action_value)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box));
+
+ /* NULL actions are rendered as separators. */
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter, COLUMN_ACTION,
+ NULL, COLUMN_SORT, (gfloat) action_value + 0.5, -1);
+}
diff --git a/widgets/misc/e-action-combo-box.h b/widgets/misc/e-action-combo-box.h
new file mode 100644
index 0000000000..300338639a
--- /dev/null
+++ b/widgets/misc/e-action-combo-box.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-action-combo-box.h
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef E_ACTION_COMBO_BOX_H
+#define E_ACTION_COMBO_BOX_H
+
+/* This is a GtkComboBox that is driven by a group of GtkRadioActions.
+ * Just plug in a GtkRadioAction and the widget will handle the rest.
+ * (Based on GtkhtmlComboBox.) */
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ACTION_COMBO_BOX \
+ (e_action_combo_box_get_type ())
+#define E_ACTION_COMBO_BOX(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBox))
+#define E_ACTION_COMBO_BOX_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxClass))
+#define E_ACTION_IS_COMBO_BOX(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ACTION_COMBO_BOX))
+#define E_ACTION_IS_COMBO_BOX_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ACTION_COMBO_BOX))
+#define E_ACTION_COMBO_BOX_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ACTION_COMBO_BOX, EActionComboBoxClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EActionComboBox EActionComboBox;
+typedef struct _EActionComboBoxClass EActionComboBoxClass;
+typedef struct _EActionComboBoxPrivate EActionComboBoxPrivate;
+
+struct _EActionComboBox {
+ GtkComboBox parent;
+ EActionComboBoxPrivate *priv;
+};
+
+struct _EActionComboBoxClass {
+ GtkComboBoxClass parent_class;
+};
+
+GType e_action_combo_box_get_type (void);
+GtkWidget * e_action_combo_box_new (void);
+GtkWidget * e_action_combo_box_new_with_action
+ (GtkRadioAction *action);
+GtkRadioAction *e_action_combo_box_get_action (EActionComboBox *combo_box);
+void e_action_combo_box_set_action (EActionComboBox *combo_box,
+ GtkRadioAction *action);
+gint e_action_combo_box_get_current_value
+ (EActionComboBox *combo_box);
+void e_action_combo_box_set_current_value
+ (EActionComboBox *combo_box,
+ gint current_value);
+void e_action_combo_box_add_separator_before
+ (EActionComboBox *combo_box,
+ gint action_value);
+void e_action_combo_box_add_separator_after
+ (EActionComboBox *combo_box,
+ gint action_value);
+
+G_END_DECLS
+
+#endif /* E_ACTION_COMBO_BOX_H */
diff --git a/widgets/misc/e-activity-handler.c b/widgets/misc/e-activity-handler.c
deleted file mode 100644
index 338e4015fb..0000000000
--- a/widgets/misc/e-activity-handler.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-activity-handler.h"
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-#include <misc/e-popup-menu.h>
-
-#define ICON_SIZE 16
-
-struct _ActivityInfo {
- gchar *component_id;
- gint error_type;
- guint id;
- gchar *information;
- gboolean cancellable;
- double progress;
- GtkWidget *menu;
- void (*cancel_func) (gpointer data);
- gpointer data;
- gpointer error;
- time_t error_time;
-};
-typedef struct _ActivityInfo ActivityInfo;
-
-struct _EActivityHandlerPrivate {
- guint next_activity_id;
- GList *activity_infos;
- GSList *task_bars;
- ELogger *logger;
- guint error_timer;
- guint error_flush_interval;
-
-};
-
-/* In the status bar, we show only errors and info. Errors are pictured as warnings. */
-const gchar *icon_data [] = {"dialog-warning", "dialog-information"};
-
-G_DEFINE_TYPE (EActivityHandler, e_activity_handler, G_TYPE_OBJECT)
-
-/* Utility functions. */
-
-static void handle_error (ETaskWidget *task);
-
-static guint
-get_new_activity_id (EActivityHandler *activity_handler)
-{
- EActivityHandlerPrivate *priv;
-
- priv = activity_handler->priv;
-
- return priv->next_activity_id ++;
-}
-
-static GList *
-lookup_activity (GList *list,
- guint activity_id,
- gint *order_number_return)
-{
- GList *p;
- gint i;
-
- for (p = list, i = 0; p != NULL; p = p->next, i ++) {
- ActivityInfo *activity_info;
-
- activity_info = (ActivityInfo *) p->data;
- if (activity_info->id == activity_id) {
- *order_number_return = i;
- return p;
- }
- }
-
- *order_number_return = -1;
- return NULL;
-}
-
-/* ETaskWidget actions. */
-
-static gint
-task_widget_button_press_event_callback (GtkWidget *widget,
- GdkEventButton *button_event,
- gpointer data)
-{
- ActivityInfo *activity_info;
-
- activity_info = (ActivityInfo *) data;
-
- if (button_event->button == 3)
- return activity_info->cancellable;
-
- if (button_event->button != 1)
- return FALSE;
-
- return TRUE;
-}
-
-/* Creating and destroying ActivityInfos. */
-
-static ActivityInfo *
-activity_info_new (const gchar *component_id,
- guint id,
- const gchar *information,
- gboolean cancellable)
-{
- ActivityInfo *info;
-
- info = g_new (ActivityInfo, 1);
- info->component_id = g_strdup (component_id);
- info->id = id;
- info->information = g_strdup (information);
- info->cancellable = cancellable;
- info->progress = -1.0; /* (Unknown) */
- info->menu = NULL;
- info->error = NULL;
- info->cancel_func = NULL;
-
- return info;
-}
-
-static void
-activity_info_free (ActivityInfo *info)
-{
- g_free (info->component_id);
- g_free (info->information);
-
- if (info->menu != NULL)
- gtk_widget_destroy (info->menu);
-
- g_free (info);
-}
-
-static ETaskWidget *
-task_widget_new_from_activity_info (ActivityInfo *activity_info)
-{
- GtkWidget *widget;
- ETaskWidget *etw;
-
- widget = e_task_widget_new_with_cancel (
- activity_info->component_id,
- activity_info->information,
- activity_info->cancel_func,
- activity_info->data);
- etw = (ETaskWidget *) widget;
- etw->id = activity_info->id;
- gtk_widget_show (widget);
-
- g_signal_connect (widget, "button_press_event",
- G_CALLBACK (task_widget_button_press_event_callback),
- activity_info);
-
- return E_TASK_WIDGET (widget);
-}
-
-/* Task Bar handling. */
-
-static void
-setup_task_bar (EActivityHandler *activity_handler,
- ETaskBar *task_bar)
-{
- EActivityHandlerPrivate *priv;
- GList *p;
-
- priv = activity_handler->priv;
-
- for (p = g_list_last (priv->activity_infos); p != NULL; p = p->prev) {
- ActivityInfo *info = p->data;
- ETaskWidget *task_widget = task_widget_new_from_activity_info (info);
- task_widget->id = info->id;
- e_task_bar_prepend_task (task_bar, task_widget);
- if (info->error) {
- /* Prepare to handle existing errors*/
- GtkWidget *tool;
- const gchar *stock;
-
- stock = info->error_type ? icon_data [1] : icon_data[0];
- tool = e_task_widget_update_image (task_widget, (gchar *)stock, info->information);
- g_object_set_data ((GObject *) task_widget, "tool", tool);
- g_object_set_data ((GObject *) task_widget, "error", info->error);
- g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler);
- g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(info->id));
- g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(info->error_type));
- g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget);
- }
- }
-}
-
-static void
-task_bar_destroy_notify (gpointer data,
- GObject *task_bar_instance)
-{
- EActivityHandler *activity_handler;
- EActivityHandlerPrivate *priv;
-
- activity_handler = E_ACTIVITY_HANDLER (data);
- priv = activity_handler->priv;
-
- priv->task_bars = g_slist_remove (priv->task_bars, task_bar_instance);
-}
-
-/* GObject methods. */
-
-static void
-impl_dispose (GObject *object)
-{
- EActivityHandler *handler;
- EActivityHandlerPrivate *priv;
- GList *p;
- GSList *sp;
-
- handler = E_ACTIVITY_HANDLER (object);
- priv = handler->priv;
-
- for (p = priv->activity_infos; p != NULL; p = p->next) {
- ActivityInfo *info;
-
- info = (ActivityInfo *) p->data;
- activity_info_free (info);
- }
-
- g_list_free (priv->activity_infos);
- priv->activity_infos = NULL;
-
- for (sp = priv->task_bars; sp != NULL; sp = sp->next)
- g_object_weak_unref (G_OBJECT (sp->data), task_bar_destroy_notify, handler);
- priv->task_bars = NULL;
-
- (* G_OBJECT_CLASS (e_activity_handler_parent_class)->dispose) (object);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- EActivityHandler *handler;
- EActivityHandlerPrivate *priv;
-
- handler = E_ACTIVITY_HANDLER (object);
- priv = handler->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_activity_handler_parent_class)->finalize) (object);
-}
-
-static void
-e_activity_handler_class_init (EActivityHandlerClass *activity_handler_class)
-{
- GObjectClass *object_class = (GObjectClass *) activity_handler_class;
-
- object_class->dispose = impl_dispose;
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_activity_handler_init (EActivityHandler *activity_handler)
-{
- EActivityHandlerPrivate *priv;
-
- priv = g_new (EActivityHandlerPrivate, 1);
- priv->next_activity_id = 1;
- priv->activity_infos = NULL;
- priv->task_bars = NULL;
- priv->logger = NULL;
- priv->error_timer = 0;
- priv->error_flush_interval = 0;
- activity_handler->priv = priv;
-}
-
-EActivityHandler *
-e_activity_handler_new (void)
-{
- return g_object_new (e_activity_handler_get_type (), NULL);
-}
-
-void
-e_activity_handler_set_error_flush_time (EActivityHandler *handler, gint time)
-{
- handler->priv->error_flush_interval = time;
-}
-void
-e_activity_handler_set_logger (EActivityHandler *handler, ELogger *logger)
-{
- handler->priv->logger = logger;
-}
-
-void
-e_activity_handler_set_message (EActivityHandler *activity_handler,
- const gchar *message)
-{
- EActivityHandlerPrivate *priv;
- GSList *i;
-
- priv = activity_handler->priv;
-
- for (i = priv->task_bars; i; i = i->next)
- e_task_bar_set_message (E_TASK_BAR (i->data), message);
-}
-
-void
-e_activity_handler_unset_message (EActivityHandler *activity_handler)
-{
- EActivityHandlerPrivate *priv;
- GSList *i;
-
- priv = activity_handler->priv;
-
- for (i = priv->task_bars; i; i = i->next)
- e_task_bar_unset_message (E_TASK_BAR (i->data));
-}
-
-void
-e_activity_handler_attach_task_bar (EActivityHandler *activity_handler,
- ETaskBar *task_bar)
-{
- EActivityHandlerPrivate *priv;
-
- g_return_if_fail (activity_handler != NULL);
- g_return_if_fail (E_IS_ACTIVITY_HANDLER (activity_handler));
- g_return_if_fail (task_bar != NULL);
- g_return_if_fail (E_IS_TASK_BAR (task_bar));
-
- priv = activity_handler->priv;
-
- g_object_weak_ref (G_OBJECT (task_bar), task_bar_destroy_notify, activity_handler);
-
- priv->task_bars = g_slist_prepend (priv->task_bars, task_bar);
-
- setup_task_bar (activity_handler, task_bar);
-}
-
-struct _cancel_wdata {
- EActivityHandler *handler;
- ActivityInfo *info;
- guint id;
- void (*cancel)(gpointer);
- gpointer data;
-};
-
-static void
-cancel_wrapper (gpointer pdata)
-{
- struct _cancel_wdata *data = (struct _cancel_wdata *) pdata;
- /* This can be invoked in two scenario. Either to cancel or to hide error */
- if (data->info->error) {
- /* Hide the error */
- EActivityHandler *handler = data->handler;
- ActivityInfo *info;
- gint order, len;
- GSList *sp;
- GList *p = lookup_activity (handler->priv->activity_infos, data->id, &order);
- e_logger_log (handler->priv->logger, E_LOG_ERROR, g_object_get_data (data->info->error, "primary"),
- g_object_get_data (data->info->error, "secondary"));
- gtk_widget_destroy (data->info->error);
- data->info->error = NULL;
- info = data->info;
- for (sp = handler->priv->task_bars; sp != NULL; sp = sp->next) {
- ETaskBar *task_bar;
-
- task_bar = E_TASK_BAR (sp->data);
- e_task_bar_remove_task_from_id (task_bar, info->id);
- }
- activity_info_free (info);
- len = g_list_length (handler->priv->activity_infos);
- handler->priv->activity_infos = g_list_remove_link (handler->priv->activity_infos, p);
- if (len == 1)
- handler->priv->activity_infos = NULL;
- } else {
- /* Cancel the operation */
- data->cancel (data->data);
- }
- /* No need to free the data. It will be freed as part of the task widget destroy */
-}
-
-/* CORBA methods. */
-guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler,
- const gchar *component_id,
- const gchar *information,
- gboolean cancellable,
- void (*cancel_func)(gpointer),
- gpointer user_data)
-{
- EActivityHandlerPrivate *priv;
- ActivityInfo *activity_info;
- guint activity_id;
- GSList *p;
- struct _cancel_wdata *data;
- gboolean bfree = FALSE;
- priv = activity_handler->priv;
-
- activity_id = get_new_activity_id (activity_handler);
- activity_info = activity_info_new (component_id, activity_id, information, cancellable);
-
- data = g_new(struct _cancel_wdata, 1);
- data->handler = activity_handler;
- data->id = activity_id;
- data->info = activity_info;
- data->cancel = cancel_func;
- data->data = user_data;
-
- activity_info->cancel_func = cancel_wrapper;
- activity_info->data = data;
- for (p = priv->task_bars; p != NULL; p = p->next) {
- ETaskWidget *tw = task_widget_new_from_activity_info (activity_info);
- tw->id = activity_id;
- if (!bfree) {
- /* The data will be freed part of the widget destroy */
- g_object_set_data_full ((GObject *) tw, "free-data", data, g_free);
- bfree = TRUE;
- }
- e_task_bar_prepend_task (E_TASK_BAR (p->data), tw);
- }
-
- priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info);
-
- return activity_id;
-
-}
-
-guint
-e_activity_handler_operation_started (EActivityHandler *activity_handler,
- const gchar *component_id,
- const gchar *information,
- gboolean cancellable)
-{
- EActivityHandlerPrivate *priv;
- ActivityInfo *activity_info;
- guint activity_id;
- GSList *p;
-
- priv = activity_handler->priv;
-
- activity_id = get_new_activity_id (activity_handler);
-
- activity_info = activity_info_new (component_id, activity_id, information, cancellable);
-
- for (p = priv->task_bars; p != NULL; p = p->next) {
- ETaskWidget *tw = task_widget_new_from_activity_info (activity_info);
- tw->id = activity_id;
- e_task_bar_prepend_task (E_TASK_BAR (p->data), tw);
- }
-
- priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info);
-
- return activity_id;
-}
-
-static void
-handle_error (ETaskWidget *task)
-{
- GtkWidget *tool, *error;
- EActivityHandler *activity_handler;
- guint id;
- gint error_type = GPOINTER_TO_INT((g_object_get_data ((GObject *) task, "error-type")));
- tool = g_object_get_data ((GObject *) task, "tool");
- error = g_object_get_data ((GObject *) task, "error");
- activity_handler = g_object_get_data ((GObject *) task, "activity-handler");
- id = GPOINTER_TO_UINT (g_object_get_data ((GObject *) task, "activity"));
- e_activity_handler_operation_finished (activity_handler, id);
- gtk_widget_show (error);
- e_logger_log (activity_handler->priv->logger, error_type,
- g_object_get_data ((GObject *) error, "primary"),
- g_object_get_data ((GObject *) error, "secondary"));
-}
-
-static gboolean
-error_cleanup (EActivityHandler *activity_handler)
-{
- EActivityHandlerPrivate *priv = activity_handler->priv;
- GList *p, *node;
- GSList *sp;
- gint i;
- time_t now = time (NULL);
- gboolean berror = FALSE;
-
- for (p = priv->activity_infos, i = 0; p != NULL; i++) {
- ActivityInfo *info;
-
- info = (ActivityInfo *) p->data;
- if (info->error)
- berror = TRUE;
- if (info->error && info->error_time && (now - info->error_time) > 5 ) {
- /* Error older than wanted time. So cleanup */
- e_logger_log (priv->logger, info->error_type, g_object_get_data (info->error, "primary"),
- g_object_get_data (info->error, "secondary"));
-
- if (GTK_IS_DIALOG (info->error))
- gtk_dialog_response (GTK_DIALOG (info->error), GTK_RESPONSE_CLOSE);
- else
- gtk_widget_destroy (info->error);
-
- node = p;
- p = p->next;
-
- for (sp = priv->task_bars; sp != NULL; sp = sp->next) {
- ETaskBar *task_bar;
-
- task_bar = E_TASK_BAR (sp->data);
- e_task_bar_remove_task_from_id (task_bar, info->id);
- }
- activity_info_free (info);
- priv->activity_infos = g_list_remove_link (priv->activity_infos, node);
-
- } else
- p = p->next;
- }
- if (!berror)
- priv->error_timer = 0;
- return berror;
-}
-
-static gboolean
-show_intrusive_errors (void)
-{
- const gchar *intrusive = NULL;
-
- intrusive = g_getenv ("EVO-SHOW-INTRUSIVE-ERRORS");
-
- if (intrusive && g_str_equal (intrusive, "1"))
- return TRUE;
- else
- return FALSE;
-}
-
-guint
-e_activity_handler_make_error (EActivityHandler *activity_handler,
- const gchar *component_id,
- gint error_type,
- GtkWidget *error)
-{
- EActivityHandlerPrivate *priv;
- ActivityInfo *activity_info;
- guint activity_id;
- GSList *p;
- gchar *information = g_object_get_data((GObject *) error, "primary");
- const gchar *img;
-
- priv = activity_handler->priv;
- activity_id = get_new_activity_id (activity_handler);
-
- if (show_intrusive_errors ()) {
- gtk_widget_show (error);
- return activity_id;
- }
-
- activity_info = activity_info_new (component_id, activity_id, information, TRUE);
- activity_info->error = error;
- activity_info->error_time = time (NULL);
- activity_info->error_type = error_type;
-
- img = error_type ? icon_data[1] : icon_data[0];
- for (p = priv->task_bars; p != NULL; p = p->next) {
- ETaskBar *task_bar;
- ETaskWidget *task_widget;
- GtkWidget *tool;
-
- task_bar = E_TASK_BAR (p->data);
- task_widget = task_widget_new_from_activity_info (activity_info);
- task_widget->id = activity_id;
- e_task_bar_prepend_task (E_TASK_BAR (p->data), task_widget);
-
- tool = e_task_widget_update_image (task_widget, (gchar *)img, information);
- g_object_set_data ((GObject *) task_widget, "tool", tool);
- g_object_set_data ((GObject *) task_widget, "error", error);
- g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler);
- g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(activity_id));
- g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(error_type));
- g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget);
- }
-
- priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info);
-
- if (!activity_handler->priv->error_timer)
- activity_handler->priv->error_timer = g_timeout_add (activity_handler->priv->error_flush_interval, (GSourceFunc)error_cleanup, activity_handler);
-
- return activity_id;
-}
-
-void
-e_activity_handler_operation_set_error(EActivityHandler *activity_handler,
- guint activity_id,
- GtkWidget *error)
-{
- EActivityHandlerPrivate *priv = activity_handler->priv;
- ActivityInfo *activity_info;
- GList *p;
- GSList *sp;
- gint order_number;
-
- p = lookup_activity (priv->activity_infos, activity_id, &order_number);
- if (p == NULL) {
- g_warning ("EActivityHandler: unknown operation %d", activity_id);
- return;
- }
-
- activity_info = (ActivityInfo *) p->data;
- activity_info->error = error;
- activity_info->error_time = time (NULL);
- activity_info->error_type = E_LOG_ERROR;
- g_free (activity_info->information);
- activity_info->information = g_strdup (g_object_get_data ((GObject *) error, "primary"));
- for (sp = priv->task_bars; sp != NULL; sp = sp->next) {
- ETaskBar *task_bar;
- ETaskWidget *task_widget;
- GtkWidget *tool;
-
- task_bar = E_TASK_BAR (sp->data);
- task_widget = e_task_bar_get_task_widget_from_id (task_bar, activity_info->id);
- if (!task_widget)
- continue;
-
- tool = e_task_widget_update_image (task_widget, (gchar *)icon_data[0], g_object_get_data ((GObject *) error, "primary"));
- g_object_set_data ((GObject *) task_widget, "tool", tool);
- g_object_set_data ((GObject *) task_widget, "error", error);
- g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler);
- g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(activity_id));
- g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(E_LOG_ERROR));
- g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget);
- }
-
- if (!activity_handler->priv->error_timer)
- activity_handler->priv->error_timer = g_timeout_add (activity_handler->priv->error_flush_interval, (GSourceFunc) error_cleanup, activity_handler);
-}
-
-void
-e_activity_handler_operation_progressing (EActivityHandler *activity_handler,
- guint activity_id,
- const gchar *information,
- double progress)
-{
- EActivityHandlerPrivate *priv = activity_handler->priv;
- ActivityInfo *activity_info;
- GList *p;
- GSList *sp;
- gint order_number;
-
- p = lookup_activity (priv->activity_infos, activity_id, &order_number);
- if (p == NULL) {
- g_warning ("EActivityHandler: unknown operation %d", activity_id);
- return;
- }
-
- activity_info = (ActivityInfo *) p->data;
-
- g_free (activity_info->information);
- activity_info->information = g_strdup (information);
-
- activity_info->progress = progress;
-
- for (sp = priv->task_bars; sp != NULL; sp = sp->next) {
- ETaskBar *task_bar;
- ETaskWidget *task_widget;
-
- task_bar = E_TASK_BAR (sp->data);
- task_widget = e_task_bar_get_task_widget_from_id (task_bar, activity_info->id);
- if (!task_widget)
- continue;
-
- e_task_widget_update (task_widget, information, progress);
- }
-}
-
-void
-e_activity_handler_operation_finished (EActivityHandler *activity_handler,
- guint activity_id)
-{
- EActivityHandlerPrivate *priv = activity_handler->priv;
- GList *p;
- GSList *sp;
- gint order_number;
-
- p = lookup_activity (priv->activity_infos, activity_id, &order_number);
- if (p == NULL) {
- g_warning ("e_activity_handler_operation_finished: Unknown activity %d\n", activity_id);
- return;
- }
-
- activity_info_free ((ActivityInfo *) p->data);
- priv->activity_infos = g_list_remove_link (priv->activity_infos, p);
-
- for (sp = priv->task_bars; sp != NULL; sp = sp->next) {
- ETaskBar *task_bar;
-
- task_bar = E_TASK_BAR (sp->data);
- e_task_bar_remove_task_from_id (task_bar, activity_id);
- }
-}
-
diff --git a/widgets/misc/e-activity-handler.h b/widgets/misc/e-activity-handler.h
deleted file mode 100644
index 3fd5c64d9a..0000000000
--- a/widgets/misc/e-activity-handler.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_ACTIVITY_HANDLER_H_
-#define _E_ACTIVITY_HANDLER_H_
-
-#include "e-task-bar.h"
-#include "e-util/e-logger.h"
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_ACTIVITY_HANDLER (e_activity_handler_get_type ())
-#define E_ACTIVITY_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_ACTIVITY_HANDLER, EActivityHandler))
-#define E_ACTIVITY_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_ACTIVITY_HANDLER, EActivityHandlerClass))
-#define E_IS_ACTIVITY_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_ACTIVITY_HANDLER))
-#define E_IS_ACTIVITY_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_ACTIVITY_HANDLER))
-
-typedef struct _EActivityHandler EActivityHandler;
-typedef struct _EActivityHandlerPrivate EActivityHandlerPrivate;
-typedef struct _EActivityHandlerClass EActivityHandlerClass;
-
-#define EAH_ICON_INFO "stock_dialog-info"
-#define EAH_ICON_ERROR "stock_dialog-warning"
-
-struct _EActivityHandler {
- GObject parent;
-
- EActivityHandlerPrivate *priv;
-};
-
-struct _EActivityHandlerClass {
- GObjectClass parent_class;
-};
-
-GType e_activity_handler_get_type (void);
-
-EActivityHandler *e_activity_handler_new (void);
-
-void e_activity_handler_attach_task_bar (EActivityHandler *activity_hanlder,
- ETaskBar *task_bar);
-
-void e_activity_handler_set_message (EActivityHandler *activity_handler,
- const gchar *message);
-
-void e_activity_handler_unset_message (EActivityHandler *activity_handler);
-
-guint e_activity_handler_operation_started (EActivityHandler *activity_handler,
- const gchar *component_id,
- const gchar *information,
- gboolean cancellable);
-guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler,
- const gchar *component_id,
- const gchar *information,
- gboolean cancellable,
- void (*cancel_func)(gpointer),
- gpointer user_data);
-
-void e_activity_handler_operation_progressing (EActivityHandler *activity_handler,
- guint activity_id,
- const gchar *information,
- double progress);
-
-void e_activity_handler_operation_finished (EActivityHandler *activity_handler,
- guint activity_id);
-
-void e_activity_handler_set_logger (EActivityHandler *handler, ELogger *logger);
-guint e_activity_handler_make_error (EActivityHandler *activity_handler,
- const gchar *component_id,
- gint error_type,
- GtkWidget *error);
-void
-e_activity_handler_operation_set_error (EActivityHandler *activity_handler,
- guint activity_id,
- GtkWidget *error);
-
-void
-e_activity_handler_set_error_flush_time (EActivityHandler *handler, gint time);
-
-G_END_DECLS
-
-#endif /* _E_ACTIVITY_HANDLER_H_ */
diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c
new file mode 100644
index 0000000000..10249b1911
--- /dev/null
+++ b/widgets/misc/e-activity-proxy.c
@@ -0,0 +1,346 @@
+/*
+ * e-activity-proxy.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-activity-proxy.h"
+
+#include <glib/gi18n.h>
+#include <e-spinner.h>
+
+#define E_ACTIVITY_PROXY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxyPrivate))
+
+struct _EActivityProxyPrivate {
+ EActivity *activity;
+ GtkWidget *button;
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkWidget *cancel;
+ GtkWidget *spinner;
+};
+
+enum {
+ PROP_0,
+ PROP_ACTIVITY
+};
+
+static gpointer parent_class;
+
+static void
+activity_proxy_update (EActivityProxy *proxy)
+{
+ EActivity *activity = proxy->priv->activity;
+ const gchar *icon_name;
+ gboolean allow_cancel;
+ gboolean cancelled;
+ gboolean clickable;
+ gboolean completed;
+ gboolean sensitive;
+ gchar *description;
+
+ allow_cancel = e_activity_get_allow_cancel (activity);
+ cancelled = e_activity_is_cancelled (activity);
+ clickable = e_activity_get_clickable (activity);
+ completed = e_activity_is_completed (activity);
+ icon_name = e_activity_get_icon_name (activity);
+
+ description = e_activity_describe (activity);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (proxy), description);
+ gtk_label_set_text (GTK_LABEL (proxy->priv->label), description);
+ g_free (description);
+
+ /* Note, an activity requires an icon name in order to
+ * be clickable. We don't support spinner buttons. */
+ if (icon_name != NULL) {
+ gtk_image_set_from_icon_name (
+ GTK_IMAGE (proxy->priv->image),
+ icon_name, GTK_ICON_SIZE_MENU);
+ gtk_button_set_image (
+ GTK_BUTTON (proxy->priv->button),
+ gtk_image_new_from_icon_name (
+ icon_name, GTK_ICON_SIZE_MENU));
+ gtk_widget_hide (proxy->priv->spinner);
+ if (clickable) {
+ gtk_widget_show (proxy->priv->button);
+ gtk_widget_hide (proxy->priv->image);
+ } else {
+ gtk_widget_hide (proxy->priv->button);
+ gtk_widget_show (proxy->priv->image);
+ }
+ } else {
+ gtk_widget_show (proxy->priv->spinner);
+ gtk_widget_hide (proxy->priv->button);
+ gtk_widget_hide (proxy->priv->image);
+ }
+
+ if (allow_cancel)
+ gtk_widget_show (proxy->priv->cancel);
+ else
+ gtk_widget_hide (proxy->priv->cancel);
+
+ sensitive = !(cancelled || completed);
+ gtk_widget_set_sensitive (proxy->priv->cancel, sensitive);
+}
+
+static void
+activity_proxy_set_activity (EActivityProxy *proxy,
+ EActivity *activity)
+{
+ g_return_if_fail (proxy->priv->activity == NULL);
+
+ proxy->priv->activity = g_object_ref (activity);
+}
+
+static void
+activity_proxy_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVITY:
+ activity_proxy_set_activity (
+ E_ACTIVITY_PROXY (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+activity_proxy_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVITY:
+ g_value_set_object (
+ value, e_activity_proxy_get_activity (
+ E_ACTIVITY_PROXY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+activity_proxy_dispose (GObject *object)
+{
+ EActivityProxyPrivate *priv;
+
+ priv = E_ACTIVITY_PROXY_GET_PRIVATE (object);
+
+ if (priv->activity != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->activity, G_SIGNAL_MATCH_FUNC, 0, 0,
+ NULL, activity_proxy_update, NULL);
+ g_object_unref (priv->activity);
+ priv->activity = NULL;
+ }
+
+ if (priv->button != NULL) {
+ g_object_unref (priv->button);
+ priv->button = NULL;
+ }
+
+ if (priv->image != NULL) {
+ g_object_unref (priv->image);
+ priv->image = NULL;
+ }
+
+ if (priv->label != NULL) {
+ g_object_unref (priv->label);
+ priv->label = NULL;
+ }
+
+ if (priv->cancel != NULL) {
+ g_object_unref (priv->cancel);
+ priv->cancel = NULL;
+ }
+
+ if (priv->spinner != NULL) {
+ g_object_unref (priv->spinner);
+ priv->spinner = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+activity_proxy_constructed (GObject *object)
+{
+ EActivityProxy *proxy;
+
+ proxy = E_ACTIVITY_PROXY (object);
+
+ g_signal_connect_swapped (
+ proxy->priv->button, "clicked",
+ G_CALLBACK (e_activity_clicked), proxy->priv->activity);
+
+ g_signal_connect_swapped (
+ proxy->priv->cancel, "clicked",
+ G_CALLBACK (e_activity_cancel), proxy->priv->activity);
+
+ g_signal_connect_swapped (
+ proxy->priv->activity, "cancelled",
+ G_CALLBACK (activity_proxy_update), proxy);
+
+ g_signal_connect_swapped (
+ proxy->priv->activity, "completed",
+ G_CALLBACK (activity_proxy_update), proxy);
+
+ g_signal_connect_swapped (
+ proxy->priv->activity, "notify",
+ G_CALLBACK (activity_proxy_update), proxy);
+
+ activity_proxy_update (proxy);
+}
+
+static void
+activity_proxy_class_init (EActivityProxyClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EActivityProxyPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = activity_proxy_set_property;
+ object_class->get_property = activity_proxy_get_property;
+ object_class->dispose = activity_proxy_dispose;
+ object_class->constructed = activity_proxy_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTIVITY,
+ g_param_spec_object (
+ "activity",
+ NULL,
+ NULL,
+ E_TYPE_ACTIVITY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+activity_proxy_init (EActivityProxy *proxy)
+{
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ proxy->priv = E_ACTIVITY_PROXY_GET_PRIVATE (proxy);
+
+ container = GTK_WIDGET (proxy);
+
+ widget = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_hbox_new (FALSE, 3);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ proxy->priv->image = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ widget = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ proxy->priv->button = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ /* XXX What's the rationale for killing the old spinner API? */
+ widget = e_spinner_new_spinning_small_shown ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ proxy->priv->spinner = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ proxy->priv->label = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_button_new ();
+ gtk_button_set_image (
+ GTK_BUTTON (widget), gtk_image_new_from_stock (
+ GTK_STOCK_STOP, GTK_ICON_SIZE_MENU));
+ gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_set_tooltip_text (widget, _("Cancel"));
+ proxy->priv->cancel = g_object_ref (widget);
+ gtk_widget_show (widget);
+}
+
+GType
+e_activity_proxy_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EActivityProxyClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) activity_proxy_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EActivityProxy),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) activity_proxy_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_EVENT_BOX, "EActivityProxy", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_activity_proxy_new (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL);
+
+ return g_object_new (
+ E_TYPE_ACTIVITY_PROXY,
+ "activity", activity, NULL);
+}
+
+EActivity *
+e_activity_proxy_get_activity (EActivityProxy *proxy)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY_PROXY (proxy), NULL);
+
+ return proxy->priv->activity;
+}
diff --git a/widgets/misc/e-activity-proxy.h b/widgets/misc/e-activity-proxy.h
new file mode 100644
index 0000000000..714dc63e0f
--- /dev/null
+++ b/widgets/misc/e-activity-proxy.h
@@ -0,0 +1,68 @@
+/*
+ * e-activity-proxy.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_ACTIVITY_PROXY_H
+#define E_ACTIVITY_PROXY_H
+
+#include <gtk/gtk.h>
+#include <e-activity.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ACTIVITY_PROXY \
+ (e_activity_proxy_get_type ())
+#define E_ACTIVITY_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxy))
+#define E_ACTIVITY_PROXY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ACTIVITY_PROXY, EActivityProxyClass))
+#define E_IS_ACTIVITY_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ACTIVITY_PROXY))
+#define E_IS_ACTIVITY_PROXY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ACTIVITY_PROXY))
+#define E_ACTIVITY_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ACTIVITY_PROXY, EActivityProxyClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EActivityProxy EActivityProxy;
+typedef struct _EActivityProxyClass EActivityProxyClass;
+typedef struct _EActivityProxyPrivate EActivityProxyPrivate;
+
+struct _EActivityProxy {
+ GtkEventBox parent;
+ EActivityProxyPrivate *priv;
+};
+
+struct _EActivityProxyClass {
+ GtkEventBoxClass parent_class;
+};
+
+GType e_activity_proxy_get_type (void);
+GtkWidget * e_activity_proxy_new (EActivity *activity);
+EActivity * e_activity_proxy_get_activity (EActivityProxy *proxy);
+
+G_END_DECLS
+
+#endif /* E_ACTIVITY_PROXY_H */
diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c
new file mode 100644
index 0000000000..9f8faf75cb
--- /dev/null
+++ b/widgets/misc/e-activity.c
@@ -0,0 +1,605 @@
+/*
+ * e-activity.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-activity.h"
+
+#include <stdarg.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+
+#define E_ACTIVITY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ACTIVITY, EActivityPrivate))
+
+struct _EActivityPrivate {
+ gchar *icon_name;
+ gchar *primary_text;
+ gchar *secondary_text;
+ gdouble percent;
+
+ guint allow_cancel : 1;
+ guint cancelled : 1;
+ guint clickable : 1;
+ guint completed : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_ALLOW_CANCEL,
+ PROP_CLICKABLE,
+ PROP_ICON_NAME,
+ PROP_PERCENT,
+ PROP_PRIMARY_TEXT,
+ PROP_SECONDARY_TEXT
+};
+
+enum {
+ CANCELLED,
+ CLICKED,
+ COMPLETED,
+ DESCRIBE,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static gulong signals[LAST_SIGNAL];
+
+static gboolean
+activity_describe_accumulator (GSignalInvocationHint *ihint,
+ GValue *return_accu,
+ const GValue *handler_return,
+ gpointer accu_data)
+{
+ const gchar *string;
+
+ string = g_value_get_string (handler_return);
+ g_value_set_string (return_accu, string);
+
+ return (string == NULL);
+}
+
+static void
+activity_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ALLOW_CANCEL:
+ e_activity_set_allow_cancel (
+ E_ACTIVITY (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_CLICKABLE:
+ e_activity_set_clickable (
+ E_ACTIVITY (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_ICON_NAME:
+ e_activity_set_icon_name (
+ E_ACTIVITY (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_PERCENT:
+ e_activity_set_percent (
+ E_ACTIVITY (object),
+ g_value_get_double (value));
+ return;
+
+ case PROP_PRIMARY_TEXT:
+ e_activity_set_primary_text (
+ E_ACTIVITY (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_SECONDARY_TEXT:
+ e_activity_set_secondary_text (
+ E_ACTIVITY (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+activity_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ALLOW_CANCEL:
+ g_value_set_boolean (
+ value, e_activity_get_allow_cancel (
+ E_ACTIVITY (object)));
+ return;
+
+ case PROP_CLICKABLE:
+ g_value_set_boolean (
+ value, e_activity_get_clickable (
+ E_ACTIVITY (object)));
+ return;
+
+ case PROP_ICON_NAME:
+ g_value_set_string (
+ value, e_activity_get_icon_name (
+ E_ACTIVITY (object)));
+ return;
+
+ case PROP_PERCENT:
+ g_value_set_double (
+ value, e_activity_get_percent (
+ E_ACTIVITY (object)));
+ return;
+
+ case PROP_PRIMARY_TEXT:
+ g_value_set_string (
+ value, e_activity_get_primary_text (
+ E_ACTIVITY (object)));
+ return;
+
+ case PROP_SECONDARY_TEXT:
+ g_value_set_string (
+ value, e_activity_get_secondary_text (
+ E_ACTIVITY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+activity_finalize (GObject *object)
+{
+ EActivityPrivate *priv;
+
+ priv = E_ACTIVITY_GET_PRIVATE (object);
+
+ g_free (priv->icon_name);
+ g_free (priv->primary_text);
+ g_free (priv->secondary_text);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+activity_cancelled (EActivity *activity)
+{
+ activity->priv->cancelled = TRUE;
+}
+
+static void
+activity_completed (EActivity *activity)
+{
+ activity->priv->completed = TRUE;
+}
+
+static void
+activity_clicked (EActivity *activity)
+{
+ /* Allow subclasses to safely chain up. */
+}
+
+static gchar *
+activity_describe (EActivity *activity)
+{
+ GString *string;
+ const gchar *text;
+ gboolean cancelled;
+ gboolean completed;
+ gdouble percent;
+
+ string = g_string_sized_new (256);
+ text = e_activity_get_primary_text (activity);
+ cancelled = e_activity_is_cancelled (activity);
+ completed = e_activity_is_completed (activity);
+ percent = e_activity_get_percent (activity);
+
+ if (cancelled) {
+ /* Translators: This is a cancelled activity. */
+ g_string_printf (string, _("%s (cancelled)"), text);
+ } else if (completed) {
+ /* Translators: This is a completed activity. */
+ g_string_printf (string, _("%s (completed)"), text);
+ } else if (percent < 0.0) {
+ /* Translators: This is an activity whose percent
+ * complete is unknown. */
+ g_string_printf (string, _("%s..."), text);
+ } else {
+ /* Translators: This is an activity whose percent
+ * complete is known. */
+ g_string_printf (
+ string, _("%s (%d%% complete)"), text,
+ (gint) (percent * 100.0 + 0.5));
+ }
+
+ return g_string_free (string, FALSE);
+}
+
+static void
+activity_class_init (EActivityClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EActivityPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = activity_set_property;
+ object_class->get_property = activity_get_property;
+ object_class->finalize = activity_finalize;
+
+ class->cancelled = activity_cancelled;
+ class->completed = activity_completed;
+ class->clicked = activity_clicked;
+ class->describe = activity_describe;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ALLOW_CANCEL,
+ g_param_spec_boolean (
+ "allow-cancel",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLICKABLE,
+ g_param_spec_boolean (
+ "clickable",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ICON_NAME,
+ g_param_spec_string (
+ "icon-name",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PERCENT,
+ g_param_spec_double (
+ "percent",
+ NULL,
+ NULL,
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ -1.0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PRIMARY_TEXT,
+ g_param_spec_string (
+ "primary-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SECONDARY_TEXT,
+ g_param_spec_string (
+ "secondary-text",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[CANCELLED] = g_signal_new (
+ "cancelled",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EActivityClass, cancelled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CLICKED] = g_signal_new (
+ "clicked",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EActivityClass, clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[COMPLETED] = g_signal_new (
+ "completed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EActivityClass, completed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DESCRIBE] = g_signal_new (
+ "describe",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EActivityClass, describe),
+ activity_describe_accumulator, NULL,
+ e_marshal_STRING__VOID,
+ G_TYPE_STRING, 0);
+}
+
+static void
+activity_init (EActivity *activity)
+{
+ activity->priv = E_ACTIVITY_GET_PRIVATE (activity);
+}
+
+GType
+e_activity_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EActivityClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) activity_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EActivity),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) activity_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EActivity", &type_info, 0);
+ }
+
+ return type;
+}
+
+EActivity *
+e_activity_new (const gchar *primary_text)
+{
+ return g_object_new (
+ E_TYPE_ACTIVITY,
+ "primary-text", primary_text, NULL);
+}
+
+EActivity *
+e_activity_newv (const gchar *format, ...)
+{
+ EActivity *activity;
+ gchar *primary_text;
+ va_list args;
+
+ va_start (args, format);
+ primary_text = g_strdup_vprintf (format, args);
+ activity = e_activity_new (primary_text);
+ g_free (primary_text);
+ va_end (args);
+
+ return activity;
+}
+
+void
+e_activity_cancel (EActivity *activity)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ if (!activity->priv->allow_cancel)
+ return;
+
+ if (activity->priv->cancelled)
+ return;
+
+ if (activity->priv->completed)
+ return;
+
+ g_signal_emit (activity, signals[CANCELLED], 0);
+}
+
+void
+e_activity_complete (EActivity *activity)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ if (activity->priv->cancelled)
+ return;
+
+ if (activity->priv->completed)
+ return;
+
+ g_signal_emit (activity, signals[COMPLETED], 0);
+}
+
+void
+e_activity_clicked (EActivity *activity)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ g_signal_emit (activity, signals[CLICKED], 0);
+}
+
+gchar *
+e_activity_describe (EActivity *activity)
+{
+ EActivityClass *class;
+
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL);
+
+ class = E_ACTIVITY_GET_CLASS (activity);
+ g_return_val_if_fail (class->describe != NULL, NULL);
+
+ return class->describe (activity);
+}
+
+gboolean
+e_activity_is_cancelled (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE);
+
+ return activity->priv->cancelled;
+}
+
+gboolean
+e_activity_is_completed (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE);
+
+ return activity->priv->completed;
+}
+
+gboolean
+e_activity_get_allow_cancel (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE);
+
+ return activity->priv->allow_cancel;
+}
+
+void
+e_activity_set_allow_cancel (EActivity *activity,
+ gboolean allow_cancel)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ activity->priv->allow_cancel = allow_cancel;
+
+ g_object_notify (G_OBJECT (activity), "allow-cancel");
+}
+
+gboolean
+e_activity_get_clickable (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE);
+
+ return activity->priv->clickable;
+}
+
+void
+e_activity_set_clickable (EActivity *activity,
+ gboolean clickable)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ activity->priv->clickable = clickable;
+
+ g_object_notify (G_OBJECT (activity), "clickable");
+}
+
+const gchar *
+e_activity_get_icon_name (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL);
+
+ return activity->priv->icon_name;
+}
+
+void
+e_activity_set_icon_name (EActivity *activity,
+ const gchar *icon_name)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ g_free (activity->priv->icon_name);
+ activity->priv->icon_name = g_strdup (icon_name);
+
+ g_object_notify (G_OBJECT (activity), "icon-name");
+}
+
+gdouble
+e_activity_get_percent (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), -1.0);
+
+ return activity->priv->percent;
+}
+
+void
+e_activity_set_percent (EActivity *activity,
+ gdouble percent)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ activity->priv->percent = percent;
+
+ g_object_notify (G_OBJECT (activity), "percent");
+}
+
+const gchar *
+e_activity_get_primary_text (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL);
+
+ return activity->priv->primary_text;
+}
+
+void
+e_activity_set_primary_text (EActivity *activity,
+ const gchar *primary_text)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ g_free (activity->priv->primary_text);
+ activity->priv->primary_text = g_strdup (primary_text);
+
+ g_object_notify (G_OBJECT (activity), "primary-text");
+}
+
+const gchar *
+e_activity_get_secondary_text (EActivity *activity)
+{
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL);
+
+ return activity->priv->secondary_text;
+}
+
+void
+e_activity_set_secondary_text (EActivity *activity,
+ const gchar *secondary_text)
+{
+ g_return_if_fail (E_IS_ACTIVITY (activity));
+
+ g_free (activity->priv->secondary_text);
+ activity->priv->secondary_text = g_strdup (secondary_text);
+
+ g_object_notify (G_OBJECT (activity), "secondary-text");
+}
diff --git a/widgets/misc/e-activity.h b/widgets/misc/e-activity.h
new file mode 100644
index 0000000000..b396e3a630
--- /dev/null
+++ b/widgets/misc/e-activity.h
@@ -0,0 +1,98 @@
+/*
+ * e-activity.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_ACTIVITY_H
+#define E_ACTIVITY_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ACTIVITY \
+ (e_activity_get_type ())
+#define E_ACTIVITY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ACTIVITY, EActivity))
+#define E_ACTIVITY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ACTIVITY, EActivityClass))
+#define E_IS_ACTIVITY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ACTIVITY))
+#define E_IS_ACTIVITY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ACTIVITY))
+#define E_ACTIVITY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ACTIVITY, EActivityClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EActivity EActivity;
+typedef struct _EActivityClass EActivityClass;
+typedef struct _EActivityPrivate EActivityPrivate;
+
+struct _EActivity {
+ GObject parent;
+ EActivityPrivate *priv;
+};
+
+struct _EActivityClass {
+ GObjectClass parent_class;
+
+ /* Signals */
+ void (*cancelled) (EActivity *activity);
+ void (*completed) (EActivity *activity);
+ void (*clicked) (EActivity *activity);
+ gchar * (*describe) (EActivity *activity);
+};
+
+GType e_activity_get_type (void);
+EActivity * e_activity_new (const gchar *primary_text);
+EActivity * e_activity_newv (const gchar *format,
+ ...) G_GNUC_PRINTF (1, 2);
+void e_activity_cancel (EActivity *activity);
+void e_activity_complete (EActivity *activity);
+void e_activity_clicked (EActivity *activity);
+gchar * e_activity_describe (EActivity *activity);
+gboolean e_activity_is_cancelled (EActivity *activity);
+gboolean e_activity_is_completed (EActivity *activity);
+gboolean e_activity_get_allow_cancel (EActivity *activity);
+void e_activity_set_allow_cancel (EActivity *activity,
+ gboolean allow_cancel);
+gboolean e_activity_get_clickable (EActivity *activity);
+void e_activity_set_clickable (EActivity *activity,
+ gboolean clickable);
+const gchar * e_activity_get_icon_name (EActivity *activity);
+void e_activity_set_icon_name (EActivity *activity,
+ const gchar *icon_name);
+gdouble e_activity_get_percent (EActivity *activity);
+void e_activity_set_percent (EActivity *activity,
+ gdouble percent);
+const gchar * e_activity_get_primary_text (EActivity *activity);
+void e_activity_set_primary_text (EActivity *activity,
+ const gchar *primary_text);
+const gchar * e_activity_get_secondary_text (EActivity *activity);
+void e_activity_set_secondary_text (EActivity *activity,
+ const gchar *secondary_text);
+
+G_END_DECLS
+
+#endif /* E_ACTIVITY_H */
diff --git a/widgets/misc/e-alert-activity.c b/widgets/misc/e-alert-activity.c
new file mode 100644
index 0000000000..1e8f915213
--- /dev/null
+++ b/widgets/misc/e-alert-activity.c
@@ -0,0 +1,258 @@
+/*
+ * e-alert-activity.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-alert-activity.h"
+
+#define E_ALERT_ACTIVITY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ALERT_ACTIVITY, EAlertActivityPrivate))
+
+struct _EAlertActivityPrivate {
+ GtkWidget *message_dialog;
+};
+
+enum {
+ PROP_0,
+ PROP_MESSAGE_DIALOG
+};
+
+static gpointer parent_class;
+
+static void
+alert_activity_set_message_dialog (EAlertActivity *alert_activity,
+ GtkWidget *message_dialog)
+{
+ g_return_if_fail (alert_activity->priv->message_dialog == NULL);
+
+ alert_activity->priv->message_dialog = g_object_ref (message_dialog);
+}
+
+static void
+alert_activity_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MESSAGE_DIALOG:
+ alert_activity_set_message_dialog (
+ E_ALERT_ACTIVITY (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+alert_activity_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MESSAGE_DIALOG:
+ g_value_set_object (
+ value, e_alert_activity_get_message_dialog (
+ E_ALERT_ACTIVITY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+alert_activity_dispose (GObject *object)
+{
+ EAlertActivityPrivate *priv;
+
+ priv = E_ALERT_ACTIVITY_GET_PRIVATE (object);
+
+ if (priv->message_dialog != NULL) {
+ g_object_unref (priv->message_dialog);
+ priv->message_dialog = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+alert_activity_constructed (GObject *object)
+{
+ EActivity *activity;
+ EAlertActivity *alert_activity;
+ GtkWidget *message_dialog;
+ const gchar *primary_text;
+ const gchar *secondary_text;
+
+ alert_activity = E_ALERT_ACTIVITY (object);
+ message_dialog = e_alert_activity_get_message_dialog (alert_activity);
+
+ object = G_OBJECT (message_dialog);
+ primary_text = g_object_get_data (object, "primary");
+ secondary_text = g_object_get_data (object, "secondary");
+
+ activity = E_ACTIVITY (alert_activity);
+ e_activity_set_primary_text (activity, primary_text);
+ e_activity_set_secondary_text (activity, secondary_text);
+
+ /* This is a constructor property, so can't do it in init().
+ * XXX What we really want to do is override the property's
+ * default value, but GObject does not support that. */
+ e_activity_set_clickable (E_ACTIVITY (alert_activity), TRUE);
+}
+
+static void
+alert_activity_clicked (EActivity *activity)
+{
+ EAlertActivity *alert_activity;
+ GtkWidget *message_dialog;
+
+ e_activity_complete (activity);
+
+ alert_activity = E_ALERT_ACTIVITY (activity);
+ message_dialog = e_alert_activity_get_message_dialog (alert_activity);
+ gtk_dialog_run (GTK_DIALOG (message_dialog));
+ gtk_widget_hide (message_dialog);
+
+ /* Chain up to parent's clicked() method. */
+ E_ACTIVITY_CLASS (parent_class)->clicked (activity);
+}
+
+static void
+alert_activity_timeout (ETimeoutActivity *activity)
+{
+ e_activity_complete (E_ACTIVITY (activity));
+
+ /* Chain up to parent's timeout() method. */
+ E_TIMEOUT_ACTIVITY_CLASS (parent_class)->timeout (activity);
+}
+
+static void
+alert_activity_class_init (EAlertActivityClass *class)
+{
+ GObjectClass *object_class;
+ EActivityClass *activity_class;
+ ETimeoutActivityClass *timeout_activity_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EAlertActivityPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = alert_activity_set_property;
+ object_class->get_property = alert_activity_get_property;
+ object_class->dispose = alert_activity_dispose;
+ object_class->constructed = alert_activity_constructed;
+
+ activity_class = E_ACTIVITY_CLASS (class);
+ activity_class->clicked = alert_activity_clicked;
+
+ timeout_activity_class = E_TIMEOUT_ACTIVITY_CLASS (class);
+ timeout_activity_class->timeout = alert_activity_timeout;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MESSAGE_DIALOG,
+ g_param_spec_object (
+ "message-dialog",
+ NULL,
+ NULL,
+ GTK_TYPE_DIALOG,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+alert_activity_init (EAlertActivity *alert_activity)
+{
+ alert_activity->priv = E_ALERT_ACTIVITY_GET_PRIVATE (alert_activity);
+
+ e_timeout_activity_set_timeout (E_TIMEOUT_ACTIVITY (alert_activity), 60);
+}
+
+GType
+e_alert_activity_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EAlertActivityClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) alert_activity_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EAlertActivity),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) alert_activity_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_TIMEOUT_ACTIVITY, "EAlertActivity",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+EActivity *
+e_alert_activity_new_info (GtkWidget *message_dialog)
+{
+ g_return_val_if_fail (GTK_IS_DIALOG (message_dialog), NULL);
+
+ return g_object_new (
+ E_TYPE_ALERT_ACTIVITY,
+ "icon-name", "dialog-information",
+ "message-dialog", message_dialog, NULL);
+}
+
+EActivity *
+e_alert_activity_new_error (GtkWidget *message_dialog)
+{
+ g_return_val_if_fail (GTK_IS_DIALOG (message_dialog), NULL);
+
+ return g_object_new (
+ E_TYPE_ALERT_ACTIVITY,
+ "icon-name", "dialog-error",
+ "message-dialog", message_dialog, NULL);
+}
+
+EActivity *
+e_alert_activity_new_warning (GtkWidget *message_dialog)
+{
+ g_return_val_if_fail (GTK_IS_DIALOG (message_dialog), NULL);
+
+ return g_object_new (
+ E_TYPE_ALERT_ACTIVITY,
+ "icon-name", "dialog-warning",
+ "message-dialog", message_dialog, NULL);
+}
+
+GtkWidget *
+e_alert_activity_get_message_dialog (EAlertActivity *alert_activity)
+{
+ g_return_val_if_fail (E_IS_ALERT_ACTIVITY (alert_activity), NULL);
+
+ return alert_activity->priv->message_dialog;
+}
diff --git a/widgets/misc/e-alert-activity.h b/widgets/misc/e-alert-activity.h
new file mode 100644
index 0000000000..5557094dda
--- /dev/null
+++ b/widgets/misc/e-alert-activity.h
@@ -0,0 +1,70 @@
+/*
+ * e-alert-activity.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_ALERT_ACTIVITY_H
+#define E_ALERT_ACTIVITY_H
+
+#include <e-timeout-activity.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ALERT_ACTIVITY \
+ (e_alert_activity_get_type ())
+#define E_ALERT_ACTIVITY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ALERT_ACTIVITY, EAlertActivity))
+#define E_ALERT_ACTIVITY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ALERT_ACTIVITY, EAlertActivityClass))
+#define E_IS_ALERT_ACTIVITY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ALERT_ACTIVITY))
+#define E_IS_ALERT_ACTIVITY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ALERT_ACTIVITY))
+#define E_ALERT_ACTIVITY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ALERT_ACTIVITY, EAlertActivityClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EAlertActivity EAlertActivity;
+typedef struct _EAlertActivityClass EAlertActivityClass;
+typedef struct _EAlertActivityPrivate EAlertActivityPrivate;
+
+struct _EAlertActivity {
+ ETimeoutActivity parent;
+ EAlertActivityPrivate *priv;
+};
+
+struct _EAlertActivityClass {
+ ETimeoutActivityClass parent_class;
+};
+
+GType e_alert_activity_get_type (void);
+EActivity * e_alert_activity_new_info (GtkWidget *message_dialog);
+EActivity * e_alert_activity_new_error (GtkWidget *message_dialog);
+EActivity * e_alert_activity_new_warning (GtkWidget *message_dialog);
+GtkWidget * e_alert_activity_get_message_dialog
+ (EAlertActivity *alert_activity);
+
+G_END_DECLS
+
+#endif /* E_ALERT_ACTIVITY_H */
diff --git a/widgets/misc/e-attachment-button.c b/widgets/misc/e-attachment-button.c
index d64dcafb4a..1cd517d3e2 100644
--- a/widgets/misc/e-attachment-button.c
+++ b/widgets/misc/e-attachment-button.c
@@ -199,7 +199,7 @@ exit:
static void
attachment_button_update_pixbufs (EAttachmentButton *button)
{
- GtkCellView *cell_view;
+ GtkCellLayout *cell_layout;
GtkCellRenderer *renderer;
GtkIconTheme *icon_theme;
GdkPixbuf *pixbuf_expander_open;
@@ -209,8 +209,8 @@ attachment_button_update_pixbufs (EAttachmentButton *button)
icon_theme = gtk_icon_theme_get_default ();
/* Grab the first cell renderer. */
- cell_view = GTK_CELL_VIEW (button->priv->cell_view);
- list = gtk_cell_view_get_cell_renderers (cell_view);
+ cell_layout = GTK_CELL_LAYOUT (button->priv->cell_view);
+ list = gtk_cell_layout_get_cells (cell_layout);
renderer = GTK_CELL_RENDERER (list->data);
g_list_free (list);
diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c
index fd17c67aab..e9aacfa8b9 100644
--- a/widgets/misc/e-calendar.c
+++ b/widgets/misc/e-calendar.c
@@ -241,12 +241,16 @@ e_calendar_destroy (GtkObject *object)
static void
e_calendar_realize (GtkWidget *widget)
{
+ GtkStyle *style;
+ GdkWindow *window;
+
(*GTK_WIDGET_CLASS (e_calendar_parent_class)->realize) (widget);
/* Set the background of the canvas window to the normal color,
or the arrow buttons are not displayed properly. */
- gdk_window_set_background (GTK_LAYOUT (widget)->bin_window,
- &widget->style->bg[GTK_STATE_NORMAL]);
+ style = gtk_widget_get_style (widget);
+ window = gtk_layout_get_bin_window (GTK_LAYOUT (widget));
+ gdk_window_set_background (window, &style->bg[GTK_STATE_NORMAL]);
}
static void
@@ -254,6 +258,7 @@ e_calendar_style_set (GtkWidget *widget,
GtkStyle *previous_style)
{
ECalendar *e_calendar;
+ GtkWidget *parent;
e_calendar = E_CALENDAR(widget);
if (GTK_WIDGET_CLASS (e_calendar_parent_class)->style_set)
@@ -262,9 +267,15 @@ e_calendar_style_set (GtkWidget *widget,
/* Set the background of the canvas window to the normal color,
or the arrow buttons are not displayed properly. */
- if (GTK_WIDGET_REALIZED (widget->parent))
- gdk_window_set_background (GTK_LAYOUT (widget)->bin_window,
- &widget->style->bg[GTK_STATE_NORMAL]);
+ parent = gtk_widget_get_parent (widget);
+ if (GTK_WIDGET_REALIZED (parent)) {
+ GtkStyle *style;
+ GdkWindow *window;
+
+ style = gtk_widget_get_style (widget);
+ window = gtk_layout_get_bin_window (GTK_LAYOUT (widget));
+ gdk_window_set_background (window, &style->bg[GTK_STATE_NORMAL]);
+ }
e_calendar_item_style_set (widget, e_calendar->calitem);
}
@@ -277,7 +288,7 @@ e_calendar_size_request (GtkWidget *widget,
gint col_width, row_height, width, height;
cal = E_CALENDAR (widget);
- style = GTK_WIDGET (cal)->style;
+ style = gtk_widget_get_style (GTK_WIDGET (cal));
g_object_get((cal->calitem),
"row_height", &row_height,
@@ -296,6 +307,7 @@ e_calendar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
ECalendar *cal;
+ GtkStyle *style;
PangoFontDescription *font_desc;
PangoContext *pango_context;
PangoFontMetrics *font_metrics;
@@ -303,8 +315,9 @@ e_calendar_size_allocate (GtkWidget *widget,
gdouble xthickness, ythickness, arrow_button_size;
cal = E_CALENDAR (widget);
- xthickness = widget->style->xthickness;
- ythickness = widget->style->ythickness;
+ style = gtk_widget_get_style (widget);
+ xthickness = style->xthickness;
+ ythickness = style->ythickness;
(*GTK_WIDGET_CLASS (e_calendar_parent_class)->size_allocate) (widget, allocation);
@@ -412,7 +425,7 @@ e_calendar_get_border_size (ECalendar *cal,
g_return_if_fail (E_IS_CALENDAR (cal));
- style = GTK_WIDGET (cal)->style;
+ style = gtk_widget_get_style (GTK_WIDGET (cal));
if (style) {
*top = style->ythickness;
diff --git a/widgets/misc/e-calendar.h b/widgets/misc/e-calendar.h
index 2ee002807a..d6b50209a7 100644
--- a/widgets/misc/e-calendar.h
+++ b/widgets/misc/e-calendar.h
@@ -37,9 +37,24 @@ G_BEGIN_DECLS
* to got to the current day.
*/
-#define E_CALENDAR(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_calendar_get_type (), ECalendar)
-#define E_CALENDAR_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_calendar_get_type (), ECalendarClass)
-#define E_IS_CALENDAR(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_calendar_get_type ())
+/* Standard GObject macros */
+#define E_TYPE_CALENDAR \
+ (e_calendar_get_type ())
+#define E_CALENDAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CALENDAR, ECalendar))
+#define E_CALENDAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CALENDAR, ECalendarClass))
+#define E_IS_CALENDAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CALENDAR))
+#define E_IS_CALENDAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CALENDAR))
+#define E_CALENDAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CALENDAR, ECalendarClass))
typedef struct _ECalendar ECalendar;
typedef struct _ECalendarClass ECalendarClass;
diff --git a/widgets/misc/e-charset-combo-box.c b/widgets/misc/e-charset-combo-box.c
new file mode 100644
index 0000000000..9c992ce1f7
--- /dev/null
+++ b/widgets/misc/e-charset-combo-box.c
@@ -0,0 +1,428 @@
+/*
+ * e-charset-combo-box.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-charset-combo-box.h"
+
+#include <glib/gi18n.h>
+
+#include "e-util/e-charset.h"
+#include "e-util/e-util.h"
+
+#define E_CHARSET_COMBO_BOX_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxPrivate))
+
+#define DEFAULT_CHARSET "UTF-8"
+#define OTHER_VALUE G_MAXINT
+
+struct _ECharsetComboBoxPrivate {
+ GtkActionGroup *action_group;
+ GtkRadioAction *other_action;
+ GHashTable *charset_index;
+
+ /* Used when the user clicks Cancel in the character set
+ * dialog. Reverts to the previous combo box setting. */
+ gint previous_index;
+
+ /* When setting the character set programmatically, this
+ * prevents the custom character set dialog from running. */
+ guint block_dialog : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_CHARSET
+};
+
+static gpointer parent_class;
+
+static void
+charset_combo_box_entry_changed_cb (GtkEntry *entry,
+ GtkDialog *dialog)
+{
+ const gchar *text;
+ gboolean sensitive;
+
+ text = gtk_entry_get_text (entry);
+ sensitive = (text != NULL && *text != '\0');
+ gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, sensitive);
+}
+
+static void
+charset_combo_box_run_dialog (ECharsetComboBox *combo_box)
+{
+ GtkDialog *dialog;
+ GtkEntry *entry;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GObject *object;
+ gpointer parent;
+ const gchar *charset;
+
+ /* FIXME Using a dialog for this is lame. Selecting "Other..."
+ * should unlock an entry directly in the Preferences tab.
+ * Unfortunately space in Preferences is at a premium right
+ * now, but we should revisit this when the space issue is
+ * finally resolved. */
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (combo_box));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ object = G_OBJECT (combo_box->priv->other_action);
+ charset = g_object_get_data (object, "charset");
+
+ widget = gtk_dialog_new_with_buttons (
+ _("Character Encoding"), parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+ /* Load the broken border width defaults so we can override them. */
+ gtk_widget_ensure_style (widget);
+
+ dialog = GTK_DIALOG (widget);
+
+ gtk_dialog_set_has_separator (dialog, FALSE);
+ gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
+
+ widget = gtk_dialog_get_action_area (dialog);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 0);
+
+ widget = gtk_dialog_get_content_area (dialog);
+ gtk_box_set_spacing (GTK_BOX (widget), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 0);
+
+ container = widget;
+
+ widget = gtk_label_new (_("Enter the character set to use"));
+ gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 12, 0);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_entry_new ();
+ entry = GTK_ENTRY (widget);
+ gtk_entry_set_activates_default (entry, TRUE);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect (
+ entry, "changed",
+ G_CALLBACK (charset_combo_box_entry_changed_cb), dialog);
+
+ /* Set the default text -after- connecting the signal handler.
+ * This will initialize the "OK" button to the proper state. */
+ gtk_entry_set_text (entry, charset);
+
+ if (gtk_dialog_run (dialog) != GTK_RESPONSE_OK) {
+ gint active;
+
+ /* Revert to the previously selected character set. */
+ combo_box->priv->block_dialog = TRUE;
+ active = combo_box->priv->previous_index;
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), active);
+ combo_box->priv->block_dialog = FALSE;
+
+ goto exit;
+ }
+
+ charset = gtk_entry_get_text (entry);
+ g_return_if_fail (charset != NULL && charset != '\0');
+
+ g_object_set_data_full (
+ object, "charset", g_strdup (charset),
+ (GDestroyNotify) g_free);
+
+exit:
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+charset_combo_box_notify_charset_cb (ECharsetComboBox *combo_box)
+{
+ GtkToggleAction *action;
+
+ action = GTK_TOGGLE_ACTION (combo_box->priv->other_action);
+ if (!gtk_toggle_action_get_active (action))
+ return;
+
+ if (combo_box->priv->block_dialog)
+ return;
+
+ /* "Other" action was selected by user. */
+ charset_combo_box_run_dialog (combo_box);
+}
+
+static void
+charset_combo_box_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CHARSET:
+ e_charset_combo_box_set_charset (
+ E_CHARSET_COMBO_BOX (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+charset_combo_box_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CHARSET:
+ g_value_set_string (
+ value, e_charset_combo_box_get_charset (
+ E_CHARSET_COMBO_BOX (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+charset_combo_box_dispose (GObject *object)
+{
+ ECharsetComboBoxPrivate *priv;
+
+ priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (object);
+
+ if (priv->action_group != NULL) {
+ g_object_unref (priv->action_group);
+ priv->action_group = NULL;
+ }
+
+ if (priv->other_action != NULL) {
+ g_object_unref (priv->other_action);
+ priv->other_action = NULL;
+ }
+
+ g_hash_table_remove_all (priv->charset_index);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+charset_combo_box_finalize (GObject *object)
+{
+ ECharsetComboBoxPrivate *priv;
+
+ priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->charset_index);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+charset_combo_box_changed (GtkComboBox *combo_box)
+{
+ ECharsetComboBoxPrivate *priv;
+
+ priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (combo_box);
+
+ /* Chain up to parent's changed() method. */
+ GTK_COMBO_BOX_CLASS (parent_class)->changed (combo_box);
+
+ /* Notify -before- updating previous index. */
+ g_object_notify (G_OBJECT (combo_box), "charset");
+ priv->previous_index = gtk_combo_box_get_active (combo_box);
+}
+
+static void
+charset_combo_box_class_init (ECharsetComboBoxClass *class)
+{
+ GObjectClass *object_class;
+ GtkComboBoxClass *combo_box_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ECharsetComboBoxPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = charset_combo_box_set_property;
+ object_class->get_property = charset_combo_box_get_property;
+ object_class->dispose = charset_combo_box_dispose;
+ object_class->finalize = charset_combo_box_finalize;
+
+ combo_box_class = GTK_COMBO_BOX_CLASS (class);
+ combo_box_class->changed = charset_combo_box_changed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CHARSET,
+ g_param_spec_string (
+ "charset",
+ "Charset",
+ "The selected character set",
+ "UTF-8",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+}
+
+static void
+charset_combo_box_init (ECharsetComboBox *combo_box)
+{
+ GtkActionGroup *action_group;
+ GtkRadioAction *radio_action;
+ GHashTable *charset_index;
+ GSList *group, *iter;
+
+ action_group = gtk_action_group_new ("charset-combo-box-internal");
+
+ charset_index = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ combo_box->priv = E_CHARSET_COMBO_BOX_GET_PRIVATE (combo_box);
+ combo_box->priv->action_group = action_group;
+ combo_box->priv->charset_index = charset_index;
+
+ group = e_charset_add_radio_actions (
+ action_group, "charset-", NULL, NULL, NULL);
+
+ /* Populate the character set index. */
+ for (iter = group; iter != NULL; iter = iter->next) {
+ GObject *object = iter->data;
+ const gchar *charset;
+
+ charset = g_object_get_data (object, "charset");
+ g_return_if_fail (charset != NULL);
+
+ g_hash_table_insert (
+ charset_index, g_strdup (charset),
+ g_object_ref (object));
+ }
+
+ /* Note the "other" action is not included in the index. */
+
+ radio_action = gtk_radio_action_new (
+ "charset-other", _("Other..."), NULL, NULL, OTHER_VALUE);
+
+ g_object_set_data (G_OBJECT (radio_action), "charset", (gpointer) "");
+
+ gtk_radio_action_set_group (radio_action, group);
+ group = gtk_radio_action_get_group (radio_action);
+
+ e_action_combo_box_set_action (
+ E_ACTION_COMBO_BOX (combo_box), radio_action);
+
+ e_action_combo_box_add_separator_after (
+ E_ACTION_COMBO_BOX (combo_box), g_slist_length (group));
+
+ g_signal_connect (
+ combo_box, "notify::charset",
+ G_CALLBACK (charset_combo_box_notify_charset_cb), NULL);
+
+ combo_box->priv->other_action = radio_action;
+}
+
+GType
+e_charset_combo_box_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ECharsetComboBoxClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) charset_combo_box_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECharsetComboBox),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) charset_combo_box_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_ACTION_COMBO_BOX, "ECharsetComboBox",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_charset_combo_box_new (void)
+{
+ return g_object_new (E_TYPE_CHARSET_COMBO_BOX, NULL);
+}
+
+const gchar *
+e_charset_combo_box_get_charset (ECharsetComboBox *combo_box)
+{
+ GtkRadioAction *radio_action;
+
+ g_return_val_if_fail (E_IS_CHARSET_COMBO_BOX (combo_box), NULL);
+
+ radio_action = combo_box->priv->other_action;
+ radio_action = e_radio_action_get_current_action (radio_action);
+
+ return g_object_get_data (G_OBJECT (radio_action), "charset");
+}
+
+void
+e_charset_combo_box_set_charset (ECharsetComboBox *combo_box,
+ const gchar *charset)
+{
+ GHashTable *charset_index;
+ GtkRadioAction *radio_action;
+
+ g_return_if_fail (E_IS_CHARSET_COMBO_BOX (combo_box));
+
+ if (charset == NULL || *charset == '\0')
+ charset = "UTF-8";
+
+ charset_index = combo_box->priv->charset_index;
+ radio_action = g_hash_table_lookup (charset_index, charset);
+
+ if (radio_action == NULL) {
+ radio_action = combo_box->priv->other_action;
+ g_object_set_data_full (
+ G_OBJECT (radio_action),
+ "charset", g_strdup (charset),
+ (GDestroyNotify) g_free);
+ }
+
+ combo_box->priv->block_dialog = TRUE;
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (radio_action), TRUE);
+ combo_box->priv->block_dialog = FALSE;
+}
diff --git a/widgets/misc/e-charset-combo-box.h b/widgets/misc/e-charset-combo-box.h
new file mode 100644
index 0000000000..471dfa6a54
--- /dev/null
+++ b/widgets/misc/e-charset-combo-box.h
@@ -0,0 +1,69 @@
+/*
+ * e-charset-combo-box.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CHARSET_COMBO_BOX_H
+#define E_CHARSET_COMBO_BOX_H
+
+#include <misc/e-action-combo-box.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CHARSET_COMBO_BOX \
+ (e_charset_combo_box_get_type ())
+#define E_CHARSET_COMBO_BOX(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBox))
+#define E_CHARSET_COMBO_BOX_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxClass))
+#define E_IS_CHARSET_COMBO_BOX(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CHARSET_COMBO_BOX))
+#define E_IS_CHARSET_COMBO_BOX_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CHARSET_COMBO_BOX))
+#define E_CHARSET_COMBO_BOX_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CHARSET_COMBO_BOX, ECharsetComboBoxClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECharsetComboBox ECharsetComboBox;
+typedef struct _ECharsetComboBoxClass ECharsetComboBoxClass;
+typedef struct _ECharsetComboBoxPrivate ECharsetComboBoxPrivate;
+
+struct _ECharsetComboBox {
+ EActionComboBox parent;
+ ECharsetComboBoxPrivate *priv;
+};
+
+struct _ECharsetComboBoxClass {
+ EActionComboBoxClass parent_class;
+};
+
+GType e_charset_combo_box_get_type (void);
+GtkWidget * e_charset_combo_box_new (void);
+const gchar * e_charset_combo_box_get_charset (ECharsetComboBox *combo_box);
+void e_charset_combo_box_set_charset (ECharsetComboBox *combo_box,
+ const gchar *charset);
+
+G_END_DECLS
+
+#endif /* E_CHARSET_COMBO_BOX_H */
diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c
deleted file mode 100644
index 53beaa9c11..0000000000
--- a/widgets/misc/e-charset-picker.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-charset-picker.h"
-#include "e-util/e-dialog-utils.h"
-
-#include <string.h>
-#include <iconv.h>
-
-#include <glib/gi18n-lib.h>
-
-#include <bonobo/bonobo-ui-node.h>
-#include <bonobo/bonobo-ui-util.h>
-
-typedef enum {
- E_CHARSET_UNKNOWN,
- E_CHARSET_ARABIC,
- E_CHARSET_BALTIC,
- E_CHARSET_CENTRAL_EUROPEAN,
- E_CHARSET_CHINESE,
- E_CHARSET_CYRILLIC,
- E_CHARSET_GREEK,
- E_CHARSET_HEBREW,
- E_CHARSET_JAPANESE,
- E_CHARSET_KOREAN,
- E_CHARSET_THAI,
- E_CHARSET_TURKISH,
- E_CHARSET_UNICODE,
- E_CHARSET_WESTERN_EUROPEAN,
- E_CHARSET_WESTERN_EUROPEAN_NEW
-} ECharsetClass;
-
-static const gchar *classnames[] = {
- N_("Unknown"),
- N_("Arabic"),
- N_("Baltic"),
- N_("Central European"),
- N_("Chinese"),
- N_("Cyrillic"),
- N_("Greek"),
- N_("Hebrew"),
- N_("Japanese"),
- N_("Korean"),
- N_("Thai"),
- N_("Turkish"),
- N_("Unicode"),
- N_("Western European"),
- N_("Western European, New"),
-};
-
-typedef struct {
- const gchar *name;
- ECharsetClass class;
- const gchar *subclass;
-} ECharset;
-
-/* This list is based on what other mailers/browsers support. There's
- * not a lot of point in using, say, ISO-8859-3, if anything that can
- * read that can read UTF8 too.
- */
-/* To Translators: Character set "Logical Hebrew" */
-static ECharset charsets[] = {
- { "ISO-8859-6", E_CHARSET_ARABIC, NULL },
- { "ISO-8859-13", E_CHARSET_BALTIC, NULL },
- { "ISO-8859-4", E_CHARSET_BALTIC, NULL },
- { "ISO-8859-2", E_CHARSET_CENTRAL_EUROPEAN, NULL },
- { "Big5", E_CHARSET_CHINESE, N_("Traditional") },
- { "BIG5HKSCS", E_CHARSET_CHINESE, N_("Traditional") },
- { "EUC-TW", E_CHARSET_CHINESE, N_("Traditional") },
- { "GB18030", E_CHARSET_CHINESE, N_("Simplified") },
- { "GB2312", E_CHARSET_CHINESE, N_("Simplified") },
- { "HZ", E_CHARSET_CHINESE, N_("Simplified") },
- { "ISO-2022-CN", E_CHARSET_CHINESE, N_("Simplified") },
- { "KOI8-R", E_CHARSET_CYRILLIC, NULL },
- { "Windows-1251", E_CHARSET_CYRILLIC, NULL },
- { "KOI8-U", E_CHARSET_CYRILLIC, N_("Ukrainian") },
- { "ISO-8859-5", E_CHARSET_CYRILLIC, NULL },
- { "ISO-8859-7", E_CHARSET_GREEK, NULL },
- { "ISO-8859-8", E_CHARSET_HEBREW, N_("Visual") },
- { "ISO-2022-JP", E_CHARSET_JAPANESE, NULL },
- { "EUC-JP", E_CHARSET_JAPANESE, NULL },
- { "Shift_JIS", E_CHARSET_JAPANESE, NULL },
- { "EUC-KR", E_CHARSET_KOREAN, NULL },
- { "TIS-620", E_CHARSET_THAI, NULL },
- { "ISO-8859-9", E_CHARSET_TURKISH, NULL },
- { "UTF-8", E_CHARSET_UNICODE, NULL },
- { "UTF-7", E_CHARSET_UNICODE, NULL },
- { "ISO-8859-1", E_CHARSET_WESTERN_EUROPEAN, NULL },
- { "ISO-8859-15", E_CHARSET_WESTERN_EUROPEAN_NEW, NULL },
-};
-static const gint num_charsets = sizeof (charsets) / sizeof (charsets[0]);
-
-static void
-select_item (GtkMenuShell *menu_shell, GtkWidget *item)
-{
- gtk_menu_shell_select_item (menu_shell, item);
- gtk_menu_shell_deactivate (menu_shell);
-}
-
-static void
-activate (GtkWidget *item, gpointer menu)
-{
- g_object_set_data ((GObject *) menu, "activated_item", item);
-}
-
-static GtkWidget *
-add_charset (GtkWidget *menu, ECharset *charset, gboolean free_name)
-{
- GtkWidget *item;
- gchar *label;
-
- if (charset->subclass) {
- label = g_strdup_printf ("%s, %s (%s)",
- _(classnames[charset->class]),
- _(charset->subclass),
- charset->name);
- } else if (charset->class) {
- label = g_strdup_printf ("%s (%s)",
- _(classnames[charset->class]),
- charset->name);
- } else {
- label = g_strdup (charset->name);
- }
-
- item = gtk_menu_item_new_with_label (label);
- g_object_set_data_full ((GObject *) item, "charset",
- (gpointer) charset->name, free_name ? g_free : NULL);
- g_free (label);
-
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- g_signal_connect (item, "activate", G_CALLBACK (activate), menu);
-
- return item;
-}
-
-static gboolean
-add_other_charset (GtkWidget *menu, GtkWidget *other, const gchar *new_charset)
-{
- ECharset charset = { NULL, E_CHARSET_UNKNOWN, NULL };
- GtkWidget *item;
- iconv_t ic;
-
- ic = iconv_open ("UTF-8", new_charset);
- if (ic == (iconv_t)-1) {
- GtkWidget *window = gtk_widget_get_ancestor (other, GTK_TYPE_WINDOW);
- e_notice (window, GTK_MESSAGE_ERROR,
- _("Unknown character set: %s"), new_charset);
- return FALSE;
- }
- iconv_close (ic);
-
- /* Temporarily remove the "Other..." item */
- g_object_ref (other);
- gtk_container_remove (GTK_CONTAINER (menu), other);
-
- /* Create new menu item */
- charset.name = g_strdup (new_charset);
- item = add_charset (menu, &charset, TRUE);
-
- /* And re-add "Other..." */
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), other);
- g_object_unref (other);
-
- g_object_set_data_full ((GObject *) menu, "other_charset",
- g_strdup (new_charset), g_free);
-
- g_object_set_data ((GObject *) menu, "activated_item", item);
- select_item (GTK_MENU_SHELL (menu), item);
-
- return TRUE;
-}
-
-static void
-activate_entry (GtkWidget *entry, GtkDialog *dialog)
-{
- gtk_dialog_response (dialog, GTK_RESPONSE_OK);
-}
-
-static void
-activate_other (GtkWidget *item, gpointer menu)
-{
- GtkWidget *window, *entry, *label, *vbox, *hbox;
- gchar *old_charset, *new_charset;
- GtkDialog *dialog;
-
- window = gtk_widget_get_toplevel (menu);
- if (!GTK_WIDGET_TOPLEVEL (window))
- window = gtk_widget_get_ancestor (item, GTK_TYPE_WINDOW);
-
- old_charset = g_object_get_data(menu, "other_charset");
-
- dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Character Encoding"),
- GTK_WINDOW (window),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- NULL));
-
- gtk_dialog_set_has_separator (dialog, FALSE);
- gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
-
- vbox = gtk_vbox_new (FALSE, 6);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
- gtk_box_pack_start (GTK_BOX (dialog->vbox), vbox, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- label = gtk_label_new (_("Enter the character set to use"));
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- hbox = gtk_hbox_new (FALSE, 12);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
- gtk_widget_show (hbox);
-
- label = gtk_label_new ("");
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- entry = gtk_entry_new ();
- gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
- gtk_widget_show (entry);
-
- if (old_charset)
- gtk_entry_set_text (GTK_ENTRY (entry), old_charset);
- g_signal_connect (entry, "activate",
- G_CALLBACK (activate_entry), dialog);
-
- gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 0);
- gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 12);
-
- gtk_widget_show_all (GTK_WIDGET (dialog));
-
- g_object_ref (dialog);
- if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK) {
- new_charset = (gchar *)gtk_entry_get_text (GTK_ENTRY (entry));
-
- if (*new_charset) {
- if (add_other_charset (menu, item, new_charset)) {
- gtk_widget_destroy (GTK_WIDGET (dialog));
- g_object_unref (dialog);
- return;
- }
- }
- }
- gtk_widget_destroy (GTK_WIDGET (dialog));
- g_object_unref (dialog);
-
- /* Revert to previous selection */
- select_item (GTK_MENU_SHELL (menu), g_object_get_data(G_OBJECT(menu), "activated_item"));
-}
-
-/**
- * e_charset_picker_new:
- * @default_charset: the default character set, or %NULL to use the
- * locale character set.
- *
- * This creates an option menu widget and fills it in with a selection
- * of available character sets. The @default_charset (or locale character
- * set if @default_charset is %NULL) will be listed first, and selected
- * by default (except that iso-8859-1 will always be used instead of
- * US-ASCII). Any other character sets of the same language class as
- * the default will be listed next, followed by the remaining character
- * sets, a separator, and an "Other..." menu item, which can be used to
- * select other charsets.
- *
- * Return value: an option menu widget, filled in and with signals
- * attached.
- */
-GtkWidget *
-e_charset_picker_new (const gchar *default_charset)
-{
- GtkWidget *menu, *item;
- gint def, i;
- const gchar *locale_charset;
-
- g_get_charset (&locale_charset);
- if (!g_ascii_strcasecmp (locale_charset, "US-ASCII"))
- locale_charset = "iso-8859-1";
-
- if (!default_charset)
- default_charset = locale_charset;
- for (def = 0; def < num_charsets; def++) {
- if (!g_ascii_strcasecmp (charsets[def].name, default_charset))
- break;
- }
-
- menu = gtk_menu_new ();
- for (i = 0; i < num_charsets; i++) {
- item = add_charset (menu, &charsets[i], FALSE);
- if (i == def) {
- activate (item, menu);
- select_item (GTK_MENU_SHELL (menu), item);
- }
- }
-
- /* do the Unknown/Other section */
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_menu_item_new ());
-
- if (def == num_charsets) {
- ECharset other = { NULL, E_CHARSET_UNKNOWN, NULL };
-
- /* Add an entry for @default_charset */
- other.name = g_strdup (default_charset);
- item = add_charset (menu, &other, TRUE);
- activate (item, menu);
- select_item (GTK_MENU_SHELL (menu), item);
- g_object_set_data_full ((GObject *) menu, "other_charset",
- g_strdup (default_charset), g_free);
- def++;
- }
-
- item = gtk_menu_item_new_with_label (_("Other..."));
- g_signal_connect (item, "activate", G_CALLBACK (activate_other), menu);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- gtk_widget_show_all (menu);
-
- return menu;
-}
-
-/**
- * e_charset_picker_get_charset:
- * @menu: a character set menu from e_charset_picker_new()
- *
- * Return value: the currently-selected character set in @picker,
- * which must be freed with g_free().
- **/
-gchar *
-e_charset_picker_get_charset (GtkWidget *menu)
-{
- GtkWidget *item;
- gchar *charset;
-
- g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
-
- item = gtk_menu_get_active (GTK_MENU (menu));
- charset = g_object_get_data ((GObject *) item, "charset");
-
- return g_strdup (charset);
-}
-
-/**
- * e_charset_picker_dialog:
- * @title: title for the dialog box
- * @prompt: prompt string for the dialog box
- * @default_charset: as for e_charset_picker_new()
- * @parent: a parent window for the dialog box, or %NULL
- *
- * This creates a new dialog box with the given @title and @prompt and
- * a character set picker menu. It then runs the dialog and returns
- * the selected character set, or %NULL if the user clicked "Cancel".
- *
- * Return value: the selected character set (which must be freed with
- * g_free()), or %NULL.
- **/
-gchar *
-e_charset_picker_dialog (const gchar *title, const gchar *prompt,
- const gchar *default_charset, GtkWindow *parent)
-{
- GtkDialog *dialog;
- GtkWidget *label, *omenu, *picker, *vbox, *hbox;
- gchar *charset = NULL;
-
- dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (title,
- parent,
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- NULL));
-
- gtk_dialog_set_has_separator (dialog, FALSE);
- gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
-
- vbox = gtk_vbox_new (FALSE, 6);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
- gtk_box_pack_start (GTK_BOX (dialog->vbox), vbox, FALSE, FALSE, 0);
- gtk_widget_show (vbox);
-
- label = gtk_label_new (prompt);
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- hbox = gtk_hbox_new (FALSE, 12);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
- gtk_widget_show (hbox);
-
- label = gtk_label_new ("");
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- picker = e_charset_picker_new (default_charset);
- omenu = gtk_option_menu_new ();
- gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), picker);
- gtk_box_pack_start (GTK_BOX (hbox), omenu, TRUE, TRUE, 0);
- gtk_widget_show (omenu);
-
- gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 0);
- gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 12);
-
- gtk_widget_show_all (GTK_WIDGET (dialog));
-
- g_object_ref (dialog);
-
- if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK)
- charset = e_charset_picker_get_charset (picker);
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
- g_object_unref (dialog);
-
- return charset;
-}
-
-/**
- * e_charset_add_radio_actions:
- * @action_group: a #GtkActionGroup
- * @default_charset: the default character set, or %NULL to use the
- * locale character set
- * @callback: a callback function for actions in the group, or %NULL
- * @user_data: user data to be passed to @callback, or %NULL
- *
- * Adds a set of #GtkRadioActions for available character sets to
- * @action_group. The @default_charset (or locale character set if
- * @default_charset is %NULL) will be added first, and selected by
- * default (except that iso-8859-1 will always be used instead of
- * US-ASCII). Any other character sets of the same language class as
- * the default will be added next, followed by the remaining character
- * sets.
- **/
-void
-e_charset_add_radio_actions (GtkActionGroup *action_group,
- const gchar *default_charset,
- GCallback callback,
- gpointer user_data)
-{
- GtkRadioAction *action = NULL;
- GSList *group = NULL;
- const gchar *locale_charset;
- gint def, ii;
-
- g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
-
- /* XXX I could try to factor out code common to this
- * function and e_charset_picker_bonobo_ui_populate()
- * instead of duplicating it, but I expect the latter
- * function to be obsolete in the foreseeable future. */
-
- g_get_charset (&locale_charset);
- if (!g_ascii_strcasecmp (locale_charset, "US-ASCII"))
- locale_charset = "iso-8859-1";
-
- if (default_charset == NULL)
- default_charset = locale_charset;
- for (def = 0; def < G_N_ELEMENTS (charsets); def++)
- if (!g_ascii_strcasecmp (charsets[def].name, default_charset))
- break;
-
- for (ii = 0; ii < G_N_ELEMENTS (charsets); ii++) {
- gchar *escaped_name;
- gchar *charset_label;
- gchar **str_array;
-
- /* Escape underlines in the character set name so
- * they're not treated as GtkLabel mnemonics. */
- str_array = g_strsplit (charsets[ii].name, "_", -1);
- escaped_name = g_strjoinv ("__", str_array);
- g_strfreev (str_array);
-
- if (charsets[ii].subclass != NULL)
- charset_label = g_strdup_printf (
- "%s, %s (%s)",
- gettext (classnames[charsets[ii].class]),
- gettext (charsets[ii].subclass),
- escaped_name);
- else if (charsets[ii].class != E_CHARSET_UNKNOWN)
- charset_label = g_strdup_printf (
- "%s (%s)",
- gettext (classnames[charsets[ii].class]),
- escaped_name);
- else
- charset_label = g_strdup (escaped_name);
-
- action = gtk_radio_action_new (
- charsets[ii].name, charset_label, NULL, NULL, ii);
-
- gtk_radio_action_set_group (action, group);
- group = gtk_radio_action_get_group (action);
-
- if (callback != NULL)
- g_signal_connect (
- action, "changed", callback, user_data);
-
- gtk_action_group_add_action (
- action_group, GTK_ACTION (action));
-
- g_object_unref (action);
-
- g_free (escaped_name);
- g_free (charset_label);
- }
-
- if (def == G_N_ELEMENTS (charsets)) {
- gchar *charset_label;
- gchar **str_array;
-
- /* Escape underlines in the character set name so
- * they're not treated as GtkLabel mnemonics. */
- str_array = g_strsplit (default_charset, "_", -1);
- charset_label = g_strjoinv ("__", str_array);
- g_strfreev (str_array);
-
- action = gtk_radio_action_new (
- default_charset, charset_label, NULL, NULL, def);
-
- gtk_radio_action_set_group (action, group);
- group = gtk_radio_action_get_group (action);
-
- if (callback != NULL)
- g_signal_connect (
- action, "changed", callback, user_data);
-
- gtk_action_group_add_action (
- action_group, GTK_ACTION (action));
-
- g_object_unref (action);
-
- g_free (charset_label);
- }
-
- /* Any of the actions in the action group will do. */
- if (action != NULL)
- gtk_radio_action_set_current_value (action, def);
-}
-
-/**
- * e_charset_picker_bonobo_ui_populate:
- * @uic: Bonobo UI Component
- * @path: menu path
- * @default_charset: the default character set, or %NULL to use the
- * locale character set.
- * @cb: Callback function
- * @user_data: data to be passed to the callback.
- *
- * This creates a Bonobo UI menu and fills it in with a selection
- * of available character sets. The @default_charset (or locale character
- * set if @default_charset is %NULL) will be listed first, and selected
- * by default (except that iso-8859-1 will always be used instead of
- * US-ASCII). Any other character sets of the same language class as
- * the default will be listed next, followed by the remaining character
- * sets.
- **/
-void
-e_charset_picker_bonobo_ui_populate (BonoboUIComponent *uic, const gchar *path,
- const gchar *default_charset,
- BonoboUIListenerFn cb, gpointer user_data)
-{
- gchar *encoded_label, *label;
- const gchar *locale_charset;
- GString *menuitems;
- gint def, i;
-
- g_get_charset (&locale_charset);
- if (!g_ascii_strcasecmp (locale_charset, "US-ASCII"))
- locale_charset = "iso-8859-1";
-
- if (!default_charset)
- default_charset = locale_charset;
- for (def = 0; def < num_charsets; def++) {
- if (!g_ascii_strcasecmp (charsets[def].name, default_charset))
- break;
- }
-
- label = g_strdup (_("Ch_aracter Encoding"));
- encoded_label = bonobo_ui_util_encode_str (label);
- menuitems = g_string_new ("");
- g_string_append_printf (menuitems, "<submenu name=\"ECharsetPicker\" label=\"%s\">\n",
- encoded_label);
- g_free (encoded_label);
- g_free (label);
-
- for (i = 0; i < num_charsets; i++) {
- gchar *charset_name;
- gchar *command, *u;
-
- /* escape _'s in the charset name so that it doesn't become an underline in a GtkLabel */
- if ((u = strchr (charsets[i].name, '_'))) {
- gint extra = 1;
- const gchar *s;
- gchar *d;
-
- while ((u = strchr (u + 1, '_')))
- extra++;
-
- d = charset_name = g_alloca (strlen (charsets[i].name) + extra + 1);
- s = charsets[i].name;
- while (*s != '\0') {
- if (*s == '_')
- *d++ = '_';
- *d++ = *s++;
- }
- *d = '\0';
- } else {
- charset_name = (gchar *) charsets[i].name;
- }
-
- if (charsets[i].subclass) {
- label = g_strdup_printf ("%s, %s (%s)",
- _(classnames[charsets[i].class]),
- _(charsets[i].subclass),
- charset_name);
- } else if (charsets[i].class) {
- label = g_strdup_printf ("%s (%s)",
- _(classnames[charsets[i].class]),
- charset_name);
- } else {
- label = g_strdup (charset_name);
- }
-
- encoded_label = bonobo_ui_util_encode_str (label);
- g_free (label);
-
- command = g_strdup_printf ("<cmd name=\"Charset-%s\" label=\"%s\" type=\"radio\""
- " group=\"charset_picker\" state=\"%d\"/>\n",
- charsets[i].name, encoded_label, i == def);
-
- bonobo_ui_component_set (uic, "/commands", command, NULL);
- g_free (command);
-
- g_string_append_printf (menuitems, " <menuitem name=\"Charset-%s\" verb=\"\"/>\n",
- charsets[i].name);
-
- g_free (encoded_label);
-
- label = g_strdup_printf ("Charset-%s", charsets[i].name);
- bonobo_ui_component_add_listener (uic, label, cb, user_data);
- g_free (label);
- }
-
- if (def == num_charsets) {
- gchar *command;
- gchar *charset_name, *u;
-
- /* escape _'s in the charset name so that it doesn't become an underline in a GtkLabel */
- if ((u = strchr (default_charset, '_'))) {
- gint extra = 1;
- gchar *s, *d;
-
- while ((u = strchr (u + 1, '_')))
- extra++;
-
- d = charset_name = g_alloca (strlen (default_charset) + extra + 1);
- s = (gchar *) default_charset;
- while (*s != '\0') {
- if (*s == '_')
- *d++ = '_';
- *d++ = *s++;
- }
- *d = '\0';
- } else {
- charset_name = (gchar *) default_charset;
- }
-
- label = g_strdup (charset_name);
- encoded_label = bonobo_ui_util_encode_str (label);
- g_free (label);
-
- command = g_strdup_printf ("<cmd name=\"Charset-%s\" label=\"%s\" type=\"radio\""
- " group=\"charset_picker\" state=\"1\"/>\n",
- default_charset, encoded_label);
-
- bonobo_ui_component_set (uic, "/commands", command, NULL);
- g_free (command);
-
- g_string_append (menuitems, " <separator/>\n");
- g_string_append_printf (menuitems, " <menuitem name=\"Charset-%s\" verb=\"\"/>\n",
- default_charset);
-
- g_free (encoded_label);
-
- label = g_strdup_printf ("Charset-%s", default_charset);
- bonobo_ui_component_add_listener (uic, label, cb, user_data);
- g_free (label);
- }
-
- g_string_append (menuitems, "</submenu>\n");
-
- bonobo_ui_component_set (uic, path, menuitems->str, NULL);
- g_string_free (menuitems, TRUE);
-}
diff --git a/widgets/misc/e-charset-picker.h b/widgets/misc/e-charset-picker.h
deleted file mode 100644
index 04c013bd88..0000000000
--- a/widgets/misc/e-charset-picker.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_CHARSETPICKER_H
-#define E_CHARSETPICKER_H
-
-#include <gtk/gtk.h>
-#include <bonobo/bonobo-ui-component.h>
-
-G_BEGIN_DECLS
-
-GtkWidget * e_charset_picker_new (const gchar *default_charset);
-gchar * e_charset_picker_get_charset (GtkWidget *picker);
-gchar * e_charset_picker_dialog (const gchar *title,
- const gchar *prompt,
- const gchar *default_charset,
- GtkWindow *parent);
-
-void e_charset_add_radio_actions (GtkActionGroup *action_group,
- const gchar *default_charset,
- GCallback callback,
- gpointer user_data);
-
-void e_charset_picker_bonobo_ui_populate
- (BonoboUIComponent *uic,
- const gchar *path,
- const gchar *default_charset,
- BonoboUIListenerFn cb,
- gpointer user_data);
-
-G_END_DECLS
-
-#endif /* E_CHARSETPICKER_H */
diff --git a/widgets/misc/e-combo-button.c b/widgets/misc/e-combo-button.c
deleted file mode 100644
index 3caf793611..0000000000
--- a/widgets/misc/e-combo-button.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-combo-button.h"
-#include "ea-widgets.h"
-
-struct _EComboButtonPrivate {
- GdkPixbuf *icon;
-
- GtkWidget *icon_image;
- GtkWidget *label;
- GtkWidget *arrow_image;
- GtkWidget *hbox;
- GtkWidget *vbox;
-
- GtkMenu *menu;
-
- gboolean menu_popped_up;
- gboolean is_already_packed;
-};
-
-#define SPACING 2
-
-enum {
- ACTIVATE_DEFAULT,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (EComboButton, e_combo_button, GTK_TYPE_BUTTON)
-
-/* Utility functions. */
-
-static void
-set_icon (EComboButton *combo_button,
- GdkPixbuf *pixbuf)
-{
- EComboButtonPrivate *priv;
-
- priv = combo_button->priv;
-
- if (priv->icon != NULL)
- g_object_unref (priv->icon);
-
- if (pixbuf == NULL) {
- priv->icon = NULL;
- gtk_widget_hide (priv->icon_image);
- return;
- }
-
- priv->icon = g_object_ref (pixbuf);
-
- gtk_image_set_from_pixbuf (GTK_IMAGE (priv->icon_image), priv->icon);
-
- gtk_widget_show (priv->icon_image);
-}
-
-
-/* Paint the borders. */
-
-static void
-paint (EComboButton *combo_button,
- GdkRectangle *area)
-{
- EComboButtonPrivate *priv = combo_button->priv;
- GtkWidget *widget = GTK_WIDGET (combo_button);
- GtkButton *button = GTK_BUTTON (combo_button);
- GtkShadowType shadow_type;
- gboolean interior_focus;
- gint separator_x;
- gint focus_width, focus_pad;
- gint x, y, width, height;
- gint border_width;
-
- if (GTK_BUTTON (widget)->depressed || priv->menu_popped_up) {
- shadow_type = GTK_SHADOW_IN;
- gtk_widget_set_state (widget, GTK_STATE_ACTIVE);
- } else if (GTK_BUTTON (widget)->relief == GTK_RELIEF_NONE &&
- (GTK_WIDGET_STATE (widget) == GTK_STATE_NORMAL ||
- GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE))
- shadow_type = GTK_SHADOW_NONE;
- else
- shadow_type = GTK_SHADOW_OUT;
-
- border_width = GTK_CONTAINER (widget)->border_width;
-
- x = widget->allocation.x + border_width;
- y = widget->allocation.y + border_width;
- width = widget->allocation.width - border_width * 2;
- height = widget->allocation.height - border_width * 2;
-
- separator_x = (priv->label->allocation.width
- + priv->label->allocation.x
- + priv->arrow_image->allocation.x) / 2;
-
- gtk_widget_style_get (GTK_WIDGET (widget),
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- "interior-focus", &interior_focus,
- NULL);
-
- if (GTK_WIDGET_HAS_DEFAULT (widget)
- && GTK_BUTTON (widget)->relief == GTK_RELIEF_NORMAL)
- gtk_paint_box (widget->style, widget->window,
- GTK_STATE_NORMAL, GTK_SHADOW_IN,
- area, widget, "buttondefault",
- x, y, width, height);
-
- if (!interior_focus && GTK_WIDGET_HAS_FOCUS (widget)) {
- x += focus_width + focus_pad;
- y += focus_width + focus_pad;
- width -= 2 * (focus_width + focus_pad);
- height -= 2 * (focus_width + focus_pad);
- }
-
- if (button->relief != GTK_RELIEF_NONE || button->depressed ||
- priv->menu_popped_up ||
- GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) {
-
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE (widget), shadow_type,
- area, widget, "button",
- x, y, separator_x, height);
-
- if (width - separator_x > 0)
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE (widget), shadow_type,
- area, widget, "button",
- separator_x, y, width - separator_x, height);
- }
-
- if (GTK_WIDGET_HAS_FOCUS (widget)) {
- if (interior_focus) {
- x += widget->style->xthickness + focus_pad;
- y += widget->style->ythickness + focus_pad;
- width -= 2 * (widget->style->xthickness + focus_pad);
- height -= 2 * (widget->style->xthickness + focus_pad);
- } else {
- x -= focus_width + focus_pad;
- y -= focus_width + focus_pad;
- width += 2 * (focus_width + focus_pad);
- height += 2 * (focus_width + focus_pad);
- }
-
- gtk_paint_focus (widget->style, widget->window,
- GTK_WIDGET_STATE (widget),
- area, widget, "button",
- x, y, width, height);
- }
-}
-
-
-/* Callbacks for the associated menu. */
-
-static void
-menu_detacher (GtkWidget *widget,
- GtkMenu *menu)
-{
- EComboButton *combo_button;
- EComboButtonPrivate *priv;
-
- combo_button = E_COMBO_BUTTON (widget);
- priv = combo_button->priv;
- g_signal_handlers_disconnect_matched (menu,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL,
- combo_button);
- priv->menu = NULL;
-}
-
-static void
-menu_deactivate_callback (GtkMenuShell *menu_shell,
- gpointer data)
-{
- EComboButton *combo_button;
- EComboButtonPrivate *priv;
-
- combo_button = E_COMBO_BUTTON (data);
- priv = combo_button->priv;
-
- priv->menu_popped_up = FALSE;
-
- GTK_BUTTON (combo_button)->button_down = FALSE;
- GTK_BUTTON (combo_button)->in_button = FALSE;
- gtk_button_leave (GTK_BUTTON (combo_button));
- gtk_button_clicked (GTK_BUTTON (combo_button));
-}
-
-static void
-menu_position_func (GtkMenu *menu,
- gint *x_return,
- gint *y_return,
- gboolean *push_in,
- gpointer data)
-{
- EComboButton *combo_button;
- GtkAllocation *allocation;
-
- combo_button = E_COMBO_BUTTON (data);
- allocation = & (GTK_WIDGET (combo_button)->allocation);
-
- gdk_window_get_origin (GTK_WIDGET (combo_button)->window, x_return, y_return);
-
- *y_return += allocation->height;
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_destroy (GtkObject *object)
-{
- EComboButton *combo_button;
- EComboButtonPrivate *priv;
-
- combo_button = E_COMBO_BUTTON (object);
- priv = combo_button->priv;
-
- if (priv) {
- if (priv->arrow_image != NULL) {
- gtk_widget_destroy (priv->arrow_image);
- priv->arrow_image = NULL;
- }
-
- if (priv->icon != NULL) {
- g_object_unref (priv->icon);
- priv->icon = NULL;
- }
-
- g_free (priv);
- combo_button->priv = NULL;
- }
-
- (* GTK_OBJECT_CLASS (e_combo_button_parent_class)->destroy) (object);
-}
-
-
-
-static gboolean
-e_combo_button_popup (EComboButton *combo_button, GdkEventButton *event)
-{
- EComboButtonPrivate *priv;
-
- g_return_val_if_fail (combo_button != NULL, FALSE);
- g_return_val_if_fail (E_IS_COMBO_BUTTON (combo_button), FALSE);
-
- priv = combo_button->priv;
-
- priv->menu_popped_up = TRUE;
-
- if (event)
- gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
- menu_position_func, combo_button,
- event->button, event->time);
- else
- gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
- menu_position_func, combo_button,
- 0, gtk_get_current_event_time());
-
- return TRUE;
-}
-/* GtkWidget methods. */
-
-static gint
-impl_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- EComboButton *combo_button;
- EComboButtonPrivate *priv;
-
- combo_button = E_COMBO_BUTTON (widget);
- priv = combo_button->priv;
-
- if (event->type == GDK_BUTTON_PRESS &&
- (event->button == 1 || event->button == 3)) {
- GTK_BUTTON (widget)->button_down = TRUE;
-
- if (event->button == 3 ||
- event->x >= priv->arrow_image->allocation.x) {
- /* User clicked on the right side: pop up the menu. */
- gtk_button_pressed (GTK_BUTTON (widget));
-
- e_combo_button_popup (combo_button, event);
- } else {
- /* User clicked on the left side: just behave like a
- normal button (i.e. not a toggle). */
- gtk_button_pressed (GTK_BUTTON (widget));
- }
- }
-
- return TRUE;
-}
-
-static gint
-impl_leave_notify_event (GtkWidget *widget,
- GdkEventCrossing *event)
-{
- EComboButton *combo_button;
- EComboButtonPrivate *priv;
-
- combo_button = E_COMBO_BUTTON (widget);
- priv = combo_button->priv;
-
- /* This is to override the standard behavior of deactivating the button
- when the pointer gets out of the widget, in the case in which we
- have just popped up the menu. Otherwise, the button would look as
- inactive when the menu is popped up. */
- if (! priv->menu_popped_up)
- return (* GTK_WIDGET_CLASS (e_combo_button_parent_class)->leave_notify_event) (widget, event);
-
- return FALSE;
-}
-
-static gint
-impl_expose_event (GtkWidget *widget,
- GdkEventExpose *event)
-{
- GtkBin *bin;
- GdkEventExpose child_event;
-
- if (! GTK_WIDGET_DRAWABLE (widget))
- return FALSE;
-
- bin = GTK_BIN (widget);
-
- paint (E_COMBO_BUTTON (widget), &event->area);
-
- child_event = *event;
- if (bin->child && GTK_WIDGET_NO_WINDOW (bin->child) &&
- gtk_widget_intersect (bin->child, &event->area, &child_event.area))
- gtk_container_propagate_expose (GTK_CONTAINER (widget), bin->child, &child_event);
-
- return FALSE;
-}
-
-
-/* GtkButton methods. */
-
-static void
-impl_released (GtkButton *button)
-{
- EComboButton *combo_button;
- EComboButtonPrivate *priv;
-
- combo_button = E_COMBO_BUTTON (button);
- priv = combo_button->priv;
-
- /* Massive cut & paste from GtkButton here... The only change in
- behavior here is that we want to emit ::activate_default when not
- the menu hasn't been popped up. */
-
- if (button->button_down) {
- gint new_state;
-
- button->button_down = FALSE;
-
- if (button->in_button) {
- gtk_button_clicked (button);
-
- if (! priv->menu_popped_up)
- g_signal_emit (button, signals[ACTIVATE_DEFAULT], 0);
- }
-
- new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
-
- if (GTK_WIDGET_STATE (button) != new_state) {
- gtk_widget_set_state (GTK_WIDGET (button), new_state);
-
- /* We _draw () instead of queue_draw so that if the
- operation blocks, the label doesn't vanish. */
- /* XXX gtk_widget_draw() is deprecated.
- * Replace it with GTK's implementation. */
- gtk_widget_queue_draw (GTK_WIDGET (button));
- gdk_window_process_updates (
- GTK_WIDGET (button)->window, TRUE);
- }
- }
-}
-
-
-static void
-e_combo_button_class_init (EComboButtonClass *combo_button_class)
-{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- GtkButtonClass *button_class;
-
- object_class = GTK_OBJECT_CLASS (combo_button_class);
- object_class->destroy = impl_destroy;
-
- widget_class = GTK_WIDGET_CLASS (object_class);
- widget_class->button_press_event = impl_button_press_event;
- widget_class->leave_notify_event = impl_leave_notify_event;
- widget_class->expose_event = impl_expose_event;
-
- button_class = GTK_BUTTON_CLASS (object_class);
- button_class->released = impl_released;
-
- signals[ACTIVATE_DEFAULT] = g_signal_new ("activate_default",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EComboButtonClass, activate_default),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- e_combo_button_a11y_init ();
-}
-
-static void
-e_combo_button_init (EComboButton *combo_button)
-{
- EComboButtonPrivate *priv;
-
- priv = g_new (EComboButtonPrivate, 1);
- combo_button->priv = priv;
-
- priv->icon = NULL;
- priv->menu = NULL;
- priv->menu_popped_up = FALSE;
- priv->is_already_packed = FALSE;
-}
-
-void
-e_combo_button_pack_hbox (EComboButton *combo_button)
-{
- EComboButtonPrivate *priv;
-
- priv = combo_button->priv;
-
- if (priv->is_already_packed) {
- gtk_widget_destroy (priv->hbox);
- }
-
- priv->hbox = gtk_hbox_new (FALSE, SPACING);
- gtk_container_add (GTK_CONTAINER (combo_button), priv->hbox);
- gtk_widget_show (priv->hbox);
-
- priv->icon_image = gtk_image_new_from_stock (
- GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU);
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->icon_image, TRUE, TRUE, 0);
- gtk_widget_show (priv->icon_image);
-
- priv->label = gtk_label_new ("");
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->label, TRUE, TRUE,
- 0);
- gtk_widget_show (priv->label);
-
- priv->arrow_image = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
- gtk_box_pack_end (GTK_BOX (priv->hbox), priv->arrow_image, TRUE, TRUE,
- GTK_WIDGET (combo_button)->style->xthickness);
- gtk_widget_show (priv->arrow_image);
-
- gtk_widget_show (priv->hbox);
-
- priv->is_already_packed = TRUE;
-}
-
-void
-e_combo_button_pack_vbox (EComboButton *combo_button)
-{
- EComboButtonPrivate *priv;
-
- priv = combo_button->priv;
-
- if (priv->is_already_packed) {
- gtk_widget_destroy (priv->hbox);
- }
-
- priv->hbox = gtk_hbox_new (FALSE, SPACING);
- gtk_container_add (GTK_CONTAINER (combo_button), priv->hbox);
- gtk_widget_show (priv->hbox);
-
- priv->vbox = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (priv->vbox);
-
- priv->icon_image = gtk_image_new_from_stock (
- GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU);
- gtk_box_pack_start (GTK_BOX (priv->vbox), priv->icon_image, TRUE, TRUE, 0);
- gtk_widget_show (priv->icon_image);
-
- priv->label = gtk_label_new ("");
- gtk_box_pack_start (GTK_BOX (priv->vbox), priv->label, TRUE, TRUE,
- 0);
- gtk_widget_show (priv->label);
-
- gtk_box_pack_start (GTK_BOX(priv->hbox),priv->vbox, TRUE, TRUE, 0);
-
- priv->arrow_image = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
- gtk_box_pack_end (GTK_BOX (priv->hbox), priv->arrow_image, TRUE, TRUE,
- GTK_WIDGET (combo_button)->style->xthickness);
- gtk_widget_show (priv->arrow_image);
-
- gtk_widget_show (priv->hbox);
-
- priv->is_already_packed = TRUE;
-}
-
-
-void
-e_combo_button_construct (EComboButton *combo_button)
-{
- EComboButtonPrivate *priv;
-
- g_return_if_fail (combo_button != NULL);
- g_return_if_fail (E_IS_COMBO_BUTTON (combo_button));
-
- priv = combo_button->priv;
- g_return_if_fail (priv->menu == NULL);
-
- GTK_WIDGET_UNSET_FLAGS (combo_button, GTK_CAN_FOCUS);
-
- gtk_button_set_relief (GTK_BUTTON (combo_button), GTK_RELIEF_NONE);
-}
-
-GtkWidget *
-e_combo_button_new (void)
-{
- EComboButton *new;
-
- new = g_object_new (e_combo_button_get_type (), NULL);
- e_combo_button_construct (new);
-
- return GTK_WIDGET (new);
-}
-
-
-void
-e_combo_button_set_icon (EComboButton *combo_button,
- GdkPixbuf *pixbuf)
-{
- g_return_if_fail (combo_button != NULL);
- g_return_if_fail (E_IS_COMBO_BUTTON (combo_button));
-
- set_icon (combo_button, pixbuf);
-}
-
-void
-e_combo_button_set_label (EComboButton *combo_button,
- const gchar *label)
-{
- EComboButtonPrivate *priv;
-
- g_return_if_fail (combo_button != NULL);
- g_return_if_fail (E_IS_COMBO_BUTTON (combo_button));
-
- priv = combo_button->priv;
-
- if (label == NULL)
- label = "";
-
- gtk_label_set_label (GTK_LABEL (priv->label), label);
- gtk_label_set_use_markup (GTK_LABEL (priv->label), FALSE);
- gtk_label_set_use_underline (GTK_LABEL (priv->label), TRUE);
-}
-
-void
-e_combo_button_set_menu (EComboButton *combo_button,
- GtkMenu *menu)
-{
- EComboButtonPrivate *priv;
-
- g_return_if_fail (combo_button != NULL);
- g_return_if_fail (E_IS_COMBO_BUTTON (combo_button));
- g_return_if_fail (menu != NULL);
- g_return_if_fail (GTK_IS_MENU (menu));
-
- priv = combo_button->priv;
-
- if (priv->menu != NULL)
- gtk_menu_detach (priv->menu);
-
- priv->menu = menu;
- if (menu == NULL)
- return;
-
- gtk_menu_attach_to_widget (menu, GTK_WIDGET (combo_button), menu_detacher);
-
- g_signal_connect((menu), "deactivate",
- G_CALLBACK (menu_deactivate_callback),
- combo_button);
-}
-
-GtkWidget *
-e_combo_button_get_label (EComboButton *combo_button)
-{
- EComboButtonPrivate *priv;
-
- g_return_val_if_fail (combo_button != NULL, NULL);
- g_return_val_if_fail (E_IS_COMBO_BUTTON (combo_button), NULL);
-
- priv = combo_button->priv;
-
- return priv->label;
-}
-
-gboolean
-e_combo_button_popup_menu (EComboButton *combo_button)
-{
- return e_combo_button_popup (combo_button, NULL);
-}
diff --git a/widgets/misc/e-combo-button.h b/widgets/misc/e-combo-button.h
deleted file mode 100644
index 29d4b2efe7..0000000000
--- a/widgets/misc/e-combo-button.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_COMBO_BUTTON_H_
-#define _E_COMBO_BUTTON_H_
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_COMBO_BUTTON (e_combo_button_get_type ())
-#define E_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_COMBO_BUTTON, EComboButton))
-#define E_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_COMBO_BUTTON, EComboButtonClass))
-#define E_IS_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_COMBO_BUTTON))
-#define E_IS_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_COMBO_BUTTON))
-
-
-typedef struct _EComboButton EComboButton;
-typedef struct _EComboButtonPrivate EComboButtonPrivate;
-typedef struct _EComboButtonClass EComboButtonClass;
-
-struct _EComboButton {
- GtkButton parent;
-
- EComboButtonPrivate *priv;
-};
-
-struct _EComboButtonClass {
- GtkButtonClass parent_class;
-
- /* Signals. */
- void (* activate_default) (EComboButton *combo_button);
-};
-
-
-GType e_combo_button_get_type (void);
-void e_combo_button_construct (EComboButton *combo_button);
-GtkWidget *e_combo_button_new (void);
-
-void e_combo_button_set_icon (EComboButton *combo_button,
- GdkPixbuf *pixbuf);
-void e_combo_button_set_label (EComboButton *combo_button,
- const gchar *label);
-void e_combo_button_set_menu (EComboButton *combo_button,
- GtkMenu *menu);
-void e_combo_button_pack_vbox (EComboButton *combo_button);
-void e_combo_button_pack_hbox (EComboButton *combo_button);
-
-GtkWidget *e_combo_button_get_label (EComboButton *combo_button);
-
-gboolean e_combo_button_popup_menu (EComboButton *combo_button);
-
-G_END_DECLS
-
-#endif /* _E_COMBO_BUTTON_H_ */
diff --git a/widgets/misc/e-config-page.h b/widgets/misc/e-config-page.h
deleted file mode 100644
index 1de9591397..0000000000
--- a/widgets/misc/e-config-page.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_CONFIG_PAGE_H_
-#define _E_CONFIG_PAGE_H_
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_CONFIG_PAGE (e_config_page_get_type ())
-#define E_CONFIG_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONFIG_PAGE, EConfigPage))
-#define E_CONFIG_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONFIG_PAGE, EConfigPageClass))
-#define E_IS_CONFIG_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONFIG_PAGE))
-#define E_IS_CONFIG_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CONFIG_PAGE))
-
-
-typedef struct _EConfigPage EConfigPage;
-typedef struct _EConfigPagePrivate EConfigPagePrivate;
-typedef struct _EConfigPageClass EConfigPageClass;
-
-struct _EConfigPage {
- GtkEventBox parent;
-
- EConfigPagePrivate *priv;
-};
-
-struct _EConfigPageClass {
- GtkEventBoxClass parent_class;
-
-};
-
-
-GType e_config_page_get_type (void);
-GtkWidget *e_config_page_new (void);
-
-G_END_DECLS
-
-#endif /* _E_CONFIG_PAGE_H_ */
diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c
index 775ab3b8a3..07a9fc61c4 100644
--- a/widgets/misc/e-dateedit.c
+++ b/widgets/misc/e-dateedit.c
@@ -42,6 +42,10 @@
#include <e-util/e-util.h>
#include "e-calendar.h"
+#define E_DATE_EDIT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_DATE_EDIT, EDateEditPrivate))
+
struct _EDateEditPrivate {
GtkWidget *date_entry;
GtkWidget *date_button;
@@ -108,16 +112,18 @@ struct _EDateEditPrivate {
};
enum {
+ PROP_0,
+ PROP_SHOW_WEEK_NUMBERS,
+ PROP_USE_24_HOUR_FORMAT,
+ PROP_WEEK_START_DAY
+};
+
+enum {
CHANGED,
LAST_SIGNAL
};
-static gint date_edit_signals [LAST_SIGNAL] = { 0 };
-
-static void e_date_edit_class_init (EDateEditClass *class);
-static void e_date_edit_init (EDateEdit *dedit);
static void create_children (EDateEdit *dedit);
-static void e_date_edit_dispose (GObject *object);
static gboolean e_date_edit_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling);
static void e_date_edit_grab_focus (GtkWidget *widget);
@@ -188,87 +194,168 @@ static gboolean e_date_edit_set_time_internal (EDateEdit *dedit,
gint hour,
gint minute);
-static GtkHBoxClass *parent_class;
+static gpointer parent_class;
+static gint signals[LAST_SIGNAL];
-/**
- * e_date_edit_get_type:
- *
- * Returns the GType for the EDateEdit widget
- */
-GType
-e_date_edit_get_type (void)
-{
- static GType date_edit_type = 0;
+static void
+date_edit_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHOW_WEEK_NUMBERS:
+ e_date_edit_set_show_week_numbers (
+ E_DATE_EDIT (object),
+ g_value_get_boolean (value));
+ return;
- if (!date_edit_type) {
- static const GTypeInfo date_edit_info = {
- sizeof (EDateEditClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_date_edit_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EDateEdit),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_date_edit_init,
- };
+ case PROP_USE_24_HOUR_FORMAT:
+ e_date_edit_set_use_24_hour_format (
+ E_DATE_EDIT (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_WEEK_START_DAY:
+ e_date_edit_set_week_start_day (
+ E_DATE_EDIT (object),
+ g_value_get_int (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
- date_edit_type = g_type_register_static (GTK_TYPE_HBOX, "EDateEdit", &date_edit_info, 0);
+static void
+date_edit_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHOW_WEEK_NUMBERS:
+ g_value_set_boolean (
+ value, e_date_edit_get_show_week_numbers (
+ E_DATE_EDIT (object)));
+ return;
+
+ case PROP_USE_24_HOUR_FORMAT:
+ g_value_set_boolean (
+ value, e_date_edit_get_use_24_hour_format (
+ E_DATE_EDIT (object)));
+ return;
+
+ case PROP_WEEK_START_DAY:
+ g_value_set_int (
+ value, e_date_edit_get_week_start_day (
+ E_DATE_EDIT (object)));
+ return;
}
- return date_edit_type;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_date_edit_class_init (EDateEditClass *class)
+date_edit_dispose (GObject *object)
{
- GObjectClass *object_class = (GObjectClass *) class;
- GtkWidgetClass *widget_class = (GtkWidgetClass *) class;
+ EDateEdit *dedit;
- parent_class = g_type_class_ref (GTK_TYPE_HBOX);
+ dedit = E_DATE_EDIT (object);
- date_edit_signals [CHANGED] =
- g_signal_new ("changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EDateEditClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ e_date_edit_set_get_time_callback (dedit, NULL, NULL, NULL);
- object_class->dispose = e_date_edit_dispose;
+ if (dedit->priv->cal_popup != NULL) {
+ gtk_widget_destroy (dedit->priv->cal_popup);
+ dedit->priv->cal_popup = NULL;
+ }
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+date_edit_class_init (EDateEditClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EDateEditPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = date_edit_set_property;
+ object_class->get_property = date_edit_get_property;
+ object_class->dispose = date_edit_dispose;
+
+ widget_class = GTK_WIDGET_CLASS (class);
widget_class->mnemonic_activate = e_date_edit_mnemonic_activate;
widget_class->grab_focus = e_date_edit_grab_focus;
- class->changed = NULL;
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_WEEK_NUMBERS,
+ g_param_spec_boolean (
+ "show-week-numbers",
+ "Show Week Numbers",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USE_24_HOUR_FORMAT,
+ g_param_spec_boolean (
+ "use-24-hour-format",
+ "Use 24-Hour Format",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WEEK_START_DAY,
+ g_param_spec_int (
+ "week-start-day",
+ "Week Start Day",
+ NULL,
+ 0, /* Monday */
+ 6, /* Sunday */
+ 0,
+ G_PARAM_READWRITE));
+
+ signals[CHANGED] = g_signal_new (
+ "changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EDateEditClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
-e_date_edit_init (EDateEdit *dedit)
+date_edit_init (EDateEdit *dedit)
{
- EDateEditPrivate *priv;
+ dedit->priv = E_DATE_EDIT_GET_PRIVATE (dedit);
- dedit->priv = priv = g_new0 (EDateEditPrivate, 1);
+ dedit->priv->show_date = TRUE;
+ dedit->priv->show_time = TRUE;
+ dedit->priv->use_24_hour_format = TRUE;
- priv->show_date = TRUE;
- priv->show_time = TRUE;
- priv->use_24_hour_format = TRUE;
+ dedit->priv->make_time_insensitive = FALSE;
- priv->make_time_insensitive = FALSE;
+ dedit->priv->lower_hour = 0;
+ dedit->priv->upper_hour = 24;
- priv->lower_hour = 0;
- priv->upper_hour = 24;
+ dedit->priv->date_is_valid = TRUE;
+ dedit->priv->date_set_to_none = TRUE;
+ dedit->priv->time_is_valid = TRUE;
+ dedit->priv->time_set_to_none = TRUE;
+ dedit->priv->time_callback = NULL;
+ dedit->priv->time_callback_data = NULL;
+ dedit->priv->time_callback_destroy = NULL;
- priv->date_is_valid = TRUE;
- priv->date_set_to_none = TRUE;
- priv->time_is_valid = TRUE;
- priv->time_set_to_none = TRUE;
- priv->time_callback = NULL;
- priv->time_callback_data = NULL;
- priv->time_callback_destroy = NULL;
-
- priv->twodigit_year_can_future = TRUE;
+ dedit->priv->twodigit_year_can_future = TRUE;
create_children (dedit);
@@ -276,6 +363,32 @@ e_date_edit_init (EDateEdit *dedit)
e_date_edit_set_time (dedit, 0);
}
+GType
+e_date_edit_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EDateEditClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) date_edit_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EDateEdit),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) date_edit_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HBOX, "EDateEdit", &type_info, 0);
+ }
+
+ return type;
+}
+
/**
* e_date_edit_new:
*
@@ -472,29 +585,6 @@ create_children (EDateEdit *dedit)
G_CALLBACK (on_date_popup_none_button_clicked), dedit);
}
-static void
-e_date_edit_dispose (GObject *object)
-{
- EDateEdit *dedit;
-
- g_return_if_fail (E_IS_DATE_EDIT (object));
-
- dedit = E_DATE_EDIT (object);
-
- if (dedit->priv) {
- e_date_edit_set_get_time_callback (dedit, NULL, NULL, NULL);
-
- gtk_widget_destroy (dedit->priv->cal_popup);
- dedit->priv->cal_popup = NULL;
-
- g_free (dedit->priv);
- dedit->priv = NULL;
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
/* GtkWidget::mnemonic_activate() handler for the EDateEdit */
static gboolean
e_date_edit_mnemonic_activate (GtkWidget *widget, gboolean group_cycling)
@@ -647,8 +737,7 @@ e_date_edit_set_time (EDateEdit *dedit,
/* Emit the signals if the date and/or time has actually changed. */
if (date_changed || time_changed)
- g_signal_emit (dedit,
- date_edit_signals [CHANGED], 0);
+ g_signal_emit (dedit, signals[CHANGED], 0);
}
/**
@@ -715,8 +804,7 @@ e_date_edit_set_date (EDateEdit *dedit,
/* Emit the signals if the date has actually changed. */
if (date_changed)
- g_signal_emit (dedit,
- date_edit_signals [CHANGED], 0);
+ g_signal_emit (dedit, signals[CHANGED], 0);
}
/**
@@ -792,8 +880,7 @@ e_date_edit_set_time_of_day (EDateEdit *dedit,
e_date_edit_update_time_entry (dedit);
if (time_changed)
- g_signal_emit (dedit,
- date_edit_signals [CHANGED], 0);
+ g_signal_emit (dedit, signals[CHANGED], 0);
}
void
@@ -818,8 +905,7 @@ e_date_edit_set_date_and_time_of_day (EDateEdit *dedit,
e_date_edit_update_time_combo_state (dedit);
if (date_changed || time_changed)
- g_signal_emit (dedit,
- date_edit_signals [CHANGED], 0);
+ g_signal_emit (dedit, signals[CHANGED], 0);
}
/**
@@ -969,21 +1055,21 @@ e_date_edit_set_make_time_insensitive (EDateEdit *dedit,
/**
* e_date_edit_get_week_start_day:
* @dedit: an #EDateEdit widget
- * @Returns: the week start day, from 0 (Sunday) to 6 (Saturday).
+ * @Returns: the week start day, from 0 (Monday) to 6 (Sunday).
*
* Description: Returns the week start day currently used in the calendar
* popup.
*/
gint
-e_date_edit_get_week_start_day (EDateEdit *dedit)
+e_date_edit_get_week_start_day (EDateEdit *dedit)
{
gint week_start_day;
g_return_val_if_fail (E_IS_DATE_EDIT (dedit), 1);
- g_object_get (E_CALENDAR (dedit->priv->calendar)->calitem,
- "week_start_day", &week_start_day,
- NULL);
+ g_object_get (
+ E_CALENDAR (dedit->priv->calendar)->calitem,
+ "week_start_day", &week_start_day, NULL);
return week_start_day;
}
@@ -991,50 +1077,54 @@ e_date_edit_get_week_start_day (EDateEdit *dedit)
/**
* e_date_edit_set_week_start_day:
* @dedit: an #EDateEdit widget
- * @week_start_day: the week start day, from 0 (Sunday) to 6 (Saturday).
+ * @week_start_day: the week start day, from 0 (Monday) to 6 (Sunday).
*
* Description: Sets the week start day to use in the calendar popup.
*/
void
-e_date_edit_set_week_start_day (EDateEdit *dedit,
- gint week_start_day)
+e_date_edit_set_week_start_day (EDateEdit *dedit,
+ gint week_start_day)
{
g_return_if_fail (E_IS_DATE_EDIT (dedit));
- gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
- "week_start_day", week_start_day,
- NULL);
+ gnome_canvas_item_set (
+ GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
+ "week_start_day", week_start_day, NULL);
+
+ g_object_notify (G_OBJECT (dedit), "week-start-day");
}
/* Whether we show week numbers in the date popup. */
gboolean
-e_date_edit_get_show_week_numbers (EDateEdit *dedit)
+e_date_edit_get_show_week_numbers (EDateEdit *dedit)
{
gboolean show_week_numbers;
g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE);
- g_object_get (E_CALENDAR (dedit->priv->calendar)->calitem,
- "show_week_numbers", &show_week_numbers,
- NULL);
+ g_object_get (
+ E_CALENDAR (dedit->priv->calendar)->calitem,
+ "show_week_numbers", &show_week_numbers, NULL);
return show_week_numbers;
}
void
-e_date_edit_set_show_week_numbers (EDateEdit *dedit,
- gboolean show_week_numbers)
+e_date_edit_set_show_week_numbers (EDateEdit *dedit,
+ gboolean show_week_numbers)
{
g_return_if_fail (E_IS_DATE_EDIT (dedit));
- gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
- "show_week_numbers", show_week_numbers,
- NULL);
+ gnome_canvas_item_set (
+ GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
+ "show_week_numbers", show_week_numbers, NULL);
+
+ g_object_notify (G_OBJECT (dedit), "show-week-numbers");
}
/* Whether we use 24 hour format in the time field & popup. */
gboolean
-e_date_edit_get_use_24_hour_format (EDateEdit *dedit)
+e_date_edit_get_use_24_hour_format (EDateEdit *dedit)
{
g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE);
@@ -1042,8 +1132,8 @@ e_date_edit_get_use_24_hour_format (EDateEdit *dedit)
}
void
-e_date_edit_set_use_24_hour_format (EDateEdit *dedit,
- gboolean use_24_hour_format)
+e_date_edit_set_use_24_hour_format (EDateEdit *dedit,
+ gboolean use_24_hour_format)
{
g_return_if_fail (E_IS_DATE_EDIT (dedit));
@@ -1055,6 +1145,8 @@ e_date_edit_set_use_24_hour_format (EDateEdit *dedit,
rebuild_time_popup (dedit);
e_date_edit_update_time_entry (dedit);
+
+ g_object_notify (G_OBJECT (dedit), "use-24-hour-format");
}
/* Whether we allow the date to be set to 'None'. e_date_edit_get_time() will
@@ -1399,8 +1491,8 @@ rebuild_time_popup (EDateEdit *dedit)
/* For 12-hour am/pm format, we want space padding, not zero padding. This
* can be done with strftime's %l, but it's a potentially unportable extension. */
- if (!priv->use_24_hour_format && buffer [0] == '0')
- buffer [0] = ' ';
+ if (!priv->use_24_hour_format && buffer[0] == '0')
+ buffer[0] = ' ';
gtk_combo_box_append_text (combo, buffer);
}
@@ -1736,8 +1828,8 @@ e_date_edit_update_time_entry (EDateEdit *dedit)
/* For 12-hour am/pm format, we want space padding, not zero padding. This
* can be done with strftime's %l, but it's a potentially unportable extension. */
- if (!priv->use_24_hour_format && buffer [0] == '0')
- buffer [0] = ' ';
+ if (!priv->use_24_hour_format && buffer[0] == '0')
+ buffer[0] = ' ';
gtk_entry_set_text (GTK_ENTRY (GTK_BIN (priv->time_combo)->child),
buffer);
@@ -1860,8 +1952,7 @@ e_date_edit_check_date_changed (EDateEdit *dedit)
tmp_tm.tm_mday);
if (date_changed)
- g_signal_emit (dedit,
- date_edit_signals [CHANGED], 0);
+ g_signal_emit (dedit, signals[CHANGED], 0);
}
/* Parses the time, and if it is different from the current settings it
@@ -1891,8 +1982,7 @@ e_date_edit_check_time_changed (EDateEdit *dedit)
if (time_changed) {
e_date_edit_update_time_entry (dedit);
- g_signal_emit (dedit,
- date_edit_signals [CHANGED], 0);
+ g_signal_emit (dedit, signals[CHANGED], 0);
}
}
diff --git a/widgets/misc/e-dropdown-button.c b/widgets/misc/e-dropdown-button.c
deleted file mode 100644
index 0ff0c99fef..0000000000
--- a/widgets/misc/e-dropdown-button.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-dropdown-button.h"
-
-#include <stdio.h>
-
-struct _EDropdownButtonPrivate {
- GtkAccelGroup *accel_group;
- GtkWidget *menu;
-};
-
-G_DEFINE_TYPE (EDropdownButton, e_dropdown_button, GTK_TYPE_TOGGLE_BUTTON)
-
-/* Callback to position the pop-up menu. */
-
-static void
-menu_position_cb (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer data)
-{
- EDropdownButton *dropdown_button;
- EDropdownButtonPrivate *priv;
- GtkRequisition menu_requisition;
- gint max_x, max_y;
-
- dropdown_button = E_DROPDOWN_BUTTON (data);
- priv = dropdown_button->priv;
-
- /* Calculate our preferred position. */
- gdk_window_get_origin (GTK_WIDGET (dropdown_button)->window, x, y);
- *y += GTK_WIDGET (dropdown_button)->allocation.height;
-
- /* Now make sure we are on the screen. */
- gtk_widget_size_request (GTK_WIDGET (priv->menu), &menu_requisition);
- max_x = MAX (0, gdk_screen_width () - menu_requisition.width);
- max_y = MAX (0, gdk_screen_height () - menu_requisition.height);
-
- *x = CLAMP (*x, 0, max_x);
- *y = CLAMP (*y, 0, max_y);
-}
-
-/* Callback for the "deactivate" signal on the pop-up menu. This is used so
- that we unset the state of the toggle button when the pop-up menu
- disappears. */
-
-static gint
-menu_deactivate_cb (GtkMenuShell *menu_shell,
- gpointer data)
-{
- EDropdownButton *dropdown_button;
-
- dropdown_button = E_DROPDOWN_BUTTON (data);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dropdown_button), FALSE);
- return TRUE;
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_destroy (GtkObject *object)
-{
- EDropdownButton *dropdown_button;
- EDropdownButtonPrivate *priv;
-
- dropdown_button = E_DROPDOWN_BUTTON (object);
- priv = dropdown_button->priv;
-
- g_object_unref (priv->accel_group);
- gtk_widget_destroy (priv->menu);
-
- g_free (priv);
-
- if (GTK_OBJECT_CLASS (e_dropdown_button_parent_class)->destroy)
- (* GTK_OBJECT_CLASS (e_dropdown_button_parent_class)->destroy) (object);
-}
-
-
-/* GtkWidget methods. */
-
-static void
-impl_toggled (GtkToggleButton *toggle_button)
-{
- EDropdownButton *dropdown_button;
- EDropdownButtonPrivate *priv;
-
- if (GTK_TOGGLE_BUTTON_CLASS (e_dropdown_button_parent_class)->toggled)
- GTK_TOGGLE_BUTTON_CLASS (e_dropdown_button_parent_class)->toggled (toggle_button);
-
- dropdown_button = E_DROPDOWN_BUTTON (toggle_button);
- priv = dropdown_button->priv;
-
- if (toggle_button->active) {
- gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
- menu_position_cb, dropdown_button,
- 1, GDK_CURRENT_TIME);
- } else {
- gtk_menu_popdown (GTK_MENU (priv->menu));
- }
-}
-
-
-static void
-e_dropdown_button_class_init (EDropdownButtonClass *klass)
-{
- GtkObjectClass *object_class;
- GtkToggleButtonClass *toggle_class;
-
- object_class = GTK_OBJECT_CLASS (klass);
- toggle_class = GTK_TOGGLE_BUTTON_CLASS (klass);
-
- object_class->destroy = impl_destroy;
- toggle_class->toggled = impl_toggled;
-}
-
-static void
-e_dropdown_button_init (EDropdownButton *dropdown_button)
-{
- EDropdownButtonPrivate *priv;
-
- priv = g_new (EDropdownButtonPrivate, 1);
- priv->accel_group = gtk_accel_group_new ();
- priv->menu = NULL;
-
- dropdown_button->priv = priv;
-}
-
-
-/**
- * e_dropdown_button_construct:
- * @dropdown_button: A pointer to an %EDropdownButton object
- * @label_text: Text to display in the button
- * @menu: The menu to pop up when the button is pressed
- *
- * Construct the @dropdown_button with the specified @label_text and the
- * associated @menu.
- **/
-void
-e_dropdown_button_construct (EDropdownButton *dropdown_button,
- const gchar *label_text,
- GtkMenu *menu)
-{
- EDropdownButtonPrivate *priv;
- GtkWidget *hbox;
- GtkWidget *arrow;
- GtkWidget *label;
- guint accel_key;
-
- g_return_if_fail (dropdown_button != NULL);
- g_return_if_fail (E_IS_DROPDOWN_BUTTON (dropdown_button));
- g_return_if_fail (label_text != NULL);
- g_return_if_fail (menu != NULL);
- g_return_if_fail (GTK_IS_MENU (menu));
-
- priv = dropdown_button->priv;
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_container_add (GTK_CONTAINER (dropdown_button), hbox);
- gtk_widget_show (hbox);
-
- label = gtk_label_new ("");
- gtk_label_set_label (GTK_LABEL (label), label_text);
- gtk_label_set_use_markup (GTK_LABEL (label), FALSE);
- gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
-
- accel_key = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
- gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
- gtk_widget_show (label);
- gtk_widget_add_accelerator (GTK_WIDGET (dropdown_button), "clicked",
- priv->accel_group, accel_key, GDK_MOD1_MASK, 0);
-
- arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
- gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 2);
- gtk_widget_show (arrow);
-
- priv->menu = GTK_WIDGET (menu);
-
- g_signal_connect_object (priv->menu, "deactivate",
- G_CALLBACK (menu_deactivate_cb),
- dropdown_button, 0);
-}
-
-/**
- * e_dropdown_button_new:
- * @label_text: Text to display in the button
- * @menu: The menu to pop up when the button is pressed
- *
- * Create a new dropdown button. When the button is clicked, the specified
- * @menu will be popped up.
- *
- * Return value: A pointer to the newly created %EDropdownButton.
- **/
-GtkWidget *
-e_dropdown_button_new (const gchar *label_text,
- GtkMenu *menu)
-{
- GtkWidget *widget;
-
- g_return_val_if_fail (label_text != NULL, NULL);
- g_return_val_if_fail (menu != NULL, NULL);
- g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
-
- widget = g_object_new (e_dropdown_button_get_type (), NULL);
-
- e_dropdown_button_construct (E_DROPDOWN_BUTTON (widget), label_text, menu);
- return widget;
-}
-
diff --git a/widgets/misc/e-dropdown-button.h b/widgets/misc/e-dropdown-button.h
deleted file mode 100644
index f58cd73085..0000000000
--- a/widgets/misc/e-dropdown-button.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_DROPDOWN_BUTTON_H_
-#define _E_DROPDOWN_BUTTON_H_
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_DROPDOWN_BUTTON (e_dropdown_button_get_type ())
-#define E_DROPDOWN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_DROPDOWN_BUTTON, EDropdownButton))
-#define E_DROPDOWN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_DROPDOWN_BUTTON, EDropdownButtonClass))
-#define E_IS_DROPDOWN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_DROPDOWN_BUTTON))
-#define E_IS_DROPDOWN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_DROPDOWN_BUTTON))
-
-
-typedef struct _EDropdownButton EDropdownButton;
-typedef struct _EDropdownButtonPrivate EDropdownButtonPrivate;
-typedef struct _EDropdownButtonClass EDropdownButtonClass;
-
-struct _EDropdownButton {
- GtkToggleButton parent;
-
- EDropdownButtonPrivate *priv;
-};
-
-struct _EDropdownButtonClass {
- GtkToggleButtonClass parent_class;
-};
-
-
-GType e_dropdown_button_get_type (void);
-void e_dropdown_button_construct (EDropdownButton *dropdown_button,
- const gchar *label_text,
- GtkMenu *menu);
-GtkWidget *e_dropdown_button_new (const gchar *label_text,
- GtkMenu *menu);
-
-G_END_DECLS
-
-#endif /* _E_DROPDOWN_BUTTON_H_ */
diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c
deleted file mode 100644
index 42fc03882f..0000000000
--- a/widgets/misc/e-filter-bar.c
+++ /dev/null
@@ -1,1032 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-
-#include <glib/gi18n.h>
-
-#include "e-dropdown-button.h"
-#include "e-filter-bar.h"
-#include "filter/rule-editor.h"
-
-#define d(x)
-
-enum {
- LAST_SIGNAL
-};
-
-/*static gint esb_signals [LAST_SIGNAL] = { 0, };*/
-
-static ESearchBarClass *parent_class = NULL;
-
-/* The arguments we take */
-enum {
- PROP_0,
- PROP_QUERY,
- PROP_STATE
-};
-
-/* Callbacks. */
-
-static void rule_changed (FilterRule *rule, gpointer user_data);
-
-/* rule editor thingy */
-static void
-rule_editor_destroyed (EFilterBar *efb, GObject *deadbeef)
-{
- efb->save_dialog = NULL;
- e_search_bar_set_menu_sensitive (E_SEARCH_BAR (efb), E_FILTERBAR_SAVE_ID, TRUE);
-}
-
-/* FIXME: need to update the popup menu to match any edited rules, sigh */
-static void
-full_rule_editor_response (GtkWidget *dialog, gint response, gpointer data)
-{
- EFilterBar *efb = data;
-
- if (response == GTK_RESPONSE_OK)
- rule_context_save (efb->context, efb->userrules);
-
- gtk_widget_destroy (dialog);
-}
-
-static void
-rule_editor_response (GtkWidget *dialog, gint response, gpointer data)
-{
- EFilterBar *efb = data;
- FilterRule *rule;
-
- if (response == GTK_RESPONSE_OK) {
- rule = g_object_get_data (G_OBJECT (dialog), "rule");
- if (rule) {
- if (!filter_rule_validate (rule))
- return;
-
- rule_context_add_rule (efb->context, rule);
- /* FIXME: check return */
- rule_context_save (efb->context, efb->userrules);
- }
- }
-
- gtk_widget_destroy (dialog);
-}
-
-static void
-rule_advanced_response (GtkWidget *dialog, gint response, gpointer data)
-{
- EFilterBar *efb = data;
- /* the below generates a compiler warning about incompatible pointer types */
- ESearchBar *esb = (ESearchBar *)efb;
- FilterRule *rule;
-
- if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
- rule = g_object_get_data ((GObject *) dialog, "rule");
- if (rule) {
- GtkStyle *style = gtk_widget_get_default_style ();
-
- if (!filter_rule_validate (rule))
- return;
-
- efb->current_query = rule;
- g_object_ref (rule);
-
- gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- e_search_bar_set_text (esb,_("Advanced Search"));
- gtk_widget_set_sensitive (esb->clear_button, TRUE);
-
- g_signal_emit_by_name (efb, "search_activated");
-
- if (response == GTK_RESPONSE_APPLY) {
- if (!rule_context_find_rule (efb->context, rule->name, rule->source))
- rule_context_add_rule (efb->context, rule);
- /* FIXME: check return */
- rule_context_save (efb->context, efb->userrules);
- }
- }
- } else {
- e_search_bar_set_item_id (esb, esb->last_search_option);
- }
-
- if (response != GTK_RESPONSE_APPLY)
- gtk_widget_destroy (dialog);
-}
-
-static void
-dialog_rule_changed (FilterRule *fr, GtkWidget *dialog)
-{
- gboolean sensitive;
-
- g_return_if_fail (dialog != NULL);
-
- sensitive = fr && fr->parts;
- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_APPLY, sensitive);
-}
-
-static void
-do_advanced (ESearchBar *esb)
-{
- EFilterBar *efb = (EFilterBar *)esb;
-
- d(printf("Advanced search!\n"));
-
- if (!efb->save_dialog && !efb->setquery) {
- GtkWidget *dialog, *w;
- FilterRule *rule;
-
- if (efb->current_query)
- rule = filter_rule_clone (efb->current_query);
- else {
- rule = filter_rule_new ();
- efb->current_query = rule;
- }
-
- w = filter_rule_get_widget (rule, efb->context);
- filter_rule_set_source (rule, FILTER_SOURCE_INCOMING);
- gtk_container_set_border_width (GTK_CONTAINER (w), 12);
-
- /* FIXME: get the toplevel window... */
- dialog = gtk_dialog_new_with_buttons (_("Advanced Search"), NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_SAVE, GTK_RESPONSE_APPLY,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
-
- efb->save_dialog = dialog;
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-
- gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
- gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 300);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12);
-
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), w, TRUE, TRUE, 0);
-
- g_object_ref (rule);
- g_object_set_data_full ((GObject *) dialog, "rule", rule, (GDestroyNotify) g_object_unref);
-
- g_signal_connect (rule, "changed", G_CALLBACK (dialog_rule_changed), dialog);
- dialog_rule_changed (rule, dialog);
-
- g_signal_connect (dialog, "response", G_CALLBACK (rule_advanced_response), efb);
- g_object_weak_ref ((GObject *) dialog, (GWeakNotify) rule_editor_destroyed, efb);
-
- e_search_bar_set_menu_sensitive (esb, E_FILTERBAR_SAVE_ID, FALSE);
-
- gtk_widget_show (dialog);
- }
-}
-
-static void
-save_search_dialog (ESearchBar *esb)
-{
- FilterRule *rule;
- gchar *name, *text;
- GtkWidget *dialog, *w;
-
- EFilterBar *efb = (EFilterBar *)esb;
-
- rule = filter_rule_clone (efb->current_query);
- text = e_search_bar_get_text (esb);
- name = g_strdup_printf ("%s %s", rule->name, text && text[0] ? text : "''");
- filter_rule_set_name (rule, name);
- g_free (text);
- g_free (name);
-
- w = filter_rule_get_widget (rule, efb->context);
- filter_rule_set_source (rule, FILTER_SOURCE_INCOMING);
- gtk_container_set_border_width (GTK_CONTAINER (w), 12);
-
- /* FIXME: get the toplevel window... */
- dialog = gtk_dialog_new_with_buttons (_("Save Search"), NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
- efb->save_dialog = dialog;
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12);
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 300);
-
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), w, TRUE, TRUE, 0);
-
- g_object_ref (rule);
- g_object_set_data_full ((GObject *) dialog, "rule", rule, (GDestroyNotify) g_object_unref);
- g_signal_connect (dialog, "response", G_CALLBACK (rule_editor_response), efb);
- g_object_weak_ref ((GObject *) dialog, (GWeakNotify) rule_editor_destroyed, efb);
-
- g_signal_connect (rule, "changed", G_CALLBACK (dialog_rule_changed), dialog);
- dialog_rule_changed (rule, dialog);
-
- e_search_bar_set_menu_sensitive (esb, E_FILTERBAR_SAVE_ID, FALSE);
-
- gtk_widget_show (dialog);
-}
-
-static void
-menubar_activated (ESearchBar *esb, gint id, gpointer data)
-{
- EFilterBar *efb = (EFilterBar *)esb;
- GtkWidget *dialog;
- GtkStyle *style;
-
- d(printf ("menubar activated!\n"));
-
- switch (id) {
- case E_FILTERBAR_EDIT_ID:
- if (!efb->save_dialog) {
- efb->save_dialog = dialog = (GtkWidget *) rule_editor_new (efb->context, FILTER_SOURCE_INCOMING, _("_Searches"));
-
- gtk_window_set_title (GTK_WINDOW (dialog), _("Searches"));
- g_signal_connect (dialog, "response", G_CALLBACK (full_rule_editor_response), efb);
- g_object_weak_ref ((GObject *) dialog, (GWeakNotify) rule_editor_destroyed, efb);
- gtk_widget_show (dialog);
- }
- break;
- case E_FILTERBAR_SAVE_ID:
- if (efb->current_query && !efb->save_dialog)
- save_search_dialog (esb);
-
- d(printf("Save menu\n"));
- break;
- case E_FILTERBAR_ADVANCED_ID:
- e_search_bar_set_item_id (esb, E_FILTERBAR_ADVANCED_ID);
- break;
- default:
- if (id >= efb->menu_base && id < efb->menu_base + efb->menu_rules->len) {
-#if d(!)0
- GString *out = g_string_new ("");
-
- printf("Selected rule: %s\n", ((FilterRule *)efb->menu_rules->pdata[id - efb->menu_base])->name);
- filter_rule_build_code (efb->menu_rules->pdata[id - efb->menu_base], out);
- printf("query: '%s'\n", out->str);
- g_string_free (out, TRUE);
-#endif
- efb->current_query = (FilterRule *)efb->menu_rules->pdata[id - efb->menu_base];
-
- efb->setquery = TRUE;
- e_search_bar_set_item_id (esb, E_FILTERBAR_ADVANCED_ID);
- efb->setquery = FALSE;
-
- /* saved searches activated */
- style = gtk_widget_get_default_style ();
- efb->setquery = TRUE;
- gtk_widget_modify_base (esb->entry , GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED] ));
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text [GTK_STATE_SELECTED] ));
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base [GTK_STATE_SELECTED] ));
- gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base [GTK_STATE_SELECTED] ));
- e_search_bar_set_text (esb,_("Advanced Search"));
- g_signal_emit_by_name (efb, "search_activated", NULL);
- efb->setquery = FALSE;
- } else {
- return;
- }
- }
-
- g_signal_stop_emission_by_name (esb, "menu_activated");
-}
-
-static void
-option_changed (ESearchBar *esb, gpointer data)
-{
- EFilterBar *efb = (EFilterBar *)esb;
- gint id = e_search_bar_get_item_id (esb);
- gchar *query;
-
- d(printf("option changed, id = %d, setquery = %s %d\n", id, efb->setquery ? "true" : "false", esb->block_search));
-
- if (efb->setquery)
- return;
-
- switch (id) {
- case E_FILTERBAR_SAVE_ID:
- /* Fixme */
- /* save_search_dialog (esb); */
- break;
- case E_FILTERBAR_ADVANCED_ID:
- d(printf ("do_advanced\n"));
- if (!esb->block_search)
- do_advanced (esb);
- break;
- default:
- if (id >= efb->option_base && id < efb->option_base + efb->option_rules->len) {
- efb->current_query = (FilterRule *)efb->option_rules->pdata[id - efb->option_base];
- if (efb->config && efb->current_query) {
- query = e_search_bar_get_text (esb);
- efb->config (efb, efb->current_query, id, query, efb->config_data);
- g_free (query);
- }
- } else {
- gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL);
- efb->current_query = NULL;
- gtk_entry_set_text ((GtkEntry *)esb->entry, "");
- }
- }
-}
-
-static void
-dup_item_no_subitems (ESearchBarItem *dest,
- const ESearchBarItem *src)
-{
- dest->id = src->id;
- dest->text = g_strdup (src->text);
- dest->type = src->type;
-}
-
-static GArray *
-build_items (ESearchBar *esb, ESearchBarItem *items, gint type, gint *start, GPtrArray *rules)
-{
- FilterRule *rule = NULL;
- EFilterBar *efb = (EFilterBar *)esb;
- gint id = 0, i;
- GArray *menu = g_array_new (FALSE, FALSE, sizeof (ESearchBarItem));
- ESearchBarItem item = { NULL, -1, 2 };
- const gchar *source;
- GSList *gtksux = NULL;
- gint num;
-
- for (i=0;i<rules->len;i++)
- gtksux = g_slist_prepend(gtksux, rules->pdata[i]);
-
- g_ptr_array_set_size(rules, 0);
-
- /* find a unique starting point for the id's of our items */
- for (i = 0; items[i].id != -1; i++) {
- ESearchBarItem dup_item = { NULL, -1, 2 };
-
- if (items[i].id >= id)
- id = items[i].id + 1;
-
- dup_item_no_subitems (&dup_item, items + i);
- g_array_append_vals (menu, &dup_item, 1);
- }
-
- *start = id;
-
- if (type == 0) {
- source = FILTER_SOURCE_INCOMING;
-
- /* Add a separator if there is at least one custom rule. */
- if (rule_context_next_rule (efb->context, rule, source) != NULL) {
- item.id = 0;
- item.text = NULL;
- item.type = 0;
- g_array_append_vals (menu, &item, 1);
- }
- } else {
- source = FILTER_SOURCE_DEMAND;
- }
-
- num = 1;
- while ((rule = rule_context_next_rule (efb->context, rule, source))) {
- item.id = id++;
-
- if (type == 0 && num <= 10) {
- item.text = g_strdup_printf ("_%d. %s", num % 10, rule->name);
- num ++;
- } else {
- item.text = g_strdup (rule->name);
- }
- g_array_append_vals (menu, &item, 1);
-
- if (g_slist_find(gtksux, rule) == NULL) {
- g_object_ref (rule);
- g_signal_connect (rule, "changed", G_CALLBACK (rule_changed), efb);
- } else {
- gtksux = g_slist_remove(gtksux, rule);
- }
- g_ptr_array_add (rules, rule);
- }
-
- /* anything elft in gtksux has gone away, and we need to unref/disconnect from it */
- while (gtksux) {
- GSList *next;
-
- next = gtksux->next;
- rule = gtksux->data;
-
- g_signal_handlers_disconnect_by_func (rule, G_CALLBACK (rule_changed), efb);
- g_object_unref (rule);
-
- g_slist_free_1(gtksux);
- gtksux = next;
- }
-
- /* always add on the advanced menu */
- if (type == 1) {
- ESearchBarItem sb_items[2] = { E_FILTERBAR_SEPARATOR, E_FILTERBAR_ADVANCED,
- /* E_FILTERBAR_SEPARATOR, E_FILTERBAR_SAVE */ };
- ESearchBarItem dup_items[2];
-
- dup_item_no_subitems (&dup_items[0], &sb_items[0]);
- dup_item_no_subitems (&dup_items[1], &sb_items[1]);
- /* dup_item_no_subitems (&dup_items[2], &sb_items[2]); */
- /* dup_item_no_subitems (&dup_items[3], &sb_items[3]); */
- g_array_append_vals (menu, &dup_items, 2);
- }
-
- item.id = -1;
- item.text = NULL;
- g_array_append_vals (menu, &item, 1);
-
- return menu;
-}
-
-static void
-free_built_items (GArray *menu)
-{
- gint i;
-
- for (i = 0; i < menu->len; i ++) {
- ESearchBarItem *item;
-
- item = & g_array_index (menu, ESearchBarItem, i);
- g_free (item->text);
- }
-
- g_array_free (menu, TRUE);
-}
-
-static void
-generate_menu (ESearchBar *esb, ESearchBarItem *items)
-{
- EFilterBar *efb = (EFilterBar *)esb;
- GArray *menu;
-
- menu = build_items (esb, items, 0, &efb->menu_base, efb->menu_rules);
- ((ESearchBarClass *)parent_class)->set_menu (esb, (ESearchBarItem *)menu->data);
- free_built_items (menu);
-}
-
-static void
-free_items (ESearchBarItem *items)
-{
- gint i;
-
- for (i = 0; items[i].id != -1; i++)
- g_free (items[i].text);
-
- g_free (items);
-}
-
-/* Virtual methods */
-static void
-set_menu (ESearchBar *esb, ESearchBarItem *items)
-{
- EFilterBar *efb = E_FILTER_BAR (esb);
- ESearchBarItem *default_items;
- gint i, num;
-
- if (efb->default_items)
- free_items (efb->default_items);
-
- for (num = 0; items[num].id != -1; num++)
- ;
-
- default_items = g_new (ESearchBarItem, num + 1);
- for (i = 0; i < num + 1; i++) {
- default_items[i].text = g_strdup (items[i].text);
- default_items[i].id = items[i].id;
- default_items[i].type = items[i].type;
- }
-
- efb->default_items = default_items;
-
- generate_menu (esb, default_items);
-}
-
-static void
-set_option (ESearchBar *esb, ESearchBarItem *items)
-{
- GArray *menu;
- EFilterBar *efb = (EFilterBar *)esb;
-
- menu = build_items (esb, items, 1, &efb->option_base, efb->option_rules);
- ((ESearchBarClass *)parent_class)->set_option (esb, (ESearchBarItem *)menu->data);
- free_built_items (menu);
-
- e_search_bar_set_item_id (esb, efb->option_base);
-}
-
-static void
-context_changed (RuleContext *context, gpointer user_data)
-{
- EFilterBar *efb = E_FILTER_BAR (user_data);
- ESearchBar *esb = E_SEARCH_BAR (user_data);
-
- /* just generate whole menu again */
- generate_menu (esb, efb->default_items);
-}
-
-static void
-context_rule_removed (RuleContext *context, FilterRule *rule, gpointer user_data)
-{
- EFilterBar *efb = E_FILTER_BAR (user_data);
- ESearchBar *esb = E_SEARCH_BAR (user_data);
-
- /* just generate whole menu again */
- generate_menu (esb, efb->default_items);
-}
-
-static void
-rule_changed (FilterRule *rule, gpointer user_data)
-{
- EFilterBar *efb = E_FILTER_BAR (user_data);
- ESearchBar *esb = E_SEARCH_BAR (user_data);
-
- /* just generate whole menu again */
- generate_menu (esb, efb->default_items);
-}
-
-
-/* GtkObject methods. */
-
-static void
-get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- EFilterBar *efb = (EFilterBar *) object;
- ESearchBar *esb = E_SEARCH_BAR (object);
-
- switch (property_id) {
- case PROP_QUERY: {
- gchar *text = e_search_bar_get_text (E_SEARCH_BAR (efb));
-
- /* empty search text means searching turned off */
- if (efb->current_query && text && *text) {
- GString *out = g_string_new ("");
-
- filter_rule_build_code (efb->current_query, out);
- g_value_take_string (value, out->str);
- g_string_free (out, FALSE);
- } else {
- g_value_set_string (value, NULL);
- }
-
- g_free (text);
- break; }
- case PROP_STATE: {
- /* FIXME: we should have ESearchBar save its own state to the xmlDocPtr */
- xmlChar *xmlbuf;
- gchar *text, buf[12];
- gint searchscope, item_id, n, view_id;
- xmlNodePtr root, node;
- xmlDocPtr doc;
-
- item_id = e_search_bar_get_item_id ((ESearchBar *) efb);
-
- doc = xmlNewDoc ((const guchar *)"1.0");
- root = xmlNewDocNode (doc, NULL, (const guchar *)"state", NULL);
- xmlDocSetRootElement (doc, root);
- searchscope = e_search_bar_get_search_scope ((ESearchBar *) efb);
- view_id = e_search_bar_get_viewitem_id ((ESearchBar *) efb);
-
- if (searchscope < E_FILTERBAR_CURRENT_FOLDER_ID)
- item_id = esb->last_search_option;
-
- if (item_id == E_FILTERBAR_ADVANCED_ID) {
- /* advanced query, save the filterbar state */
- node = xmlNewChild (root, NULL, (const guchar *)"filter-bar", NULL);
-
- sprintf (buf, "%d", esb->last_search_option);
- xmlSetProp (node, (const guchar *)"item_id", (guchar *)buf);
- sprintf (buf, "%d", searchscope);
- xmlSetProp (node, (const guchar *)"searchscope", (guchar *)buf);
- sprintf (buf, "%d", view_id);
- xmlSetProp (node, (const guchar *)"view_id", (guchar *)buf);
-
- xmlAddChild (node, filter_rule_xml_encode (efb->current_query));
- } else {
- /* simple query, save the searchbar state */
- text = e_search_bar_get_text ((ESearchBar *) efb);
-
- node = xmlNewChild (root, NULL, (const guchar *)"search-bar", NULL);
- xmlSetProp (node, (const guchar *)"text", (guchar *)(text ? text : ""));
- sprintf (buf, "%d", item_id);
- xmlSetProp (node, (const guchar *)"item_id", (guchar *)buf);
- sprintf (buf, "%d", searchscope);
- xmlSetProp (node, (const guchar *)"searchscope", (guchar *)buf);
- sprintf (buf, "%d", view_id);
- xmlSetProp (node, (const guchar *)"view_id", (guchar *)buf);
- g_free (text);
- }
-
- xmlDocDumpMemory (doc, &xmlbuf, &n);
- xmlFreeDoc (doc);
-
- /* remap to glib memory */
- text = g_malloc (n + 1);
- memcpy (text, (gchar *)xmlbuf, n);
- text[n] = '\0';
- xmlFree (xmlbuf);
-
- g_value_take_string (value, text);
-
- break; }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static gint
-xml_get_prop_int (xmlNodePtr node, const gchar *prop)
-{
- gchar *buf;
- gint ret;
-
- if ((buf = (gchar *)xmlGetProp (node, (guchar *)prop))) {
- ret = strtol (buf, NULL, 10);
- xmlFree (buf);
- } else {
- ret = -1;
- }
-
- return ret;
-}
-
-static void
-set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- EFilterBar *efb = (EFilterBar *) object;
- ESearchBar *esb = E_SEARCH_BAR (object);
- xmlNodePtr root, node;
- const gchar *state;
- xmlDocPtr doc;
- gboolean rule_set = FALSE, is_cur_folder=FALSE;
- gint view_id, scope, item_id;
-
- switch (property_id) {
- case PROP_STATE:
- if ((state = g_value_get_string (value))) {
- if (!(doc = xmlParseDoc ((guchar *) state)))
- return;
-
- root = doc->children;
- if (strcmp ((gchar *)root->name, "state") != 0) {
- xmlFreeDoc (doc);
- return;
- }
-
- node = root->children;
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "filter-bar")) {
- FilterRule *rule = NULL;
-
- view_id = xml_get_prop_int (node, "view_id");
- scope = xml_get_prop_int (node, "searchscope");
- item_id = xml_get_prop_int (node, "item_id");
- if (item_id == -1)
- item_id = 0;
-
- if (scope == E_FILTERBAR_CURRENT_FOLDER_ID)
- is_cur_folder = TRUE;
-
- if ((node = node->children)) {
- GtkStyle *style = gtk_widget_get_default_style ();
-
- rule = filter_rule_new ();
- if (filter_rule_xml_decode (rule, node, efb->context) != 0) {
- gtk_widget_modify_base (E_SEARCH_BAR (efb)->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_text (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_base (((ESearchBar *)efb)->icon_entry, GTK_STATE_NORMAL, NULL);
- g_object_unref (rule);
- rule = NULL;
- } else {
- rule_set = TRUE;
- gtk_widget_set_sensitive (esb->clear_button, TRUE);
- gtk_widget_modify_base (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_text (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (((ESearchBar *)efb)->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (((ESearchBar *)efb)->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- g_object_set_data_full (object, "rule", rule, (GDestroyNotify) g_object_unref);
- }
- }
-
- if (rule_set) {
- esb->block_search = TRUE;
- e_search_bar_set_text (esb, _("Advanced Search"));
- e_search_bar_set_item_menu ((ESearchBar *) efb, item_id);
- e_search_bar_set_search_scope ((ESearchBar *) efb, scope);
- esb->block_search = FALSE;
- efb->current_query = (FilterRule *)efb->option_rules->pdata[item_id - efb->option_base];
- if (efb->config && efb->current_query) {
- gchar *query = e_search_bar_get_text (esb);
- efb->config (efb, efb->current_query, item_id, query, efb->config_data);
- g_free (query);
-
- }
- }
- e_search_bar_set_viewitem_id ((ESearchBar *) efb, view_id);
- efb->current_query = rule;
- efb->setquery = TRUE;
- e_search_bar_set_item_id ((ESearchBar *) efb, E_FILTERBAR_ADVANCED_ID);
- efb->setquery = FALSE;
-
- break;
- } else if (!strcmp ((gchar *)node->name, "search-bar")) {
- gint subitem_id, item_id, scope, view_id;
- gchar *text;
- GtkStyle *style = gtk_widget_get_default_style ();
-
- /* set the text first (it doesn't emit a signal) */
-
- /* now set the item_id and subitem_id */
- item_id = xml_get_prop_int (node, "item_id");
- subitem_id = xml_get_prop_int (node, "subitem_id");
-
- esb->block_search = TRUE;
- if (subitem_id >= 0)
- e_search_bar_set_ids (E_SEARCH_BAR (efb), item_id, subitem_id);
- else
- e_search_bar_set_item_menu (E_SEARCH_BAR (efb), item_id);
- esb->block_search = FALSE;
- view_id = xml_get_prop_int (node, "view_id");
- e_search_bar_set_viewitem_id (E_SEARCH_BAR (efb), view_id);
- scope = xml_get_prop_int (node, "searchscope");
- e_search_bar_set_search_scope (E_SEARCH_BAR (efb), scope);
-
- text = (gchar *)xmlGetProp (node, (const guchar *)"text");
- e_search_bar_set_text (E_SEARCH_BAR (efb), text);
- if (text && *text) {
- efb->current_query = (FilterRule *)efb->option_rules->pdata[item_id - efb->option_base];
- if (efb->config && efb->current_query)
- efb->config (efb, efb->current_query, item_id, text, efb->config_data);
- gtk_widget_set_sensitive (esb->clear_button, TRUE);
- gtk_widget_modify_base (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_text (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (((ESearchBar *)efb)->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (((ESearchBar *)efb)->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- } else {
- gtk_widget_modify_base (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_text (((ESearchBar *)efb)->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_base (((ESearchBar *)efb)->icon_entry, GTK_STATE_NORMAL, NULL);
- e_search_bar_paint (esb);
- efb->current_query = (FilterRule *)efb->option_rules->pdata[item_id - efb->option_base];
- if (efb->config && efb->current_query)
- efb->config (efb, efb->current_query, item_id, "", efb->config_data);
- }
-
- xmlFree (text);
-
- break;
- }
-
- node = node->next;
- }
-
- xmlFreeDoc (doc);
- } else {
- /* set default state */
- e_search_bar_set_item_id ((ESearchBar *) efb, 0);
- e_search_bar_set_viewitem_id ((ESearchBar *) efb, 0);
- e_search_bar_set_search_scope ((ESearchBar *) efb, E_FILTERBAR_CURRENT_FOLDER_ID);
- }
-
- /* we don't want to run option_changed */
- efb->setquery = TRUE;
- g_signal_emit_by_name (efb, "search_activated", NULL);
- efb->setquery = FALSE;
-
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void clear_rules(EFilterBar *efb, GPtrArray *rules)
-{
- gint i;
- FilterRule *rule;
-
- /* clear out any data on old rules */
- for (i=0;i<rules->len;i++) {
- rule = rules->pdata[i];
- g_signal_handlers_disconnect_by_func (rule, G_CALLBACK (rule_changed), efb);
- g_object_unref(rule);
- }
- g_ptr_array_set_size (rules, 0);
-}
-
-static void
-dispose (GObject *object)
-{
- EFilterBar *bar;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (E_IS_FILTER_BAR (object));
-
- bar = E_FILTER_BAR (object);
-
- if (bar->context != NULL && bar->userrules != NULL)
- rule_context_save (bar->context, bar->userrules);
-
- if (bar->menu_rules != NULL) {
- clear_rules(bar, bar->menu_rules);
- clear_rules(bar, bar->option_rules);
-
- g_ptr_array_free (bar->menu_rules, TRUE);
- g_ptr_array_free (bar->option_rules, TRUE);
-
- g_free (bar->systemrules);
- g_free (bar->userrules);
-
- bar->menu_rules = NULL;
- bar->option_rules = NULL;
- bar->systemrules = NULL;
- bar->userrules = NULL;
- }
-
- if (bar->context != NULL) {
- g_signal_handlers_disconnect_by_func (bar->context, G_CALLBACK (context_changed), bar);
- g_signal_handlers_disconnect_by_func (bar->context, G_CALLBACK (context_rule_removed), bar);
-
- g_object_unref (bar->context);
- bar->context = NULL;
- }
-
- if (bar->default_items) {
- free_items (bar->default_items);
- bar->default_items = NULL;
- }
-
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
-
-
-static void
-class_init (EFilterBarClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *) klass;
- ESearchBarClass *esb_class = (ESearchBarClass *) klass;
- GParamSpec *pspec;
-
- parent_class = g_type_class_ref (e_search_bar_get_type ());
-
- object_class->dispose = dispose;
- object_class->get_property = get_property;
- object_class->set_property = set_property;
-
- esb_class->set_menu = set_menu;
- esb_class->set_option = set_option;
-
- pspec = g_param_spec_string ("query", NULL, NULL, NULL, G_PARAM_READABLE);
- g_object_class_install_property (object_class, PROP_QUERY, pspec);
-
- pspec = g_param_spec_string ("state", NULL, NULL, NULL, G_PARAM_READWRITE);
- g_object_class_install_property (object_class, PROP_STATE, pspec);
-
- /*gtk_object_add_arg_type ("EFilterBar::query", G_TYPE_STRING, GTK_ARG_READABLE, ARG_QUERY);*/
-
-#if 0
- esb_signals [QUERY_CHANGED] =
- g_signal_new ("query_changed",
- G_SIGNAL_RUN_LAST,
- object_class->type,
- G_STRUCT_OFFSET (EFilterBarClass, query_changed),
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- esb_signals [MENU_ACTIVATED] =
- g_signal_new ("menu_activated",
- G_SIGNAL_RUN_LAST,
- object_class->type,
- G_STRUCT_OFFSET (EFilterBarClass, menu_activated),
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1, G_TYPE_INT);
-
- gtk_object_class_add_signals (object_class, esb_signals, LAST_SIGNAL);
-#endif
-}
-
-static void
-init (EFilterBar *efb)
-{
- g_signal_connect (efb, "menu_activated", G_CALLBACK (menubar_activated), NULL);
- g_signal_connect (efb, "query_changed", G_CALLBACK (option_changed), NULL);
- g_signal_connect (efb, "search_activated", G_CALLBACK (option_changed), NULL);
-
- efb->menu_rules = g_ptr_array_new ();
- efb->option_rules = g_ptr_array_new ();
-}
-
-
-/* Object construction. */
-
-EFilterBar *
-e_filter_bar_new (RuleContext *context,
- const gchar *systemrules,
- const gchar *userrules,
- EFilterBarConfigRule config,
- gpointer data)
-{
- EFilterBar *bar;
-
- bar = g_object_new (e_filter_bar_get_type (), NULL);
- ((ESearchBar *)bar)->lite = FALSE;
-
- e_filter_bar_new_construct (context, systemrules, userrules, config, data, bar);
-
- return bar;
-}
-
-EFilterBar *
-e_filter_bar_lite_new (RuleContext *context,
- const gchar *systemrules,
- const gchar *userrules,
- EFilterBarConfigRule config,
- gpointer data)
-{
- EFilterBar *bar;
-
- bar = g_object_new (e_filter_bar_get_type (), NULL);
- ((ESearchBar *)bar)->lite = TRUE;
- e_filter_bar_new_construct (context, systemrules, userrules, config, data, bar);
-
- return bar;
-}
-
-void
-e_filter_bar_new_construct (RuleContext *context,
- const gchar *systemrules,
- const gchar *userrules,
- EFilterBarConfigRule config,
- gpointer data ,EFilterBar *bar )
-{
- ESearchBarItem item = { NULL, -1, 0 };
-
- bar->context = context;
- g_object_ref (context);
-
- bar->config = config;
- bar->config_data = data;
-
- bar->systemrules = g_strdup (systemrules);
- bar->userrules = g_strdup (userrules);
-
- bar->all_account_search_vf = NULL;
- bar->account_search_vf = NULL;
- bar->account_search_cancel = NULL;
-
- e_search_bar_construct ((ESearchBar *)bar, &item, &item);
-
- g_signal_connect (context, "changed", G_CALLBACK (context_changed), bar);
- g_signal_connect (context, "rule_removed", G_CALLBACK (context_rule_removed), bar);
-
-}
-
-GType
-e_filter_bar_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EFilterBarClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EFilterBar),
- 0, /* n_preallocs */
- (GInstanceInitFunc) init,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- e_search_bar_get_type (), "EFilterBar", &type_info, 0);
- }
-
- return type;
-}
diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h
deleted file mode 100644
index 8659f0a638..0000000000
--- a/widgets/misc/e-filter-bar.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __E_FILTER_BAR_H__
-#define __E_FILTER_BAR_H__
-
-#include <gtk/gtk.h>
-#include <camel/camel-vee-folder.h>
-#include <camel/camel-operation.h>
-
-#include "e-search-bar.h"
-
-#include "filter/rule-context.h"
-#include "filter/filter-rule.h"
-
-G_BEGIN_DECLS
-
-/* EFilterBar - A filter rule driven search bar.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * ---------------------------------------------------------------------------------
- * query string R String representing query.
- * state string RW XML string representing the state.
- */
-
-#define E_FILTER_BAR_TYPE (e_filter_bar_get_type ())
-#define E_FILTER_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_FILTER_BAR_TYPE, EFilterBar))
-#define E_FILTER_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_FILTER_BAR_TYPE, EFilterBarClass))
-#define E_IS_FILTER_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_FILTER_BAR_TYPE))
-#define E_IS_FILTER_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_FILTER_BAR_TYPE))
-
-typedef struct _EFilterBar EFilterBar;
-typedef struct _EFilterBarClass EFilterBarClass;
-
-typedef void (*EFilterBarConfigRule)(EFilterBar *, FilterRule *rule, gint id, const gchar *query, gpointer data);
-
-struct _EFilterBar {
- ESearchBar parent;
- gint menu_base, option_base;
- GPtrArray *menu_rules, *option_rules;
-
- ESearchBarItem *default_items;
-
- GtkWidget *save_dialog; /* current save dialogue (so we dont pop up multiple ones) */
-
- FilterRule *current_query; /* as it says */
- gint setquery; /* true when we're setting a query directly to advanced, so dont popup the dialog */
-
- RuleContext *context;
- gchar *systemrules;
- gchar *userrules;
-
- EFilterBarConfigRule config;
- gpointer config_data;
-
- CamelVeeFolder *all_account_search_vf;
- CamelVeeFolder *account_search_vf;
- CamelOperation *account_search_cancel;
-};
-
-struct _EFilterBarClass
-{
- ESearchBarClass parent_class;
-};
-
-/* "preset" items */
-enum {
- /* preset menu options */
- E_FILTERBAR_SAVE_ID = -3,
- E_FILTERBAR_EDIT_ID = -4,
-
- /* preset option options */
- E_FILTERBAR_ADVANCED_ID = -5,
- E_FILTERBAR_CURRENT_FOLDER_ID = -7,
- E_FILTERBAR_CURRENT_ACCOUNT_ID = -8,
- E_FILTERBAR_ALL_ACCOUNTS_ID = -9
-};
-
-#define E_FILTERBAR_SAVE { (gchar *) N_("_Save Search..."), E_FILTERBAR_SAVE_ID, 0 }
-#define E_FILTERBAR_EDIT { (gchar *) N_("_Edit Saved Searches..."), E_FILTERBAR_EDIT_ID, 0 }
-#define E_FILTERBAR_ADVANCED { (gchar *) N_("_Advanced Search..."), E_FILTERBAR_ADVANCED_ID, 0 }
-#define E_FILTERBAR_ALL_ACCOUNTS { (gchar *) N_("All Accounts"), E_FILTERBAR_ALL_ACCOUNTS_ID, ESB_ITEMTYPE_RADIO }
-#define E_FILTERBAR_CURRENT_ACCOUNT { (gchar *) N_("Current Account"), E_FILTERBAR_CURRENT_ACCOUNT_ID, ESB_ITEMTYPE_RADIO }
-#define E_FILTERBAR_CURRENT_FOLDER { (gchar *) N_("Current Folder"), E_FILTERBAR_CURRENT_FOLDER_ID, ESB_ITEMTYPE_RADIO }
-#define E_FILTERBAR_SEPARATOR { NULL, 0, 0 }
-
-#ifdef JUST_FOR_TRANSLATORS
-const gchar * strings[] = {
- N_("_Save Search..."),
- N_("_Edit Saved Searches..."),
- N_("_Advanced Search...")
-};
-#endif
-
-GType e_filter_bar_get_type (void);
-
-EFilterBar *e_filter_bar_new (RuleContext *context,
- const gchar *systemrules,
- const gchar *userrules,
- EFilterBarConfigRule config,
- gpointer data);
-EFilterBar *e_filter_bar_lite_new (RuleContext *context,
- const gchar *systemrules,
- const gchar *userrules,
- EFilterBarConfigRule config,
- gpointer data);
-
-void
-e_filter_bar_new_construct (RuleContext *context,
- const gchar *systemrules,
- const gchar *userrules,
- EFilterBarConfigRule config,
- gpointer data ,EFilterBar *bar );
-
-G_END_DECLS
-
-#endif /* __E_FILTER_BAR_H__ */
diff --git a/widgets/misc/e-hinted-entry.c b/widgets/misc/e-hinted-entry.c
new file mode 100644
index 0000000000..ca75e85297
--- /dev/null
+++ b/widgets/misc/e-hinted-entry.c
@@ -0,0 +1,298 @@
+/*
+ * e-hinted-entry.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-hinted-entry.h"
+
+#define E_HINTED_ENTRY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_HINTED_ENTRY, EHintedEntryPrivate))
+
+struct _EHintedEntryPrivate {
+ gchar *hint;
+ guint hint_shown : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_HINT,
+ PROP_HINT_SHOWN
+};
+
+static gpointer parent_class;
+
+static void
+hinted_entry_hide_hint (EHintedEntry *entry)
+{
+ gtk_entry_set_text (GTK_ENTRY (entry), "");
+
+ gtk_widget_modify_text (GTK_WIDGET (entry), GTK_STATE_NORMAL, NULL);
+
+ entry->priv->hint_shown = FALSE;
+
+ g_object_notify (G_OBJECT (entry), "hint-shown");
+}
+
+static void
+hinted_entry_show_hint (EHintedEntry *entry)
+{
+ GtkStyle *style;
+ const GdkColor *color;
+ const gchar *hint;
+
+ hint = e_hinted_entry_get_hint (entry);
+ gtk_entry_set_text (GTK_ENTRY (entry), hint);
+
+ style = gtk_widget_get_style (GTK_WIDGET (entry));
+ color = &style->text[GTK_STATE_INSENSITIVE];
+ gtk_widget_modify_text (GTK_WIDGET (entry), GTK_STATE_NORMAL, color);
+
+ entry->priv->hint_shown = TRUE;
+
+ g_object_notify (G_OBJECT (entry), "hint-shown");
+}
+
+static void
+hinted_entry_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_HINT:
+ e_hinted_entry_set_hint (
+ E_HINTED_ENTRY (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+hinted_entry_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_HINT:
+ g_value_set_string (
+ value, e_hinted_entry_get_hint (
+ E_HINTED_ENTRY (object)));
+ return;
+
+ case PROP_HINT_SHOWN:
+ g_value_set_boolean (
+ value, e_hinted_entry_get_hint_shown (
+ E_HINTED_ENTRY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+hinted_entry_finalize (GObject *object)
+{
+ EHintedEntryPrivate *priv;
+
+ priv = E_HINTED_ENTRY_GET_PRIVATE (object);
+
+ g_free (priv->hint);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+hinted_entry_focus_in_event (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ EHintedEntry *entry = E_HINTED_ENTRY (widget);
+
+ if (e_hinted_entry_get_hint_shown (entry))
+ hinted_entry_hide_hint (entry);
+
+ /* Chain up to parent's focus_in_event() method. */
+ return GTK_WIDGET_CLASS (parent_class)->
+ focus_in_event (widget, event);
+}
+
+static gboolean
+hinted_entry_focus_out_event (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ EHintedEntry *entry = E_HINTED_ENTRY (widget);
+ const gchar *text;
+
+ text = e_hinted_entry_get_text (entry);
+
+ if (text == NULL || *text == '\0')
+ hinted_entry_show_hint (E_HINTED_ENTRY (widget));
+
+ /* Chain up to parent's focus_out_event() method. */
+ return GTK_WIDGET_CLASS (parent_class)->
+ focus_out_event (widget, event);
+}
+
+static void
+hinted_entry_class_init (EHintedEntryClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EHintedEntryPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = hinted_entry_set_property;
+ object_class->get_property = hinted_entry_get_property;
+ object_class->finalize = hinted_entry_finalize;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->focus_in_event = hinted_entry_focus_in_event;
+ widget_class->focus_out_event = hinted_entry_focus_out_event;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HINT,
+ g_param_spec_string (
+ "hint",
+ "Hint",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HINT_SHOWN,
+ g_param_spec_boolean (
+ "hint-shown",
+ "Hint Shown",
+ NULL,
+ FALSE,
+ G_PARAM_READABLE));
+}
+
+static void
+hinted_entry_init (EHintedEntry *entry)
+{
+ entry->priv = E_HINTED_ENTRY_GET_PRIVATE (entry);
+ entry->priv->hint = g_strdup (""); /* hint must never be NULL */
+}
+
+GType
+e_hinted_entry_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EHintedEntryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) hinted_entry_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EHintedEntry),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hinted_entry_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_ENTRY, "EHintedEntry", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_hinted_entry_new (void)
+{
+ return g_object_new (E_TYPE_HINTED_ENTRY, NULL);
+}
+
+const gchar *
+e_hinted_entry_get_hint (EHintedEntry *entry)
+{
+ g_return_val_if_fail (E_IS_HINTED_ENTRY (entry), NULL);
+
+ return entry->priv->hint;
+}
+
+void
+e_hinted_entry_set_hint (EHintedEntry *entry,
+ const gchar *hint)
+{
+ g_return_if_fail (E_IS_HINTED_ENTRY (entry));
+
+ if (hint == NULL)
+ hint = "";
+
+ g_free (entry->priv->hint);
+ entry->priv->hint = g_strdup (hint);
+
+ if (e_hinted_entry_get_hint_shown (entry))
+ gtk_entry_set_text (GTK_ENTRY (entry), hint);
+
+ g_object_notify (G_OBJECT (entry), "hint");
+}
+
+gboolean
+e_hinted_entry_get_hint_shown (EHintedEntry *entry)
+{
+ g_return_val_if_fail (E_IS_HINTED_ENTRY (entry), FALSE);
+
+ return entry->priv->hint_shown;
+}
+
+const gchar *
+e_hinted_entry_get_text (EHintedEntry *entry)
+{
+ /* XXX This clumsily overrides gtk_entry_get_text(). */
+
+ g_return_val_if_fail (E_IS_HINTED_ENTRY (entry), NULL);
+
+ if (e_hinted_entry_get_hint_shown (entry))
+ return "";
+
+ return gtk_entry_get_text (GTK_ENTRY (entry));
+}
+
+void
+e_hinted_entry_set_text (EHintedEntry *entry,
+ const gchar *text)
+{
+ /* XXX This clumsily overrides gtk_entry_set_text(). */
+
+ g_return_if_fail (E_IS_HINTED_ENTRY (entry));
+
+ if (text == NULL)
+ text = "";
+
+ if (*text == '\0' && !GTK_WIDGET_HAS_FOCUS (entry))
+ hinted_entry_show_hint (entry);
+ else {
+ hinted_entry_hide_hint (entry);
+ gtk_entry_set_text (GTK_ENTRY (entry), text);
+ }
+}
diff --git a/widgets/misc/e-hinted-entry.h b/widgets/misc/e-hinted-entry.h
new file mode 100644
index 0000000000..02379d4ad7
--- /dev/null
+++ b/widgets/misc/e-hinted-entry.h
@@ -0,0 +1,73 @@
+/*
+ * e-hinted-entry.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_HINTED_ENTRY_H
+#define E_HINTED_ENTRY_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_HINTED_ENTRY \
+ (e_hinted_entry_get_type ())
+#define E_HINTED_ENTRY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_HINTED_ENTRY, EHintedEntry))
+#define E_HINTED_ENTRY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_HINTED_ENTRY, EHintedEntryClass))
+#define E_IS_HINTED_ENTRY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_HINTED_ENTRY))
+#define E_IS_HINTED_ENTRY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_HINTED_ENTRY))
+#define E_HINTED_ENTRY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_HINTED_ENTRY, EHintedEntryClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EHintedEntry EHintedEntry;
+typedef struct _EHintedEntryClass EHintedEntryClass;
+typedef struct _EHintedEntryPrivate EHintedEntryPrivate;
+
+struct _EHintedEntry {
+ GtkEntry parent;
+ EHintedEntryPrivate *priv;
+};
+
+struct _EHintedEntryClass {
+ GtkEntryClass parent_class;
+};
+
+GType e_hinted_entry_get_type (void);
+GtkWidget * e_hinted_entry_new (void);
+const gchar * e_hinted_entry_get_hint (EHintedEntry *entry);
+void e_hinted_entry_set_hint (EHintedEntry *entry,
+ const gchar *hint);
+gboolean e_hinted_entry_get_hint_shown (EHintedEntry *entry);
+const gchar * e_hinted_entry_get_text (EHintedEntry *entry);
+void e_hinted_entry_set_text (EHintedEntry *entry,
+ const gchar *text);
+
+G_END_DECLS
+
+#endif /* E_HINTED_ENTRY_H */
diff --git a/widgets/misc/e-icon-entry.c b/widgets/misc/e-icon-entry.c
deleted file mode 100644
index 87b89f61d5..0000000000
--- a/widgets/misc/e-icon-entry.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * e-icon-entry.c
- *
- * Author: Johnny Jacob <jjohnny@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * Copyright (C) 2003, 2004, 2005 Christian Persch
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Adapted and modified from gtk+ code:
- *
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- * Modified by the GTK+ Team and others 1997-2005. See the AUTHORS
- * file in the gtk+ distribution for a list of people on the GTK+ Team.
- * See the ChangeLog in the gtk+ distribution files for a list of changes.
- * These files are distributed with GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- *
- */
-
-#include "config.h"
-
-#include "e-icon-entry.h"
-
-#define E_ICON_ENTRY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), E_TYPE_ICON_ENTRY, EIconEntryPrivate))
-
-struct _EIconEntryPrivate
-{
- GtkWidget *hbox;
-};
-
-static GtkWidgetClass *parent_class = NULL;
-
-/* private helper functions */
-
-static gboolean
-entry_focus_change_cb (GtkWidget *widget,
- GdkEventFocus *event,
- GtkWidget *entry)
-{
- gtk_widget_queue_draw (entry);
-
- return FALSE;
-}
-
-static void
-e_icon_entry_get_borders (GtkWidget *widget,
- GtkWidget *entry,
- gint *xborder,
- gint *yborder)
-{
- gint focus_width;
- gboolean interior_focus;
-
- g_return_if_fail (entry->style != NULL);
-
- gtk_widget_style_get (entry,
- "focus-line-width", &focus_width,
- "interior-focus", &interior_focus,
- NULL);
-
- *xborder = entry->style->xthickness;
- *yborder = entry->style->ythickness;
-
- if (!interior_focus)
- {
- *xborder += focus_width;
- *yborder += focus_width;
- }
-}
-
-static void
-e_icon_entry_paint (GtkWidget *widget,
- GdkEventExpose *event)
-{
- EIconEntry *entry = E_ICON_ENTRY (widget);
- GtkWidget *entry_widget = entry->entry;
- gint x = 0, y = 0, width, height, focus_width;
- gboolean interior_focus;
-
- gtk_widget_style_get (entry_widget,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_width,
- NULL);
-
- gdk_drawable_get_size (widget->window, &width, &height);
-
- if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus)
- {
- x += focus_width;
- y += focus_width;
- width -= 2 * focus_width;
- height -= 2 * focus_width;
- }
-
- gtk_paint_flat_box (entry_widget->style, widget->window,
- GTK_WIDGET_STATE (entry_widget), GTK_SHADOW_NONE,
- NULL, entry_widget, "entry_bg",
- /* FIXME: was 0, 0 in gtk_entry_expose, but I think this is correct: */
- x, y, width, height);
-
- gtk_paint_shadow (entry_widget->style, widget->window,
- GTK_STATE_NORMAL, GTK_SHADOW_IN,
- NULL, entry_widget, "entry",
- x, y, width, height);
-
- if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus)
- {
- x -= focus_width;
- y -= focus_width;
- width += 2 * focus_width;
- height += 2 * focus_width;
-
- gtk_paint_focus (entry_widget->style, widget->window,
- GTK_WIDGET_STATE (entry_widget),
- NULL, entry_widget, "entry",
- /* FIXME: was 0, 0 in gtk_entry_draw_frame, but I think this is correct: */
- x, y, width, height);
- }
-}
-
-/* Class implementation */
-
-static void
-e_icon_entry_init (EIconEntry *entry)
-{
- EIconEntryPrivate *priv;
- GtkWidget *widget = (GtkWidget *) entry;
-
- priv = entry->priv = E_ICON_ENTRY_GET_PRIVATE (entry);
-
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_WINDOW);
-
- priv->hbox = gtk_hbox_new (FALSE, /* FIXME */ 0);
- gtk_container_add (GTK_CONTAINER (entry), priv->hbox);
-
- entry->entry = gtk_entry_new ();
- gtk_entry_set_has_frame (GTK_ENTRY (entry->entry), FALSE);
- gtk_box_pack_start (GTK_BOX (priv->hbox), entry->entry, TRUE, TRUE, /* FIXME */ 0);
-
- /* We need to queue a redraw when focus changes, to comply with themes
- * (like Clearlooks) which draw focused and unfocused entries differently.
- */
- g_signal_connect_after (entry->entry, "focus-in-event",
- G_CALLBACK (entry_focus_change_cb), entry);
- g_signal_connect_after (entry->entry, "focus-out-event",
- G_CALLBACK (entry_focus_change_cb), entry);
-}
-
-static void
-e_icon_entry_realize (GtkWidget *widget)
-{
- GdkWindowAttr attributes;
- gint attributes_mask;
- gint border_width;
-
- GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-
- border_width = GTK_CONTAINER (widget)->border_width;
-
- attributes.x = widget->allocation.x + border_width;
- attributes.y = widget->allocation.y + border_width;
- attributes.width = widget->allocation.width - 2 * border_width;
- attributes.height = widget->allocation.height - 2 * border_width;
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.event_mask = gtk_widget_get_events (widget)
- | GDK_EXPOSURE_MASK;
-
- attributes.visual = gtk_widget_get_visual (widget);
- attributes.colormap = gtk_widget_get_colormap (widget);
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-
- widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
- &attributes, attributes_mask);
- gdk_window_set_user_data (widget->window, widget);
-
- widget->style = gtk_style_attach (widget->style, widget->window);
-
- gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
-}
-
-static void
-e_icon_entry_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- EIconEntry *entry = E_ICON_ENTRY (widget);
- GtkContainer *container = GTK_CONTAINER (widget);
- GtkBin *bin = GTK_BIN (widget);
- gint xborder, yborder;
-
- requisition->width = requisition->height = container->border_width * 2;
-
- gtk_widget_ensure_style (entry->entry);
- e_icon_entry_get_borders (widget, entry->entry, &xborder, &yborder);
-
- if (GTK_WIDGET_VISIBLE (bin->child))
- {
- GtkRequisition child_requisition;
-
- gtk_widget_size_request (bin->child, &child_requisition);
- requisition->width += child_requisition.width;
- requisition->height += child_requisition.height;
- }
-
- requisition->width += 2 * xborder;
- requisition->height += 2 * yborder;
-}
-
-static void
-e_icon_entry_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- EIconEntry *entry = E_ICON_ENTRY (widget);
- GtkContainer *container = GTK_CONTAINER (widget);
- GtkBin *bin = GTK_BIN (widget);
- GtkAllocation child_allocation;
- gint xborder, yborder;
-
- widget->allocation = *allocation;
-
- e_icon_entry_get_borders (widget, entry->entry, &xborder, &yborder);
-
- if (GTK_WIDGET_REALIZED (widget))
- {
- child_allocation.x = container->border_width;
- child_allocation.y = container->border_width;
- child_allocation.width = MAX (allocation->width - container->border_width * 2, 0);
- child_allocation.height = MAX (allocation->height - container->border_width * 2, 0);
-
- gdk_window_move_resize (widget->window,
- allocation->x + child_allocation.x,
- allocation->y + child_allocation.y,
- child_allocation.width,
- child_allocation.height);
- }
-
- child_allocation.x = container->border_width + xborder;
- child_allocation.y = container->border_width + yborder;
- child_allocation.width = MAX (allocation->width - (container->border_width + xborder) * 2, 0);
- child_allocation.height = MAX (allocation->height - (container->border_width + yborder) * 2, 0);
-
- gtk_widget_size_allocate (bin->child, &child_allocation);
-}
-
-static gboolean
-e_icon_entry_expose (GtkWidget *widget,
- GdkEventExpose *event)
-{
- if (GTK_WIDGET_DRAWABLE (widget) &&
- event->window == widget->window)
- {
- e_icon_entry_paint (widget, event);
- }
-
- return parent_class->expose_event (widget, event);
-}
-
-static void
-e_icon_entry_class_init (EIconEntryClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- parent_class = GTK_WIDGET_CLASS (g_type_class_peek_parent (klass));
-
- widget_class->realize = e_icon_entry_realize;
- widget_class->size_request = e_icon_entry_size_request;
- widget_class->size_allocate = e_icon_entry_size_allocate;
- widget_class->expose_event = e_icon_entry_expose;
-
- g_type_class_add_private (object_class, sizeof (EIconEntryPrivate));
-}
-
-GType
-e_icon_entry_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0))
- {
- static const GTypeInfo our_info =
- {
- sizeof (EIconEntryClass),
- NULL,
- NULL,
- (GClassInitFunc) e_icon_entry_class_init,
- NULL,
- NULL,
- sizeof (EIconEntry),
- 0,
- (GInstanceInitFunc) e_icon_entry_init
- };
-
- type = g_type_register_static (GTK_TYPE_BIN,
- "EIconEntry",
- &our_info, 0);
- }
-
- return type;
-}
-
-/* public functions */
-
-GtkWidget *
-e_icon_entry_new (void)
-{
- return GTK_WIDGET (g_object_new (E_TYPE_ICON_ENTRY, NULL));
-}
-
-void
-e_icon_entry_pack_widget (EIconEntry *entry,
- GtkWidget *widget,
- gboolean start)
-{
- EIconEntryPrivate *priv;
-
- g_return_if_fail (E_IS_ICON_ENTRY (entry));
-
- priv = entry->priv;
-
- if (start)
- {
- gtk_box_pack_start (GTK_BOX (priv->hbox), widget, FALSE, FALSE, /* FIXME */ 2);
- gtk_box_reorder_child (GTK_BOX (priv->hbox), widget, 0);
- }
- else
- {
- gtk_box_pack_end (GTK_BOX (priv->hbox), widget, FALSE, FALSE, /* FIXME */ 2);
- }
-}
-
-static void
-set_cursor (GtkWidget *widget, GdkEventCrossing *event, gpointer dummy)
-{
-
- if (event->type == GDK_ENTER_NOTIFY)
- gdk_window_set_cursor (widget->window, gdk_cursor_new (GDK_HAND1));
- else
- gdk_window_set_cursor (widget->window, gdk_cursor_new (GDK_LEFT_PTR));
-
-}
-
-GtkWidget *
-e_icon_entry_create_button (const gchar *stock)
-{
- GtkWidget *eventbox;
- GtkWidget *image;
-
- eventbox = gtk_event_box_new ();
- gtk_container_set_border_width (GTK_CONTAINER (eventbox), 2);
- gtk_event_box_set_visible_window (GTK_EVENT_BOX (eventbox), FALSE);
-
- image = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU);
- gtk_container_add (GTK_CONTAINER (eventbox), image);
-
- g_signal_connect_after (eventbox, "enter-notify-event", (GCallback) set_cursor, NULL);
- g_signal_connect_after (eventbox, "leave-notify-event", (GCallback) set_cursor, NULL);
-
- return eventbox;
-}
-
-GtkWidget *
-e_icon_entry_create_text (const gchar *text)
-{
- GtkWidget *eventbox;
- GtkWidget *image;
-
- eventbox = gtk_event_box_new ();
- gtk_container_set_border_width (GTK_CONTAINER (eventbox), 2);
- gtk_event_box_set_visible_window (GTK_EVENT_BOX (eventbox), FALSE);
-
- image = gtk_label_new (text);
- gtk_container_add (GTK_CONTAINER (eventbox), image);
- g_object_set_data ((GObject *)eventbox, "lbl", image);
- g_signal_connect_after (eventbox, "enter-notify-event", (GCallback) set_cursor, NULL);
- g_signal_connect_after (eventbox, "leave-notify-event", (GCallback) set_cursor, NULL);
-
- return eventbox;
-}
-
-GtkWidget *
-e_icon_entry_create_separator ()
-{
- GtkWidget *eventbox;
- GtkWidget *image;
-
- eventbox = gtk_event_box_new ();
- gtk_container_set_border_width (GTK_CONTAINER (eventbox), 0);
- gtk_event_box_set_visible_window (GTK_EVENT_BOX (eventbox), FALSE);
-
- image = (GtkWidget *)gtk_separator_tool_item_new ();
- gtk_container_add (GTK_CONTAINER (eventbox), image);
-
- return eventbox;
-}
-
-GtkWidget *
-e_icon_entry_get_entry (EIconEntry *entry)
-{
- g_return_val_if_fail (E_IS_ICON_ENTRY (entry), NULL);
-
- return entry->entry;
-}
diff --git a/widgets/misc/e-icon-entry.h b/widgets/misc/e-icon-entry.h
deleted file mode 100644
index cde735ba6f..0000000000
--- a/widgets/misc/e-icon-entry.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * e-icon-entry.h
- *
- * Authors: Johnny Jacob <jjohnny@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * Adapted and modified from Epiphany.
- *
- * Copyright (C) 2003, 2004, 2005 Christian Persch
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Adapted and modified from gtk+ code:
- *
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
- * file in the gtk+ distribution for a list of people on the GTK+ Team.
- * See the ChangeLog in the gtk+ distribution files for a list of changes.
- * These files are distributed with GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- *
- */
-
-#ifndef E_ICON_ENTRY_H
-#define E_ICON_ENTRY_H
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_ICON_ENTRY (e_icon_entry_get_type())
-#define E_ICON_ENTRY(object) (G_TYPE_CHECK_INSTANCE_CAST((object), E_TYPE_ICON_ENTRY, EIconEntry))
-#define E_ICON_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), E_TYPE_ICON_ENTRY, EIconEntryClass))
-#define E_IS_ICON_ENTRY(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), E_TYPE_ICON_ENTRY))
-#define E_IS_ICON_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), E_TYPE_ICON_ENTRY))
-#define E_ICON_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), E_TYPE_ICON_ENTRY, EIconEntryClass))
-
-typedef struct _EIconEntryClass EIconEntryClass;
-typedef struct _EIconEntry EIconEntry;
-typedef struct _EIconEntryPrivate EIconEntryPrivate;
-
-struct _EIconEntryClass
-{
- GtkBinClass parent_class;
-};
-
-struct _EIconEntry
-{
- GtkBin parent_object;
-
- /*< public >*/
- GtkWidget *entry;
-
- /*< private >*/
- EIconEntryPrivate *priv;
-};
-
-GType e_icon_entry_get_type (void);
-
-GtkWidget *e_icon_entry_new (void);
-
-void e_icon_entry_pack_widget (EIconEntry *entry,
- GtkWidget *widget,
- gboolean start);
-
-GtkWidget *e_icon_entry_get_entry (EIconEntry *entry);
-
-GtkWidget *e_icon_entry_create_button (const gchar *stock);
-GtkWidget * e_icon_entry_create_text (const gchar *text);
-GtkWidget * e_icon_entry_create_separator (void);
-
-G_END_DECLS
-
-#endif
diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c
index e5a20e5303..32a3f2a899 100644
--- a/widgets/misc/e-image-chooser.c
+++ b/widgets/misc/e-image-chooser.c
@@ -1,4 +1,6 @@
/*
+ * e-image-chooser.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,9 +15,6 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Chris Toshok <toshok@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
@@ -28,23 +27,20 @@
#include <glib/gi18n.h>
#include "e-image-chooser.h"
-#include "e-util/e-icon-factory.h"
#include "e-util/e-util.h"
-#define d(x)
+#define E_IMAGE_CHOOSER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooserPrivate))
struct _EImageChooserPrivate {
-
GtkWidget *frame;
GtkWidget *image;
- GtkWidget *browse_button;
gchar *image_buf;
- gint image_buf_size;
- gint image_width;
- gint image_height;
-
- gboolean editable;
+ gint image_buf_size;
+ gint image_width;
+ gint image_height;
};
enum {
@@ -52,182 +48,24 @@ enum {
LAST_SIGNAL
};
-static gint image_chooser_signals [LAST_SIGNAL] = { 0 };
-
-static void e_image_chooser_init (EImageChooser *chooser);
-static void e_image_chooser_class_init (EImageChooserClass *klass);
-#if 0
-static void e_image_chooser_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void e_image_chooser_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-#endif
-static void e_image_chooser_dispose (GObject *object);
-
-static gboolean image_drag_motion_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y, guint time, EImageChooser *chooser);
-static void image_drag_leave_cb (GtkWidget *widget,
- GdkDragContext *context,
- guint time, EImageChooser *chooser);
-static gboolean image_drag_drop_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y, guint time, EImageChooser *chooser);
-static void image_drag_data_received_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data,
- guint info, guint time, EImageChooser *chooser);
-
-static GtkObjectClass *parent_class = NULL;
-#define PARENT_TYPE GTK_TYPE_VBOX
-
-enum DndTargetType {
- DND_TARGET_TYPE_URI_LIST
-};
-#define URI_LIST_TYPE "text/uri-list"
-
-static GtkTargetEntry image_drag_types[] = {
- { (gchar *) URI_LIST_TYPE, 0, DND_TARGET_TYPE_URI_LIST },
-};
-static const gint num_image_drag_types = sizeof (image_drag_types) / sizeof (image_drag_types[0]);
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
-GtkWidget *
-e_image_chooser_new (void)
-{
- return g_object_new (E_TYPE_IMAGE_CHOOSER, NULL);
-}
-
-GType
-e_image_chooser_get_type (void)
-{
- static GType eic_type = 0;
-
- if (!eic_type) {
- static const GTypeInfo eic_info = {
- sizeof (EImageChooserClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_image_chooser_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EImageChooser),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_image_chooser_init,
- };
-
- eic_type = g_type_register_static (PARENT_TYPE, "EImageChooser", &eic_info, 0);
- }
-
- return eic_type;
-}
-
-static void
-e_image_chooser_class_init (EImageChooserClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_ref (PARENT_TYPE);
-
- image_chooser_signals [CHANGED] =
- g_signal_new ("changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EImageChooserClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- /*
- object_class->set_property = e_image_chooser_set_property;
- object_class->get_property = e_image_chooser_get_property;
- */
- object_class->dispose = e_image_chooser_dispose;
-}
-
-#ifdef UI_CHANGE_OK
-static void
-browse_for_image_cb (GtkWidget *button, gpointer data)
-{
-}
-#endif
-
-static void
-e_image_chooser_init (EImageChooser *chooser)
-{
- EImageChooserPrivate *priv;
- GtkWidget *alignment;
-
- priv = chooser->priv = g_new0 (EImageChooserPrivate, 1);
-
- alignment = gtk_alignment_new (0, 0, 0, 0);
- priv->frame = gtk_frame_new ("");
- priv->image = gtk_image_new ();
-
- gtk_container_add (GTK_CONTAINER (alignment), priv->image);
-
-#ifdef UI_CHANGE_OK
- priv->browse_button = gtk_button_new_with_label (_("Choose Image"));
-#endif
-
- gtk_frame_set_shadow_type (GTK_FRAME (priv->frame), GTK_SHADOW_NONE);
-
- gtk_container_add (GTK_CONTAINER (priv->frame), alignment);
- gtk_box_set_homogeneous (GTK_BOX (chooser), FALSE);
- gtk_box_pack_start (GTK_BOX (chooser), priv->frame, TRUE, TRUE, 0);
-#ifdef UI_CHANGE_OK
- gtk_box_pack_start (GTK_BOX (chooser), priv->browse_button, FALSE, FALSE, 0);
-
- g_signal_connect (priv->browse_button, "clicked", G_CALLBACK (browse_for_image_cb), NULL);
-#endif
-
- gtk_drag_dest_set (priv->image, 0, image_drag_types, num_image_drag_types, GDK_ACTION_COPY);
- g_signal_connect (priv->image,
- "drag_motion", G_CALLBACK (image_drag_motion_cb), chooser);
- g_signal_connect (priv->image,
- "drag_leave", G_CALLBACK (image_drag_leave_cb), chooser);
- g_signal_connect (priv->image,
- "drag_drop", G_CALLBACK (image_drag_drop_cb), chooser);
- g_signal_connect (priv->image,
- "drag_data_received", G_CALLBACK (image_drag_data_received_cb), chooser);
-
- gtk_widget_show_all (priv->frame);
-#ifdef UI_CHANGE_OK
- gtk_widget_show (priv->browse_button);
-#endif
-
- /* we default to being editable */
- priv->editable = TRUE;
-}
-
-static void
-e_image_chooser_dispose (GObject *object)
-{
- EImageChooser *eic = E_IMAGE_CHOOSER (object);
-
- if (eic->priv) {
- EImageChooserPrivate *priv = eic->priv;
-
- if (priv->image_buf) {
- g_free (priv->image_buf);
- priv->image_buf = NULL;
- }
-
- g_free (eic->priv);
- eic->priv = NULL;
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
-}
+#define URI_LIST_TYPE "text/uri-list"
static gboolean
set_image_from_data (EImageChooser *chooser,
- gchar *data, gint length)
+ gchar *data,
+ gint length)
{
- gboolean rv = FALSE;
- GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
+ GdkPixbufLoader *loader;
GdkPixbuf *pixbuf;
+ gfloat scale;
+ gint new_height;
+ gint new_width;
- gdk_pixbuf_loader_write (loader, (guchar *)data, length, NULL);
+ loader = gdk_pixbuf_loader_new ();
+ gdk_pixbuf_loader_write (loader, (guchar *) data, length, NULL);
gdk_pixbuf_loader_close (loader, NULL);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
@@ -236,98 +74,92 @@ set_image_from_data (EImageChooser *chooser,
g_object_unref (loader);
- if (pixbuf) {
- GdkPixbuf *scaled;
- GdkPixbuf *composite;
-
- gfloat scale;
- gint new_height, new_width;
-
- new_height = gdk_pixbuf_get_height (pixbuf);
- new_width = gdk_pixbuf_get_width (pixbuf);
-
- d (printf ("new dimensions = (%d,%d)\n", new_width, new_height));
-
- if (chooser->priv->image_height == 0
- && chooser->priv->image_width == 0) {
- d (printf ("initial setting of an image. no scaling\n"));
- scale = 1.0;
- }
- else if (chooser->priv->image_height < new_height
- || chooser->priv->image_width < new_width) {
- /* we need to scale down */
- d (printf ("we need to scale down\n"));
- if (new_height > new_width)
- scale = (gfloat)chooser->priv->image_height / new_height;
- else
- scale = (gfloat)chooser->priv->image_width / new_width;
- }
- else {
- /* we need to scale up */
- d (printf ("we need to scale up\n"));
- if (new_height > new_width)
- scale = (gfloat)new_height / chooser->priv->image_height;
- else
- scale = (gfloat)new_width / chooser->priv->image_width;
- }
-
- d (printf ("scale = %g\n", scale));
+ if (pixbuf == NULL)
+ return FALSE;
- if (scale == 1.0) {
- gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image), pixbuf);
+ new_height = gdk_pixbuf_get_height (pixbuf);
+ new_width = gdk_pixbuf_get_width (pixbuf);
+
+ if (chooser->priv->image_height == 0
+ && chooser->priv->image_width == 0) {
+ scale = 1.0;
+ } else if (chooser->priv->image_height < new_height
+ || chooser->priv->image_width < new_width) {
+ /* we need to scale down */
+ if (new_height > new_width)
+ scale = (gfloat)chooser->priv->image_height / new_height;
+ else
+ scale = (gfloat)chooser->priv->image_width / new_width;
+ } else {
+ /* we need to scale up */
+ if (new_height > new_width)
+ scale = (gfloat)new_height / chooser->priv->image_height;
+ else
+ scale = (gfloat)new_width / chooser->priv->image_width;
+ }
- chooser->priv->image_width = new_width;
- chooser->priv->image_height = new_height;
- }
- else {
- new_width *= scale;
- new_height *= scale;
- new_width = MIN (new_width, chooser->priv->image_width);
- new_height = MIN (new_height, chooser->priv->image_height);
+ if (scale == 1.0) {
+ gtk_image_set_from_pixbuf (
+ GTK_IMAGE (chooser->priv->image), pixbuf);
+ chooser->priv->image_width = new_width;
+ chooser->priv->image_height = new_height;
+ } else {
+ GdkPixbuf *scaled;
+ GdkPixbuf *composite;
- d (printf ("new scaled dimensions = (%d,%d)\n", new_width, new_height));
+ new_width *= scale;
+ new_height *= scale;
+ new_width = MIN (new_width, chooser->priv->image_width);
+ new_height = MIN (new_height, chooser->priv->image_height);
- scaled = e_icon_factory_pixbuf_scale (pixbuf, new_width, new_height);
+ scaled = gdk_pixbuf_scale_simple (
+ pixbuf, new_width, new_height,
+ GDK_INTERP_BILINEAR);
- composite = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, gdk_pixbuf_get_bits_per_sample (pixbuf),
- chooser->priv->image_width, chooser->priv->image_height);
+ composite = gdk_pixbuf_new (
+ GDK_COLORSPACE_RGB, TRUE,
+ gdk_pixbuf_get_bits_per_sample (pixbuf),
+ chooser->priv->image_width,
+ chooser->priv->image_height);
- gdk_pixbuf_fill (composite, 0x00000000);
+ gdk_pixbuf_fill (composite, 0x00000000);
- gdk_pixbuf_copy_area (scaled, 0, 0, new_width, new_height,
- composite,
- chooser->priv->image_width / 2 - new_width / 2,
- chooser->priv->image_height / 2 - new_height / 2);
+ gdk_pixbuf_copy_area (
+ scaled, 0, 0, new_width, new_height,
+ composite,
+ chooser->priv->image_width / 2 - new_width / 2,
+ chooser->priv->image_height / 2 - new_height / 2);
- gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image), composite);
- g_object_unref (scaled);
- g_object_unref (composite);
- }
+ gtk_image_set_from_pixbuf (
+ GTK_IMAGE (chooser->priv->image), composite);
- g_object_unref (pixbuf);
+ g_object_unref (scaled);
+ g_object_unref (composite);
+ }
- g_free (chooser->priv->image_buf);
- chooser->priv->image_buf = data;
- chooser->priv->image_buf_size = length;
+ g_object_unref (pixbuf);
- g_signal_emit (chooser,
- image_chooser_signals [CHANGED], 0);
+ g_free (chooser->priv->image_buf);
+ chooser->priv->image_buf = data;
+ chooser->priv->image_buf_size = length;
- rv = TRUE;
- }
+ g_signal_emit (chooser, signals[CHANGED], 0);
- return rv;
+ return TRUE;
}
static gboolean
image_drag_motion_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y, guint time, EImageChooser *chooser)
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ EImageChooser *chooser)
{
+ GtkFrame *frame;
GList *p;
- if (!chooser->priv->editable)
- return FALSE;
+ frame = GTK_FRAME (chooser->priv->frame);
for (p = context->targets; p != NULL; p = p->next) {
gchar *possible_type;
@@ -336,37 +168,45 @@ image_drag_motion_cb (GtkWidget *widget,
if (!strcmp (possible_type, URI_LIST_TYPE)) {
g_free (possible_type);
gdk_drag_status (context, GDK_ACTION_COPY, time);
- gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_IN);
+ gtk_frame_set_shadow_type (frame, GTK_SHADOW_IN);
return TRUE;
}
g_free (possible_type);
}
- gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
+ gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE);
+
return FALSE;
}
static void
image_drag_leave_cb (GtkWidget *widget,
- GdkDragContext *context,
- guint time, EImageChooser *chooser)
+ GdkDragContext *context,
+ guint time,
+ EImageChooser *chooser)
{
- gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
+ GtkFrame *frame;
+
+ frame = GTK_FRAME (chooser->priv->frame);
+ gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE);
}
static gboolean
image_drag_drop_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y, guint time, EImageChooser *chooser)
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ EImageChooser *chooser)
{
+ GtkFrame *frame;
GList *p;
- if (!chooser->priv->editable)
- return FALSE;
+ frame = GTK_FRAME (chooser->priv->frame);
if (context->targets == NULL) {
- gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
+ gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE);
return FALSE;
}
@@ -376,77 +216,205 @@ image_drag_drop_cb (GtkWidget *widget,
possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
if (!strcmp (possible_type, URI_LIST_TYPE)) {
g_free (possible_type);
- gtk_drag_get_data (widget, context,
- GDK_POINTER_TO_ATOM (p->data),
- time);
- gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
+ gtk_drag_get_data (
+ widget, context,
+ GDK_POINTER_TO_ATOM (p->data), time);
+ gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE);
return TRUE;
}
g_free (possible_type);
}
- gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
+ gtk_frame_set_shadow_type (frame, GTK_SHADOW_NONE);
+
return FALSE;
}
static void
image_drag_data_received_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data,
- guint info, guint time, EImageChooser *chooser)
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ EImageChooser *chooser)
{
- gchar *target_type;
gboolean handled = FALSE;
+ gchar **uris;
+ gchar *buf = NULL;
+ gsize read = 0;
+ GError *error = NULL;
- target_type = gdk_atom_name (selection_data->target);
+ uris = gtk_selection_data_get_uris (selection_data);
- if (!strcmp (target_type, URI_LIST_TYPE)) {
- GError *error = NULL;
- gchar *uri;
- gchar *nl = strstr ((gchar *)selection_data->data, "\r\n");
- gchar *buf = NULL;
- gsize read = 0;
+ if (uris == NULL)
+ goto exit;
- if (nl)
- uri = g_strndup ((gchar *)selection_data->data, nl - (gchar *)selection_data->data);
- else
- uri = g_strdup ((gchar *)selection_data->data);
+ if (e_util_read_file (uris[0], TRUE, &buf, &read, &error) && read > 0 && buf)
+ handled = set_image_from_data (chooser, buf, read);
- if (e_util_read_file (uri, TRUE, &buf, &read, &error) && read > 0 && buf) {
- if (set_image_from_data (chooser, buf, read)) {
- handled = TRUE;
- }
- }
+ if (!handled)
+ g_free (buf);
- if (!handled)
- g_free (buf);
- g_free (uri);
+ g_strfreev (uris);
- if (error) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
+ if (error) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
+exit:
gtk_drag_finish (context, handled, FALSE, time);
}
-
+static void
+image_chooser_dispose (GObject *object)
+{
+ EImageChooserPrivate *priv;
+
+ priv = E_IMAGE_CHOOSER_GET_PRIVATE (object);
+
+ if (priv->frame != NULL) {
+ g_object_unref (priv->frame);
+ priv->frame = NULL;
+ }
+
+ if (priv->image != NULL) {
+ g_object_unref (priv->image);
+ priv->image = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+image_chooser_finalize (GObject *object)
+{
+ EImageChooserPrivate *priv;
+
+ priv = E_IMAGE_CHOOSER_GET_PRIVATE (object);
+
+ g_free (priv->image_buf);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+e_image_chooser_class_init (EImageChooserClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EImageChooserPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = image_chooser_dispose;
+ object_class->finalize = image_chooser_finalize;
+
+ signals[CHANGED] = g_signal_new (
+ "changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EImageChooserClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_image_chooser_init (EImageChooser *chooser)
+{
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ chooser->priv = E_IMAGE_CHOOSER_GET_PRIVATE (chooser);
+
+ container = GTK_WIDGET (chooser);
+
+ widget = gtk_frame_new ("");
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_NONE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ chooser->priv->frame = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_alignment_new (0, 0, 0, 0);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_image_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ chooser->priv->image = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ gtk_drag_dest_set (widget, 0, NULL, 0, GDK_ACTION_COPY);
+ gtk_drag_dest_add_uri_targets (widget);
+
+ g_signal_connect (
+ widget, "drag-motion",
+ G_CALLBACK (image_drag_motion_cb), chooser);
+ g_signal_connect (
+ widget, "drag-leave",
+ G_CALLBACK (image_drag_leave_cb), chooser);
+ g_signal_connect (
+ widget, "drag-drop",
+ G_CALLBACK (image_drag_drop_cb), chooser);
+ g_signal_connect (
+ widget, "drag-data-received",
+ G_CALLBACK (image_drag_data_received_cb), chooser);
+}
+
+GType
+e_image_chooser_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EImageChooserClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) e_image_chooser_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EImageChooser),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) e_image_chooser_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_VBOX, "EImageChooser", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_image_chooser_new (void)
+{
+ return g_object_new (E_TYPE_IMAGE_CHOOSER, NULL);
+}
gboolean
-e_image_chooser_set_from_file (EImageChooser *chooser, const gchar *filename)
+e_image_chooser_set_from_file (EImageChooser *chooser,
+ const gchar *filename)
{
gchar *data;
gsize data_length;
g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE);
- g_return_val_if_fail (filename, FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
- if (!g_file_get_contents (filename, &data, &data_length, NULL)) {
+ if (!g_file_get_contents (filename, &data, &data_length, NULL))
return FALSE;
- }
if (!set_image_from_data (chooser, data, data_length))
g_free (data);
@@ -454,18 +422,10 @@ e_image_chooser_set_from_file (EImageChooser *chooser, const gchar *filename)
return TRUE;
}
-void
-e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable)
-{
- g_return_if_fail (E_IS_IMAGE_CHOOSER (chooser));
-
- chooser->priv->editable = editable;
-
- gtk_widget_set_sensitive (chooser->priv->browse_button, editable);
-}
-
gboolean
-e_image_chooser_get_image_data (EImageChooser *chooser, gchar **data, gsize *data_length)
+e_image_chooser_get_image_data (EImageChooser *chooser,
+ gchar **data,
+ gsize *data_length)
{
g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE);
g_return_val_if_fail (data != NULL, FALSE);
@@ -479,7 +439,9 @@ e_image_chooser_get_image_data (EImageChooser *chooser, gchar **data, gsize *dat
}
gboolean
-e_image_chooser_set_image_data (EImageChooser *chooser, gchar *data, gsize data_length)
+e_image_chooser_set_image_data (EImageChooser *chooser,
+ gchar *data,
+ gsize data_length)
{
gchar *buf;
diff --git a/widgets/misc/e-image-chooser.h b/widgets/misc/e-image-chooser.h
index ece1419633..7116500dc4 100644
--- a/widgets/misc/e-image-chooser.h
+++ b/widgets/misc/e-image-chooser.h
@@ -1,4 +1,5 @@
/*
+ * e-image-chooser.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,53 +15,61 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Chris Toshok <toshok@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef _E_IMAGE_CHOOSER_H_
-#define _E_IMAGE_CHOOSER_H_
+#ifndef E_IMAGE_CHOOSER_H
+#define E_IMAGE_CHOOSER_H
#include <gtk/gtk.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_IMAGE_CHOOSER \
+ (e_image_chooser_get_type ())
+#define E_IMAGE_CHOOSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser))
+#define E_IMAGE_CHOOSER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_IMAGE_CHOOSER, EImageChooserClass))
+#define E_IS_IMAGE_CHOOSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_IMAGE_CHOOSER))
+#define E_IS_IMAGE_CHOOSER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_IMAGE_CHOOSER))
+#define E_IMAGE_CHOOSER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooserClass))
-#define E_TYPE_IMAGE_CHOOSER (e_image_chooser_get_type ())
-#define E_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser))
-#define E_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_IMAGE_CHOOSER, EImageChooserClass))
-#define E_IS_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_IMAGE_CHOOSER))
-#define E_IS_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_IMAGE_CHOOSER))
+G_BEGIN_DECLS
-typedef struct _EImageChooser EImageChooser;
-typedef struct _EImageChooserClass EImageChooserClass;
+typedef struct _EImageChooser EImageChooser;
+typedef struct _EImageChooserClass EImageChooserClass;
typedef struct _EImageChooserPrivate EImageChooserPrivate;
-struct _EImageChooser
-{
+struct _EImageChooser {
GtkVBox parent;
-
EImageChooserPrivate *priv;
};
-struct _EImageChooserClass
-{
+struct _EImageChooserClass {
GtkVBoxClass parent_class;
/* signals */
void (*changed) (EImageChooser *chooser);
-
};
-GtkWidget *e_image_chooser_new (void);
-GType e_image_chooser_get_type (void);
-
-gboolean e_image_chooser_set_from_file (EImageChooser *chooser, const gchar *filename);
-gboolean e_image_chooser_set_image_data (EImageChooser *chooser, gchar *data, gsize data_length);
-void e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable);
-
-gboolean e_image_chooser_get_image_data (EImageChooser *chooser, gchar **data, gsize *data_length);
+GType e_image_chooser_get_type (void);
+GtkWidget * e_image_chooser_new (void);
+gboolean e_image_chooser_set_from_file (EImageChooser *chooser,
+ const gchar *filename);
+gboolean e_image_chooser_set_image_data (EImageChooser *chooser,
+ gchar *data,
+ gsize data_length);
+gboolean e_image_chooser_get_image_data (EImageChooser *chooser,
+ gchar **data,
+ gsize *data_length);
-#endif /* _E_IMAGE_CHOOSER_H_ */
+#endif /* E_IMAGE_CHOOSER_H */
diff --git a/widgets/misc/e-info-label.c b/widgets/misc/e-info-label.c
deleted file mode 100644
index 3333d47202..0000000000
--- a/widgets/misc/e-info-label.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "e-info-label.h"
-
-static GtkHBoxClass *el_parent;
-
-static void
-el_init(GObject *o)
-{
- /*EInfoLabel *el = (EInfoLabel *)o;*/
-}
-
-static void
-el_finalise(GObject *o)
-{
- ((GObjectClass *)el_parent)->finalize(o);
-}
-
-static void
-el_destroy (GtkObject *o)
-{
- ((EInfoLabel *)o)->location = NULL;
- ((EInfoLabel *)o)->info = NULL;
-
- ((GtkObjectClass *)el_parent)->destroy(o);
-}
-
-static gint
-el_expose_event(GtkWidget *w, GdkEventExpose *event)
-{
- gint x = ((GtkContainer *)w)->border_width;
-
- /* This seems a hack to me, but playing with styles wouldn't affect the background */
- gtk_paint_flat_box(w->style, w->window,
- GTK_STATE_ACTIVE, GTK_SHADOW_NONE,
- &event->area, w, "EInfoLabel",
- w->allocation.x+x, w->allocation.y+x,
- w->allocation.width-x*2, w->allocation.height-x*2);
-
- return ((GtkWidgetClass *)el_parent)->expose_event(w, event);
-}
-
-static gint
-get_text_full_width (GtkWidget *label)
-{
- PangoLayout *layout;
- PangoRectangle rect;
- gint width;
-
- g_return_val_if_fail (GTK_IS_LABEL (label), 0);
-
- layout = gtk_label_get_layout (GTK_LABEL (label));
-
- if (!layout)
- return 0;
-
- width = pango_layout_get_width (layout);
- pango_layout_set_width (layout, -1);
- pango_layout_get_extents (layout, NULL, &rect);
- pango_layout_set_width (layout, width);
-
- return PANGO_PIXELS (rect.width);
-}
-
-static void
-el_size_allocate (GtkWidget *widget, GtkAllocation *pallocation)
-{
- EInfoLabel *el;
- GtkAllocation allocation;
- gint full_loc, full_nfo;
- gint diff;
-
- /* let calculate parent class first, and then just make it not divide evenly */
- ((GtkWidgetClass *)el_parent)->size_allocate (widget, pallocation);
-
- g_return_if_fail (widget!= NULL);
-
- el = (EInfoLabel*) widget;
-
- if (!el->location)
- return;
-
- full_loc = get_text_full_width (el->location) + 1;
- full_nfo = get_text_full_width (el->info) + 1;
-
- /* do not know the width of text, thus return */
- if (full_loc == 1 && full_nfo == 1)
- return;
-
- if (el->location->allocation.width + el->info->allocation.width >= full_loc + full_nfo) {
- /* allocate for location only as many pixels as it requires to not ellipsize
- and keep rest for the info part */
- diff = el->location->allocation.width - full_loc;
- } else {
- /* make both shorter, but based on the ratio of its full widths */
- gint total_have = el->location->allocation.width + el->info->allocation.width;
- gint total_full = full_loc + full_nfo;
-
- diff = el->location->allocation.width - full_loc * total_have / total_full;
- }
-
- if (!diff)
- return;
-
- allocation = el->location->allocation;
- allocation.width -= diff;
- gtk_widget_size_allocate (el->location, &allocation);
-
- allocation = el->info->allocation;
- allocation.x -= diff;
- allocation.width += diff;
- gtk_widget_size_allocate (el->info, &allocation);
-}
-
-static void
-el_class_init(GObjectClass *klass)
-{
- klass->finalize = el_finalise;
-
- ((GtkObjectClass *)klass)->destroy = el_destroy;
- ((GtkWidgetClass *)klass)->expose_event = el_expose_event;
- ((GtkWidgetClass *)klass)->size_allocate = el_size_allocate;
-}
-
-GType
-e_info_label_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EInfoLabelClass),
- NULL, NULL,
- (GClassInitFunc)el_class_init,
- NULL, NULL,
- sizeof(EInfoLabel), 0,
- (GInstanceInitFunc)el_init
- };
- el_parent = g_type_class_ref(gtk_hbox_get_type());
- type = g_type_register_static(gtk_hbox_get_type(), "EInfoLabel", &info, 0);
- }
-
- return type;
-}
-
-/**
- * e_info_label_new:
- * @icon:
- *
- * Create a new info label widget. @icon is the name of the icon
- * (from the icon theme) to use for the icon image.
- *
- * Return value:
- **/
-GtkWidget *
-e_info_label_new(const gchar *icon)
-{
- EInfoLabel *el = g_object_new(e_info_label_get_type(), NULL);
- GtkWidget *image;
-
- image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
- gtk_misc_set_padding((GtkMisc *)image, 6, 6);
- gtk_box_pack_start((GtkBox *)el, image, FALSE, TRUE, 0);
- gtk_widget_show(image);
-
- gtk_container_set_border_width((GtkContainer *)el, 3);
-
- return (GtkWidget *)el;
-}
-
-/**
- * e_info_label_set_info:
- * @el:
- * @location:
- * @info:
- *
- * Set the information to show on the label. @location is some
- * context about the current view. e.g. the folder name. If the
- * label is too wide, this will be truncated.
- *
- * @info is some info about this location.
- **/
-void
-e_info_label_set_info(EInfoLabel *el, const gchar *location, const gchar *info)
-{
- gchar *markup;
-
- if (el->location == NULL) {
- el->location = gtk_label_new (NULL);
- el->info = gtk_label_new (NULL);
-
- gtk_label_set_ellipsize (GTK_LABEL (el->location), PANGO_ELLIPSIZE_END);
- gtk_misc_set_alignment (GTK_MISC (el->location), 0.0, 0.5);
- gtk_misc_set_padding (GTK_MISC (el->location), 0, 6);
-
- gtk_label_set_ellipsize (GTK_LABEL (el->info), PANGO_ELLIPSIZE_MIDDLE);
- gtk_misc_set_alignment (GTK_MISC (el->info), 1.0, 0.5);
- gtk_misc_set_padding (GTK_MISC (el->info), 0, 6);
-
- gtk_widget_show (el->location);
- gtk_widget_show (el->info);
-
- gtk_box_pack_start (
- GTK_BOX (el), GTK_WIDGET (el->location),
- TRUE, TRUE, 0);
- gtk_box_pack_end (
- GTK_BOX (el), GTK_WIDGET (el->info),
- TRUE, TRUE, 6);
- gtk_widget_set_state (GTK_WIDGET (el), GTK_STATE_ACTIVE);
- }
-
- markup = g_markup_printf_escaped ("<b>%s</b>", location);
- gtk_label_set_markup (GTK_LABEL (el->location), markup);
- g_free (markup);
-
- markup = g_markup_printf_escaped ("<small>%s</small>", info);
- gtk_label_set_markup (GTK_LABEL (el->info), markup);
- g_free (markup);
-}
-
diff --git a/widgets/misc/e-menu-tool-button.c b/widgets/misc/e-menu-tool-button.c
new file mode 100644
index 0000000000..fcf73d6c4e
--- /dev/null
+++ b/widgets/misc/e-menu-tool-button.c
@@ -0,0 +1,183 @@
+/*
+ * e-menu-tool-button.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-menu-tool-button.h"
+
+static gpointer parent_class;
+
+static GtkWidget *
+menu_tool_button_clone_image (GtkWidget *source)
+{
+ GtkIconSize size;
+ GtkImageType image_type;
+ const gchar *icon_name;
+
+ /* XXX This isn't general purpose because it requires that the
+ * source image be using a named icon. Somewhat surprised
+ * GTK+ doesn't offer something like this. */
+ image_type = gtk_image_get_storage_type (GTK_IMAGE (source));
+ g_return_val_if_fail (image_type == GTK_IMAGE_ICON_NAME, NULL);
+ gtk_image_get_icon_name (GTK_IMAGE (source), &icon_name, &size);
+
+ return gtk_image_new_from_icon_name (icon_name, size);
+}
+
+static GtkMenuItem *
+menu_tool_button_get_first_menu_item (GtkMenuToolButton *menu_tool_button)
+{
+ GtkWidget *menu;
+ GList *children;
+
+ menu = gtk_menu_tool_button_get_menu (menu_tool_button);
+ if (!GTK_IS_MENU (menu))
+ return NULL;
+
+ /* XXX GTK+ 2.12 provides no accessor function. */
+ children = GTK_MENU_SHELL (menu)->children;
+ if (children == NULL)
+ return NULL;
+
+ return GTK_MENU_ITEM (children->data);
+}
+
+static void
+menu_tool_button_update_button (GtkToolButton *tool_button)
+{
+ GtkMenuItem *menu_item;
+ GtkMenuToolButton *menu_tool_button;
+ GtkImageMenuItem *image_menu_item;
+ GtkAction *action;
+ GtkWidget *image;
+ gchar *tooltip = NULL;
+
+ menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button);
+ menu_item = menu_tool_button_get_first_menu_item (menu_tool_button);
+ if (!GTK_IS_IMAGE_MENU_ITEM (menu_item))
+ return;
+
+ image_menu_item = GTK_IMAGE_MENU_ITEM (menu_item);
+ image = gtk_image_menu_item_get_image (image_menu_item);
+ if (!GTK_IS_IMAGE (image))
+ return;
+
+ image = menu_tool_button_clone_image (image);
+ gtk_tool_button_set_icon_widget (tool_button, image);
+ gtk_widget_show (image);
+
+ /* If the menu item is a proxy for a GtkAction, extract
+ * the action's tooltip and use it as our own tooltip. */
+ action = gtk_activatable_get_related_action (
+ GTK_ACTIVATABLE (menu_item));
+ if (action != NULL)
+ g_object_get (action, "tooltip", &tooltip, NULL);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (tool_button), tooltip);
+ g_free (tooltip);
+}
+
+static void
+menu_tool_button_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ gint minimum_width;
+
+ /* Chain up to parent's size_request() method. */
+ GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
+
+ /* XXX This is a hack. This widget is only used for the New
+ * button in the main window toolbar. The New button is
+ * pretty important, but the word "New" is pretty short
+ * (in English, anyway) and this results in a small screen
+ * target when using a "text below item" toolbar style.
+ *
+ * We can't go hard-coding a width, but we -can- use a
+ * heuristic based on the toolbar button height. */
+ minimum_width = requisition->height * 2;
+ requisition->width = MAX (minimum_width, requisition->width);
+}
+
+static void
+menu_tool_button_clicked (GtkToolButton *tool_button)
+{
+ GtkMenuItem *menu_item;
+ GtkMenuToolButton *menu_tool_button;
+
+ menu_tool_button = GTK_MENU_TOOL_BUTTON (tool_button);
+ menu_item = menu_tool_button_get_first_menu_item (menu_tool_button);
+
+ if (GTK_IS_MENU_ITEM (menu_item))
+ gtk_menu_item_activate (menu_item);
+}
+
+static void
+menu_tool_button_class_init (EMenuToolButtonClass *class)
+{
+ GtkWidgetClass *widget_class;
+ GtkToolButtonClass *tool_button_class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->size_request = menu_tool_button_size_request;
+
+ tool_button_class = GTK_TOOL_BUTTON_CLASS (class);
+ tool_button_class->clicked = menu_tool_button_clicked;
+}
+
+static void
+menu_tool_button_init (EMenuToolButton *button)
+{
+ g_signal_connect (
+ button, "notify::menu",
+ G_CALLBACK (menu_tool_button_update_button), NULL);
+}
+
+GType
+e_menu_tool_button_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EMenuToolButtonClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) menu_tool_button_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMenuToolButton),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) menu_tool_button_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_MENU_TOOL_BUTTON, "EMenuToolButton",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkToolItem *
+e_menu_tool_button_new (const gchar *label)
+{
+ return g_object_new (E_TYPE_MENU_TOOL_BUTTON, "label", label, NULL);
+}
diff --git a/widgets/misc/e-menu-tool-button.h b/widgets/misc/e-menu-tool-button.h
new file mode 100644
index 0000000000..214f5ab217
--- /dev/null
+++ b/widgets/misc/e-menu-tool-button.h
@@ -0,0 +1,68 @@
+/*
+ * e-menu-tool-button.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* EMenuToolButton is a variation of GtkMenuToolButton where the
+ * button icon always reflects the first menu item, and clicking
+ * the button activates the first menu item. */
+
+#ifndef E_MENU_TOOL_BUTTON_H
+#define E_MENU_TOOL_BUTTON_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MENU_TOOL_BUTTON \
+ (e_menu_tool_button_get_type ())
+#define E_MENU_TOOL_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButton))
+#define E_MENU_TOOL_BUTTON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButtonClass))
+#define E_IS_MENU_TOOL_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MENU_TOOL_BUTTON))
+#define E_IS_MENU_TOOL_BUTTON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MENU_TOOL_BUTTON))
+#define E_MENU_TOOL_BUTTON_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MENU_TOOL_BUTTON, EMenuToolButtonClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMenuToolButton EMenuToolButton;
+typedef struct _EMenuToolButtonClass EMenuToolButtonClass;
+
+struct _EMenuToolButton {
+ GtkMenuToolButton parent;
+};
+
+struct _EMenuToolButtonClass {
+ GtkMenuToolButtonClass parent_class;
+};
+
+GType e_menu_tool_button_get_type (void);
+GtkToolItem * e_menu_tool_button_new (const gchar *label);
+
+G_END_DECLS
+
+#endif /* E_MENU_TOOL_BUTTON_H */
diff --git a/widgets/misc/e-multi-config-dialog.c b/widgets/misc/e-multi-config-dialog.c
deleted file mode 100644
index 1f31ff8cc4..0000000000
--- a/widgets/misc/e-multi-config-dialog.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-multi-config-dialog.h"
-
-#include <e-util/e-util.h>
-#include <table/e-table-scrolled.h>
-#include <table/e-table-memory-store.h>
-#include <table/e-cell-pixbuf.h>
-#include <table/e-cell-vbox.h>
-#include <table/e-cell-text.h>
-
-#define SWITCH_PAGE_INTERVAL 250
-
-struct _EMultiConfigDialogPrivate {
- GSList *pages;
-
- GtkWidget *list_e_table;
- ETableModel *list_e_table_model;
-
- GtkWidget *notebook;
-
- gint set_page_timeout_id;
- gint set_page_timeout_page;
-};
-
-G_DEFINE_TYPE (EMultiConfigDialog, e_multi_config_dialog, GTK_TYPE_DIALOG)
-
-
-/* ETable stuff. */
-
-static const gchar *list_e_table_spec =
- "<ETableSpecification cursor-mode=\"line\""
- " selection-mode=\"browse\""
- " no-headers=\"true\""
- " alternating-row-colors=\"false\""
- " horizontal-resize=\"true\""
- ">"
- " <ETableColumn model_col=\"0\""
- " expansion=\"1.0\""
- " cell=\"vbox\""
- " minimum_width=\"32\""
- " resizable=\"true\""
- " _title=\"Category\""
- " compare=\"string\"/>"
- " <ETableState>"
- " <column source=\"0\"/>"
- " <grouping>"
- " </grouping>"
- " </ETableState>"
- "</ETableSpecification>";
-
-/* Page handling. */
-
-static GtkWidget *
-create_page_container (const gchar *description,
- GtkWidget *widget)
-{
- GtkWidget *vbox;
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0);
-
- gtk_widget_show (widget);
- gtk_widget_show (vbox);
-
- return vbox;
-}
-
-/* Timeout for switching pages (so it's more comfortable navigating with the
- keyboard). */
-
-static gint
-set_page_timeout_callback (gpointer data)
-{
- EMultiConfigDialog *multi_config_dialog;
- EMultiConfigDialogPrivate *priv;
-
- multi_config_dialog = E_MULTI_CONFIG_DIALOG (data);
- priv = multi_config_dialog->priv;
-
- gtk_notebook_set_current_page (
- GTK_NOTEBOOK (priv->notebook), priv->set_page_timeout_page);
-
- priv->set_page_timeout_id = 0;
- gtk_widget_grab_focus(priv->list_e_table);
- return FALSE;
-}
-
-/* Button handling. */
-
-static void
-do_close (EMultiConfigDialog *dialog)
-{
- gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-/* ETable signals. */
-
-static void
-table_cursor_change_callback (ETable *etable,
- gint row,
- gpointer data)
-{
- EMultiConfigDialog *dialog;
- EMultiConfigDialogPrivate *priv;
-
- dialog = E_MULTI_CONFIG_DIALOG (data);
- priv = dialog->priv;
-
- if (priv->set_page_timeout_id == 0)
- priv->set_page_timeout_id = g_timeout_add (SWITCH_PAGE_INTERVAL,
- set_page_timeout_callback,
- dialog);
-
- priv->set_page_timeout_page = row;
-}
-
-/* GObject methods. */
-
-static void
-impl_finalize (GObject *object)
-{
- EMultiConfigDialog *dialog;
- EMultiConfigDialogPrivate *priv;
-
- dialog = E_MULTI_CONFIG_DIALOG (object);
- priv = dialog->priv;
-
- if (priv->set_page_timeout_id != 0)
- g_source_remove (priv->set_page_timeout_id);
-
- g_slist_free (priv->pages);
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_multi_config_dialog_parent_class)->finalize) (object);
-}
-
-/* GtkDialog methods. */
-
-static void
-impl_response (GtkDialog *dialog, gint response_id)
-{
- EMultiConfigDialog *multi_config_dialog;
-
- multi_config_dialog = E_MULTI_CONFIG_DIALOG (dialog);
-
- switch (response_id) {
- case GTK_RESPONSE_HELP:
- e_display_help (GTK_WINDOW (dialog), "config-prefs");
- break;
- case GTK_RESPONSE_CLOSE:
- default:
- do_close (multi_config_dialog);
- break;
- }
-}
-
-
-/* GObject ctors. */
-
-static void
-e_multi_config_dialog_class_init (EMultiConfigDialogClass *class)
-{
- GObjectClass *object_class;
- GtkDialogClass *dialog_class;
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = impl_finalize;
-
- dialog_class = GTK_DIALOG_CLASS (class);
- dialog_class->response = impl_response;
-}
-
-#define RGB_COLOR(color) (((color).red & 0xff00) << 8 | \
- ((color).green & 0xff00) | \
- ((color).blue & 0xff00) >> 8)
-
-static void
-canvas_realize (GtkWidget *widget, EMultiConfigDialog *dialog)
-{
-}
-
-static ETableMemoryStoreColumnInfo columns[] = {
- E_TABLE_MEMORY_STORE_STRING,
- E_TABLE_MEMORY_STORE_PIXBUF,
- E_TABLE_MEMORY_STORE_PIXBUF,
- E_TABLE_MEMORY_STORE_PIXBUF,
- E_TABLE_MEMORY_STORE_PIXBUF,
- E_TABLE_MEMORY_STORE_TERMINATOR
-};
-
-static void
-e_multi_config_dialog_init (EMultiConfigDialog *multi_config_dialog)
-{
- EMultiConfigDialogPrivate *priv;
- ETableModel *list_e_table_model;
- GtkWidget *dialog_vbox;
- GtkWidget *hbox;
- GtkWidget *notebook;
- GtkWidget *list_e_table;
- ETableExtras *extras;
- ECell *pixbuf;
- ECell *text;
- ECell *vbox;
-
- gtk_dialog_set_has_separator (GTK_DIALOG (multi_config_dialog), FALSE);
- gtk_widget_realize (GTK_WIDGET (multi_config_dialog));
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (multi_config_dialog)->vbox), 0);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (multi_config_dialog)->action_area), 12);
-
- hbox = gtk_hbox_new (FALSE, 6);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
- dialog_vbox = GTK_DIALOG (multi_config_dialog)->vbox;
-
- gtk_container_add (GTK_CONTAINER (dialog_vbox), hbox);
-
- list_e_table_model = e_table_memory_store_new (columns);
-
- vbox = e_cell_vbox_new ();
-
- pixbuf = e_cell_pixbuf_new();
- g_object_set (G_OBJECT (pixbuf),
- "focused_column", 2,
- "selected_column", 3,
- "unselected_column", 4,
- NULL);
- e_cell_vbox_append (E_CELL_VBOX (vbox), pixbuf, 1);
- g_object_unref (pixbuf);
-
- text = e_cell_text_new (NULL, GTK_JUSTIFY_CENTER);
- e_cell_vbox_append (E_CELL_VBOX (vbox), text, 0);
- g_object_unref (text);
-
- extras = e_table_extras_new ();
- e_table_extras_add_cell (extras, "vbox", vbox);
-
- list_e_table = e_table_scrolled_new (list_e_table_model, extras, list_e_table_spec, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (list_e_table), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (list_e_table)),
- "cursor_change", G_CALLBACK (table_cursor_change_callback), multi_config_dialog);
-
- g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (list_e_table))->table_canvas,
- "realize", G_CALLBACK (canvas_realize), multi_config_dialog);
-
- g_object_unref (extras);
-
- gtk_box_pack_start (GTK_BOX (hbox), list_e_table, FALSE, TRUE, 0);
-
- notebook = gtk_notebook_new ();
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
- gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
- gtk_box_pack_start (GTK_BOX (hbox), notebook, TRUE, TRUE, 0);
-
- gtk_widget_show (hbox);
- gtk_widget_show (notebook);
- gtk_widget_show (list_e_table);
-
- gtk_dialog_add_buttons (GTK_DIALOG (multi_config_dialog),
- GTK_STOCK_HELP, GTK_RESPONSE_HELP,
- GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
- NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (multi_config_dialog), GTK_RESPONSE_OK);
-
- gtk_window_set_resizable (GTK_WINDOW (multi_config_dialog), TRUE);
-
- priv = g_new (EMultiConfigDialogPrivate, 1);
- priv->pages = NULL;
- priv->list_e_table = list_e_table;
- priv->list_e_table_model = list_e_table_model;
- priv->notebook = notebook;
- priv->set_page_timeout_id = 0;
- priv->set_page_timeout_page = 0;
-
- multi_config_dialog->priv = priv;
-}
-
-
-GtkWidget *
-e_multi_config_dialog_new (void)
-{
- return g_object_new (e_multi_config_dialog_get_type (), NULL);
-}
-
-void
-e_multi_config_dialog_add_page (EMultiConfigDialog *dialog,
- const gchar *title,
- const gchar *description,
- GdkPixbuf *icon,
- EConfigPage *page_widget)
-{
- EMultiConfigDialogPrivate *priv;
- AtkObject *a11y;
- AtkObject *a11yPage;
- gint page_no;
-
- g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog));
- g_return_if_fail (title != NULL);
- g_return_if_fail (description != NULL);
- g_return_if_fail (E_IS_CONFIG_PAGE (page_widget));
-
- priv = dialog->priv;
-
- priv->pages = g_slist_append (priv->pages, page_widget);
-
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (priv->list_e_table_model), -1, NULL, title, icon, NULL, NULL, NULL);
-
- page_no = gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
- create_page_container (description, GTK_WIDGET (page_widget)),
- NULL);
-
- a11y = gtk_widget_get_accessible (GTK_WIDGET(priv->notebook));
- a11yPage = atk_object_ref_accessible_child (a11y, page_no);
- if (a11yPage != NULL) {
- if (atk_object_get_role (a11yPage) == ATK_ROLE_PAGE_TAB)
- atk_object_set_name (a11yPage, title);
- g_object_unref (a11yPage);
- }
- if (priv->pages->next == NULL) {
- ETable *table;
-
- /* FIXME: This is supposed to select the first entry by default
- but it doesn't seem to work at all. */
- table = e_table_scrolled_get_table (E_TABLE_SCROLLED (priv->list_e_table));
- e_table_set_cursor_row (table, 0);
- e_selection_model_select_all (e_table_get_selection_model (table));
- }
-}
-
-void
-e_multi_config_dialog_show_page (EMultiConfigDialog *dialog, gint page)
-{
- EMultiConfigDialogPrivate *priv;
-
- g_return_if_fail (dialog != NULL);
- g_return_if_fail (E_IS_MULTI_CONFIG_DIALOG (dialog));
-
- priv = dialog->priv;
-
- e_table_set_cursor_row (e_table_scrolled_get_table (E_TABLE_SCROLLED (priv->list_e_table)), page);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), page);
-}
-
diff --git a/widgets/misc/e-multi-config-dialog.h b/widgets/misc/e-multi-config-dialog.h
deleted file mode 100644
index 1bc310b888..0000000000
--- a/widgets/misc/e-multi-config-dialog.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_MULTI_CONFIG_DIALOG_H_
-#define _E_MULTI_CONFIG_DIALOG_H_
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-config-page.h"
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_MULTI_CONFIG_DIALOG (e_multi_config_dialog_get_type ())
-#define E_MULTI_CONFIG_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialog))
-#define E_MULTI_CONFIG_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MULTI_CONFIG_DIALOG, EMultiConfigDialogClass))
-#define E_IS_MULTI_CONFIG_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MULTI_CONFIG_DIALOG))
-#define E_IS_MULTI_CONFIG_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MULTI_CONFIG_DIALOG))
-
-
-typedef struct _EMultiConfigDialog EMultiConfigDialog;
-typedef struct _EMultiConfigDialogPrivate EMultiConfigDialogPrivate;
-typedef struct _EMultiConfigDialogClass EMultiConfigDialogClass;
-
-struct _EMultiConfigDialog {
- GtkDialog parent;
-
- EMultiConfigDialogPrivate *priv;
-};
-
-struct _EMultiConfigDialogClass {
- GtkDialogClass parent_class;
-};
-
-
-GType e_multi_config_dialog_get_type (void);
-GtkWidget *e_multi_config_dialog_new (void);
-
-void e_multi_config_dialog_add_page (EMultiConfigDialog *dialog,
- const gchar *title,
- const gchar *description,
- GdkPixbuf *icon,
- EConfigPage *page);
-void e_multi_config_dialog_show_page (EMultiConfigDialog *dialog,
- gint page);
-
-G_END_DECLS
-
-#endif /* _E_MULTI_CONFIG_DIALOG_H_ */
diff --git a/widgets/misc/e-online-button.c b/widgets/misc/e-online-button.c
index 114d76ac32..444296dcef 100644
--- a/widgets/misc/e-online-button.c
+++ b/widgets/misc/e-online-button.c
@@ -23,6 +23,15 @@
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_ONLINE_BUTTON, EOnlineButtonPrivate))
+#define ONLINE_TOOLTIP \
+ _("Evolution is currently online. Click this button to work offline.")
+
+#define OFFLINE_TOOLTIP \
+ _("Evolution is currently offline. Click this button to work online.")
+
+#define NETWORK_UNAVAILABLE_TOOLTIP \
+ _("Evolution is currently offline because the network is unavailable.")
+
struct _EOnlineButtonPrivate {
GtkWidget *image;
gboolean online;
@@ -36,6 +45,21 @@ enum {
static gpointer parent_class;
static void
+online_button_update_tooltip (EOnlineButton *button)
+{
+ const gchar *tooltip;
+
+ if (e_online_button_get_online (button))
+ tooltip = ONLINE_TOOLTIP;
+ else if (GTK_WIDGET_SENSITIVE (button))
+ tooltip = OFFLINE_TOOLTIP;
+ else
+ tooltip = NETWORK_UNAVAILABLE_TOOLTIP;
+
+ gtk_widget_set_tooltip_text (GTK_WIDGET (button), tooltip);
+}
+
+static void
online_button_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -124,6 +148,14 @@ online_button_init (EOnlineButton *button)
gtk_container_add (GTK_CONTAINER (button), widget);
button->priv->image = g_object_ref (widget);
gtk_widget_show (widget);
+
+ g_signal_connect (
+ button, "notify::online",
+ G_CALLBACK (online_button_update_tooltip), NULL);
+
+ g_signal_connect (
+ button, "notify::sensitive",
+ G_CALLBACK (online_button_update_tooltip), NULL);
}
GType
diff --git a/widgets/misc/e-paned.c b/widgets/misc/e-paned.c
new file mode 100644
index 0000000000..51f8dbfa1c
--- /dev/null
+++ b/widgets/misc/e-paned.c
@@ -0,0 +1,310 @@
+/*
+ * e-paned.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-paned.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#define E_PANED_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_PANED, EPanedPrivate))
+
+struct _EPanedPrivate {
+ gint hposition;
+ gint vposition;
+
+ guint sync_position : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_HPOSITION,
+ PROP_VPOSITION
+};
+
+static gpointer parent_class;
+
+static void
+paned_notify_orientation_cb (EPaned *paned)
+{
+ /* Ignore the next "notify::position" emission. */
+ paned->priv->sync_position = TRUE;
+ gtk_widget_queue_resize (GTK_WIDGET (paned));
+}
+
+static void
+paned_notify_position_cb (EPaned *paned)
+{
+ GtkAllocation *allocation;
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+ gint position;
+
+ if (paned->priv->sync_position)
+ return;
+
+ orientable = GTK_ORIENTABLE (paned);
+ orientation = gtk_orientable_get_orientation (orientable);
+
+ allocation = &GTK_WIDGET (paned)->allocation;
+ position = gtk_paned_get_position (GTK_PANED (paned));
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+ position = MAX (0, allocation->width - position);
+ e_paned_set_hposition (paned, position);
+ } else {
+ position = MAX (0, allocation->height - position);
+ e_paned_set_vposition (paned, position);
+ }
+}
+
+static void
+paned_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_HPOSITION:
+ e_paned_set_hposition (
+ E_PANED (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_VPOSITION:
+ e_paned_set_vposition (
+ E_PANED (object),
+ g_value_get_int (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+paned_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_HPOSITION:
+ g_value_set_int (
+ value, e_paned_get_hposition (
+ E_PANED (object)));
+ return;
+
+ case PROP_VPOSITION:
+ g_value_set_int (
+ value, e_paned_get_vposition (
+ E_PANED (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+paned_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EPaned *paned = E_PANED (widget);
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+ gint allocated;
+ gint position;
+
+ /* Chain up to parent's size_allocate() method. */
+ GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
+
+ if (!paned->priv->sync_position)
+ return;
+
+ orientable = GTK_ORIENTABLE (paned);
+ orientation = gtk_orientable_get_orientation (orientable);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+ allocated = allocation->width;
+ position = e_paned_get_hposition (paned);
+ } else {
+ allocated = allocation->height;
+ position = e_paned_get_vposition (paned);
+ }
+
+ position = MAX (0, allocated - position);
+ gtk_paned_set_position (GTK_PANED (paned), position);
+
+ paned->priv->sync_position = FALSE;
+}
+
+static void
+paned_class_init (EPanedClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EPanedPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = paned_set_property;
+ object_class->get_property = paned_get_property;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->size_allocate = paned_size_allocate;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HPOSITION,
+ g_param_spec_int (
+ "hposition",
+ _("Horizontal Position"),
+ _("Pane position when oriented horizontally"),
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_VPOSITION,
+ g_param_spec_int (
+ "vposition",
+ _("Vertical Position"),
+ _("Pane position when oriented vertically"),
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+}
+
+static void
+paned_init (EPaned *paned)
+{
+ paned->priv = E_PANED_GET_PRIVATE (paned);
+
+ g_signal_connect (
+ paned, "notify::orientation",
+ G_CALLBACK (paned_notify_orientation_cb), NULL);
+
+ g_signal_connect (
+ paned, "notify::position",
+ G_CALLBACK (paned_notify_position_cb), NULL);
+}
+
+GType
+e_paned_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EPanedClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) paned_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EPaned),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) paned_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_PANED, "EPaned", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_paned_new (GtkOrientation orientation)
+{
+ return g_object_new (E_TYPE_PANED, "orientation", orientation, NULL);
+}
+
+gint
+e_paned_get_hposition (EPaned *paned)
+{
+ g_return_val_if_fail (E_IS_PANED (paned), 0);
+
+ return paned->priv->hposition;
+}
+
+void
+e_paned_set_hposition (EPaned *paned,
+ gint hposition)
+{
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+
+ g_return_if_fail (E_IS_PANED (paned));
+
+ if (hposition == paned->priv->hposition)
+ return;
+
+ paned->priv->hposition = hposition;
+
+ g_object_notify (G_OBJECT (paned), "hposition");
+
+ orientable = GTK_ORIENTABLE (paned);
+ orientation = gtk_orientable_get_orientation (orientable);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+ paned->priv->sync_position = TRUE;
+ gtk_widget_queue_resize (GTK_WIDGET (paned));
+ }
+}
+
+gint
+e_paned_get_vposition (EPaned *paned)
+{
+ g_return_val_if_fail (E_IS_PANED (paned), 0);
+
+ return paned->priv->vposition;
+}
+
+void
+e_paned_set_vposition (EPaned *paned,
+ gint vposition)
+{
+ GtkOrientable *orientable;
+ GtkOrientation orientation;
+
+ g_return_if_fail (E_IS_PANED (paned));
+
+ if (vposition == paned->priv->vposition)
+ return;
+
+ paned->priv->vposition = vposition;
+
+ g_object_notify (G_OBJECT (paned), "vposition");
+
+ orientable = GTK_ORIENTABLE (paned);
+ orientation = gtk_orientable_get_orientation (orientable);
+
+ if (orientation == GTK_ORIENTATION_VERTICAL) {
+ paned->priv->sync_position = TRUE;
+ gtk_widget_queue_resize (GTK_WIDGET (paned));
+ }
+}
diff --git a/widgets/misc/e-paned.h b/widgets/misc/e-paned.h
new file mode 100644
index 0000000000..8bd1c22024
--- /dev/null
+++ b/widgets/misc/e-paned.h
@@ -0,0 +1,72 @@
+/*
+ * e-paned.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_PANED_H
+#define E_PANED_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PANED \
+ (e_paned_get_type ())
+#define E_PANED(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_PANED, EPaned))
+#define E_PANED_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_PANED, EPanedClass))
+#define E_IS_PANED(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_PANED))
+#define E_IS_PANED_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_PANED))
+#define E_PANED_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_PANED, EPanedClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPaned EPaned;
+typedef struct _EPanedClass EPanedClass;
+typedef struct _EPanedPrivate EPanedPrivate;
+
+struct _EPaned {
+ GtkPaned parent;
+ EPanedPrivate *priv;
+};
+
+struct _EPanedClass {
+ GtkPanedClass parent_class;
+};
+
+GType e_paned_get_type (void);
+GtkWidget * e_paned_new (GtkOrientation orientation);
+gint e_paned_get_hposition (EPaned *paned);
+void e_paned_set_hposition (EPaned *paned,
+ gint hposition);
+gint e_paned_get_vposition (EPaned *paned);
+void e_paned_set_vposition (EPaned *paned,
+ gint vposition);
+
+G_END_DECLS
+
+#endif /* E_PANED_H */
diff --git a/widgets/misc/e-popup-action.c b/widgets/misc/e-popup-action.c
new file mode 100644
index 0000000000..e856a1fc24
--- /dev/null
+++ b/widgets/misc/e-popup-action.c
@@ -0,0 +1,285 @@
+/*
+ * e-popup-action.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-popup-action.h"
+
+#include <glib/gi18n.h>
+#include "e-util/e-binding.h"
+
+#define E_POPUP_ACTION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_POPUP_ACTION, EPopupActionPrivate))
+
+enum {
+ PROP_0,
+ PROP_SOURCE
+};
+
+struct _EPopupActionPrivate {
+ GtkAction *source;
+};
+
+static gpointer parent_class;
+
+static void
+popup_action_set_source (EPopupAction *popup_action,
+ GtkAction *source)
+{
+ g_return_if_fail (popup_action->priv->source == NULL);
+ g_return_if_fail (GTK_IS_ACTION (source));
+
+ popup_action->priv->source = g_object_ref (source);
+}
+
+static void
+popup_action_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SOURCE:
+ popup_action_set_source (
+ E_POPUP_ACTION (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+popup_action_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SOURCE:
+ g_value_set_object (
+ value, e_popup_action_get_source (
+ E_POPUP_ACTION (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+popup_action_dispose (GObject *object)
+{
+ EPopupActionPrivate *priv;
+
+ priv = E_POPUP_ACTION_GET_PRIVATE (object);
+
+ if (priv->source != NULL) {
+ g_object_unref (priv->source);
+ priv->source = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+popup_action_constructed (GObject *object)
+{
+ EPopupActionPrivate *priv;
+ GObject *source;
+ gchar *icon_name;
+ gchar *label;
+ gchar *stock_id;
+ gchar *tooltip;
+
+ priv = E_POPUP_ACTION_GET_PRIVATE (object);
+
+ source = G_OBJECT (priv->source);
+
+ g_object_get (
+ object, "icon-name", &icon_name, "label", &label,
+ "stock-id", &stock_id, "tooltip", &tooltip, NULL);
+
+ if (label == NULL)
+ e_binding_new (source, "label", object, "label");
+
+ if (tooltip == NULL)
+ e_binding_new (source, "tooltip", object, "tooltip");
+
+ if (icon_name == NULL && stock_id == NULL) {
+ g_free (icon_name);
+ g_free (stock_id);
+
+ g_object_get (
+ source, "icon-name", &icon_name,
+ "stock-id", &stock_id, NULL);
+
+ if (icon_name == NULL) {
+ e_binding_new (
+ source, "icon-name", object, "icon-name");
+ e_binding_new (
+ source, "stock-id", object, "stock-id");
+ } else {
+ e_binding_new (
+ source, "stock-id", object, "stock-id");
+ e_binding_new (
+ source, "icon-name", object, "icon-name");
+ }
+ }
+
+ e_binding_new (source, "sensitive", object, "visible");
+
+ g_free (icon_name);
+ g_free (label);
+ g_free (stock_id);
+ g_free (tooltip);
+}
+
+static void
+popup_action_class_init (EPopupActionClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EPopupActionPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = popup_action_set_property;
+ object_class->get_property = popup_action_get_property;
+ object_class->dispose = popup_action_dispose;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE,
+ g_param_spec_object (
+ "source",
+ _("Source Action"),
+ _("The source action to proxy"),
+ GTK_TYPE_ACTION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+popup_action_init (EPopupAction *popup_action)
+{
+ popup_action->priv = E_POPUP_ACTION_GET_PRIVATE (popup_action);
+}
+
+GType
+e_popup_action_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EPopupActionClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) popup_action_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EPopupAction),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) popup_action_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_ACTION, "EPopupAction", &type_info, 0);
+ }
+
+ return type;
+}
+
+EPopupAction *
+e_popup_action_new (const gchar *name,
+ const gchar *label,
+ GtkAction *source)
+{
+ EPopupAction *popup_action;
+
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_ACTION (source), NULL);
+
+ popup_action = g_object_new (
+ E_TYPE_POPUP_ACTION, "name", name,
+ "label", label, "source", source, NULL);
+
+ /* XXX This is a hack to work around the fact that GtkAction's
+ * "label" and "tooltip" properties are not constructor
+ * properties, even though they're supplied upfront.
+ *
+ * See: http://bugzilla.gnome.org/show_bug.cgi?id=568334 */
+ popup_action_constructed (G_OBJECT (popup_action));
+
+ return popup_action;
+}
+
+GtkAction *
+e_popup_action_get_source (EPopupAction *popup_action)
+{
+ g_return_val_if_fail (E_IS_POPUP_ACTION (popup_action), NULL);
+
+ return popup_action->priv->source;
+}
+
+void
+e_action_group_add_popup_actions (GtkActionGroup *action_group,
+ const EPopupActionEntry *entries,
+ guint n_entries)
+{
+ guint ii;
+
+ g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
+
+ for (ii = 0; ii < n_entries; ii++) {
+ EPopupAction *popup_action;
+ GtkAction *source;
+ const gchar *label;
+
+ label = gtk_action_group_translate_string (
+ action_group, entries[ii].label);
+
+ source = gtk_action_group_get_action (
+ action_group, entries[ii].source);
+
+ if (source == NULL) {
+ g_warning (
+ "Source action '%s' not found in "
+ "action group '%s'", entries[ii].source,
+ gtk_action_group_get_name (action_group));
+ continue;
+ }
+
+ popup_action = e_popup_action_new (
+ entries[ii].name, label, source);
+
+ g_signal_connect_swapped (
+ popup_action, "activate",
+ G_CALLBACK (gtk_action_activate),
+ popup_action->priv->source);
+
+ gtk_action_group_add_action (
+ action_group, GTK_ACTION (popup_action));
+
+ g_object_unref (popup_action);
+ }
+}
diff --git a/widgets/misc/e-popup-action.h b/widgets/misc/e-popup-action.h
new file mode 100644
index 0000000000..d19971f303
--- /dev/null
+++ b/widgets/misc/e-popup-action.h
@@ -0,0 +1,95 @@
+/*
+ * e-popup-action.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* A popup action is an action that lives in a popup menu. It proxies an
+ * equivalent action in the main menu, with two differences:
+ *
+ * 1) If the main menu action is insensitive, the popup action is invisible.
+ * 2) The popup action may have a different label than the main menu action.
+ *
+ * To use:
+ *
+ * Create an array of EPopupActionEntry structs. Add the main menu actions
+ * that serve as "sources" for the popup actions to an action group first.
+ * Then pass the same action group and the EPopupActionEntry array to
+ * e_action_group_add_popup_actions() to add popup actions.
+ */
+
+#ifndef E_POPUP_ACTION_H
+#define E_POPUP_ACTION_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_POPUP_ACTION \
+ (e_popup_action_get_type ())
+#define E_POPUP_ACTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_POPUP_ACTION, EPopupAction))
+#define E_POPUP_ACTION_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_POPUP_ACTION, EPopupActionClass))
+#define E_IS_POPUP_ACTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_POPUP_ACTION))
+#define E_IS_POPUP_ACTION_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_POPUP_ACTION))
+#define E_POPUP_ACTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_POPUP_ACTION, EPopupActionClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPopupAction EPopupAction;
+typedef struct _EPopupActionClass EPopupActionClass;
+typedef struct _EPopupActionPrivate EPopupActionPrivate;
+typedef struct _EPopupActionEntry EPopupActionEntry;
+
+struct _EPopupAction {
+ GtkAction parent;
+ EPopupActionPrivate *priv;
+};
+
+struct _EPopupActionClass {
+ GtkActionClass parent_class;
+};
+
+struct _EPopupActionEntry {
+ const gchar *name;
+ const gchar *label; /* optional: overrides the source action */
+ const gchar *source; /* name of the source action */
+};
+
+GType e_popup_action_get_type (void);
+EPopupAction * e_popup_action_new (const gchar *name,
+ const gchar *label,
+ GtkAction *source);
+GtkAction * e_popup_action_get_source (EPopupAction *popup_action);
+
+void e_action_group_add_popup_actions
+ (GtkActionGroup *action_group,
+ const EPopupActionEntry *entries,
+ guint n_entries);
+
+G_END_DECLS
+
+#endif /* E_POPUP_ACTION_H */
diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c
new file mode 100644
index 0000000000..af2d07d871
--- /dev/null
+++ b/widgets/misc/e-preferences-window.c
@@ -0,0 +1,393 @@
+/*
+ * e-preferences-window.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-preferences-window.h"
+
+#include <glib/gi18n.h>
+#include <e-util/e-util.h>
+
+#define SWITCH_PAGE_INTERVAL 250
+
+#define E_PREFERENCES_WINDOW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowPrivate))
+
+struct _EPreferencesWindowPrivate {
+ GtkWidget *icon_view;
+ GtkWidget *notebook;
+ GHashTable *index;
+};
+
+enum {
+ COLUMN_TEXT, /* G_TYPE_STRING */
+ COLUMN_PIXBUF, /* GDK_TYPE_PIXBUF */
+ COLUMN_PAGE, /* G_TYPE_INT */
+ COLUMN_SORT /* G_TYPE_INT */
+};
+
+static gpointer parent_class;
+
+static GdkPixbuf *
+preferences_window_load_pixbuf (const gchar *icon_name)
+{
+ GtkIconTheme *icon_theme;
+ GtkIconInfo *icon_info;
+ GdkPixbuf *pixbuf;
+ const gchar *filename;
+ gint size;
+ GError *error = NULL;
+
+ icon_theme = gtk_icon_theme_get_default ();
+
+ if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &size, 0))
+ return NULL;
+
+ icon_info = gtk_icon_theme_lookup_icon (
+ icon_theme, icon_name, size, 0);
+
+ if (icon_info == NULL)
+ return NULL;
+
+ filename = gtk_icon_info_get_filename (icon_info);
+
+ pixbuf = gdk_pixbuf_new_from_file (filename, &error);
+
+ gtk_icon_info_free (icon_info);
+
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+
+ return pixbuf;
+}
+
+static void
+preferences_window_help_clicked_cb (GtkWindow *window)
+{
+ e_display_help (window, "config-prefs");
+}
+
+static void
+preferences_window_selection_changed_cb (EPreferencesWindow *window)
+{
+ GtkIconView *icon_view;
+ GtkNotebook *notebook;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GList *list;
+ gint page;
+
+ icon_view = GTK_ICON_VIEW (window->priv->icon_view);
+ list = gtk_icon_view_get_selected_items (icon_view);
+ if (list == NULL)
+ return;
+
+ model = gtk_icon_view_get_model (icon_view);
+ gtk_tree_model_get_iter (model, &iter, list->data);
+ gtk_tree_model_get (model, &iter, COLUMN_PAGE, &page, -1);
+
+ notebook = GTK_NOTEBOOK (window->priv->notebook);
+ gtk_notebook_set_current_page (notebook, page);
+
+ g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (list);
+
+ gtk_widget_grab_focus (GTK_WIDGET (icon_view));
+}
+
+static void
+preferences_window_dispose (GObject *object)
+{
+ EPreferencesWindowPrivate *priv;
+
+ priv = E_PREFERENCES_WINDOW_GET_PRIVATE (object);
+
+ if (priv->icon_view != NULL) {
+ g_object_unref (priv->icon_view);
+ priv->icon_view = NULL;
+ }
+
+ if (priv->notebook != NULL) {
+ g_object_unref (priv->notebook);
+ priv->notebook = NULL;
+ }
+
+ g_hash_table_remove_all (priv->index);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+preferences_window_finalize (GObject *object)
+{
+ EPreferencesWindowPrivate *priv;
+
+ priv = E_PREFERENCES_WINDOW_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->index);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+preferences_window_show (GtkWidget *widget)
+{
+ EPreferencesWindowPrivate *priv;
+ GtkIconView *icon_view;
+ GtkTreePath *path;
+
+ priv = E_PREFERENCES_WINDOW_GET_PRIVATE (widget);
+
+ icon_view = GTK_ICON_VIEW (priv->icon_view);
+
+ path = gtk_tree_path_new_first ();
+ gtk_icon_view_select_path (icon_view, path);
+ gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0);
+ gtk_tree_path_free (path);
+
+ gtk_widget_grab_focus (priv->icon_view);
+
+ /* Chain up to parent's show() method. */
+ GTK_WIDGET_CLASS (parent_class)->show (widget);
+}
+
+static void
+preferences_window_class_init (EPreferencesWindowClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EPreferencesWindowPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = preferences_window_dispose;
+ object_class->finalize = preferences_window_finalize;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->show = preferences_window_show;
+}
+
+static void
+preferences_window_init (EPreferencesWindow *window)
+{
+ GtkListStore *store;
+ GtkWidget *container;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *widget;
+ GHashTable *index;
+ const gchar *title;
+
+ index = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) gtk_tree_row_reference_free);
+
+ window->priv = E_PREFERENCES_WINDOW_GET_PRIVATE (window);
+ window->priv->index = index;
+
+ store = gtk_list_store_new (
+ 4, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_INT, G_TYPE_INT);
+ gtk_tree_sortable_set_sort_column_id (
+ GTK_TREE_SORTABLE (store), COLUMN_SORT, GTK_SORT_ASCENDING);
+
+ title = _("Evolution Preferences");
+ gtk_window_set_title (GTK_WINDOW (window), title);
+ gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 12);
+
+ g_signal_connect (
+ window, "delete-event",
+ G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+
+ widget = gtk_vbox_new (FALSE, 12);
+ gtk_container_add (GTK_CONTAINER (window), widget);
+ gtk_widget_show (widget);
+
+ vbox = widget;
+
+ widget = gtk_hbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ hbox = widget;
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_icon_view_new_with_model (GTK_TREE_MODEL (store));
+ gtk_icon_view_set_columns (GTK_ICON_VIEW (widget), 1);
+ gtk_icon_view_set_text_column (GTK_ICON_VIEW (widget), COLUMN_TEXT);
+ gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget), COLUMN_PIXBUF);
+ g_signal_connect_swapped (
+ widget, "selection-changed",
+ G_CALLBACK (preferences_window_selection_changed_cb), window);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ window->priv->icon_view = g_object_ref (widget);
+ gtk_widget_show (widget);
+ g_object_unref (store);
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+ window->priv->notebook = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_hbutton_box_new ();
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_END);
+ gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_HELP);
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (preferences_window_help_clicked_cb), window);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_button_box_set_child_secondary (
+ GTK_BUTTON_BOX (container), widget, TRUE);
+ gtk_widget_show (widget);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (gtk_widget_hide), window);
+ GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_grab_default (widget);
+ gtk_widget_show (widget);
+}
+
+GType
+e_preferences_window_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EPreferencesWindowClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) preferences_window_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EPreferencesWindow),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) preferences_window_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_WINDOW, "EPreferencesWindow", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_preferences_window_new (void)
+{
+ return g_object_new (E_TYPE_PREFERENCES_WINDOW, NULL);
+}
+
+void
+e_preferences_window_add_page (EPreferencesWindow *window,
+ const gchar *page_name,
+ const gchar *icon_name,
+ const gchar *caption,
+ GtkWidget *widget,
+ gint sort_order)
+{
+ GtkTreeRowReference *reference;
+ GtkIconView *icon_view;
+ GtkNotebook *notebook;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GHashTable *index;
+ GdkPixbuf *pixbuf;
+ GtkTreeIter iter;
+ gint page;
+
+ g_return_if_fail (E_IS_PREFERENCES_WINDOW (window));
+ g_return_if_fail (page_name != NULL);
+ g_return_if_fail (icon_name != NULL);
+ g_return_if_fail (caption != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ icon_view = GTK_ICON_VIEW (window->priv->icon_view);
+ notebook = GTK_NOTEBOOK (window->priv->notebook);
+
+ page = gtk_notebook_get_n_pages (notebook);
+ model = gtk_icon_view_get_model (icon_view);
+ pixbuf = preferences_window_load_pixbuf (icon_name);
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter,
+ COLUMN_TEXT, caption, COLUMN_PIXBUF, pixbuf,
+ COLUMN_PAGE, page, COLUMN_SORT, sort_order, -1);
+
+ index = window->priv->index;
+ path = gtk_tree_model_get_path (model, &iter);
+ reference = gtk_tree_row_reference_new (model, path);
+ g_hash_table_insert (index, g_strdup (page_name), reference);
+ gtk_tree_path_free (path);
+
+ gtk_widget_show (widget);
+ gtk_notebook_append_page (notebook, widget, NULL);
+}
+
+void
+e_preferences_window_show_page (EPreferencesWindow *window,
+ const gchar *page_name)
+{
+ GtkTreeRowReference *reference;
+ GtkIconView *icon_view;
+ GtkTreePath *path;
+
+ g_return_if_fail (E_IS_PREFERENCES_WINDOW (window));
+ g_return_if_fail (page_name != NULL);
+
+ icon_view = GTK_ICON_VIEW (window->priv->icon_view);
+ reference = g_hash_table_lookup (window->priv->index, page_name);
+ g_return_if_fail (reference != NULL);
+
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_icon_view_select_path (icon_view, path);
+ gtk_icon_view_scroll_to_path (icon_view, path, FALSE, 0.0, 0.0);
+ gtk_tree_path_free (path);
+}
diff --git a/widgets/misc/e-preferences-window.h b/widgets/misc/e-preferences-window.h
new file mode 100644
index 0000000000..4944a89e58
--- /dev/null
+++ b/widgets/misc/e-preferences-window.h
@@ -0,0 +1,74 @@
+/*
+ * e-preferences-window.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_PREFERENCES_WINDOW_H
+#define E_PREFERENCES_WINDOW_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PREFERENCES_WINDOW \
+ (e_preferences_window_get_type ())
+#define E_PREFERENCES_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindow))
+#define E_PREFERENCES_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowClass))
+#define E_IS_PREFERENCES_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_PREFERENCES_WINDOW))
+#define E_IS_PREFERENCES_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_PREFERENCES_WINDOW))
+#define E_PREFERENCES_WINDOW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_TYPE \
+ ((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPreferencesWindow EPreferencesWindow;
+typedef struct _EPreferencesWindowClass EPreferencesWindowClass;
+typedef struct _EPreferencesWindowPrivate EPreferencesWindowPrivate;
+
+struct _EPreferencesWindow {
+ GtkWindow parent;
+ EPreferencesWindowPrivate *priv;
+};
+
+struct _EPreferencesWindowClass {
+ GtkWindowClass parent_class;
+};
+
+GType e_preferences_window_get_type (void);
+GtkWidget * e_preferences_window_new (void);
+void e_preferences_window_add_page (EPreferencesWindow *window,
+ const gchar *page_name,
+ const gchar *icon_name,
+ const gchar *caption,
+ GtkWidget *widget,
+ gint sort_order);
+void e_preferences_window_show_page (EPreferencesWindow *window,
+ const gchar *page_name);
+
+G_END_DECLS
+
+#endif /* E_PREFERENCES_WINDOW_H */
diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c
deleted file mode 100644
index 0a778531b7..0000000000
--- a/widgets/misc/e-search-bar.c
+++ /dev/null
@@ -1,1683 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Ettore Perazzoli <ettore@ximian.com>
- * Jon Trowbridge <trow@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gdk/gdkkeysyms.h>
-
-#include <misc/e-unicode.h>
-#include <misc/e-gui-utils.h>
-
-#include <glib/gi18n.h>
-
-#include <bonobo/bonobo-ui-util.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "e-icon-entry.h"
-#include "e-search-bar.h"
-#include "e-util/e-util.h"
-
-
-enum {
- QUERY_CHANGED,
- MENU_ACTIVATED,
- SEARCH_ACTIVATED,
- SEARCH_CLEARED,
- LAST_SIGNAL
-};
-
-static gint esb_signals [LAST_SIGNAL] = { 0, };
-
-static GtkHBoxClass *parent_class = NULL;
-
-/* The arguments we take */
-enum {
- PROP_0,
- PROP_ITEM_ID,
- PROP_SUBITEM_ID,
- PROP_TEXT
-};
-
-
-/* Forward decls. */
-
-static gint find_id (GtkWidget *menu, gint idin, const gchar *type, GtkWidget **widget);
-
-static void emit_search_activated (ESearchBar *esb);
-static void emit_query_changed (ESearchBar *esb);
-
-
-/* Utility functions. */
-
-static void
-esb_paint_label (GtkWidget *label, gboolean active)
-{
- static gchar *sens = NULL;
- static gchar *insens = NULL;
- gchar *text;
-
- if (!label)
- return;
-
- if (!sens) {
- GtkStyle *default_style = gtk_widget_get_default_style ();
- sens = gdk_color_to_string (&default_style->text[GTK_STATE_SELECTED]);
- insens = gdk_color_to_string (&default_style->text[GTK_STATE_NORMAL]);
- }
- text = g_strdup_printf("<span foreground=\"%s\">%s</span>", active ? sens : insens, _("Search"));
- gtk_label_set_markup ((GtkLabel *)label, text);
- g_free(text);
-}
-
-static void
-set_find_now_sensitive (ESearchBar *search_bar,
- gboolean sensitive)
-{
- if (search_bar->ui_component != NULL)
- bonobo_ui_component_set_prop (search_bar->ui_component,
- "/commands/ESearchBar:FindNow",
- "sensitive", sensitive ? "1" : "0", NULL);
-}
-
-static void
-update_clear_menuitem_sensitive (ESearchBar *search_bar)
-{
- if (search_bar->ui_component != NULL) {
- gboolean sensitive = GTK_WIDGET_SENSITIVE (search_bar->clear_button) || search_bar->viewitem_id != 0;
-
- bonobo_ui_component_set_prop (search_bar->ui_component,
- "/commands/ESearchBar:Clear",
- "sensitive", sensitive ? "1" : "0", NULL);
- }
-}
-
-static void
-clear_button_state_changed (GtkWidget *clear_button, GtkStateType state, ESearchBar *search_bar)
-{
- g_return_if_fail (clear_button != NULL && search_bar != NULL);
-
- if (!search_bar->lite)
- update_clear_menuitem_sensitive (search_bar);
-}
-
-static gchar *
-verb_name_from_id (gint id)
-{
- return g_strdup_printf ("ESearchBar:Activate:%d", id);
-}
-
-/* This implements the "clear" action, i.e. clears the text and then emits
- * ::search_activated. */
-
-static void
-clear_search (ESearchBar *esb)
-{
- e_search_bar_set_text (esb, "");
- esb->block_search = TRUE;
- if (esb->item_id < 0)
- e_search_bar_set_item_id (esb, esb->last_search_option);
- e_search_bar_set_viewitem_id (esb, 0);
- esb->block_search = FALSE;
- emit_search_activated (esb);
-}
-
-static void
-free_menu_items (ESearchBar *esb)
-{
- GSList *p;
-
- if (esb->menu_items == NULL)
- return;
-
- for (p = esb->menu_items; p != NULL; p = p->next) {
- ESearchBarItem *item;
-
- item = (ESearchBarItem *) p->data;
-
- /* (No submitems for the menu_items, so no need to free that
- member.) */
-
- g_free (item->text);
- g_free (item);
- }
-
- g_slist_free (esb->menu_items);
- esb->menu_items = NULL;
-}
-
-
-/* Signals. */
-
-static void
-emit_query_changed (ESearchBar *esb)
-{
- g_signal_emit (esb, esb_signals [QUERY_CHANGED], 0);
- if (!esb->lite)
- update_clear_menuitem_sensitive (esb);
-}
-
-static void
-emit_search_activated(ESearchBar *esb)
-{
- if (esb->pending_activate) {
- g_source_remove (esb->pending_activate);
- esb->pending_activate = 0;
- }
-
- g_signal_emit (esb, esb_signals [SEARCH_ACTIVATED], 0);
-
- if (!esb->lite) {
- set_find_now_sensitive (esb, FALSE);
- update_clear_menuitem_sensitive (esb);
- }
-}
-
-static void
-emit_menu_activated (ESearchBar *esb, gint item)
-{
- g_signal_emit (esb,
- esb_signals [MENU_ACTIVATED], 0,
- item);
-}
-
-
-/* Callbacks -- Standard verbs. */
-
-static void
-search_now_verb_cb (BonoboUIComponent *ui_component,
- gpointer data,
- const gchar *verb_name)
-{
- ESearchBar *esb;
- GtkStyle *style = gtk_widget_get_default_style ();
- gchar *text;
-
- esb = E_SEARCH_BAR (data);
- text = e_search_bar_get_text (esb);
-
- if (text && *text) {
- gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- } else {
- gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_set_sensitive (esb->clear_button, FALSE);
- }
-
- g_free (text);
- emit_search_activated (esb);
-}
-
-static void
-clear_verb_cb (BonoboUIComponent *ui_component,
- gpointer data,
- const gchar *verb_name)
-{
- ESearchBar *esb;
- esb = E_SEARCH_BAR (data);
-
- gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_set_sensitive (esb->clear_button, FALSE);
-
- clear_search (esb);
- gtk_entry_set_text (GTK_ENTRY (esb->entry), "");
- gtk_widget_grab_focus (esb->entry);
-}
-
-static void
-setup_standard_verbs (ESearchBar *search_bar)
-{
- bonobo_ui_component_add_verb (search_bar->ui_component, "ESearchBar:Clear",
- clear_verb_cb, search_bar);
- bonobo_ui_component_add_verb (search_bar->ui_component, "ESearchBar:FindNow",
- search_now_verb_cb, search_bar);
-
- bonobo_ui_component_set (search_bar->ui_component, "/",
- ("<commands>"
- " <cmd name=\"ESearchBar:Clear\"/>"
- " <cmd name=\"ESearchBar:FindNow\"/>"
- "</commands>"),
- NULL);
-
- /* Make sure the entries are created with the correct sensitivity. */
- set_find_now_sensitive (search_bar, FALSE);
- update_clear_menuitem_sensitive (search_bar);
-}
-
-/* Callbacks -- The verbs for all the definable items. */
-
-static void
-search_verb_cb (BonoboUIComponent *ui_component,
- gpointer data,
- const gchar *verb_name)
-{
- ESearchBar *esb;
- const gchar *p;
- gint id;
-
- esb = E_SEARCH_BAR (data);
-
- p = strrchr (verb_name, ':');
- g_return_if_fail (p != NULL);
-
- id = atoi (p + 1);
-
- emit_menu_activated (esb, id);
-}
-
-/* Get the selected menu item's label */
-static const gchar *
-get_selected_item_label (GtkWidget *menu)
-{
- GtkWidget *label, *item;
- const gchar *text = NULL;
-
- item = gtk_menu_get_active ((GtkMenu *)menu);
- label = gtk_bin_get_child ((GtkBin *)item);
-
- if (GTK_IS_LABEL (label))
- text = gtk_label_get_text ((GtkLabel *)label);
-
- return text;
-}
-
-static gboolean
-entry_focus_in_cb (GtkWidget *widget,
- GdkEventFocus *event,
- ESearchBar *esb)
-{
- GtkStyle *entry_style, *default_style;
-
- entry_style = gtk_widget_get_style (esb->entry);
- default_style = gtk_widget_get_default_style ();
-
- if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) {
- gtk_entry_set_text (GTK_ENTRY (esb->entry), "");
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
- }
-
- return FALSE;
-}
-
-static gboolean
-paint_search_text (GtkWidget *widget, ESearchBar *esb)
-{
- GtkStyle *style = gtk_widget_get_default_style ();
- const gchar *text = NULL;
- GtkWidget *menu_widget = esb->option_menu;
-
- text = gtk_entry_get_text (GTK_ENTRY (widget));
- if (text && *text)
- return FALSE;
-
- if (!GTK_WIDGET_SENSITIVE (esb->option_button)) {
- menu_widget = esb->scopeoption_menu;
- text = g_object_get_data (G_OBJECT(gtk_menu_get_active ( GTK_MENU (esb->scopeoption_menu))),"string");
- } else if (!GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (esb->option_menu))))
- return FALSE;
- else /* no query in search entry .. so set the current option */
- text = get_selected_item_label (menu_widget);
-
- if (text && *text) {
- gchar *t;
-
- if (!GTK_WIDGET_HAS_FOCUS(esb->entry)) {
- gtk_entry_set_text (GTK_ENTRY (esb->entry), text);
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_INSENSITIVE]));
- }
-
- t = g_strdup_printf ("%s: %s\n%s", _("Search"), text, _("Click here to change the search type"));
- gtk_widget_set_tooltip_text (esb->option_button, t);
- g_free (t);
-
- gtk_widget_set_sensitive (esb->clear_button, FALSE);
- }
-
- return FALSE;
-}
-
-void
-e_search_bar_paint (ESearchBar *search_bar)
-{
- paint_search_text (search_bar->entry, search_bar);
-}
-
-static gboolean
-entry_focus_out_cb (GtkWidget *widget,
- GdkEventFocus *event,
- ESearchBar *esb)
-{
- return paint_search_text (widget, esb);
-}
-
-static void
-entry_activated_cb (GtkWidget *widget,
- ESearchBar *esb)
-{
- const gchar *text = gtk_entry_get_text (GTK_ENTRY (esb->entry));
- GtkStyle *style = gtk_widget_get_default_style ();
-
- if (text && *text) {
- gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED]));
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- esb_paint_label (esb->label, TRUE);
- if (!esb->lite)
- gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
- } else {
- gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL);
- esb_paint_label (esb->label, FALSE);
- if (!esb->lite)
- gtk_widget_set_sensitive (esb->clear_button, FALSE);
- }
-
- emit_search_activated (esb);
-}
-
-static void
-search_entry_press_cb (GtkWidget *w, GdkEventButton *event, ESearchBar *esb)
-{
- if (event->button == 1)
- entry_activated_cb (w, esb);
-}
-
-static void
-entry_changed_cb (GtkWidget *widget,
- ESearchBar *esb)
-{
- const gchar *text = gtk_entry_get_text (GTK_ENTRY (esb->entry));
- GtkStyle *entry_style, *default_style;
-
- entry_style = gtk_widget_get_style (esb->entry);
- default_style = gtk_widget_get_default_style ();
-
- if (text && *text) {
- if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE])))
- gtk_widget_set_sensitive (esb->clear_button, FALSE);
- else
- gtk_widget_set_sensitive (esb->clear_button, TRUE);
- } else {
- /* selected color means some search text is active */
- gtk_widget_set_sensitive (esb->clear_button, gdk_color_equal (&(entry_style->base[GTK_STATE_NORMAL]), &(default_style->base[GTK_STATE_SELECTED])));
- }
-}
-
-static void
-viewitem_activated_cb(GtkWidget *widget, ESearchBar *esb)
-{
- gint viewid;
- GtkStyle *entry_style, *default_style;
-
- widget = gtk_menu_get_active (GTK_MENU (esb->viewoption_menu));
-
- viewid = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId"));
- esb->viewitem_id = viewid;
-
- entry_style = gtk_widget_get_style (esb->entry);
- default_style = gtk_widget_get_default_style ();
-
- /* If the text is grayed, Its not the query string */
- if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) {
- gtk_entry_set_text (GTK_ENTRY (esb->entry), "");
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
- }
-
- esb->block_search = TRUE;
- emit_search_activated (esb);
- esb->block_search = FALSE;
-}
-
-static void
-scopeitem_activated_cb(GtkWidget *widget, ESearchBar *esb)
-{
- gint scopeid;
- GtkStyle *entry_style, *default_style;
-
- widget = gtk_menu_get_active (GTK_MENU (esb->scopeoption_menu));
-
- scopeid = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId"));
- esb->scopeitem_id = scopeid;
-
- entry_style = gtk_widget_get_style (esb->entry);
- default_style = gtk_widget_get_default_style ();
-
- /* If the text is grayed, Its not the query string */
- if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) {
- gtk_widget_grab_focus (esb->entry);
- gtk_entry_set_text (GTK_ENTRY (esb->entry), "");
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
- }
-
- esb->block_search = TRUE;
- emit_search_activated (esb);
- esb->block_search = FALSE;
-}
-
-static void
-option_activated_cb (GtkWidget *widget,
- ESearchBar *esb)
-{
- gint id;
- const gchar *text;
-
- id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId"));
-
- e_search_bar_set_item_id (esb, id);
-
- if (GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (esb->option_menu)))) {
- gchar *t;
- text = get_selected_item_label (esb->option_menu);
- if (text && *text)
- t = g_strdup_printf ("%s: %s\n%s", _("Search"), text, _("Click here to change the search type"));
- else
- t = g_strdup_printf ("%s: %s", _("Search"), _("Click here to change the search type"));
-
- gtk_widget_set_tooltip_text (esb->option_button, t);
- g_free (t);
- }
-
- if (!esb->block_search) {
- emit_query_changed (esb);
- }
- if (!esb->block_search && id > 0) {
- emit_search_activated (esb);
- }
-}
-
-static void
-option_button_clicked_cb (GtkWidget *widget, GdkEventButton *event,
- ESearchBar *esb)
-{
- gtk_menu_popup (GTK_MENU (esb->option_menu), NULL, NULL, NULL, NULL,1,gtk_get_current_event_time());
-
- gtk_widget_grab_focus (esb->entry);
-}
-
-static void
-clear_button_clicked_cb (GtkWidget *widget, GdkEventButton *event,
- ESearchBar *esb)
-{
- gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL);
- gtk_widget_set_sensitive (esb->clear_button, FALSE);
- esb_paint_label (esb->label, FALSE);
-
- clear_search (esb);
- gtk_entry_set_text (GTK_ENTRY (esb->entry), "");
- gtk_widget_grab_focus (esb->entry);
-}
-
-static gboolean
-entry_key_press_cb (GtkWidget *widget,
- GdkEventKey *key_event,
- ESearchBar *esb)
-{
- if (((key_event->state & gtk_accelerator_get_default_mod_mask ()) ==
- GDK_MOD1_MASK) && (key_event->keyval == GDK_Down)) {
- option_button_clicked_cb (NULL, NULL, esb);
- return TRUE;
- }
-
- return FALSE;
-}
-
-#if 0
-static void
-scopeoption_changed_cb (GtkWidget *option_menu, ESearchBar *search_bar)
-{
- gchar *text = NULL;
-
- text = e_search_bar_get_text (search_bar);
- if (!(text && *text))
- gtk_widget_grab_focus (search_bar->entry);
-
- if (!search_bar->block_search)
- emit_query_changed (search_bar);
-
- g_free (text);
-}
-#endif
-
-/* Widgetry creation. */
-
-#if 0
-/* This function exists to fix the irreparable GtkOptionMenu stupidity. In
- fact, this lame-ass widget adds a 1-pixel-wide empty border around the
- button for no reason. So we have add a 1-pixel-wide border around the the
- buttons we have in the search bar to make things look right. This is done
- through an event box. */
-static GtkWidget *
-put_in_spacer_widget (GtkWidget *widget)
-{
- GtkWidget *holder;
-
- holder = gtk_event_box_new ();
- gtk_container_set_border_width (GTK_CONTAINER (holder), 1);
- gtk_container_add (GTK_CONTAINER (holder), widget);
-
- return holder;
-}
-#endif
-
-static void
-append_xml_menu_item (GString *xml,
- const gchar *name,
- const gchar *label,
- const gchar *stock,
- const gchar *verb,
- const gchar *accelerator)
-{
- gchar *encoded_label;
-
- encoded_label = bonobo_ui_util_encode_str (label);
- g_string_append_printf (xml, "<menuitem name=\"%s\" verb=\"%s\" label=\"%s\"",
- name, verb, encoded_label);
- g_free (encoded_label);
-
- if (accelerator != NULL)
- g_string_append_printf (xml, " accel=\"%s\"", accelerator);
- if (stock != NULL)
- g_string_append_printf (xml, " pixtype=\"stock\" pixname=\"%s\"", stock);
-
- g_string_append (xml, "/>");
-}
-
-static void
-remove_bonobo_menus (ESearchBar *esb)
-{
- if (bonobo_ui_component_get_container (esb->ui_component) == CORBA_OBJECT_NIL)
- return;
-
- bonobo_ui_component_rm (esb->ui_component, "/menu/SearchPlaceholder", NULL);
-}
-
-static void
-setup_bonobo_menus (ESearchBar *esb)
-{
- GString *xml;
- GSList *p;
- gchar *verb_name;
- gchar *encoded_title;
-
- xml = g_string_new ("");
-
- encoded_title = bonobo_ui_util_encode_str (_("_Search"));
- g_string_append_printf (xml, "<submenu name=\"Search\" label=\"%s\">", encoded_title);
- g_free (encoded_title);
-
- g_string_append (xml, "<placeholder name=\"SearchBar\">");
-
- append_xml_menu_item (xml, "FindNow", _("_Find Now"), "gtk-find", "ESearchBar:FindNow", NULL);
- append_xml_menu_item (xml, "Clear", _("_Clear"), "gtk-clear", "ESearchBar:Clear", "*Control**Shift*q");
-
- for (p = esb->menu_items; p != NULL; p = p->next) {
- const ESearchBarItem *item;
-
- item = (const ESearchBarItem *) p->data;
-
- verb_name = verb_name_from_id (item->id);
- bonobo_ui_component_add_verb (esb->ui_component, verb_name, search_verb_cb, esb);
-
- if (item->text == NULL)
- g_string_append (xml, "<separator/>");
- else
- append_xml_menu_item (xml, verb_name, item->text, NULL, verb_name, NULL);
-
- g_free (verb_name);
- }
-
- g_string_append (xml, "</placeholder>");
- g_string_append (xml, "</submenu>");
-
- remove_bonobo_menus (esb);
- bonobo_ui_component_set (esb->ui_component, "/menu/SearchPlaceholder", xml->str, NULL);
-
- g_string_free (xml, TRUE);
-
- if (esb->clear_button) {
- g_signal_connect (esb->clear_button, "state-changed", G_CALLBACK (clear_button_state_changed), esb);
- }
-}
-
-static void
-update_bonobo_menus (ESearchBar *esb)
-{
- setup_bonobo_menus (esb);
-}
-
-static void
-set_menu (ESearchBar *esb,
- ESearchBarItem *items)
-{
- gint i;
-
- free_menu_items (esb);
-
- if (items == NULL)
- return;
-
- for (i = 0; items[i].id != -1; i++) {
- ESearchBarItem *new_item;
-
- new_item = g_new (ESearchBarItem, 1);
- new_item->text = items[i].text ? g_strdup (_(items[i].text)) : NULL;
- new_item->id = items[i].id;
- new_item->type = items[i].type;
-
- esb->menu_items = g_slist_append (esb->menu_items, new_item);
- }
-
- if (!esb->lite && esb->ui_component != NULL)
- update_bonobo_menus (esb);
-}
-
-/* /\* Callback used when an option item is destroyed. We have to destroy its */
-/* * suboption items. */
-/* *\/ */
-/* static gpointer */
-/* option_item_destroy_cb (GtkObject *object, gpointer data) */
-/* { */
-/* /\* ESearchBarSubitem *subitems; *\/ */
-
-/* /\* subitems = data; *\/ */
-
-/* /\* g_assert (subitems != NULL); *\/ */
-/* /\* free_subitems (subitems); *\/ */
-/* /\* g_object_set_data (G_OBJECT (object), "EsbChoiceSubitems", NULL); *\/ */
-/* } */
-
-static void
-set_option (ESearchBar *esb, ESearchBarItem *items)
-{
- GtkWidget *menu;
- GSList *group = NULL;
- gint i;
-
- if (esb->option_menu)
- gtk_widget_destroy (esb->option_menu);
-
- esb->option_menu = menu = gtk_menu_new ();
- for (i = 0; items[i].id != -1; i++) {
- GtkWidget *item;
-
- /* Create a new group */
- if (items[i].id == 0)
- group = NULL;
-
- if (items[i].text) {
- gchar *str;
- str = e_str_without_underscores (_(items[i].text));
- switch (items[i].type) {
- case ESB_ITEMTYPE_NORMAL:
- item = gtk_menu_item_new_with_label (str);
- break;
- case ESB_ITEMTYPE_CHECK:
- item = gtk_check_menu_item_new_with_label (str);
- break;
- case ESB_ITEMTYPE_RADIO:
- item = gtk_radio_menu_item_new_with_label (group, str);
- group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item));
- break;
- default:
- /* Fixme : this should be a normal item */
- item = gtk_radio_menu_item_new_with_label (group, str);
- group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item));
- break;
- }
- g_free (str);
- } else {
- item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (item, FALSE);
- }
-
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-
- g_object_set_data (G_OBJECT (item), "EsbItemId", GINT_TO_POINTER(items[i].id));
-
- g_signal_connect (item, "activate",
- G_CALLBACK (option_activated_cb),
- esb);
- }
-
- gtk_widget_show_all (menu);
- g_object_set_data (G_OBJECT(esb->option_menu), "group", group);
- entry_focus_out_cb (esb->entry, NULL, esb);
-}
-
-static gint
-find_id (GtkWidget *menu, gint idin, const gchar *type, GtkWidget **widget)
-{
- GList *l = GTK_MENU_SHELL (menu)->children;
- gint row = -1, i = 0, id;
-
- if (widget)
- *widget = NULL;
- while (l) {
- id = GPOINTER_TO_INT (g_object_get_data (l->data, type));
- if (id == idin) {
- row = i;
- if (widget)
- *widget = l->data;
- break;
- }
- i++;
- l = l->next;
- }
- return row;
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- ESearchBar *esb = E_SEARCH_BAR (object);
-
- switch (prop_id) {
- case PROP_ITEM_ID:
- g_value_set_int (value, e_search_bar_get_item_id (esb));
- break;
-
- case PROP_TEXT:
- g_value_take_string (value, e_search_bar_get_text (esb));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- ESearchBar *esb = E_SEARCH_BAR(object);
-
- switch (prop_id) {
- case PROP_ITEM_ID:
- e_search_bar_set_item_id (esb, g_value_get_int (value));
- break;
-
- case PROP_TEXT:
- e_search_bar_set_text (esb, g_value_get_string (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-impl_dispose (GObject *object)
-{
- ESearchBar *esb = E_SEARCH_BAR (object);
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (E_IS_SEARCH_BAR (object));
-
- /* These three we do need to unref, because we explicitly hold
- references to them. */
-
- if (!esb->lite && esb->ui_component != NULL) {
- bonobo_object_unref (BONOBO_OBJECT (esb->ui_component));
- esb->ui_component = NULL;
- }
-/* if (esb->entry) { */
-/* g_object_unref (esb->entry); */
-/* esb->entry = NULL; */
-/* } */
- if (esb->suboption) {
- g_object_unref (esb->suboption);
- esb->suboption = NULL;
- }
-
- if (esb->pending_activate) {
- g_source_remove (esb->pending_activate);
- esb->pending_activate = 0;
- }
-
- free_menu_items (esb);
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-
-static void
-class_init (ESearchBarClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_ref (gtk_hbox_get_type ());
-
- object_class->set_property = impl_set_property;
- object_class->get_property = impl_get_property;
- object_class->dispose = impl_dispose;
-
- klass->set_menu = set_menu;
- klass->set_option = set_option;
-
- g_object_class_install_property (object_class, PROP_ITEM_ID,
- g_param_spec_int ("item_id",
- _("Item ID"),
- /*_( */"XXX blurb" /*)*/,
- 0, 0, 0,
- G_PARAM_READWRITE | G_PARAM_LAX_VALIDATION));
-
- g_object_class_install_property (object_class, PROP_TEXT,
- g_param_spec_string ("text",
- _("Text"),
- /*_( */"XXX blurb" /*)*/,
- NULL,
- G_PARAM_READWRITE));
-
- esb_signals [QUERY_CHANGED] =
- g_signal_new ("query_changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESearchBarClass, query_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- esb_signals [MENU_ACTIVATED] =
- g_signal_new ("menu_activated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESearchBarClass, menu_activated),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1, G_TYPE_INT);
-
- esb_signals [SEARCH_ACTIVATED] =
- g_signal_new ("search_activated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESearchBarClass, search_activated),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- esb_signals [SEARCH_CLEARED] =
- g_signal_new ("search_cleared",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESearchBarClass, search_cleared),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-static void
-init (ESearchBar *esb)
-{
- esb->ui_component = NULL;
- esb->menu_items = NULL;
-
- esb->option = NULL;
- esb->entry = NULL;
- esb->suboption = NULL;
-
- esb->option_menu = NULL;
- esb->suboption_menu = NULL;
- esb->option_button = NULL;
- esb->clear_button = NULL;
- esb->entry_box = NULL;
-
- esb->scopeoption_menu = NULL;
- esb->scopeoption = NULL;
- esb->scopeoption_box = NULL;
-
- esb->pending_activate = 0;
-
- esb->item_id = 0;
- esb->scopeitem_id = 0;
- esb->last_search_option = 0;
- esb->block_search = FALSE;
-}
-
-
-/* Object construction. */
-
-static gint
-idle_activate_hack (gpointer ptr)
-{
- ESearchBar *esb = E_SEARCH_BAR (ptr);
- esb->pending_activate = 0;
- emit_search_activated (esb);
- return FALSE;
-}
-
-void
-e_search_bar_construct (ESearchBar *search_bar,
- ESearchBarItem *menu_items,
- ESearchBarItem *option_items)
-{
- GtkWidget *label, *hbox, *bighbox;
-
- g_return_if_fail (search_bar != NULL);
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
- g_return_if_fail (option_items != NULL);
-
- gtk_box_set_spacing (GTK_BOX (search_bar), 3);
-
- gtk_box_set_homogeneous (GTK_BOX (search_bar), FALSE);
-
- bighbox = gtk_hbox_new (FALSE, 0);
- search_bar->entry_box = gtk_hbox_new (0, FALSE);
- search_bar->icon_entry = e_icon_entry_new ();
- search_bar->entry = e_icon_entry_get_entry (E_ICON_ENTRY (search_bar->icon_entry));
-
- g_signal_connect (search_bar->entry, "changed",
- G_CALLBACK (entry_changed_cb), search_bar);
- g_signal_connect (search_bar->entry, "activate",
- G_CALLBACK (entry_activated_cb), search_bar);
- g_signal_connect (search_bar->entry, "focus-in-event",
- G_CALLBACK (entry_focus_in_cb), search_bar);
- g_signal_connect (search_bar->entry, "focus-out-event",
- G_CALLBACK (entry_focus_out_cb), search_bar);
- g_signal_connect (search_bar->entry, "key-press-event",
- G_CALLBACK (entry_key_press_cb), search_bar);
-
- search_bar->label = NULL;
- if (search_bar->lite) {
- label = e_icon_entry_create_text (_("Search"));
- g_signal_connect (G_OBJECT (label), "button-press-event", G_CALLBACK(search_entry_press_cb), search_bar);
- e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), label, FALSE);
- search_bar->label = g_object_get_data ((GObject *)label, "lbl");
- esb_paint_label (search_bar->label, FALSE);
-
- label = e_icon_entry_create_separator ();
- e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), label, FALSE);
- }
-
- search_bar->clear_button = e_icon_entry_create_button ("gtk-clear");
- g_signal_connect (G_OBJECT (search_bar->clear_button), "button-press-event", G_CALLBACK(clear_button_clicked_cb), search_bar);
- e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->clear_button, FALSE);
-
- search_bar->option_button = e_icon_entry_create_button ("gtk-find");
- g_signal_connect (G_OBJECT (search_bar->option_button), "button-press-event", G_CALLBACK(option_button_clicked_cb), search_bar);
- e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->option_button, TRUE);
-
- if (!search_bar->lite)
- gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, FALSE, FALSE, 0);
- else
- gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, TRUE, TRUE, 0);
-
- gtk_widget_show_all (search_bar->entry_box);
- gtk_widget_set_sensitive (search_bar->clear_button, FALSE);
-
- if (!search_bar->lite) {
- /* Current View filter */
- search_bar->viewoption_box = gtk_hbox_new (0, FALSE);
-
- /* To Translators: The "Show: " label is followed by the Quick Search Dropdown Menu where you can choose
- to display "All Messages", "Unread Messages", "Message with 'Important' Label" and so on... */
- label = gtk_label_new_with_mnemonic (_("Sho_w: "));
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), label, FALSE, FALSE, 0);
-
- search_bar->viewoption = gtk_option_menu_new ();
- gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->viewoption);
- gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), search_bar->viewoption, FALSE, TRUE, 0);
- gtk_widget_show_all (search_bar->viewoption_box);
- gtk_box_pack_start (GTK_BOX(search_bar), search_bar->viewoption_box, FALSE, FALSE, 0);
-
- hbox = gtk_hbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0);
- }
-
- /* Search entry */
- hbox = gtk_hbox_new (FALSE, 0);
- /* To Translators: The "Show: " label is followed by the Quick Search Text input field where one enters
- the term to search for */
- if (!search_bar->lite) {
- label = gtk_label_new_with_mnemonic (_("Sear_ch: "));
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, FALSE, FALSE, 0);
- gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->entry);
- } else {
- gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, TRUE, TRUE, 0);
- }
- gtk_widget_show (search_bar->entry_box);
-
- if (!search_bar->lite) {
- /* Search Scope Widgets */
- search_bar->scopeoption_box = gtk_hbox_new (0, FALSE);
- gtk_box_set_spacing (GTK_BOX (search_bar->scopeoption_box), 3);
- /* To Translators: The " in " label is part of the Quick Search Bar, example:
- Search: | <user's_search_term> | in | Current Folder/All Accounts/Current Account */
- label = gtk_label_new_with_mnemonic (_(" i_n "));
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), label, FALSE, FALSE, 0);
-
- search_bar->scopeoption = gtk_option_menu_new ();
- /* g_signal_connect (GTK_OPTION_MENU (search_bar->scopeoption), "changed", scopeoption_changed_cb, search_bar); */
- gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), search_bar->scopeoption, FALSE, FALSE, 0);
- gtk_widget_show_all (search_bar->scopeoption_box);
- gtk_widget_hide (hbox);
- gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->scopeoption);
-
- gtk_box_pack_end (GTK_BOX(hbox), search_bar->scopeoption_box, FALSE, FALSE, 0);
- gtk_widget_hide (search_bar->scopeoption_box);
-
- }
- if (!search_bar->lite)
- gtk_box_pack_end (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0);
- else
- gtk_box_pack_end (GTK_BOX(search_bar), hbox, TRUE, TRUE, 0);
-
- gtk_widget_show (hbox);
-
- /* Set the menu */
- e_search_bar_set_menu (search_bar, menu_items);
- e_search_bar_set_option (search_bar, option_items);
-
- /*
- * If the default choice for the option menu has subitems, then we need to
- * activate the search immediately. However, the developer won't have
- * connected to the activated signal until after the object is constructed,
- * so we can't emit here. Thus we launch a one-shot idle function that will
- * emit the changed signal, so that the proper callback will get invoked.
- */
- if (!search_bar->lite)
- search_bar->pending_activate = g_idle_add (idle_activate_hack, search_bar);
-}
-
-void
-e_search_bar_set_menu (ESearchBar *search_bar, ESearchBarItem *menu_items)
-{
- g_return_if_fail (search_bar != NULL);
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
-
- ((ESearchBarClass *) GTK_OBJECT_GET_CLASS (search_bar))->set_menu (search_bar, menu_items);
-}
-
-void
-e_search_bar_add_menu (ESearchBar *search_bar, ESearchBarItem *menu_item)
-{
- g_return_if_fail (search_bar != NULL);
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
-
- set_menu (search_bar, menu_item);
-}
-
-void
-e_search_bar_set_option (ESearchBar *search_bar, ESearchBarItem *option_items)
-{
- g_return_if_fail (search_bar != NULL);
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
- g_return_if_fail (option_items != NULL);
-
- ((ESearchBarClass *) GTK_OBJECT_GET_CLASS (search_bar))->set_option (search_bar, option_items);
-}
-
-void
-e_search_bar_set_viewoption_menufunc (ESearchBar *search_bar, ESearchBarMenuFunc *menu_gen_func, gpointer data)
-{
- g_signal_connect (search_bar->viewoption, "button_press_event", G_CALLBACK (menu_gen_func), data);
-}
-
-/**
- * e_search_bar_set_viewoption_menu:
- * @search_bar: A search bar.
- * @option_id: Identifier of the main option menu item under which the subitems
- * are to be set.
- * @subitems: Array of subitem information.
- *
- * Sets the items for the secondary option menu of a search bar.
- **/
-void
-e_search_bar_set_viewoption_menu (ESearchBar *search_bar, GtkWidget *menu)
-{
-
- if (search_bar->viewoption_menu != NULL)
- gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->viewoption));
-
- search_bar->viewoption_menu = menu;
- gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->viewoption), search_bar->viewoption_menu);
-
- g_signal_connect (search_bar->viewoption_menu,
- "selection-done",
- G_CALLBACK (viewitem_activated_cb),
- search_bar);
-}
-
-GtkWidget *
-e_search_bar_get_selected_viewitem (ESearchBar *search_bar)
-{
- GtkWidget *widget = NULL;
-
- widget = gtk_menu_get_active (GTK_MENU (search_bar->viewoption_menu));
-
- return widget;
-}
-
-/**
- * e_search_bar_set_viewoption:
- * @search_bar: A search bar.
- * @option_id: Identifier of the main option menu item under which the subitems
- * are to be set.
- * @subitems: Array of subitem information.
- *
- * Sets the items for the secondary option menu of a search bar.
- **/
-void
-e_search_bar_set_viewoption (ESearchBar *search_bar, gint option_id, ESearchBarItem *subitems)
-{
- GtkWidget *menu;
- GtkWidget *menu_item;
- gint i;
-
- /* Create the menu if it is not there. right scenario ????*/
-
- if (search_bar->viewoption_menu == NULL) {
- search_bar->viewoption_menu = menu = gtk_menu_new ();
- } else {
- gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->viewoption));
- search_bar->viewoption_menu = menu = gtk_menu_new ();
- }
-
- /* Create the items */
-
- for (i = 0; subitems[i].id != -1; ++i) {
- if (subitems[i].text) {
- gchar *str = NULL;
- str = e_str_without_underscores (subitems[i].text);
- menu_item = gtk_menu_item_new_with_label (str);
- g_free (str);
- } else {
- menu_item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
-
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (subitems[i].id));
-
- g_signal_connect (menu_item,
- "activate",
- G_CALLBACK (viewitem_activated_cb),
- search_bar);
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
- gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->viewoption), menu);
-
-}
-
-/**
- * e_search_bar_set_scopeoption:
- * @search_bar: A search bar.
- * are to be set.
- * @scopeitems: Array of scope information.
- *
- * Sets the items for the search scope option menu of a search bar.
- **/
-void
-e_search_bar_set_scopeoption (ESearchBar *search_bar, ESearchBarItem *scopeitems)
-{
- GtkWidget *menu;
- GtkWidget *menu_item;
- gint i;
-
- gtk_widget_show (search_bar->scopeoption_box);
- if (search_bar->scopeoption_menu != NULL) {
- gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->scopeoption));
- }
-
- search_bar->scopeoption_menu = menu = gtk_menu_new ();
-
- /* Generate items */
- for (i = 0; scopeitems[i].id != -1; ++i) {
- if (scopeitems[i].text) {
- gchar *str;
- str = e_str_without_underscores (_(scopeitems[i].text));
- menu_item = gtk_menu_item_new_with_label (str);
- g_object_set_data_full (G_OBJECT (menu_item), "string",str, g_free);
- } else {
- menu_item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
-
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (scopeitems[i].id));
-
- g_signal_connect (menu_item,
- "activate",
- G_CALLBACK (scopeitem_activated_cb),
- search_bar);
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
- gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->scopeoption), menu);
-}
-
-/**
- * e_search_bar_set_scopeoption_menu:
- * @search_bar: A search bar.
- * @menu: the scope option menu
- *
- * Sets the items for the secondary option menu of a search bar.
- **/
-void
-e_search_bar_set_scopeoption_menu (ESearchBar *search_bar, GtkMenu *menu)
-{
-
- if (search_bar->scopeoption_menu != NULL)
- gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->scopeoption));
-
- search_bar->scopeoption_menu = GTK_WIDGET (menu);
- gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->scopeoption), search_bar->scopeoption_menu);
-
- g_signal_connect (search_bar->scopeoption_menu,
- "selection-done",
- G_CALLBACK (scopeitem_activated_cb),
- search_bar);
-}
-
-GtkWidget *
-e_search_bar_new (ESearchBarItem *menu_items,
- ESearchBarItem *option_items)
-{
- GtkWidget *widget;
-
- g_return_val_if_fail (option_items != NULL, NULL);
-
- widget = g_object_new (e_search_bar_get_type (), NULL);
-
- e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items);
-
- return widget;
-}
-
-GtkWidget *
-e_search_bar_lite_new (ESearchBarItem *menu_items,
- ESearchBarItem *option_items)
-{
- GtkWidget *widget;
-
- g_return_val_if_fail (option_items != NULL, NULL);
-
- widget = g_object_new (e_search_bar_get_type (), NULL);
- E_SEARCH_BAR(widget)->lite = TRUE;
-
- e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items);
-
- return widget;
-}
-
-void
-e_search_bar_set_ui_component (ESearchBar *search_bar,
- BonoboUIComponent *ui_component)
-{
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
-
- if (search_bar->lite)
- return;
-
- if (search_bar->ui_component != NULL) {
- remove_bonobo_menus (search_bar);
- bonobo_object_unref (BONOBO_OBJECT (search_bar->ui_component));
- }
-
- search_bar->ui_component = ui_component;
- if (ui_component != NULL) {
- bonobo_object_ref (BONOBO_OBJECT (ui_component));
- setup_standard_verbs (search_bar);
- setup_bonobo_menus (search_bar);
- }
-}
-
-void
-e_search_bar_set_menu_sensitive (ESearchBar *search_bar, gint id, gboolean state)
-{
- gchar *verb_name;
- gchar *path;
-
- if (search_bar->lite)
- return;
-
- verb_name = verb_name_from_id (id);
- path = g_strconcat ("/commands/", verb_name, NULL);
- g_free (verb_name);
-
- bonobo_ui_component_set_prop (search_bar->ui_component, path,
- "sensitive", state ? "1" : "0",
- NULL);
-
- g_free (path);
-}
-
-GType
-e_search_bar_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (ESearchBarClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (ESearchBar),
- 0, /* n_preallocs */
- (GInstanceInitFunc) init,
- };
-
- type = g_type_register_static (gtk_hbox_get_type (), "ESearchBar", &info, 0);
- }
-
- return type;
-}
-
-void
-e_search_bar_set_viewitem_id (ESearchBar *search_bar, gint id)
-{
- gint row;
-
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
- if (!search_bar->viewoption_menu)
- return;
-
- row = find_id (search_bar->viewoption_menu, id, "EsbItemId", NULL);
- if (row == -1)
- return;
- search_bar->viewitem_id = id;
- gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->viewoption), row);
-
- emit_query_changed (search_bar);
-}
-
-/**
- * e_search_bar_set_item_id:
- * @search_bar: A search bar.
- * @id: Identifier of the item to set.
- *
- * Sets the active item in the options menu of a search bar.
- **/
-void
-e_search_bar_set_item_id (ESearchBar *search_bar, gint id)
-{
- gint row;
-
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
-
- if (!search_bar->option_menu)
- return;
- row = find_id (search_bar->option_menu, id, "EsbItemId", NULL);
- if (row == -1)
- return;
-
- if (id>=0)
- search_bar->last_search_option = id;
- search_bar->item_id = id;
- gtk_menu_set_active ((GtkMenu *)search_bar->option_menu, row);
-
- if (!search_bar->block_search)
- emit_query_changed (search_bar);
-
- if (!search_bar->lite)
- update_clear_menuitem_sensitive (search_bar);
-}
-
-void
-e_search_bar_set_item_menu (ESearchBar *search_bar, gint id)
-{
- gint row;
- GtkWidget *item;
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
-
- row = find_id (search_bar->option_menu, id, "EsbItemId", &item);
- if (row == -1)
- return;
-
- gtk_menu_set_active ((GtkMenu *)search_bar->option_menu, row);
- if (id>=0)
- gtk_check_menu_item_set_active ((GtkCheckMenuItem *)item, TRUE);
-}
-
-/**
- * e_search_bar_set_search_scope:
- * @search_bar: A search bar.
- * @id: Identifier of the item to set.
- *
- * Sets the active item in the options menu of a search bar.
- **/
-void
-e_search_bar_set_search_scope (ESearchBar *search_bar, gint id)
-{
- gint row;
-
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
-
- if (!search_bar->scopeoption_menu)
- return;
- row = find_id (search_bar->scopeoption_menu, id, "EsbItemId", NULL);
- if (row == -1)
- return;
-
- search_bar->scopeitem_id = id;
- gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->scopeoption), row);
-
- if (!search_bar->block_search)
- emit_query_changed (search_bar);
-}
-
-/**
- * e_search_bar_get_item_id:
- * @search_bar: A search bar.
- *
- * Queries the currently selected item in the options menu of a search bar.
- *
- * Return value: Identifier of the selected item in the options menu.
- **/
-gint
-e_search_bar_get_item_id (ESearchBar *search_bar)
-{
- GtkWidget *menu_item;
- gint item_id;
-
- g_return_val_if_fail (search_bar != NULL, -1);
- g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1);
-
- menu_item = gtk_menu_get_active (GTK_MENU (search_bar->option_menu));
- item_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId"));
- search_bar->item_id = item_id;
-
- return search_bar->item_id;
-}
-
-/**
- * e_search_bar_get_search_scope:
- * @search_bar: A search bar.
- *
- * Queries the currently selected search type in the options menu of a search bar.
- *
- * Return value: Identifier of the selected item in the options menu.
- **/
-gint
-e_search_bar_get_search_scope (ESearchBar *search_bar)
-{
- GtkWidget *menu_item;
- gint scopeitem_id;
-
- g_return_val_if_fail (search_bar != NULL, -1);
- g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1);
-
- if (!search_bar->scopeoption_menu)
- return -7 /*Current folder hack */;
-
- menu_item = gtk_menu_get_active (GTK_MENU (search_bar->scopeoption_menu));
- scopeitem_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId"));
-
- search_bar->scopeitem_id = scopeitem_id;
-
- return search_bar->scopeitem_id;
-}
-
-/**
- * e_search_bar_get_viewitem_id:
- * @search_bar: A search bar.
- *
- * Queries the currently selected item in the viewoptions menu of a search bar.
- *
- * Return value: Identifier of the selected item in the viewoptions menu.
- * If the search bar currently contains an entry rather than a a viewoption menu,
- * a value less than zero is returned.
- **/
-gint
-e_search_bar_get_viewitem_id (ESearchBar *search_bar)
-{
- GtkWidget *menu_item;
- gint viewitem_id;
-
- g_return_val_if_fail (search_bar != NULL, -1);
- g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1);
-
- if (!search_bar->viewoption_menu)
- return -1;
-
- menu_item = gtk_menu_get_active (GTK_MENU (search_bar->viewoption_menu));
- viewitem_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId"));
-
- search_bar->viewitem_id = viewitem_id;
-
- return search_bar->viewitem_id;
-}
-
-/**
- * e_search_bar_set_ids:
- * @search_bar: A search bar.
- * @item_id: Identifier of the item to set.
- * @subitem_id: Identifier of the subitem to set.
- *
- * Sets the item and subitem ids for a search bar. This is intended to switch
- * to an item that has subitems.
- **/
-void
-e_search_bar_set_ids (ESearchBar *search_bar, gint item_id, gint subitem_id)
-{
- gint item_row;
- GtkWidget *item_widget;
-
- g_return_if_fail (search_bar != NULL);
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
-
- item_row = find_id (search_bar->option_menu, item_id, "EsbChoiceId", &item_widget);
- if (item_row == -1 || !item_widget)
- return;
-
- search_bar->item_id = item_id;
- gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->option), item_row);
-
-}
-
-/**
- * e_search_bar_set_text:
- * @search_bar: A search bar.
- * @text: Text to set in the search bar's entry line.
- *
- * Sets the text string inside the entry line of a search bar.
- **/
-void
-e_search_bar_set_text (ESearchBar *search_bar, const gchar *text)
-{
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
- gtk_entry_set_text (GTK_ENTRY (search_bar->entry), text);
-}
-
-/**
- * e_search_bar_get_text:
- * @search_bar: A search bar.
- *
- * Queries the text of the entry line in a search bar.
- *
- * Return value: The text string that is in the entry line of the search bar.
- * This must be freed using g_free(). If a suboption menu is active instead
- * of an entry, NULL is returned.
- **/
-gchar *
-e_search_bar_get_text (ESearchBar *search_bar)
-{
- GtkStyle *entry_style, *default_style;
-
- g_return_val_if_fail (search_bar != NULL, NULL);
- g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL);
-
- entry_style = gtk_widget_get_style (search_bar->entry);
- default_style = gtk_widget_get_default_style ();
-
- if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE])))
- return g_strdup ("");
-
- return g_strdup (gtk_entry_get_text (GTK_ENTRY (search_bar->entry)));
-}
-
-void e_search_bar_scope_enable (ESearchBar *esb, gint did, gboolean state)
-{
- GtkWidget *widget=NULL;
- GList *l;
- gint id;
- gpointer *pointer;
-
- g_return_if_fail (esb != NULL);
- g_return_if_fail (E_IS_SEARCH_BAR (esb));
-
- l = GTK_MENU_SHELL (esb->scopeoption_menu)->children;
- while (l) {
- pointer = g_object_get_data (l->data, "EsbItemId");
- if (pointer) {
- id = GPOINTER_TO_INT (pointer);
- if (id == did) {
- widget = l->data;
- break;
- }
- }
- l = l->next;
- }
-
- if (widget)
- gtk_widget_set_sensitive (widget, state);
-}
diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h
deleted file mode 100644
index 5385ebf66a..0000000000
--- a/widgets/misc/e-search-bar.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __E_SEARCH_BAR_H__
-#define __E_SEARCH_BAR_H__
-
-#include <gtk/gtk.h>
-
-#include <bonobo/bonobo-ui-component.h>
-
-G_BEGIN_DECLS
-
-/* ESearchBar - A card displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * ---------------------------------------------------------------------------------
- * item_id gint RW Which option item is currently selected.
- * subitem_id gint RW Which option subitem is currently selected.
- * text string RW Text in the entry box.
- */
-
-#define E_SEARCH_BAR_TYPE (e_search_bar_get_type ())
-#define E_SEARCH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_SEARCH_BAR_TYPE, ESearchBar))
-#define E_SEARCH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_SEARCH_BAR_TYPE, ESearchBarClass))
-#define E_IS_SEARCH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_SEARCH_BAR_TYPE))
-#define E_IS_SEARCH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_SEARCH_BAR_TYPE))
-
-enum _ESearchBarItemType {
- ESB_ITEMTYPE_NORMAL,
- ESB_ITEMTYPE_CHECK,
- ESB_ITEMTYPE_RADIO
-};
-typedef enum _ESearchBarItemType ESearchBarItemType;
-
-typedef struct {
- gchar *text;
- gint id;
- gint type;
-} ESearchBarItem;
-
-typedef struct _ESearchBar ESearchBar;
-typedef struct _ESearchBarClass ESearchBarClass;
-
-typedef void (*ESearchBarMenuFunc)(ESearchBar *esb, ESearchBarItem *menu_items);
-
-struct _ESearchBar
-{
- GtkHBox parent;
-
- BonoboUIComponent *ui_component;
-
- GSList *menu_items;
-
- /* item specific fields */
- GtkWidget *option;
- GtkWidget *entry;
- GtkWidget *suboption; /* an option menu for the choices associated with some options */
-
- /* PRIVATE */
- GtkWidget *dropdown_holder; /* holds the dropdown */
- GtkWidget *option_menu;
- GtkWidget *suboption_menu;
- GtkWidget *option_button;
- GtkWidget *clear_button;
- GtkWidget *entry_box;
- GtkWidget *icon_entry;
- GtkWidget *label;
-
- /* show option widgets */
- GtkWidget *viewoption_box;
- GtkWidget *viewoption; /* an option menu for the choices associated with some search options */
- GtkWidget *viewoption_menu;
-
- /* search scope widgets */
- GtkWidget *scopeoption_box;
- GtkWidget *scopeoption; /* an option menu for the choices associated with scope search */
- GtkWidget *scopeoption_menu;
-
- guint pending_activate;
-
- /* The currently-selected item & subitem */
- gint item_id;
- gint viewitem_id; /* Current View Id */
- gint scopeitem_id; /* Scope of search */
- gint last_search_option;
-
- gboolean block_search;
- gboolean lite;
-};
-
-struct _ESearchBarClass
-{
- GtkHBoxClass parent_class;
-
- void (*set_menu) (ESearchBar *, ESearchBarItem *);
- void (*set_option) (ESearchBar *, ESearchBarItem *);
-
- /* signals */
- void (*search_activated) (ESearchBar *search);
- void (*search_cleared) (ESearchBar *search);
- void (*query_changed) (ESearchBar *search);
- void (*menu_activated) (ESearchBar *search, gint item);
-};
-
-enum {
- E_SEARCHBAR_FIND_NOW_ID = -1,
- E_SEARCHBAR_CLEAR_ID = -2
-};
-
-
-GType e_search_bar_get_type (void);
-void e_search_bar_construct (ESearchBar *search_bar,
- ESearchBarItem *menu_items,
- ESearchBarItem *option_items);
-GtkWidget *e_search_bar_new (ESearchBarItem *menu_items,
- ESearchBarItem *option_items);
-GtkWidget *e_search_bar_lite_new (ESearchBarItem *menu_items,
- ESearchBarItem *option_items);
-
-void e_search_bar_set_ui_component (ESearchBar *search_bar,
- BonoboUIComponent *ui_component);
-
-void e_search_bar_set_menu (ESearchBar *search_bar,
- ESearchBarItem *menu_items);
-void e_search_bar_add_menu (ESearchBar *search_bar,
- ESearchBarItem *menu_item);
-
-void e_search_bar_set_option (ESearchBar *search_bar,
- ESearchBarItem *option_items);
-void e_search_bar_paint (ESearchBar *search_bar);
-void e_search_bar_set_viewoption (ESearchBar *search_bar,
- gint option_id,
- ESearchBarItem *subitems);
-
-void e_search_bar_set_menu_sensitive (ESearchBar *search_bar,
- gint id,
- gboolean state);
-
-void e_search_bar_set_item_id (ESearchBar *search_bar,
- gint id);
-void e_search_bar_set_item_menu (ESearchBar *search_bar,
- gint id);
-gint e_search_bar_get_item_id (ESearchBar *search_bar);
-
-gint e_search_bar_get_viewitem_id (ESearchBar *search_bar);
-
-void e_search_bar_set_viewitem_id (ESearchBar *search_bar, gint id);
-
-void e_search_bar_set_ids (ESearchBar *search_bar,
- gint item_id,
- gint subitem_id);
-
-void e_search_bar_set_scopeoption (ESearchBar *search_bar, ESearchBarItem *scopeitems);
-
-void e_search_bar_set_scopeoption_menu (ESearchBar *search_bar, GtkMenu *menu);
-
-void e_search_bar_set_search_scope (ESearchBar *search_bar, gint id);
-
-void e_search_bar_set_viewoption_menu (ESearchBar *search_bar, GtkWidget *menu);
-
-void e_search_bar_set_viewoption_menufunc (ESearchBar *search_bar, ESearchBarMenuFunc *menu_gen_func, gpointer data);
-
-GtkWidget *e_search_bar_get_selected_viewitem (ESearchBar *search_bar);
-
-gint e_search_bar_get_search_scope (ESearchBar *search_bar);
-
-void e_search_bar_set_text (ESearchBar *search_bar,
- const gchar *text);
-gchar *e_search_bar_get_text (ESearchBar *search_bar);
-void e_search_bar_scope_enable (ESearchBar *search_bar, gint did, gboolean state);
-G_END_DECLS
-
-#endif /* __E_SEARCH_BAR_H__ */
diff --git a/widgets/misc/e-signature-combo-box.c b/widgets/misc/e-signature-combo-box.c
index abaa8eafe3..fe4e474729 100644
--- a/widgets/misc/e-signature-combo-box.c
+++ b/widgets/misc/e-signature-combo-box.c
@@ -1,4 +1,5 @@
/*
+ * e-signature-combo-box.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/widgets/misc/e-signature-combo-box.h b/widgets/misc/e-signature-combo-box.h
index fac47518e1..dd81eb55c3 100644
--- a/widgets/misc/e-signature-combo-box.h
+++ b/widgets/misc/e-signature-combo-box.h
@@ -1,4 +1,5 @@
/*
+ * e-signature-combo-box.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/mail/mail-signature-editor.c b/widgets/misc/e-signature-editor.c
index c35e9f99fd..699216784f 100644
--- a/mail/mail-signature-editor.c
+++ b/widgets/misc/e-signature-editor.c
@@ -1,4 +1,6 @@
/*
+ * e-signature-editor.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,24 +15,17 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Radek Doulik <rodo@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#include "mail-signature-editor.h"
+#include "e-signature-editor.h"
#include <string.h>
#include <glib/gi18n.h>
#include <e-util/e-error.h>
-#include <e-util/e-signature-list.h>
-#include <composer/e-msg-composer.h>
-
-#include "mail-config.h"
+#include <e-util/e-signature-utils.h>
#define E_SIGNATURE_EDITOR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -128,9 +123,19 @@ action_save_and_close_cb (GtkAction *action,
entry = editor->priv->entry;
html = gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (editor));
- if (editor->priv->signature == NULL)
- signature = mail_config_signature_new (NULL, FALSE, html);
- else {
+ if (editor->priv->signature == NULL) {
+ gchar *new_filename;
+
+ signature = e_signature_new ();
+ e_signature_set_name (signature, _("Unnamed"));
+ e_signature_set_is_script (signature, FALSE);
+ e_signature_set_is_html (signature, html);
+
+ /* FIXME Pass a GError and deal with it. */
+ new_filename = e_create_signature_file (NULL);
+ e_signature_set_filename (signature, new_filename);
+ g_free (new_filename);
+ } else {
signature = g_object_ref (editor->priv->signature);
e_signature_set_is_html (signature, html);
}
@@ -147,7 +152,7 @@ action_save_and_close_cb (GtkAction *action,
return;
}
- signature_list = mail_config_get_signatures ();
+ signature_list = e_get_signature_list ();
signature_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
g_strstrip (signature_name);
@@ -457,8 +462,11 @@ e_signature_editor_set_signature (ESignatureEditor *editor,
else {
gchar *data;
- data = e_msg_composer_get_sig_file_content (filename, FALSE);
- contents = g_strdup_printf ("<PRE>\n%s", data);
+ data = e_read_signature_file (signature, FALSE, &error);
+ if (data != NULL)
+ contents = g_strdup_printf ("<PRE>\n%s", data);
+ else
+ contents = NULL;
length = -1;
g_free (data);
}
diff --git a/mail/mail-signature-editor.h b/widgets/misc/e-signature-editor.h
index 82c786c90e..1e8b88a909 100644
--- a/mail/mail-signature-editor.h
+++ b/widgets/misc/e-signature-editor.h
@@ -1,4 +1,5 @@
/*
+ * e-signature-editor.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,15 +15,12 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Radek Doulik <rodo@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef MAIL_SIGNATURE_EDITOR_H
-#define MAIL_SIGNATURE_EDITOR_H
+#ifndef E_SIGNATURE_EDITOR_H
+#define E_SIGNATURE_EDITOR_H
#include <gtkhtml-editor.h>
#include <e-util/e-signature.h>
@@ -69,4 +67,4 @@ void e_signature_editor_set_signature (ESignatureEditor *editor,
G_END_DECLS
-#endif /* MAIL_SIGNATURE_EDITOR_H */
+#endif /* E_SIGNATURE_EDITOR_H */
diff --git a/widgets/misc/e-signature-manager.c b/widgets/misc/e-signature-manager.c
new file mode 100644
index 0000000000..7e29f75cef
--- /dev/null
+++ b/widgets/misc/e-signature-manager.c
@@ -0,0 +1,753 @@
+/*
+ * e-signature-manager.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-signature-manager.h"
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <gdk/gdkkeysyms.h>
+#include "e-util/e-binding.h"
+#include "e-signature-tree-view.h"
+#include "e-signature-script-dialog.h"
+
+#define E_SIGNATURE_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SIGNATURE_MANAGER, ESignatureManagerPrivate))
+
+struct _ESignatureManagerPrivate {
+ ESignatureList *signature_list;
+
+ GtkWidget *tree_view;
+ GtkWidget *add_button;
+ GtkWidget *add_script_button;
+ GtkWidget *edit_button;
+ GtkWidget *remove_button;
+
+ guint allow_scripts : 1;
+ guint prefer_html : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_ALLOW_SCRIPTS,
+ PROP_PREFER_HTML,
+ PROP_SIGNATURE_LIST
+};
+
+enum {
+ ADD_SIGNATURE,
+ ADD_SIGNATURE_SCRIPT,
+ EDITOR_CREATED,
+ EDIT_SIGNATURE,
+ REMOVE_SIGNATURE,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+signature_manager_emit_editor_created (ESignatureManager *manager,
+ GtkWidget *editor)
+{
+ g_return_if_fail (E_IS_SIGNATURE_EDITOR (editor));
+
+ g_signal_emit (manager, signals[EDITOR_CREATED], 0, editor);
+}
+
+static gboolean
+signature_manager_key_press_event_cb (ESignatureManager *manager,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_Delete) {
+ e_signature_manager_remove_signature (manager);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+signature_manager_run_script_dialog (ESignatureManager *manager,
+ ESignature *signature,
+ const gchar *title)
+{
+ GtkWidget *dialog;
+ GFile *script_file;
+ const gchar *name;
+ const gchar *filename;
+ const gchar *script_name;
+ gboolean success = FALSE;
+ gpointer parent;
+ gchar *path;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ dialog = e_signature_script_dialog_new (parent);
+ gtk_window_set_title (GTK_WINDOW (dialog), title);
+
+ name = e_signature_get_name (signature);
+ filename = e_signature_get_filename (signature);
+
+ if (filename != NULL && name != NULL) {
+
+ script_file = g_file_new_for_path (filename);
+ script_name = name;
+
+ e_signature_script_dialog_set_script_file (
+ E_SIGNATURE_SCRIPT_DIALOG (dialog), script_file);
+ e_signature_script_dialog_set_script_name (
+ E_SIGNATURE_SCRIPT_DIALOG (dialog), script_name);
+
+ g_object_unref (script_file);
+ }
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ script_file = e_signature_script_dialog_get_script_file (
+ E_SIGNATURE_SCRIPT_DIALOG (dialog));
+ script_name = e_signature_script_dialog_get_script_name (
+ E_SIGNATURE_SCRIPT_DIALOG (dialog));
+
+ path = g_file_get_path (script_file);
+ e_signature_set_name (signature, script_name);
+ e_signature_set_filename (signature, path);
+ g_free (path);
+
+ g_object_unref (script_file);
+
+ success = TRUE;
+
+exit:
+ gtk_widget_destroy (dialog);
+
+ return success;
+}
+
+static void
+signature_manager_selection_changed_cb (ESignatureManager *manager,
+ GtkTreeSelection *selection)
+{
+ ESignatureTreeView *tree_view;
+ ESignature *signature;
+ GtkWidget *edit_button;
+ GtkWidget *remove_button;
+ gboolean sensitive;
+
+ edit_button = manager->priv->edit_button;
+ remove_button = manager->priv->remove_button;
+
+ tree_view = e_signature_manager_get_tree_view (manager);
+ signature = e_signature_tree_view_get_selected (tree_view);
+ sensitive = (signature != NULL);
+
+ gtk_widget_set_sensitive (edit_button, sensitive);
+ gtk_widget_set_sensitive (remove_button, sensitive);
+}
+
+static void
+signature_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ALLOW_SCRIPTS:
+ e_signature_manager_set_allow_scripts (
+ E_SIGNATURE_MANAGER (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_PREFER_HTML:
+ e_signature_manager_set_prefer_html (
+ E_SIGNATURE_MANAGER (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SIGNATURE_LIST:
+ e_signature_manager_set_signature_list (
+ E_SIGNATURE_MANAGER (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ALLOW_SCRIPTS:
+ g_value_set_boolean (
+ value,
+ e_signature_manager_get_allow_scripts (
+ E_SIGNATURE_MANAGER (object)));
+ return;
+
+ case PROP_PREFER_HTML:
+ g_value_set_boolean (
+ value,
+ e_signature_manager_get_prefer_html (
+ E_SIGNATURE_MANAGER (object)));
+ return;
+
+ case PROP_SIGNATURE_LIST:
+ g_value_set_object (
+ value,
+ e_signature_manager_get_signature_list (
+ E_SIGNATURE_MANAGER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_manager_dispose (GObject *object)
+{
+ ESignatureManagerPrivate *priv;
+
+ priv = E_SIGNATURE_MANAGER_GET_PRIVATE (object);
+
+ if (priv->signature_list != NULL) {
+ g_object_unref (priv->signature_list);
+ priv->signature_list = NULL;
+ }
+
+ if (priv->tree_view != NULL) {
+ g_object_unref (priv->tree_view);
+ priv->tree_view = NULL;
+ }
+
+ if (priv->add_button != NULL) {
+ g_object_unref (priv->add_button);
+ priv->add_button = NULL;
+ }
+
+ if (priv->add_script_button != NULL) {
+ g_object_unref (priv->add_script_button);
+ priv->add_script_button = NULL;
+ }
+
+ if (priv->edit_button != NULL) {
+ g_object_unref (priv->edit_button);
+ priv->edit_button = NULL;
+ }
+
+ if (priv->remove_button != NULL) {
+ g_object_unref (priv->remove_button);
+ priv->remove_button = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_manager_add_signature (ESignatureManager *manager)
+{
+ ESignatureTreeView *tree_view;
+ GtkWidget *editor;
+
+ tree_view = e_signature_manager_get_tree_view (manager);
+
+ editor = e_signature_editor_new ();
+ gtkhtml_editor_set_html_mode (
+ GTKHTML_EDITOR (editor), manager->priv->prefer_html);
+ signature_manager_emit_editor_created (manager, editor);
+
+ gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+}
+
+static void
+signature_manager_add_signature_script (ESignatureManager *manager)
+{
+ ESignatureTreeView *tree_view;
+ ESignatureList *signature_list;
+ ESignature *signature;
+ const gchar *title;
+
+ title = _("Add Signature Script");
+ tree_view = e_signature_manager_get_tree_view (manager);
+ signature_list = e_signature_manager_get_signature_list (manager);
+
+ signature = e_signature_new ();
+ e_signature_set_is_script (signature, TRUE);
+ e_signature_set_is_html (signature, TRUE);
+
+ if (signature_manager_run_script_dialog (manager, signature, title))
+ e_signature_list_add (signature_list, signature);
+
+ e_signature_list_save (signature_list);
+ g_object_unref (signature);
+
+ gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+}
+
+static void
+signature_manager_editor_created (ESignatureManager *manager,
+ ESignatureEditor *editor)
+{
+ GtkWindowPosition position;
+ gpointer parent;
+
+ position = GTK_WIN_POS_CENTER_ON_PARENT;
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
+ gtk_window_set_position (GTK_WINDOW (editor), position);
+ gtk_widget_show (GTK_WIDGET (editor));
+}
+
+static void
+signature_manager_edit_signature (ESignatureManager *manager)
+{
+ ESignatureTreeView *tree_view;
+ ESignatureList *signature_list;
+ ESignature *signature;
+ GtkWidget *editor;
+ const gchar *title;
+ const gchar *filename;
+
+ tree_view = e_signature_manager_get_tree_view (manager);
+ signature = e_signature_tree_view_get_selected (tree_view);
+ signature_list = e_signature_manager_get_signature_list (manager);
+
+ if (signature == NULL)
+ return;
+
+ if (e_signature_get_is_script (signature))
+ goto script;
+
+ filename = e_signature_get_filename (signature);
+ if (filename == NULL || *filename == '\0')
+ e_signature_set_filename (signature, _("Unnamed"));
+
+ editor = e_signature_editor_new ();
+ e_signature_editor_set_signature (
+ E_SIGNATURE_EDITOR (editor), signature);
+ signature_manager_emit_editor_created (manager, editor);
+
+ goto exit;
+
+script:
+ title = _("Edit Signature Script");
+
+ if (signature_manager_run_script_dialog (manager, signature, title))
+ e_signature_list_change (signature_list, signature);
+
+ e_signature_list_save (signature_list);
+
+exit:
+ gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+
+ g_object_unref (signature);
+}
+
+static void
+signature_manager_remove_signature (ESignatureManager *manager)
+{
+ ESignatureTreeView *tree_view;
+ ESignatureList *signature_list;
+ ESignature *signature;
+ const gchar *filename;
+ gboolean is_script;
+
+ tree_view = e_signature_manager_get_tree_view (manager);
+ signature = e_signature_tree_view_get_selected (tree_view);
+ signature_list = e_signature_tree_view_get_signature_list (tree_view);
+
+ if (signature == NULL)
+ return;
+
+ filename = e_signature_get_filename (signature);
+ is_script = e_signature_get_is_script (signature);
+
+ if (filename != NULL && !is_script)
+ g_unlink (filename);
+
+ e_signature_list_remove (signature_list, signature);
+ e_signature_list_save (signature_list);
+
+ gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+}
+
+static void
+signature_manager_class_init (ESignatureManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ESignatureManagerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = signature_manager_set_property;
+ object_class->get_property = signature_manager_get_property;
+ object_class->dispose = signature_manager_dispose;
+
+ class->add_signature = signature_manager_add_signature;
+ class->add_signature_script = signature_manager_add_signature_script;
+ class->editor_created = signature_manager_editor_created;
+ class->edit_signature = signature_manager_edit_signature;
+ class->remove_signature = signature_manager_remove_signature;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ALLOW_SCRIPTS,
+ g_param_spec_boolean (
+ "allow-scripts",
+ "Allow Scripts",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_PREFER_HTML,
+ g_param_spec_boolean (
+ "prefer-html",
+ "Prefer HTML",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SIGNATURE_LIST,
+ g_param_spec_object (
+ "signature-list",
+ "Signature List",
+ NULL,
+ E_TYPE_SIGNATURE_LIST,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[ADD_SIGNATURE] = g_signal_new (
+ "add-signature",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ESignatureManagerClass, add_signature),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[ADD_SIGNATURE_SCRIPT] = g_signal_new (
+ "add-signature-script",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ESignatureManagerClass, add_signature_script),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[EDITOR_CREATED] = g_signal_new (
+ "editor-created",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ESignatureManagerClass, editor_created),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_SIGNATURE_EDITOR);
+
+ signals[EDIT_SIGNATURE] = g_signal_new (
+ "edit-signature",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ESignatureManagerClass, edit_signature),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[REMOVE_SIGNATURE] = g_signal_new (
+ "remove-signature",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ESignatureManagerClass, remove_signature),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+signature_manager_init (ESignatureManager *manager)
+{
+ GtkTreeSelection *selection;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ manager->priv = E_SIGNATURE_MANAGER_GET_PRIVATE (manager);
+
+ gtk_table_resize (GTK_TABLE (manager), 1, 2);
+ gtk_table_set_col_spacings (GTK_TABLE (manager), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (manager), 12);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_table_attach (
+ GTK_TABLE (container), widget, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_signature_tree_view_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ manager->priv->tree_view = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_mutual_binding_new (
+ G_OBJECT (manager), "signature-list",
+ G_OBJECT (widget), "signature-list");
+
+ g_signal_connect_swapped (
+ widget, "key-press-event",
+ G_CALLBACK (signature_manager_key_press_event_cb),
+ manager);
+
+ g_signal_connect_swapped (
+ widget, "row-activated",
+ G_CALLBACK (e_signature_manager_edit_signature),
+ manager);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (signature_manager_selection_changed_cb),
+ manager);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_vbutton_box_new ();
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (widget), 6);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 0, 2, 0, GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->add_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_signature_manager_add_signature),
+ manager);
+
+ widget = gtk_button_new_with_mnemonic (_("Add _Script"));
+ gtk_button_set_image (
+ GTK_BUTTON (widget), gtk_image_new_from_stock (
+ GTK_STOCK_EXECUTE, GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->add_script_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_binding_new (
+ G_OBJECT (manager), "allow-scripts",
+ G_OBJECT (widget), "sensitive");
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_signature_manager_add_signature_script),
+ manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->edit_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_signature_manager_edit_signature),
+ manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->remove_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_signature_manager_remove_signature),
+ manager);
+}
+
+GType
+e_signature_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ESignatureManagerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) signature_manager_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_init */
+ sizeof (ESignatureManager),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) signature_manager_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "ESignatureManager", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_signature_manager_new (ESignatureList *signature_list)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_LIST (signature_list), NULL);
+
+ return g_object_new (
+ E_TYPE_SIGNATURE_MANAGER,
+ "signature-list", signature_list, NULL);
+}
+
+void
+e_signature_manager_add_signature (ESignatureManager *manager)
+{
+ g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+ g_signal_emit (manager, signals[ADD_SIGNATURE], 0);
+}
+
+void
+e_signature_manager_add_signature_script (ESignatureManager *manager)
+{
+ g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+ g_signal_emit (manager, signals[ADD_SIGNATURE_SCRIPT], 0);
+}
+
+void
+e_signature_manager_edit_signature (ESignatureManager *manager)
+{
+ g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+ g_signal_emit (manager, signals[EDIT_SIGNATURE], 0);
+}
+
+void
+e_signature_manager_remove_signature (ESignatureManager *manager)
+{
+ g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+ g_signal_emit (manager, signals[REMOVE_SIGNATURE], 0);
+}
+
+gboolean
+e_signature_manager_get_allow_scripts (ESignatureManager *manager)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_MANAGER (manager), FALSE);
+
+ return manager->priv->allow_scripts;
+}
+
+void
+e_signature_manager_set_allow_scripts (ESignatureManager *manager,
+ gboolean allow_scripts)
+{
+ g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+ manager->priv->allow_scripts = allow_scripts;
+
+ g_object_notify (G_OBJECT (manager), "allow-scripts");
+}
+
+gboolean
+e_signature_manager_get_prefer_html (ESignatureManager *manager)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_MANAGER (manager), FALSE);
+
+ return manager->priv->prefer_html;
+}
+
+void
+e_signature_manager_set_prefer_html (ESignatureManager *manager,
+ gboolean prefer_html)
+{
+ g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+ manager->priv->prefer_html = prefer_html;
+
+ g_object_notify (G_OBJECT (manager), "prefer-html");
+}
+
+ESignatureList *
+e_signature_manager_get_signature_list (ESignatureManager *manager)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_MANAGER (manager), NULL);
+
+ return manager->priv->signature_list;
+}
+
+void
+e_signature_manager_set_signature_list (ESignatureManager *manager,
+ ESignatureList *signature_list)
+{
+ g_return_if_fail (E_IS_SIGNATURE_MANAGER (manager));
+
+ if (signature_list != NULL) {
+ g_return_if_fail (E_IS_SIGNATURE_LIST (signature_list));
+ g_object_ref (signature_list);
+ }
+
+ if (manager->priv->signature_list != NULL)
+ g_object_unref (manager->priv->signature_list);
+
+ manager->priv->signature_list = signature_list;
+
+ g_object_notify (G_OBJECT (manager), "signature-list");
+}
+
+ESignatureTreeView *
+e_signature_manager_get_tree_view (ESignatureManager *manager)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_MANAGER (manager), NULL);
+
+ return E_SIGNATURE_TREE_VIEW (manager->priv->tree_view);
+}
diff --git a/widgets/misc/e-signature-manager.h b/widgets/misc/e-signature-manager.h
new file mode 100644
index 0000000000..662836e4ef
--- /dev/null
+++ b/widgets/misc/e-signature-manager.h
@@ -0,0 +1,100 @@
+/*
+ * e-signature-manager.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SIGNATURE_MANAGER_H
+#define E_SIGNATURE_MANAGER_H
+
+#include <gtk/gtk.h>
+#include <e-util/e-signature-list.h>
+#include <misc/e-signature-editor.h>
+#include <misc/e-signature-tree-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_MANAGER \
+ (e_signature_manager_get_type ())
+#define E_SIGNATURE_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SIGNATURE_MANAGER, ESignatureManager))
+#define E_SIGNATURE_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SIGNATURE_MANAGER, ESignatureManagerClass))
+#define E_IS_SIGNATURE_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SIGNATURE_MANAGER))
+#define E_IS_SIGNATURE_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SIGNATURE_MANAGER))
+#define E_SIGNATURE_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SIGNATURE_MANAGER, ESignatureManagerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignatureManager ESignatureManager;
+typedef struct _ESignatureManagerClass ESignatureManagerClass;
+typedef struct _ESignatureManagerPrivate ESignatureManagerPrivate;
+
+struct _ESignatureManager {
+ GtkTable parent;
+ ESignatureManagerPrivate *priv;
+};
+
+struct _ESignatureManagerClass {
+ GtkTableClass parent_class;
+
+ void (*add_signature) (ESignatureManager *manager);
+ void (*add_signature_script) (ESignatureManager *manager);
+ void (*editor_created) (ESignatureManager *manager,
+ ESignatureEditor *editor);
+ void (*edit_signature) (ESignatureManager *manager);
+ void (*remove_signature) (ESignatureManager *manager);
+};
+
+GType e_signature_manager_get_type (void);
+GtkWidget * e_signature_manager_new (ESignatureList *signature_list);
+void e_signature_manager_add_signature
+ (ESignatureManager *manager);
+void e_signature_manager_add_signature_script
+ (ESignatureManager *manager);
+void e_signature_manager_edit_signature
+ (ESignatureManager *manager);
+void e_signature_manager_remove_signature
+ (ESignatureManager *manager);
+gboolean e_signature_manager_get_allow_scripts
+ (ESignatureManager *manager);
+void e_signature_manager_set_allow_scripts
+ (ESignatureManager *manager,
+ gboolean allow_scripts);
+gboolean e_signature_manager_get_prefer_html
+ (ESignatureManager *manager);
+void e_signature_manager_set_prefer_html
+ (ESignatureManager *manager,
+ gboolean prefer_html);
+ESignatureList *e_signature_manager_get_signature_list
+ (ESignatureManager *manager);
+void e_signature_manager_set_signature_list
+ (ESignatureManager *manager,
+ ESignatureList *signature_list);
+ESignatureTreeView *
+ e_signature_manager_get_tree_view
+ (ESignatureManager *manager);
+
+#endif /* E_SIGNATURE_MANAGER_H */
diff --git a/widgets/misc/e-signature-preview.c b/widgets/misc/e-signature-preview.c
new file mode 100644
index 0000000000..bbef65f39c
--- /dev/null
+++ b/widgets/misc/e-signature-preview.c
@@ -0,0 +1,349 @@
+/*
+ * e-signature-preview.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-signature-preview.h"
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib/gstdio.h>
+#include "e-util/e-signature-utils.h"
+
+#define E_SIGNATURE_PREVIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreviewPrivate))
+
+enum {
+ PROP_0,
+ PROP_ALLOW_SCRIPTS,
+ PROP_SIGNATURE
+};
+
+enum {
+ REFRESH,
+ LAST_SIGNAL
+};
+
+struct _ESignaturePreviewPrivate {
+ ESignature *signature;
+ guint allow_scripts : 1;
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+signature_preview_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ALLOW_SCRIPTS:
+ e_signature_preview_set_allow_scripts (
+ E_SIGNATURE_PREVIEW (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SIGNATURE:
+ e_signature_preview_set_signature (
+ E_SIGNATURE_PREVIEW (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_preview_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ALLOW_SCRIPTS:
+ g_value_set_boolean (
+ value, e_signature_preview_get_allow_scripts (
+ E_SIGNATURE_PREVIEW (object)));
+ return;
+
+ case PROP_SIGNATURE:
+ g_value_set_object (
+ value, e_signature_preview_get_signature (
+ E_SIGNATURE_PREVIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_preview_dispose (GObject *object)
+{
+ ESignaturePreviewPrivate *priv;
+
+ priv = E_SIGNATURE_PREVIEW_GET_PRIVATE (object);
+
+ if (priv->signature != NULL) {
+ g_object_unref (priv->signature);
+ priv->signature = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_preview_url_requested (GtkHTML *html,
+ const gchar *url,
+ GtkHTMLStream *handle)
+{
+ GtkHTMLStreamStatus status;
+ gchar buffer[128];
+ gchar *filename;
+ gssize size;
+ gint fd;
+
+ /* FIXME Use GInputStream for this. */
+
+ if (g_str_has_prefix (url, "file:"))
+ filename = g_filename_from_uri (url, NULL, NULL);
+ else
+ filename = g_strdup (url);
+ fd = g_open (filename, O_RDONLY, 0);
+ g_free (filename);
+
+ status = GTK_HTML_STREAM_OK;
+ if (fd != -1) {
+ while ((size = read (fd, buffer, sizeof (buffer)))) {
+ if (size == -1) {
+ status = GTK_HTML_STREAM_ERROR;
+ break;
+ } else
+ gtk_html_write (html, handle, buffer, size);
+ }
+ } else
+ status = GTK_HTML_STREAM_ERROR;
+
+ gtk_html_end (html, handle, status);
+
+ if (fd > 0)
+ close (fd);
+}
+
+static void
+signature_preview_refresh (ESignaturePreview *preview)
+{
+ GtkHTML *html;
+ ESignature *signature;
+ const gchar *filename;
+ gboolean is_script;
+ gchar *content = NULL;
+ gsize length;
+
+ /* XXX We should show error messages in the preview. */
+
+ html = GTK_HTML (preview);
+ signature = e_signature_preview_get_signature (preview);
+
+ if (signature == NULL)
+ goto clear;
+
+ filename = e_signature_get_filename (signature);
+ is_script = e_signature_get_is_script (signature);
+
+ if (is_script && !preview->priv->allow_scripts)
+ goto clear;
+
+ if (is_script)
+ content = e_run_signature_script (filename);
+ else
+ content = e_read_signature_file (signature, FALSE, NULL);
+
+ if (content == NULL || *content == '\0')
+ goto clear;
+
+ length = strlen (content);
+
+ if (e_signature_get_is_html (signature))
+ gtk_html_load_from_string (html, content, length);
+ else {
+ GtkHTMLStream *stream;
+
+ stream = gtk_html_begin_content (
+ html, "text/html; charset=utf-8");
+ gtk_html_write (html, stream, "<PRE>", 5);
+ if (length > 0)
+ gtk_html_write (html, stream, content, length);
+ gtk_html_write (html, stream, "</PRE>", 6);
+ gtk_html_end (html, stream, GTK_HTML_STREAM_OK);
+ }
+
+ g_free (content);
+ return;
+
+clear:
+ gtk_html_load_from_string (html, " ", 1);
+ g_free (content);
+}
+
+static void
+signature_preview_class_init (ESignaturePreviewClass *class)
+{
+ GObjectClass *object_class;
+ GtkHTMLClass *html_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ESignaturePreviewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = signature_preview_set_property;
+ object_class->get_property = signature_preview_get_property;
+ object_class->dispose = signature_preview_dispose;
+
+ html_class = GTK_HTML_CLASS (class);
+ html_class->url_requested = signature_preview_url_requested;
+
+ class->refresh = signature_preview_refresh;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ALLOW_SCRIPTS,
+ g_param_spec_boolean (
+ "allow-scripts",
+ "Allow Scripts",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SIGNATURE,
+ g_param_spec_object (
+ "signature",
+ "Signature",
+ NULL,
+ E_TYPE_SIGNATURE,
+ G_PARAM_READWRITE));
+
+ signals[REFRESH] = g_signal_new (
+ "refresh",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (ESignaturePreviewClass, refresh),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+signature_preview_init (ESignaturePreview *preview)
+{
+ preview->priv = E_SIGNATURE_PREVIEW_GET_PRIVATE (preview);
+}
+
+GType
+e_signature_preview_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ESignaturePreviewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) signature_preview_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ESignaturePreview),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) signature_preview_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HTML, "ESignaturePreview", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_signature_preview_new (void)
+{
+ return g_object_new (E_TYPE_SIGNATURE_PREVIEW, NULL);
+}
+
+void
+e_signature_preview_refresh (ESignaturePreview *preview)
+{
+ g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview));
+
+ g_signal_emit (preview, signals[REFRESH], 0);
+}
+
+gboolean
+e_signature_preview_get_allow_scripts (ESignaturePreview *preview)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_PREVIEW (preview), FALSE);
+
+ return preview->priv->allow_scripts;
+}
+
+void
+e_signature_preview_set_allow_scripts (ESignaturePreview *preview,
+ gboolean allow_scripts)
+{
+ g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview));
+
+ preview->priv->allow_scripts = allow_scripts;
+ g_object_notify (G_OBJECT (preview), "allow-scripts");
+}
+
+ESignature *
+e_signature_preview_get_signature (ESignaturePreview *preview)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_PREVIEW (preview), NULL);
+
+ return preview->priv->signature;
+}
+
+void
+e_signature_preview_set_signature (ESignaturePreview *preview,
+ ESignature *signature)
+{
+ g_return_if_fail (E_IS_SIGNATURE_PREVIEW (preview));
+
+ if (signature != NULL) {
+ g_return_if_fail (E_IS_SIGNATURE (signature));
+ g_object_ref (signature);
+ }
+
+ if (preview->priv->signature != NULL)
+ g_object_unref (preview->priv->signature);
+
+ preview->priv->signature = signature;
+ g_object_notify (G_OBJECT (preview), "signature");
+
+ e_signature_preview_refresh (preview);
+}
diff --git a/widgets/misc/e-signature-preview.h b/widgets/misc/e-signature-preview.h
new file mode 100644
index 0000000000..a4221832c2
--- /dev/null
+++ b/widgets/misc/e-signature-preview.h
@@ -0,0 +1,81 @@
+/*
+ * e-signature-preview.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SIGNATURE_PREVIEW_H
+#define E_SIGNATURE_PREVIEW_H
+
+#include <gtkhtml/gtkhtml.h>
+#include <e-util/e-signature.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_PREVIEW \
+ (e_signature_preview_get_type ())
+#define E_SIGNATURE_PREVIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreview))
+#define E_SIGNATURE_PREVIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreviewClass))
+#define E_IS_SIGNATURE_PREVIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SIGNATURE_PREVIEW))
+#define E_IS_SIGNATURE_PREVIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SIGNATURE_PREVIEW))
+#define E_SIGNATURE_PREVIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SIGNATURE_PREVIEW, ESignaturePreview))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignaturePreview ESignaturePreview;
+typedef struct _ESignaturePreviewClass ESignaturePreviewClass;
+typedef struct _ESignaturePreviewPrivate ESignaturePreviewPrivate;
+
+struct _ESignaturePreview {
+ GtkHTML parent;
+ ESignaturePreviewPrivate *priv;
+};
+
+struct _ESignaturePreviewClass {
+ GtkHTMLClass parent_class;
+
+ /* Signals */
+ void (*refresh) (ESignaturePreview *preview);
+};
+
+GType e_signature_preview_get_type (void);
+GtkWidget * e_signature_preview_new (void);
+void e_signature_preview_refresh (ESignaturePreview *preview);
+gboolean e_signature_preview_get_allow_scripts
+ (ESignaturePreview *preview);
+void e_signature_preview_set_allow_scripts
+ (ESignaturePreview *preview,
+ gboolean allow_scripts);
+ESignature * e_signature_preview_get_signature
+ (ESignaturePreview *preview);
+void e_signature_preview_set_signature
+ (ESignaturePreview *preview,
+ ESignature *signature);
+
+G_END_DECLS
+
+#endif /* E_SIGNATURE_PREVIEW_H */
diff --git a/widgets/misc/e-signature-script-dialog.c b/widgets/misc/e-signature-script-dialog.c
new file mode 100644
index 0000000000..777d064f09
--- /dev/null
+++ b/widgets/misc/e-signature-script-dialog.c
@@ -0,0 +1,463 @@
+/*
+ * e-signature-script-dialog.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-signature-script-dialog.h"
+
+#include <glib/gi18n.h>
+#include "e-util/e-binding.h"
+
+#define E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialogPrivate))
+
+struct _ESignatureScriptDialogPrivate {
+ GtkWidget *entry;
+ GtkWidget *file_chooser;
+ GtkWidget *alert;
+};
+
+enum {
+ PROP_0,
+ PROP_SCRIPT_FILE,
+ PROP_SCRIPT_NAME
+};
+
+static gpointer parent_class;
+
+static gboolean
+signature_script_dialog_filter_cb (const GtkFileFilterInfo *filter_info)
+{
+ const gchar *filename = filter_info->filename;
+
+ return g_file_test (filename, G_FILE_TEST_IS_EXECUTABLE);
+}
+
+static void
+signature_script_dialog_update_status (ESignatureScriptDialog *dialog)
+{
+ GFile *script_file;
+ const gchar *script_name;
+ gboolean show_alert;
+ gboolean sensitive;
+
+ script_file = e_signature_script_dialog_get_script_file (dialog);
+ script_name = e_signature_script_dialog_get_script_name (dialog);
+
+ sensitive = (script_name != NULL && *script_name != '\0');
+
+ if (script_file != NULL) {
+ gboolean executable;
+ gchar *filename;
+
+ filename = g_file_get_path (script_file);
+ executable = g_file_test (filename, G_FILE_TEST_IS_EXECUTABLE);
+ g_free (filename);
+
+ show_alert = !executable;
+ sensitive &= executable;
+
+ g_object_unref (script_file);
+ } else {
+ sensitive = FALSE;
+ show_alert = FALSE;
+ }
+
+ if (show_alert)
+ gtk_widget_show (dialog->priv->alert);
+ else
+ gtk_widget_hide (dialog->priv->alert);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
+}
+
+static void
+signature_script_dialog_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SCRIPT_FILE:
+ e_signature_script_dialog_set_script_file (
+ E_SIGNATURE_SCRIPT_DIALOG (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SCRIPT_NAME:
+ e_signature_script_dialog_set_script_name (
+ E_SIGNATURE_SCRIPT_DIALOG (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_script_dialog_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SCRIPT_FILE:
+ g_value_set_object (
+ value,
+ e_signature_script_dialog_get_script_file (
+ E_SIGNATURE_SCRIPT_DIALOG (object)));
+ return;
+
+ case PROP_SCRIPT_NAME:
+ g_value_set_string (
+ value,
+ e_signature_script_dialog_get_script_name (
+ E_SIGNATURE_SCRIPT_DIALOG (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_script_dialog_dispose (GObject *object)
+{
+ ESignatureScriptDialogPrivate *priv;
+
+ priv = E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object);
+
+ if (priv->entry != NULL) {
+ g_object_unref (priv->entry);
+ priv->entry = NULL;
+ }
+
+ if (priv->file_chooser != NULL) {
+ g_object_unref (priv->file_chooser);
+ priv->file_chooser = NULL;
+ }
+
+ if (priv->alert != NULL) {
+ g_object_unref (priv->alert);
+ priv->alert = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_script_dialog_map (GtkWidget *widget)
+{
+ GtkWidget *action_area;
+ GtkWidget *content_area;
+
+ /* Chain up to parent's map() method. */
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+
+ /* XXX Override GtkDialog's broken style property defaults. */
+ action_area = gtk_dialog_get_action_area (GTK_DIALOG (widget));
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (widget));
+
+ gtk_box_set_spacing (GTK_BOX (content_area), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (action_area), 0);
+ gtk_container_set_border_width (GTK_CONTAINER (content_area), 12);
+}
+
+static void
+signature_script_dialog_class_init (ESignatureScriptDialogClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ESignatureScriptDialogPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = signature_script_dialog_set_property;
+ object_class->get_property = signature_script_dialog_get_property;
+ object_class->dispose = signature_script_dialog_dispose;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->map = signature_script_dialog_map;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCRIPT_FILE,
+ g_param_spec_object (
+ "script-file",
+ "Script File",
+ NULL,
+ G_TYPE_FILE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SCRIPT_NAME,
+ g_param_spec_string (
+ "script-name",
+ "Script Name",
+ NULL,
+ _("Unnamed"),
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+}
+
+static void
+signature_script_dialog_init (ESignatureScriptDialog *dialog)
+{
+ GtkFileFilter *filter;
+ GtkWidget *content_area;
+ GtkWidget *container;
+ GtkWidget *widget;
+ gchar *markup;
+
+ dialog->priv = E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (dialog);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ gtk_dialog_add_button (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+ gtk_dialog_add_button (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_SAVE, GTK_RESPONSE_OK);
+
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ container = content_area;
+
+ widget = gtk_table_new (4, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (widget), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (widget), 6);
+ gtk_table_set_row_spacing (GTK_TABLE (widget), 0, 12);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_image_new_from_stock (
+ GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 0, 1, 0, 1, 0, 0, 0, 0);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (_(
+ "The output of this script will be used as your\n"
+ "signature. The name you specify will be used\n"
+ "for display purposes only."));
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_widget_show (widget);
+
+ widget = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ dialog->priv->entry = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new_with_mnemonic (_("_Name:"));
+ gtk_label_set_mnemonic_widget (
+ GTK_LABEL (widget), dialog->priv->entry);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
+ gtk_widget_show (widget);
+
+ widget = gtk_file_chooser_button_new (
+ NULL, GTK_FILE_CHOOSER_ACTION_OPEN);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ dialog->priv->file_chooser = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ /* Restrict file selection to executable files. */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_custom (
+ filter, GTK_FILE_FILTER_FILENAME,
+ (GtkFileFilterFunc) signature_script_dialog_filter_cb,
+ NULL, NULL);
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), filter);
+
+ /* XXX ESignature stores a filename instead of a URI,
+ * so we have to restrict it to local files only. */
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
+
+ widget = gtk_label_new_with_mnemonic (_("S_cript:"));
+ gtk_label_set_mnemonic_widget (
+ GTK_LABEL (widget), dialog->priv->file_chooser);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
+ gtk_widget_show (widget);
+
+ /* This is just a placeholder. */
+ widget = gtk_label_new (NULL);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
+ gtk_widget_show (widget);
+
+ widget = gtk_hbox_new (FALSE, 6);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 3, 4, 0, 0, 0, 0);
+ dialog->priv->alert = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_image_new_from_stock (
+ GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ markup = g_markup_printf_escaped (
+ "<small>%s</small>",
+ _("Script file must be executable."));
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ g_signal_connect (
+ dialog, "notify::script-file",
+ G_CALLBACK (signature_script_dialog_update_status), NULL);
+
+ g_signal_connect (
+ dialog, "notify::script-name",
+ G_CALLBACK (signature_script_dialog_update_status), NULL);
+
+ g_signal_connect_swapped (
+ dialog->priv->entry, "changed",
+ G_CALLBACK (signature_script_dialog_update_status), dialog);
+
+ g_signal_connect_swapped (
+ dialog->priv->file_chooser, "file-set",
+ G_CALLBACK (signature_script_dialog_update_status), dialog);
+
+ signature_script_dialog_update_status (dialog);
+}
+
+GType
+e_signature_script_dialog_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ESignatureScriptDialogClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) signature_script_dialog_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ESignatureScriptDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) signature_script_dialog_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_DIALOG, "ESignatureScriptDialog",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_signature_script_dialog_new (GtkWindow *parent)
+{
+ return g_object_new (
+ E_TYPE_SIGNATURE_SCRIPT_DIALOG,
+ "transient-for", parent, NULL);
+}
+
+GFile *
+e_signature_script_dialog_get_script_file (ESignatureScriptDialog *dialog)
+{
+ GtkFileChooser *file_chooser;
+
+ g_return_val_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
+
+ file_chooser = GTK_FILE_CHOOSER (dialog->priv->file_chooser);
+
+ return gtk_file_chooser_get_file (file_chooser);
+}
+
+void
+e_signature_script_dialog_set_script_file (ESignatureScriptDialog *dialog,
+ GFile *script_file)
+{
+ GtkFileChooser *file_chooser;
+ GError *error = NULL;
+
+ g_return_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog));
+ g_return_if_fail (G_IS_FILE (script_file));
+
+ file_chooser = GTK_FILE_CHOOSER (dialog->priv->file_chooser);
+
+ if (gtk_file_chooser_set_file (file_chooser, script_file, &error))
+ g_object_notify (G_OBJECT (dialog), "script-file");
+ else {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+}
+
+const gchar *
+e_signature_script_dialog_get_script_name (ESignatureScriptDialog *dialog)
+{
+ GtkEntry *entry;
+
+ g_return_val_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
+
+ entry = GTK_ENTRY (dialog->priv->entry);
+
+ return gtk_entry_get_text (entry);
+}
+
+void
+e_signature_script_dialog_set_script_name (ESignatureScriptDialog *dialog,
+ const gchar *script_name)
+{
+ GtkEntry *entry;
+
+ g_return_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog));
+
+ if (script_name == NULL)
+ script_name = "";
+
+ entry = GTK_ENTRY (dialog->priv->entry);
+ gtk_entry_set_text (entry, script_name);
+
+ g_object_notify (G_OBJECT (dialog), "script-name");
+}
diff --git a/widgets/misc/e-signature-script-dialog.h b/widgets/misc/e-signature-script-dialog.h
new file mode 100644
index 0000000000..3967ae60c3
--- /dev/null
+++ b/widgets/misc/e-signature-script-dialog.h
@@ -0,0 +1,76 @@
+/*
+ * e-signature-script-dialog.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SIGNATURE_SCRIPT_DIALOG_H
+#define E_SIGNATURE_SCRIPT_DIALOG_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_SCRIPT_DIALOG \
+ (e_signature_script_dialog_get_type ())
+#define E_SIGNATURE_SCRIPT_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialog))
+#define E_SIGNATURE_SCRIPT_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialogClass))
+#define E_IS_SIGNATURE_SCRIPT_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG))
+#define E_IS_SIGNATURE_SCRIPT_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SIGNATURE_SCRIPT_DIALOG))
+#define E_SIGNATURE_SCRIPT_DIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialogClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignatureScriptDialog ESignatureScriptDialog;
+typedef struct _ESignatureScriptDialogClass ESignatureScriptDialogClass;
+typedef struct _ESignatureScriptDialogPrivate ESignatureScriptDialogPrivate;
+
+struct _ESignatureScriptDialog {
+ GtkDialog parent;
+ ESignatureScriptDialogPrivate *priv;
+};
+
+struct _ESignatureScriptDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType e_signature_script_dialog_get_type (void);
+GtkWidget * e_signature_script_dialog_new (GtkWindow *parent);
+GFile * e_signature_script_dialog_get_script_file
+ (ESignatureScriptDialog *dialog);
+void e_signature_script_dialog_set_script_file
+ (ESignatureScriptDialog *dialog,
+ GFile *script_file);
+const gchar * e_signature_script_dialog_get_script_name
+ (ESignatureScriptDialog *dialog);
+void e_signature_script_dialog_set_script_name
+ (ESignatureScriptDialog *dialog,
+ const gchar *script_name);
+
+G_END_DECLS
+
+#endif /* E_SIGNATURE_SCRIPT_DIALOG_H */
diff --git a/widgets/misc/e-signature-tree-view.c b/widgets/misc/e-signature-tree-view.c
new file mode 100644
index 0000000000..5c931c8d93
--- /dev/null
+++ b/widgets/misc/e-signature-tree-view.c
@@ -0,0 +1,448 @@
+/*
+ * e-signature-tree-view.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-signature-tree-view.h"
+
+#define E_SIGNATURE_TREE_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SIGNATURE_TREE_VIEW, ESignatureTreeViewPrivate))
+
+enum {
+ COLUMN_STRING,
+ COLUMN_SIGNATURE
+};
+
+enum {
+ PROP_0,
+ PROP_SELECTED,
+ PROP_SIGNATURE_LIST
+};
+
+enum {
+ REFRESHED,
+ LAST_SIGNAL
+};
+
+struct _ESignatureTreeViewPrivate {
+ ESignatureList *signature_list;
+ GHashTable *index;
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+signature_tree_view_refresh_cb (ESignatureList *signature_list,
+ ESignature *unused,
+ ESignatureTreeView *tree_view)
+{
+ GtkListStore *store;
+ GtkTreeModel *model;
+ GtkTreeIter tree_iter;
+ EIterator *signature_iter;
+ ESignature *signature;
+ GHashTable *index;
+ GList *list = NULL;
+ GList *iter;
+
+ store = gtk_list_store_new (2, G_TYPE_STRING, E_TYPE_SIGNATURE);
+ model = GTK_TREE_MODEL (store);
+ index = tree_view->priv->index;
+
+ g_hash_table_remove_all (index);
+
+ if (signature_list == NULL)
+ goto skip;
+
+ /* Build a list of ESignatures to display. */
+ signature_iter = e_list_get_iterator (E_LIST (signature_list));
+ while (e_iterator_is_valid (signature_iter)) {
+
+ /* XXX EIterator misuses const. */
+ signature = (ESignature *) e_iterator_get (signature_iter);
+ list = g_list_prepend (list, signature);
+ e_iterator_next (signature_iter);
+ }
+ g_object_unref (signature_iter);
+
+ list = g_list_reverse (list);
+
+ /* Populate the list store and index. */
+ for (iter = list; iter != NULL; iter = iter->next) {
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
+ const gchar *name;
+
+ signature = iter->data;
+
+ /* Skip autogenerated signatures. */
+ if (e_signature_get_autogenerated (signature))
+ continue;
+
+ name = e_signature_get_name (signature);
+
+ gtk_list_store_append (store, &tree_iter);
+ gtk_list_store_set (
+ store, &tree_iter,
+ COLUMN_STRING, name,
+ COLUMN_SIGNATURE, signature, -1);
+
+ path = gtk_tree_model_get_path (model, &tree_iter);
+ reference = gtk_tree_row_reference_new (model, path);
+ g_hash_table_insert (index, signature, reference);
+ gtk_tree_path_free (path);
+ }
+
+skip:
+ /* Restore the previously selected signature. */
+ signature = e_signature_tree_view_get_selected (tree_view);
+ if (signature != NULL)
+ g_object_ref (signature);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model);
+ e_signature_tree_view_set_selected (tree_view, signature);
+ if (signature != NULL)
+ g_object_unref (signature);
+
+ g_signal_emit (tree_view, signals[REFRESHED], 0);
+}
+
+static void
+signature_tree_view_selection_changed_cb (ESignatureTreeView *tree_view)
+{
+ g_object_notify (G_OBJECT (tree_view), "selected");
+}
+
+static GObject *
+signature_tree_view_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *object;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ /* Chain up to parent's constructor() method. */
+ object = G_OBJECT_CLASS (parent_class)->constructor (
+ type, n_construct_properties, construct_properties);
+
+ tree_view = GTK_TREE_VIEW (object);
+ gtk_tree_view_set_headers_visible (tree_view, FALSE);
+
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_add_attribute (
+ column, renderer, "text", COLUMN_STRING);
+ gtk_tree_view_append_column (tree_view, column);
+
+ return object;
+}
+
+static void
+signature_tree_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SELECTED:
+ e_signature_tree_view_set_selected (
+ E_SIGNATURE_TREE_VIEW (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SIGNATURE_LIST:
+ e_signature_tree_view_set_signature_list (
+ E_SIGNATURE_TREE_VIEW (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_tree_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SELECTED:
+ g_value_set_object (
+ value,
+ e_signature_tree_view_get_selected (
+ E_SIGNATURE_TREE_VIEW (object)));
+ return;
+
+ case PROP_SIGNATURE_LIST:
+ g_value_set_object (
+ value,
+ e_signature_tree_view_get_signature_list (
+ E_SIGNATURE_TREE_VIEW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_tree_view_dispose (GObject *object)
+{
+ ESignatureTreeViewPrivate *priv;
+
+ priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (object);
+
+ if (priv->signature_list != NULL) {
+ g_signal_handlers_disconnect_by_func (
+ priv->signature_list,
+ signature_tree_view_refresh_cb, object);
+ g_object_unref (priv->signature_list);
+ priv->signature_list = NULL;
+ }
+
+ g_hash_table_remove_all (priv->index);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+signature_tree_view_finalize (GObject *object)
+{
+ ESignatureTreeViewPrivate *priv;
+
+ priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->index);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+signature_tree_view_class_init (ESignatureTreeViewClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ESignatureTreeViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructor = signature_tree_view_constructor;
+ object_class->set_property = signature_tree_view_set_property;
+ object_class->get_property = signature_tree_view_get_property;
+ object_class->dispose = signature_tree_view_dispose;
+ object_class->finalize = signature_tree_view_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTED,
+ g_param_spec_object (
+ "selected",
+ "Selected Signature",
+ NULL,
+ E_TYPE_SIGNATURE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SIGNATURE_LIST,
+ g_param_spec_object (
+ "signature-list",
+ "Signature List",
+ NULL,
+ E_TYPE_SIGNATURE_LIST,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[REFRESHED] = g_signal_new (
+ "refreshed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+signature_tree_view_init (ESignatureTreeView *tree_view)
+{
+ GHashTable *index;
+ GtkTreeSelection *selection;
+
+ /* Reverse-lookup index */
+ index = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) gtk_tree_row_reference_free);
+
+ tree_view->priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (tree_view);
+ tree_view->priv->index = index;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (signature_tree_view_selection_changed_cb),
+ tree_view);
+}
+
+GType
+e_signature_tree_view_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ESignatureTreeViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) signature_tree_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ESignatureTreeView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) signature_tree_view_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TREE_VIEW, "ESignatureTreeView",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_signature_tree_view_new (void)
+{
+ return g_object_new (E_TYPE_SIGNATURE_TREE_VIEW, NULL);
+}
+
+ESignatureList *
+e_signature_tree_view_get_signature_list (ESignatureTreeView *tree_view)
+{
+ g_return_val_if_fail (E_IS_SIGNATURE_TREE_VIEW (tree_view), NULL);
+
+ return tree_view->priv->signature_list;
+}
+
+void
+e_signature_tree_view_set_signature_list (ESignatureTreeView *tree_view,
+ ESignatureList *signature_list)
+{
+ ESignatureTreeViewPrivate *priv;
+
+ g_return_if_fail (E_IS_SIGNATURE_TREE_VIEW (tree_view));
+
+ if (signature_list != NULL)
+ g_return_if_fail (E_IS_SIGNATURE_LIST (signature_list));
+
+ priv = E_SIGNATURE_TREE_VIEW_GET_PRIVATE (tree_view);
+
+ if (priv->signature_list != NULL) {
+ g_signal_handlers_disconnect_by_func (
+ priv->signature_list,
+ signature_tree_view_refresh_cb, tree_view);
+ g_object_unref (priv->signature_list);
+ priv->signature_list = NULL;
+ }
+
+ if (signature_list != NULL) {
+ priv->signature_list = g_object_ref (signature_list);
+
+ /* Listen for changes to the signature list. */
+ g_signal_connect (
+ priv->signature_list, "signature-added",
+ G_CALLBACK (signature_tree_view_refresh_cb),
+ tree_view);
+ g_signal_connect (
+ priv->signature_list, "signature-changed",
+ G_CALLBACK (signature_tree_view_refresh_cb),
+ tree_view);
+ g_signal_connect (
+ priv->signature_list, "signature-removed",
+ G_CALLBACK (signature_tree_view_refresh_cb),
+ tree_view);
+ }
+
+ signature_tree_view_refresh_cb (signature_list, NULL, tree_view);
+
+ g_object_notify (G_OBJECT (tree_view), "signature-list");
+}
+
+ESignature *
+e_signature_tree_view_get_selected (ESignatureTreeView *tree_view)
+{
+ ESignature *signature;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_val_if_fail (E_IS_SIGNATURE_TREE_VIEW (tree_view), NULL);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COLUMN_SIGNATURE, &signature, -1);
+
+ return signature;
+}
+
+gboolean
+e_signature_tree_view_set_selected (ESignatureTreeView *tree_view,
+ ESignature *signature)
+{
+ GtkTreeRowReference *reference;
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+
+ g_return_val_if_fail (E_IS_SIGNATURE_TREE_VIEW (tree_view), FALSE);
+
+ if (signature != NULL)
+ g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ /* NULL means clear the selection. */
+ if (signature == NULL) {
+ gtk_tree_selection_unselect_all (selection);
+ return TRUE;
+ }
+
+ /* Lookup the tree row reference for the signature. */
+ reference = g_hash_table_lookup (tree_view->priv->index, signature);
+ if (reference == NULL)
+ return FALSE;
+
+ /* Select the referenced path. */
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+
+ g_object_notify (G_OBJECT (tree_view), "selected");
+
+ return TRUE;
+}
diff --git a/widgets/misc/e-signature-tree-view.h b/widgets/misc/e-signature-tree-view.h
new file mode 100644
index 0000000000..50d1e11905
--- /dev/null
+++ b/widgets/misc/e-signature-tree-view.h
@@ -0,0 +1,78 @@
+/*
+ * e-signature-tree-view.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_SIGNATURE_TREE_VIEW_H
+#define E_SIGNATURE_TREE_VIEW_H
+
+#include <gtk/gtk.h>
+#include <e-util/e-signature.h>
+#include <e-util/e-signature-list.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE_TREE_VIEW \
+ (e_signature_tree_view_get_type ())
+#define E_SIGNATURE_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SIGNATURE_TREE_VIEW, ESignatureTreeView))
+#define E_SIGNATURE_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SIGNATURE_TREE_VIEW, ESignatureTreeViewClass))
+#define E_IS_SIGNATURE_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SIGNATURE_TREE_VIEW))
+#define E_IS_SIGNATURE_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SIGNATURE_TREE_VIEW))
+#define E_SIGNATURE_TREE_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SIGNATURE_TREE_VIEW, ESignatureTreeViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESignatureTreeView ESignatureTreeView;
+typedef struct _ESignatureTreeViewClass ESignatureTreeViewClass;
+typedef struct _ESignatureTreeViewPrivate ESignatureTreeViewPrivate;
+
+struct _ESignatureTreeView {
+ GtkTreeView parent;
+ ESignatureTreeViewPrivate *priv;
+};
+
+struct _ESignatureTreeViewClass {
+ GtkTreeViewClass parent_class;
+};
+
+GType e_signature_tree_view_get_type (void);
+GtkWidget * e_signature_tree_view_new (void);
+ESignatureList *e_signature_tree_view_get_signature_list
+ (ESignatureTreeView *tree_view);
+void e_signature_tree_view_set_signature_list
+ (ESignatureTreeView *tree_view,
+ ESignatureList *signature_list);
+ESignature * e_signature_tree_view_get_selected
+ (ESignatureTreeView *tree_view);
+gboolean e_signature_tree_view_set_selected
+ (ESignatureTreeView *tree_view,
+ ESignature *signature);
+
+G_END_DECLS
+
+#endif /* E_SIGNATURE_TREE_VIEW_H */
diff --git a/widgets/misc/e-task-bar.c b/widgets/misc/e-task-bar.c
deleted file mode 100644
index e7fc15fe00..0000000000
--- a/widgets/misc/e-task-bar.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-task-bar.h"
-
-struct _ETaskBarPrivate
-{
- GtkWidget *message_label;
- GtkHBox *hbox;
-};
-
-/* WARNING: Ugly hack starts here. */
-#define MAX_ACTIVITIES_PER_COMPONENT 2
-
-G_DEFINE_TYPE (ETaskBar, e_task_bar, GTK_TYPE_HBOX)
-
-#if 0
-static void
-reduce_displayed_activities_per_component (ETaskBar *task_bar)
-{
- GHashTable *component_ids_hash;
- GtkBox *box;
- GList *p;
-
- component_ids_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- box = GTK_BOX (task_bar->priv->hbox);
-
- for (p = box->children; p != NULL; p = p->next) {
- GtkBoxChild *child;
- const gchar *component_id;
- gpointer hash_item;
-
- child = (GtkBoxChild *) p->data;
- component_id = e_task_widget_get_component_id (E_TASK_WIDGET (child->widget));
-
- hash_item = g_hash_table_lookup (component_ids_hash, component_id);
-
- if (hash_item == NULL) {
- gtk_widget_show (child->widget);
- g_hash_table_insert (component_ids_hash, (gpointer) component_id, GINT_TO_POINTER (1));
- } else {
- gint num_items;
-
- num_items = GPOINTER_TO_INT (hash_item);
- g_return_if_fail (num_items <= MAX_ACTIVITIES_PER_COMPONENT);
-
- if (num_items == MAX_ACTIVITIES_PER_COMPONENT) {
- gtk_widget_hide (child->widget);
- } else {
- num_items ++;
- gtk_widget_show (child->widget);
- g_hash_table_insert (component_ids_hash, (gpointer) component_id, GINT_TO_POINTER (num_items));
- }
- }
- }
-
- g_hash_table_destroy (component_ids_hash);
-}
-#endif
-
-
-static void impl_finalize (GObject *object);
-
-static void
-e_task_bar_class_init (ETaskBarClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_task_bar_init (ETaskBar *task_bar)
-{
- GtkWidget *label, *hbox;
- gint height;
-
- task_bar->priv = g_new (ETaskBarPrivate, 1);
-
- gtk_box_set_spacing (GTK_BOX (task_bar), 10);
-
- label = gtk_label_new (NULL);
- gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
- gtk_box_pack_start (GTK_BOX (task_bar), label, TRUE, TRUE, 0);
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
- task_bar->priv->message_label = label;
-
- hbox = gtk_hbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (task_bar), hbox);
- task_bar->priv->hbox = GTK_HBOX (hbox);
-
- /* Make the task bar large enough to accomodate a small icon.
- * XXX The "* 2" is a fudge factor to allow for some padding.
- * The true value is probably buried in a style property. */
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
- gtk_widget_set_size_request (GTK_WIDGET (task_bar), -1, height * 2);
-}
-
-static void
-impl_finalize (GObject *object)
-{
- ETaskBar *task_bar;
- ETaskBarPrivate *priv;
-
- task_bar = E_TASK_BAR (object);
- priv = task_bar->priv;
-
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_task_bar_parent_class)->finalize) (object);
-}
-
-
-void
-e_task_bar_construct (ETaskBar *task_bar)
-{
- g_return_if_fail (task_bar != NULL);
- g_return_if_fail (E_IS_TASK_BAR (task_bar));
-
- /* Nothing to do here. */
-}
-
-GtkWidget *
-e_task_bar_new (void)
-{
- ETaskBar *task_bar;
-
- task_bar = g_object_new (e_task_bar_get_type (), NULL);
- e_task_bar_construct (task_bar);
-
- return GTK_WIDGET (task_bar);
-}
-
-void
-e_task_bar_set_message (ETaskBar *task_bar,
- const gchar *message)
-{
- if (message) {
- gtk_label_set_text (
- GTK_LABEL (task_bar->priv->message_label), message);
- gtk_widget_show (task_bar->priv->message_label);
- } else {
- e_task_bar_unset_message (task_bar);
- }
-}
-
-void
-e_task_bar_unset_message (ETaskBar *task_bar)
-{
- gtk_widget_hide (task_bar->priv->message_label);
-}
-
-void
-e_task_bar_prepend_task (ETaskBar *task_bar,
- ETaskWidget *task_widget)
-{
- GtkBoxChild *child_info;
- GtkBox *box;
-
- g_return_if_fail (task_bar != NULL);
- g_return_if_fail (E_IS_TASK_BAR (task_bar));
- g_return_if_fail (task_widget != NULL);
- g_return_if_fail (E_IS_TASK_WIDGET (task_widget));
-
- /* Hah hah. GTK+ sucks. This is adapted from `gtkhbox.c'. */
-
- child_info = g_new (GtkBoxChild, 1);
- child_info->widget = GTK_WIDGET (task_widget);
- child_info->padding = 0;
- child_info->expand = TRUE;
- child_info->fill = TRUE;
- child_info->pack = GTK_PACK_START;
-
- box = GTK_BOX (task_bar->priv->hbox);
-
- box->children = g_list_prepend (box->children, child_info);
-
- gtk_widget_set_parent (GTK_WIDGET (task_widget), GTK_WIDGET (task_bar->priv->hbox));
-
- if (GTK_WIDGET_REALIZED (task_bar))
- gtk_widget_realize (GTK_WIDGET (task_widget));
-
- if (GTK_WIDGET_VISIBLE (task_bar) && GTK_WIDGET_VISIBLE (task_widget)) {
- if (GTK_WIDGET_MAPPED (task_bar))
- gtk_widget_map (GTK_WIDGET (task_widget));
- gtk_widget_queue_resize (GTK_WIDGET (task_widget));
- }
-
- /* We don't restrict */
- /* reduce_displayed_activities_per_component (task_bar);*/
-
- gtk_widget_show (GTK_WIDGET (task_bar->priv->hbox));
-}
-
-void
-e_task_bar_remove_task_from_id (ETaskBar *task_bar,
- guint id)
-{
- ETaskWidget *task_widget;
-
- g_return_if_fail (task_bar != NULL);
- g_return_if_fail (E_IS_TASK_BAR (task_bar));
-
- task_widget = e_task_bar_get_task_widget_from_id (task_bar, id);
- if (!task_widget) {
- printf("Failed...\n");
- return;
- }
-
- gtk_widget_destroy (GTK_WIDGET (task_widget));
-
- /* We don't restrict here on */
- /* reduce_displayed_activities_per_component (task_bar); */
-
- if (g_list_length (GTK_BOX (task_bar->priv->hbox)->children) == 0)
- gtk_widget_hide (GTK_WIDGET (task_bar->priv->hbox));
-}
-
-void
-e_task_bar_remove_task (ETaskBar *task_bar,
- gint n)
-{
- ETaskWidget *task_widget;
-
- g_return_if_fail (task_bar != NULL);
- g_return_if_fail (E_IS_TASK_BAR (task_bar));
- g_return_if_fail (n >= 0);
-
- task_widget = e_task_bar_get_task_widget (task_bar, n);
- gtk_widget_destroy (GTK_WIDGET (task_widget));
-
- /* We don't restrict here on */
- /* reduce_displayed_activities_per_component (task_bar); */
-
- if (g_list_length (GTK_BOX (task_bar->priv->hbox)->children) == 0)
- gtk_widget_hide (GTK_WIDGET (task_bar->priv->hbox));
-}
-
-ETaskWidget *
-e_task_bar_get_task_widget_from_id (ETaskBar *task_bar,
- guint id)
-{
- GtkBoxChild *child_info;
- ETaskWidget *w = NULL;
- GList *list;
-
- g_return_val_if_fail (task_bar != NULL, NULL);
- g_return_val_if_fail (E_IS_TASK_BAR (task_bar), NULL);
-
- list = GTK_BOX (task_bar->priv->hbox)->children;
- while (list) {
- child_info = list->data;
- w = (ETaskWidget *) child_info->widget;
- if (w && w->id == id)
- break;
-
- w = NULL;
- list = list->next;
- }
-
- return w;
-}
-
-ETaskWidget *
-
-e_task_bar_get_task_widget (ETaskBar *task_bar,
- gint n)
-{
- GtkBoxChild *child_info;
-
- g_return_val_if_fail (task_bar != NULL, NULL);
- g_return_val_if_fail (E_IS_TASK_BAR (task_bar), NULL);
-
- child_info = (GtkBoxChild *) g_list_nth (GTK_BOX (task_bar->priv->hbox)->children, n)->data;
-
- return E_TASK_WIDGET (child_info->widget);
-}
-
-gint
-e_task_bar_get_num_children (ETaskBar *task_bar)
-{
- return g_list_length (GTK_BOX (task_bar->priv->hbox)->children);
-}
diff --git a/widgets/misc/e-task-bar.h b/widgets/misc/e-task-bar.h
deleted file mode 100644
index 19ed37a2e8..0000000000
--- a/widgets/misc/e-task-bar.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_TASK_BAR_H_
-#define _E_TASK_BAR_H_
-
-#include "e-task-widget.h"
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_TASK_BAR (e_task_bar_get_type ())
-#define E_TASK_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TASK_BAR, ETaskBar))
-#define E_TASK_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_TASK_BAR, ETaskBarClass))
-#define E_IS_TASK_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TASK_BAR))
-#define E_IS_TASK_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_TASK_BAR))
-
-
-typedef struct _ETaskBar ETaskBar;
-typedef struct _ETaskBarPrivate ETaskBarPrivate;
-typedef struct _ETaskBarClass ETaskBarClass;
-
-struct _ETaskBar {
- GtkHBox parent;
-
- ETaskBarPrivate *priv;
-};
-
-struct _ETaskBarClass {
- GtkHBoxClass parent_class;
-};
-
-
-GType e_task_bar_get_type (void);
-void e_task_bar_construct (ETaskBar *task_bar);
-GtkWidget *e_task_bar_new (void);
-
-void e_task_bar_set_message (ETaskBar *task_bar,
- const gchar *message);
-void e_task_bar_unset_message (ETaskBar *task_bar);
-
-void e_task_bar_prepend_task (ETaskBar *task_bar,
- ETaskWidget *task_widget);
-void e_task_bar_remove_task (ETaskBar *task_bar,
- gint n);
-ETaskWidget * e_task_bar_get_task_widget_from_id (ETaskBar *task_bar,
- guint id);
-
-void e_task_bar_remove_task_from_id (ETaskBar *task_bar,
- guint id);
-ETaskWidget *e_task_bar_get_task_widget (ETaskBar *task_bar,
- gint n);
-gint e_task_bar_get_num_children (ETaskBar *task_bar);
-G_END_DECLS
-
-#endif /* _E_TASK_BAR_H_ */
diff --git a/widgets/misc/e-task-widget.c b/widgets/misc/e-task-widget.c
deleted file mode 100644
index 7d583c3ffa..0000000000
--- a/widgets/misc/e-task-widget.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-task-widget.h"
-#include "e-spinner.h"
-
-#include <glib/gi18n.h>
-
-#define SPACING 2
-
-struct _ETaskWidgetPrivate {
- gchar *component_id;
-
- GtkWidget *label;
- GtkWidget *box;
- GtkWidget *image;
-
- void (*cancel_func) (gpointer data);
- gpointer data;
-};
-
-G_DEFINE_TYPE (ETaskWidget, e_task_widget, GTK_TYPE_EVENT_BOX)
-
-/* GObject methods. */
-
-static void
-impl_finalize (GObject *object)
-{
- ETaskWidget *task_widget;
- ETaskWidgetPrivate *priv;
-
- task_widget = E_TASK_WIDGET (object);
- priv = task_widget->priv;
-
- g_free (priv->component_id);
- g_free (priv);
-
- (* G_OBJECT_CLASS (e_task_widget_parent_class)->finalize) (object);
-}
-
-
-static void
-e_task_widget_class_init (ETaskWidgetClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = impl_finalize;
-}
-
-static void
-e_task_widget_init (ETaskWidget *task_widget)
-{
- ETaskWidgetPrivate *priv;
-
- priv = g_new (ETaskWidgetPrivate, 1);
-
- priv->component_id = NULL;
- priv->label = NULL;
- priv->image = NULL;
- priv->box = NULL;
-
- task_widget->priv = priv;
- task_widget->id = 0;
-}
-
-static gboolean
-button_press_event_cb (GtkWidget *w, gpointer data)
-{
- ETaskWidget *tw = (ETaskWidget *) data;
- ETaskWidgetPrivate *priv = tw->priv;
-
- priv->cancel_func (priv->data);
-
- return TRUE;
-}
-
-static gboolean
-prepare_popup (ETaskWidget *widget, GdkEventButton *event)
-{
- if (event->type != GDK_BUTTON_PRESS)
- return FALSE;
-
- if (event->button != 3)
- return FALSE;
-
- /* FIXME: Implement Cancel */
-
- return TRUE;
-}
-
-
-void
-e_task_widget_construct (ETaskWidget *task_widget,
- const gchar *component_id,
- const gchar *information,
- void (*cancel_func) (gpointer data),
- gpointer data)
-{
- ETaskWidgetPrivate *priv;
- GtkWidget *box;
- GtkWidget *frame;
-
- g_return_if_fail (task_widget != NULL);
- g_return_if_fail (E_IS_TASK_WIDGET (task_widget));
- g_return_if_fail (component_id != NULL);
- g_return_if_fail (information != NULL);
-
- priv = task_widget->priv;
-
- priv->component_id = g_strdup (component_id);
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (task_widget), frame);
- gtk_widget_show (frame);
-
- box = gtk_hbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (frame), box);
- gtk_widget_show (box);
-
- gtk_widget_set_size_request (box, 1, -1);
-
- priv->box = gtk_hbox_new (FALSE, 0);
- priv->image = e_spinner_new_spinning_small_shown ();
- gtk_widget_show (priv->box);
- gtk_box_pack_start (GTK_BOX (priv->box), priv->image, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (box), priv->box, FALSE, TRUE, 0);
- priv->label = gtk_label_new ("");
- gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.5);
- gtk_widget_show (priv->label);
- gtk_box_pack_start (GTK_BOX (box), priv->label, TRUE, TRUE, 0);
- if (cancel_func) {
- GdkPixbuf *pixbuf;
- GtkWidget *image;
- GtkWidget *tool;
-
- pixbuf = gtk_icon_theme_load_icon (
- gtk_icon_theme_get_default (),
- "gtk-stop", 16, 0, NULL);
- image = gtk_image_new_from_pixbuf (pixbuf);
- g_object_unref (pixbuf);
-
- tool = (GtkWidget *) gtk_tool_button_new (image, NULL);
- gtk_box_pack_end (GTK_BOX (box), tool, FALSE, TRUE, 0);
- gtk_widget_show_all (tool);
-
- gtk_widget_set_sensitive (tool, cancel_func != NULL);
- priv->cancel_func = cancel_func;
- priv->data = data;
- g_signal_connect (tool, "clicked", G_CALLBACK (button_press_event_cb), task_widget);
- g_signal_connect (task_widget, "button-press-event", G_CALLBACK (prepare_popup), task_widget);
-
- }
-
- e_task_widget_update (task_widget, information, -1.0);
-}
-
-GtkWidget *
-e_task_widget_new_with_cancel (const gchar *component_id,
- const gchar *information,
- void (*cancel_func) (gpointer data),
- gpointer data)
-{
- ETaskWidget *task_widget;
-
- g_return_val_if_fail (information != NULL, NULL);
-
- task_widget = g_object_new (e_task_widget_get_type (), NULL);
- e_task_widget_construct (task_widget, component_id, information, cancel_func, data);
-
- return GTK_WIDGET (task_widget);
-}
-
-GtkWidget *
-e_task_widget_new (const gchar *component_id,
- const gchar *information)
-{
- ETaskWidget *task_widget;
-
- g_return_val_if_fail (information != NULL, NULL);
-
- task_widget = g_object_new (e_task_widget_get_type (), NULL);
- e_task_widget_construct (task_widget, component_id, information, NULL, NULL);
-
- return GTK_WIDGET (task_widget);
-}
-
-GtkWidget *
-e_task_widget_update_image (ETaskWidget *task_widget,
- const gchar *stock, const gchar *text)
-{
- GtkWidget *image, *tool;
- GdkPixbuf *pixbuf;
-
- pixbuf = gtk_icon_theme_load_icon (
- gtk_icon_theme_get_default (),
- stock, 16, 0, NULL);
- image = gtk_image_new_from_pixbuf (pixbuf);
- g_object_unref (pixbuf);
-
- tool = (GtkWidget *) gtk_tool_button_new (image, NULL);
- gtk_box_pack_start (GTK_BOX(task_widget->priv->box), tool, FALSE, TRUE, 0);
- gtk_widget_show_all (task_widget->priv->box);
- gtk_widget_hide (task_widget->priv->image);
- task_widget->priv->image = image;
- gtk_label_set_text (GTK_LABEL (task_widget->priv->label), text);
-
- return tool;
-}
-
-
-void
-e_task_widget_update (ETaskWidget *task_widget,
- const gchar *information,
- double completion)
-{
- ETaskWidgetPrivate *priv;
- gchar *text;
-
- g_return_if_fail (task_widget != NULL);
- g_return_if_fail (E_IS_TASK_WIDGET (task_widget));
- g_return_if_fail (information != NULL);
-
- priv = task_widget->priv;
-
- if (completion < 0.0) {
- /* For Translator only: %s is status message that is displayed (eg "moving items", "updating objects") */
- text = g_strdup_printf (_("%s (...)"), information);
- } else {
- gint percent_complete;
- percent_complete = (gint) (completion * 100.0 + .5);
- /* For Translator only: %s is status message that is displayed (eg "moving items", "updating objects");
- %d is a number between 0 and 100, describing the percentage of operation complete */
- text = g_strdup_printf (_("%s (%d%% complete)"), information, percent_complete);
- }
-
- gtk_label_set_text (GTK_LABEL (priv->label), text);
-
- gtk_widget_set_tooltip_text (GTK_WIDGET (task_widget), text);
-
- g_free (text);
-}
-
-void
-e_task_wiget_alert (ETaskWidget *task_widget)
-{
- g_return_if_fail (task_widget != NULL);
- g_return_if_fail (E_IS_TASK_WIDGET (task_widget));
-}
-
-void
-e_task_wiget_unalert (ETaskWidget *task_widget)
-{
- g_return_if_fail (task_widget != NULL);
- g_return_if_fail (E_IS_TASK_WIDGET (task_widget));
-}
-
-
-const gchar *
-e_task_widget_get_component_id (ETaskWidget *task_widget)
-{
- g_return_val_if_fail (task_widget != NULL, NULL);
- g_return_val_if_fail (E_IS_TASK_WIDGET (task_widget), NULL);
-
- return task_widget->priv->component_id;
-}
-
diff --git a/widgets/misc/e-task-widget.h b/widgets/misc/e-task-widget.h
deleted file mode 100644
index b650bd8ac5..0000000000
--- a/widgets/misc/e-task-widget.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_TASK_WIDGET_H_
-#define _E_TASK_WIDGET_H_
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define E_TYPE_TASK_WIDGET (e_task_widget_get_type ())
-#define E_TASK_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TASK_WIDGET, ETaskWidget))
-#define E_TASK_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_TASK_WIDGET, ETaskWidgetClass))
-#define E_IS_TASK_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TASK_WIDGET))
-#define E_IS_TASK_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_TASK_WIDGET))
-
-
-typedef struct _ETaskWidget ETaskWidget;
-typedef struct _ETaskWidgetPrivate ETaskWidgetPrivate;
-typedef struct _ETaskWidgetClass ETaskWidgetClass;
-
-struct _ETaskWidget {
- GtkEventBox parent;
-
- ETaskWidgetPrivate *priv;
- guint id;
-};
-
-struct _ETaskWidgetClass {
- GtkEventBoxClass parent_class;
-};
-
-
-GType e_task_widget_get_type (void);
-void e_task_widget_construct (ETaskWidget *task_widget,
- const gchar *component_id,
- const gchar *information,
- void (*cancel_func) (gpointer data),
- gpointer data);
-GtkWidget * e_task_widget_new (const gchar *component_id,
- const gchar *information);
-GtkWidget * e_task_widget_new_with_cancel (const gchar *component_id,
- const gchar *information,
- void (*cancel_func) (gpointer data),
- gpointer data);
-void e_task_widget_update (ETaskWidget *task_widget,
- const gchar *information,
- double completion);
-GtkWidget * e_task_widget_update_image (ETaskWidget *task_widget,
- const gchar *stock,
- const gchar *text);
-void e_task_wiget_alert (ETaskWidget *task_widget);
-void e_task_wiget_unalert (ETaskWidget *task_widget);
-const gchar * e_task_widget_get_component_id (ETaskWidget *task_widget);
-
-G_END_DECLS
-
-#endif /* _E_TASK_WIDGET_H_ */
diff --git a/widgets/misc/e-timeout-activity.c b/widgets/misc/e-timeout-activity.c
new file mode 100644
index 0000000000..aa57960fe0
--- /dev/null
+++ b/widgets/misc/e-timeout-activity.c
@@ -0,0 +1,198 @@
+/*
+ * e-timeout-activity.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-timeout-activity.h"
+
+#include <stdarg.h>
+
+#define E_TIMEOUT_ACTIVITY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivityPrivate))
+
+struct _ETimeoutActivityPrivate {
+ guint timeout_id;
+};
+
+enum {
+ TIMEOUT,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static gulong signals[LAST_SIGNAL];
+
+static gboolean
+timeout_activity_cb (ETimeoutActivity *timeout_activity)
+{
+ g_signal_emit (timeout_activity, signals[TIMEOUT], 0);
+
+ return FALSE;
+}
+
+static void
+timeout_activity_finalize (GObject *object)
+{
+ ETimeoutActivityPrivate *priv;
+
+ priv = E_TIMEOUT_ACTIVITY_GET_PRIVATE (object);
+
+ if (priv->timeout_id > 0)
+ g_source_remove (priv->timeout_id);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+timeout_activity_cancelled (EActivity *activity)
+{
+ ETimeoutActivityPrivate *priv;
+
+ priv = E_TIMEOUT_ACTIVITY_GET_PRIVATE (activity);
+
+ if (priv->timeout_id > 0) {
+ g_source_remove (priv->timeout_id);
+ priv->timeout_id = 0;
+ }
+
+ /* Chain up to parent's cancelled() method. */
+ E_ACTIVITY_CLASS (parent_class)->cancelled (activity);
+}
+
+static void
+timeout_activity_completed (EActivity *activity)
+{
+ ETimeoutActivityPrivate *priv;
+
+ priv = E_TIMEOUT_ACTIVITY_GET_PRIVATE (activity);
+
+ if (priv->timeout_id > 0) {
+ g_source_remove (priv->timeout_id);
+ priv->timeout_id = 0;
+ }
+
+ /* Chain up to parent's completed() method. */
+ E_ACTIVITY_CLASS (parent_class)->completed (activity);
+}
+
+static void
+timeout_activity_timeout (ETimeoutActivity *timeout_activity)
+{
+ /* Allow subclasses to safely chain up. */
+}
+
+static void
+timeout_activity_class_init (ETimeoutActivityClass *class)
+{
+ GObjectClass *object_class;
+ EActivityClass *activity_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ETimeoutActivityPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = timeout_activity_finalize;
+
+ activity_class = E_ACTIVITY_CLASS (class);
+ activity_class->cancelled = timeout_activity_cancelled;
+ activity_class->completed = timeout_activity_completed;
+
+ class->timeout = timeout_activity_timeout;
+
+ signals[TIMEOUT] = g_signal_new (
+ "timeout",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (ETimeoutActivityClass, timeout),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+timeout_activity_init (ETimeoutActivity *timeout_activity)
+{
+ timeout_activity->priv =
+ E_TIMEOUT_ACTIVITY_GET_PRIVATE (timeout_activity);
+}
+
+GType
+e_timeout_activity_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ETimeoutActivityClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) timeout_activity_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ETimeoutActivity),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) timeout_activity_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ E_TYPE_ACTIVITY, "ETimeoutActivity", &type_info, 0);
+ }
+
+ return type;
+}
+
+EActivity *
+e_timeout_activity_new (const gchar *primary_text)
+{
+ return g_object_new (
+ E_TYPE_TIMEOUT_ACTIVITY,
+ "primary-text", primary_text, NULL);
+}
+
+EActivity *
+e_timeout_activity_newv (const gchar *format, ...)
+{
+ EActivity *activity;
+ gchar *primary_text;
+ va_list args;
+
+ va_start (args, format);
+ primary_text = g_strdup_vprintf (format, args);
+ activity = e_timeout_activity_new (primary_text);
+ g_free (primary_text);
+ va_end (args);
+
+ return activity;
+}
+
+void
+e_timeout_activity_set_timeout (ETimeoutActivity *timeout_activity,
+ guint seconds)
+{
+ g_return_if_fail (E_IS_TIMEOUT_ACTIVITY (timeout_activity));
+
+ if (timeout_activity->priv->timeout_id > 0)
+ e_activity_cancel (E_ACTIVITY (timeout_activity));
+
+ timeout_activity->priv->timeout_id = g_timeout_add_seconds (
+ seconds, (GSourceFunc) timeout_activity_cb, timeout_activity);
+}
diff --git a/widgets/misc/e-timeout-activity.h b/widgets/misc/e-timeout-activity.h
new file mode 100644
index 0000000000..82dd1138c2
--- /dev/null
+++ b/widgets/misc/e-timeout-activity.h
@@ -0,0 +1,73 @@
+/*
+ * e-timeout-activity.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_TIMEOUT_ACTIVITY_H
+#define E_TIMEOUT_ACTIVITY_H
+
+#include <e-activity.h>
+
+/* Standard GObject macros */
+#define E_TYPE_TIMEOUT_ACTIVITY \
+ (e_timeout_activity_get_type ())
+#define E_TIMEOUT_ACTIVITY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivity))
+#define E_TIMEOUT_ACTIVITY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivityClass))
+#define E_IS_TIMEOUT_ACTIVITY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_TIMEOUT_ACTIVITY))
+#define E_IS_TIMEOUT_ACTIVITY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_TIMEOUT_ACTIVITY))
+#define E_TIMEOUT_ACTIVITY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_TIMEOUT_ACTIVITY, ETimeoutActivityClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ETimeoutActivity ETimeoutActivity;
+typedef struct _ETimeoutActivityClass ETimeoutActivityClass;
+typedef struct _ETimeoutActivityPrivate ETimeoutActivityPrivate;
+
+struct _ETimeoutActivity {
+ EActivity parent;
+ ETimeoutActivityPrivate *priv;
+};
+
+struct _ETimeoutActivityClass {
+ EActivityClass parent_class;
+
+ /* Signals */
+ void (*timeout) (ETimeoutActivity *timeout_activity);
+};
+
+GType e_timeout_activity_get_type (void);
+EActivity * e_timeout_activity_new (const gchar *primary_text);
+EActivity * e_timeout_activity_newv (const gchar *format,
+ ...) G_GNUC_PRINTF (1, 2);
+void e_timeout_activity_set_timeout (ETimeoutActivity *timeout_activity,
+ guint seconds);
+
+G_END_DECLS
+
+#endif /* E_TIMEOUT_ACTIVITY_H */
diff --git a/a11y/widgets/ea-calendar-cell.c b/widgets/misc/ea-calendar-cell.c
index 4b2f3d2ab4..05d0dcce6b 100644
--- a/a11y/widgets/ea-calendar-cell.c
+++ b/widgets/misc/ea-calendar-cell.c
@@ -25,7 +25,7 @@
#include <e-util/e-util.h>
#include "ea-calendar-cell.h"
#include "ea-calendar-item.h"
-#include "ea-factory.h"
+#include "a11y/ea-factory.h"
/* ECalendarCell */
diff --git a/a11y/widgets/ea-calendar-cell.h b/widgets/misc/ea-calendar-cell.h
index fa68fdca55..fa68fdca55 100644
--- a/a11y/widgets/ea-calendar-cell.h
+++ b/widgets/misc/ea-calendar-cell.h
diff --git a/a11y/widgets/ea-calendar-item.c b/widgets/misc/ea-calendar-item.c
index 9dcb83449c..9dcb83449c 100644
--- a/a11y/widgets/ea-calendar-item.c
+++ b/widgets/misc/ea-calendar-item.c
diff --git a/a11y/widgets/ea-calendar-item.h b/widgets/misc/ea-calendar-item.h
index b5271a9f8b..b5271a9f8b 100644
--- a/a11y/widgets/ea-calendar-item.h
+++ b/widgets/misc/ea-calendar-item.h
diff --git a/a11y/ea-cell-table.c b/widgets/misc/ea-cell-table.c
index 95ae59dea4..95ae59dea4 100644
--- a/a11y/ea-cell-table.c
+++ b/widgets/misc/ea-cell-table.c
diff --git a/a11y/ea-cell-table.h b/widgets/misc/ea-cell-table.h
index 353bbd0634..353bbd0634 100644
--- a/a11y/ea-cell-table.h
+++ b/widgets/misc/ea-cell-table.h
diff --git a/a11y/widgets/ea-widgets.c b/widgets/misc/ea-widgets.c
index 3dca419104..9deede235e 100644
--- a/a11y/widgets/ea-widgets.c
+++ b/widgets/misc/ea-widgets.c
@@ -20,20 +20,13 @@
*
*/
-#include "ea-factory.h"
-#include "widgets/ea-calendar-item.h"
-#include "widgets/ea-combo-button.h"
+#include "a11y/ea-factory.h"
+#include "ea-calendar-item.h"
#include "ea-widgets.h"
EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_ITEM, ea_calendar_item, ea_calendar_item_new)
-EA_FACTORY (EA_TYPE_COMBO_BUTTON, ea_combo_button, ea_combo_button_new)
void e_calendar_item_a11y_init (void)
{
EA_SET_FACTORY (e_calendar_item_get_type (), ea_calendar_item);
}
-
-void e_combo_button_a11y_init (void)
-{
- EA_SET_FACTORY (e_combo_button_get_type (), ea_combo_button);
-}
diff --git a/a11y/widgets/ea-widgets.h b/widgets/misc/ea-widgets.h
index c07526f4fd..495222ae05 100644
--- a/a11y/widgets/ea-widgets.h
+++ b/widgets/misc/ea-widgets.h
@@ -28,6 +28,5 @@
#define _EA_WIDGETS_H__
void e_calendar_item_a11y_init (void);
-void e_combo_button_a11y_init (void);
#endif /* _EA_WIDGETS_H__ */
diff --git a/widgets/misc/test-calendar.c b/widgets/misc/test-calendar.c
index c9cc8e7891..458d60f90a 100644
--- a/widgets/misc/test-calendar.c
+++ b/widgets/misc/test-calendar.c
@@ -114,7 +114,7 @@ on_date_range_changed (ECalendarItem *calitem)
start_day, start_month + 1, start_year,
end_day, end_month + 1, end_year);
- /* These days should appear bold. Remember month is 0 to 11. */
+ /* These days should windowear bold. Remember month is 0 to 11. */
e_calendar_item_mark_day (calitem, 2000, 7, 26, /* 26th Aug 2000. */
E_CALENDAR_ITEM_MARK_BOLD, FALSE);
e_calendar_item_mark_day (calitem, 2000, 8, 13, /* 13th Sep 2000. */
diff --git a/widgets/misc/test-dropdown-button.c b/widgets/misc/test-dropdown-button.c
deleted file mode 100644
index 7320fb9bac..0000000000
--- a/widgets/misc/test-dropdown-button.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <gtk/gtk.h>
-
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-app-helper.h>
-#include <libgnomeui/gnome-ui-init.h>
-
-#include "e-dropdown-button.h"
-
-
-/* (The following is shameless stolen from `testgnome.c'. */
-
-static void
-item_activated (GtkWidget *widget,
- gpointer data)
-{
- printf ("%s activated.\n", (gchar *) data);
-}
-
-static GnomeUIInfo ui_info[] = {
- { GNOME_APP_UI_ITEM, "_New", "Create a new file", item_activated, (gpointer) "file/new", NULL,
- GNOME_APP_PIXMAP_STOCK, GTK_STOCK_NEW, 'n', GDK_CONTROL_MASK, NULL },
- { GNOME_APP_UI_ITEM, "_Open...", "Open an existing file", item_activated, (gpointer) "file/open", NULL,
- GNOME_APP_PIXMAP_STOCK, GTK_STOCK_OPEN, 'o', GDK_CONTROL_MASK, NULL },
- { GNOME_APP_UI_ITEM, "_Save", "Save the current file", item_activated, (gpointer) "file/save", NULL,
- GNOME_APP_PIXMAP_STOCK, GTK_STOCK_SAVE, 's', GDK_CONTROL_MASK, NULL },
- { GNOME_APP_UI_ITEM, "Save _as...", "Save the current file with a new name", item_activated, (gpointer) "file/save as", NULL,
- GNOME_APP_PIXMAP_STOCK, GTK_STOCK_SAVE_AS, 0, 0, NULL },
-
- GNOMEUIINFO_SEPARATOR,
-
- { GNOME_APP_UI_ITEM, "_Print...", "Print the current file", item_activated, (gpointer) "file/print", NULL,
- GNOME_APP_PIXMAP_STOCK, GTK_STOCK_PRINT, 'p', GDK_CONTROL_MASK, NULL },
-
- GNOMEUIINFO_SEPARATOR,
-
- { GNOME_APP_UI_ITEM, "_Close", "Close the current file", item_activated, (gpointer) "file/close", NULL,
- GNOME_APP_PIXMAP_STOCK, GTK_STOCK_CLOSE, 0, 0, NULL },
- { GNOME_APP_UI_ITEM, "E_xit", "Exit the program", item_activated, (gpointer) "file/exit", NULL,
- GNOME_APP_PIXMAP_STOCK, GTK_STOCK_QUIT, 'q', GDK_CONTROL_MASK, NULL },
- GNOMEUIINFO_END
-};
-
-
-gint
-main (gint argc, gchar **argv)
-{
- GtkWidget *window;
- GtkWidget *menu;
- GtkWidget *dropdown_button;
-
- gnome_program_init (
- "test-dropdown-button", "0.0", LIBGNOMEUI_MODULE,
- argc, argv, GNOME_PARAM_NONE);
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_default_size (GTK_WINDOW (window), 1, 1);
-
- menu = gtk_menu_new ();
-
- gnome_app_fill_menu (GTK_MENU_SHELL (menu), ui_info, NULL, TRUE, 0);
-
- dropdown_button = e_dropdown_button_new ("Me_nu", GTK_MENU (menu));
- gtk_container_add (GTK_CONTAINER (window), dropdown_button);
-
- gtk_widget_show (window);
- gtk_widget_show (dropdown_button);
-
- gtk_main ();
-
- return 0;
-}
diff --git a/widgets/misc/test-error.c b/widgets/misc/test-error.c
deleted file mode 100644
index a7d584bf6c..0000000000
--- a/widgets/misc/test-error.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-error.h"
-
-gint
-main (gint argc, gchar **argv)
-{
- gtk_init (&argc, &argv);
-
- argc--;
- switch (argc) {
- case 1:
- e_error_run(NULL, argv[1], NULL);
- break;
- case 2:
- e_error_run(NULL, argv[1], argv[2], NULL);
- break;
- case 3:
- e_error_run(NULL, argv[1], argv[2], argv[3], NULL);
- break;
- case 4:
- e_error_run(NULL, argv[1], argv[2], argv[3], argv[4], NULL);
- break;
- case 5:
- e_error_run(NULL, argv[1], argv[2], argv[3], argv[4], argv[5], NULL);
- break;
- case 6:
- e_error_run(NULL, argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL);
- break;
- default:
- printf("Error: too many or too few arguments\n");
- printf("Usage:\n %s domain:error-id [ args ... ]\n", argv[0]);
- }
-
- return 0;
-}
diff --git a/widgets/misc/test-info-label.c b/widgets/misc/test-info-label.c
deleted file mode 100644
index 0f292a0487..0000000000
--- a/widgets/misc/test-info-label.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include "e-info-label.h"
-
-static void
-delete_event_cb (GtkWidget *widget,
- GdkEventAny *event,
- gpointer data)
-{
- gtk_main_quit ();
-}
-
-gint
-main (gint argc, gchar **argv)
-{
- GtkWidget *window;
- GtkWidget *info_label;
- GtkWidget *label;
- GtkWidget *vbox;
-
- gtk_init (&argc, &argv);
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), "EInfoLabel Test");
- gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
- gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
-
- g_signal_connect (window, "delete_event",
- G_CALLBACK (delete_event_cb), NULL);
-
- info_label = e_info_label_new ("stock_default-folder");
- e_info_label_set_info ((EInfoLabel *) info_label, "Component Name", "An annoyingly long component message");
- gtk_widget_show (info_label);
-
- label = gtk_label_new ("boo");
- gtk_widget_show (label);
-
- vbox = gtk_vbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), info_label, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- gtk_container_add (GTK_CONTAINER (window), vbox);
- gtk_widget_show (window);
-
- gtk_main ();
-
- return 0;
-}
diff --git a/widgets/misc/test-multi-config-dialog.c b/widgets/misc/test-preferences-window.c
index 14327cd6ae..c5291cf755 100644
--- a/widgets/misc/test-multi-config-dialog.c
+++ b/widgets/misc/test-preferences-window.c
@@ -1,4 +1,6 @@
/*
+ * test-preferences-window.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -13,49 +15,38 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#include "e-multi-config-dialog.c"
+#include "e-preferences-window.c"
#include <gtk/gtk.h>
-
#define NUM_PAGES 10
-
static void
-add_pages (EMultiConfigDialog *multi_config_dialog)
+add_pages (EPreferencesWindow *preferences_window)
{
gint i;
for (i = 0; i < NUM_PAGES; i ++) {
GtkWidget *widget;
- GtkWidget *page;
- gchar *string;
- gchar *title;
- gchar *description;
+ gchar *caption;
+ gchar *page_name;
- string = g_strdup_printf ("This is page %d", i);
- description = g_strdup_printf ("Description of page %d", i);
- title = g_strdup_printf ("Title of page %d", i);
+ caption = g_strdup_printf ("Title of page %d", i);
+ page_name = g_strdup_printf ("page-%d", i);
- widget = gtk_label_new (string);
+ widget = gtk_label_new (caption);
gtk_widget_show (widget);
- page = e_config_page_new ();
- gtk_container_add (GTK_CONTAINER (page), widget);
-
- e_multi_config_dialog_add_page (multi_config_dialog, title, description, NULL,
- E_CONFIG_PAGE (page));
+ e_preferences_window_add_page (
+ preferences_window, page_name,
+ "gtk-properties", caption, widget, i);
- g_free (string);
- g_free (title);
- g_free (description);
+ g_free (caption);
+ g_free (page_name);
}
}
@@ -69,23 +60,23 @@ delete_event_callback (GtkWidget *widget,
return TRUE;
}
-
gint
main (gint argc, gchar **argv)
{
- GtkWidget *dialog;
+ GtkWidget *window;
gtk_init (&argc, &argv);
- dialog = e_multi_config_dialog_new ();
+ window = e_preferences_window_new ();
+ gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
g_signal_connect(
- dialog, "delete-event",
+ window, "delete-event",
G_CALLBACK (delete_event_callback), NULL);
- add_pages (E_MULTI_CONFIG_DIALOG (dialog));
+ add_pages (E_PREFERENCES_WINDOW (window));
- gtk_widget_show (dialog);
+ gtk_widget_show (window);
gtk_main ();
diff --git a/widgets/table/Makefile.am b/widgets/table/Makefile.am
index 4ae0861027..7a8a5c7fab 100644
--- a/widgets/table/Makefile.am
+++ b/widgets/table/Makefile.am
@@ -1,16 +1,11 @@
-if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = \
- $(top_builddir)/win32/libemiscwidgets.la \
- $(top_builddir)/win32/libetext.la
-endif
-
glade_DATA = \
e-table-config.glade \
e-table-field-chooser.glade
AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/widgets \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ $(E_UTIL_CFLAGS) \
$(E_WIDGETS_CFLAGS) \
$(GNOME_PLATFORM_CFLAGS) \
-DEVOLUTION_GLADEDIR=\"$(gladedir)\" \
@@ -23,7 +18,9 @@ libetable_la_SOURCES = \
e-cell-checkbox.c \
e-cell-combo.c \
e-cell-date.c \
+ e-cell-date-edit.c \
e-cell-number.c \
+ e-cell-percent.c \
e-cell-pixbuf.c \
e-cell-popup.c \
e-cell-size.c \
@@ -75,7 +72,23 @@ libetable_la_SOURCES = \
e-tree-selection-model.c \
e-tree-sorted.c \
e-tree-table-adapter.c \
- e-tree.c
+ e-tree.c \
+ gal-a11y-e-cell.c \
+ gal-a11y-e-cell-popup.c \
+ gal-a11y-e-cell-registry.c \
+ gal-a11y-e-cell-text.c \
+ gal-a11y-e-cell-toggle.c \
+ gal-a11y-e-cell-tree.c \
+ gal-a11y-e-cell-vbox.c \
+ gal-a11y-e-table.c \
+ gal-a11y-e-table-click-to-add.c \
+ gal-a11y-e-table-click-to-add-factory.c \
+ gal-a11y-e-table-column-header.c \
+ gal-a11y-e-table-factory.c \
+ gal-a11y-e-table-item.c \
+ gal-a11y-e-table-item-factory.c \
+ gal-a11y-e-tree.c \
+ gal-a11y-e-tree-factory.c
libetableincludedir = $(privincludedir)/table
@@ -84,7 +97,9 @@ libetableinclude_HEADERS = \
e-cell-checkbox.h \
e-cell-combo.h \
e-cell-date.h \
+ e-cell-date-edit.h \
e-cell-number.h \
+ e-cell-percent.h \
e-cell-pixbuf.h \
e-cell-popup.h \
e-cell-size.h \
@@ -139,15 +154,34 @@ libetableinclude_HEADERS = \
e-tree-selection-model.h \
e-tree-sorted.h \
e-tree-table-adapter.h \
- e-tree.h
+ e-tree.h \
+ gal-a11y-e-cell.h \
+ gal-a11y-e-cell-popup.h \
+ gal-a11y-e-cell-registry.h \
+ gal-a11y-e-cell-text.h \
+ gal-a11y-e-cell-toggle.h \
+ gal-a11y-e-cell-tree.h \
+ gal-a11y-e-cell-vbox.h \
+ gal-a11y-e-table.h \
+ gal-a11y-e-table-click-to-add.h \
+ gal-a11y-e-table-click-to-add-factory.h \
+ gal-a11y-e-table-column-header.h \
+ gal-a11y-e-table-factory.h \
+ gal-a11y-e-table-item.h \
+ gal-a11y-e-table-item-factory.h \
+ gal-a11y-e-tree.h \
+ gal-a11y-e-tree-factory.h
libetable_la_LDFLAGS = $(NO_UNDEFINED)
libetable_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(top_builddir)/e-util/libeutil.la \
$(top_builddir)/a11y/libevolution-a11y.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/widgets/text/libetext.la \
+ $(E_UTIL_LIBS) \
$(E_WIDGETS_LIBS) \
+ $(MATH_LIB) \
$(GNOME_PLATFORM_LIBS)
icons = \
diff --git a/widgets/table/e-cell-combo.c b/widgets/table/e-cell-combo.c
index 988ba8e12f..af79261c64 100644
--- a/widgets/table/e-cell-combo.c
+++ b/widgets/table/e-cell-combo.c
@@ -62,7 +62,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-item.h"
#include "e-cell-combo.h"
diff --git a/widgets/misc/e-cell-date-edit.c b/widgets/table/e-cell-date-edit.c
index dfbe183f88..1848b2808a 100644
--- a/widgets/misc/e-cell-date-edit.c
+++ b/widgets/table/e-cell-date-edit.c
@@ -38,15 +38,15 @@
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
-#include <table/e-table-item.h>
-#include <table/e-cell-text.h>
+#include "e-table-item.h"
+#include "e-cell-text.h"
#include <glib/gi18n.h>
#include <libedataserver/e-time-utils.h>
/* This depends on ECalendar which is why I didn't put it in gal. */
-#include "e-calendar.h"
+#include <misc/e-calendar.h>
static void e_cell_date_edit_destroy (GtkObject *object);
static void e_cell_date_edit_get_property (GObject *object,
diff --git a/widgets/misc/e-cell-date-edit.h b/widgets/table/e-cell-date-edit.h
index 72fe952e31..4de4dc1819 100644
--- a/widgets/misc/e-cell-date-edit.h
+++ b/widgets/table/e-cell-date-edit.h
@@ -81,21 +81,22 @@ struct _ECellDateEditClass {
ECellPopupClass parent_class;
};
-GType e_cell_date_edit_get_type (void);
-ECell *e_cell_date_edit_new (void);
+GType e_cell_date_edit_get_type (void);
+ECell * e_cell_date_edit_new (void);
/* These freeze and thaw the rebuilding of the time list. They are useful when
setting several properties which result in rebuilds of the list, e.g. the
lower_hour, upper_hour and use_24_hour_format properties. */
-void e_cell_date_edit_freeze (ECellDateEdit *ecde);
-void e_cell_date_edit_thaw (ECellDateEdit *ecde);
+void e_cell_date_edit_freeze (ECellDateEdit *ecde);
+void e_cell_date_edit_thaw (ECellDateEdit *ecde);
/* Sets a callback to use to get the current time. This is useful if the
application needs to use its own timezone data rather than rely on the
Unix timezone. */
-void e_cell_date_edit_set_get_time_callback(ECellDateEdit *ecde,
- ECellDateEditGetTimeCallback cb,
- gpointer data,
- GDestroyNotify destroy);
+void e_cell_date_edit_set_get_time_callback
+ (ECellDateEdit *ecde,
+ ECellDateEditGetTimeCallback cb,
+ gpointer data,
+ GDestroyNotify destroy);
#endif /* _E_CELL_DATE_EDIT_H_ */
diff --git a/widgets/table/e-cell-date.c b/widgets/table/e-cell-date.c
index a3989dcc46..ca1d842526 100644
--- a/widgets/table/e-cell-date.c
+++ b/widgets/table/e-cell-date.c
@@ -29,8 +29,8 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
+#include "e-util/e-unicode.h"
#include "e-util/e-datetime-format.h"
-#include "misc/e-unicode.h"
#include "e-cell-date.h"
diff --git a/widgets/table/e-cell-hbox.c b/widgets/table/e-cell-hbox.c
index 8fd82a9504..53d1b79934 100644
--- a/widgets/table/e-cell-hbox.c
+++ b/widgets/table/e-cell-hbox.c
@@ -32,8 +32,8 @@
#include <gtk/gtk.h>
-/* #include "a11y/e-table/gal-a11y-e-cell-registry.h" */
-/* #include "a11y/e-table/gal-a11y-e-cell-vbox.h" */
+/* #include "a11y/gal-a11y-e-cell-registry.h" */
+/* #include "a11y/gal-a11y-e-cell-vbox.h" */
#include "e-util/e-util.h"
#include "e-cell-hbox.h"
diff --git a/widgets/misc/e-cell-percent.c b/widgets/table/e-cell-percent.c
index 3ed995421b..3ed995421b 100644
--- a/widgets/misc/e-cell-percent.c
+++ b/widgets/table/e-cell-percent.c
diff --git a/widgets/misc/e-cell-percent.h b/widgets/table/e-cell-percent.h
index 3ac15afab7..3ac15afab7 100644
--- a/widgets/misc/e-cell-percent.h
+++ b/widgets/table/e-cell-percent.h
diff --git a/widgets/table/e-cell-popup.c b/widgets/table/e-cell-popup.c
index b427a0c24f..45c6d07377 100644
--- a/widgets/table/e-cell-popup.c
+++ b/widgets/table/e-cell-popup.c
@@ -33,8 +33,8 @@
#include <gdk/gdkkeysyms.h>
-#include "a11y/e-table/gal-a11y-e-cell-popup.h"
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
+#include "gal-a11y-e-cell-popup.h"
+#include "gal-a11y-e-cell-registry.h"
#include "e-util/e-util.h"
#include "e-cell-popup.h"
diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c
index f960760189..9f7d7f113a 100644
--- a/widgets/table/e-cell-text.c
+++ b/widgets/table/e-cell-text.c
@@ -45,15 +45,15 @@
#include <libgnomecanvas/gnome-canvas.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
-#include "a11y/e-table/gal-a11y-e-cell-text.h"
+#include "gal-a11y-e-cell-registry.h"
+#include "gal-a11y-e-cell-text.h"
#include "text/e-text.h"
#include <glib/gi18n.h>
#include "e-util/e-text-event-processor.h"
#include "e-util/e-text-event-processor-emacs-like.h"
#include "e-util/e-util.h"
#include "misc/e-canvas.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-cell-text.h"
#include "e-table-item.h"
diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c
index 45e6c50651..db047f1220 100644
--- a/widgets/table/e-cell-toggle.c
+++ b/widgets/table/e-cell-toggle.c
@@ -28,8 +28,8 @@
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas.h>
-#include "a11y/e-table/gal-a11y-e-cell-toggle.h"
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
+#include "gal-a11y-e-cell-toggle.h"
+#include "gal-a11y-e-cell-registry.h"
#include "e-util/e-util.h"
#include "misc/e-hsv-utils.h"
diff --git a/widgets/table/e-cell-tree.c b/widgets/table/e-cell-tree.c
index 27698f8f67..a22cf6d04b 100644
--- a/widgets/table/e-cell-tree.c
+++ b/widgets/table/e-cell-tree.c
@@ -38,8 +38,8 @@
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas.h>
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
-#include "a11y/e-table/gal-a11y-e-cell-tree.h"
+#include "gal-a11y-e-cell-registry.h"
+#include "gal-a11y-e-cell-tree.h"
#include "e-util/e-util.h"
#include "e-cell-tree.h"
diff --git a/widgets/table/e-cell-vbox.c b/widgets/table/e-cell-vbox.c
index 7759203d32..db12ed14e9 100644
--- a/widgets/table/e-cell-vbox.c
+++ b/widgets/table/e-cell-vbox.c
@@ -29,8 +29,8 @@
#include <gtk/gtk.h>
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
-#include "a11y/e-table/gal-a11y-e-cell-vbox.h"
+#include "gal-a11y-e-cell-registry.h"
+#include "gal-a11y-e-cell-vbox.h"
#include "e-util/e-util.h"
#include "e-cell-vbox.h"
diff --git a/widgets/table/e-table-click-to-add.c b/widgets/table/e-table-click-to-add.c
index 3b9f6d7d8a..57769d1540 100644
--- a/widgets/table/e-table-click-to-add.c
+++ b/widgets/table/e-table-click-to-add.c
@@ -29,7 +29,7 @@
#include <libgnomecanvas/gnome-canvas-util.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
-#include "a11y/e-table/gal-a11y-e-table-click-to-add.h"
+#include "gal-a11y-e-table-click-to-add.h"
#include "text/e-text.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
diff --git a/widgets/table/e-table-config.c b/widgets/table/e-table-config.c
index 634cadafb3..375e2cf99f 100644
--- a/widgets/table/e-table-config.c
+++ b/widgets/table/e-table-config.c
@@ -38,7 +38,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util-private.h"
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-config.h"
#include "e-table-memory-store.h"
diff --git a/widgets/table/e-table-example-1.c b/widgets/table/e-table-example-1.c
deleted file mode 100644
index a45868bf72..0000000000
--- a/widgets/table/e-table-example-1.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-#include "gal/e-util/e-cursors.h"
-#include "e-table-simple.h"
-#include "e-table-header.h"
-#include "e-table-header-item.h"
-#include "e-table-item.h"
-#include "e-cell-text.h"
-#include "e-cell-checkbox.h"
-#include "e-table.h"
-
-#include "table-test.h"
-
-/*
- * One way in which we make it simpler to build an ETableModel is through
- * the ETableSimple class. Instead of creating your own ETableModel
- * class, you simply create a new object of the ETableSimple class. You
- * give it a bunch of functions that act as callbacks.
- *
- * You also get to pass a gpointer to ETableSimple and it gets passed to
- * your callbacks. This would be for having multiple models of the same
- * type. This is just an example though, so we statically define all the
- * data and ignore the gpointer data parameter.
- *
- * In our example we will be creating a table model with 6 columns and 10
- * rows. This corresponds to having 6 different types of information and
- * 10 different sets of data in our database.
- *
- * The headers will be hard coded, as will be the example data.
- *
- */
-
-/*
- * There are two different meanings to the word "column". The first is
- * the model column. A model column corresponds to a specific type of
- * data. This is very much like the usage in a database table where a
- * column is a field in the database.
- *
- * The second type of column is a view column. A view column
- * corresponds to a visually displayed column. Each view column
- * corresponds to a specific model column, though a model column may
- * have any number of view columns associated with it, from zero to
- * greater than one.
- *
- * Also, a view column doesn't necessarily depend on only one model
- * column. In some cases, the view column renderer can be given a
- * reference to another column to get extra information about its
- * display.
-*/
-
-#define ROWS 10
-#define COLS 4
-
-#define IMPORTANCE_COLUMN 4
-#define COLOR_COLUMN 5
-
-/*
- * Here we define the initial layout of the table. This is an xml
- * format that allows you to change the initial ordering of the
- * columns or to do sorting or grouping initially. This specification
- * shows all 5 columns, but moves the importance column nearer to the
- * front. It also sorts by the "Full Name" column (ascending.)
- * Sorting and grouping take the model column as their arguments
- * (sorting is specified by the "column" argument to the leaf elemnt.
- */
-
-#define INITIAL_SPEC "<ETableSpecification> \
- <columns-shown> \
- <column> 0 </column> \
- <column> 4 </column> \
- <column> 1 </column> \
- <column> 2 </column> \
- <column> 3 </column> \
- </columns-shown> \
- <grouping> <leaf column=\"1\" ascending=\"true\"/> </grouping> \
-</ETableSpecification>"
-
-gchar *headers [COLS] = {
- "Email",
- "Full Name",
- "Address",
- "Phone"
-};
-
-/*
- * Virtual Column list:
- * 0 Email
- * 1 Full Name
- * 2 Address
- * 3 Phone
- */
-
-gchar *table_data [ROWS] [COLS];
-
-/*
- * ETableSimple callbacks
- * These are the callbacks that define the behavior of our custom model.
- */
-
-/*
- * Since our model is a constant size, we can just return its size in
- * the column and row count fields.
- */
-
-/* This function returns the number of columns in our ETableModel. */
-static gint
-my_col_count (ETableModel *etc, gpointer data)
-{
- return COLS;
-}
-
-/* This function returns the number of rows in our ETableModel. */
-static gint
-my_row_count (ETableModel *etc, gpointer data)
-{
- return ROWS;
-}
-
-/* This function returns the value at a particular point in our ETableModel. */
-static gpointer
-my_value_at (ETableModel *etc, gint col, gint row, gpointer data)
-{
- return (gpointer) table_data [row] [col];
-}
-
-/* This function sets the value at a particular point in our ETableModel. */
-static void
-my_set_value_at (ETableModel *etc, gint col, gint row, gconstpointer val, gpointer data)
-{
- g_free (table_data [row] [col]);
- table_data [row] [col] = g_strdup (val);
-}
-
-/* This function returns whether a particular cell is editable. */
-static gboolean
-my_is_cell_editable (ETableModel *etc, gint col, gint row, gpointer data)
-{
- return TRUE;
-}
-
-/* This function duplicates the value passed to it. */
-static gpointer
-my_duplicate_value (ETableModel *etc, gint col, gconstpointer value, gpointer data)
-{
- return g_strdup (value);
-}
-
-/* This function frees the value passed to it. */
-static void
-my_free_value (ETableModel *etc, gint col, gpointer value, gpointer data)
-{
- g_free (value);
-}
-
-/* This function creates an empty value. */
-static gpointer
-my_initialize_value (ETableModel *etc, gint col, gpointer data)
-{
- return g_strdup ("");
-}
-
-/* This function reports if a value is empty. */
-static gboolean
-my_value_is_empty (ETableModel *etc, gint col, gconstpointer value, gpointer data)
-{
- return !(value && *(gchar *)value);
-}
-
-/* This function reports if a value is empty. */
-static gchar *
-my_value_to_string (ETableModel *etc, gint col, gconstpointer value, gpointer data)
-{
- return g_strdup(value);
-}
-
-/* We create a window containing our new table. */
-static void
-create_table (void)
-{
- GtkWidget *e_table, *window, *frame;
- ECell *cell_left_just;
- ETableHeader *e_table_header;
- gint i, j;
- ETableModel *e_table_model = NULL;
-
- /* First we fill in the simple data. */
- for (i = 0; i < ROWS; i++) {
- for (j = 0; j < COLS; j++)
- table_data [i] [j] = g_strdup ("");
- }
- /* Next we create our model. This uses the functions we defined
- earlier. */
- e_table_model = e_table_simple_new (
- my_col_count, my_row_count, my_value_at,
- my_set_value_at, my_is_cell_editable,
- my_duplicate_value, my_free_value,
- my_initialize_value, my_value_is_empty,
- my_value_to_string,
- NULL);
- /*
- * Next we create a header. The ETableHeader is used in two
- * different way. The first is the full_header. This is the
- * list of possible columns in the view. The second use is
- * completely internal. Many of the ETableHeader functions are
- * for that purpose. The only functions we really need are
- * e_table_header_new and e_table_header_add_col.
- *
- * First we create the header.
- */
- e_table_header = e_table_header_new ();
-
- /*
- * Next we have to build renderers for all of the columns.
- * Since all our columns are text columns, we can simply use
- * the same renderer over and over again. If we had different
- * types of columns, we could use a different renderer for
- * each column.
- */
- cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT);
-
- /*
- * Next we create a column object for each view column and add
- * them to the header. We don't create a column object for
- * the importance column since it will not be shown.
- */
- for (i = 0; i < COLS; i++) {
- /* Create the column. */
- ETableCol *ecol = e_table_col_new (
- i, headers [i],
- 1.0, 20, cell_left_just,
- g_str_compare, TRUE);
- /* Add it to the header. */
- e_table_header_add_column (e_table_header, ecol, i);
- }
-
- /*
- * Here we create a window for our new table. This window
- * will get shown and the person will be able to test their
- * item.
- */
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
- /* This frame is simply to get a bevel around our table. */
- frame = gtk_frame_new (NULL);
-
- /*
- * Here we create the table. We give it the three pieces of
- * the table we've created, the header, the model, and the
- * initial layout. It does the rest.
- */
- e_table = e_table_new (e_table_header, e_table_model, INITIAL_SPEC);
-
- /* Build the gtk widget hierarchy. */
- gtk_container_add (GTK_CONTAINER (frame), e_table);
- gtk_container_add (GTK_CONTAINER (window), frame);
-
- /* Size the initial window. */
- gtk_widget_set_size_request (window, 200, 200);
-
- /* Show it all. */
- gtk_widget_show_all (window);
-}
-
-/* This is the main function which just initializes gnome and call our create_table function */
-
-gint
-main (gint argc, gchar *argv [])
-{
- gnome_init ("TableExample", "TableExample", argc, argv);
- e_cursors_init ();
-
- gtk_widget_push_colormap (gdk_rgb_get_colormap ());
-
- create_table ();
-
- gtk_main ();
-
- e_cursors_shutdown ();
- return 0;
-}
-
diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c
index 523e948a2d..43513ddc89 100644
--- a/widgets/table/e-table-group-container.c
+++ b/widgets/table/e-table-group-container.c
@@ -31,7 +31,7 @@
#include "e-util/e-util.h"
#include "misc/e-canvas-utils.h"
#include "misc/e-canvas.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-defines.h"
#include "e-table-group-container.h"
diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c
index b3c68be346..d5a02f491a 100644
--- a/widgets/table/e-table-header-item.c
+++ b/widgets/table/e-table-header-item.c
@@ -912,7 +912,10 @@ ethi_unrealize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
- pango_font_description_free (ethi->font_desc);
+ if (ethi->font_desc != NULL) {
+ pango_font_description_free (ethi->font_desc);
+ ethi->font_desc = NULL;
+ }
g_signal_handler_disconnect (item->canvas, ethi->drag_motion_id);
g_signal_handler_disconnect (item->canvas, ethi->drag_leave_id);
diff --git a/widgets/table/e-table-header-utils.c b/widgets/table/e-table-header-utils.c
index 3e3c7f44c9..c87ae40f79 100644
--- a/widgets/table/e-table-header-utils.c
+++ b/widgets/table/e-table-header-utils.c
@@ -29,7 +29,7 @@
#include <gtk/gtk.h>
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-defines.h"
#include "e-table-header-utils.h"
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index d009774dc9..c8809b6087 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -36,8 +36,8 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
-#include "a11y/e-table/gal-a11y-e-table-item-factory.h"
-#include "a11y/e-table/gal-a11y-e-table-item.h"
+#include "gal-a11y-e-table-item-factory.h"
+#include "gal-a11y-e-table-item.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "misc/e-canvas.h"
diff --git a/widgets/table/e-table-utils.c b/widgets/table/e-table-utils.c
index 784f1f5b66..03c8e17a33 100644
--- a/widgets/table/e-table-utils.c
+++ b/widgets/table/e-table-utils.c
@@ -27,7 +27,7 @@
#include <string.h>
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-utils.h"
#include "e-table-header-utils.h"
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index b25ae6a3ce..96e5e57d7b 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -36,13 +36,13 @@
#include <libgnomecanvas/gnome-canvas.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "a11y/e-table/gal-a11y-e-table.h"
+#include "gal-a11y-e-table.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "misc/e-canvas.h"
#include "misc/e-canvas-background.h"
#include "misc/e-canvas-vbox.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table.h"
#include "e-table-click-to-add.h"
diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c
index 8c8b05e2d4..38c7a5111b 100644
--- a/widgets/table/e-tree.c
+++ b/widgets/table/e-tree.c
@@ -30,7 +30,7 @@
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "a11y/e-table/gal-a11y-e-tree.h"
+#include "gal-a11y-e-tree.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "misc/e-canvas.h"
diff --git a/a11y/e-table/gal-a11y-e-cell-popup.c b/widgets/table/gal-a11y-e-cell-popup.c
index 141ce172a4..141ce172a4 100644
--- a/a11y/e-table/gal-a11y-e-cell-popup.c
+++ b/widgets/table/gal-a11y-e-cell-popup.c
diff --git a/a11y/e-table/gal-a11y-e-cell-popup.h b/widgets/table/gal-a11y-e-cell-popup.h
index 5e056a0df0..9729e13e55 100644
--- a/a11y/e-table/gal-a11y-e-cell-popup.h
+++ b/widgets/table/gal-a11y-e-cell-popup.h
@@ -26,7 +26,7 @@
#include <glib-object.h>
#include <table/e-table-item.h>
-#include <a11y/e-table/gal-a11y-e-cell.h>
+#include <table/gal-a11y-e-cell.h>
#include <atk/atkgobjectaccessible.h>
#define GAL_A11Y_TYPE_E_CELL_POPUP (gal_a11y_e_cell_popup_get_type ())
diff --git a/a11y/e-table/gal-a11y-e-cell-registry.c b/widgets/table/gal-a11y-e-cell-registry.c
index 5c741e1955..5c741e1955 100644
--- a/a11y/e-table/gal-a11y-e-cell-registry.c
+++ b/widgets/table/gal-a11y-e-cell-registry.c
diff --git a/a11y/e-table/gal-a11y-e-cell-registry.h b/widgets/table/gal-a11y-e-cell-registry.h
index 85afdadf4e..85afdadf4e 100644
--- a/a11y/e-table/gal-a11y-e-cell-registry.h
+++ b/widgets/table/gal-a11y-e-cell-registry.h
diff --git a/a11y/e-table/gal-a11y-e-cell-text.c b/widgets/table/gal-a11y-e-cell-text.c
index 26fffcb3e7..26fffcb3e7 100644
--- a/a11y/e-table/gal-a11y-e-cell-text.c
+++ b/widgets/table/gal-a11y-e-cell-text.c
diff --git a/a11y/e-table/gal-a11y-e-cell-text.h b/widgets/table/gal-a11y-e-cell-text.h
index 8ccb9c70f9..e5a95accad 100644
--- a/a11y/e-table/gal-a11y-e-cell-text.h
+++ b/widgets/table/gal-a11y-e-cell-text.h
@@ -26,7 +26,7 @@
#include <glib-object.h>
#include <table/e-table-item.h>
#include <table/e-cell-text.h>
-#include <a11y/e-table/gal-a11y-e-cell.h>
+#include <table/gal-a11y-e-cell.h>
#define GAL_A11Y_TYPE_E_CELL_TEXT (gal_a11y_e_cell_text_get_type ())
#define GAL_A11Y_E_CELL_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_TEXT, GalA11yECellText))
diff --git a/a11y/e-table/gal-a11y-e-cell-toggle.c b/widgets/table/gal-a11y-e-cell-toggle.c
index fa23f6c6fd..fa23f6c6fd 100644
--- a/a11y/e-table/gal-a11y-e-cell-toggle.c
+++ b/widgets/table/gal-a11y-e-cell-toggle.c
diff --git a/a11y/e-table/gal-a11y-e-cell-toggle.h b/widgets/table/gal-a11y-e-cell-toggle.h
index 3c29d777e3..3c29d777e3 100644
--- a/a11y/e-table/gal-a11y-e-cell-toggle.h
+++ b/widgets/table/gal-a11y-e-cell-toggle.h
diff --git a/a11y/e-table/gal-a11y-e-cell-tree.c b/widgets/table/gal-a11y-e-cell-tree.c
index aaf490c726..aaf490c726 100644
--- a/a11y/e-table/gal-a11y-e-cell-tree.c
+++ b/widgets/table/gal-a11y-e-cell-tree.c
diff --git a/a11y/e-table/gal-a11y-e-cell-tree.h b/widgets/table/gal-a11y-e-cell-tree.h
index fa48c1486a..fa48c1486a 100644
--- a/a11y/e-table/gal-a11y-e-cell-tree.h
+++ b/widgets/table/gal-a11y-e-cell-tree.h
diff --git a/a11y/e-table/gal-a11y-e-cell-vbox.c b/widgets/table/gal-a11y-e-cell-vbox.c
index b3f92a695a..b3f92a695a 100644
--- a/a11y/e-table/gal-a11y-e-cell-vbox.c
+++ b/widgets/table/gal-a11y-e-cell-vbox.c
diff --git a/a11y/e-table/gal-a11y-e-cell-vbox.h b/widgets/table/gal-a11y-e-cell-vbox.h
index 657cb5d9a5..657cb5d9a5 100644
--- a/a11y/e-table/gal-a11y-e-cell-vbox.h
+++ b/widgets/table/gal-a11y-e-cell-vbox.h
diff --git a/a11y/e-table/gal-a11y-e-cell.c b/widgets/table/gal-a11y-e-cell.c
index 211afa401c..211afa401c 100644
--- a/a11y/e-table/gal-a11y-e-cell.c
+++ b/widgets/table/gal-a11y-e-cell.c
diff --git a/a11y/e-table/gal-a11y-e-cell.h b/widgets/table/gal-a11y-e-cell.h
index 4f2e536b8d..4f2e536b8d 100644
--- a/a11y/e-table/gal-a11y-e-cell.h
+++ b/widgets/table/gal-a11y-e-cell.h
diff --git a/a11y/e-table/gal-a11y-e-table-click-to-add-factory.c b/widgets/table/gal-a11y-e-table-click-to-add-factory.c
index 0ebb3c4621..0ebb3c4621 100644
--- a/a11y/e-table/gal-a11y-e-table-click-to-add-factory.c
+++ b/widgets/table/gal-a11y-e-table-click-to-add-factory.c
diff --git a/a11y/e-table/gal-a11y-e-table-click-to-add-factory.h b/widgets/table/gal-a11y-e-table-click-to-add-factory.h
index 5321ccd241..5321ccd241 100644
--- a/a11y/e-table/gal-a11y-e-table-click-to-add-factory.h
+++ b/widgets/table/gal-a11y-e-table-click-to-add-factory.h
diff --git a/a11y/e-table/gal-a11y-e-table-click-to-add.c b/widgets/table/gal-a11y-e-table-click-to-add.c
index 225f24c685..225f24c685 100644
--- a/a11y/e-table/gal-a11y-e-table-click-to-add.c
+++ b/widgets/table/gal-a11y-e-table-click-to-add.c
diff --git a/a11y/e-table/gal-a11y-e-table-click-to-add.h b/widgets/table/gal-a11y-e-table-click-to-add.h
index 17d6940d08..17d6940d08 100644
--- a/a11y/e-table/gal-a11y-e-table-click-to-add.h
+++ b/widgets/table/gal-a11y-e-table-click-to-add.h
diff --git a/a11y/e-table/gal-a11y-e-table-column-header.c b/widgets/table/gal-a11y-e-table-column-header.c
index 41e6ab0fca..41e6ab0fca 100644
--- a/a11y/e-table/gal-a11y-e-table-column-header.c
+++ b/widgets/table/gal-a11y-e-table-column-header.c
diff --git a/a11y/e-table/gal-a11y-e-table-column-header.h b/widgets/table/gal-a11y-e-table-column-header.h
index 0cf0695f75..0cf0695f75 100644
--- a/a11y/e-table/gal-a11y-e-table-column-header.h
+++ b/widgets/table/gal-a11y-e-table-column-header.h
diff --git a/a11y/e-table/gal-a11y-e-table-factory.c b/widgets/table/gal-a11y-e-table-factory.c
index f459f3b67c..f459f3b67c 100644
--- a/a11y/e-table/gal-a11y-e-table-factory.c
+++ b/widgets/table/gal-a11y-e-table-factory.c
diff --git a/a11y/e-table/gal-a11y-e-table-factory.h b/widgets/table/gal-a11y-e-table-factory.h
index f0a1cecd0b..f0a1cecd0b 100644
--- a/a11y/e-table/gal-a11y-e-table-factory.h
+++ b/widgets/table/gal-a11y-e-table-factory.h
diff --git a/a11y/e-table/gal-a11y-e-table-item-factory.c b/widgets/table/gal-a11y-e-table-item-factory.c
index fa14652788..fa14652788 100644
--- a/a11y/e-table/gal-a11y-e-table-item-factory.c
+++ b/widgets/table/gal-a11y-e-table-item-factory.c
diff --git a/a11y/e-table/gal-a11y-e-table-item-factory.h b/widgets/table/gal-a11y-e-table-item-factory.h
index 5fdf7ce1ef..5fdf7ce1ef 100644
--- a/a11y/e-table/gal-a11y-e-table-item-factory.h
+++ b/widgets/table/gal-a11y-e-table-item-factory.h
diff --git a/a11y/e-table/gal-a11y-e-table-item.c b/widgets/table/gal-a11y-e-table-item.c
index 37f55f68c1..37f55f68c1 100644
--- a/a11y/e-table/gal-a11y-e-table-item.c
+++ b/widgets/table/gal-a11y-e-table-item.c
diff --git a/a11y/e-table/gal-a11y-e-table-item.h b/widgets/table/gal-a11y-e-table-item.h
index 87773aae48..87773aae48 100644
--- a/a11y/e-table/gal-a11y-e-table-item.h
+++ b/widgets/table/gal-a11y-e-table-item.h
diff --git a/a11y/e-table/gal-a11y-e-table.c b/widgets/table/gal-a11y-e-table.c
index bf75227af4..bf75227af4 100644
--- a/a11y/e-table/gal-a11y-e-table.c
+++ b/widgets/table/gal-a11y-e-table.c
diff --git a/a11y/e-table/gal-a11y-e-table.h b/widgets/table/gal-a11y-e-table.h
index ba7c8adc03..ba7c8adc03 100644
--- a/a11y/e-table/gal-a11y-e-table.h
+++ b/widgets/table/gal-a11y-e-table.h
diff --git a/a11y/e-table/gal-a11y-e-tree-factory.c b/widgets/table/gal-a11y-e-tree-factory.c
index 8dc06e2936..8dc06e2936 100644
--- a/a11y/e-table/gal-a11y-e-tree-factory.c
+++ b/widgets/table/gal-a11y-e-tree-factory.c
diff --git a/a11y/e-table/gal-a11y-e-tree-factory.h b/widgets/table/gal-a11y-e-tree-factory.h
index 36b4a61dc2..36b4a61dc2 100644
--- a/a11y/e-table/gal-a11y-e-tree-factory.h
+++ b/widgets/table/gal-a11y-e-tree-factory.h
diff --git a/a11y/e-table/gal-a11y-e-tree.c b/widgets/table/gal-a11y-e-tree.c
index 879b517aab..879b517aab 100644
--- a/a11y/e-table/gal-a11y-e-tree.c
+++ b/widgets/table/gal-a11y-e-tree.c
diff --git a/a11y/e-table/gal-a11y-e-tree.h b/widgets/table/gal-a11y-e-tree.h
index ef15dade36..ef15dade36 100644
--- a/a11y/e-table/gal-a11y-e-tree.h
+++ b/widgets/table/gal-a11y-e-tree.h
diff --git a/widgets/text/Makefile.am b/widgets/text/Makefile.am
index ad106158d9..ee426f4791 100644
--- a/widgets/text/Makefile.am
+++ b/widgets/text/Makefile.am
@@ -15,22 +15,29 @@ privsolib_LTLIBRARIES = libetext.la
libetext_la_SOURCES = \
e-text-model-repos.c \
e-text-model.c \
- e-text.c
+ e-text.c \
+ e-reflow.c \
+ e-reflow-model.c \
+ gal-a11y-e-text-factory.c \
+ gal-a11y-e-text.c
libetextincludedir = $(privincludedir)/text
libetextinclude_HEADERS = \
e-text-model-repos.h \
e-text-model.h \
- e-text.h
+ e-text.h \
+ e-reflow.h \
+ e-reflow-model.h \
+ gal-a11y-e-text-factory.h \
+ gal-a11y-e-text.h
libetext_la_LDFLAGS = $(NO_UNDEFINED)
libetext_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(top_builddir)/e-util/libeutil.la \
$(top_builddir)/a11y/libevolution-a11y.la \
- $(top_builddir)/widgets/table/libetable.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
$(E_UTIL_LIBS) \
$(GNOME_PLATFORM_LIBS) \
$(REGEX_LIBS)
diff --git a/widgets/misc/e-reflow-model.c b/widgets/text/e-reflow-model.c
index 1eaccdad09..1eaccdad09 100644
--- a/widgets/misc/e-reflow-model.c
+++ b/widgets/text/e-reflow-model.c
diff --git a/widgets/misc/e-reflow-model.h b/widgets/text/e-reflow-model.h
index ebbf3c1f75..ebbf3c1f75 100644
--- a/widgets/misc/e-reflow-model.h
+++ b/widgets/text/e-reflow-model.h
diff --git a/widgets/misc/e-reflow.c b/widgets/text/e-reflow.c
index 794e650ea1..705678bbf8 100644
--- a/widgets/misc/e-reflow.c
+++ b/widgets/text/e-reflow.c
@@ -30,12 +30,12 @@
#include "text/e-text.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
-#include "e-canvas.h"
-#include "e-canvas-utils.h"
+#include "misc/e-canvas.h"
+#include "misc/e-canvas-utils.h"
#include "e-reflow.h"
-#include "e-selection-model-simple.h"
+#include "misc/e-selection-model-simple.h"
static gboolean e_reflow_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_reflow_realize (GnomeCanvasItem *item);
diff --git a/widgets/misc/e-reflow.h b/widgets/text/e-reflow.h
index ab27051d40..1559ad6bc0 100644
--- a/widgets/misc/e-reflow.h
+++ b/widgets/text/e-reflow.h
@@ -24,7 +24,7 @@
#define __E_REFLOW_H__
#include <libgnomecanvas/gnome-canvas.h>
-#include <misc/e-reflow-model.h>
+#include <text/e-reflow-model.h>
#include <misc/e-selection-model.h>
#include <e-util/e-sorter-array.h>
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c
index 0fb9f926e1..b9c5e0cbe3 100644
--- a/widgets/text/e-text.c
+++ b/widgets/text/e-text.c
@@ -46,10 +46,10 @@
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "a11y/e-text/gal-a11y-e-text.h"
+#include "gal-a11y-e-text.h"
#include "misc/e-canvas.h"
#include "misc/e-canvas-utils.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include <glib/gi18n.h>
#include "e-util/e-text-event-processor-emacs-like.h"
#include "e-util/e-util.h"
diff --git a/a11y/e-text/gal-a11y-e-text-factory.c b/widgets/text/gal-a11y-e-text-factory.c
index 2df9241014..2df9241014 100644
--- a/a11y/e-text/gal-a11y-e-text-factory.c
+++ b/widgets/text/gal-a11y-e-text-factory.c
diff --git a/a11y/e-text/gal-a11y-e-text-factory.h b/widgets/text/gal-a11y-e-text-factory.h
index 7e7f8e9f1a..7e7f8e9f1a 100644
--- a/a11y/e-text/gal-a11y-e-text-factory.h
+++ b/widgets/text/gal-a11y-e-text-factory.h
diff --git a/a11y/e-text/gal-a11y-e-text.c b/widgets/text/gal-a11y-e-text.c
index 113c503da9..113c503da9 100644
--- a/a11y/e-text/gal-a11y-e-text.c
+++ b/widgets/text/gal-a11y-e-text.c
diff --git a/a11y/e-text/gal-a11y-e-text.h b/widgets/text/gal-a11y-e-text.h
index ff55bdadc7..ff55bdadc7 100644
--- a/a11y/e-text/gal-a11y-e-text.h
+++ b/widgets/text/gal-a11y-e-text.h
diff --git a/win32/Makefile.am b/win32/Makefile.am
index d2b25958c0..7720d56543 100644
--- a/win32/Makefile.am
+++ b/win32/Makefile.am
@@ -6,7 +6,6 @@ EXTRA_DIST = \
libevolution-addressbook.def \
libevolution-calendar.def \
libevolution-mail.def \
- libevolution-mail-shared.def \
libfilter.def
if OS_WIN32
@@ -17,7 +16,6 @@ BOOTSTRAP_LIBS = \
libevolution-addressbook.la \
libevolution-calendar.la \
libevolution-mail.la \
- libevolution-mail-shared.la \
libfilter.la
endif
@@ -58,11 +56,6 @@ libevolution-mail.la: dummy.la libevolution-mail.def
mkdir -p .libs
$(DLLTOOL) --output-lib=.libs/libevolution-mail.dll.a --dllname=libevolution-mail.dll --input-def=libevolution-mail.def
-libevolution-mail-shared.la: dummy.la libevolution-mail-shared.def
- sed -e s!%DLL%!libevolution-mail-shared-0! -e s!%LIB%!libevolution-mail-shared! -e s!%PFX%!$(prefix)! <dummy.la >$@
- mkdir -p .libs
- $(DLLTOOL) --output-lib=.libs/libevolution-mail-shared.dll.a --dllname=libevolution-mail-shared-0.dll --input-def=libevolution-mail-shared.def
-
libfilter.la: dummy.la libfilter.def
sed -e s!%DLL%!libfilter-0! -e s!%LIB%!libfilter! -e s!%PFX%!$(prefix)! <dummy.la >$@
mkdir -p .libs