source: filezilla/trunk/fuentes/src/interface/FileZilla.cpp @ 3185

Last change on this file since 3185 was 3185, checked in by jrpelegrina, 3 years ago

Update new version: 3.15.02

File size: 21.3 KB
Line 
1#include <filezilla.h>
2#ifdef _MSC_VER
3#pragma hdrstop
4#endif
5#include "filezillaapp.h"
6#include "Mainfrm.h"
7#include "Options.h"
8#include "wrapengine.h"
9#include "buildinfo.h"
10#include <wx/tokenzr.h>
11#include "cmdline.h"
12#include "welcome_dialog.h"
13#include <msgbox.h>
14
15#include <libfilezilla/local_filesys.hpp>
16
17#include <wx/xrc/xh_animatctrl.h>
18#include <wx/xrc/xh_bmpbt.h>
19#include <wx/xrc/xh_bttn.h>
20#include <wx/xrc/xh_chckb.h>
21#include <wx/xrc/xh_chckl.h>
22#include <wx/xrc/xh_choic.h>
23#include <wx/xrc/xh_dlg.h>
24#include <wx/xrc/xh_gauge.h>
25#include <wx/xrc/xh_listb.h>
26#include <wx/xrc/xh_listc.h>
27#include <wx/xrc/xh_menu.h>
28#include <wx/xrc/xh_notbk.h>
29#include <wx/xrc/xh_panel.h>
30#include <wx/xrc/xh_radbt.h>
31#include <wx/xrc/xh_scwin.h>
32#include <wx/xrc/xh_sizer.h>
33#include <wx/xrc/xh_spin.h>
34#include <wx/xrc/xh_stbmp.h>
35#include <wx/xrc/xh_stbox.h>
36#include <wx/xrc/xh_stlin.h>
37#include <wx/xrc/xh_sttxt.h>
38#include "xh_text_ex.h"
39#include <wx/xrc/xh_tree.h>
40#include <wx/xrc/xh_hyperlink.h>
41#include "xh_toolb_ex.h"
42#ifdef __WXMSW__
43#include <wx/dynlib.h>
44#endif
45#ifdef WITH_LIBDBUS
46#include <../dbus/session_manager.h>
47#endif
48
49#if defined(__WXMAC__) || defined(__UNIX__)
50#include <wx/stdpaths.h>
51#endif
52
53#include "locale_initializer.h"
54
55#ifdef ENABLE_BINRELOC
56        #define BR_PTHREADS 0
57        #include "prefix.h"
58#endif
59
60#ifndef __WXGTK__
61IMPLEMENT_APP(CFileZillaApp)
62#else
63IMPLEMENT_APP_NO_MAIN(CFileZillaApp)
64#endif //__WXGTK__
65
66CFileZillaApp::CFileZillaApp()
67{
68        m_profilingActive = true;
69        AddStartupProfileRecord(_T("CFileZillaApp::CFileZillaApp()"));
70}
71
72CFileZillaApp::~CFileZillaApp()
73{
74        COptions::Destroy();
75}
76
77#ifdef __WXMSW__
78namespace {
79extern "C"
80{
81        typedef HRESULT(WINAPI *t_SetCurrentProcessExplicitAppUserModelID)(PCWSTR AppID);
82}
83
84static void SetAppId()
85{
86        wxDynamicLibrary dll;
87        if (!dll.Load(_T("shell32.dll")))
88                return;
89
90        if (!dll.HasSymbol(_T("SetCurrentProcessExplicitAppUserModelID")))
91                return;
92
93        t_SetCurrentProcessExplicitAppUserModelID pSetCurrentProcessExplicitAppUserModelID =
94                (t_SetCurrentProcessExplicitAppUserModelID)dll.GetSymbol(_T("SetCurrentProcessExplicitAppUserModelID"));
95
96        if (!pSetCurrentProcessExplicitAppUserModelID)
97                return;
98
99        pSetCurrentProcessExplicitAppUserModelID(_T("FileZilla.Client.AppID"));
100}
101
102static bool InitWinsock()
103{
104        WSADATA d{};
105        int res = WSAStartup((2 << 8) | 8, &d);
106        if (res != 0) {
107                int err = WSAGetLastError();
108                wxString msg = wxString::Format(_("Could not initialize Winsock (%d): %s"), err, wxSysErrorMsg(err));
109                wxMessageBoxEx(msg, _("Failed to initialize networking"), wxICON_EXCLAMATION);
110                return false;
111        }
112
113        return true;
114}
115
116static void UninitWinsock()
117{
118        WSACleanup();
119}
120}
121
122#endif //__WXMSW__
123
124void CFileZillaApp::InitLocale()
125{
126        wxString language = COptions::Get()->GetOption(OPTION_LANGUAGE);
127        const wxLanguageInfo* pInfo = wxLocale::FindLanguageInfo(language);
128        if (!language.empty()) {
129#ifdef __WXGTK__
130                if (CInitializer::error) {
131                        wxString error;
132
133                        wxLocale *loc = wxGetLocale();
134                        const wxLanguageInfo* currentInfo = loc ? loc->GetLanguageInfo(loc->GetLanguage()) : 0;
135                        if (!loc || !currentInfo) {
136                                if (!pInfo)
137                                        error.Printf(_("Failed to set language to %s, using default system language."),
138                                                language);
139                                else
140                                        error.Printf(_("Failed to set language to %s (%s), using default system language."),
141                                                pInfo->Description, language);
142                        }
143                        else {
144                                wxString currentName = currentInfo->CanonicalName;
145
146                                if (!pInfo)
147                                        error.Printf(_("Failed to set language to %s, using default system language (%s, %s)."),
148                                                language, loc->GetLocale(),
149                                                currentName);
150                                else
151                                        error.Printf(_("Failed to set language to %s (%s), using default system language (%s, %s)."),
152                                                pInfo->Description, language, loc->GetLocale(),
153                                                currentName);
154                        }
155
156                        error += _T("\n");
157                        error += _("Please make sure the requested locale is installed on your system.");
158                        wxMessageBoxEx(error, _("Failed to change language"), wxICON_EXCLAMATION);
159
160                        COptions::Get()->SetOption(OPTION_LANGUAGE, _T(""));
161                }
162#else
163                if (!pInfo || !SetLocale(pInfo->Language)) {
164                        for( language = GetFallbackLocale(language); !language.empty(); language = GetFallbackLocale(language) ) {
165                                const wxLanguageInfo* fallbackInfo = wxLocale::FindLanguageInfo(language);
166                                if( fallbackInfo && SetLocale(fallbackInfo->Language )) {
167                                        COptions::Get()->SetOption(OPTION_LANGUAGE, language);
168                                        return;
169                                }
170                        }
171                        COptions::Get()->SetOption(OPTION_LANGUAGE, wxString());
172                        if (pInfo && !pInfo->Description.empty())
173                                wxMessageBoxEx(wxString::Format(_("Failed to set language to %s (%s), using default system language"), pInfo->Description, language), _("Failed to change language"), wxICON_EXCLAMATION);
174                        else
175                                wxMessageBoxEx(wxString::Format(_("Failed to set language to %s, using default system language"), language), _("Failed to change language"), wxICON_EXCLAMATION);
176                }
177#endif
178        }
179}
180
181bool CFileZillaApp::OnInit()
182{
183        AddStartupProfileRecord(_T("CFileZillaApp::OnInit()"));
184
185        srand( (unsigned)time( NULL ) );
186
187#ifdef __WXMSW__
188        if (!InitWinsock()) {
189                return false;
190        }
191
192        SetAppId();
193#endif
194
195        //wxSystemOptions is slow, if a value is not set, it keeps querying the environment
196        //each and every time...
197        wxSystemOptions::SetOption(_T("filesys.no-mimetypesmanager"), 0);
198        wxSystemOptions::SetOption(_T("window-default-variant"), _T(""));
199#ifdef __WXMSW__
200        wxSystemOptions::SetOption(_T("no-maskblt"), 0);
201        wxSystemOptions::SetOption(_T("msw.window.no-clip-children"), 0);
202        wxSystemOptions::SetOption(_T("msw.font.no-proof-quality"), 0);
203        wxSystemOptions::SetOption(_T("msw.remap"), 0);
204        wxSystemOptions::SetOption(_T("msw.staticbox.optimized-paint"), 0);
205#endif
206#ifdef __WXMAC__
207        wxSystemOptions::SetOption(_T("mac.listctrl.always_use_generic"), 1);
208        wxSystemOptions::SetOption(_T("mac.textcontrol-use-spell-checker"), 0);
209#endif
210
211        int cmdline_result = ProcessCommandLine();
212        if (!cmdline_result)
213                return false;
214
215        LoadLocales();
216
217        if (cmdline_result < 0) {
218                if (m_pCommandLine) {
219                        m_pCommandLine->DisplayUsage();
220                }
221                return false;
222        }
223
224        InitDefaultsDir();
225
226        COptions::Init();
227
228        InitLocale();
229
230#ifndef _DEBUG
231        const wxString& buildType = CBuildInfo::GetBuildType();
232        if (buildType == _T("nightly")) {
233                wxMessageBoxEx(_T("You are using a nightly development version of FileZilla 3, do not expect anything to work.\r\nPlease use the official releases instead.\r\n\r\n\
234Unless explicitly instructed otherwise,\r\n\
235DO NOT post bugreports,\r\n\
236DO NOT use it in production environments,\r\n\
237DO NOT distribute the binaries,\r\n\
238DO NOT complain about it\r\n\
239USE AT OWN RISK"), _T("Important Information"));
240        }
241        else {
242                wxString v;
243                if (!wxGetEnv(_T("FZDEBUG"), &v) || v != _T("1")) {
244                        COptions::Get()->SetOption(OPTION_LOGGING_DEBUGLEVEL, 0);
245                        COptions::Get()->SetOption(OPTION_LOGGING_RAWLISTING, 0);
246                }
247        }
248#endif
249
250        if (!LoadResourceFiles()) {
251                COptions::Destroy();
252                return false;
253        }
254
255        CheckExistsFzsftp();
256
257        // Turn off idle events, we don't need them
258        wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED);
259
260        wxUpdateUIEvent::SetMode(wxUPDATE_UI_PROCESS_SPECIFIED);
261
262#ifdef WITH_LIBDBUS
263        CSessionManager::Init();
264#endif
265
266        // Load the text wrapping engine
267        m_pWrapEngine = std::make_unique<CWrapEngine>();
268        m_pWrapEngine->LoadCache();
269
270        CMainFrame *frame = new CMainFrame();
271        frame->Show(true);
272        SetTopWindow(frame);
273
274        CWelcomeDialog *welcome_dialog = new CWelcomeDialog;
275        welcome_dialog->Run(frame, false, true);
276
277        frame->ProcessCommandLine();
278        frame->PostInitialize();
279
280        ShowStartupProfile();
281
282        return true;
283}
284
285int CFileZillaApp::OnExit()
286{
287        COptions::Get()->SaveIfNeeded();
288
289#ifdef WITH_LIBDBUS
290        CSessionManager::Uninit();
291#endif
292#ifdef __WXMSW__
293        UninitWinsock();
294#endif
295        return wxApp::OnExit();
296}
297
298bool CFileZillaApp::FileExists(const wxString& file) const
299{
300        int pos = file.Find('*');
301        if (pos < 0)
302                return wxFileExists(file);
303
304        wxASSERT(pos > 0);
305        wxASSERT(file[pos - 1] == '/');
306        wxASSERT(file.size() > static_cast<size_t>(pos + 1) && file[pos + 1] == '/');
307
308        wxLogNull nullLog;
309        wxDir dir(file.Left(pos));
310        if (!dir.IsOpened())
311                return false;
312
313        wxString subDir;
314        bool found = dir.GetFirst(&subDir, _T(""), wxDIR_DIRS);
315        while (found) {
316                if (FileExists(file.Left(pos) + subDir + file.Mid(pos + 1)))
317                        return true;
318
319                found = dir.GetNext(&subDir);
320        }
321
322        return false;
323}
324
325CLocalPath CFileZillaApp::GetDataDir(wxString fileToFind) const
326{
327        /*
328         * Finding the resources in all cases is a difficult task,
329         * due to the huge variety of diffent systems and their filesystem
330         * structure.
331         * Basically we just check a couple of paths for presence of the resources,
332         * and hope we find them. If not, the user can still specify on the cmdline
333         * and using environment variables where the resources are.
334         *
335         * At least on OS X it's simple: All inside application bundle.
336         */
337
338#ifdef __WXMAC__
339        CLocalPath path(wxStandardPaths::Get().GetDataDir());
340        if (FileExists(path.GetPath() + fileToFind))
341                return path;
342
343        return CLocalPath();
344#else
345
346        wxPathList pathList;
347        // FIXME: --datadir cmdline
348
349        // First try the user specified data dir.
350        pathList.AddEnvList(_T("FZ_DATADIR"));
351
352        // Next try the current path and the current executable path.
353        // Without this, running development versions would be difficult.
354        pathList.Add(wxGetCwd());
355
356#ifdef ENABLE_BINRELOC
357        const char* path = SELFPATH;
358        if (path && *path) {
359                wxString datadir(SELFPATH , *wxConvCurrent);
360                wxFileName fn(datadir);
361                datadir = fn.GetPath();
362                if (!datadir.empty())
363                        pathList.Add(datadir);
364
365        }
366        path = DATADIR;
367        if (path && *path) {
368                wxString datadir(DATADIR, *wxConvCurrent);
369                if (!datadir.empty())
370                        pathList.Add(datadir);
371        }
372#elif defined __WXMSW__
373        wxChar path[1024];
374        int res = GetModuleFileName(0, path, 1000);
375        if (res > 0 && res < 1000) {
376                wxFileName fn(path);
377                pathList.Add(fn.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
378        }
379#endif //ENABLE_BINRELOC and __WXMSW__ blocks
380
381        // Now scan through the path
382        pathList.AddEnvList(_T("PATH"));
383
384#ifndef __WXMSW__
385        // Try some common paths
386        pathList.Add(_T("/usr/share/filezilla"));
387        pathList.Add(_T("/usr/local/share/filezilla"));
388#endif
389
390        // For each path, check for the resources
391        wxPathList::const_iterator node;
392        for (node = pathList.begin(); node != pathList.end(); ++node) {
393                wxString cur = CLocalPath(*node).GetPath();
394                if (FileExists(cur + fileToFind))
395                        return CLocalPath(cur);
396                if (FileExists(cur + _T("share/filezilla/") + fileToFind))
397                        return CLocalPath(cur + _T("/share/filezilla"));
398                if (FileExists(cur + _T("filezilla/") + fileToFind))
399                        return CLocalPath(cur + _T("filezilla"));
400        }
401
402        for (node = pathList.begin(); node != pathList.end(); ++node) {
403                wxString cur = CLocalPath(*node).GetPath();
404                if (FileExists(cur + _T("../") + fileToFind))
405                        return CLocalPath(cur + _T("/.."));
406                if (FileExists(cur + _T("../share/filezilla/") + fileToFind))
407                        return CLocalPath(cur + _T("../share/filezilla"));
408        }
409
410        for (node = pathList.begin(); node != pathList.end(); ++node) {
411                wxString cur = CLocalPath(*node).GetPath();
412                if (FileExists(cur + _T("../../") + fileToFind))
413                        return CLocalPath(cur + _T("../.."));
414        }
415
416        return CLocalPath();
417#endif //__WXMAC__
418}
419
420bool CFileZillaApp::LoadResourceFiles()
421{
422        AddStartupProfileRecord(_T("CFileZillaApp::LoadResourceFiles"));
423        m_resourceDir = GetDataDir(_T("resources/theme.xml"));
424
425        wxImage::AddHandler(new wxPNGHandler());
426
427        if (m_resourceDir.empty()) {
428                wxString msg = _("Could not find the resource files for FileZilla, closing FileZilla.\nYou can set the data directory of FileZilla using the '--datadir <custompath>' commandline option or by setting the FZ_DATADIR environment variable.");
429                wxMessageBoxEx(msg, _("FileZilla Error"), wxOK | wxICON_ERROR);
430                return false;
431        }
432
433        m_resourceDir.AddSegment(_T("resources"));
434
435        wxXmlResource *pResource = wxXmlResource::Get();
436
437#ifndef __WXDEBUG__
438        pResource->SetFlags(pResource->GetFlags() | wxXRC_NO_RELOADING);
439#endif
440
441        pResource->AddHandler(new wxMenuXmlHandler);
442        pResource->AddHandler(new wxMenuBarXmlHandler);
443        pResource->AddHandler(new wxDialogXmlHandler);
444        pResource->AddHandler(new wxPanelXmlHandler);
445        pResource->AddHandler(new wxSizerXmlHandler);
446        pResource->AddHandler(new wxButtonXmlHandler);
447        pResource->AddHandler(new wxBitmapButtonXmlHandler);
448        pResource->AddHandler(new wxStaticTextXmlHandler);
449        pResource->AddHandler(new wxStaticBoxXmlHandler);
450        pResource->AddHandler(new wxStaticBitmapXmlHandler);
451        pResource->AddHandler(new wxTreeCtrlXmlHandler);
452        pResource->AddHandler(new wxListCtrlXmlHandler);
453        pResource->AddHandler(new wxCheckListBoxXmlHandler);
454        pResource->AddHandler(new wxChoiceXmlHandler);
455        pResource->AddHandler(new wxGaugeXmlHandler);
456        pResource->AddHandler(new wxCheckBoxXmlHandler);
457        pResource->AddHandler(new wxSpinCtrlXmlHandler);
458        pResource->AddHandler(new wxRadioButtonXmlHandler);
459        pResource->AddHandler(new wxNotebookXmlHandler);
460        pResource->AddHandler(new wxTextCtrlXmlHandlerEx);
461        pResource->AddHandler(new wxListBoxXmlHandler);
462        pResource->AddHandler(new wxToolBarXmlHandlerEx);
463        pResource->AddHandler(new wxStaticLineXmlHandler);
464        pResource->AddHandler(new wxScrolledWindowXmlHandler);
465        pResource->AddHandler(new wxHyperlinkCtrlXmlHandler);
466        pResource->AddHandler(new wxAnimationCtrlXmlHandler);
467        pResource->AddHandler(new wxStdDialogButtonSizerXmlHandler);
468
469        if (fz::local_filesys::get_file_type(fz::to_native(m_resourceDir.GetPath() + _T("xrc/resources.xrc"))) == fz::local_filesys::file) {
470                pResource->LoadFile(m_resourceDir.GetPath() + _T("xrc/resources.xrc"));
471        }
472        else {
473                fz::local_filesys fs;
474                wxString dir = m_resourceDir.GetPath() + _T("xrc/");
475                bool found = fs.begin_find_files(fz::to_native(dir), false);
476                while (found) {
477                        fz::native_string name;
478                        found = fs.get_next_file(name);
479                        if (name.size() <= 4 || name.substr(name.size() - 4) != fzT(".xrc")) {
480                                continue;
481                        }
482                        pResource->LoadFile(dir + name);
483                }
484        }
485
486        return true;
487}
488
489bool CFileZillaApp::InitDefaultsDir()
490{
491        AddStartupProfileRecord(_T("InitDefaultsDir"));
492#ifdef __WXGTK__
493        m_defaultsDir = COptions::GetUnadjustedSettingsDir();
494        if( m_defaultsDir.empty() || !wxFileName::FileExists(m_defaultsDir.GetPath() + _T("fzdefaults.xml"))) {
495                if (wxFileName::FileExists(_T("/etc/filezilla/fzdefaults.xml"))) {
496                        m_defaultsDir.SetPath(_T("/etc/filezilla"));
497                }
498                else {
499                        m_defaultsDir.clear();
500                }
501        }
502
503#endif
504        if( m_defaultsDir.empty() ) {
505                m_defaultsDir = GetDataDir(_T("fzdefaults.xml"));
506        }
507
508        return !m_defaultsDir.empty();
509}
510
511bool CFileZillaApp::LoadLocales()
512{
513        AddStartupProfileRecord(_T("CFileZillaApp::LoadLocales"));
514#ifndef __WXMAC__
515        m_localesDir = GetDataDir(_T("../locale/*/filezilla.mo"));
516        if (m_localesDir.empty())
517                m_localesDir = GetDataDir(_T("../locale/*/LC_MESSAGES/filezilla.mo"));
518        if (!m_localesDir.empty()) {
519                m_localesDir.ChangePath( _T("../locale") );
520        }
521        else {
522                m_localesDir = GetDataDir(_T("locales/*/filezilla.mo"));
523                if (!m_localesDir.empty()) {
524                        m_localesDir.AddSegment(_T("locales"));
525                }
526        }
527#else
528        m_localesDir.SetPath(wxStandardPaths::Get().GetDataDir() + _T("/locales"));
529#endif
530
531        if (!m_localesDir.empty()) {
532                wxLocale::AddCatalogLookupPathPrefix(m_localesDir.GetPath());
533        }
534
535        SetLocale(wxLANGUAGE_DEFAULT);
536
537        return true;
538}
539
540bool CFileZillaApp::SetLocale(int language)
541{
542        // First check if we can load the new locale
543        auto pLocale = std::make_unique<wxLocale>();
544        wxLogNull log;
545        pLocale->Init(language);
546        if (!pLocale->IsOk() || !pLocale->AddCatalog(_T("filezilla"))) {
547                return false;
548        }
549
550        // Now unload old locale
551        // We unload new locale as well, else the internal locale chain in wxWidgets get's broken.
552        pLocale.reset();
553        m_pLocale.reset();
554
555        // Finally load new one
556        pLocale = std::make_unique<wxLocale>();
557        pLocale->Init(language);
558        if (!pLocale->IsOk() || !pLocale->AddCatalog(_T("filezilla"))) {
559                return false;
560        }
561        m_pLocale = std::move(pLocale);
562
563        return true;
564}
565
566int CFileZillaApp::GetCurrentLanguage() const
567{
568        if (!m_pLocale)
569                return wxLANGUAGE_ENGLISH;
570
571        return m_pLocale->GetLanguage();
572}
573
574wxString CFileZillaApp::GetCurrentLanguageCode() const
575{
576        if (!m_pLocale)
577                return wxString();
578
579        return m_pLocale->GetCanonicalName();
580}
581
582#if wxUSE_DEBUGREPORT && wxUSE_ON_FATAL_EXCEPTION
583void CFileZillaApp::OnFatalException()
584{
585}
586#endif
587
588void CFileZillaApp::DisplayEncodingWarning()
589{
590        static bool displayedEncodingWarning = false;
591        if (displayedEncodingWarning)
592                return;
593
594        displayedEncodingWarning = true;
595
596        wxMessageBoxEx(_("A local filename could not be decoded.\nPlease make sure the LC_CTYPE (or LC_ALL) environment variable is set correctly.\nUnless you fix this problem, files might be missing in the file listings.\nNo further warning will be displayed this session."), _("Character encoding issue"), wxICON_EXCLAMATION);
597}
598
599CWrapEngine* CFileZillaApp::GetWrapEngine()
600{
601        return m_pWrapEngine.get();
602}
603
604void CFileZillaApp::CheckExistsFzsftp()
605{
606        AddStartupProfileRecord(_T("CFileZillaApp::CheckExistsFzstp"));
607        // Get the correct path to the fzsftp executable
608
609#ifdef __WXMAC__
610        wxString executable = wxStandardPaths::Get().GetExecutablePath();
611        int pos = executable.Find('/', true);
612        if (pos != -1)
613                executable = executable.Left(pos);
614        executable += _T("/fzsftp");
615        if (!wxFileName::FileExists(executable))
616        {
617                wxMessageBoxEx(wxString::Format(_("%s could not be found. Without this component of FileZilla, SFTP will not work.\n\nPlease download FileZilla again. If this problem persists, please submit a bug report."), executable),
618                        _("File not found"), wxICON_ERROR);
619                executable.clear();
620        }
621
622#else
623
624        wxString program = _T("fzsftp");
625#ifdef __WXMSW__
626        program += _T(".exe");
627#endif
628
629        bool found = false;
630
631        // First check the FZ_FZSFTP environment variable
632        wxString executable;
633        if (wxGetEnv(_T("FZ_FZSFTP"), &executable)) {
634                if (wxFileName::FileExists(executable))
635                        found = true;
636        }
637
638        if (!found) {
639                wxPathList pathList;
640
641                // Add current working directory
642                const wxString &cwd = wxGetCwd();
643                pathList.Add(cwd);
644#ifdef __WXMSW__
645
646                // Add executable path
647                wxChar modulePath[1000];
648                DWORD len = GetModuleFileName(0, modulePath, 999);
649                if (len) {
650                        modulePath[len] = 0;
651                        wxString path(modulePath);
652                        int pos = path.Find('\\', true);
653                        if (pos != -1) {
654                                path = path.Left(pos);
655                                pathList.Add(path);
656                        }
657                }
658#endif
659
660                // Add a few paths relative to the current working directory
661                pathList.Add(cwd + _T("/bin"));
662                pathList.Add(cwd + _T("/src/putty"));
663                pathList.Add(cwd + _T("/putty"));
664
665                executable = pathList.FindAbsoluteValidPath(program);
666                if (!executable.empty())
667                        found = true;
668        }
669
670#ifdef __UNIX__
671        if (!found) {
672                const wxString prefix = ((const wxStandardPaths&)wxStandardPaths::Get()).GetInstallPrefix();
673                if (prefix != _T("/usr/local")) {
674                        // /usr/local is the fallback value. /usr/local/bin is most likely in the PATH
675                        // environment variable already so we don't have to check it. Furthermore, other
676                        // directories might be listed before it (For example a developer's own
677                        // application prefix)
678                        wxFileName fn(prefix + _T("/bin/"), program);
679                        fn.Normalize();
680                        if (fn.FileExists()) {
681                                executable = fn.GetFullPath();
682                                found = true;
683                        }
684                }
685        }
686#endif
687
688        if (!found) {
689                // Check PATH
690                wxPathList pathList;
691                pathList.AddEnvList(_T("PATH"));
692                executable = pathList.FindAbsoluteValidPath(program);
693                if (!executable.empty())
694                        found = true;
695        }
696
697        if (!found) {
698                // Quote path if it contains spaces
699                if (executable.Find(_T(" ")) != -1 && executable[0] != '"' && executable[0] != '\'')
700                        executable = _T("\"") + executable + _T("\"");
701
702                wxMessageBoxEx(wxString::Format(_("%s could not be found. Without this component of FileZilla, SFTP will not work.\n\nPossible solutions:\n- Make sure %s is in a directory listed in your PATH environment variable.\n- Set the full path to %s in the FZ_FZSFTP environment variable."), program, program, program),
703                        _("File not found"), wxICON_ERROR | wxOK);
704                executable.clear();
705        }
706#endif
707
708        COptions::Get()->SetOption(OPTION_FZSFTP_EXECUTABLE, executable);
709}
710
711#ifdef __WXMSW__
712extern "C" BOOL CALLBACK EnumWindowCallback(HWND hwnd, LPARAM)
713{
714        HWND child = FindWindowEx(hwnd, 0, 0, _T("FileZilla process identificator 3919DB0A-082D-4560-8E2F-381A35969FB4"));
715        if (child) {
716                ::PostMessage(hwnd, WM_ENDSESSION, (WPARAM)TRUE, (LPARAM)ENDSESSION_LOGOFF);
717        }
718
719        return TRUE;
720}
721#endif
722
723int CFileZillaApp::ProcessCommandLine()
724{
725        AddStartupProfileRecord(_T("CFileZillaApp::ProcessCommandLine"));
726        m_pCommandLine = std::make_unique<CCommandLine>(argc, argv);
727        int res = m_pCommandLine->Parse() ? 1 : -1;
728
729        if (res > 0) {
730                if (m_pCommandLine->HasSwitch(CCommandLine::close)) {
731#ifdef __WXMSW__
732                        EnumWindows((WNDENUMPROC)EnumWindowCallback, 0);
733#endif
734                        return 0;
735                }
736
737                if (m_pCommandLine->HasSwitch(CCommandLine::version)) {
738                        wxString out = wxString::Format(_T("FileZilla %s"), CBuildInfo::GetVersion());
739                        if (!CBuildInfo::GetBuildType().empty())
740                                out += _T(" ") + CBuildInfo::GetBuildType() + _T(" build");
741                        out += _T(", compiled on ") + CBuildInfo::GetBuildDateString();
742
743                        printf("%s\n", (const char*)out.mb_str());
744                        return 0;
745                }
746        }
747
748        return res;
749}
750
751void CFileZillaApp::AddStartupProfileRecord(const wxString& msg)
752{
753        if (!m_profilingActive)
754                return;
755
756        m_startupProfile.push_back(std::make_pair(wxDateTime::UNow(), msg));
757}
758
759void CFileZillaApp::ShowStartupProfile()
760{
761        m_profilingActive = false;
762
763        std::list<std::pair<wxDateTime, wxString> > profile;
764        profile.swap(m_startupProfile);
765
766        if (m_pCommandLine && !m_pCommandLine->HasSwitch(CCommandLine::debug_startup))
767                return;
768
769        wxString msg = _T("Profile:\n");
770        for (auto const& p : profile) {
771                msg += p.first.Format(_T("%Y-%m-%d %H:%M:%S %l"));
772                msg += _T(" ");
773                msg += p.second;
774                msg += _T("\n");
775        }
776
777        wxMessageBoxEx(msg);
778}
779
780wxString CFileZillaApp::GetSettingsFile(wxString const& name) const
781{
782        return COptions::Get()->GetOption(OPTION_DEFAULT_SETTINGSDIR) + name + _T(".xml");
783}
Note: See TracBrowser for help on using the repository browser.