lib: added implicit ctor converter from DatabaseDatabase to DBListType
[barry/progweb.git] / desktop / src / CUI_Evolution.cc
blobe91fea0f49f0196d88972d4356c64f6ee857f72b
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();
107 //////////////////////////////////////////////////////////////////////////////
108 // Evolution config UI class
110 Evolution::Evolution()
111 : m_evolution(0)
112 , m_parent(0)
116 bool Evolution::InitialRun()
118 wxString msg = _T(
119 "Unable to automatically detect Evolution's configuration.\n"
120 "You need to run Evolution, and manually click each of the\n"
121 "section buttons:\n"
122 "\n"
123 " Mail, Contacts, Calendars, Memos, and Tasks\n"
124 "\n"
125 "Then quit Evolution to continue configuration.\n"
126 "\n"
127 "Would you like to start Evolution now?\n");
129 int choice = wxMessageBox(msg, _T("Evolution Config"),
130 wxYES_NO | wxICON_QUESTION, m_parent);
132 if( choice == wxNO )
133 return false;
135 ForceShutdown();
137 // start Evolution, and wait for it to exit, showing a waiting
138 // message to the user
139 WaitDialog waitdlg(m_parent, _T("Waiting for Evolution to exit..."),
140 _T("Evolution Running"));
142 ExecCallback *callback = new ExecCallback(&waitdlg);
144 const wxChar *start_argv[] = {
145 _T("evolution"),
146 NULL
148 long ret = wxExecute((wxChar**)start_argv, wxEXEC_ASYNC, callback);
149 if( ret == 0 ) {
150 delete callback;
151 wxMessageBox(_T("Failed to run evolution. Please make sure it is installed and in your PATH."), _T("Evolution Config"), wxOK | wxICON_ERROR, m_parent);
152 return false;
155 if( waitdlg.ShowModal() == wxID_CANCEL ) {
156 // user aborted, so ExecCallback will be left
157 // waiting, and waitdlg will go out of scope, so
158 // reset the callback's pointer
159 callback->m_waitdlg = 0;
160 return false; // user aborted
162 else {
163 // if we don't get wxID_CANCEL, then the callback
164 // closed us, and we can delete it
165 if( callback->m_status ) {
166 // error status code
167 wxMessageBox(_T("Failed to run evolution. Please make sure it is installed and in your PATH."), _T("Evolution Config"), wxOK | wxICON_ERROR, m_parent);
168 delete callback;
169 return false;
171 else {
172 delete callback;
176 // so far so good...
177 return true;
180 std::string Evolution::AppName() const
182 return OpenSync::Config::Evolution::AppName();
185 bool Evolution::Configure(wxWindow *parent, plugin_ptr old_plugin)
187 m_parent = parent;
189 // create our plugin config
190 m_evolution = dynamic_cast<OpenSync::Config::Evolution*> (old_plugin.get());
191 if( m_evolution ) {
192 m_evolution = m_evolution->Clone();
194 else {
195 m_evolution = new OpenSync::Config::Evolution;
197 m_container.reset( m_evolution );
200 // auto detect first
201 EvoSources srcs;
203 // if no sources are found at all, and if Evolution is in the path
204 // do InitialRun and then auto detect again
205 if( srcs.IsEmpty() ) {
206 if( !InitialRun() ) {
207 // impossible to do initial run, so fail here
208 m_container.reset();
209 m_evolution = 0;
210 return false;
212 srcs.Detect();
215 // we now have an auto detect (EvoSources) to work with
216 // if minimum three paths are available, and if no list has
217 // more than 1 item, then just default to those settings
218 // and notify the user... in the notification, allow
219 // the user to "Manual Cfg..." button
220 bool manual = false;
221 if( srcs.IsDefaultable() ) {
222 EvoDefaultDlg dlg(m_parent);
223 if( dlg.ShowModal() == Dialog_EvoDefault_ManualConfigButton ) {
224 manual = true;
228 // otherwise, if default settings are not possible, then
229 // load the path config dialog without notification
230 if( !srcs.IsDefaultable() || manual ) {
231 EvoCfgDlg cfgdlg(m_parent, *m_evolution, srcs);
232 if( cfgdlg.ShowModal() == wxID_OK ) {
233 cfgdlg.SetPaths(*m_evolution);
235 else {
236 m_container.reset();
237 m_evolution = 0;
238 return false;
241 else {
242 // it's defaultable! use default paths
243 m_evolution->SetAddressPath(srcs.GetAddressBook().size() ?
244 srcs.GetAddressBook()[0].m_SourcePath : "");
245 m_evolution->SetCalendarPath(srcs.GetEvents().size() ?
246 srcs.GetEvents()[0].m_SourcePath : "");
247 m_evolution->SetTasksPath(srcs.GetTasks().size() ?
248 srcs.GetTasks()[0].m_SourcePath : "");
249 m_evolution->SetMemosPath(srcs.GetMemos().size() ?
250 srcs.GetMemos()[0].m_SourcePath : "");
253 // success!
254 return true;
257 ConfigUI::plugin_ptr Evolution::GetPlugin()
259 m_evolution = 0;
260 return m_container;
263 bool Evolution::RunApp(wxWindow *parent)
265 return Run(parent, AppName(), _T("evolution"));
268 void Evolution::PreSyncAppInit()
270 ForceShutdown();
273 bool Evolution::ZapData(wxWindow *parent,
274 plugin_ptr plugin,
275 OpenSync::API *engine)
277 m_parent = parent;
279 // extract OpenSync::Config::Evolution from plugin
280 // this *can* throw an exception if the wrong plugin is
281 // passed in, but we want this... such an exception would
282 // represent a bug in the app, not a runtime error
283 // OpenSync::Config::Evolution &evo =
284 // dynamic_cast<OpenSync::Config::Evolution&>(*plugin);
286 if( IsAppRunning() ) {
287 wxMessageBox(_T("Evolution already running."),
288 _T("No Biscuit"), wxOK | wxICON_INFORMATION,
289 m_parent);
290 return false;
293 // tell the user what to do
294 wxString msg;
295 if( dynamic_cast<OpenSync::OpenSync22*>(engine) ) {
296 msg = _T(
297 "Starting Evolution. Delete all contacts and calendar "
298 "entries manually.");
300 else {
301 msg = _T(
302 "Starting Evolution. Delete all contacts and calendar "
303 "entries manually (as well as memos and tasks if you are "
304 "syncing them too)."
307 int choice = wxMessageBox(msg, _T("Starting Evolution"),
308 wxOK | wxCANCEL | wxICON_QUESTION, m_parent);
309 if( choice != wxOK )
310 return false;
312 RunApp(parent);
314 // wait for app to finish... this is kinda lame, but
315 // we don't want other Zaps to happen before this is finished
316 while( IsAppRunning() )
317 wxMilliSleep(500);
319 return true;
322 } // namespace AppConfig