desktop: added concept of configured PST type mask
[barry.git] / desktop / src / CUI_Evolution.cc
bloba4adef3a10a633144b0fe45b596979c513d53b6b
1 ///
2 /// \file CUI_Evolution.cc
3 /// ConfigUI derived class to configure the Evolution App
4 ///
6 /*
7 Copyright (C) 2009-2012, 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>
31 namespace AppConfig {
33 namespace {
34 class ExecCallback : public wxProcess
36 public:
37 wxDialog *m_waitdlg;
38 int m_pid;
39 int m_status;
41 ExecCallback(wxDialog *dlg)
42 : m_waitdlg(dlg)
43 , m_pid(0)
44 , m_status(0)
48 virtual void OnTerminate(int pid, int status)
50 m_pid = pid;
51 m_status = status;
53 if( m_waitdlg ) {
54 // close the dialog and let it delete us
55 m_waitdlg->EndModal(wxID_OK);
57 else {
58 // our parent doesn't exist, delete ourselves
59 delete this;
64 class WaitDialog : public wxDialog
66 DECLARE_EVENT_TABLE()
67 public:
68 WaitDialog(wxWindow *parent, const wxString &msg,
69 const wxString &title)
70 : wxDialog(parent, wxID_ANY, title)
72 wxBoxSizer *top = new wxBoxSizer(wxVERTICAL);
73 top->Add( new wxStaticText(this, wxID_ANY, msg),
74 0, wxALL | wxALIGN_LEFT, 10);
75 top->Add( new wxButton(this, wxID_CANCEL,
76 _T("Stop waiting")),
77 0, wxALL | wxALIGN_RIGHT, 5);
78 SetSizer(top);
79 top->SetSizeHints(this);
80 top->Layout();
82 SetEscapeId(wxID_CANCEL);
85 void OnButton(wxCommandEvent &event)
87 EndModal(wxID_CANCEL);
91 BEGIN_EVENT_TABLE(WaitDialog, wxDialog)
92 EVT_BUTTON (wxID_CANCEL, WaitDialog::OnButton)
93 END_EVENT_TABLE()
94 } // namespace
96 //////////////////////////////////////////////////////////////////////////////
97 // Static utility functions
99 long Evolution::ForceShutdown()
101 ExecHelper shutdown(NULL);
102 shutdown.Run(NULL, "Evolution shutdown", _T("evolution --force-shutdown"));
103 shutdown.WaitForChild();
104 return shutdown.GetChildExitCode();
108 //////////////////////////////////////////////////////////////////////////////
109 // EvolutionPtrBase class
111 EvolutionPtrBase::EvolutionPtrBase()
112 : m_evolution(0)
116 void EvolutionPtrBase::AcquirePlugin(plugin_ptr old_plugin)
118 // create our plugin config
119 m_evolution = dynamic_cast<OpenSync::Config::Evolution*> (old_plugin.get());
120 if( m_evolution ) {
121 m_evolution = m_evolution->Clone();
123 else {
124 m_evolution = new OpenSync::Config::Evolution;
126 m_container.reset( m_evolution );
129 OpenSync::Config::Evolution* EvolutionPtrBase::GetEvolutionPtr()
131 return m_evolution;
134 void EvolutionPtrBase::Clear()
136 m_container.reset();
137 m_evolution = 0;
140 ConfigUI::plugin_ptr EvolutionPtrBase::GetPlugin()
142 m_evolution = 0;
143 return m_container;
146 //////////////////////////////////////////////////////////////////////////////
147 // Evolution config UI class
149 Evolution::Evolution()
150 : m_parent(0)
154 bool Evolution::InitialRun()
156 wxString msg = _T(
157 "Unable to automatically detect Evolution's configuration.\n"
158 "You need to run Evolution, and manually click each of the\n"
159 "section buttons:\n"
160 "\n"
161 " Mail, Contacts, Calendars, Memos, and Tasks\n"
162 "\n"
163 "Then quit Evolution to continue configuration.\n"
164 "\n"
165 "Would you like to start Evolution now?\n");
167 int choice = wxMessageBox(msg, _T("Evolution Config"),
168 wxYES_NO | wxICON_QUESTION, m_parent);
170 if( choice == wxNO )
171 return false;
173 ForceShutdown();
175 // start Evolution, and wait for it to exit, showing a waiting
176 // message to the user
177 WaitDialog waitdlg(m_parent, _T("Waiting for Evolution to exit..."),
178 _T("Evolution Running"));
180 ExecCallback *callback = new ExecCallback(&waitdlg);
182 const wxChar *start_argv[] = {
183 _T("evolution"),
184 NULL
186 long ret = wxExecute((wxChar**)start_argv, wxEXEC_ASYNC, callback);
187 if( ret == 0 ) {
188 delete callback;
189 wxMessageBox(_T("Failed to run evolution. Please make sure it is installed and in your PATH."), _T("Evolution Config"), wxOK | wxICON_ERROR, m_parent);
190 return false;
193 if( waitdlg.ShowModal() == wxID_CANCEL ) {
194 // user aborted, so ExecCallback will be left
195 // waiting, and waitdlg will go out of scope, so
196 // reset the callback's pointer
197 callback->m_waitdlg = 0;
198 return false; // user aborted
200 else {
201 // if we don't get wxID_CANCEL, then the callback
202 // closed us, and we can delete it
203 if( callback->m_status ) {
204 // error status code
205 wxMessageBox(_T("Failed to run evolution. Please make sure it is installed and in your PATH."), _T("Evolution Config"), wxOK | wxICON_ERROR, m_parent);
206 delete callback;
207 return false;
209 else {
210 delete callback;
214 // so far so good...
215 return true;
218 std::string Evolution::AppName() const
220 return OpenSync::Config::Evolution::AppName();
223 bool Evolution::Configure(wxWindow *parent, plugin_ptr old_plugin)
225 m_parent = parent;
227 AcquirePlugin(old_plugin);
229 // auto detect first
230 EvoSources srcs;
232 // if no sources are found at all, and if Evolution is in the path
233 // do InitialRun and then auto detect again
234 if( srcs.IsEmpty() ) {
235 if( !InitialRun() ) {
236 // impossible to do initial run, so fail here
237 Clear();
238 return false;
240 srcs.Detect();
243 // we now have an auto detect (EvoSources) to work with
244 // if minimum three paths are available, and if no list has
245 // more than 1 item, then just default to those settings
246 // and notify the user... in the notification, allow
247 // the user to "Manual Cfg..." button
248 bool manual = false;
249 if( srcs.IsDefaultable() ) {
250 EvoDefaultDlg dlg(m_parent);
251 if( dlg.ShowModal() == Dialog_EvoDefault_ManualConfigButton ) {
252 manual = true;
256 // otherwise, if default settings are not possible, then
257 // load the path config dialog without notification
258 if( !srcs.IsDefaultable() || manual ) {
259 EvoCfgDlg cfgdlg(m_parent, *GetEvolutionPtr(), srcs);
260 if( cfgdlg.ShowModal() == wxID_OK ) {
261 cfgdlg.SetPaths(*GetEvolutionPtr());
263 else {
264 Clear();
265 return false;
268 else {
269 // it's defaultable! use default paths
270 GetEvolutionPtr()->SetAddressPath(srcs.GetAddressBook().size() ?
271 srcs.GetAddressBook()[0].m_SourcePath : "");
272 GetEvolutionPtr()->SetCalendarPath(srcs.GetEvents().size() ?
273 srcs.GetEvents()[0].m_SourcePath : "");
274 GetEvolutionPtr()->SetTasksPath(srcs.GetTasks().size() ?
275 srcs.GetTasks()[0].m_SourcePath : "");
276 GetEvolutionPtr()->SetMemosPath(srcs.GetMemos().size() ?
277 srcs.GetMemos()[0].m_SourcePath : "");
280 // success!
281 return true;
284 bool Evolution::RunApp(wxWindow *parent)
286 return Run(parent, AppName(), _T("evolution"));
289 void Evolution::PreSyncAppInit()
291 ForceShutdown();
294 bool Evolution::ZapData(wxWindow *parent,
295 plugin_ptr plugin,
296 OpenSync::API *engine)
298 m_parent = parent;
300 // extract OpenSync::Config::Evolution from plugin
301 // this *can* throw an exception if the wrong plugin is
302 // passed in, but we want this... such an exception would
303 // represent a bug in the app, not a runtime error
304 // OpenSync::Config::Evolution &evo =
305 // dynamic_cast<OpenSync::Config::Evolution&>(*plugin);
307 if( IsAppRunning() ) {
308 wxMessageBox(_T("Evolution already running."),
309 _T("No Biscuit"), wxOK | wxICON_INFORMATION,
310 m_parent);
311 return false;
314 // tell the user what to do
315 wxString msg;
316 if( dynamic_cast<OpenSync::OpenSync22*>(engine) ) {
317 msg = _T(
318 "Starting Evolution. Delete all contacts and/or calendar "
319 "entries manually, depending on your sync configuration.");
321 else {
322 msg = _T(
323 "Starting Evolution. Delete all objects (contacts, calendar, "
324 "memos, and tasks, depending on your sync configuration)."
327 int choice = wxMessageBox(msg, _T("Starting Evolution"),
328 wxOK | wxCANCEL | wxICON_QUESTION, m_parent);
329 if( choice != wxOK )
330 return false;
332 RunApp(parent);
334 // wait for app to finish... this is kinda lame, but
335 // we don't want other Zaps to happen before this is finished
336 while( IsAppRunning() )
337 wxMilliSleep(500);
339 return true;
343 //////////////////////////////////////////////////////////////////////////////
344 // Evolution3 class
346 Evolution3::Evolution3()
347 : m_evolution3(0)
351 void Evolution3::AcquirePlugin(plugin_ptr old_plugin)
353 // create our plugin config
354 m_evolution3 = dynamic_cast<OpenSync::Config::Evolution3*> (old_plugin.get());
355 if( m_evolution3 ) {
356 m_evolution3 = m_evolution3->Clone();
358 else {
359 m_evolution3 = new OpenSync::Config::Evolution3;
361 m_container.reset( m_evolution3 );
364 OpenSync::Config::Evolution* Evolution3::GetEvolutionPtr()
366 return m_evolution3;
369 void Evolution3::Clear()
371 m_container.reset();
372 m_evolution3 = 0;
375 ConfigUI::plugin_ptr Evolution3::GetPlugin()
377 m_evolution3 = 0;
378 return m_container;
382 } // namespace AppConfig