Bumped copyright dates for 2013
[barry.git] / desktop / src / CUI_Evolution.cc
blob0c8febe537fea0029250cfd9a5d57392a10a969a
1 ///
2 /// \file CUI_Evolution.cc
3 /// ConfigUI derived class to configure the Evolution App
4 ///
6 /*
7 Copyright (C) 2009-2013, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "CUI_Evolution.h"
23 #include "EvoSources.h"
24 #include "EvoCfgDlg.h"
25 #include "EvoDefaultDlg.h"
26 #include "os22.h" // only for the dynamic_cast
27 #include "windowids.h"
28 #include <wx/wx.h>
29 #include <wx/process.h>
30 #include "wxi18n.h"
32 namespace AppConfig {
34 namespace {
35 class ExecCallback : public wxProcess
37 public:
38 wxDialog *m_waitdlg;
39 int m_pid;
40 int m_status;
42 ExecCallback(wxDialog *dlg)
43 : m_waitdlg(dlg)
44 , m_pid(0)
45 , m_status(0)
49 virtual void OnTerminate(int pid, int status)
51 m_pid = pid;
52 m_status = status;
54 if( m_waitdlg ) {
55 // close the dialog and let it delete us
56 m_waitdlg->EndModal(wxID_OK);
58 else {
59 // our parent doesn't exist, delete ourselves
60 delete this;
65 class WaitDialog : public wxDialog
67 DECLARE_EVENT_TABLE()
68 public:
69 WaitDialog(wxWindow *parent, const wxString &msg,
70 const wxString &title)
71 : wxDialog(parent, wxID_ANY, title)
73 wxBoxSizer *top = new wxBoxSizer(wxVERTICAL);
74 top->Add( new wxStaticText(this, wxID_ANY, msg),
75 0, wxALL | wxALIGN_LEFT, 10);
76 top->Add( new wxButton(this, wxID_CANCEL,
77 _W("Stop waiting")),
78 0, wxALL | wxALIGN_RIGHT, 5);
79 SetSizer(top);
80 top->SetSizeHints(this);
81 top->Layout();
83 SetEscapeId(wxID_CANCEL);
86 void OnButton(wxCommandEvent &event)
88 EndModal(wxID_CANCEL);
92 BEGIN_EVENT_TABLE(WaitDialog, wxDialog)
93 EVT_BUTTON (wxID_CANCEL, WaitDialog::OnButton)
94 END_EVENT_TABLE()
95 } // namespace
97 //////////////////////////////////////////////////////////////////////////////
98 // Static utility functions
100 long Evolution::ForceShutdown()
102 ExecHelper shutdown(NULL);
103 shutdown.Run(NULL, _C("Evolution shutdown"), _T("evolution --force-shutdown"));
104 shutdown.WaitForChild();
105 return shutdown.GetChildExitCode();
109 //////////////////////////////////////////////////////////////////////////////
110 // EvolutionPtrBase class
112 EvolutionPtrBase::EvolutionPtrBase()
113 : m_evolution(0)
117 void EvolutionPtrBase::AcquirePlugin(plugin_ptr old_plugin)
119 // create our plugin config
120 m_evolution = dynamic_cast<OpenSync::Config::Evolution*> (old_plugin.get());
121 if( m_evolution ) {
122 m_evolution = m_evolution->Clone();
124 else {
125 m_evolution = new OpenSync::Config::Evolution;
127 m_container.reset( m_evolution );
130 OpenSync::Config::Evolution* EvolutionPtrBase::GetEvolutionPtr()
132 return m_evolution;
135 void EvolutionPtrBase::Clear()
137 m_container.reset();
138 m_evolution = 0;
141 ConfigUI::plugin_ptr EvolutionPtrBase::GetPlugin()
143 m_evolution = 0;
144 return m_container;
147 //////////////////////////////////////////////////////////////////////////////
148 // Evolution config UI class
150 Evolution::Evolution()
151 : m_parent(0)
155 bool Evolution::InitialRun()
157 wxString msg = _W(
158 "Unable to automatically detect Evolution's configuration.\n"
159 "You need to run Evolution, and manually click each of the\n"
160 "section buttons:\n"
161 "\n"
162 " Mail, Contacts, Calendars, Memos, and Tasks\n"
163 "\n"
164 "Then quit Evolution to continue configuration.\n"
165 "\n"
166 "Would you like to start Evolution now?\n");
168 int choice = wxMessageBox(msg, _W("Evolution Config"),
169 wxYES_NO | wxICON_QUESTION, m_parent);
171 if( choice == wxNO )
172 return false;
174 ForceShutdown();
176 // start Evolution, and wait for it to exit, showing a waiting
177 // message to the user
178 WaitDialog waitdlg(m_parent, _W("Waiting for Evolution to exit..."),
179 _W("Evolution Running"));
181 ExecCallback *callback = new ExecCallback(&waitdlg);
183 const wxChar *start_argv[] = {
184 _T("evolution"),
185 NULL
187 long ret = wxExecute((wxChar**)start_argv, wxEXEC_ASYNC, callback);
188 if( ret == 0 ) {
189 delete callback;
190 wxMessageBox(_W("Failed to run evolution. Please make sure it is installed and in your PATH."), _W("Evolution Config"), wxOK | wxICON_ERROR, m_parent);
191 return false;
194 if( waitdlg.ShowModal() == wxID_CANCEL ) {
195 // user aborted, so ExecCallback will be left
196 // waiting, and waitdlg will go out of scope, so
197 // reset the callback's pointer
198 callback->m_waitdlg = 0;
199 return false; // user aborted
201 else {
202 // if we don't get wxID_CANCEL, then the callback
203 // closed us, and we can delete it
204 if( callback->m_status ) {
205 // error status code
206 wxMessageBox(_W("Failed to run evolution. Please make sure it is installed and in your PATH."), _W("Evolution Config"), wxOK | wxICON_ERROR, m_parent);
207 delete callback;
208 return false;
210 else {
211 delete callback;
215 // so far so good...
216 return true;
219 std::string Evolution::AppName() const
221 return OpenSync::Config::Evolution::AppName();
224 bool Evolution::Configure(wxWindow *parent, plugin_ptr old_plugin)
226 m_parent = parent;
228 AcquirePlugin(old_plugin);
230 // auto detect first
231 EvoSources srcs;
233 // if no sources are found at all, and if Evolution is in the path
234 // do InitialRun and then auto detect again
235 if( srcs.IsEmpty() ) {
236 if( !InitialRun() ) {
237 // impossible to do initial run, so fail here
238 Clear();
239 return false;
241 srcs.Detect();
244 // we now have an auto detect (EvoSources) to work with
245 // if minimum three paths are available, and if no list has
246 // more than 1 item, then just default to those settings
247 // and notify the user... in the notification, allow
248 // the user to "Manual Cfg..." button
249 bool manual = false;
250 if( srcs.IsDefaultable() ) {
251 EvoDefaultDlg dlg(m_parent);
252 if( dlg.ShowModal() == Dialog_EvoDefault_ManualConfigButton ) {
253 manual = true;
257 // otherwise, if default settings are not possible, then
258 // load the path config dialog without notification
259 if( !srcs.IsDefaultable() || manual ) {
260 EvoCfgDlg cfgdlg(m_parent, *GetEvolutionPtr(), srcs);
261 if( cfgdlg.ShowModal() == wxID_OK ) {
262 cfgdlg.SetPaths(*GetEvolutionPtr());
264 else {
265 Clear();
266 return false;
269 else {
270 // it's defaultable! use default paths
271 GetEvolutionPtr()->SetAddressPath(srcs.GetAddressBook().size() ?
272 srcs.GetAddressBook()[0].m_SourcePath : "");
273 GetEvolutionPtr()->SetCalendarPath(srcs.GetEvents().size() ?
274 srcs.GetEvents()[0].m_SourcePath : "");
275 GetEvolutionPtr()->SetTasksPath(srcs.GetTasks().size() ?
276 srcs.GetTasks()[0].m_SourcePath : "");
277 GetEvolutionPtr()->SetMemosPath(srcs.GetMemos().size() ?
278 srcs.GetMemos()[0].m_SourcePath : "");
281 // success!
282 return true;
285 bool Evolution::RunApp(wxWindow *parent)
287 return Run(parent, AppName(), _T("evolution"));
290 void Evolution::PreSyncAppInit()
292 ForceShutdown();
295 bool Evolution::ZapData(wxWindow *parent,
296 plugin_ptr plugin,
297 OpenSync::API *engine)
299 m_parent = parent;
301 // extract OpenSync::Config::Evolution from plugin
302 // this *can* throw an exception if the wrong plugin is
303 // passed in, but we want this... such an exception would
304 // represent a bug in the app, not a runtime error
305 // OpenSync::Config::Evolution &evo =
306 // dynamic_cast<OpenSync::Config::Evolution&>(*plugin);
308 if( IsAppRunning() ) {
309 wxMessageBox(_W("Evolution already running."),
310 _W("Oops..."), wxOK | wxICON_INFORMATION,
311 m_parent);
312 return false;
315 // tell the user what to do
316 wxString msg;
317 if( dynamic_cast<OpenSync::OpenSync22*>(engine) ) {
318 msg = _W(
319 "Starting Evolution. Delete all contacts and/or calendar "
320 "entries manually, depending on your sync configuration.");
322 else {
323 msg = _W(
324 "Starting Evolution. Delete all objects (contacts, calendar, "
325 "memos, and tasks, depending on your sync configuration)."
328 int choice = wxMessageBox(msg, _W("Starting Evolution"),
329 wxOK | wxCANCEL | wxICON_QUESTION, m_parent);
330 if( choice != wxOK )
331 return false;
333 RunApp(parent);
335 // wait for app to finish... this is kinda lame, but
336 // we don't want other Zaps to happen before this is finished
337 while( IsAppRunning() )
338 wxMilliSleep(500);
340 return true;
344 //////////////////////////////////////////////////////////////////////////////
345 // Evolution3 class
347 Evolution3::Evolution3()
348 : m_evolution3(0)
352 void Evolution3::AcquirePlugin(plugin_ptr old_plugin)
354 // create our plugin config
355 m_evolution3 = dynamic_cast<OpenSync::Config::Evolution3*> (old_plugin.get());
356 if( m_evolution3 ) {
357 m_evolution3 = m_evolution3->Clone();
359 else {
360 m_evolution3 = new OpenSync::Config::Evolution3;
362 m_container.reset( m_evolution3 );
365 OpenSync::Config::Evolution* Evolution3::GetEvolutionPtr()
367 return m_evolution3;
370 void Evolution3::Clear()
372 m_container.reset();
373 m_evolution3 = 0;
376 ConfigUI::plugin_ptr Evolution3::GetPlugin()
378 m_evolution3 = 0;
379 return m_container;
383 } // namespace AppConfig