Annotation of truecrypt/main/forms/mainframe.cpp, revision 1.1.1.2

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 "System.h"
                     10: #include "Volume/EncryptionTest.h"
                     11: #include "Main/Main.h"
                     12: #include "Main/Resources.h"
                     13: #include "Main/Application.h"
                     14: #include "Main/GraphicUserInterface.h"
                     15: #include "Main/VolumeHistory.h"
                     16: #include "Main/Xml.h"
                     17: #include "MainFrame.h"
                     18: #include "AboutDialog.h"
                     19: #include "ChangePasswordDialog.h"
                     20: #include "FavoriteVolumesDialog.h"
                     21: #include "LegalNoticesDialog.h"
                     22: #include "PreferencesDialog.h"
1.1.1.2 ! root       23: #ifdef TC_WINDOWS
1.1       root       24: #include "TravelerDiskWizard.h"
1.1.1.2 ! root       25: #endif
1.1       root       26: #include "VolumeCreationWizard.h"
                     27: #include "VolumePropertiesDialog.h"
                     28: 
                     29: namespace TrueCrypt
                     30: {
                     31:        MainFrame::MainFrame (wxWindow* parent) : MainFrameBase (parent),
                     32:                SelectedItemIndex (-1),
                     33:                SelectedSlotNumber (0)
                     34:        {
                     35:                wxBusyCursor busy;
                     36: 
                     37:                SetName (Application::GetName());
                     38:                SetTitle (Application::GetName());
                     39:                SetIcon (Resources::GetTrueCryptIcon());
                     40: 
                     41:                InitControls();
                     42:                InitPreferences();
                     43:                InitTaskBarIcon();
                     44:                InitEvents();
                     45:                InitMessageFilter();
                     46:        }
                     47: 
                     48:        MainFrame::~MainFrame ()
                     49:        {
                     50:                Core->VolumeMountedEvent.Disconnect (this);
                     51:                Core->VolumeDismountedEvent.Disconnect (this);
                     52:                Gui->PreferencesUpdatedEvent.Disconnect (this);
                     53: 
                     54:                VolumeHistory::DisconnectComboBox (VolumePathComboBox);
                     55: 
                     56: #ifdef TC_WINDOWS
                     57:                Hotkey::UnregisterList (this, GetPreferences().Hotkeys);
                     58: #endif
                     59:        }
                     60: 
                     61:        void MainFrame::AddToFavorites (const VolumeInfoList &volumes)
                     62:        {
                     63:                FavoriteVolumeList newFavorites;
                     64: 
                     65:                // Delete duplicates
                     66:                foreach (shared_ptr <FavoriteVolume> favorite, FavoriteVolume::LoadList())
                     67:                {
                     68:                        bool mounted = false;
                     69:                        foreach_ref (const VolumeInfo &volume, volumes)
                     70:                        {
                     71:                                if (volume.Path == favorite->Path)
                     72:                                {
                     73:                                        mounted = true;
                     74:                                        break;
                     75:                                }
                     76:                        }
                     77:                        if (!mounted)
                     78:                                newFavorites.push_back (favorite);
                     79:                }
                     80: 
                     81:                size_t newItemCount = 0;
                     82:                foreach_ref (const VolumeInfo &volume, volumes)
                     83:                {
                     84:                        newFavorites.push_back (shared_ptr <FavoriteVolume> (new FavoriteVolume (volume.Path, volume.MountPoint, volume.SlotNumber)));
                     85:                        ++newItemCount;
                     86:                }
                     87: 
                     88:                OrganizeFavorites (newFavorites, newItemCount);
                     89:        }
                     90: 
                     91:        bool MainFrame::CanExit () const
                     92:        {
                     93:                return Gui->IsTheOnlyTopLevelWindow (this);
                     94:        }
                     95: 
                     96:        void MainFrame::ChangePassword (ChangePasswordDialog::Mode::Enum mode)
                     97:        {
                     98:                if (!CheckVolumePathNotEmpty ())
                     99:                        return;
                    100: 
                    101:                shared_ptr <VolumePath> volumePath = GetSelectedVolumePath();
                    102: 
                    103:                if (Core->IsVolumeMounted (*volumePath))
                    104:                {
                    105:                        Gui->ShowInfo (LangString [mode == ChangePasswordDialog::Mode::ChangePkcs5Prf ? "MOUNTED_NO_PKCS5_PRF_CHANGE" : "MOUNTED_NOPWCHANGE"]);
                    106:                        return;
                    107:                }
                    108: 
                    109:                ChangePasswordDialog dialog (this, volumePath, mode);
                    110:                dialog.ShowModal();
                    111:        }
                    112: 
                    113:        void MainFrame::CheckFilesystem (bool repair)
                    114:        {
                    115:                shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume();
                    116:                if (selectedVolume)
                    117:                {
                    118:                        try
                    119:                        {
                    120: #ifdef TC_WINDOWS
                    121:                                string mountPoint = selectedVolume->MountPoint;
                    122: 
                    123:                                wstring args = StringFormatter (repair ? L"/C echo {0} & chkdsk {1} /F /X & pause" : L"/C echo {0} & chkdsk {1} & pause",
                    124:                                        StringFormatter (LangString[repair ? "REPAIRING_FS" : "CHECKING_FS"], mountPoint), mountPoint);
                    125: 
                    126:                                ShellExecute (static_cast <HWND> (GetHandle()), 
                    127:                                        L"runas",
                    128:                                        L"cmd.exe", args.c_str(), nullptr, SW_SHOW);
                    129: #else
                    130:                                Core->CheckFilesystem (selectedVolume, repair);
                    131:                                UpdateVolumeList();
                    132: #endif
                    133:                        }
                    134:                        catch (exception &e)
                    135:                        {
                    136:                                Gui->ShowError (e);
                    137:                        }
                    138:                }
                    139:        }
                    140: 
                    141:        bool MainFrame::CheckVolumePathNotEmpty () const
                    142:        {
                    143:                if (VolumePathComboBox->GetValue().empty())
                    144:                {
                    145:                        Gui->ShowInfo ("NO_VOLUME_SELECTED");
                    146:                        return false;
                    147:                }
                    148:                return true;
                    149:        }
                    150: 
                    151:        void MainFrame::DismountVolume (shared_ptr <VolumeInfo> volume)
                    152:        {
                    153:                try
                    154:                {
                    155:                        if (!volume)
                    156:                                volume = GetSelectedVolume();
                    157: 
                    158:                        if (volume)
                    159:                                Gui->DismountVolume (volume);
                    160:                }
                    161:                catch (exception &e)
                    162:                {
                    163:                        Gui->ShowError (e);
                    164:                }
                    165:        }
                    166: 
                    167:        shared_ptr <VolumeInfo> MainFrame::GetSelectedVolume () const
                    168:        {
                    169:                return Core->GetMountedVolume (SelectedSlotNumber);
                    170:        }
                    171: 
                    172:        void MainFrame::InitControls ()
                    173:        {
                    174:                LogoBitmap->SetBitmap (Resources::GetLogoBitmap());
                    175:                
                    176:                list <int> colPermilles;
                    177: 
                    178: #ifndef TC_WINDOWS
                    179:                SettingsMenu->Remove (HotkeysMenuItem);
                    180:                ToolsMenu->Remove (TravelerDiskWizardMenuItem);
                    181: #endif
                    182: 
                    183: #ifdef TC_MACOSX
                    184:                SettingsMenu->Remove (PreferencesMenuItem);
                    185:                SettingsMenu->AppendSeparator();
                    186:                SettingsMenu->Append (PreferencesMenuItem);
                    187: 
                    188:                LowStaticBoxSizer->Detach (HigherButtonSizer);
                    189:                VolumeStaticBoxSizer->Detach (VolumeGridBagSizer);
                    190:                VolumeStaticBoxSizer->Add (VolumeGridBagSizer, 1, wxEXPAND, 0);
                    191: 
                    192:                ExitButton->SetLabel (_("Close"));
                    193:                MountAllDevicesButton->SetLabel (_("Mount All Devices"));
                    194: #endif
                    195: 
                    196: #ifdef TC_WINDOWS               
                    197:                SlotListCtrl->InsertColumn (ColumnSlot, LangString["DRIVE"], wxLIST_FORMAT_LEFT, 1);
                    198:                colPermilles.push_back (75);
                    199: #else
                    200:                SlotListCtrl->InsertColumn (ColumnSlot, _("Slot"), wxLIST_FORMAT_LEFT, 1);
                    201:                colPermilles.push_back (81);
                    202: #endif
                    203: 
                    204:                SlotListCtrl->InsertColumn (ColumnPath, LangString["VOLUME"], wxLIST_FORMAT_LEFT, 1);
                    205: #ifdef TC_WINDOWS               
                    206:                colPermilles.push_back (487);
                    207: #else
                    208:                colPermilles.push_back (430);
                    209: #endif
                    210: 
                    211:                SlotListCtrl->InsertColumn (ColumnSize, LangString["SIZE"], wxLIST_FORMAT_RIGHT, 1);
                    212: #ifdef TC_WINDOWS               
                    213:                colPermilles.push_back (126);
                    214: #else
                    215:                colPermilles.push_back (130);
                    216: #endif
                    217: 
                    218: #ifdef TC_WINDOWS               
                    219:                SlotListCtrl->InsertColumn (ColumnEA, LangString["ENCRYPTION_ALGORITHM_LV"], wxLIST_FORMAT_LEFT, 1);
                    220:                colPermilles.push_back (233);
                    221: #else
                    222:                SlotListCtrl->InsertColumn (ColumnMountPoint, LangString["MOUNT_POINT"], wxLIST_FORMAT_LEFT, 1);
                    223:                colPermilles.push_back (259);
                    224: #endif
                    225: 
                    226:                SlotListCtrl->InsertColumn (ColumnType, LangString["TYPE"], wxLIST_FORMAT_LEFT, 1);
                    227:                colPermilles.push_back (100);
                    228: 
                    229:                wxImageList *imageList = new wxImageList (16, 12, true);
                    230:                imageList->Add (Resources::GetDriveIconBitmap(), Resources::GetDriveIconMaskBitmap());
                    231:                SlotListCtrl->AssignImageList (imageList, wxIMAGE_LIST_SMALL);
                    232: 
                    233:                SetMinSize (wxSize (-1, -1));
                    234:                Gui->SetListCtrlHeight (SlotListCtrl, 12);
                    235: 
                    236: #ifdef __WXGTK__
                    237:                if (CreateVolumeButton->GetSize().GetHeight() > 26)
                    238:                {
                    239:                        wxSize size (-1, (int) ((double) Gui->GetCharHeight (this) * 1.53));
                    240:                        CreateVolumeButton->SetMinSize (size);
                    241:                        VolumePropertiesButton->SetMinSize (size);
                    242:                        WipeCacheButton->SetMinSize (size);
                    243:                        VolumePathComboBox->SetMinSize (size);
                    244:                        SelectFileButton->SetMinSize (size);
                    245:                        SelectDeviceButton->SetMinSize (size);
                    246:                        VolumeToolsButton->SetMinSize (size);
                    247:                        size = wxSize (-1, 38);
                    248:                        VolumeButton->SetMinSize (size);
                    249:                }
                    250: #endif
                    251:                Fit();
                    252:                Layout();
                    253:                Center();
                    254: 
                    255:                VolumePathComboBox->SetMinSize (VolumePathComboBox->GetSize());
                    256:                VolumePathComboBox->SetMaxSize (VolumePathComboBox->GetSize());
                    257: 
                    258:                SetMinSize (GetSize());
                    259:                SetMaxSize (GetSize());
                    260: 
                    261:                Gui->SetListCtrlColumnWidths (SlotListCtrl, colPermilles);
                    262:                
                    263:                UpdateVolumeList();
                    264:                UpdateWipeCacheButton();
                    265:        }
                    266: 
                    267:        void MainFrame::InitEvents ()
                    268:        {
                    269:                Core->VolumeMountedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnVolumeMounted));
                    270:                Core->VolumeDismountedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnVolumeDismounted));
                    271:                Gui->PreferencesUpdatedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnPreferencesUpdated));
                    272: 
                    273:                // Drag & drop
                    274:                class FileDropTarget : public wxFileDropTarget
                    275:                {
                    276:                public:
                    277:                        FileDropTarget (MainFrame *frame) : Frame (frame) { }
                    278: 
                    279:                        wxDragResult OnDragOver (wxCoord x, wxCoord y, wxDragResult def)
                    280:                        {
                    281:                                wxPoint p;
                    282:                                wxWindow *w = wxFindWindowAtPointer (p);
                    283:                                if (w == Frame || wxGetTopLevelParent (w) == Frame)
                    284:                                        return wxDragLink;
                    285:                                return wxDragNone;
                    286:                        }
                    287: 
                    288:                        bool OnDropFiles (wxCoord x, wxCoord y, const wxArrayString &filenames)
                    289:                        {
                    290:                                if (!filenames.empty())
                    291:                                        Frame->SetVolumePath (wstring (filenames.front()));
                    292:                                return true;
                    293:                        }
                    294: 
                    295:                        MainFrame *Frame;
                    296:                };
                    297: 
                    298:                SetDropTarget (new FileDropTarget (this));
                    299: #ifdef TC_MACOSX
                    300:                foreach (wxWindow *c, MainPanel->GetChildren())
                    301:                        c->SetDropTarget (new FileDropTarget (this));
                    302: #endif
                    303: 
                    304:                // Volume history
                    305:                VolumeHistory::ConnectComboBox (VolumePathComboBox);
                    306: 
                    307: #ifdef TC_WINDOWS
                    308:                // Hotkeys
                    309:                Hotkey::RegisterList (this, GetPreferences().Hotkeys);
                    310:                Connect (wxEVT_HOTKEY, wxKeyEventHandler (MainFrame::OnHotkey));
                    311: #endif
                    312: 
                    313:                // Timer
                    314:                class Timer : public wxTimer
                    315:                {
                    316:                public:
                    317:                        Timer (MainFrame *frame) : Frame (frame) { }
                    318: 
                    319:                        void Notify()
                    320:                        {
                    321:                                Frame->OnTimer();
                    322:                        }
                    323: 
                    324:                        MainFrame *Frame;
                    325:                };
                    326: 
                    327:                mTimer.reset (dynamic_cast <wxTimer *> (new Timer (this)));
                    328:                mTimer->Start (1000);
                    329:        }
                    330: 
                    331: #ifdef TC_WINDOWS
                    332: #include <dbt.h>
                    333:        static WNDPROC MainFrameWndProc;
                    334:        static LRESULT CALLBACK MainFrameWndProcFilter (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                    335:        {
                    336:                if (message == WM_DEVICECHANGE && !Core->IsDeviceChangeInProgress())
                    337:                {
                    338:                        MainFrame *frame = dynamic_cast <MainFrame *> (Gui->GetMainFrame());
                    339:                        PDEV_BROADCAST_HDR hdr = (PDEV_BROADCAST_HDR) lParam;
                    340:                        
                    341:                        if (wParam == DBT_DEVICEREMOVECOMPLETE && hdr->dbch_devicetype == DBT_DEVTYP_VOLUME)
                    342:                        {
                    343:                                PDEV_BROADCAST_VOLUME vol = (PDEV_BROADCAST_VOLUME) lParam;
                    344:                                for (wchar_t driveNo = 0; driveNo < 26; ++driveNo)
                    345:                                {
                    346:                                        if (vol->dbcv_unitmask & (1 << driveNo))
                    347:                                                frame->OnDeviceChange (wstring (StringFormatter (L"{0}:\\", wchar_t (L'A' + driveNo))));
                    348:                                }
                    349:                        }
                    350:                        else
                    351:                        {
                    352:                                frame->OnDeviceChange ();
                    353:                        }
                    354:                }
                    355: 
                    356:                return CallWindowProc (MainFrameWndProc, hwnd, message, wParam, lParam);
                    357:        }
                    358: #endif
                    359: 
                    360:        void MainFrame::InitMessageFilter ()
                    361:        {
                    362: #ifdef TC_WINDOWS
                    363:                HWND mainFrameHwnd = static_cast <HWND> (GetHandle());
                    364:                MainFrameWndProc = (WNDPROC) GetWindowLongPtr (mainFrameHwnd, GWL_WNDPROC);
                    365:                SetWindowLongPtr (mainFrameHwnd, GWL_WNDPROC, (LONG_PTR) MainFrameWndProcFilter);
                    366: #endif
                    367:        }
                    368: 
                    369:        void MainFrame::InitPreferences ()
                    370:        {
                    371:                try
                    372:                {
                    373:                        LoadPreferences();
                    374: 
                    375:                        VolumeSlotNumber lastSelectedSlotNumber = GetPreferences().LastSelectedSlotNumber;
                    376:                        if (Core->IsSlotNumberValid (lastSelectedSlotNumber))
                    377:                        {
                    378:                                long slotIndex = SlotNumberToItemIndex (lastSelectedSlotNumber);
                    379:                                if (slotIndex >= 0)
                    380:                                {
                    381:                                        SlotListCtrl->SetItemState (slotIndex, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
                    382:                                        SlotListCtrl->EnsureVisible (slotIndex);
                    383:                                }
                    384:                        }
                    385: 
                    386:                        LoadFavoriteVolumes();
                    387:                        VolumeHistory::Load();
                    388:                }
                    389:                catch (exception &e)
                    390:                {
                    391:                        Gui->ShowError (e);
                    392:                        Gui->ShowError (_("Error while loading configuration files located in ") + wstring (Application::GetConfigFilePath (L"")));
                    393:                }
                    394:        }
                    395: 
                    396:        void MainFrame::InitTaskBarIcon ()
                    397:        {
                    398:                class TaskBarIcon : public wxTaskBarIcon
                    399:                {
                    400:                public:
                    401:                        TaskBarIcon (MainFrame *frame) : Busy (false), Frame (frame)
                    402:                        {
                    403:                                Connect (wxEVT_TASKBAR_LEFT_DOWN, wxTaskBarIconEventHandler (TaskBarIcon::OnLeftButtonDown));
                    404:                        }
                    405: 
                    406:                        wxMenu *CreatePopupMenu ()
                    407:                        { 
                    408:                                auto_ptr <wxMenu> popup (new wxMenu);
                    409: 
                    410:                                Gui->AppendToMenu (*popup, LangString[Gui->IsInBackgroundMode() ? "SHOW_TC" : "HIDE_TC"], this, wxCommandEventHandler (TaskBarIcon::OnShowHideMenuItemSelected));
                    411:                                
                    412:                                popup->AppendSeparator();
                    413:                                Gui->AppendToMenu (*popup, _("Mount All Favorite Volumes"), this, wxCommandEventHandler (TaskBarIcon::OnMountAllFavoritesMenuItemSelected))->Enable (!Busy);
                    414:                                Gui->AppendToMenu (*popup, _("Dismount All Mounted Volumes"), this, wxCommandEventHandler (TaskBarIcon::OnDismountAllMenuItemSelected))->Enable (!Busy);
                    415:                                
                    416:                                // Favorite volumes
                    417:                                if (Gui->GetPreferences().BackgroundTaskMenuMountItemsEnabled && !Frame->FavoriteVolumesMenuMap.empty())
                    418:                                {
                    419:                                        popup->AppendSeparator();
                    420:                                        typedef pair <int, FavoriteVolume> FavMapPair;
                    421:                                        foreach (FavMapPair fp, Frame->FavoriteVolumesMenuMap)
                    422:                                        {
                    423:                                                Gui->AppendToMenu (*popup, LangString["MOUNT"] + L" " + wstring (fp.second.Path) + (fp.second.MountPoint.IsEmpty() ? L"" : L"  " + wstring (fp.second.MountPoint)),
                    424:                                                        this, wxCommandEventHandler (TaskBarIcon::OnFavoriteVolumeMenuItemSelected), fp.first)->Enable (!Busy);
                    425:                                        }
                    426:                                }
                    427: 
                    428:                                // Mounted volumes
                    429:                                VolumeInfoList mountedVolumes = Core->GetMountedVolumes();
                    430:                                if (!mountedVolumes.empty())
                    431:                                {
                    432:                                        if (Gui->GetPreferences().BackgroundTaskMenuOpenItemsEnabled)
                    433:                                        {
                    434:                                                popup->AppendSeparator();
                    435:                                                OpenMap.clear();
                    436:                                                foreach (shared_ptr <VolumeInfo> volume, mountedVolumes)
                    437:                                                {
                    438:                                                        if (!volume->MountPoint.IsEmpty())
                    439:                                                        {
                    440:                                                                wxString label = LangString["OPEN"] + L" " + wstring (volume->MountPoint) + L" (" + wstring (volume->Path) + L")";
                    441:                                                                wxMenuItem *item = Gui->AppendToMenu (*popup, label, this, wxCommandEventHandler (TaskBarIcon::OnOpenMenuItemSelected));
                    442:                                                                OpenMap[item->GetId()] = volume;
                    443:                                                        }
                    444:                                                }
                    445:                                        }
                    446: 
                    447:                                        if (Gui->GetPreferences().BackgroundTaskMenuDismountItemsEnabled)
                    448:                                        {
                    449:                                                popup->AppendSeparator();
                    450:                                                DismountMap.clear();
                    451:                                                foreach (shared_ptr <VolumeInfo> volume, mountedVolumes)
                    452:                                                {
                    453:                                                        wxString label = LangString["DISMOUNT"] + L" ";
                    454: 
                    455:                                                        if (!volume->MountPoint.IsEmpty())
                    456:                                                                label += wstring (volume->MountPoint) + L" (" + wstring (volume->Path) + L")";
                    457:                                                        else
                    458:                                                                label += wstring (volume->Path);
                    459: 
                    460:                                                        wxMenuItem *item = Gui->AppendToMenu (*popup, label, this, wxCommandEventHandler (TaskBarIcon::OnDismountMenuItemSelected));
                    461:                                                        item->Enable (!Busy);
                    462:                                                        DismountMap[item->GetId()] = volume;
                    463:                                                }
                    464:                                        }
                    465:                                }
                    466: 
                    467:                                popup->AppendSeparator();
                    468:                                Gui->AppendToMenu (*popup, _("Preferences..."), this, wxCommandEventHandler (TaskBarIcon::OnPreferencesMenuItemSelected))->Enable (!Busy);
                    469: #ifndef TC_MACOSX
                    470:                                popup->AppendSeparator();
                    471:                                Gui->AppendToMenu (*popup, _("Exit"), this, wxCommandEventHandler (TaskBarIcon::OnExitMenuItemSelected))->Enable (!Busy && Frame->CanExit());
                    472: #endif
                    473:                                return popup.release();
                    474:                        }
                    475: 
                    476:                        void OnDismountAllMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnDismountAllButtonClick (event); Busy = false; }
                    477:                        void OnDismountMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->DismountVolume (DismountMap[event.GetId()]); Busy = false; }
                    478:                        void OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnFavoriteVolumeMenuItemSelected (event); Busy = false; }
                    479:                        void OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->MountAllFavorites (); Busy = false; }
                    480: 
                    481:                        void OnExitMenuItemSelected (wxCommandEvent& event)
                    482:                        {
                    483:                                Busy = true;
                    484:                                if (Core->GetMountedVolumes().empty() || Gui->AskYesNo (LangString ["CONFIRM_EXIT"], false, true))
                    485:                                        Frame->Close (true);
                    486:                                Busy = false;
                    487:                        }
                    488: 
                    489:                        void OnLeftButtonDown (wxTaskBarIconEvent& event) { Gui->SetBackgroundMode (false); }
                    490:                        void OnOpenMenuItemSelected (wxCommandEvent& event) { Gui->OpenExplorerWindow (OpenMap[event.GetId()]->MountPoint); }
                    491:                        void OnPreferencesMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnPreferencesMenuItemSelected (event); Busy = false; }
                    492:                        void OnShowHideMenuItemSelected (wxCommandEvent& event) { Gui->SetBackgroundMode (!Gui->IsInBackgroundMode()); }
                    493: 
                    494:                        bool Busy;
                    495:                        map < int, shared_ptr <VolumeInfo> > DismountMap;
                    496:                        MainFrame *Frame;
                    497:                        map < int, shared_ptr <VolumeInfo> > OpenMap;
                    498:                };
                    499: 
                    500:                mTaskBarIcon.reset (new TaskBarIcon (this));
                    501:                ShowTaskBarIcon (GetPreferences().BackgroundTaskEnabled);
                    502:        }
                    503: 
                    504:        void MainFrame::LoadFavoriteVolumes ()
                    505:        {
                    506:                typedef pair <int, FavoriteVolume> FavMapPair;
                    507:                foreach (FavMapPair p, FavoriteVolumesMenuMap)
                    508:                {
                    509:                        FavoritesMenu->Delete (p.first);
                    510:                }
                    511:                FavoriteVolumesMenuMap.clear();
                    512: 
                    513:                foreach_ref (const FavoriteVolume &favorite, FavoriteVolume::LoadList())
                    514:                {
                    515:                        wstring label = wstring (favorite.Path);
                    516:                        if (!favorite.MountPoint.IsEmpty())
                    517:                                label += wstring (L"   ") + wstring (favorite.MountPoint);
                    518: 
                    519:                        wxMenuItem *item = Gui->AppendToMenu (*FavoritesMenu, label, this, wxCommandEventHandler (MainFrame::OnFavoriteVolumeMenuItemSelected));
                    520:                        FavoriteVolumesMenuMap[item->GetId()] = favorite;
                    521:                }
                    522:        }
                    523: 
                    524:        void MainFrame::LoadPreferences ()
                    525:        {
                    526:                UserPreferences prefs;
                    527:                prefs.Load();
                    528:                Gui->SetPreferences (prefs);
                    529:                NoHistoryCheckBox->SetValue (!prefs.SaveHistory);
                    530:        }
                    531:        
                    532:        void MainFrame::MountAllDevices ()
                    533:        {
                    534:                try
                    535:                {
                    536:                        MountOptions mountOptions (GetPreferences().DefaultMountOptions);
                    537: 
                    538:                        if (SlotListCtrl->GetSelectedItemCount() == 1)
                    539:                                mountOptions.SlotNumber = SelectedSlotNumber;
                    540: 
                    541:                        Gui->MountAllDeviceHostedVolumes (mountOptions);
                    542:                }
                    543:                catch (exception &e)
                    544:                {
                    545:                        Gui->ShowError (e);
                    546:                }
                    547:        }
                    548:        
                    549:        void MainFrame::MountAllFavorites ()
                    550:        {
                    551:                MountOptions mountOptions (GetPreferences().DefaultMountOptions);
                    552:                Gui->MountAllFavoriteVolumes (mountOptions);
                    553:        }
                    554: 
                    555:        void MainFrame::MountVolume ()
                    556:        {
                    557:                if (!IsFreeSlotSelected())
                    558:                {
                    559:                        Gui->ShowWarning (_("Please select a free drive slot from the list."));
                    560:                        return;
                    561:                }
                    562: 
                    563:                if (!CheckVolumePathNotEmpty())
                    564:                        return;
                    565: 
                    566:                MountOptions mountOptions (GetPreferences().DefaultMountOptions);
                    567:                mountOptions.SlotNumber = SelectedSlotNumber;
                    568:                mountOptions.Path = GetSelectedVolumePath();
                    569: 
                    570:                try
                    571:                {
                    572:                        if (Gui->MountVolume (mountOptions) && GetPreferences().SaveHistory)
                    573:                                VolumeHistory::Add (*mountOptions.Path);
                    574:                }
                    575:                catch (exception &e)
                    576:                {
                    577:                        Gui->ShowError (e);
                    578:                }
                    579:        }
                    580: 
                    581:        void MainFrame::OnAboutMenuItemSelected (wxCommandEvent& event)
                    582:        {
                    583:                AboutDialog dialog (this);
                    584:                dialog.ShowModal();
                    585:        }
                    586: 
                    587:        void MainFrame::OnActivate (wxActivateEvent& event)
                    588:        {
                    589: #ifdef TC_MACOSX
                    590:                if (event.GetActive() && Gui->IsInBackgroundMode())
                    591:                        Gui->SetBackgroundMode (false);
                    592: #endif
                    593:                event.Skip();
                    594:        }
                    595: 
                    596:        void MainFrame::OnAddAllMountedToFavoritesMenuItemSelected (wxCommandEvent& event)
                    597:        {
                    598:                AddToFavorites (MountedVolumes);
                    599:        }
                    600: 
                    601:        void MainFrame::OnAddToFavoritesMenuItemSelected (wxCommandEvent& event)
                    602:        {
                    603:                shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume();
                    604:                if (selectedVolume)
                    605:                {
                    606:                        VolumeInfoList volumes;
                    607:                        volumes.push_back (selectedVolume);
                    608:                        AddToFavorites (volumes);
                    609:                }
                    610:        }
                    611: 
                    612:        void MainFrame::OnBackupVolumeHeadersMenuItemSelected (wxCommandEvent& event)
                    613:        {
                    614:                if (!CheckVolumePathNotEmpty ())
                    615:                        return;
                    616: 
                    617:                shared_ptr <VolumePath> volumePath = GetSelectedVolumePath();
                    618: 
                    619:                if (Core->IsVolumeMounted (*volumePath))
                    620:                {
                    621:                        Gui->ShowInfo ("DISMOUNT_FIRST");
                    622:                        return;
                    623:                }
                    624: 
                    625:                wxString confirmMsg = LangString["CONFIRM_VOL_HEADER_BAK"];
                    626:                confirmMsg.Replace (L"%hs", L"%s");
                    627: 
                    628:                if (!Gui->AskYesNo (wxString::Format (confirmMsg, wstring (*volumePath).c_str()), true))
                    629:                        return;
                    630: 
                    631:                FilePathList files = Gui->SelectFiles (this, wxEmptyString, true, false);
                    632:                if (files.empty())
                    633:                        return;
                    634: 
                    635:                try
                    636:                {
                    637:                        Core->BackupVolumeHeaders (*volumePath, *files.front());
                    638:                        Gui->ShowWarning ("VOL_HEADER_BACKED_UP");
                    639:                }
                    640:                catch (Exception &e)
                    641:                {
                    642:                        Gui->ShowError (e);
                    643:                }
                    644:        }
                    645: 
                    646:        void MainFrame::OnClearSlotSelectionMenuItemSelected (wxCommandEvent& event)
                    647:        {
                    648:                Gui->ClearListCtrlSelection (SlotListCtrl);
                    649:                UpdateControls();
                    650:        }
                    651: 
                    652:        void MainFrame::OnClose (wxCloseEvent& event)
                    653:        {
                    654:                if (GetPreferences().WipeCacheOnClose)
                    655:                        Core->WipePasswordCache();
                    656: 
                    657:                if (!Gui->IsTheOnlyTopLevelWindow (this))
                    658:                {
                    659:                        // Bring first frame to foreground
                    660:                        wxFrame *frame = nullptr;
                    661:                        foreach (wxWindow *window, wxTopLevelWindows)
                    662:                        {
                    663:                                if (window != this
                    664:                                        && dynamic_cast <wxFrame *> (window)
                    665:                                        && StringConverter::GetTypeName (typeid (*window)).find ("wxTaskBarIcon") == string::npos)
                    666:                                {
                    667:                                        frame = dynamic_cast <wxFrame *> (window);
                    668:                                        if (window->IsShown())
                    669:                                                break;
                    670:                                }
                    671:                        }
                    672: 
                    673:                        if (frame)
                    674:                        {
                    675:                                frame->Show();
                    676:                                if (frame->IsIconized())
                    677:                                        frame->Iconize(false);
                    678:                                frame->Raise();
                    679:                        }
                    680:                }
                    681:                else if (event.CanVeto() && GetPreferences().BackgroundTaskEnabled
                    682:                        && (!GetPreferences().CloseBackgroundTaskOnNoVolumes || !MountedVolumes.empty()))
                    683:                {
                    684:                        // Enter background mode
                    685:                        if (!Gui->IsInBackgroundMode())
                    686:                                Gui->SetBackgroundMode (true);
                    687:                }
                    688:                else
                    689:                {
                    690: #ifdef __WXGTK__
                    691:                        Show();
                    692: #endif
                    693:                        SavePreferences();
                    694: 
                    695:                        Destroy();
                    696:                }
                    697: 
                    698:                 // Cancel close - veto is not used to prevent aborting log off procedure on Windows
                    699:                return;
                    700:        }
                    701: 
                    702:        void MainFrame::OnCreateVolumeButtonClick (wxCommandEvent& event)
                    703:        {
                    704:                (new VolumeCreationWizard (nullptr))->Show();
                    705:        }
                    706: 
                    707:        void MainFrame::OnDefaultKeyfilesMenuItemSelected (wxCommandEvent& event)
                    708:        {
                    709:                PreferencesDialog dialog (this);
                    710:                dialog.SelectPage (dialog.DefaultKeyfilesPage);
                    711:                dialog.ShowModal();
                    712:        }
                    713:        
                    714:        void MainFrame::OnDeviceChange (const DirectoryPath &mountPoint)
                    715:        {
                    716:                // Check if any host device has been removed and force dismount of volumes accordingly
                    717:                VolumeInfoList removedVolumes;
                    718:                foreach (shared_ptr <VolumeInfo> volume, Core->GetMountedVolumes())
                    719:                {
                    720:                        // File-hosted volumes
                    721:                        if (!volume->Path.IsDevice() && !mountPoint.IsEmpty())
                    722:                        {
                    723:                                if (wxString (volume->Path).Upper().StartsWith (wstring (mountPoint).c_str()))
                    724:                                {
                    725:                                        removedVolumes.push_back (volume);
                    726:                                        continue;
                    727:                                }
                    728:                        }
                    729: 
                    730:                        // Device-hosted volumes
                    731:                        if (volume->Path.IsDevice() && !Core->IsDevicePresent (volume->Path))
                    732:                                removedVolumes.push_back (volume);
                    733:                }
                    734:                
                    735:                if (!removedVolumes.empty())
                    736:                        Gui->AutoDismountVolumes (removedVolumes, true);
                    737:        }
                    738: 
                    739:        void MainFrame::OnDismountAllButtonClick (wxCommandEvent& event)
                    740:        {
                    741:                Gui->DismountAllVolumes();
                    742:        }
                    743: 
                    744:        void MainFrame::OnEncryptionTestMenuItemSelected (wxCommandEvent& event)
                    745:        {
                    746:                try
                    747:                {
                    748:                        EncryptionTest::TestAll();
                    749:                        Gui->ShowInfo ("TESTS_PASSED");
                    750:                }
                    751:                catch (Exception &e)
                    752:                {
                    753:                        Gui->ShowError (e);
                    754:                        Gui->ShowError ("TESTS_FAILED");
                    755:                }
                    756:        }
                    757: 
                    758:        void MainFrame::OnExitButtonClick (wxCommandEvent& event)
                    759:        {
                    760:                Close();
                    761:        }
                    762: 
                    763:        void MainFrame::OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event)
                    764:        {
                    765:                FavoriteVolume favorite = FavoriteVolumesMenuMap[event.GetId()];
                    766:                if (!favorite.Path.IsEmpty())
                    767:                {
                    768:                        SetVolumePath (favorite.Path);
                    769: 
                    770:                        MountOptions mountOptions (GetPreferences().DefaultMountOptions);
                    771:                        favorite.ToMountOptions (mountOptions);
                    772: 
                    773:                        shared_ptr <VolumeInfo> volume = Gui->MountVolume (mountOptions);
                    774:                        if (volume)
                    775:                                SlotListCtrl->EnsureVisible (SlotNumberToItemIndex (volume->SlotNumber));
                    776:                }
                    777:        }
                    778: 
                    779:        void MainFrame::OnHiddenVolumeProtectionTriggered (shared_ptr <VolumeInfo> protectedVolume)
                    780:        {
                    781:                Gui->ShowWarningTopMost (StringFormatter (LangString["DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"], wstring (protectedVolume->Path)));
                    782:        }
                    783: 
                    784:        void MainFrame::OnHotkey (wxKeyEvent& event)
                    785:        {
                    786: #ifdef TC_WINDOWS
                    787:                switch (event.GetId())
                    788:                {
                    789:                case Hotkey::Id::DismountAll:
                    790:                        {
                    791:                                size_t mountedCount = Core->GetMountedVolumes().size();
                    792:                                Gui->DismountAllVolumes();
                    793:                                size_t newMountedCount = Core->GetMountedVolumes().size();
                    794: 
                    795:                                if (newMountedCount < mountedCount)
                    796:                                {
                    797:                                        if (newMountedCount == 0 && GetPreferences().DisplayMessageAfterHotkeyDismount)
                    798:                                                Gui->ShowInfo ("MOUNTED_VOLUMES_DISMOUNTED");
                    799:                                        else if (GetPreferences().BeepAfterHotkeyMountDismount)
                    800:                                                MessageBeep((UINT) -1);
                    801:                                }
                    802:                        }
                    803:                        break;
                    804: 
                    805:                case Hotkey::Id::ForceDismountAllWipeCache:
                    806:                case Hotkey::Id::ForceDismountAllWipeCacheExit:
                    807:                        {
                    808:                                bool mounted = !Core->GetMountedVolumes().empty();
                    809: 
                    810:                                WipeCache();
                    811:                                Gui->DismountAllVolumes (true, true);
                    812: 
                    813:                                if (mounted && GetPreferences().DisplayMessageAfterHotkeyDismount)
                    814:                                        Gui->ShowInfo ("VOLUMES_DISMOUNTED_CACHE_WIPED");
                    815:                                else if (mounted && GetPreferences().BeepAfterHotkeyMountDismount)
                    816:                                        MessageBeep((UINT) -1);
                    817: 
                    818:                                if (event.GetId() == Hotkey::Id::ForceDismountAllWipeCacheExit)
                    819:                                        Close (true);
                    820:                        }
                    821:                        break;
                    822: 
                    823:                case Hotkey::Id::MountAllDevices:
                    824:                case Hotkey::Id::MountAllFavorites:
                    825:                        {
                    826:                                size_t mountedCount = Core->GetMountedVolumes().size();
                    827:                                
                    828:                                if (event.GetId() == Hotkey::Id::MountAllDevices)
                    829:                                        MountAllDevices();
                    830:                                else
                    831:                                        MountAllFavorites();
                    832: 
                    833:                                if (Core->GetMountedVolumes().size() > mountedCount && GetPreferences().BeepAfterHotkeyMountDismount)
                    834:                                        MessageBeep((UINT) -1);
                    835:                        }
                    836:                        break;
                    837: 
                    838:                case Hotkey::Id::ShowHideApplication:
                    839:                        Gui->SetBackgroundMode (!Gui->IsInBackgroundMode());
                    840:                        break;
                    841: 
                    842:                case Hotkey::Id::WipeCache:
                    843:                        WipeCache();
                    844:                        Gui->ShowInfo ("WIPE_CACHE");
                    845:                        break;
                    846: 
                    847:                default:
                    848:                        assert (false);
                    849:                        break;
                    850:                }
                    851: #endif // TC_WINDOWS
                    852:        }
                    853: 
                    854:        void MainFrame::OnHotkeysMenuItemSelected (wxCommandEvent& event)
                    855:        {
                    856:                PreferencesDialog dialog (this);
                    857:                dialog.SelectPage (dialog.HotkeysPage);
                    858:                dialog.ShowModal();
                    859:        }
                    860: 
                    861:        void MainFrame::OnLegalNoticesMenuItemSelected (wxCommandEvent& event)
                    862:        {
                    863:                LegalNoticesDialog dialog (this);
                    864:                dialog.ShowModal();
                    865:        }
                    866: 
                    867:        void MainFrame::OnListChanged ()
                    868:        {
                    869:                OnListItemSelectionChanged();
                    870:                UpdateControls();
                    871:        }
                    872: 
                    873:        void MainFrame::OnListItemActivated (wxListEvent& event)
                    874:        {
                    875:                if (IsMountedSlotSelected())
                    876:                        OpenSelectedVolume();
                    877:                else
                    878:                        MountVolume();
                    879:        }
                    880: 
                    881:        void MainFrame::OnListItemDeleted (long itemIndex)
                    882:        {
                    883:                if (SelectedItemIndex > itemIndex)
                    884:                        --SelectedItemIndex;
                    885:        }
                    886:        
                    887:        void MainFrame::OnListItemDeselected (wxListEvent& event)
                    888:        {
                    889:                OnListItemSelectionChanged();
                    890:        }
                    891: 
                    892:        void MainFrame::OnListItemInserted (long itemIndex)
                    893:        {
                    894:                if (SelectedItemIndex >= itemIndex)
                    895:                        ++SelectedItemIndex;
                    896:        }
                    897: 
                    898:        void MainFrame::OnListItemRightClick (wxListEvent& event)
                    899:        {
                    900: #ifdef TC_MACOSX
                    901:                if (SelectedItemIndex != event.GetIndex())
                    902:                {
                    903:                        SelectedItemIndex = event.GetIndex();
                    904:                        OnListItemSelectionChanged();
                    905:                }
                    906: #endif
                    907:                wxMenu popup;
                    908:                if (IsMountedSlotSelected())
                    909:                {
                    910:                        Gui->AppendToMenu (popup, LangString["DISMOUNT"], this, wxCommandEventHandler (MainFrame::OnDismountVolumeMenuItemSelected));
                    911:                        Gui->AppendToMenu (popup, LangString["OPEN"], this, wxCommandEventHandler (MainFrame::OnOpenVolumeMenuItemSelected));
                    912:                        Gui->AppendToMenu (popup, _("Deselect"), this, wxCommandEventHandler (MainFrame::OnClearSlotSelectionMenuItemSelected));
                    913: 
                    914:                        popup.AppendSeparator();
                    915:                        Gui->AppendToMenu (popup, _("Add to Favorites..."), this, wxCommandEventHandler (MainFrame::OnAddToFavoritesMenuItemSelected));
                    916: 
                    917: #if defined (TC_WINDOWS) || defined (TC_LINUX)
                    918:                        popup.AppendSeparator();
                    919:                        Gui->AppendToMenu (popup, LangString["IDPM_CHECK_FILESYS"], this, wxCommandEventHandler (MainFrame::OnCheckFilesystemMenuItemSelected));
                    920:                        Gui->AppendToMenu (popup, LangString["IDPM_REPAIR_FILESYS"], this, wxCommandEventHandler (MainFrame::OnRepairFilesystemMenuItemSelected));
                    921: #endif
                    922:                        popup.AppendSeparator();
                    923:                        Gui->AppendToMenu (popup, LangString["IDPM_PROPERTIES"], this, wxCommandEventHandler (MainFrame::OnVolumePropertiesButtonClick));
                    924: 
                    925:                        PopupMenu (&popup);
                    926:                }
                    927:                else if (IsFreeSlotSelected())
                    928:                {
                    929:                        Gui->AppendToMenu (popup, _("Mount Volume"), this, wxCommandEventHandler (MainFrame::OnMountVolumeMenuItemSelected));
                    930:                        Gui->AppendToMenu (popup, _("Deselect"), this, wxCommandEventHandler (MainFrame::OnClearSlotSelectionMenuItemSelected));
                    931: 
                    932:                        PopupMenu (&popup);
                    933:                }
                    934: 
                    935:                event.Skip();
                    936:        }
                    937: 
                    938:        void MainFrame::OnListItemSelected (wxListEvent& event)
                    939:        {
                    940:                SelectedItemIndex = event.GetIndex();
                    941:                OnListItemSelectionChanged();
                    942:        }
                    943:                        
                    944:        void MainFrame::OnListItemSelectionChanged ()
                    945:        {
                    946:                if (SlotListCtrl->GetSelectedItemCount() < 1)
                    947:                        SelectedItemIndex = -1;
                    948:                
                    949:                if (SelectedItemIndex >= 0)
                    950:                        SelectedSlotNumber = (VolumeSlotNumber) SlotListCtrl->GetItemData (SelectedItemIndex);
                    951:                else
                    952:                        SelectedSlotNumber = 0;
                    953: 
                    954:                UpdateControls();
                    955:        }
                    956:                
                    957:        void MainFrame::OnMountAllDevicesButtonClick (wxCommandEvent& event)
                    958:        {
                    959:                MountAllDevices();
                    960:        }
                    961: 
                    962:        void MainFrame::OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event)
                    963:        {
                    964:                MountAllFavorites();
                    965:        }
                    966: 
                    967:        void MainFrame::OnNoHistoryCheckBoxClick (wxCommandEvent& event)
                    968:        {
                    969:                UserPreferences prefs = GetPreferences();
                    970:                prefs.SaveHistory = !event.IsChecked();
                    971:                Gui->SetPreferences (prefs);
                    972: 
                    973:                if (event.IsChecked())
                    974:                {
                    975:                        VolumeHistory::Clear();
                    976:                }
                    977:        }
                    978: 
                    979:        void MainFrame::OnOrganizeFavoritesMenuItemSelected (wxCommandEvent& event)
                    980:        {
                    981:                OrganizeFavorites (FavoriteVolume::LoadList());
                    982:        }
                    983: 
                    984:        void MainFrame::OnPreferencesMenuItemSelected (wxCommandEvent& event)
                    985:        {
                    986:                PreferencesDialog dialog (this);
                    987:                dialog.ShowModal();
                    988:        }
                    989: 
                    990:        void MainFrame::OnPreferencesUpdated (EventArgs &args)
                    991:        {
                    992:                const UserPreferences &prefs = GetPreferences();
                    993: 
                    994:                NoHistoryCheckBox->SetValue (!prefs.SaveHistory);
                    995: 
                    996:                ShowTaskBarIcon (prefs.BackgroundTaskEnabled);
                    997:                if (Gui->IsInBackgroundMode() && !prefs.BackgroundTaskEnabled)
                    998:                        Close (true);
                    999: 
                   1000:                prefs.Save();
                   1001:        }
                   1002:        
                   1003:        void MainFrame::OnRestoreVolumeHeaderMenuItemSelected (wxCommandEvent& event)
                   1004:        {
                   1005:                if (!CheckVolumePathNotEmpty ())
                   1006:                        return;
                   1007: 
                   1008:                shared_ptr <VolumePath> volumePath = GetSelectedVolumePath();
                   1009: 
                   1010:                if (Core->IsVolumeMounted (*volumePath))
                   1011:                {
                   1012:                        Gui->ShowInfo ("DISMOUNT_FIRST");
                   1013:                        return;
                   1014:                }
                   1015: 
                   1016:                wxString confirmMsg = LangString["CONFIRM_VOL_HEADER_RESTORE"];
                   1017:                confirmMsg.Replace (L"%hs", L"%s");
                   1018: 
                   1019:                if (!Gui->AskYesNo (wxString::Format (confirmMsg, wstring (*volumePath).c_str()), true, true))
                   1020:                        return;
                   1021: 
                   1022:                FilePathList files = Gui->SelectFiles (this, wxEmptyString, false, false);
                   1023:                if (files.empty())
                   1024:                        return;
                   1025: 
                   1026:                wxArrayString choices;
                   1027:                choices.Add (LangString["RESTORE_NORMAL_VOLUME_HEADER"]);
                   1028:                choices.Add (LangString["RESTORE_HIDDEN_VOLUME_HEADER"]);
                   1029: 
                   1030:                wxSingleChoiceDialog choiceDialog (this, LangString["HEADER_RESTORE_TYPE"], Application::GetName(), choices);
                   1031:                choiceDialog.SetSelection (-1);
                   1032:                
                   1033:                if (choiceDialog.ShowModal() != wxID_OK)
                   1034:                        return;
                   1035: 
                   1036:                VolumeType::Enum volumeType;
                   1037: 
                   1038:                switch (choiceDialog.GetSelection())
                   1039:                {
                   1040:                case 0:
                   1041:                        volumeType = VolumeType::Normal;
                   1042:                        break;
                   1043: 
                   1044:                case 1:
                   1045:                        volumeType = VolumeType::Hidden;
                   1046:                        break;
                   1047: 
                   1048:                default:
                   1049:                        return;
                   1050:                }
                   1051: 
                   1052:                try
                   1053:                {
                   1054:                        Core->RestoreVolumeHeaders (*volumePath, volumeType, *files.front());
                   1055:                        Gui->ShowInfo ("VOL_HEADER_RESTORED");
                   1056:                }
                   1057:                catch (Exception &e)
                   1058:                {
                   1059:                        Gui->ShowError (e);
                   1060:                }
                   1061:        }
                   1062: 
                   1063:        void MainFrame::OnSelectDeviceButtonClick (wxCommandEvent& event)
                   1064:        {
                   1065:                DevicePath path = Gui->SelectDevice (this);
                   1066: 
                   1067:                if (!path.IsEmpty())
                   1068:                        SetVolumePath (path);
                   1069:        }
                   1070: 
                   1071:        void MainFrame::OnSelectFileButtonClick (wxCommandEvent& event)
                   1072:        {
                   1073:                FilePath path = Gui->SelectVolumeFile (this);
                   1074:                if (!path.IsEmpty())
                   1075:                        SetVolumePath (path);
                   1076:        }
                   1077:        
                   1078:        void MainFrame::OnTimer ()
                   1079:        {
                   1080:                UpdateVolumeList();
                   1081:                UpdateWipeCacheButton();
                   1082: 
                   1083:                if (GetPreferences().BackgroundTaskEnabled)
                   1084:                {
                   1085:                        // Inactivity auto-dismount
                   1086:                        if (GetPreferences().DismountOnInactivity)
                   1087:                        {
                   1088:                                VolumeInfoList inactiveVolumes;
                   1089:                                wxLongLong currentTime = wxGetLocalTimeMillis().GetValue();
                   1090: 
                   1091:                                map <wstring, VolumeActivityMapEntry> newActivityTimeMap;
                   1092: 
                   1093:                                foreach (shared_ptr <VolumeInfo> volume, MountedVolumes)
                   1094:                                {
                   1095:                                        if (VolumeActivityMap.find (volume->Path) != VolumeActivityMap.end()
                   1096:                                                && VolumeActivityMap[volume->Path].SerialInstanceNumber == volume->SerialInstanceNumber)
                   1097:                                        {
                   1098:                                                VolumeActivityMapEntry ae = VolumeActivityMap[volume->Path];
                   1099: 
                   1100:                                                if (volume->TotalDataRead != ae.TotalDataRead || volume->TotalDataWritten != ae.TotalDataWritten)
                   1101:                                                {
                   1102:                                                        ae.LastActivityTime = currentTime;
                   1103:                                                        ae.TotalDataRead = volume->TotalDataRead;
                   1104:                                                        ae.TotalDataWritten = volume->TotalDataWritten;
                   1105:                                                }
                   1106:                                                else if ((currentTime - ae.LastActivityTime) > GetPreferences().MaxVolumeIdleTime * 1000LL * 60)
                   1107:                                                {
                   1108:                                                        inactiveVolumes.push_back (volume);
                   1109:                                                }
                   1110: 
                   1111:                                                newActivityTimeMap[volume->Path] = ae;
                   1112:                                        }
                   1113:                                        else
                   1114:                                        {
                   1115:                                                newActivityTimeMap[volume->Path] = VolumeActivityMapEntry (*volume, currentTime);
                   1116:                                        }
                   1117:                                }
                   1118: 
                   1119:                                VolumeActivityMap = newActivityTimeMap;
                   1120:                                
                   1121:                                if (!inactiveVolumes.empty())
                   1122:                                        Gui->AutoDismountVolumes (inactiveVolumes);
                   1123:                        }
                   1124: 
                   1125:                        // Screen saver auto-dismount
                   1126:                        if (GetPreferences().DismountOnScreenSaver)
                   1127:                        {
                   1128: #ifdef TC_WINDOWS
                   1129:                                bool running;
                   1130:                                if (SystemParametersInfo (SPI_GETSCREENSAVERRUNNING, 0, &running, 0) != 0)
                   1131:                                {
                   1132:                                        static bool previousState = false;
                   1133:                                        if (running && !previousState)
                   1134:                                        {
                   1135:                                                previousState = true;
                   1136:                                                Gui->OnAutoDismountAllEvent();
                   1137:                                        }
                   1138:                                        else
                   1139:                                        {
                   1140:                                                previousState = running;
                   1141:                                        }
                   1142:                                }
                   1143: #endif
                   1144:                        }
                   1145:                }
                   1146: 
                   1147:                if (Gui->IsInBackgroundMode())
                   1148:                {
                   1149:                        if (!GetPreferences().BackgroundTaskEnabled)
                   1150:                        {
                   1151:                                Close (true);
                   1152:                        }
                   1153:                        else if (MountedVolumes.empty() && (GetPreferences().CloseBackgroundTaskOnNoVolumes || Core->IsInTravelMode()))
                   1154:                        {
                   1155:                                Close (true);
                   1156:                        }
                   1157:                }
                   1158:        }
                   1159: 
                   1160:        void MainFrame::OnTravelerDiskWizardMenuItemSelected (wxCommandEvent& event)
                   1161:        {
                   1162: #ifdef TC_WINDOWS
                   1163:                (new TravelerDiskWizard (this))->Show();
                   1164: #endif
                   1165:        }
                   1166: 
                   1167:        void MainFrame::OnVolumeButtonClick (wxCommandEvent& event)
                   1168:        {
                   1169:                if (IsMountedSlotSelected())
                   1170:                        DismountVolume();
                   1171:                else
                   1172:                        MountVolume();
                   1173:        }
                   1174: 
                   1175:        void MainFrame::OnVolumePropertiesButtonClick (wxCommandEvent& event)
                   1176:        {
                   1177:                shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume();
                   1178:                if (selectedVolume)
                   1179:                {
                   1180:                        VolumePropertiesDialog dialog (this, *selectedVolume);
                   1181:                        dialog.ShowModal();
                   1182:                }
                   1183:        }
                   1184: 
                   1185:        void MainFrame::OnVolumeToolsButtonClick (wxCommandEvent& event)
                   1186:        {
                   1187:                if (!CheckVolumePathNotEmpty())
                   1188:                        return;
                   1189: 
                   1190:                wxMenu popup;
                   1191: 
                   1192:                Gui->AppendToMenu (popup, _("Change Volume Password..."), this, wxCommandEventHandler (MainFrame::OnChangePasswordMenuItemSelected));
                   1193: 
                   1194:                popup.AppendSeparator ();
                   1195: 
                   1196:                Gui->AppendToMenu (popup, _("Add/Remove Keyfiles to/from Volume..."), this, wxCommandEventHandler (MainFrame::OnChangeKeyfilesMenuItemSelected));
                   1197:                Gui->AppendToMenu (popup, _("Remove All Keyfiles from Volume..."), this, wxCommandEventHandler (MainFrame::OnRemoveKeyfilesMenuItemSelected));
                   1198: 
                   1199:                popup.AppendSeparator ();
                   1200: 
                   1201:                Gui->AppendToMenu (popup, _("Change Header Key Derivation Algorithm..."), this, wxCommandEventHandler (MainFrame::OnChangePkcs5PrfMenuItemSelected));
                   1202: 
                   1203:                popup.AppendSeparator ();
                   1204: 
                   1205:                Gui->AppendToMenu (popup, _("Backup Volume Header..."), this, wxCommandEventHandler (MainFrame::OnBackupVolumeHeadersMenuItemSelected));
                   1206:                Gui->AppendToMenu (popup, _("Restore Volume Header..."), this, wxCommandEventHandler (MainFrame::OnRestoreVolumeHeaderMenuItemSelected));
                   1207: 
                   1208:                PopupMenu (&popup, VolumeToolsButton->GetPosition().x + 2, VolumeToolsButton->GetPosition().y + 2);
                   1209:        }
                   1210: 
                   1211:        void MainFrame::OnWipeCacheButtonClick (wxCommandEvent& event)
                   1212:        {
                   1213:                WipeCache();
                   1214:                Gui->ShowInfo ("WIPE_CACHE");
                   1215:        }
                   1216:        
                   1217:        void MainFrame::OpenSelectedVolume () const
                   1218:        {
                   1219:                shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume();
                   1220:                if (selectedVolume)
                   1221:                {
                   1222:                        try
                   1223:                        {
                   1224:                                wxBusyCursor busy;
                   1225:                                Gui->OpenExplorerWindow (selectedVolume->MountPoint);
                   1226:                        }
                   1227:                        catch (exception &e)
                   1228:                        {
                   1229:                                Gui->ShowError (e);
                   1230:                        }
                   1231:                }
                   1232:        }
                   1233: 
                   1234:        void MainFrame::OrganizeFavorites (const FavoriteVolumeList &favorites, size_t newItemCount)
                   1235:        {
                   1236:                FavoriteVolumesDialog dialog (this, favorites, newItemCount);
                   1237: 
                   1238:                if (dialog.ShowModal() == wxID_OK)
                   1239:                {
                   1240:                        FavoriteVolume::SaveList (dialog.GetFavorites());
                   1241:                        LoadFavoriteVolumes();
                   1242:                }
                   1243:        }
                   1244: 
                   1245:        void MainFrame::SavePreferences () const
                   1246:        {
                   1247:                try
                   1248:                {
                   1249:                        UserPreferences prefs = GetPreferences();
                   1250:                        prefs.LastSelectedSlotNumber = SelectedSlotNumber;
                   1251:                        prefs.Save();
                   1252: 
                   1253:                        VolumeHistory::Save();
                   1254:                }
                   1255:                catch (exception &e)
                   1256:                {
                   1257:                        if (!Core->IsInTravelMode())
                   1258:                                Gui->ShowError (e);
                   1259:                }
                   1260:        }
                   1261: 
                   1262:        void MainFrame::ShowTaskBarIcon (bool show)
                   1263:        {
                   1264:                if (!show && mTaskBarIcon->IsIconInstalled())
                   1265:                {
                   1266:                        mTaskBarIcon->RemoveIcon();
                   1267:                }
                   1268:                else if (show && !mTaskBarIcon->IsIconInstalled())
                   1269:                {
                   1270: #ifndef TC_MACOSX
                   1271:                        mTaskBarIcon->SetIcon (Resources::GetTrueCryptIcon(), L"TrueCrypt");
                   1272: #endif
                   1273:                }
                   1274:        }
                   1275: 
                   1276:        long MainFrame::SlotNumberToItemIndex (uint32 slotNumber) const
                   1277:        {
                   1278:                for (long itemIndex = 0; itemIndex < SlotListCtrl->GetItemCount(); itemIndex++)
                   1279:                {
                   1280:                        wxListItem item;
                   1281:                        item.SetId (itemIndex);
                   1282:                        if (slotNumber == SlotListCtrl->GetItemData (item))
                   1283:                                return itemIndex;
                   1284:                }
                   1285:                return -1;
                   1286:        }
                   1287:        
                   1288:        void MainFrame::UpdateControls ()
                   1289:        {
                   1290:                bool mounted = IsMountedSlotSelected();
                   1291: 
                   1292:                VolumeButton->SetLabel (mounted ? LangString["DISMOUNT"] : wxString (_("Mount")));
                   1293:                VolumePropertiesButton->Enable (mounted);
                   1294: 
                   1295:                DismountVolumeMenuItem->Enable (mounted); 
                   1296:                MountVolumeMenuItem->Enable (!mounted);
                   1297:                VolumePropertiesMenuItem->Enable (mounted);
                   1298:                AddToFavoritesMenuItem->Enable (mounted);
                   1299:                AddAllMountedToFavoritesMenuItem->Enable (!MountedVolumes.empty());
                   1300:                UpdateWipeCacheButton();
                   1301:        }
                   1302: 
                   1303:        void MainFrame::UpdateVolumeList ()
                   1304:        {
                   1305:                static Mutex mutex;
                   1306:                ScopeLock lock (mutex);
                   1307: 
                   1308:                bool listChanged = false;
                   1309: 
                   1310:                MountedVolumes = Core->GetMountedVolumes();
                   1311:                
                   1312:                map < VolumeSlotNumber, shared_ptr <VolumeInfo> > mountedVolumesMap;
                   1313:                foreach (shared_ptr <VolumeInfo> volume, MountedVolumes)
                   1314:                {
                   1315:                        mountedVolumesMap[volume->SlotNumber] = volume;
                   1316:                }
                   1317: 
                   1318:                VolumeInfoList protectionTriggeredVolumes;
                   1319: 
                   1320:                // Update list
                   1321:                long prevItemIndex = -1;
                   1322:                for (VolumeSlotNumber slotNumber = Core->GetFirstSlotNumber(); slotNumber <= Core->GetLastSlotNumber(); ++slotNumber)
                   1323:                {
                   1324:                        long itemIndex = SlotNumberToItemIndex (slotNumber);
                   1325:                        vector <wstring> fields (SlotListCtrl->GetColumnCount());
                   1326: 
                   1327:                        if (mountedVolumesMap.find (slotNumber) != mountedVolumesMap.end())
                   1328:                        {
                   1329:                                shared_ptr <VolumeInfo> volume = mountedVolumesMap[slotNumber];
                   1330: 
                   1331: #ifdef TC_WINDOWS
                   1332:                                fields[ColumnSlot] = volume->MountPoint;
                   1333:                                fields[ColumnEA] = volume->EncryptionAlgorithmName;
                   1334: #else
                   1335:                                fields[ColumnSlot] = StringConverter::FromNumber (slotNumber);
                   1336:                                fields[ColumnMountPoint] = volume->MountPoint;
                   1337: #endif
                   1338:                                fields[ColumnPath] = volume->Path;
                   1339:                                fields[ColumnSize] = Gui->SizeToString (volume->Size);
                   1340:                                fields[ColumnType] = Gui->VolumeTypeToString (volume->Type, volume->Protection);
                   1341:                                
                   1342:                                if (volume->HiddenVolumeProtectionTriggered)
                   1343:                                {
                   1344:                                        fields[ColumnType] += L"(!)";
                   1345:                                }
                   1346: 
                   1347:                                bool slotUpdated = false;
                   1348:                                if (itemIndex == -1)
                   1349:                                {
                   1350:                                        Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *) volume->SlotNumber);
                   1351:                                        OnListItemInserted (prevItemIndex);
                   1352: 
                   1353:                                        listChanged |= true;
                   1354:                                        slotUpdated = true;
                   1355:                                }
                   1356:                                else
                   1357:                                {
                   1358:                                        if (Gui->UpdateListCtrlItem (SlotListCtrl, itemIndex, fields))
                   1359:                                        {
                   1360:                                                listChanged = true;
                   1361:                                                slotUpdated = true;
                   1362:                                        }
                   1363:                                        prevItemIndex = itemIndex;
                   1364:                                }
                   1365: 
                   1366:                                if (slotUpdated && volume->HiddenVolumeProtectionTriggered)
                   1367:                                        protectionTriggeredVolumes.push_back (volume);
                   1368:                        }
                   1369:                        else
                   1370:                        {
                   1371: #ifdef TC_WINDOWS
                   1372:                                fields[ColumnSlot] = Core->SlotNumberToMountPoint (slotNumber);
                   1373: #else
                   1374:                                fields[ColumnSlot] = StringConverter::FromNumber (slotNumber);
                   1375: #endif
                   1376:                                
                   1377: #ifdef TC_WINDOWS
                   1378:                                if (Core->IsMountPointAvailable (fields[ColumnSlot]))
                   1379: #else
                   1380:                                if (true)
                   1381: #endif
                   1382:                                {
                   1383:                                        if (itemIndex == -1)
                   1384:                                        {
                   1385:                                                Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *) slotNumber);
                   1386:                                                OnListItemInserted (prevItemIndex);
                   1387:                                                listChanged |= true;
                   1388:                                        }
                   1389:                                        else
                   1390:                                        {
                   1391:                                                listChanged |= Gui->UpdateListCtrlItem (SlotListCtrl, itemIndex, fields);
                   1392:                                                prevItemIndex = itemIndex;
                   1393:                                        }
                   1394:                                }
                   1395:                                else if (itemIndex != -1)
                   1396:                                {
                   1397:                                        SlotListCtrl->DeleteItem (itemIndex);
                   1398:                                        OnListItemDeleted (itemIndex);
                   1399:                                        listChanged = true;
                   1400:                                }
                   1401:                        }
                   1402:                }
                   1403: 
                   1404:                if (listChanged)
                   1405:                        OnListChanged();
                   1406: 
                   1407:                foreach (shared_ptr <VolumeInfo> volume, protectionTriggeredVolumes)
                   1408:                        OnHiddenVolumeProtectionTriggered (volume);
                   1409:        }
                   1410: 
                   1411:        void MainFrame::UpdateWipeCacheButton ()
                   1412:        {
                   1413:                bool enabled = WipeCacheButton->IsEnabled();
                   1414:                bool empty = Core->IsPasswordCacheEmpty();
                   1415: 
                   1416:                if (empty && enabled)
                   1417:                {
                   1418:                        WipeCacheButton->Disable();
                   1419:                        WipeCachedPasswordsMenuItem->Enable (false);
                   1420:                }
                   1421:                else if (!empty && !enabled)
                   1422:                {
                   1423:                        WipeCacheButton->Enable();
                   1424:                        WipeCachedPasswordsMenuItem->Enable();
                   1425:                }
                   1426:        }
                   1427: 
                   1428:        void MainFrame::WipeCache ()
                   1429:        {
                   1430:                Core->WipePasswordCache();
                   1431:                UpdateWipeCacheButton();
                   1432:        }
                   1433: }

unix.superglobalmegacorp.com

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