2 /// \file CUI_Evolution.cc
3 /// ConfigUI derived class to configure the Evolution App
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"
29 #include <wx/process.h>
34 class ExecCallback
: public wxProcess
41 ExecCallback(wxDialog
*dlg
)
48 virtual void OnTerminate(int pid
, int status
)
54 // close the dialog and let it delete us
55 m_waitdlg
->EndModal(wxID_OK
);
58 // our parent doesn't exist, delete ourselves
64 class WaitDialog
: public wxDialog
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
,
77 0, wxALL
| wxALIGN_RIGHT
, 5);
79 top
->SetSizeHints(this);
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
)
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()
116 void EvolutionPtrBase::AcquirePlugin(plugin_ptr old_plugin
)
118 // create our plugin config
119 m_evolution
= dynamic_cast<OpenSync::Config::Evolution
*> (old_plugin
.get());
121 m_evolution
= m_evolution
->Clone();
124 m_evolution
= new OpenSync::Config::Evolution
;
126 m_container
.reset( m_evolution
);
129 OpenSync::Config::Evolution
* EvolutionPtrBase::GetEvolutionPtr()
134 void EvolutionPtrBase::Clear()
140 ConfigUI::plugin_ptr
EvolutionPtrBase::GetPlugin()
146 //////////////////////////////////////////////////////////////////////////////
147 // Evolution config UI class
149 Evolution::Evolution()
154 bool Evolution::InitialRun()
157 "Unable to automatically detect Evolution's configuration.\n"
158 "You need to run Evolution, and manually click each of the\n"
161 " Mail, Contacts, Calendars, Memos, and Tasks\n"
163 "Then quit Evolution to continue configuration.\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
);
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
[] = {
186 long ret
= wxExecute((wxChar
**)start_argv
, wxEXEC_ASYNC
, 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
);
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
201 // if we don't get wxID_CANCEL, then the callback
202 // closed us, and we can delete it
203 if( callback
->m_status
) {
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
);
218 std::string
Evolution::AppName() const
220 return OpenSync::Config::Evolution::AppName();
223 bool Evolution::Configure(wxWindow
*parent
, plugin_ptr old_plugin
)
227 AcquirePlugin(old_plugin
);
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
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
249 if( srcs
.IsDefaultable() ) {
250 EvoDefaultDlg
dlg(m_parent
);
251 if( dlg
.ShowModal() == Dialog_EvoDefault_ManualConfigButton
) {
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());
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
: "");
284 bool Evolution::RunApp(wxWindow
*parent
)
286 return Run(parent
, AppName(), _T("evolution"));
289 void Evolution::PreSyncAppInit()
294 bool Evolution::ZapData(wxWindow
*parent
,
296 OpenSync::API
*engine
)
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
,
314 // tell the user what to do
316 if( dynamic_cast<OpenSync::OpenSync22
*>(engine
) ) {
318 "Starting Evolution. Delete all contacts and/or calendar "
319 "entries manually, depending on your sync configuration.");
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
);
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() )
343 //////////////////////////////////////////////////////////////////////////////
346 Evolution3::Evolution3()
351 void Evolution3::AcquirePlugin(plugin_ptr old_plugin
)
353 // create our plugin config
354 m_evolution3
= dynamic_cast<OpenSync::Config::Evolution3
*> (old_plugin
.get());
356 m_evolution3
= m_evolution3
->Clone();
359 m_evolution3
= new OpenSync::Config::Evolution3
;
361 m_container
.reset( m_evolution3
);
364 OpenSync::Config::Evolution
* Evolution3::GetEvolutionPtr()
369 void Evolution3::Clear()
375 ConfigUI::plugin_ptr
Evolution3::GetPlugin()
382 } // namespace AppConfig