Annotation of truecrypt/main/graphicuserinterface.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
                      3: 
                      4:  Governed by the TrueCrypt License 2.4 the full text of which is contained
                      5:  in the file License.txt included in TrueCrypt binary and source code
                      6:  distribution packages.
                      7: */
                      8: 
                      9: #include <wx/mimetype.h>
                     10: #include <wx/sckipc.h>
                     11: #include "System.h"
                     12: 
                     13: #ifdef TC_UNIX
                     14: #include <signal.h>
                     15: #include <sys/utsname.h>
                     16: #include "Platform/Unix/Process.h"
                     17: #endif
                     18: 
                     19: #include "Application.h"
                     20: #include "GraphicUserInterface.h"
                     21: #include "FatalErrorHandler.h"
                     22: #include "Forms/DeviceSelectionDialog.h"
                     23: #include "Forms/MainFrame.h"
                     24: #include "Forms/MountOptionsDialog.h"
                     25: 
                     26: namespace TrueCrypt
                     27: {
                     28:        GraphicUserInterface::GraphicUserInterface () : BackgroundMode (false), mMainFrame (nullptr)
                     29:        {
                     30: #ifdef TC_UNIX
                     31:                signal (SIGHUP, OnSignal);
                     32:                signal (SIGINT, OnSignal);
                     33:                signal (SIGQUIT, OnSignal);
                     34:                signal (SIGTERM, OnSignal);
                     35: #endif
                     36: 
                     37: #ifdef TC_MACOSX
                     38:                wxApp::s_macHelpMenuTitleName = _("Help");
                     39: #endif
                     40:        }
                     41: 
                     42:        GraphicUserInterface::~GraphicUserInterface ()
                     43:        {
                     44:                FatalErrorHandler::Deregister();
                     45: 
                     46: #ifdef TC_UNIX
                     47:                signal (SIGHUP, SIG_DFL);
                     48:                signal (SIGINT, SIG_DFL);
                     49:                signal (SIGQUIT, SIG_DFL);
                     50:                signal (SIGTERM, SIG_DFL);
                     51: #endif
                     52:        }
                     53:        
                     54:        void GraphicUserInterface::AppendToListCtrl (wxListCtrl *listCtrl, const vector <wstring> &itemFields, int imageIndex, void *itemDataPtr) const
                     55:        {
                     56:                InsertToListCtrl (listCtrl, listCtrl->GetItemCount(), itemFields, imageIndex, itemDataPtr);
                     57:        }
                     58: 
                     59:        wxMenuItem *GraphicUserInterface::AppendToMenu (wxMenu &menu, const wxString &label, wxEvtHandler *handler, wxObjectEventFunction handlerFunction, int itemId) const
                     60:        {
                     61:                wxMenuItem *item = new wxMenuItem (&menu, itemId, label);
                     62:                menu.Append (item);
                     63:                
                     64:                if (handler)
                     65:                        handler->Connect (item->GetId(), wxEVT_COMMAND_MENU_SELECTED, handlerFunction);
                     66: 
                     67:                return item;
                     68:        }
                     69: 
                     70:        bool GraphicUserInterface::AskYesNo (const wxString &message, bool defaultYes, bool warning) const
                     71:        {
                     72:                return ShowMessage (message,
                     73:                        wxYES_NO | (warning ? wxICON_EXCLAMATION : wxICON_QUESTION) | (defaultYes ? wxYES_DEFAULT : wxNO_DEFAULT)
                     74:                        ) == wxYES;
                     75:        }
                     76: 
                     77:        void GraphicUserInterface::AutoDismountVolumes (VolumeInfoList mountedVolumes, bool alwaysForce)
                     78:        {
                     79:                size_t mountedVolumeCount = Core->GetMountedVolumes().size();
                     80:                try
                     81:                {
                     82:                        wxBusyCursor busy;
                     83:                        DismountVolumes (mountedVolumes, alwaysForce ? true : GetPreferences().ForceAutoDismount, false);
                     84:                }
                     85:                catch (...) { }
                     86: 
                     87:                if (Core->GetMountedVolumes().size() < mountedVolumeCount)
                     88:                        OnVolumesAutoDismounted();
                     89:        }
                     90:        
                     91:        void GraphicUserInterface::BeginInteractiveBusyState (wxWindow *window)
                     92:        {
                     93:                static auto_ptr <wxCursor> arrowWaitCursor;
                     94: 
                     95:                if (arrowWaitCursor.get() == nullptr)
                     96:                        arrowWaitCursor.reset (new wxCursor (wxCURSOR_ARROWWAIT));
                     97: 
                     98:                window->SetCursor (*arrowWaitCursor);
                     99:        }
                    100: 
                    101:        void GraphicUserInterface::ChangePassword (shared_ptr <VolumePath> volumePath, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, shared_ptr <KeyfileList> newKeyfiles) const
                    102:        {
                    103:                Gui->ShowError (_("This feature is currently supported only in text mode."));
                    104:                throw UserAbort (SRC_POS);
                    105:        }
                    106: 
                    107:        void GraphicUserInterface::ClearListCtrlSelection (wxListCtrl *listCtrl) const
                    108:        {
                    109:                foreach (long item, GetListCtrlSelectedItems (listCtrl))
                    110:                        listCtrl->SetItemState (item, 0, wxLIST_STATE_SELECTED);
                    111:        }
                    112: 
                    113:        void GraphicUserInterface::DoShowError (const wxString &message) const
                    114:        {
                    115:                ShowMessage (message, wxOK | wxICON_ERROR);
                    116:        }
                    117:        
                    118:        void GraphicUserInterface::DoShowInfo (const wxString &message) const
                    119:        {
                    120:                ShowMessage (message, wxOK | wxICON_INFORMATION);
                    121:        }
                    122: 
                    123:        void GraphicUserInterface::DoShowString (const wxString &str) const
                    124:        {
                    125:                ShowMessage (str, wxOK);
                    126:        }
                    127: 
                    128:        void GraphicUserInterface::DoShowWarning (const wxString &message) const
                    129:        {
                    130:                ShowMessage (message, wxOK 
                    131: #ifndef TC_MACOSX
                    132:                        | wxICON_EXCLAMATION
                    133: #endif
                    134:                        );
                    135:        }
                    136:        
                    137:        void GraphicUserInterface::EndInteractiveBusyState (wxWindow *window) const
                    138:        {
                    139:                static auto_ptr <wxCursor> arrowCursor;
                    140: 
                    141:                if (arrowCursor.get() == nullptr)
                    142:                        arrowCursor.reset (new wxCursor (wxCURSOR_ARROW));
                    143: 
                    144:                window->SetCursor (*arrowCursor);
                    145:        }
                    146: 
                    147:        wxTopLevelWindow *GraphicUserInterface::GetActiveWindow () const
                    148:        {
                    149: #ifdef TC_WINDOWS
                    150:                return dynamic_cast <wxTopLevelWindow *> (wxGetActiveWindow());
                    151: #endif
                    152:                if (wxTopLevelWindows.size() == 1)
                    153:                        return dynamic_cast <wxTopLevelWindow *> (wxTopLevelWindows.front());
                    154: 
                    155: #ifdef __WXGTK__
                    156:                wxLongLong startTime = wxGetLocalTimeMillis();
                    157:                do
                    158:                {
                    159: #endif
                    160:                        foreach (wxWindow *window, wxTopLevelWindows)
                    161:                        {
                    162:                                wxTopLevelWindow *topLevelWin = dynamic_cast <wxTopLevelWindow *> (window);
                    163:                                if (topLevelWin && topLevelWin->IsActive() && topLevelWin->IsShown())
                    164:                                        return topLevelWin;
                    165:                        }
                    166: #ifdef __WXGTK__
                    167:                        Yield(); // GTK does a lot of operations asynchronously, which makes it prone to many race conditions
                    168:                } while (wxGetLocalTimeMillis() - startTime < 500);
                    169: #endif
                    170: 
                    171:                return dynamic_cast <wxTopLevelWindow *> (GetTopWindow());
                    172:        }
                    173: 
                    174:        shared_ptr <GetStringFunctor> GraphicUserInterface::GetAdminPasswordRequestHandler ()
                    175:        {
                    176:                struct AdminPasswordRequestHandler : public GetStringFunctor
                    177:                {
                    178:                        virtual string operator() ()
                    179:                        {
                    180:                                wxPasswordEntryDialog dialog (Gui->GetActiveWindow(), LangString["ENTER_PASSWORD"] + L":", _("Administrator privileges required"));
                    181: 
                    182:                                if (dialog.ShowModal() != wxID_OK)
                    183:                                        throw UserAbort (SRC_POS);
                    184: 
                    185:                                return StringConverter::ToSingle (wstring (dialog.GetValue()));
                    186:                        }
                    187:                };
                    188: 
                    189:                return shared_ptr <GetStringFunctor> (new AdminPasswordRequestHandler);
                    190:        }
                    191:        
                    192:        int GraphicUserInterface::GetCharHeight (wxWindow *window) const
                    193:        {
                    194:                int width;
                    195:                int height;
                    196:                window->GetTextExtent (L"a", &width, &height);
                    197: 
                    198:                if (height < 1)
                    199:                        return 14;
                    200: 
                    201:                return height;
                    202:        }
                    203: 
                    204:        int GraphicUserInterface::GetCharWidth (wxWindow *window) const
                    205:        {
                    206:                int width;
                    207:                int height;
                    208:                window->GetTextExtent (L"a", &width, &height);
                    209: 
                    210:                if (width < 1)
                    211:                        return 7;
                    212: 
                    213:                return width;
                    214:        }
                    215: 
                    216:        wxFont GraphicUserInterface::GetDefaultBoldFont (wxWindow *window) const
                    217:        {
                    218:                return wxFont (
                    219: #ifdef __WXGTK__
                    220:                        9
                    221: #elif defined(TC_MACOSX)
                    222:                        13
                    223: #else
                    224:                        10 
                    225: #endif
                    226:                        * GetCharHeight (window) / 13, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, 
                    227: #ifdef __WXGTK__
                    228:                        wxFONTWEIGHT_BOLD, false);
                    229: #elif defined(TC_MACOSX)
                    230:                        wxFONTWEIGHT_NORMAL, false);
                    231: #else
                    232:                        wxFONTWEIGHT_BOLD, false, L"Arial");
                    233: #endif
                    234:        }
                    235: 
                    236:        list <long> GraphicUserInterface::GetListCtrlSelectedItems (wxListCtrl *listCtrl) const
                    237:        {
                    238:                list <long> selectedItems;
                    239:                
                    240:                long item = -1;
                    241:                while ((item = listCtrl->GetNextItem (item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != -1)
                    242:                        selectedItems.push_back (item);
                    243: 
                    244:                return selectedItems;
                    245:        }
                    246: 
                    247:        wxString GraphicUserInterface::GetListCtrlSubItemText (wxListCtrl *listCtrl, long itemIndex, int columnIndex) const
                    248:        {
                    249:                wxListItem item;
                    250:                item.SetId (itemIndex);
                    251:                item.SetColumn (columnIndex);
                    252:                item.SetText (L"");
                    253:                        
                    254:                if (!listCtrl->GetItem (item))
                    255:                        throw ParameterIncorrect (SRC_POS);
                    256: 
                    257:                return item.GetText();
                    258:        }
                    259: 
                    260:        int GraphicUserInterface::GetScrollbarWidth (wxWindow *window, bool noScrollBar) const
                    261:        {
                    262:                int offset = 0;
                    263: #ifdef TC_WINDOWS
                    264:                offset = 4;
                    265: #elif defined (__WXGTK__)
                    266:                offset = 5;
                    267: #elif defined (TC_MACOSX)
                    268:                offset = 9;
                    269: #endif
                    270:                if (noScrollBar)
                    271:                        return offset;
                    272: 
                    273:                int width = wxSystemSettings::GetMetric (wxSYS_VSCROLL_X, window);
                    274:                if (width == -1)
                    275:                        return 24;
                    276: 
                    277:                return width + offset;
                    278:        }
                    279: 
                    280: 
                    281:        void GraphicUserInterface::InsertToListCtrl (wxListCtrl *listCtrl, long itemIndex, const vector <wstring> &itemFields, int imageIndex, void *itemDataPtr) const
                    282:        {
                    283:                wxListItem item;
                    284:                item.SetData (itemDataPtr);
                    285:                item.SetId (itemIndex);
                    286:                item.SetImage (imageIndex);
                    287:                int col = 0;
                    288:                foreach (wxString field, itemFields)
                    289:                {
                    290:                        item.SetColumn (col++);
                    291:                        item.SetText (field);
                    292:                        if (col == 1)
                    293:                        {
                    294:                                throw_sys_if (listCtrl->InsertItem (item) == -1);
                    295:                                item.SetImage (-1);
                    296:                                continue;
                    297:                        }
                    298: 
                    299:                        listCtrl->SetItem (item);
                    300:                }
                    301:        }
                    302:        
                    303:        bool GraphicUserInterface::IsTheOnlyTopLevelWindow (const wxWindow *window) const
                    304:        {
                    305:                foreach (wxWindow *w, wxTopLevelWindows)
                    306:                {
                    307:                        if (w != window
                    308:                                && (dynamic_cast <const wxFrame *> (w) || dynamic_cast <const wxDialog *> (w))
                    309:                                && StringConverter::GetTypeName (typeid (*w)).find ("wxTaskBarIcon") == string::npos)
                    310:                        {
                    311:                                return false;
                    312:                        }
                    313:                }
                    314:                return true;
                    315:        }
                    316: 
                    317:        void GraphicUserInterface::MoveListCtrlItem (wxListCtrl *listCtrl, long itemIndex, long newItemIndex) const
                    318:        {
                    319:                if (itemIndex == newItemIndex || newItemIndex < 0
                    320:                        || (newItemIndex > itemIndex && newItemIndex == listCtrl->GetItemCount()))
                    321:                        return;
                    322: 
                    323:                wxListItem item;
                    324:                item.SetId (itemIndex);
                    325:                item.SetData ((void *) nullptr);
                    326:                item.SetImage (-1);
                    327:                
                    328:                if (!listCtrl->GetItem (item))
                    329:                        throw ParameterIncorrect (SRC_POS);
                    330: 
                    331:                int itemState = listCtrl->GetItemState (itemIndex, wxLIST_STATE_SELECTED);
                    332: 
                    333:                vector <wstring> itemFields (listCtrl->GetColumnCount());
                    334:                for (size_t col = 0; col < itemFields.size(); ++col)
                    335:                {
                    336:                        itemFields[col] = GetListCtrlSubItemText (listCtrl, itemIndex, col);
                    337:                }
                    338: 
                    339:                listCtrl->DeleteItem (itemIndex);
                    340:                
                    341:                if (newItemIndex > listCtrl->GetItemCount() - 1)
                    342:                        AppendToListCtrl (listCtrl, itemFields, item.GetImage(), (void *) item.GetData());
                    343:                else
                    344:                        InsertToListCtrl (listCtrl, newItemIndex, itemFields, item.GetImage(), (void *) item.GetData());
                    345: 
                    346:                item.SetId (newItemIndex);
                    347:                listCtrl->SetItemState (item, itemState, wxLIST_STATE_SELECTED);
                    348:        }
                    349: 
                    350:        VolumeInfoList GraphicUserInterface::MountAllDeviceHostedVolumes (MountOptions &options) const
                    351:        {
                    352:                MountOptionsDialog dialog (GetTopWindow(), options);
                    353:                while (true)
                    354:                {
                    355:                        options.Path.reset();
                    356: 
                    357:                        if (dialog.ShowModal() != wxID_OK)
                    358:                                return VolumeInfoList();
                    359: 
                    360:                        VolumeInfoList mountedVolumes = UserInterface::MountAllDeviceHostedVolumes (options);
                    361:                        
                    362:                        if (!mountedVolumes.empty())
                    363:                                return mountedVolumes;
                    364:                }
                    365:        }
                    366: 
                    367:        shared_ptr <VolumeInfo> GraphicUserInterface::MountVolume (MountOptions &options) const
                    368:        {
                    369:                shared_ptr <VolumeInfo> volume;
                    370: 
                    371:                if (Core->IsVolumeMounted (*options.Path))
                    372:                {
                    373:                        ShowInfo (StringFormatter (LangString["VOLUME_ALREADY_MOUNTED"], wstring (*options.Path)));
                    374:                        return volume;
                    375:                }
                    376: 
                    377:                try
                    378:                {
                    379:                        if ((!options.Password || options.Password->IsEmpty())
                    380:                                && (!options.Keyfiles || options.Keyfiles->empty())
                    381:                                && !Core->IsPasswordCacheEmpty())
                    382:                        {
                    383:                                // Cached password
                    384:                                try
                    385:                                {
                    386:                                        wxBusyCursor busy;
                    387:                                        return UserInterface::MountVolume (options);
                    388:                                }
                    389:                                catch (PasswordException&) { }
                    390:                        }
                    391: 
                    392:                        VolumePassword password;
                    393:                        KeyfileList keyfiles;
                    394: 
                    395:                        MountOptionsDialog dialog (GetTopWindow(), options);
                    396:                        while (!volume)
                    397:                        {
                    398:                                dialog.Hide();
                    399:                                if (dialog.ShowModal() != wxID_OK)
                    400:                                        return volume;
                    401: 
                    402:                                try
                    403:                                {
                    404:                                        wxBusyCursor busy;
                    405:                                        volume = UserInterface::MountVolume (options);
                    406:                                }
                    407:                                catch (PasswordException &e)
                    408:                                {
                    409:                                        ShowWarning (e);
                    410:                                }
                    411:                        }
                    412:                }
                    413:                catch (exception &e)
                    414:                {
                    415:                        ShowError (e);
                    416:                }
                    417: 
                    418:                return volume;
                    419:        }
                    420: 
                    421:        void GraphicUserInterface::OnAutoDismountAllEvent ()
                    422:        {
                    423:                VolumeInfoList mountedVolumes = Core->GetMountedVolumes();
                    424: 
                    425:                if (!mountedVolumes.empty())
                    426:                {
                    427:                        wxBusyCursor busy;
                    428:                        AutoDismountVolumes (mountedVolumes);
                    429:                }
                    430:        }
                    431: 
                    432:        bool GraphicUserInterface::OnInit ()
                    433:        {
                    434:                Gui = this;
                    435:                InterfaceType = UserInterfaceType::Graphic;
                    436:                try
                    437:                {
                    438:                        FatalErrorHandler::Register();
                    439:                        Init();
                    440: 
                    441:                        if (ProcessCommandLine() && !CmdLine->StartBackgroundTask)
                    442:                        {
                    443:                                Yield();
                    444:                                Application::SetExitCode (0);
                    445:                                return false;
                    446:                        }
                    447: 
                    448:                        // Check if another instance is already running and bring its windows to foreground
                    449: #ifndef TC_MACOSX
                    450: #ifdef TC_WINDOWS
                    451:                        const wxString serverName = Application::GetName() + L"-" + wxGetUserId();
                    452:                        class Connection : public wxDDEConnection
                    453:                        {
                    454:                        public:
                    455:                                Connection () { }
                    456: 
                    457:                                bool OnExecute (const wxString& topic, wxChar *data, int size, wxIPCFormat format)
                    458:                                {
                    459:                                        if (topic == L"raise")
                    460:                                        {
                    461:                                                if (Gui->IsInBackgroundMode())
                    462:                                                        Gui->SetBackgroundMode (false);
                    463: 
                    464:                                                Gui->mMainFrame->Show (true);
                    465:                                                Gui->mMainFrame->Raise ();
                    466:                                                return true;
                    467:                                        }
                    468:                                        return false;
                    469:                                }
                    470:                        };
                    471: #endif
                    472: 
                    473:                        SingleInstanceChecker.reset (new wxSingleInstanceChecker (wxString (L".") + Application::GetName() + L"-lock-" + wxGetUserId()));
                    474:                        
                    475:                        if (SingleInstanceChecker->IsAnotherRunning())
                    476:                        {
                    477: #ifdef TC_WINDOWS
                    478:                                class Client: public wxDDEClient
                    479:                                {
                    480:                                public:
                    481:                                        Client() {};
                    482:                                        wxConnectionBase *OnMakeConnection () { return new Connection; }
                    483:                                };
                    484: 
                    485:                                auto_ptr <wxDDEClient> client (new Client);
                    486:                                auto_ptr <wxConnectionBase> connection (client->MakeConnection (L"localhost", serverName, L"raise"));
                    487: 
                    488:                                if (connection.get() && connection->Execute (nullptr))
                    489:                                {
                    490:                                        connection->Disconnect();
                    491:                                        Application::SetExitCode (0);
                    492:                                        return false;
                    493:                                }
                    494: #endif
                    495:                                wxLog::FlushActive();
                    496:                                Application::SetExitCode (1);
                    497:                                Gui->ShowInfo (_("TrueCrypt is already running."));
                    498:                                return false;
                    499:                        }
                    500: 
                    501: #ifdef TC_WINDOWS
                    502:                        class Server : public wxDDEServer
                    503:                        {
                    504:                        public:
                    505:                                wxConnectionBase *OnAcceptConnection (const wxString &topic)
                    506:                                {
                    507:                                        if (topic == L"raise")
                    508:                                                return new Connection;
                    509:                                        return nullptr;
                    510:                                }
                    511:                        };
                    512: 
                    513:                        DDEServer.reset (new Server);
                    514:                        if (!DDEServer->Create (serverName))
                    515:                                wxLog::FlushActive();
                    516: #endif
                    517: #endif // !TC_MACOSX
                    518: 
                    519:                        Connect (wxEVT_END_SESSION, wxCloseEventHandler (GraphicUserInterface::OnEndSession));
                    520: #ifdef wxHAS_POWER_EVENTS
                    521:                        Gui->Connect (wxEVT_POWER_SUSPENDING, wxPowerEventHandler (GraphicUserInterface::OnPowerSuspending));
                    522: #endif
                    523: 
                    524:                        mMainFrame = new MainFrame (nullptr);
                    525: 
                    526:                        if (CmdLine->StartBackgroundTask)
                    527:                        {
                    528:                                UserPreferences prefs = GetPreferences ();
                    529:                                prefs.BackgroundTaskEnabled = true;
                    530:                                SetPreferences (prefs);
                    531:                                mMainFrame->Close();
                    532:                        }
                    533:                        else
                    534:                        {
                    535:                                mMainFrame->Show (true);
                    536:                        }
                    537: 
                    538:                        SetTopWindow (mMainFrame);
                    539:                }
                    540:                catch (exception &e)
                    541:                {
                    542:                        ShowError (e);
                    543:                        return false;
                    544:                }
                    545: 
                    546:                return true;
                    547:        }
                    548:        
                    549:        void GraphicUserInterface::OnLogOff ()
                    550:        {
                    551:                VolumeInfoList mountedVolumes = Core->GetMountedVolumes();
                    552:                if (GetPreferences().BackgroundTaskEnabled && GetPreferences().DismountOnLogOff
                    553:                        && !mountedVolumes.empty())
                    554:                {
                    555:                        wxLongLong startTime = wxGetLocalTimeMillis();
                    556:                        bool timeOver = false;
                    557: 
                    558:                        wxBusyCursor busy;
                    559:                        while (!timeOver && !mountedVolumes.empty())
                    560:                        {
                    561:                                try
                    562:                                {
                    563:                                        timeOver = (wxGetLocalTimeMillis() - startTime >= 4000);
                    564:                                        
                    565:                                        DismountVolumes (mountedVolumes, !timeOver ? false : GetPreferences().ForceAutoDismount, timeOver);
                    566:                                        OnVolumesAutoDismounted();
                    567:                                        
                    568:                                        break;
                    569:                                }
                    570:                                catch (UserAbort&)
                    571:                                {
                    572:                                        return;
                    573:                                }
                    574:                                catch (...)
                    575:                                {
                    576:                                        Thread::Sleep (500);
                    577:                                }
                    578: 
                    579:                                VolumeInfoList mountedVolumes = Core->GetMountedVolumes();
                    580:                        }
                    581: 
                    582:                }
                    583:        }
                    584: 
                    585: #ifdef wxHAS_POWER_EVENTS
                    586:        void GraphicUserInterface::OnPowerSuspending (wxPowerEvent& event)
                    587:        {
                    588:                size_t volumeCount = Core->GetMountedVolumes().size();
                    589:                if (GetPreferences().BackgroundTaskEnabled && GetPreferences().DismountOnPowerSaving && volumeCount > 0)
                    590:                {
                    591:                        OnAutoDismountAllEvent();
                    592: 
                    593:                        if (Core->GetMountedVolumes().size() < volumeCount)
                    594:                                ShowInfoTopMost (LangString["MOUNTED_VOLUMES_AUTO_DISMOUNTED"]);
                    595:                }
                    596:        }
                    597: #endif
                    598: 
                    599:        void GraphicUserInterface::OnSignal (int signal)
                    600:        {
                    601: #ifdef TC_UNIX
                    602:                Gui->SingleInstanceChecker.reset();
                    603:                _exit (1);
                    604: #endif
                    605:        }
                    606: 
                    607:        void GraphicUserInterface::OnVolumesAutoDismounted ()
                    608:        {
                    609:                if (GetPreferences().WipeCacheOnAutoDismount)
                    610:                        Core->WipePasswordCache();
                    611:        }
                    612: 
                    613:        void GraphicUserInterface::OpenDocument (wxWindow *parent, const wxFileName &document)
                    614:        {
                    615: 
                    616: #ifdef TC_WINDOWS
                    617: 
                    618:                if (int (ShellExecute (GetTopWindow() ? static_cast <HWND> (GetTopWindow()->GetHandle()) : nullptr, L"open",
                    619:                document.GetFullPath().c_str(), nullptr, nullptr, SW_SHOWNORMAL)) >= 32)
                    620:                return;
                    621: 
                    622: #else
                    623:                wxMimeTypesManager mimeMgr;
                    624:                wxFileType *fileType = mimeMgr.GetFileTypeFromExtension (document.GetExt());
                    625:                if (fileType)
                    626:                {
                    627:                        try
                    628:                        {
                    629: #ifdef TC_MACOSX
                    630:                                if (wxExecute (fileType->GetOpenCommand (document.GetFullPath())) != 0)
                    631:                                        return;
                    632: #else
                    633:                                if (wxExecute (fileType->GetOpenCommand (L"\"" + document.GetFullPath() + L"\"")) != 0)
                    634:                                        return;
                    635: #endif
                    636:                        }
                    637:                        catch (TimeOut&)
                    638:                        {
                    639:                                return;
                    640:                        }
                    641:                        catch (Exception &e)
                    642:                        {
                    643:                                Gui->ShowError (e);
                    644:                        }
                    645:                }
                    646: #endif
                    647:                if (Gui->AskYesNo (LangString ["HELP_READER_ERROR"]))
                    648:                        OpenOnlineHelp (parent);
                    649:        }
                    650: 
                    651:        wxString GraphicUserInterface::GetHomepageLinkURL (const wxString &linkId, const wxString &extraVars) const
                    652:        {
                    653:                wxString url = wxString (L"http://www.truecrypt.org/applink.php?version=4.3a&dest=") + linkId;
                    654:                
                    655:                wxString os, osVersion, architecture;
                    656: 
                    657: #ifdef TC_WINDOWS
                    658: 
                    659:                os = L"Windows";
                    660: 
                    661: #elif defined (TC_UNIX)
                    662:                struct utsname unameData;
                    663:                if (uname (&unameData) != -1)
                    664:                {
                    665:                        os = StringConverter::ToWide (unameData.sysname);
                    666:                        osVersion = StringConverter::ToWide (unameData.release);
                    667:                        architecture = StringConverter::ToWide (unameData.machine);
                    668:                        //os = L"MacOSX";
                    669: 
                    670:                        if (os == L"Darwin")
                    671:                                os = L"MacOSX";
                    672:                }
                    673:                else
                    674:                        os = L"Unknown";
                    675: #else
                    676:                os = L"Unknown";
                    677: #endif
                    678: 
                    679:                os.Replace (L" ", L"-");
                    680:                url += L"&os=";
                    681:                url += os;
                    682: 
                    683:                osVersion.Replace (L" ", L"-");
                    684:                url += L"&osver=";
                    685:                url += osVersion;
                    686: 
                    687:                architecture.Replace (L" ", L"-");
                    688:                url += L"&arch=";
                    689:                url += architecture;
                    690: 
                    691:                if (!extraVars.empty())
                    692:                {
                    693:                         url += L"&";
                    694:                         url += extraVars;
                    695:                }
                    696: 
                    697:                return url;
                    698:        }
                    699: 
                    700:        void GraphicUserInterface::OpenHomepageLink (wxWindow *parent, const wxString &linkId, const wxString &extraVars)
                    701:        {
                    702:                wxString url;
                    703:                
                    704:                BeginInteractiveBusyState (parent);
                    705:                wxLaunchDefaultBrowser (GetHomepageLinkURL (linkId, extraVars), wxBROWSER_NEW_WINDOW);
                    706:                Thread::Sleep (200);
                    707:                EndInteractiveBusyState (parent);
                    708:        }
                    709: 
                    710:        void GraphicUserInterface::OpenOnlineHelp (wxWindow *parent)
                    711:        {
                    712:                OpenHomepageLink (parent, L"help");
                    713:        }
                    714: 
                    715:        void GraphicUserInterface::OpenUserGuide (wxWindow *parent)
                    716:        {
                    717:                try
                    718:                {
                    719:                        wxString docPath = wstring (Application::GetExecutableDirectory());
                    720: 
                    721: #ifdef TC_WINDOWS
                    722:                        docPath += L"\\TrueCrypt User Guide.pdf";
                    723: #elif defined (TC_MACOSX)
                    724:                        docPath += L"/../Resources/TrueCrypt User Guide.pdf";
                    725: #elif defined (TC_UNIX)
                    726:                        docPath = L"/usr/share/truecrypt/doc/TrueCrypt User Guide.pdf";
                    727: #endif
                    728: 
                    729:                        wxFileName docFile = docPath;
                    730:                        docFile.Normalize();
                    731:                        Gui->OpenDocument (parent, docFile);
                    732:                }
                    733:                catch (Exception &e)
                    734:                {
                    735:                        Gui->ShowError (e);
                    736:                }
                    737:        }
                    738: 
                    739:        DevicePath GraphicUserInterface::SelectDevice (wxWindow *parent) const
                    740:        {
                    741:                try
                    742:                {
                    743:                        DeviceSelectionDialog dialog (parent);
                    744:                        if (dialog.ShowModal() == wxID_OK)
                    745:                        {
                    746:                                return dialog.SelectedDevice.Path;
                    747:                        }
                    748:                }
                    749:                catch (exception &e)
                    750:                {
                    751:                        Gui->ShowError (e);
                    752:                }
                    753: 
                    754:                return DevicePath();
                    755:        }
                    756: 
                    757:        DirectoryPath GraphicUserInterface::SelectDirectory (wxWindow *parent, const wxString &message, bool existingOnly) const
                    758:        {
                    759:                return DirectoryPath (::wxDirSelector (!message.empty() ? message :
                    760: #ifdef __WXGTK__
                    761:                        wxDirSelectorPromptStr,
                    762: #else
                    763:                        L"",
                    764: #endif
                    765:                        L"", wxDD_DEFAULT_STYLE | (existingOnly ? wxDD_DIR_MUST_EXIST : 0), wxDefaultPosition, parent));
                    766:        }
                    767: 
                    768:        FilePathList GraphicUserInterface::SelectFiles (wxWindow *parent, const wxString &caption, bool saveMode, bool allowMultiple, const list < pair <wstring, wstring> > &fileExtensions, const DirectoryPath &directory) const
                    769:        {
                    770:                FilePathList files;
                    771: 
                    772:                long style;
                    773:                if (saveMode)
                    774:                        style = wxFD_SAVE | wxFD_OVERWRITE_PROMPT;
                    775:                else
                    776:                        style = wxFD_OPEN | wxFD_FILE_MUST_EXIST | (allowMultiple ? wxFD_MULTIPLE : 0);
                    777: 
                    778:                wxString wildcards = L"*.*";
                    779: 
                    780: #ifndef __WXGTK__
                    781:                if (!fileExtensions.empty())
                    782: #endif
                    783:                {
                    784:                        wildcards = LangString["ALL_FILES"] + 
                    785: #ifdef TC_WINDOWS
                    786:                                L" (*.*)|*.*";
                    787: #else
                    788:                                L"|*";
                    789: #endif
                    790:                        typedef pair <wstring, wstring> StringPair;
                    791:                        foreach (StringPair p, fileExtensions)
                    792:                        {
                    793:                                wildcards += wxString (L"|") + p.second + L" (*." + p.first + L")|*." + p.first;
                    794:                        }
                    795:                }
                    796: 
                    797:                wxFileDialog dialog (parent, caption, wstring (directory), wxString(), wildcards, style);
                    798: 
                    799:                if (dialog.ShowModal() == wxID_OK)
                    800:                {
                    801:                        if (!allowMultiple)
                    802:                                files.push_back (make_shared <FilePath> (dialog.GetPath()));
                    803:                        else
                    804:                        {
                    805:                                wxArrayString paths;
                    806:                                dialog.GetPaths (paths);
                    807: 
                    808:                                foreach (const wxString &path, paths)
                    809:                                        files.push_back (make_shared <FilePath> (path));
                    810:                        }
                    811:                }
                    812: 
                    813:                return files;
                    814:        }
                    815:        
                    816:        FilePath GraphicUserInterface::SelectVolumeFile (wxWindow *parent, bool saveMode, const DirectoryPath &directory) const
                    817:        {
                    818:                list < pair <wstring, wstring> > extensions;
                    819:                extensions.push_back (make_pair (L"tc", LangString["TC_VOLUMES"]));
                    820: 
                    821:                FilePathList selFiles = Gui->SelectFiles (parent, LangString[saveMode ? "OPEN_NEW_VOLUME" : "OPEN_VOL_TITLE"], saveMode, false, extensions, directory);
                    822: 
                    823:                if (!selFiles.empty())
                    824:                        return *selFiles.front();
                    825:                else
                    826:                        return FilePath();
                    827:        }
                    828: 
                    829:        void GraphicUserInterface::SetBackgroundMode (bool state)
                    830:        {
                    831: #ifdef TC_MACOSX
                    832:                // Hiding an iconized window on OS X apparently cannot be reversed
                    833:                if (state && mMainFrame->IsIconized())
                    834:                        mMainFrame->Iconize (false);
                    835: #endif
                    836:                mMainFrame->Show (!state);
                    837:                if (!state)
                    838:                {
                    839:                        if (mMainFrame->IsIconized())
                    840:                                mMainFrame->Iconize (false);
                    841: 
                    842:                        mMainFrame->Raise();
                    843:                }
                    844: 
                    845:                BackgroundMode = state;
                    846:        }
                    847: 
                    848:        void GraphicUserInterface::SetListCtrlColumnWidths (wxListCtrl *listCtrl, list <int> columnWidthPermilles, bool hasVerticalScrollbar) const
                    849:        {
                    850: #ifdef TC_MACOSX
                    851:                hasVerticalScrollbar = true;
                    852: #endif
                    853:                int listWidth = listCtrl->GetSize().GetWidth();
                    854:                int minListWidth = listCtrl->GetMinSize().GetWidth();
                    855:                if (minListWidth > listWidth)
                    856:                        listWidth = minListWidth;
                    857: 
                    858:                listWidth -= GetScrollbarWidth (listCtrl, !hasVerticalScrollbar);
                    859:                
                    860:                int col = 0;
                    861:                int totalColWidth = 0;
                    862:                foreach (int colWidth, columnWidthPermilles)
                    863:                {
                    864:                        int width = listWidth * colWidth / 1000;
                    865:                        totalColWidth += width;
                    866:                        
                    867:                        if (col == listCtrl->GetColumnCount() - 1)
                    868:                                width += listWidth - totalColWidth;
                    869: 
                    870:                        listCtrl->SetColumnWidth (col++, width);
                    871:                }
                    872:        }
                    873: 
                    874:        void GraphicUserInterface::SetListCtrlHeight (wxListCtrl *listCtrl, size_t rowCount) const
                    875:        {
                    876:                wxRect itemRect;
                    877:                if (listCtrl->GetItemCount() == 0)
                    878:                {
                    879:                        bool addedCols = false;
                    880:                        if (listCtrl->GetColumnCount() == 0)
                    881:                        {
                    882:                                listCtrl->InsertColumn (0, L".", wxLIST_FORMAT_LEFT, 1);
                    883:                                addedCols = true;
                    884:                        }
                    885:                        vector <wstring> f;
                    886:                        f.push_back (L".");
                    887:                        AppendToListCtrl (listCtrl, f);
                    888:                        listCtrl->GetItemRect (0, itemRect);
                    889: 
                    890:                        if (addedCols)
                    891:                                listCtrl->ClearAll();
                    892:                        else
                    893:                                listCtrl->DeleteAllItems();
                    894:                }
                    895:                else
                    896:                        listCtrl->GetItemRect (0, itemRect);
                    897: 
                    898:                int headerHeight = itemRect.y;
                    899: #ifdef TC_WINDOWS
                    900:                headerHeight += 4;
                    901: #elif defined (TC_MACOSX)
                    902:                headerHeight += 7;
                    903: #elif defined (__WXGTK__)
                    904:                headerHeight += 5;
                    905: #endif
                    906:                int rowHeight = itemRect.height;
                    907: #ifdef TC_MACOSX
                    908:                rowHeight += 1;
                    909: #endif
                    910:                listCtrl->SetMinSize (wxSize (listCtrl->GetMinSize().GetWidth(), rowHeight * rowCount + headerHeight));
                    911:        }
                    912: 
                    913:        void GraphicUserInterface::SetListCtrlWidth (wxListCtrl *listCtrl, size_t charCount, bool hasVerticalScrollbar) const
                    914:        {
                    915:                int width = GetCharWidth (listCtrl) * charCount;
                    916: #ifdef TC_MACOSX
                    917:                if (!hasVerticalScrollbar)
                    918:                        width += GetScrollbarWidth (listCtrl);
                    919: #endif
                    920:                listCtrl->SetMinSize (wxSize (width, listCtrl->GetMinSize().GetHeight()));
                    921:        }
                    922: 
                    923:        void GraphicUserInterface::ShowErrorTopMost (const wxString &message) const
                    924:        {
                    925:                ShowMessage (message, wxOK | wxICON_ERROR, true);
                    926:        }
                    927: 
                    928:        void GraphicUserInterface::ShowInfoTopMost (const wxString &message) const
                    929:        {
                    930:                ShowMessage (message, wxOK | wxICON_INFORMATION, true);
                    931:        }
                    932:        
                    933:        int GraphicUserInterface::ShowMessage (const wxString &message, long style, bool topMost) const
                    934:        {
                    935:                wxString caption = Application::GetName();
                    936:                wxString subMessage = message;
                    937: 
                    938: #ifdef TC_MACOSX
                    939:                size_t p = message.find (L"\n");
                    940:                if (p != string::npos)
                    941:                {
                    942:                        // Divide message to caption and info message
                    943:                        caption = message.substr (0, p);
                    944: 
                    945:                        p = message.find_first_not_of (L'\n', p);
                    946:                        if (p != string::npos)
                    947:                                subMessage = message.substr (p);
                    948:                        else
                    949:                                subMessage.clear();
                    950: 
                    951:                        if (subMessage.EndsWith (L"?"))
                    952:                        {
                    953:                                // Move question to caption
                    954:                                caption += wstring (L" ");
                    955:                                p = subMessage.find_last_of (L".\n");
                    956:                                if (p != string::npos)
                    957:                                {
                    958:                                        if (caption.EndsWith (L": "))
                    959:                                                caption[caption.size() - 2] = L'.';
                    960: 
                    961:                                        caption += subMessage.substr (subMessage.find_first_not_of (L"\n ", p + 1));
                    962:                                        subMessage = subMessage.substr (0, p + 1);
                    963:                                }
                    964:                                else
                    965:                                {
                    966:                                        caption += subMessage.substr (subMessage.find_first_not_of (L"\n"));
                    967:                                        subMessage.clear();
                    968:                                }
                    969:                        }
                    970:                }
                    971:                else if (message.size() < 160)
                    972:                {
                    973:                        caption = message;
                    974:                        subMessage.clear();
                    975:                }
                    976:                else
                    977:                {
                    978:                        if (style & wxICON_EXCLAMATION)
                    979:                                caption = wxString (_("Warning")) + L':';
                    980:                        else if (style & wxICON_ERROR || style & wxICON_HAND)
                    981:                                caption = wxString (_("Error")) + L':';
                    982:                        else
                    983:                                caption.clear();
                    984:                }
                    985: #endif
                    986:                if (topMost)
                    987:                {
                    988:                        if (!IsActive())
                    989:                                mMainFrame->RequestUserAttention (wxUSER_ATTENTION_ERROR);
                    990: 
                    991:                        style |= wxSTAY_ON_TOP;
                    992:                }
                    993: 
                    994:                return wxMessageBox (subMessage, caption, style, GetActiveWindow());
                    995:        }
                    996: 
                    997:        void GraphicUserInterface::ShowWarningTopMost (const wxString &message) const
                    998:        {
                    999:                ShowMessage (message, wxOK 
                   1000: #ifndef TC_MACOSX
                   1001:                        | wxICON_EXCLAMATION
                   1002: #endif
                   1003:                        , true);
                   1004:        }
                   1005: 
                   1006:        bool GraphicUserInterface::UpdateListCtrlItem (wxListCtrl *listCtrl, long itemIndex, const vector <wstring> &itemFields) const
                   1007:        {
                   1008:                bool changed = false;
                   1009:                wxListItem item;
                   1010:                item.SetId (itemIndex);
                   1011:                item.SetText (L"");
                   1012: 
                   1013:                int col = 0;
                   1014:                foreach (wxString field, itemFields)
                   1015:                {
                   1016:                        item.SetColumn (col++);
                   1017:                        
                   1018:                        if (!listCtrl->GetItem (item))
                   1019:                                throw ParameterIncorrect (SRC_POS);
                   1020: 
                   1021:                        if (item.GetText() != field)
                   1022:                        {
                   1023:                                item.SetText (field);
                   1024:                                listCtrl->SetItem (item);
                   1025:                                changed = true;
                   1026:                        }
                   1027:                }
                   1028:                return changed;
                   1029:        }
                   1030: 
                   1031:        void GraphicUserInterface::Yield () const
                   1032:        {
                   1033: #ifndef TC_WINDOWS
                   1034:                wxSafeYield (nullptr, true);
                   1035: #endif
                   1036:        }
                   1037: 
                   1038:        DEFINE_EVENT_TYPE (TC_EVENT_THREAD_EXITING);
                   1039: 
                   1040:        GraphicUserInterface *Gui = nullptr;
                   1041: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.