2 /// \file CUI_Evolution.cc
3 /// ConfigUI derived class to configure the Evolution App
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"
29 #include <wx/process.h>
35 class ExecCallback
: public wxProcess
42 ExecCallback(wxDialog
*dlg
)
49 virtual void OnTerminate(int pid
, int status
)
55 // close the dialog and let it delete us
56 m_waitdlg
->EndModal(wxID_OK
);
59 // our parent doesn't exist, delete ourselves
65 class WaitDialog
: public wxDialog
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
,
78 0, wxALL
| wxALIGN_RIGHT
, 5);
80 top
->SetSizeHints(this);
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
)
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()
117 void EvolutionPtrBase::AcquirePlugin(plugin_ptr old_plugin
)
119 // create our plugin config
120 m_evolution
= dynamic_cast<OpenSync::Config::Evolution
*> (old_plugin
.get());
122 m_evolution
= m_evolution
->Clone();
125 m_evolution
= new OpenSync::Config::Evolution
;
127 m_container
.reset( m_evolution
);
130 OpenSync::Config::Evolution
* EvolutionPtrBase::GetEvolutionPtr()
135 void EvolutionPtrBase::Clear()
141 ConfigUI::plugin_ptr
EvolutionPtrBase::GetPlugin()
147 //////////////////////////////////////////////////////////////////////////////
148 // Evolution config UI class
150 Evolution::Evolution()
155 bool Evolution::InitialRun()
158 "Unable to automatically detect Evolution's configuration.\n"
159 "You need to run Evolution, and manually click each of the\n"
162 " Mail, Contacts, Calendars, Memos, and Tasks\n"
164 "Then quit Evolution to continue configuration.\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
);
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
[] = {
187 long ret
= wxExecute((wxChar
**)start_argv
, wxEXEC_ASYNC
, 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
);
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
202 // if we don't get wxID_CANCEL, then the callback
203 // closed us, and we can delete it
204 if( callback
->m_status
) {
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
);
219 std::string
Evolution::AppName() const
221 return OpenSync::Config::Evolution::AppName();
224 bool Evolution::Configure(wxWindow
*parent
, plugin_ptr old_plugin
)
228 AcquirePlugin(old_plugin
);
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
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
250 if( srcs
.IsDefaultable() ) {
251 EvoDefaultDlg
dlg(m_parent
);
252 if( dlg
.ShowModal() == Dialog_EvoDefault_ManualConfigButton
) {
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());
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
: "");
285 bool Evolution::RunApp(wxWindow
*parent
)
287 return Run(parent
, AppName(), _T("evolution"));
290 void Evolution::PreSyncAppInit()
295 bool Evolution::ZapData(wxWindow
*parent
,
297 OpenSync::API
*engine
)
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
,
315 // tell the user what to do
317 if( dynamic_cast<OpenSync::OpenSync22
*>(engine
) ) {
319 "Starting Evolution. Delete all contacts and/or calendar "
320 "entries manually, depending on your sync configuration.");
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
);
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() )
344 //////////////////////////////////////////////////////////////////////////////
347 Evolution3::Evolution3()
352 void Evolution3::AcquirePlugin(plugin_ptr old_plugin
)
354 // create our plugin config
355 m_evolution3
= dynamic_cast<OpenSync::Config::Evolution3
*> (old_plugin
.get());
357 m_evolution3
= m_evolution3
->Clone();
360 m_evolution3
= new OpenSync::Config::Evolution3
;
362 m_container
.reset( m_evolution3
);
365 OpenSync::Config::Evolution
* Evolution3::GetEvolutionPtr()
370 void Evolution3::Clear()
376 ConfigUI::plugin_ptr
Evolution3::GetPlugin()
383 } // namespace AppConfig