/*
This file is part of VVV (Virtual Volumes View)
Copyright (C) 2007, the VVV Development team
Author: Fulvio Senore
VVV is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
VVV is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with VVV; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/////////////////////////////////////////////////////////////////////////////
// Name: mainframe.cpp
// Purpose:
// Author:
// Modified by:
// Created: 29/12/2006 12:41:00
// RCS-ID:
// Copyright:
// Licence:
/////////////////////////////////////////////////////////////////////////////
// Generated by DialogBlocks (unregistered), 29/12/2006 12:41:00
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "mainframe.h"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
////@begin includes
#include "wx/mstream.h"
#include "catalog_volume.h"
#include "wx/imaglist.h"
////@end includes
#include "wx/textdlg.h"
#include "wx/filename.h"
#include "wx/config.h"
#include "wx/utils.h"
#include "wx/aboutdlg.h"
#include "wx/stdpaths.h"
#include "wx/textfile.h"
#include "wx/textdlg.h"
#include "wx/busyinfo.h"
#include "vvv.h"
#include "mainframe.h"
#include "data_interface/data_error.h"
#include "mytreeitemdata.h"
#include "mylistitemdata.h"
#include "object_description.h"
#include "settings.h"
#include "opencatalog.h"
#include "long_task_beep.h"
#include "exportdata.h"
#include "restore.h"
#include "update_volume.h"
#include "decode_search_string.h"
#include "dlg_file_information.h"
#include "audio_metadata.h"
////@begin XPM images
#include "graphics/vvv32.xpm"
#include "graphics/tlb_new.xpm"
#include "graphics/tlb_open.xpm"
#include "graphics/tlb_catalog.inc"
#include "graphics/tlb_up.xpm"
#include "graphics/tlb_physical.xpm"
#include "graphics/tlb_virtual.xpm"
#include "graphics/tlb_search.xpm"
////@end XPM images
#include "graphics/folder_closed.xpm"
#include "graphics/folder_opened.xpm"
#include "graphics/removable.xpm"
#include "graphics/deffile.xpm"
// column used to sort the listview: it is the number that the column would have if no columns were hidden
// columns that are not visible are always counted to make things simpler
int m_ListViewSortColumn;
// sorting order
bool m_ListViewSortAscending;
int wxCALLBACK ListControlCompareFunction( long item1, long item2, long sortData ) {
// possible values of sortData:
// 0: we are in the physical view
// 1: we are not in the physical view
int retVal = 0;
bool inPhysicalView = (sortData == 0);
MyListItemData* itemData1 = (MyListItemData*) item1;
MyListItemData* itemData2 = (MyListItemData*) item2;
// make sure that folders are always listed before files
if( itemData1->IsFolder() && !itemData2->IsFolder() ) return -1;
if( !itemData1->IsFolder() && itemData2->IsFolder() ) return 1;
if( m_ListViewSortColumn == 0 ) {
// filename
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetName(), itemData2->GetName() );
else
retVal = wxStricmp( itemData2->GetName(), itemData1->GetName() );
}
if( m_ListViewSortColumn == 1 ) {
// size
if( itemData1->GetSize() == itemData2->GetSize() )
retVal = 0;
else {
if( m_ListViewSortAscending )
retVal = (itemData1->GetSize() < itemData2->GetSize() ? -1 : 1);
else
retVal = (itemData1->GetSize() > itemData2->GetSize() ? -1 : 1);
}
}
if( m_ListViewSortColumn == 2 ) {
// extension
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetExt(), itemData2->GetExt() );
else
retVal = wxStricmp( itemData2->GetExt(), itemData1->GetExt() );
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetName(), itemData2->GetName() );
else
retVal = wxStricmp( itemData2->GetName(), itemData1->GetName() );
}
}
if( m_ListViewSortColumn == 3 ) {
// datetime
if( itemData1->GetDateTime() == itemData2->GetDateTime() )
retVal = 0;
else {
if( m_ListViewSortAscending )
retVal = (itemData1->GetDateTime() < itemData2->GetDateTime() ? -1 : 1);
else
retVal = (itemData1->GetDateTime() > itemData2->GetDateTime() ? -1 : 1);
}
}
if( m_ListViewSortColumn == 4 && !inPhysicalView ) {
// full physical path
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetFullPhysicalPath(), itemData2->GetFullPhysicalPath() );
else
retVal = wxStricmp( itemData2->GetFullPhysicalPath(), itemData1->GetFullPhysicalPath() );
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetName(), itemData2->GetName() );
else
retVal = wxStricmp( itemData2->GetName(), itemData1->GetName() );
}
}
if( (m_ListViewSortColumn == 4 && inPhysicalView) || (m_ListViewSortColumn == 5 && !inPhysicalView) ) {
// description
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetObjectDescription(), itemData2->GetObjectDescription() );
else
retVal = wxStricmp( itemData2->GetObjectDescription(), itemData1->GetObjectDescription() );
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetName(), itemData2->GetName() );
else
retVal = wxStricmp( itemData2->GetName(), itemData1->GetName() );
}
}
if( (m_ListViewSortColumn == 5 && inPhysicalView) || (m_ListViewSortColumn == 6 && !inPhysicalView) ) {
// artist
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetArtist(), itemData2->GetArtist() );
else
retVal = wxStricmp( itemData2->GetArtist(), itemData1->GetArtist() );
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetAlbum(), itemData2->GetAlbum() );
else
retVal = wxStricmp( itemData2->GetAlbum(), itemData1->GetAlbum() );
}
}
if( (m_ListViewSortColumn == 6 && inPhysicalView) || (m_ListViewSortColumn == 7 && !inPhysicalView) ) {
// album
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetAlbum(), itemData2->GetAlbum() );
else
retVal = wxStricmp( itemData2->GetAlbum(), itemData1->GetAlbum() );
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetTitle(), itemData2->GetTitle() );
else
retVal = wxStricmp( itemData2->GetTitle(), itemData1->GetTitle() );
}
}
if( (m_ListViewSortColumn == 7 && inPhysicalView) || (m_ListViewSortColumn == 8 && !inPhysicalView) ) {
// title
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetTitle(), itemData2->GetTitle() );
else
retVal = wxStricmp( itemData2->GetTitle(), itemData1->GetTitle() );
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetArtist(), itemData2->GetArtist() );
else
retVal = wxStricmp( itemData2->GetArtist(), itemData1->GetArtist() );
}
}
if( (m_ListViewSortColumn == 8 && inPhysicalView) || (m_ListViewSortColumn == 9 && !inPhysicalView) ) {
// year
if( m_ListViewSortAscending )
retVal = itemData1->GetYear() - itemData2->GetYear();
else
retVal = itemData2->GetYear() - itemData1->GetYear();
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetArtist(), itemData2->GetArtist() );
else
retVal = wxStricmp( itemData2->GetArtist(), itemData1->GetArtist() );
}
}
if( (m_ListViewSortColumn == 9 && inPhysicalView) || (m_ListViewSortColumn == 10 && !inPhysicalView) ) {
// comment
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetComment(), itemData2->GetComment() );
else
retVal = wxStricmp( itemData2->GetComment(), itemData1->GetComment() );
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetArtist(), itemData2->GetArtist() );
else
retVal = wxStricmp( itemData2->GetArtist(), itemData1->GetArtist() );
}
}
if( (m_ListViewSortColumn == 10 && inPhysicalView) || (m_ListViewSortColumn == 11 && !inPhysicalView) ) {
// number
if( m_ListViewSortAscending )
retVal = itemData1->GetNumber() - itemData2->GetNumber();
else
retVal = itemData2->GetNumber() - itemData1->GetNumber();
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetAlbum(), itemData2->GetAlbum() );
else
retVal = wxStricmp( itemData2->GetAlbum(), itemData1->GetAlbum() );
}
}
if( (m_ListViewSortColumn == 11 && inPhysicalView) || (m_ListViewSortColumn == 12 && !inPhysicalView) ) {
// genre
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetGenre(), itemData2->GetGenre() );
else
retVal = wxStricmp( itemData2->GetGenre(), itemData1->GetGenre() );
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetAlbum(), itemData2->GetAlbum() );
else
retVal = wxStricmp( itemData2->GetAlbum(), itemData1->GetAlbum() );
}
}
if( (m_ListViewSortColumn == 12 && inPhysicalView) || (m_ListViewSortColumn == 13 && !inPhysicalView) ) {
// length
if( m_ListViewSortAscending )
retVal = itemData1->GetLength() - itemData2->GetLength();
else
retVal = itemData2->GetLength() - itemData1->GetLength();
}
if( (m_ListViewSortColumn == 13 && inPhysicalView) || (m_ListViewSortColumn == 14 && !inPhysicalView) ) {
// bitrate
if( m_ListViewSortAscending )
retVal = itemData1->GetBitrate() - itemData2->GetBitrate();
else
retVal = itemData2->GetBitrate() - itemData1->GetBitrate();
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetAlbum(), itemData2->GetAlbum() );
else
retVal = wxStricmp( itemData2->GetAlbum(), itemData1->GetAlbum() );
}
}
if( (m_ListViewSortColumn == 14 && inPhysicalView) || (m_ListViewSortColumn == 15 && !inPhysicalView) ) {
// samplerate
if( m_ListViewSortAscending )
retVal = itemData1->GetSamplerate() - itemData2->GetSamplerate();
else
retVal = itemData2->GetSamplerate() - itemData1->GetSamplerate();
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetAlbum(), itemData2->GetAlbum() );
else
retVal = wxStricmp( itemData2->GetAlbum(), itemData1->GetAlbum() );
}
}
if( (m_ListViewSortColumn == 15 && inPhysicalView) || (m_ListViewSortColumn == 16 && !inPhysicalView) ) {
// channels
if( m_ListViewSortAscending )
retVal = itemData1->GetChannels() - itemData2->GetChannels();
else
retVal = itemData2->GetChannels() - itemData1->GetChannels();
if( retVal == 0 ) {
if( m_ListViewSortAscending )
retVal = wxStricmp( itemData1->GetAlbum(), itemData2->GetAlbum() );
else
retVal = wxStricmp( itemData2->GetAlbum(), itemData1->GetAlbum() );
}
}
return retVal;
}
/*!
* CRightPaneList type definition
*/
IMPLEMENT_CLASS( CRightPaneList, wxListCtrl )
/*!
* CRightPaneList event table definition
*/
BEGIN_EVENT_TABLE( CRightPaneList, wxListCtrl )
////@begin CRightPaneList event table entries
EVT_LIST_ITEM_ACTIVATED( ID_LIST_CONTROL, CRightPaneList::OnListControlItemActivated )
EVT_LIST_COL_CLICK( ID_LIST_CONTROL, CRightPaneList::OnListControlColLeftClick )
EVT_CONTEXT_MENU( CRightPaneList::OnListControlContextMenu )
EVT_SET_FOCUS( CRightPaneList::OnListControlSetFocus )
EVT_KILL_FOCUS( CRightPaneList::OnListControlKillFocus )
////@end CRightPaneList event table entries
END_EVENT_TABLE()
/*!
* CRightPaneList constructors
*/
CRightPaneList::CRightPaneList()
{
Init();
}
CRightPaneList::CRightPaneList(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator)
{
Init();
Create(parent, id, pos, size, style, validator);
}
/*!
* CRightPaneList creator
*/
bool CRightPaneList::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator)
{
////@begin CRightPaneList creation
wxListCtrl::Create(parent, id, pos, size, style, validator);
CreateControls();
////@end CRightPaneList creation
return true;
}
/*!
* CRightPaneList destructor
*/
CRightPaneList::~CRightPaneList()
{
////@begin CRightPaneList destruction
////@end CRightPaneList destruction
}
/*!
* Member initialisation
*/
void CRightPaneList::Init()
{
////@begin CRightPaneList member initialisation
////@end CRightPaneList member initialisation
m_MainFrame = NULL;
}
/*!
* Control creation for CRightPaneList
*/
void CRightPaneList::CreateControls()
{
////@begin CRightPaneList content construction
////@end CRightPaneList content construction
}
/*!
* wxEVT_COMMAND_LIST_ITEM_ACTIVATED event handler for ID_LIST_CONTROL
*/
void CRightPaneList::OnListControlItemActivated( wxListEvent& event )
{
wxASSERT( m_MainFrame != NULL );
m_MainFrame->OnListControlItemActivated( event );
}
/*!
* wxEVT_COMMAND_LIST_COL_CLICK event handler for ID_LIST_CONTROL
*/
void CRightPaneList::OnListControlColLeftClick( wxListEvent& event )
{
wxASSERT( m_MainFrame != NULL );
m_MainFrame->OnListControlColLeftClick( event );
}
/*!
* wxEVT_CONTEXT_MENU event handler for ID_LIST_CONTROL
*/
void CRightPaneList::OnListControlContextMenu( wxContextMenuEvent& event )
{
wxASSERT( m_MainFrame != NULL );
m_MainFrame->OnListControlContextMenu( event );
}
/*!
* wxEVT_SET_FOCUS event handler for ID_LIST_CONTROL
*/
void CRightPaneList::OnListControlSetFocus( wxFocusEvent& event )
{
wxASSERT( m_MainFrame != NULL );
m_MainFrame->OnListControlSetFocus( event );
}
/*!
* wxEVT_KILL_FOCUS event handler for ID_LIST_CONTROL
*/
void CRightPaneList::OnListControlKillFocus( wxFocusEvent& event )
{
wxASSERT( m_MainFrame != NULL );
m_MainFrame->OnListControlKillFocus( event );
}
/*!
* CMainFrame type definition
*/
IMPLEMENT_CLASS( CMainFrame, wxFrame )
/*!
* CMainFrame event table definition
*/
BEGIN_EVENT_TABLE( CMainFrame, wxFrame )
////@begin CMainFrame event table entries
EVT_CLOSE( CMainFrame::OnCloseWindow )
EVT_MENU( wxID_NEW, CMainFrame::OnNEWClick )
EVT_MENU( wxID_OPEN, CMainFrame::OnOPENClick )
EVT_MENU( ID_FILE_EXPORT, CMainFrame::OnFileExportClick )
EVT_UPDATE_UI( ID_FILE_EXPORT, CMainFrame::OnFileExportUpdate )
EVT_MENU( ID_FILE_BACKUP, CMainFrame::OnFileBackupClick )
EVT_UPDATE_UI( ID_FILE_BACKUP, CMainFrame::OnFileBackupUpdate )
EVT_MENU( ID_FILE_RESTORE, CMainFrame::OnFileRestoreClick )
EVT_MENU( wxID_EXIT, CMainFrame::OnEXITClick )
EVT_MENU( ID_ADD_VIRTUAL_FOLDER, CMainFrame::OnAddVirtualFolderClick )
EVT_UPDATE_UI( ID_ADD_VIRTUAL_FOLDER, CMainFrame::OnAddVirtualFolderUpdate )
EVT_MENU( ID_EDIT_RENAME, CMainFrame::OnEditRenameClick )
EVT_UPDATE_UI( ID_EDIT_RENAME, CMainFrame::OnEditRenameUpdate )
EVT_MENU( ID_EDIT_DELETE, CMainFrame::OnEditDeleteClick )
EVT_UPDATE_UI( ID_EDIT_DELETE, CMainFrame::OnEditDeleteUpdate )
EVT_MENU( ID_EDIT_OBJECT_DESCRIPTION, CMainFrame::OnEditObjectDescriptionClick )
EVT_UPDATE_UI( ID_EDIT_OBJECT_DESCRIPTION, CMainFrame::OnEditObjectDescriptionUpdate )
EVT_MENU( ID_NEW_VIRTUAL_ROOT_FOLDER, CMainFrame::OnNewVirtualRootFolderClick )
EVT_UPDATE_UI( ID_NEW_VIRTUAL_ROOT_FOLDER, CMainFrame::OnNewVirtualRootFolderUpdate )
EVT_MENU( ID_NEW_VIRTUAL_SUBFOLDER, CMainFrame::OnNewVirtualSubfolderClick )
EVT_UPDATE_UI( ID_NEW_VIRTUAL_SUBFOLDER, CMainFrame::OnNewVirtualSubfolderUpdate )
#if defined(__WXMAC__)
EVT_MENU( wxID_PREFERENCES, CMainFrame::OnPreferencesClick )
#endif
EVT_MENU( ID_CATALOG_VOLUME, CMainFrame::OnCatalogVolumeClick )
EVT_UPDATE_UI( ID_CATALOG_VOLUME, CMainFrame::OnCatalogVolumeUpdate )
EVT_MENU( ID_UPDATE_VOLUME, CMainFrame::OnUpdateVolumeClick )
EVT_UPDATE_UI( ID_UPDATE_VOLUME, CMainFrame::OnUpdateVolumeUpdate )
EVT_MENU( ID_VIEW_PHYSICAL, CMainFrame::OnViewPhysicalClick )
EVT_UPDATE_UI( ID_VIEW_PHYSICAL, CMainFrame::OnViewPhysicalUpdate )
EVT_MENU( ID_VIEW_VIRTUAL, CMainFrame::OnViewVirtualClick )
EVT_UPDATE_UI( ID_VIEW_VIRTUAL, CMainFrame::OnViewVirtualUpdate )
EVT_MENU( ID_VIEW_SEARCH, CMainFrame::OnViewSearchClick )
EVT_UPDATE_UI( ID_VIEW_SEARCH, CMainFrame::OnViewSearchUpdate )
EVT_MENU( ID_VIEW_SHOW_IN_PHYSICAL, CMainFrame::OnViewShowInPhysicalViewClick )
EVT_UPDATE_UI( ID_VIEW_SHOW_IN_PHYSICAL, CMainFrame::OnViewShowInPhysicalViewUpdate )
EVT_MENU( ID_UP_ONE_FOLDER, CMainFrame::OnUpOneFolderClick )
EVT_UPDATE_UI( ID_UP_ONE_FOLDER, CMainFrame::OnUpOneFolderUpdate )
EVT_MENU( ID_VIEW_EXPAND, CMainFrame::OnViewExpandClick )
EVT_UPDATE_UI( ID_VIEW_EXPAND, CMainFrame::OnViewExpandUpdate )
EVT_MENU( ID_VIEW_COLLAPSE, CMainFrame::OnViewCollapseClick )
EVT_UPDATE_UI( ID_VIEW_COLLAPSE, CMainFrame::OnViewCollapseUpdate )
EVT_MENU( ID_VIEW_TOOLBAR, CMainFrame::OnViewToolbarClick )
EVT_MENU( ID_VIEW_STATUS_BAR, CMainFrame::OnViewStatusBarClick )
#if defined(__WXMSW__) || defined(__WXGTK__)
EVT_MENU( wxID_PREFERENCES, CMainFrame::OnPreferencesClick )
#endif
EVT_MENU( ID_HELP_CONTENTS, CMainFrame::OnHelpContentsClick )
EVT_MENU( wxID_ABOUT, CMainFrame::OnABOUTClick )
EVT_TREE_SEL_CHANGED( ID_TREE_CONTROL, CMainFrame::OnTreeControlSelChanged )
EVT_TREE_ITEM_EXPANDING( ID_TREE_CONTROL, CMainFrame::OnTreeControlItemExpanding )
EVT_TREE_ITEM_MENU( ID_TREE_CONTROL, CMainFrame::OnTreeControlItemMenu )
////@end CMainFrame event table entries
EVT_TREE_SEL_CHANGED( ID_TREE_CONTROL_VIRTUAL, CMainFrame::OnTreeControlVirtualSelChanged )
EVT_TREE_ITEM_EXPANDING( ID_TREE_CONTROL_VIRTUAL, CMainFrame::OnTreeControlVirtualItemExpanding )
EVT_TREE_ITEM_MENU( ID_TREE_CONTROL_VIRTUAL, CMainFrame::OnTreeControlVirtualItemMenu )
EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, CMainFrame::OnMRUFile)
EVT_BUTTON( ID_BUTTON_SEARCH, CMainFrame::OnButtonSearchClick )
END_EVENT_TABLE()
/*!
* CMainFrame constructors
*/
CMainFrame::CMainFrame( )
{
Init();
}
CMainFrame::CMainFrame( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
// wxIcon ico(removable_xpm);
Init();
Create( parent, id, caption, pos, size, style );
}
/*!
* Prova creator
*/
bool CMainFrame::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
////@begin CMainFrame creation
wxFrame::Create( parent, id, caption, pos, size, style );
CreateControls();
SetIcon(GetIconResource(wxT("graphics/vvv32.xpm")));
Centre();
////@end CMainFrame creation
// reads the frame position from the config object
wxConfigBase *pConfig = wxConfigBase::Get();
pConfig->SetPath(wxT("/Mainframe/Layout"));
int x = pConfig->Read(wxT("x"), 50),
y = pConfig->Read(wxT("y"), 50),
w = pConfig->Read(wxT("w"), 600),
h = pConfig->Read(wxT("h"), 400);
// test that the coordinates
if( CWindowPosition::CheckCoordinates(x, y, w, h) ) {
Move(x, y);
SetClientSize(w, h);
}
bool FrameMaximized;
pConfig->Read( wxT("Maximized"), &FrameMaximized, false );
if( FrameMaximized ) {
Maximize(true);
}
// reads the splitter sash position
wxSplitterWindow* sw = GetSplitterWindow();
sw->SetSashPosition( pConfig->Read(wxT("SashPosition"), 200) );
// reads the MRU files list
m_fileHistory->Load( *pConfig );
// reads the listview columns width
int k = 0;
pConfig->SetPath(wxT("/Mainframe/Layout/ListViewPhysical"));
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw0"), 200);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw1"), 100);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw2"), 100);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw3"), 200);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw4"), 100);
// audio metadata
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw5"), 150);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw6"), 150);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw7"), 150);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw8"), 50);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw9"), 100);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw10"), 70);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw11"), 90);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw12"), 70);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw13"), 70);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw14"), 90);
m_ListviewColWidthPhysical[k++] = pConfig->Read(wxT("cw15"), 70);
k = 0;
pConfig->SetPath(wxT("/Mainframe/Layout/ListViewVirtual"));
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw0"), 200);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw1"), 100);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw2"), 100);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw3"), 200);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw4"), 200);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw5"), 100);
// audio metadata
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw6"), 150);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw7"), 150);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw8"), 150);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw9"), 50);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw10"), 100);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw11"), 70);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw12"), 90);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw13"), 70);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw14"), 70);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw15"), 90);
m_ListviewColWidthVirtual[k++] = pConfig->Read(wxT("cw16"), 70);
// reads the visibility state of audio metadata columns
m_amdColumnsToShow = new bool[N_AUDIO_METADATA_COLUMNS];
pConfig->SetPath(wxT("/Mainframe/Layout"));
for( k = 0; k < N_AUDIO_METADATA_COLUMNS; k++ ) {
wxString key = wxT("amdColumnVisible") + CUtils::long2string( k );
pConfig->Read( key, &m_amdColumnsToShow[k], true );
}
// reads program settings
pConfig->SetPath(wxT("/Settings"));
// if there is a settings file name we are running a portable version of this application, so we do not reopen catalogs at startup by default
bool defVal = true;
if( !wxGetApp().GetSettingsFileName().empty() ) defVal = false;
pConfig->Read( wxT("ReopenCatalog"), &m_reopenLastUsedCatalog, defVal );
pConfig->Read( wxT("ForceEnglish"), &m_forceEnglishLanguage, false );
pConfig->Read( wxT("LongTaskBeepTime"), &m_BeepTime, 5 );
pConfig->Read( wxT("CatalogAudioMetadata"), &m_CatalogAudioMetadata, true );
pConfig->SetPath(wxT("/Settings/DatabaseServer"));
pConfig->Read( wxT("ConnectToServer"), &DBConnectionData.connectToServer, false );
DBConnectionData.serverName = pConfig->Read( wxT("ServerName"), wxEmptyString );
DBConnectionData.userName = pConfig->Read( wxT("UserName"), wxT("SYSDBA") );
wxString pwd = pConfig->Read( wxT("Password"), wxT("m1a1s1t1e1r1k1e1y1i1m1p1o1s1s1i1b1l1e1d1e1f1a1u1l1t1p1a1s1s1w1o1r1d") );
if( pwd == wxT("m1a1s1t1e1r1k1e1y1i1m1p1o1s1s1i1b1l1e1d1e1f1a1u1l1t1p1a1s1s1w1o1r1d") )
pwd = wxT("masterkey"); // default password for Firebird servers
else {
if( pwd != wxEmptyString ) pwd = CUtils::Encrypt( pwd );
}
DBConnectionData.password = pwd;
CreateListControlHeaders();
// checks to see if a catalog name has been passed in the command line
// or if the program must reload the last used catalog
wxString catalogName = wxGetApp().GetParameterCatalog();
if( catalogName.empty() && m_reopenLastUsedCatalog && (m_fileHistory->GetCount() > 0) ) {
// no parameter passed, looks for auto load of last used catalog
catalogName = m_fileHistory->GetHistoryFile( 0 );
}
if( !catalogName.empty() ) {
if( !DBConnectionData.connectToServer && !wxFileName::FileExists(catalogName) ) {
CUtils::MsgErr( _("This catalog file does not exist:\n\n") + catalogName );
catalogName = wxEmptyString;
}
}
if( !catalogName.empty() )
OpenDatabase( catalogName, CUtils::GetExpectedDatabaseVersion() );
// sets the "long task beep" time
CLongTaskBeep::SetMinSecondsForBell( m_BeepTime );
return true;
}
/*!
* Member initialisation
*/
void CMainFrame::Init()
{
// wxIcon ico(removable_xpm);
////@begin CMainFrame member initialisation
m_ToolbarCtrl = NULL;
m_fileMenu = NULL;
m_StatusBar = NULL;
////@end CMainFrame member initialisation
m_SearchPanel = NULL;
m_FilenameRadioBox = NULL;
m_SearchFileName = NULL;
m_SearchExtension = NULL;
m_SearchRadioBox = NULL;
m_SearchButton = NULL;
m_DescriptionRadioBox = NULL;
m_SearchDescription = NULL;
m_fileHistory = new wxFileHistory();
m_CurrentView = cvPhysical; // let's start with the physical view
m_ListViewHasFocus = false;
m_PoppingUpContextMenu = false;
m_ListViewSortColumn = 0;
m_ListViewSortAscending = true;
nPhysicalFiles = nVirtualFiles = nSearchFiles = 0;
sizePhysicalFiles = sizeVirtualFiles = sizeSearchFiles = 0;
m_CurrentlyShowingAudioMetadata = false;
m_IgnoreTreeCtrlEvents = false;
}
/*!
* Control creation for Prova
*/
void CMainFrame::CreateControls()
{
////@begin CMainFrame content construction
CMainFrame* itemFrame1 = this;
wxMenuBar* menuBar = new wxMenuBar;
m_fileMenu = new wxMenu;
m_fileMenu->Append(wxID_NEW, _("&New..."), wxEmptyString, wxITEM_NORMAL);
m_fileMenu->Append(wxID_OPEN, _("&Open..."), wxEmptyString, wxITEM_NORMAL);
m_fileMenu->Append(ID_FILE_EXPORT, _("&Export..."), wxEmptyString, wxITEM_NORMAL);
m_fileMenu->AppendSeparator();
m_fileMenu->Append(ID_FILE_BACKUP, _("&Backup..."), wxEmptyString, wxITEM_NORMAL);
m_fileMenu->Append(ID_FILE_RESTORE, _("&Restore..."), wxEmptyString, wxITEM_NORMAL);
m_fileMenu->AppendSeparator();
m_fileMenu->Append(wxID_EXIT, _("E&xit"), wxEmptyString, wxITEM_NORMAL);
menuBar->Append(m_fileMenu, _("&File"));
wxMenu* itemMenu21 = new wxMenu;
itemMenu21->Append(ID_ADD_VIRTUAL_FOLDER, _("&Add To Virtual Folder..."), wxEmptyString, wxITEM_NORMAL);
itemMenu21->AppendSeparator();
itemMenu21->Append(ID_EDIT_RENAME, _("&Rename...\tF2"), wxEmptyString, wxITEM_NORMAL);
itemMenu21->Append(ID_EDIT_DELETE, _("&Delete"), wxEmptyString, wxITEM_NORMAL);
itemMenu21->AppendSeparator();
itemMenu21->Append(ID_EDIT_OBJECT_DESCRIPTION, _("&Object Information..."), wxEmptyString, wxITEM_NORMAL);
itemMenu21->AppendSeparator();
itemMenu21->Append(ID_NEW_VIRTUAL_ROOT_FOLDER, _("&New Virtual Root Folder..."), wxEmptyString, wxITEM_NORMAL);
itemMenu21->Append(ID_NEW_VIRTUAL_SUBFOLDER, _("New Virtual &Subfolder..."), wxEmptyString, wxITEM_NORMAL);
#if defined(__WXMAC__)
itemMenu21->Append(wxID_PREFERENCES, _("&Options..."), wxEmptyString, wxITEM_NORMAL);
#endif
menuBar->Append(itemMenu21, _("&Edit"));
wxMenu* itemMenu32 = new wxMenu;
itemMenu32->Append(ID_CATALOG_VOLUME, _("&Catalog Volume..."), wxEmptyString, wxITEM_NORMAL);
itemMenu32->Append(ID_UPDATE_VOLUME, _("&Update Volume..."), wxEmptyString, wxITEM_NORMAL);
menuBar->Append(itemMenu32, _("&Volumes"));
wxMenu* itemMenu35 = new wxMenu;
itemMenu35->Append(ID_VIEW_PHYSICAL, _("&Physical View"), wxEmptyString, wxITEM_RADIO);
itemMenu35->Check(ID_VIEW_PHYSICAL, true);
itemMenu35->Append(ID_VIEW_VIRTUAL, _("&Virtual View"), wxEmptyString, wxITEM_RADIO);
itemMenu35->Append(ID_VIEW_SEARCH, _("&Search View"), wxEmptyString, wxITEM_RADIO);
itemMenu35->AppendSeparator();
itemMenu35->Append(ID_VIEW_SHOW_IN_PHYSICAL, _("Show in physical view"), wxEmptyString, wxITEM_NORMAL);
itemMenu35->Append(ID_UP_ONE_FOLDER, _("Go &Up One Level"), wxEmptyString, wxITEM_NORMAL);
itemMenu35->Append(ID_VIEW_EXPAND, _("Expand"), wxEmptyString, wxITEM_NORMAL);
itemMenu35->Append(ID_VIEW_COLLAPSE, _("Collapse"), wxEmptyString, wxITEM_NORMAL);
itemMenu35->AppendSeparator();
itemMenu35->Append(ID_VIEW_TOOLBAR, _("&Toolbar"), wxEmptyString, wxITEM_CHECK);
itemMenu35->Check(ID_VIEW_TOOLBAR, true);
itemMenu35->Append(ID_VIEW_STATUS_BAR, _("Status &Bar"), wxEmptyString, wxITEM_CHECK);
itemMenu35->Check(ID_VIEW_STATUS_BAR, true);
menuBar->Append(itemMenu35, _("Vie&w"));
#if defined(__WXMSW__) || defined(__WXGTK__)
wxMenu* itemMenu47 = new wxMenu;
#if defined(__WXMSW__) || defined(__WXGTK__)
itemMenu47->Append(wxID_PREFERENCES, _("&Options..."), wxEmptyString, wxITEM_NORMAL);
#endif
menuBar->Append(itemMenu47, _("&Tools"));
#endif
wxMenu* itemMenu49 = new wxMenu;
itemMenu49->Append(ID_HELP_CONTENTS, _("Help &Contents"), wxEmptyString, wxITEM_NORMAL);
#if defined(__WXMSW__) || defined(__WXGTK__)
itemMenu49->AppendSeparator();
#endif
itemMenu49->Append(wxID_ABOUT, _("&About VVV..."), wxEmptyString, wxITEM_NORMAL);
menuBar->Append(itemMenu49, _("&Help"));
itemFrame1->SetMenuBar(menuBar);
m_ToolbarCtrl = CreateToolBar( wxTB_FLAT|wxTB_HORIZONTAL|wxTB_TEXT, ID_TOOLBAR1 );
m_ToolbarCtrl->SetToolBitmapSize(wxSize(16, 16));
wxBitmap itemtool3Bitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_new.xpm")));
wxBitmap itemtool3BitmapDisabled;
m_ToolbarCtrl->AddTool(wxID_NEW, _("New"), itemtool3Bitmap, itemtool3BitmapDisabled, wxITEM_NORMAL, _("Create a new catalog"), wxEmptyString);
wxBitmap itemtool4Bitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_open.xpm")));
wxBitmap itemtool4BitmapDisabled;
m_ToolbarCtrl->AddTool(wxID_OPEN, _("Open"), itemtool4Bitmap, itemtool4BitmapDisabled, wxITEM_NORMAL, _("Open an existing catalog"), wxEmptyString);
wxBitmap itemtool5Bitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_catalog.png")));
wxBitmap itemtool5BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_CATALOG_VOLUME, _("Catalog"), itemtool5Bitmap, itemtool5BitmapDisabled, wxITEM_NORMAL, _("Catalog a new volume"), wxEmptyString);
wxBitmap itemtool6Bitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_up.xpm")));
wxBitmap itemtool6BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_UP_ONE_FOLDER, _("Up"), itemtool6Bitmap, itemtool6BitmapDisabled, wxITEM_NORMAL, _("Move up one level"), wxEmptyString);
m_ToolbarCtrl->AddSeparator();
wxBitmap itemtool8Bitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_physical.xpm")));
wxBitmap itemtool8BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_VIEW_PHYSICAL, _("Physical"), itemtool8Bitmap, itemtool8BitmapDisabled, wxITEM_RADIO, _("Show the physical view"), wxEmptyString);
wxBitmap itemtool9Bitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_virtual.xpm")));
wxBitmap itemtool9BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_VIEW_VIRTUAL, _("Virtual"), itemtool9Bitmap, itemtool9BitmapDisabled, wxITEM_RADIO, _("Show the virtual view"), wxEmptyString);
wxBitmap itemtool10Bitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_search.xpm")));
wxBitmap itemtool10BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_VIEW_SEARCH, _("Search"), itemtool10Bitmap, itemtool10BitmapDisabled, wxITEM_RADIO, _("Show the search view"), wxEmptyString);
m_ToolbarCtrl->Realize();
itemFrame1->SetToolBar(m_ToolbarCtrl);
m_StatusBar = new wxStatusBar( itemFrame1, ID_STATUSBAR1, wxST_SIZEGRIP );
m_StatusBar->SetFieldsCount(4);
int m_StatusBarWidths[4];
m_StatusBarWidths[0] = 300;
m_StatusBarWidths[1] = 150;
m_StatusBarWidths[2] = 150;
m_StatusBarWidths[3] = -1;
m_StatusBar->SetStatusWidths(4, m_StatusBarWidths);
itemFrame1->SetStatusBar(m_StatusBar);
wxSplitterWindow* itemSplitterWindow54 = new wxSplitterWindow( itemFrame1, ID_SPLITTERWINDOW1, wxDefaultPosition, wxSize(100, 100), wxSP_3DBORDER|wxSP_3DSASH|wxSP_NO_XP_THEME|wxNO_BORDER );
itemSplitterWindow54->SetMinimumPaneSize(0);
wxTreeCtrl* itemTreeCtrl55 = new wxTreeCtrl( itemSplitterWindow54, ID_TREE_CONTROL, wxDefaultPosition, wxSize(100, 100), wxTR_HAS_BUTTONS |wxTR_TWIST_BUTTONS|wxTR_NO_LINES|wxTR_HIDE_ROOT|wxTR_SINGLE|wxNO_BORDER|wxTR_DEFAULT_STYLE );
CRightPaneList* itemListCtrl56 = new CRightPaneList( itemSplitterWindow54, CRightPaneList::ID_LIST_CONTROL, wxDefaultPosition, wxSize(100, 100), wxLC_REPORT|wxNO_BORDER );
itemSplitterWindow54->SplitVertically(itemTreeCtrl55, itemListCtrl56, 50);
////@end CMainFrame content construction
#if defined(__WXMAC__)
// recreate the toolbar with larger bitmaps to make it look better in OS X
delete m_ToolbarCtrl;
SetToolBar( NULL );
CreateMacToolbar();
#endif
// creates the tree control used to show virtual folders
// this control must be created in the same way as the tree control created above
wxSplitterWindow* sw = (wxSplitterWindow*) FindWindow( ID_SPLITTERWINDOW1 );
wxTreeCtrl* itemTreeCtrlVirtual = new wxTreeCtrl( sw, ID_TREE_CONTROL_VIRTUAL, wxDefaultPosition, wxSize(100, 100), wxTR_HAS_BUTTONS |wxTR_TWIST_BUTTONS|wxTR_NO_LINES|wxTR_HIDE_ROOT|wxTR_SINGLE|wxNO_BORDER|wxTR_DEFAULT_STYLE );
itemTreeCtrlVirtual->Show( false );
// stores a pointer to some window components for later use
m_splitterWindow = sw;
m_treePhysicalCtl = (wxTreeCtrl*) FindWindow( ID_TREE_CONTROL );
m_treeVirtualCtl = (wxTreeCtrl*) FindWindow( ID_TREE_CONTROL_VIRTUAL );
m_listCtl = (CRightPaneList*) FindWindow( CRightPaneList::ID_LIST_CONTROL );
m_listCtl->SetMainFrame( this );
// creates the search panel
{
m_SearchPanel = new wxPanel( m_splitterWindow, ID_SEARCH_PANEL, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
m_SearchPanel->SetSizer(itemBoxSizer3);
wxArrayString m_FilenameRadioBoxStrings;
m_FilenameRadioBoxStrings.Add(_("Is equal to:"));
m_FilenameRadioBoxStrings.Add(_("Starts with:"));
m_FilenameRadioBoxStrings.Add(_("Contains:"));
m_FilenameRadioBox = new wxRadioBox( m_SearchPanel, ID_RADIOBOX_FILENAME, _("File name"), wxDefaultPosition, wxDefaultSize, m_FilenameRadioBoxStrings, 1, wxRA_SPECIFY_COLS );
m_FilenameRadioBox->SetSelection(0);
itemBoxSizer3->Add(m_FilenameRadioBox, 0, wxALIGN_LEFT|wxALL, 5);
m_SearchFileName = new wxTextCtrl( m_SearchPanel, ID_SEARCH_FILE_NAME, _T(""), wxDefaultPosition, wxSize(200, -1), 0 );
itemBoxSizer3->Add(m_SearchFileName, 0, wxALIGN_LEFT|wxALL, 5);
itemBoxSizer3->Add(5, 3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
wxStaticText* itemStaticText7 = new wxStaticText( m_SearchPanel, wxID_STATIC, _("Extension:"), wxDefaultPosition, wxDefaultSize, 0 );
itemBoxSizer3->Add(itemStaticText7, 0, wxALIGN_LEFT|wxALL, 5);
m_SearchExtension = new wxTextCtrl( m_SearchPanel, ID_SEARCH_EXTENSION, _T(""), wxDefaultPosition, wxSize(100, -1), 0 );
itemBoxSizer3->Add(m_SearchExtension, 0, wxALIGN_LEFT|wxALL, 5);
itemBoxSizer3->Add(5, 3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
wxArrayString m_DescriptionRadioBoxStrings;
m_DescriptionRadioBoxStrings.Add(_("Is equal to:"));
m_DescriptionRadioBoxStrings.Add(_("Starts with:"));
m_DescriptionRadioBoxStrings.Add(_("Contains:"));
m_DescriptionRadioBox = new wxRadioBox( m_SearchPanel, ID_RADIOBOX_DESCRIPTION, _("Description"), wxDefaultPosition, wxDefaultSize, m_DescriptionRadioBoxStrings, 1, wxRA_SPECIFY_COLS );
m_DescriptionRadioBox->SetSelection(0);
itemBoxSizer3->Add(m_DescriptionRadioBox, 0, wxALIGN_LEFT|wxALL, 5);
m_SearchDescription = new wxTextCtrl( m_SearchPanel, ID_SEARCH_DESCRIPTION, _T(""), wxDefaultPosition, wxSize(200, -1), 0 );
itemBoxSizer3->Add(m_SearchDescription, 0, wxALIGN_LEFT|wxALL, 5);
itemBoxSizer3->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
wxArrayString m_SearchRadioBoxStrings;
m_SearchRadioBoxStrings.Add(_("All physical volumes"));
m_SearchRadioBoxStrings.Add(_("Selected physical folder"));
m_SearchRadioBoxStrings.Add(_("Selected virtual folder"));
m_SearchRadioBox = new wxRadioBox( m_SearchPanel, ID_RADIOBOX_SEARCH, _("Search"), wxDefaultPosition, wxDefaultSize, m_SearchRadioBoxStrings, 1, wxRA_SPECIFY_COLS );
m_SearchRadioBox->SetSelection(0);
itemBoxSizer3->Add(m_SearchRadioBox, 0, wxALIGN_LEFT|wxALL, 5);
itemBoxSizer3->Add(5, 3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
m_SearchButton = new wxButton( m_SearchPanel, ID_BUTTON_SEARCH, _("Search"), wxDefaultPosition, wxDefaultSize, 0 );
m_SearchButton->SetDefault();
itemBoxSizer3->Add(m_SearchButton, 0, wxALIGN_LEFT|wxALL, 5);
m_SearchPanel->Show( false );
}
// associates the MRU files list
m_fileHistory->UseMenu( m_fileMenu );
}
/*!
* Should we show tooltips?
*/
bool CMainFrame::ShowToolTips()
{
return true;
}
/*!
* Get bitmap resources
*/
wxBitmap CMainFrame::GetBitmapResource( const wxString& name )
{
// Bitmap retrieval
////@begin CMainFrame bitmap retrieval
wxUnusedVar(name);
if (name == wxT("graphics/tlb_new.xpm"))
{
wxBitmap bitmap(tlb_new_xpm);
return bitmap;
}
else if (name == wxT("graphics/tlb_open.xpm"))
{
wxBitmap bitmap(tlb_open_xpm);
return bitmap;
}
else if (name == wxT("graphics/tlb_catalog.png"))
{
wxMemoryInputStream memStream(tlb_catalog_png, sizeof(tlb_catalog_png));
wxBitmap bitmap(wxImage(memStream, wxBITMAP_TYPE_ANY, -1), -1);
return bitmap;
}
else if (name == wxT("graphics/tlb_up.xpm"))
{
wxBitmap bitmap(tlb_up_xpm);
return bitmap;
}
else if (name == wxT("graphics/tlb_physical.xpm"))
{
wxBitmap bitmap(tlb_physical_xpm);
return bitmap;
}
else if (name == wxT("graphics/tlb_virtual.xpm"))
{
wxBitmap bitmap(tlb_virtual_xpm);
return bitmap;
}
else if (name == wxT("graphics/tlb_search.xpm"))
{
wxBitmap bitmap(tlb_search_xpm);
return bitmap;
}
return wxNullBitmap;
////@end CMainFrame bitmap retrieval
}
/*!
* Get icon resources
*/
wxIcon CMainFrame::GetIconResource( const wxString& name )
{
// Icon retrieval
wxUnusedVar(name);
if (name == _T("graphics/vvv32.xpm"))
{
#ifdef __WXMSW__
wxIcon icon( wxT("VVV_ICON") );
#else
wxIcon icon(vvv32_xpm);
#endif
return icon;
}
return wxNullIcon;
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_CATALOG_VOLUME
*/
void CMainFrame::OnCatalogVolumeClick( wxCommandEvent& WXUNUSED(event) )
{
CDialogCatalogVolume dialog( this );
dialog.SetCatalogAudioMetadata( m_CatalogAudioMetadata );
dialog.ShowModal();
LoadTreeControl();
}
void CMainFrame::LoadTreeControl(void) {
DeleteAllListControlItems();
wxYield();
wxTreeCtrl* tctl = GetTreePhysicalControl();
wxImageList* iml = new wxImageList( 16, 16 );
wxIcon ico(removable_xpm);
iml->Add(ico);
iml->Add(wxIcon(folder_closed_xpm));
iml->Add(wxIcon(folder_opened_xpm));
tctl->AssignImageList( iml );
m_IgnoreTreeCtrlEvents = true;
tctl->DeleteAllItems();
m_IgnoreTreeCtrlEvents= false;
// adds a root item that will not be visible
wxTreeItemId rootID = tctl->AddRoot( wxT("Root") );
CVolumes vol;
vol.DBStartQueryListVolumes();
while( !vol.IsEOF() ) {
LoadVolumeInTreeControl( vol, tctl, rootID );
vol.DBNextRow();
}
}
void CMainFrame::LoadVolumeInTreeControl( CVolumes vol, wxTreeCtrl* tctl, wxTreeItemId rootID ) {
// first retrieves the id of the root folder
long rootPathID = -1;
CPaths pth;
CNullableLong nl;
nl.SetNull(true);
pth.DBStartQueryListPaths( vol.VolumeID, nl );
while( !pth.IsEOF() ) {
// this query should return only one row
rootPathID = pth.PathID;
pth.DBNextRow();
}
// appends the volume item
wxTreeItemId volumeID = tctl->AppendItem( rootID, CreateVolumeLabel(vol.VolumeName, vol.VolumeDescription), 0, 0,
new MyTreeItemData(vol.VolumeName, vol.VolumeID, rootPathID, true, vol.VolumeDescription) );
// appends the first level of subfolders
// now retrieves the subfolders
nl = rootPathID;
pth.DBStartQueryListPaths( vol.VolumeID, nl );
while( !pth.IsEOF() ) {
wxString name = pth.PathName;
// adds the folder to the tree
wxTreeItemId itemID = tctl->AppendItem( volumeID, name, 1, 2,
new MyTreeItemData(name, vol.VolumeID, pth.PathID, false, pth.PathDescription) );
// sets the expanded images
tctl->SetItemImage( itemID, 1, wxTreeItemIcon_Expanded );
tctl->SetItemImage( itemID, 2, wxTreeItemIcon_SelectedExpanded );
// adds the subfolders
LoadFolderInTreeControl( vol.VolumeID, tctl, itemID, pth.PathID );
pth.DBNextRow();
}
}
void CMainFrame::LoadFolderInTreeControl( long VolumeID, wxTreeCtrl* tctl, wxTreeItemId fatherTreeID, long fatherID ) {
CPaths pth;
pth.DBStartQueryListPaths( VolumeID, fatherID );
while( !pth.IsEOF() ) {
wxString name = pth.PathName;
name = name.AfterLast( wxFileName::GetPathSeparator() );
// adds the folder to the tree
wxTreeItemId itemID = tctl->AppendItem( fatherTreeID, name, 1, 2,
new MyTreeItemData(name, VolumeID, pth.PathID, false, pth.PathDescription) );
// sets the expanded images
tctl->SetItemImage( itemID, 1, wxTreeItemIcon_Expanded );
tctl->SetItemImage( itemID, 2, wxTreeItemIcon_SelectedExpanded );
pth.DBNextRow();
}
}
void CMainFrame::LoadVirtualTreeControl(void) {
wxTreeCtrl* tctl = GetTreeVirtualControl();
wxImageList* iml = new wxImageList( 16, 16 );
iml->Add(wxIcon(removable_xpm));
iml->Add(wxIcon(folder_closed_xpm));
iml->Add(wxIcon(folder_opened_xpm));
tctl->AssignImageList( iml );
tctl->DeleteAllItems();
// adds a root item that will not be visible
wxTreeItemId rootID = tctl->AddRoot( wxT("Root") );
// appends subfolders
CVirtualPaths pth;
CNullableLong nl;
nl.SetNull(true);
pth.DBStartQueryListPaths( nl );
while( !pth.IsEOF() ) {
wxString name = pth.PathName;
// adds the folder to the tree
wxTreeItemId itemID = tctl->AppendItem( rootID, name, 1, 2,
new MyTreeItemData(name, pth.PathID, pth.PhysPathID) );
if( pth.PhysPathID.IsNull() ) {
// this vistual path has been created by the user: it is not a physical path assigned to a virtual path
// show it in a different colour
tctl->SetItemTextColour( itemID, *wxBLUE );
}
// sets the expanded images
tctl->SetItemImage( itemID, 1, wxTreeItemIcon_Expanded );
tctl->SetItemImage( itemID, 2, wxTreeItemIcon_SelectedExpanded );
// adds the subfolders
LoadVirtualFolderInTreeControl( tctl, itemID, pth.PathID );
pth.DBNextRow();
}
}
void CMainFrame::LoadVirtualFolderInTreeControl( wxTreeCtrl* tctl, wxTreeItemId fatherTreeID, long fatherID ) {
CVirtualPaths pth;
pth.DBStartQueryListPaths( fatherID );
while( !pth.IsEOF() ) {
wxString name = pth.PathName;
name = name.AfterLast( wxFileName::GetPathSeparator() );
// adds the folder to the tree
wxTreeItemId itemID = tctl->AppendItem( fatherTreeID, name, 1, 2,
new MyTreeItemData(name, pth.PathID, pth.PhysPathID) );
if( pth.PhysPathID.IsNull() ) {
// this vistual path has been created by the user: it is not a physical path assigned to a virtual path
// show it in a different colour
tctl->SetItemTextColour( itemID, *wxBLUE );
}
// sets the expanded images
tctl->SetItemImage( itemID, 1, wxTreeItemIcon_Expanded );
tctl->SetItemImage( itemID, 2, wxTreeItemIcon_SelectedExpanded );
pth.DBNextRow();
}
}
/*!
* wxEVT_COMMAND_TREE_ITEM_EXPANDING event handler for ID_TREE_CONTROL
*/
void CMainFrame::OnTreeControlItemExpanding( wxTreeEvent& event )
{
wxTreeCtrl* tctl = GetTreePhysicalControl();
wxTreeItemId itemID = event.GetItem();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(itemID);
if( itemData->IsVolume() || itemData->AlreadyOpened() ) return;
// if this item has not been yet opened it loads the children of its children
itemData->SetAlreadyOpened();
// loops over the children
wxTreeItemIdValue cookie;
wxTreeItemId childID = tctl->GetFirstChild( itemID, cookie );
while( childID.IsOk() ) {
// adds the children of this child
MyTreeItemData *childItemData = (MyTreeItemData *) tctl->GetItemData(childID);
LoadFolderInTreeControl( childItemData->GetVolumeID(), tctl, childID, childItemData->GetPathID() );
childID = tctl->GetNextChild( itemID, cookie );
}
}
/*!
* wxEVT_COMMAND_TREE_SEL_CHANGED event handler for ID_TREE_CONTROL
*/
void CMainFrame::OnTreeControlSelChanged( wxTreeEvent& event )
{
if( m_IgnoreTreeCtrlEvents ) return;
if( m_CurrentView != cvPhysical ) return;
wxTreeItemId itemID = event.GetItem();
ShowFolderFiles( itemID );
}
/*!
* wxEVT_COMMAND_TREE_SEL_CHANGED event handler for ID_TREE_CONTROL_VIRTUAL
*/
void CMainFrame::OnTreeControlVirtualSelChanged( wxTreeEvent& event )
{
if( m_CurrentView != cvVirtual ) return;
wxTreeItemId itemID = event.GetItem();
ShowVirtualFolderFiles( itemID );
}
void CMainFrame::CreateListControlHeaders(void) {
int k;
wxListCtrl* lctl = GetListControl();
lctl->Hide();
DeleteAllListControlItems();
lctl->ClearAll();
// adds the columns to the list control
wxListItem itemCol;
itemCol.SetText( _("Name") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
itemCol.SetImage( -1 );
lctl->InsertColumn( 0, itemCol );
itemCol.SetText( _("Size") );
itemCol.SetAlign( wxLIST_FORMAT_RIGHT );
lctl->InsertColumn( 1, itemCol );
itemCol.SetText( _("Ext") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( 2, itemCol );
itemCol.SetText( _("Last modified") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( 3, itemCol );
if( m_CurrentView == cvVirtual || m_CurrentView == cvSearch ) {
itemCol.SetText( _("Physical path") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( 4, itemCol );
itemCol.SetText( _("Description") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( 5, itemCol );
}
else {
itemCol.SetText( _("Description") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( 4, itemCol );
}
// assigns the image list
wxImageList* iml = new wxImageList( 16, 16 );
iml->Add(wxIcon(folder_closed_xpm));
iml->Add(wxIcon(deffile_xpm));
lctl->AssignImageList( iml, wxIMAGE_LIST_SMALL );
// adds a dummy row and deletes it
// needed to correctly show the headers
int i = lctl->InsertItem( 0, "" );
// this code is used to set the item's mask
wxListItem item;
item.SetId( i );
lctl->GetItem( item );
item.SetMask( wxLIST_MASK_STATE|wxLIST_MASK_TEXT|wxLIST_MASK_IMAGE|wxLIST_MASK_DATA );
lctl->SetItem( item );
lctl->SetItem( i, 0, wxT("a") );
lctl->SetItem( i, 1, wxT("a") );
lctl->SetItem( i, 2, wxT("a") );
lctl->SetItem( i, 3, wxT("a") );
if( m_CurrentView == cvVirtual )
lctl->SetItem( i, 4, wxT("a") );
if( m_CurrentView == cvPhysical ) {
for( k = 0; k < N_BASE_COLS_PHYSICAL; k++ )
lctl->SetColumnWidth( k, m_ListviewColWidthPhysical[k] );
}
else {
for( k = 0; k < N_BASE_COLS_VIRTUAL; k++ )
lctl->SetColumnWidth( k, m_ListviewColWidthVirtual[k] );
}
m_CurrentlyShowingAudioMetadata = false;
lctl->DeleteAllItems();
lctl->Show();
}
void CMainFrame::CreateAudioMetadataListControlHeaders( void ) {
wxListItem itemCol;
wxListCtrl *lctl = GetListControl();
int k = m_CurrentView == cvPhysical ? N_BASE_COLS_PHYSICAL : N_BASE_COLS_VIRTUAL;
if( m_amdColumnsToShow[amdArtist] ) {
itemCol.SetText( _("Artist") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdAlbum] ) {
itemCol.SetText( _("Album") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdTitle] ) {
itemCol.SetText( _("Title") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdYear] ) {
itemCol.SetText( _("Year") );
itemCol.SetAlign( wxLIST_FORMAT_RIGHT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdComment] ) {
itemCol.SetText( _("Comment") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdNumber] ) {
itemCol.SetText( _("Number") );
itemCol.SetAlign( wxLIST_FORMAT_RIGHT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdGenre] ) {
itemCol.SetText( _("Genre") );
itemCol.SetAlign( wxLIST_FORMAT_LEFT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdLength] ) {
itemCol.SetText( _("Length") );
itemCol.SetAlign( wxLIST_FORMAT_RIGHT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdBitrate] ) {
itemCol.SetText( _("Bitrate") );
itemCol.SetAlign( wxLIST_FORMAT_RIGHT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdSampleRate] ) {
itemCol.SetText( _("Sample rate") );
itemCol.SetAlign( wxLIST_FORMAT_RIGHT );
lctl->InsertColumn( k++, itemCol );
}
if( m_amdColumnsToShow[amdChannels] ) {
itemCol.SetText( _("Channels") );
itemCol.SetAlign( wxLIST_FORMAT_RIGHT );
lctl->InsertColumn( k++, itemCol );
}
m_CurrentlyShowingAudioMetadata = true;
}
void CMainFrame::DeleteAudioMetadataListControlHeaders( void ) {
if( m_CurrentView == cvPhysical )
StoreListControlPhysicalWidth();
else
StoreListControlVirtualWidth();
wxListCtrl *lctl = GetListControl();
int firstCol = m_CurrentView == cvPhysical ? N_BASE_COLS_PHYSICAL : N_BASE_COLS_VIRTUAL;
for( int k = 0; k < N_AUDIO_METADATA_COLUMNS; k ++ )
if( m_amdColumnsToShow[k] )
lctl->DeleteColumn( firstCol );
m_CurrentlyShowingAudioMetadata = false;
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for wxID_OPEN
*/
void CMainFrame::OnOPENClick( wxCommandEvent& WXUNUSED(event) )
{
wxString caption = _("Open catalog");
wxString databaseName = wxEmptyString;
if( !DBConnectionData.connectToServer ) {
// open a local file
wxString wildcard = _("VVV files (*.vvv)|*.vvv|All files (*.*)|*.*");
wxFileDialog fd( this, caption, wxGetApp().GetDefaultDataFolder(), wxEmptyString, wildcard, wxFD_OPEN );
if( fd.ShowModal() == wxID_OK )
databaseName = fd.GetPath();
} else {
CDialogOpenCatalog dlg( this );
dlg.SetAction( wxT("O") );
dlg.SetShowBrowseButton( DBConnectionData.IsLocalhost() );
if( dlg.ShowModal() == wxID_OK )
databaseName = dlg.GetCatalogName();
}
if( !databaseName.empty() )
OpenDatabase( databaseName, CUtils::GetExpectedDatabaseVersion() );
}
CMainFrame::~CMainFrame() {
if( m_CurrentView == cvPhysical )
StoreListControlPhysicalWidth();
else
StoreListControlVirtualWidth();
DeleteAllListControlItems(); // to delete item data
wxConfigBase *pConfig = wxConfigBase::Get();
if ( pConfig == NULL )
return;
// saves the frame position
int x, y, w, h;
GetClientSize(&w, &h);
GetPosition(&x, &y);
pConfig->SetPath(wxT("/Mainframe/Layout"));
if( !IsMaximized() && CWindowPosition::CheckCoordinates(x, y, w, h) ) {
pConfig->Write(wxT("x"), (long) x);
pConfig->Write(wxT("y"), (long) y);
pConfig->Write(wxT("w"), (long) w);
pConfig->Write(wxT("h"), (long) h);
}
pConfig->Write(wxT("Maximized"), IsMaximized() );
// saves the sash position
wxSplitterWindow* sw = GetSplitterWindow();
pConfig->Write(wxT("SashPosition"), (long) sw->GetSashPosition() );
// saves the MRU files list
m_fileHistory->Save( *pConfig );
delete m_fileHistory;
// saves the listview columns width
int k = 0;
pConfig->SetPath(wxT("/Mainframe/Layout/ListViewPhysical"));
pConfig->Write(wxT("cw0"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw1"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw2"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw3"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw4"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw5"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw6"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw7"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw8"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw9"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw10"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw11"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw12"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw13"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw14"), (long) m_ListviewColWidthPhysical[k++]);
pConfig->Write(wxT("cw15"), (long) m_ListviewColWidthPhysical[k++]);
k = 0;
pConfig->SetPath(wxT("/Mainframe/Layout/ListViewVirtual"));
pConfig->Write(wxT("cw0"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw1"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw2"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw3"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw4"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw5"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw6"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw7"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw8"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw9"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw10"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw11"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw12"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw13"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw14"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw15"), (long) m_ListviewColWidthVirtual[k++]);
pConfig->Write(wxT("cw16"), (long) m_ListviewColWidthVirtual[k++]);
// saves the visibility state of audio metadata columns
pConfig->SetPath(wxT("/Mainframe/Layout"));
for( k = 0; k < N_AUDIO_METADATA_COLUMNS; k++ ) {
wxString key = wxT("amdColumnVisible") + CUtils::long2string( k );
pConfig->Write( key, m_amdColumnsToShow[k] );
}
// saves program settings
pConfig->SetPath(wxT("/Settings"));
pConfig->Write( wxT("ReopenCatalog"), m_reopenLastUsedCatalog );
pConfig->Write( wxT("ForceEnglish"), m_forceEnglishLanguage );
pConfig->Write( wxT("LongTaskBeepTime"), m_BeepTime );
pConfig->Write( wxT("CatalogAudioMetadata"), m_CatalogAudioMetadata );
pConfig->SetPath(wxT("/Settings/DatabaseServer"));
pConfig->Write( wxT("ConnectToServer"), DBConnectionData.connectToServer );
pConfig->Write( wxT("ServerName"), DBConnectionData.serverName );
pConfig->Write( wxT("UserName"), DBConnectionData.userName );
wxString pwd = DBConnectionData.password;
if( pwd != wxEmptyString ) pwd = CUtils::Encrypt( pwd );
pConfig->Write( wxT("Password"), pwd );
delete []m_amdColumnsToShow;
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_VIEW_PHYSICAL
*/
void CMainFrame::OnViewPhysicalClick( wxCommandEvent& event )
{
if( !event.IsChecked() ) return;
if( m_CurrentView == cvPhysical ) return;
wxSplitterWindow* sw = GetSplitterWindow();
long sp = sw->GetSashPosition();
wxListCtrl* lctl = GetListControl();
sw->Unsplit();
switch( m_CurrentView ) {
case cvVirtual:
HideVirtualView();
break;
case cvSearch:
HideSearchView();
break;
default:
wxASSERT(false);
}
ShowPhysicalView();
sw->SplitVertically( GetTreePhysicalControl(), lctl );
sw->SetSashPosition( sp );
UpdateStatusBar( nPhysicalFiles, sizePhysicalFiles );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_VIEW_VIRTUAL
*/
void CMainFrame::OnViewVirtualClick( wxCommandEvent& event )
{
if( !event.IsChecked() ) return;
if( m_CurrentView == cvVirtual ) return;
wxSplitterWindow* sw = GetSplitterWindow();
long sp = sw->GetSashPosition();
wxListCtrl* lctl = GetListControl();
sw->Unsplit();
switch( m_CurrentView ) {
case cvPhysical:
HidePhysicalView();
break;
case cvSearch:
HideSearchView();
break;
default:
wxASSERT(false);
}
ShowVirtualView();
sw->SplitVertically( GetTreeVirtualControl(), lctl );
sw->SetSashPosition( sp );
UpdateStatusBar( nVirtualFiles, sizeVirtualFiles );
}
/*!
* wxEVT_COMMAND_TREE_ITEM_EXPANDING event handler for ID_TREE_CONTROL_VIRTUAL
*/
void CMainFrame::OnTreeControlVirtualItemExpanding( wxTreeEvent& event )
{
wxTreeCtrl* tctl = GetTreeVirtualControl();
wxTreeItemId itemID = event.GetItem();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(itemID);
if( itemData->AlreadyOpened() ) return;
// if this item has not been yet opened it loads the children of its children
itemData->SetAlreadyOpened();
// loops over the children
wxTreeItemIdValue cookie;
wxTreeItemId childID = tctl->GetFirstChild( itemID, cookie );
while( childID.IsOk() ) {
// adds the children of this child
MyTreeItemData *childItemData = (MyTreeItemData *) tctl->GetItemData(childID);
LoadVirtualFolderInTreeControl( tctl, childID, childItemData->GetPathID() );
childID = tctl->GetNextChild( itemID, cookie );
}
}
void CMainFrame::DeleteAllListControlItems(void) {
wxListCtrl* lctl = GetListControl();
int nItems = lctl->GetItemCount();
for( int i = 0; i < nItems; i++ ) {
long itemData = lctl->GetItemData( i );
delete (MyListItemData*) itemData;
}
lctl->DeleteAllItems();
}
void CMainFrame::AddAudioMetatataToListControl( CFilesAudioMetadata fam, wxListCtrl *lctl, int itemIndex, int firstColumnIndex ) {
int k = firstColumnIndex;
wxString s;
if( m_amdColumnsToShow[amdArtist] ) lctl->SetItem( itemIndex, k++, fam.Artist );
if( m_amdColumnsToShow[amdAlbum] ) lctl->SetItem( itemIndex, k++, fam.Album );
if( m_amdColumnsToShow[amdTitle] ) lctl->SetItem( itemIndex, k++, fam.Title );
if( fam.Year == 0 ) s = wxEmptyString; else s = CUtils::long2string(fam.Year);
if( m_amdColumnsToShow[amdYear] ) lctl->SetItem( itemIndex, k++, s );
if( m_amdColumnsToShow[amdComment] ) lctl->SetItem( itemIndex, k++, fam.Comment );
if( fam.Number == 0 ) s = wxEmptyString; else s = CUtils::long2string(fam.Number);
if( m_amdColumnsToShow[amdNumber] ) lctl->SetItem( itemIndex, k++, s );
if( m_amdColumnsToShow[amdGenre] ) lctl->SetItem( itemIndex, k++, fam.Genre );
if( m_amdColumnsToShow[amdLength] ) lctl->SetItem( itemIndex, k++, CUtils::ConvertSecondsToTimeString(fam.Length) );
if( fam.Bitrate == 0 ) s = wxEmptyString; else s = CUtils::long2string(fam.Bitrate);
if( m_amdColumnsToShow[amdBitrate] ) lctl->SetItem( itemIndex, k++, s );
if( fam.SampleRate == 0 ) s = wxEmptyString; else s = CUtils::long2string(fam.SampleRate);
if( m_amdColumnsToShow[amdSampleRate] ) lctl->SetItem( itemIndex, k++, s );
if( fam.Channels == 0 ) s = wxEmptyString; else s = CUtils::long2string(fam.Channels);
if( m_amdColumnsToShow[amdChannels] ) lctl->SetItem( itemIndex, k++, s );
// sets the width of the metadata columns
k = firstColumnIndex;
for( int i = 0; i < N_AUDIO_METADATA_COLUMNS; i++ )
if( m_amdColumnsToShow[i] ) {
lctl->SetColumnWidth( k, m_CurrentView == cvPhysical ? m_ListviewColWidthPhysical[firstColumnIndex + i] : m_ListviewColWidthVirtual[firstColumnIndex + i] );
k++;
}
}
// shows in the listview the files contained in the passed folder
void CMainFrame::ShowFolderFiles( wxTreeItemId itemID ) {
wxString s;
wxBusyCursor wait;
wxTreeCtrl* tctl = GetTreePhysicalControl();
wxListCtrl* lctl = GetListControl();
if( lctl == NULL ) return;
// assigns the image list
wxImageList* iml = new wxImageList( 16, 16 );
iml->Add(wxIcon(folder_closed_xpm));
iml->Add(wxIcon(deffile_xpm));
lctl->AssignImageList( iml, wxIMAGE_LIST_SMALL );
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(itemID);
if( itemData == NULL ) return;
lctl->Hide(); // to speed up things
DeleteAllListControlItems();
// retrieves the files contained in the selected folder
nPhysicalFiles = 0;
sizePhysicalFiles = 0;
CFiles files;
CFilesAudioMetadata fam;
bool foundAudioFiles = false;
files.DBStartQueryListFiles( itemData->GetPathID() );
while( !files.IsEOF() ) {
bool audioMetadataAvailable = false;
if( CAudioMetadata::IsAudioExtension(files.FileExt) ) {
fam.FileID = files.FileID;
audioMetadataAvailable = fam.DBReadMetadata();
foundAudioFiles = true;
}
// adds the file to the list control
int imageIndex = (files.IsFolder() ? 0 : 1 );
wxListItem item;
item.SetId( 0 );
item.SetMask( wxLIST_MASK_STATE|wxLIST_MASK_TEXT|wxLIST_MASK_IMAGE|wxLIST_MASK_DATA );
int i = lctl->InsertItem( item );
lctl->SetItem( i, 0, files.FileName, imageIndex );
if( files.IsFolder() ) s = wxEmptyString; else s = CUtils::HumanReadableFileSize(files.FileSize);
lctl->SetItem( i, 1, s );
lctl->SetItem( i, 2, files.FileExt );
lctl->SetItem( i, 3, files.DateTime.FormatDate() + wxT(" ") + files.DateTime.FormatTime() );
lctl->SetItem( i, 4, FormatObjectDescriptionForListView(files.FileDescription) );
MyListItemData *itemData = new MyListItemData( files.FileID, -1, files.PathFileID.IsNull() ? 0 : (long) files.PathFileID, files.FileName, files.FileExt, files.FileSize, files.DateTime, files.IsFolder(), wxEmptyString, files.FileDescription );
lctl->SetItemData( i, (long) itemData );
if( audioMetadataAvailable ) {
if( !m_CurrentlyShowingAudioMetadata )
CreateAudioMetadataListControlHeaders();
AddAudioMetatataToListControl( fam, lctl, i, 5 );
itemData->AddAudioMetadata( fam );
}
nPhysicalFiles++;
sizePhysicalFiles += files.FileSize;
files.DBNextRow();
}
if( !foundAudioFiles && m_CurrentlyShowingAudioMetadata )
DeleteAudioMetadataListControlHeaders();
lctl->SortItems( ListControlCompareFunction, m_CurrentView == cvPhysical ? 0 : 1 );
lctl->Show();
UpdateStatusBar( nPhysicalFiles, sizePhysicalFiles );
}
// shows in the listview the files contained in the currently selected folder
void CMainFrame::ShowSelectedFolderFiles(void ) {
wxTreeCtrl* tctl = GetTreePhysicalControl();
wxTreeItemId itemID = tctl->GetSelection();
if( itemID.IsOk() ) {
ShowFolderFiles( itemID );
}
else {
DeleteAllListControlItems();
}
}
// shows in the listview the files contained in the passed virtual folder
void CMainFrame::ShowVirtualFolderFiles( wxTreeItemId itemID ) {
wxBusyCursor wait;
wxTreeCtrl* tctl = GetTreeVirtualControl();
wxListCtrl* lctl = GetListControl();
if( lctl == NULL ) return;
// assigns the image list
wxImageList* iml = new wxImageList( 16, 16 );
iml->Add(wxIcon(folder_closed_xpm));
iml->Add(wxIcon(deffile_xpm));
lctl->AssignImageList( iml, wxIMAGE_LIST_SMALL );
// retrieves info about the selected item
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(itemID);
if( itemData == NULL ) return;
lctl->Hide(); // to speed up things
DeleteAllListControlItems();
// retrieves the files contained in the selected folder
nVirtualFiles = 0;
sizeVirtualFiles = 0;
CVirtualFiles files;
bool foundAudioFiles = false;
files.DBStartQueryListFiles( itemData->GetPathID() );
while( !files.IsEOF() ) {
wxString prevFileName = files.FileName;
bool wasFolder = files.IsFolder();
if( CAudioMetadata::IsAudioExtension(files.FileExt) ) {
foundAudioFiles = true;
}
int i = AddRowToVirtualListControl( lctl, files.IsFolder(), files.FileName, files.FileSize, files.FileExt, files.DateTime, files.FullPhysicalPath, files.FileID, files.VirtualPathFileID.IsNull() ? 0 : (long) files.VirtualPathFileID, files.FileDescription, files.PhysicalFileID );
nVirtualFiles++;
sizeVirtualFiles += files.FileSize;
files.DBNextRow();
// removes possible duplicate folder rows. If this folder contains physical folders from different volumes
// but with the same name the query will return more than one folder with the same name
if( wasFolder ) {
while( !files.IsEOF() ) {
if( files.FileName != prevFileName ) break;
if( !files.IsFolder() ) break;
// here if the current row is a folder with the same name as the one already in the listview
lctl->SetItem( i, 4, wxEmptyString ); // remove physical path since it has no meaning (there are more than one)
files.DBNextRow(); // sjip this row
}
}
}
if( !foundAudioFiles && m_CurrentlyShowingAudioMetadata )
DeleteAudioMetadataListControlHeaders();
lctl->SortItems( ListControlCompareFunction, m_CurrentView == cvPhysical ? 0 : 1 );
lctl->Show();
UpdateStatusBar( nVirtualFiles, sizeVirtualFiles );
}
// shows in the listview the files contained in the currently selected virtual folder
void CMainFrame::ShowSelectedVirtualFolderFiles(void ) {
wxTreeCtrl* tctl = GetTreeVirtualControl();
wxTreeItemId itemID = tctl->GetSelection();
if( itemID.IsOk() ) {
ShowVirtualFolderFiles( itemID );
}
else {
DeleteAllListControlItems();
}
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_ADD_VIRTUAL_FOLDER
*/
void CMainFrame::OnAddVirtualFolderClick( wxCommandEvent& WXUNUSED(event) )
{
bool listViewHadFocus = m_ListViewHasFocus; // we store the value because it changes when opening the dialog
CDialogChooseVirtualFolder cvf( this );
cvf.SetCurrentPathArray( m_SelectedVirtualFolderForAdd );
if( cvf.ShowModal() != wxID_OK ) {
m_ListViewHasFocus = listViewHadFocus;
return;
}
long virtualFolderId = cvf.GetVirtualFolderID();
cvf.GetCurrentPathArray( m_SelectedVirtualFolderForAdd );
m_ListViewHasFocus = listViewHadFocus;
if( virtualFolderId < 0 ) return;
wxBusyCursor wait;
CLongTaskBeep ltb;
if( m_ListViewHasFocus ) {
wxListCtrl *lctl = GetListControl();
// loops over all the selected items
long item = -1;
for( ;; ) {
item = lctl->GetNextItem( item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
if( item == -1 ) break;
MyListItemData *itemData = (MyListItemData *) lctl->GetItemData( item );
if( itemData->IsFolder() )
CVirtualPaths::AppendPhysicalPath( itemData->GetPathFileID(), virtualFolderId );
else
CVirtualPaths::AddPhysicalFile( itemData->GetPhysicalFileID(), virtualFolderId );
}
}
else {
bool isVolumeItem = false; // true if the user has selected a volume (not a folder)
wxTreeCtrl *tctl = GetTreePhysicalControl();
wxTreeItemId item = tctl->GetSelection();
if( tctl->GetItemParent(item) == tctl->GetRootItem() ) isVolumeItem = true;
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
long physicalFolderId = itemData->GetPathID();
if( isVolumeItem ) {
long volumeID = itemData->GetVolumeID();
CVirtualPaths::AppendVolume( volumeID, physicalFolderId, virtualFolderId );
}
else
CVirtualPaths::AppendPhysicalPath( physicalFolderId, virtualFolderId );
}
CBaseDB::GetDatabase()->UpdateStatistics( CBaseDB::usVirtual );
// updates the tree controls
LoadVirtualTreeControl();
}
/*!
* wxEVT_UPDATE_UI event handler for ID_ADD_VIRTUAL_FOLDER
*/
void CMainFrame::OnAddVirtualFolderUpdate( wxUpdateUIEvent& event )
{
if( CBaseDB::GetDatabase() == NULL ) {
event.Enable(false);
return;
}
bool isEnabled = false;
if( m_CurrentView == cvPhysical ) {
wxTreeCtrl* tctl = GetTreePhysicalControl();
isEnabled = (tctl->GetCount() > 0);
}
if( m_CurrentView == cvSearch ) {
isEnabled = m_ListViewHasFocus;
}
event.Enable( isEnabled );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_NEW_VIRTUAL_ROOT_FOLDER
*/
void CMainFrame::OnNewVirtualRootFolderClick( wxCommandEvent& WXUNUSED(event) )
{
CNullableLong nl;
nl.SetNull( true );
CreateNewVirtualFolder( nl, _("New virtual root folder") );
}
/*!
* wxEVT_UPDATE_UI event handler for ID_NEW_VIRTUAL_ROOT_FOLDER
*/
void CMainFrame::OnNewVirtualRootFolderUpdate( wxUpdateUIEvent& event )
{
if( CBaseDB::GetDatabase() == NULL ) {
event.Enable(false);
return;
}
event.Enable( m_CurrentView == cvVirtual );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_NEW_VIRTUAL_SUBFOLDER
*/
void CMainFrame::OnNewVirtualSubfolderClick( wxCommandEvent& WXUNUSED(event) )
{
wxTreeCtrl *tctl = GetTreeVirtualControl();
wxTreeItemId item = tctl->GetSelection();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
long FatherID = itemData->GetPathID();
CreateNewVirtualFolder( FatherID, _("New virtual subfolder") );
}
void CMainFrame::CreateNewVirtualFolder( CNullableLong FatherID, wxString windowTitle ) {
wxTreeCtrl *tctl = GetTreeVirtualControl();
wxTreeItemId fatherItem;
wxString folderName = wxEmptyString;
if( FatherID.IsNull() ) {
// this is a root folder
fatherItem = tctl->GetRootItem();
}
else {
// this is a subfolder
fatherItem = tctl->GetSelection();
}
// asks for the new folder name
wxTextEntryDialog ted( this, _("Enter the new folder name"), windowTitle, folderName, wxOK | wxCANCEL );
if( ted.ShowModal() != wxID_OK ) return;
folderName = ted.GetValue();
if( folderName == wxEmptyString ) return;
// adds the new folder to the database
CVirtualPaths pth;
pth.PathName = folderName;
pth.PhysPathID.SetNull( true );
pth.FatherID = FatherID;
try {
pth.DbInsert();
}
catch( CDataErrorException& e ) {
if( e.GetErrorCause() == CDataErrorException::ecUnique ) {
CUtils::MsgErr( _("The new folder name is already present in the database") );
return;
}
else
throw;
}
// adds the folder to the tree control
wxTreeItemId newItem = tctl->AppendItem( fatherItem, pth.PathName, 1, 2,
new MyTreeItemData(pth.PathName, pth.PathID, pth.PhysPathID) );
tctl->SetItemTextColour( newItem, *wxBLUE );
// sets the expanded images
tctl->SetItemImage( newItem, 1, wxTreeItemIcon_Expanded );
tctl->SetItemImage( newItem, 2, wxTreeItemIcon_SelectedExpanded );
// updates the listview
if( !FatherID.IsNull() )
ShowVirtualFolderFiles( fatherItem );
}
/*!
* wxEVT_UPDATE_UI event handler for ID_NEW_VIRTUAL_SUBFOLDER
*/
void CMainFrame::OnNewVirtualSubfolderUpdate( wxUpdateUIEvent& event )
{
if( CBaseDB::GetDatabase() == NULL || m_ListViewHasFocus ) {
event.Enable(false);
return;
}
bool isEnabled = m_CurrentView == cvVirtual;
if( isEnabled ) {
wxTreeCtrl* tctl = GetTreeVirtualControl();
isEnabled = (tctl->GetCount() > 0);
if( isEnabled ) {
wxTreeItemId item = tctl->GetSelection();
isEnabled = item.IsOk();
}
}
event.Enable( isEnabled );
}
void CMainFrame::OnMRUFile( wxCommandEvent& event ) {
int i = event.GetId() - wxID_FILE1;
wxString fileName = m_fileHistory->GetHistoryFile( i );
if( fileName.empty() ) return;
if( !DBConnectionData.connectToServer && !wxFileName::FileExists(fileName) ) {
CUtils::MsgErr( _("This catalog file does not exist any more") );
m_fileHistory->RemoveFileFromHistory( i );
return;
}
OpenDatabase( fileName, CUtils::GetExpectedDatabaseVersion() );
}
void CMainFrame::OpenDatabase( wxString fileName, int expectedVersion ) {
wxBusyCursor wait;
wxString serverName, userName, password;
bool errorOpeningDB;
CBaseDB *db = CBaseDB::GetDatabase();
if( db != NULL ) {
CBaseDB::GetDatabase()->Disconnect();
CBaseDB::DeleteFirebirdDatabase();
}
DBConnectionData.GetConnectionData( serverName, userName, password );
CBaseDB::CreateFirebirdDatabase( serverName, fileName, userName, password );
errorOpeningDB = false;
try {
CBaseDB::GetDatabase()->Connect();
}
catch( CDataErrorException e ) {
switch( e.GetErrorCause() ) {
case CDataErrorException::ecDatabaseNotFound:
CUtils::MsgErr( _("Catalog not found:\n\n") + fileName );
errorOpeningDB = true;
break;
case CDataErrorException::ecWrongUsernameOrPassword:
CUtils::MsgErr( _("Incorrect username or password for the following database:\n\n") + fileName );
errorOpeningDB = true;
break;
case CDataErrorException::ecServerNotFound:
if( DBConnectionData.connectToServer )
CUtils::MsgErr( _("Unable to connect to the following server:\n\n") + serverName );
else
CUtils::MsgErr( _("Unable to open the catalog.\nPlease note that you are not connected to a database server so you cannot open a catalog located on another computer in the network.\nIf you want to open a catalog on another computer you must connect to the database server (Tools/Options menu).") );
errorOpeningDB = true;
break;
default:
throw;
}
if( errorOpeningDB ) {
CBaseDB::DeleteFirebirdDatabase();
LoadTreeControl();
LoadVirtualTreeControl();
DeleteAllListControlItems();
return;
}
}
int dbVersion = CBaseDB::GetDatabase()->GetDatabaseVersion();
if( dbVersion < expectedVersion ) {
// we need to upgrade the database
if( !wxFileExists(CUtils::GetStructUpdateDbName() ) ) {
CUtils::MsgErr( _("This catalog has been created with a previous version of the program and it needs to be upgraded, but the file containing the upgrades list is missing.\n\nYou can try reinstalling the program to solve this problem.") );
return;
}
wxBusyInfo bi( _("Upgrading the catalog, please wait...") );
if( dbVersion < CUtils::GetFirstUnicodeDatabaseVersion() ) {
// upgrades to the last version before unicode
if( dbVersion < CUtils::GetFirstUnicodeDatabaseVersion() - 1 )
CBaseDB::GetDatabase()->UpgradeDatabase( dbVersion, CUtils::GetFirstUnicodeDatabaseVersion() - 1 );
}
else
CBaseDB::GetDatabase()->UpgradeDatabase( dbVersion );
}
if( dbVersion < CUtils::GetFirstUnicodeDatabaseVersion() ) {
// upgrade the db to unicode
wxString msg = _("This catalog has been created with an older version of VVV so you need to convert it to a newer format.\n\n");
msg += _("The conversion will create a new catalog with the same data as the older one, then you will use this new catalog with VVV. You will not use the older catalog any more.\n\n");
msg += _("Do you want to convert the catalog creating a new one?");
if( !CUtils::MsgAskNo(msg) ) return;
if( DBConnectionData.connectToServer && !DBConnectionData.IsLocalhost() ) {
CUtils::MsgErr( _("Unable to create a new catalog.\n\nYou are connecting to a database server on another computer. You must execute this program on the server to be able to create a new catalog.") );
return;
}
wxString caption = _("Convert to a new catalog");
// creates the name of the database backup file to restore
wxString appPath = wxStandardPaths::Get().GetExecutablePath();
wxFileName fn(appPath);
wxString path = fn.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
wxString backupName = path + _T("VVV.fbk");
if( !wxFileExists(backupName) ) {
CUtils::MsgErr( _("Unable to find the database backup to restore.\n\nYou can try reinstalling the program to solve this problem.") );
return;
}
wxString newDatabaseFile = RestoreDatabase( caption, backupName );
if( newDatabaseFile.empty() ) return;
// now we have an empty unicode database: copy data into it
CBaseDB::GetDatabase()->Disconnect();
CBaseDB::DeleteFirebirdDatabase();
CUtils::ConvertDbToUnicode( fileName, newDatabaseFile );
return;
}
LoadTreeControl();
LoadVirtualTreeControl();
DeleteAllListControlItems();
// stores the file in the MRU list
m_fileHistory->AddFileToHistory( fileName );
// sets the main window caption
SetTitle( fileName + wxT(" - ") + CUtils::GetApplicationName() );
}
/*!
* wxEVT_COMMAND_LIST_COL_CLICK event handler for ID_LIST_CONTROL
*/
void CMainFrame::OnListControlColLeftClick( wxListEvent& event )
{
int nCol = ColumnNumIfNoColumnsHidden( event.GetColumn() );
if( nCol == m_ListViewSortColumn ) {
m_ListViewSortAscending = !m_ListViewSortAscending;
}
else {
m_ListViewSortColumn = nCol;
m_ListViewSortAscending = true;
}
wxListCtrl* lctl = GetListControl();
lctl->SortItems( ListControlCompareFunction, m_CurrentView == cvPhysical ? 0 : 1 );
}
/*!
* wxEVT_UPDATE_UI event handler for ID_VIEW_PHYSICAL
*/
void CMainFrame::OnViewPhysicalUpdate( wxUpdateUIEvent& event )
{
event.Enable( CBaseDB::GetDatabase() != NULL );
if( m_CurrentView == cvPhysical )
event.Check(true);
else
event.Check(false);
}
/*!
* wxEVT_UPDATE_UI event handler for ID_VIEW_VIRTUAL
*/
void CMainFrame::OnViewVirtualUpdate( wxUpdateUIEvent& event )
{
event.Enable( CBaseDB::GetDatabase() != NULL );
if( m_CurrentView == cvVirtual )
event.Check(true);
else
event.Check(false);
}
/*!
* wxEVT_UPDATE_UI event handler for ID_CATALOG_VOLUME
*/
void CMainFrame::OnCatalogVolumeUpdate( wxUpdateUIEvent& event )
{
event.Enable( CBaseDB::GetDatabase() != NULL );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_VIEW_TOOLBAR
*/
void CMainFrame::OnViewToolbarClick( wxCommandEvent& event )
{
if( event.IsChecked() )
GetToolBar()->Show(true);
else {
GetToolBar()->Show(false);
}
#ifdef __WXMSW__
SendSizeEvent();
#else
wxSize s = GetSize();
Fit();
SetSize(s);
#endif
}
void CMainFrame::StoreListControlVirtualWidth(void) {
int k;
wxListCtrl* lctl = GetListControl();
for( k = 0; k < N_BASE_COLS_VIRTUAL; k++ )
m_ListviewColWidthVirtual[k] = lctl->GetColumnWidth(k);
if( m_CurrentlyShowingAudioMetadata ) {
// stores the width of the audio metadata columns
k = N_BASE_COLS_VIRTUAL;
for( int i = 0; i < N_AUDIO_METADATA_COLUMNS; i++ )
if( m_amdColumnsToShow[i] ) {
m_ListviewColWidthVirtual[N_BASE_COLS_VIRTUAL + i] = lctl->GetColumnWidth(k);
k++;
}
}
}
void CMainFrame::StoreListControlPhysicalWidth(void) {
int k;
wxListCtrl* lctl = GetListControl();
for( k = 0; k < N_BASE_COLS_PHYSICAL; k++ )
m_ListviewColWidthPhysical[k] = lctl->GetColumnWidth(k);
if( m_CurrentlyShowingAudioMetadata ) {
// stores the width of the audio metadata columns
k = N_BASE_COLS_PHYSICAL;
for( int i = 0; i < N_AUDIO_METADATA_COLUMNS; i++ )
if( m_amdColumnsToShow[i] ) {
m_ListviewColWidthPhysical[N_BASE_COLS_PHYSICAL + i] = lctl->GetColumnWidth(k);
k++;
}
}
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for wxID_EXIT
*/
void CMainFrame::OnEXITClick( wxCommandEvent& WXUNUSED(event) )
{
Close(true);
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for wxID_ABOUT
*/
void CMainFrame::OnABOUTClick( wxCommandEvent& WXUNUSED(event) )
{
wxAboutDialogInfo info;
info.SetName( wxT("VVV") );
info.SetVersion( CUtils::GetApplicationVersion() );
info.SetWebSite( wxT("http://vvvapp.sourceforge.net/") );
info.SetDescription( _("VVV (Virtual Volumes View): a program to catalog removable devices like CDs and DVDs") );
info.SetCopyright( _("Copyright (C) 2007-2011 The VVV Team") );
info.AddDeveloper( _("Fulvio Senore: main developer") );
info.AddDeveloper( _("\nJan Albartus: worked at the portable version and designed the application's icon") );
info.AddArtist( _("This program uses icons from the Gnome, Ubuntu and Crystal icons projects") );
info.SetLicence( _("This is open source software, distributed under the GNU GENERAL PUBLIC LICENSE") );
info.AddTranslator( wxString(wxT("bec: ")) + _("Chinese") );
info.AddTranslator( wxString(wxT("Pedro Cunha: ")) + _("Portuguese") );
info.AddTranslator( wxString(wxT("David de Castro: ")) + _("Spanish") );
info.AddTranslator( wxString(wxT("Fr\u00E9d\u00E9ric Gacquer, TheG!: ")) + _("French") );
info.AddTranslator( wxString(wxT("Steve K\u00F6hler: ")) + _("German") );
info.AddTranslator( wxString(wxT("Kriszti\u00E1n Mukli: ")) + _("Hungarian") );
info.AddTranslator( wxString(wxT("Karel Kozl\u00EDk: ")) + _("Czech") );
info.AddTranslator( wxString(wxT("Dariusz Liszewski: ")) + _("Polish") );
info.AddTranslator( wxString(wxT("Krisztian Mukli: ")) + _("Hungarian") );
info.AddTranslator( wxString(wxT("Yaroslav D. Mudryy, Yuriy Karandyshev : ")) + _("Russian") );
info.AddTranslator( wxString(wxT("Yaroslav D. Mudryy : ")) + _("Ukrainian") );
info.AddTranslator( wxString(wxT("Hasan Osmanagi\u0107: ")) + _("Croatian") );
info.AddTranslator( wxString(wxT("Milos Popovic: ")) + _("Serbian") );
info.AddTranslator( wxString(wxT("Suguru SASAKI: ")) + _("Japanese") );
info.AddTranslator( wxString(wxT("Fulvio Senore: ")) + _("Italian") );
info.AddTranslator( wxString(wxT("Nick Sercaianu: ")) + _("Romanian") );
info.AddTranslator( wxString(wxT("Gideon van Melle: ")) + _("Dutch") );
wxAboutBox( info );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for wxID_NEW
*/
void CMainFrame::OnNEWClick( wxCommandEvent& WXUNUSED(event) )
{
if( DBConnectionData.connectToServer && !DBConnectionData.IsLocalhost() ) {
CUtils::MsgErr( _("Unable to create a new catalog.\n\nYou are connecting to a database server on another computer. You must execute this program on the server to be able to create a new catalog.") );
return;
}
wxString caption = _("New catalog");
// creates the name of the database backup file to restore
wxString appPath = wxStandardPaths::Get().GetExecutablePath();
wxFileName fn(appPath);
wxString path = fn.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
wxString backupName = path + _T("VVV.fbk");
if( !wxFileExists(backupName) ) {
CUtils::MsgErr( _("Unable to find the database backup to restore.\n\nYou can try reinstalling the program to solve this problem.") );
return;
}
wxString databaseFile = RestoreDatabase( caption, backupName );
if( databaseFile.empty() ) return;
// open the database
OpenDatabase( databaseFile, CUtils::GetExpectedDatabaseVersion() );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_EDIT_OPJECT_DESCRIPTION
*/
void CMainFrame::OnEditObjectDescriptionClick( wxCommandEvent& WXUNUSED(event) )
{
if( m_ListViewHasFocus ) {
wxListCtrl *lctl = GetListControl();
int nSelectedObjects = lctl->GetSelectedItemCount();
wxASSERT( nSelectedObjects > 0 );
wxString objectName;
wxString orgDescr = wxEmptyString;
wxString newDescr = wxEmptyString;
MyListItemData *itemData = NULL;
bool descriptionOnly = true; // flag to decide which dialog to show
if( nSelectedObjects == 1 ) {
long item = -1;
item = lctl->GetNextItem( item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
itemData = (MyListItemData *) lctl->GetItemData( item );
descriptionOnly = itemData->IsFolder() && nSelectedObjects > 1;
if( itemData->IsFolder() && m_CurrentView == cvVirtual ) {
// at the moment the program does not support description for folders in the virtual view
return;
}
}
if( descriptionOnly ) {
if( nSelectedObjects == 1 ) {
objectName = itemData->GetName();
}
else {
objectName = _("Multiple items") + wxString::Format( wxT(" (%d)"), nSelectedObjects );
}
CDialogObjectDescription dialog( this );
dialog.SetObjectName( objectName );
dialog.SetDescription( orgDescr );
if( dialog.ShowModal() != wxID_OK ) return;
newDescr = dialog.GetDescription();
if( newDescr == orgDescr) return;
}
else {
wxASSERT( itemData != NULL );
orgDescr = itemData->GetObjectDescription();
CFileInformationDialog dialog( this );
dialog.SetDescription( orgDescr );
dialog.SetItemData( itemData );
if( dialog.ShowModal() != wxID_OK ) return;
newDescr = dialog.GetDescription();
if( newDescr == orgDescr) return;
}
// loops over all the selected items
long item = -1;
for( ;; ) {
item = lctl->GetNextItem( item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
if( item == -1 ) break;
MyListItemData *itemData = (MyListItemData *) lctl->GetItemData( item );
itemData->SetObjectDescription( newDescr );
if( itemData->IsFolder() ) {
if( m_CurrentView == cvPhysical ) {
// at the moment the program does not support description for folders in the virtual view
CPaths::UpdateDescription( itemData->GetPathFileID(), newDescr );
}
}
else {
CFiles::UpdateDescription( itemData->GetPhysicalFileID(), newDescr );
}
lctl->SetItem( item, m_CurrentView == cvPhysical ? 4 : 5, FormatObjectDescriptionForListView(newDescr) );
}
}
else {
wxTreeCtrl *tctl = GetTreePhysicalControl();
wxTreeItemId item = tctl->GetSelection();
if( !item.IsOk() ) return;
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
if( itemData == NULL ) return; // generic treectrl bug
wxString objectName = itemData->GetDesc();
//CDialogObjectDescription dialog( this, ID_DIALOG_OBJECT_DESCRIPTION, _("Object description") );
//dialog.SetObjectName( objectName );
//wxString orgDescr = itemData->GetObjectDescription();
//dialog.SetDescription( orgDescr );
CFileInformationDialog dialog( this );
wxString orgDescr = itemData->GetObjectDescription();
dialog.SetDescription( orgDescr );
dialog.SetItemData( itemData );
if( dialog.ShowModal() != wxID_OK ) return;
wxString newDescr = dialog.GetDescription();
if( newDescr == orgDescr) return;
if( itemData->IsVolume() ) {
CVolumes vol;
vol.VolumeID = itemData->GetVolumeID();
vol.VolumeName = itemData->GetDesc();
vol.VolumeDescription = newDescr;
vol.DbUpdate();
// updates the tree control
tctl->SetItemText( item, CreateVolumeLabel(vol.VolumeName, newDescr) );
}
else {
if( m_CurrentView == cvPhysical ) {
// at the moment the program does not support description for folders in the virtual view
CPaths::UpdateDescription( itemData->GetPathID(), newDescr );
}
}
itemData->SetObjectDescription( newDescr );
}
}
/*!
* wxEVT_UPDATE_UI event handler for ID_EDIT_VOLUME_DESCRIPTION
*/
void CMainFrame::OnEditObjectDescriptionUpdate( wxUpdateUIEvent& event )
{
if( CBaseDB::GetDatabase() == NULL ) {
event.Enable(false);
return;
}
if( m_CurrentView != cvPhysical && !m_ListViewHasFocus ) {
event.Enable(false);
return;
}
bool hideElement = true;
if( m_ListViewHasFocus ) {
wxListCtrl *lctl = GetListControl();
if( lctl->GetSelectedItemCount() > 0 )
hideElement = false;
}
else {
wxTreeCtrl *tctl = GetTreePhysicalControl();
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
hideElement = false;
}
}
}
event.Enable( !hideElement );
}
wxString CMainFrame::CreateVolumeLabel( const wxString& VolumeName, const wxString& VolumeDescription ) {
wxString retVal;
retVal = VolumeName;
if( !VolumeDescription.empty() ) {
wxString s = VolumeDescription.Left(20);
s.Replace( wxT("\n"), wxT(" ") );
retVal += wxT(" - ") + s;
}
return retVal;
}
wxString CMainFrame::FormatObjectDescriptionForListView( const wxString& ObjectDescription ) {
wxString retVal;
retVal = ObjectDescription.Left(50);
if( !retVal.empty() ) {
retVal.Replace( wxT("\n"), wxT(" ") );
}
return retVal;
}
/*!
* wxEVT_COMMAND_TREE_ITEM_MENU event handler for ID_TREE_CONTROL
*/
void CMainFrame::OnTreeControlItemMenu( wxTreeEvent& event )
{
wxTreeItemId item = event.GetItem();
if( !item.IsOk() ) return;
wxTreeCtrl *tctl = GetTreePhysicalControl();
tctl->SelectItem( item );
wxPoint pt = event.GetPoint();
wxMenu menu;
menu.Append( ID_ADD_VIRTUAL_FOLDER, _("Add To Virtual Folder") );
menu.AppendSeparator();
menu.Append( ID_VIEW_EXPAND, _("Expand") );
menu.Append( ID_VIEW_COLLAPSE, _("Collapse") );
menu.AppendSeparator();
menu.Append( ID_EDIT_OBJECT_DESCRIPTION, _("Object information...") );
if( tctl->GetItemParent(item) == tctl->GetRootItem() ) {
// only for voume nodes, not for folders
menu.Append( ID_EDIT_RENAME, _("Rename...") );
menu.Append( ID_EDIT_DELETE, _("Delete") );
menu.Append( ID_UPDATE_VOLUME, _("Update Volume...") );
}
PopupMenu( &menu, pt );
event.Skip();
}
void CMainFrame::OnTreeControlVirtualItemMenu( wxTreeEvent& event )
{
wxTreeItemId item = event.GetItem();
// if( !item.IsOk() ) return;
wxTreeCtrl *tctl = GetTreeVirtualControl();
if( item.IsOk() ) tctl->SelectItem( item );
wxPoint pt = event.GetPoint();
wxMenu menu;
menu.Append( ID_NEW_VIRTUAL_ROOT_FOLDER, _("New Root Folder") );
if( item.IsOk() ) {
// only if we have a selected item
menu.Append( ID_NEW_VIRTUAL_SUBFOLDER, _("New Subfolder") );
menu.AppendSeparator();
menu.Append( ID_VIEW_EXPAND, _("Expand") );
menu.Append( ID_VIEW_COLLAPSE, _("Collapse") );
menu.AppendSeparator();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
if( itemData->GetPhysPathID().IsNull() ) menu.Append( ID_EDIT_RENAME, _("Rename") );
menu.Append( ID_EDIT_DELETE, _("Delete") );
}
PopupMenu( &menu, pt );
event.Skip();
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_VIEW_SEARCH
*/
void CMainFrame::OnViewSearchClick( wxCommandEvent& event )
{
if( !event.IsChecked() ) return;
if( m_CurrentView == cvSearch ) return;
wxSplitterWindow* sw = GetSplitterWindow();
long sp = sw->GetSashPosition();
wxListCtrl* lctl = GetListControl();
sw->Unsplit();
switch( m_CurrentView ) {
case cvPhysical:
HidePhysicalView();
break;
case cvVirtual:
HideVirtualView();
break;
default:
wxASSERT(false);
}
ShowSearchView();
sw->SplitVertically( m_SearchPanel, lctl );
sw->SetSashPosition( sp );
DeleteAllListControlItems();
nSearchFiles = 0;
sizeSearchFiles = 0;
UpdateStatusBar( nSearchFiles, sizeSearchFiles );
}
/*!
* wxEVT_UPDATE_UI event handler for ID_VIEW_SEARCH
*/
void CMainFrame::OnViewSearchUpdate( wxUpdateUIEvent& event )
{
event.Enable( CBaseDB::GetDatabase() != NULL );
if( m_CurrentView == cvSearch )
event.Check(true);
else
event.Check(false);
}
void CMainFrame::ShowPhysicalView(void) {
wxTreeCtrl* tctlPhysical = GetTreePhysicalControl();
tctlPhysical->Show( true );
m_CurrentView = cvPhysical;
CreateListControlHeaders();
ShowSelectedFolderFiles();
}
void CMainFrame::HidePhysicalView(void) {
StoreListControlPhysicalWidth();
wxTreeCtrl* tctlPhysical = GetTreePhysicalControl();
tctlPhysical->Show( false );
}
void CMainFrame::ShowVirtualView(void) {
wxTreeCtrl* tctlVirtual = GetTreeVirtualControl();
tctlVirtual->Show( true );
m_CurrentView = cvVirtual;
CreateListControlHeaders();
ShowSelectedVirtualFolderFiles();
}
void CMainFrame::HideVirtualView(void) {
StoreListControlVirtualWidth();
wxTreeCtrl* tctlVirtual = GetTreeVirtualControl();
tctlVirtual->Show( false );
}
void CMainFrame::ShowSearchView(void) {
m_SearchPanel->Show( true );
m_CurrentView = cvSearch;
CreateListControlHeaders();
// checks if there is a selected item in the tree controls and enables/disables the radio buttons
// physical...
wxTreeCtrl *tctl = GetTreePhysicalControl();
bool isFolderSelected = false; // true if the selected item is a volume
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
isFolderSelected = true;
}
}
m_SearchRadioBox->Enable( ssSelectedPhysicalFolder, isFolderSelected );
// virtual...
tctl = GetTreeVirtualControl();
isFolderSelected = false; // true if the selected item is a volume
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
isFolderSelected = true;
}
}
m_SearchRadioBox->Enable( ssSelectedVirtualFolder, isFolderSelected );
}
void CMainFrame::HideSearchView(void) {
m_SearchPanel->Show( false );
}
void CMainFrame::RefreshCurrentView(void) {
switch( m_CurrentView ) {
case cvPhysical:
ShowPhysicalView();
break;
case cvVirtual:
ShowVirtualView();
break;
case cvSearch:
ShowSearchView();
break;
}
}
void CMainFrame::OnButtonSearchClick( wxCommandEvent& WXUNUSED(event) ) {
wxString fileName = m_SearchFileName->GetValue();
wxString ext = m_SearchExtension->GetValue();
wxString description = m_SearchDescription->GetValue();
if( fileName.empty() && ext.empty() && description.empty() ) {
CUtils::MsgErr( _("Please enter some search data") );
return;
}
// decode the search strings
wxString whFileName = wxEmptyString;
wxString whExt = wxEmptyString;
wxString whDescription = wxEmptyString;
fileName = fileName.MakeUpper();
ext = ext.MakeUpper();
description = description.MakeUpper();
if( !fileName.IsEmpty() ) {
CDecodeSearchString ds( fileName );
if( ds.DecodeString() ) {
FilenameSearchKind searchKind = (FilenameSearchKind) m_FilenameRadioBox->GetSelection();
whFileName = ds.CreateWhereClause( wxT("FILE_NAME"), searchKind );
whFileName = wxT( "(" ) + whFileName + wxT( ")" );
}
else {
CUtils::MsgErr( _("Incorrect file name search data") );
return;
}
}
if( !ext.IsEmpty() ) {
CDecodeSearchString ds( ext );
if( ds.DecodeString() ) {
whExt = ds.CreateWhereClause( wxT("FILE_EXT"), fskIsEqual );
whExt = wxT( "(" ) + whExt + wxT( ")" );
}
else {
CUtils::MsgErr( _("Incorrect extension search data") );
return;
}
}
if( !description.IsEmpty() ) {
CDecodeSearchString ds( description );
if( ds.DecodeString() ) {
FilenameSearchKind searchKind = (FilenameSearchKind) m_DescriptionRadioBox->GetSelection();
whDescription = ds.CreateWhereClause( wxT("FILE_DESCRIPTION"), searchKind );
whDescription = wxT( "(" ) + whDescription + wxT( ")" );
}
else {
CUtils::MsgErr( _("Incorrect description search data") );
return;
}
}
CLongTaskBeep ltb;
// create the WHERE clause related to the search data
wxString wh = whFileName;
if( !wh.empty() && !whExt.IsEmpty() ) wh += wxT(" AND ");
wh += whExt;
if( !wh.empty() && !whDescription.IsEmpty() ) wh += wxT(" AND ");
wh += whDescription;
SearchScope scope = (SearchScope) m_SearchRadioBox->GetSelection();
wxBusyCursor wait;
wxListCtrl* lctl = GetListControl();
// assigns the image list
wxImageList* iml = new wxImageList( 16, 16 );
iml->Add(wxIcon(folder_closed_xpm));
iml->Add(wxIcon(deffile_xpm));
lctl->AssignImageList( iml, wxIMAGE_LIST_SMALL );
nSearchFiles = 0;
sizeSearchFiles = 0;
DeleteAllListControlItems();
lctl->Hide(); // to speed up things
bool foundAudioFiles = false;
switch( scope ) {
case ssAllPhysicalVolumes : {
CFiles files;
CNullableLong nl;
nl.SetNull(true);
files.DBStartSearchVolumeFilesSQL( nl, wh );
while( !files.IsEOF() ) {
if( !files.PathID.IsNull() ) {
// avoid rows that represent virtual folders created by the user
if( CAudioMetadata::IsAudioExtension(files.FileExt) ) {
foundAudioFiles = true;
}
AddRowToVirtualListControl( lctl, files.IsFolder(), files.FileName, files.FileSize, files.FileExt, files.DateTime, CPaths::GetFullPath(files.PathID), files.FileID, files.PathFileID.IsNull() ? 0 : (long) files.PathFileID, files.FileDescription, files.FileID );
nSearchFiles++;
sizeSearchFiles += files.FileSize;
}
files.DBNextRow();
}
if( !foundAudioFiles && m_CurrentlyShowingAudioMetadata )
DeleteAudioMetadataListControlHeaders();
break;
}
case ssSelectedPhysicalFolder: {
wxTreeCtrl *tctl = GetTreePhysicalControl();
wxASSERT( tctl->GetCount() > 0 );
wxTreeItemId item = tctl->GetSelection();
wxASSERT( item.IsOk() );
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
if( tctl->GetItemParent(item) == tctl->GetRootItem() ) {
// the user selected a volume
CFiles files;
files.DBStartSearchVolumeFilesSQL( itemData->GetVolumeID(), wh );
while( !files.IsEOF() ) {
if( CAudioMetadata::IsAudioExtension(files.FileExt) ) {
foundAudioFiles = true;
}
AddRowToVirtualListControl( lctl, files.IsFolder(), files.FileName, files.FileSize, files.FileExt, files.DateTime, CPaths::GetFullPath(files.PathID), files.FileID, files.PathFileID.IsNull() ? 0 : (long) files.PathFileID, files.FileDescription, files.FileID );
nSearchFiles++;
sizeSearchFiles += files.FileSize;
files.DBNextRow();
}
if( !foundAudioFiles && m_CurrentlyShowingAudioMetadata )
DeleteAudioMetadataListControlHeaders();
break;
}
else {
// the user selected a folder: recursion
CBaseDB::GetDatabase()->TransactionStart( true );
SearchPhysicalFolder( itemData->GetPathID(), itemData->GetVolumeID(), wh );
CBaseDB::GetDatabase()->TransactionCommit();
}
break;
}
case ssSelectedVirtualFolder: {
wxTreeCtrl *tctl = GetTreeVirtualControl();
wxASSERT( tctl->GetCount() > 0 );
wxTreeItemId item = tctl->GetSelection();
wxASSERT( item.IsOk() );
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
CBaseDB::GetDatabase()->TransactionStart( true );
SearchVirtualFolder( itemData->GetPathID(), wh );
CBaseDB::GetDatabase()->TransactionCommit();
break;
}
default:
wxASSERT( false );
break;
}
lctl->SortItems( ListControlCompareFunction, m_CurrentView == cvPhysical ? 0 : 1 );
lctl->Show();
if( lctl->GetItemCount() == 0 ) {
CUtils::MsgInfo( _("The search did not find anything") );
ltb.DoNotPlayBell();
}
UpdateStatusBar( nSearchFiles, sizeSearchFiles );
}
int CMainFrame::AddRowToVirtualListControl( wxListCtrl* lctl, bool isFolder, wxString fileName, wxLongLong fileSize, wxString ext, wxDateTime dateTime, wxString physicalPath, long fileID, long virtualPathFileID, wxString fileDescription, long physicalFileID ) {
wxString s;
CFilesAudioMetadata fam;
bool audioMetadataAvailable = false;
if( CAudioMetadata::IsAudioExtension(ext) ) {
fam.FileID = physicalFileID;
audioMetadataAvailable = fam.DBReadMetadata();
}
int imageIndex = (isFolder ? 0 : 1 );
wxListItem item;
item.SetId( 0 );
item.SetMask( wxLIST_MASK_STATE|wxLIST_MASK_TEXT|wxLIST_MASK_IMAGE|wxLIST_MASK_DATA );
int i = lctl->InsertItem( item );
lctl->SetItem( i, 0, fileName, imageIndex );
if( isFolder ) s = wxEmptyString; else s = CUtils::HumanReadableFileSize(fileSize);
lctl->SetItem( i, 1, s );
lctl->SetItem( i, 2, ext );
lctl->SetItem( i, 3, dateTime.FormatDate() + wxT(" ") + dateTime.FormatTime() );
lctl->SetItem( i, 4, physicalPath );
lctl->SetItem( i, 5, FormatObjectDescriptionForListView(fileDescription) );
MyListItemData *itemData = new MyListItemData( physicalFileID, fileID, virtualPathFileID, fileName, ext, fileSize, dateTime, isFolder, physicalPath, fileDescription );
lctl->SetItemData( i, (long) itemData );
if( audioMetadataAvailable ) {
if( !m_CurrentlyShowingAudioMetadata )
CreateAudioMetadataListControlHeaders();
AddAudioMetatataToListControl( fam, lctl, i, 6 );
itemData->AddAudioMetadata( fam );
}
if( physicalPath.empty() ) lctl->SetItemTextColour( i, *wxBLUE );
return i;
}
void CMainFrame::SearchVirtualFolder( long folderID, const wxString& wh ) {
// searches the current folder
CVirtualFiles files;
wxListCtrl* lctl = GetListControl();
bool foundAudioFiles = false;
files.DBStartSearchFolderFilesSQL( folderID, wh );
while( !files.IsEOF() ) {
if( CAudioMetadata::IsAudioExtension(files.FileExt) ) {
foundAudioFiles = true;
}
AddRowToVirtualListControl( lctl, files.IsFolder(), files.FileName, files.FileSize, files.FileExt, files.DateTime, files.FullPhysicalPath, files.FileID, files.VirtualPathFileID.IsNull() ? 0 : (long) files.VirtualPathFileID, files.FileDescription, files.PhysicalFileID );
nSearchFiles++;
sizeSearchFiles += files.FileSize;
files.DBNextRow();
}
if( !foundAudioFiles && m_CurrentlyShowingAudioMetadata )
DeleteAudioMetadataListControlHeaders();
// recursion in the subfolders
CVirtualPaths pth;
pth.DBStartQueryListPaths( folderID );
while( !pth.IsEOF() ) {
SearchVirtualFolder( pth.PathID, wh );
pth.DBNextRow();
}
}
void CMainFrame::SearchPhysicalFolder( long folderID, long volumeID, const wxString& wh ) {
// searches the current folder
CFiles files;
wxListCtrl* lctl = GetListControl();
bool foundAudioFiles = false;
files.DBStartSearchFolderFilesSQL( folderID, wh );
while( !files.IsEOF() ) {
if( CAudioMetadata::IsAudioExtension(files.FileExt) ) {
foundAudioFiles = true;
}
AddRowToVirtualListControl( lctl, files.IsFolder(), files.FileName, files.FileSize, files.FileExt, files.DateTime, CPaths::GetFullPath(files.PathID), files.FileID, files.PathFileID.IsNull() ? 0 : (long) files.PathFileID, files.FileDescription, files.FileID );
nSearchFiles++;
sizeSearchFiles += files.FileSize;
files.DBNextRow();
}
if( !foundAudioFiles && m_CurrentlyShowingAudioMetadata )
DeleteAudioMetadataListControlHeaders();
// recursion in the subfolders
CPaths pth;
pth.DBStartQueryListPaths( volumeID, folderID );
while( !pth.IsEOF() ) {
SearchPhysicalFolder( pth.PathID, volumeID, wh );
pth.DBNextRow();
}
}
/*!
* wxEVT_COMMAND_LIST_ITEM_ACTIVATED event handler for ID_LIST_CONTROL
*/
void CMainFrame::OnListControlItemActivated( wxListEvent& event )
{
if( m_CurrentView == cvSearch ) return;
int i = event.GetIndex();
wxListCtrl* lctl = GetListControl();
MyListItemData *itemData = (MyListItemData *) lctl->GetItemData( i );
if( !itemData->IsFolder() ) return;
long pathFileID = itemData->GetPathFileID();
if( pathFileID == 0 ) return;
wxTreeCtrl *tctl = NULL;
switch( m_CurrentView ) {
case cvPhysical:
tctl = GetTreePhysicalControl();
break;
case cvVirtual:
tctl = GetTreeVirtualControl();
break;
default:
wxASSERT( false );
}
// this is the selected item in the tree control
wxTreeItemId itemFather = tctl->GetSelection();
// looks for the child corresponding to the folder in the list view
wxTreeItemIdValue cookie;
wxTreeItemId itemChild = tctl->GetFirstChild( itemFather, cookie );
while( itemChild.IsOk() ) {
MyTreeItemData *tid = (MyTreeItemData *) tctl->GetItemData(itemChild);
if( tid->GetPathID() == pathFileID ) {
tctl->SelectItem( itemChild );
break;
}
itemChild = tctl->GetNextChild( itemFather, cookie );
}
}
void CMainFrame::UpdateStatusBar( long nObjects, wxLongLong sizeObjects ) {
if( nObjects == 0 )
m_StatusBar->SetStatusText( wxEmptyString, sbeObjectsNumber );
else {
wxString s = _("Objects: ") + CUtils::long2string( nObjects );
m_StatusBar->SetStatusText( s, sbeObjectsNumber );
}
if( sizeObjects == 0 )
m_StatusBar->SetStatusText( wxEmptyString, sbeObjectsSize );
else {
wxString s = _("Total size: ") + CUtils::HumanReadableFileSize( sizeObjects );
m_StatusBar->SetStatusText( s, sbeObjectsSize );
}
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_VIEW_STATUS_BAR
*/
void CMainFrame::OnViewStatusBarClick( wxCommandEvent& event )
{
if( event.IsChecked() )
GetStatusBar()->Show(true);
else {
GetStatusBar()->Show(false);
}
#ifdef __WXMSW__
SendSizeEvent();
#else
wxSize s = GetSize();
Fit();
SetSize(s);
#endif
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_UP_ONE_FOLDER
*/
void CMainFrame::OnUpOneFolderClick( wxCommandEvent& WXUNUSED(event) )
{
wxTreeCtrl *tctl = (m_CurrentView == cvPhysical) ? GetTreePhysicalControl() : GetTreeVirtualControl();
wxTreeItemId item = tctl->GetSelection();
tctl->SelectItem( tctl->GetItemParent(item) );
}
/*!
* wxEVT_UPDATE_UI event handler for ID_UP_ONE_FOLDER
*/
void CMainFrame::OnUpOneFolderUpdate( wxUpdateUIEvent& event )
{
if( CBaseDB::GetDatabase() == NULL || m_CurrentView == cvSearch ) {
event.Enable(false);
return;
}
bool hideElement = true;
wxTreeCtrl *tctl = m_CurrentView == cvPhysical ? GetTreePhysicalControl() : GetTreeVirtualControl();
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
if( tctl->GetItemParent(item) != tctl->GetRootItem() ) hideElement = false;
}
}
event.Enable( !hideElement );
}
/*!
* wxEVT_SET_FOCUS event handler for ID_LIST_CONTROL
*/
void CMainFrame::OnListControlSetFocus( wxFocusEvent& WXUNUSED(event) )
{
if( !m_PoppingUpContextMenu )
m_ListViewHasFocus = true;
}
/*!
* wxEVT_CONTEXT_MENU event handler for ID_LIST_CONTROL
*/
void CMainFrame::OnListControlContextMenu( wxContextMenuEvent& event )
{
bool virtualFilesSelected = false;
if( m_ListViewHasFocus && m_CurrentView == cvVirtual )
virtualFilesSelected = AreOnlyVirtualFilesSelected();
// if( m_CurrentView == cvVirtual && !virtualFilesSelected ) return;
if( GetListControl()->GetSelectedItemCount() <= 0 ) return;
wxPoint point = event.GetPosition();
// If from keyboard
if (point.x == -1 && point.y == -1) {
wxSize size = GetSize();
point.x = size.x / 2;
point.y = size.y / 2;
} else {
point = ScreenToClient(point);
}
wxMenu menu;
if( m_CurrentView == cvVirtual || m_CurrentView == cvSearch ) {
menu.Append( ID_VIEW_SHOW_IN_PHYSICAL, _("Show in physical view") );
if( virtualFilesSelected ) {
menu.Append( ID_EDIT_DELETE, _("Delete") );
}
}
if( m_CurrentView == cvPhysical || m_CurrentView == cvSearch ) {
menu.Append( ID_ADD_VIRTUAL_FOLDER, _("Add To Virtual Folder") );
}
menu.AppendSeparator();
menu.Append( ID_EDIT_OBJECT_DESCRIPTION, _("Object Information...") );
m_PoppingUpContextMenu = true;
PopupMenu( &menu, point );
m_PoppingUpContextMenu = false;
}
int CMainFrame::ColumnNumIfNoColumnsHidden( int inColNum ) {
int firstMetadataColumn = m_CurrentView == cvPhysical ? N_BASE_COLS_PHYSICAL : N_BASE_COLS_VIRTUAL;
if( inColNum < firstMetadataColumn ) return inColNum; // only metadata columns may be hidden
int k = firstMetadataColumn; // k is increased from visible column to visible column
int i = 0; // i points to the array of possible metadata columns
int retVal = inColNum;
while( k <= inColNum ) {
while( !m_amdColumnsToShow[i] ) {
retVal++;
i++;
}
k++;
i++;
}
return retVal;
}
/*!
* wxEVT_KILL_FOCUS event handler for ID_LIST_CONTROL
*/
void CMainFrame::OnListControlKillFocus( wxFocusEvent& WXUNUSED(event) )
{
if( !m_PoppingUpContextMenu )
m_ListViewHasFocus = false;
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_TOOLS_OPTIONS
*/
void CMainFrame::OnPreferencesClick( wxCommandEvent& WXUNUSED(event) )
{
CDialogSettings dlg( this );
dlg.SetAmdColumnsToShow( m_amdColumnsToShow );
dlg.SetReopenCatalog( m_reopenLastUsedCatalog );
dlg.SetConnectServer( DBConnectionData.connectToServer );
dlg.SetServerName( DBConnectionData.serverName );
dlg.SetUsername( DBConnectionData.userName );
dlg.SetPassword( DBConnectionData.password );
dlg.SetBeepTime( m_BeepTime );
dlg.SetCatalogAudioMetadata( m_CatalogAudioMetadata );
if( dlg.ShowModal() ) {
m_reopenLastUsedCatalog = dlg.GetReopenCatalog();
m_amdColumnsToShow = dlg.GetAmdColumnsToShow();
DBConnectionData.connectToServer = dlg.GetConnectServer();
DBConnectionData.serverName = dlg.GetServerName();
DBConnectionData.userName = dlg.GetUsername();
DBConnectionData.password = dlg.GetPassword();
m_BeepTime = dlg.GetBeepTime();
CLongTaskBeep::SetMinSecondsForBell( m_BeepTime );
m_CatalogAudioMetadata = dlg.GetCatalogAudioMetadata();
RefreshCurrentView(); // if the user changes the columns to show
}
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_HELP_CONTENTS
*/
void CMainFrame::OnHelpContentsClick( wxCommandEvent& WXUNUSED(event) )
{
wxGetApp().GetHelpController()->DisplayContents();
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_EDIT_RENAME
*/
void CMainFrame::OnEditRenameClick( wxCommandEvent& WXUNUSED(event) )
{
if( !IsEditRenameEnabled() ) return;
if( m_CurrentView == cvPhysical )
RenameSelectedVolume();
if( m_CurrentView == cvVirtual )
RenameSelectedVirtualFolder();
}
/*!
* wxEVT_UPDATE_UI event handler for ID_EDIT_RENAME
*/
void CMainFrame::OnEditRenameUpdate( wxUpdateUIEvent& event )
{
event.Enable( IsEditRenameEnabled() );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_EDIT_DELETE
*/
void CMainFrame::OnEditDeleteClick( wxCommandEvent& WXUNUSED(event) )
{
if( !IsEditDeleteEnabled() ) return;
if( m_ListViewHasFocus && m_CurrentView == cvVirtual )
DeleteSelectedVirtualFiles();
if( !m_ListViewHasFocus && m_CurrentView == cvPhysical )
DeleteSelectedVolume();
if( !m_ListViewHasFocus && m_CurrentView == cvVirtual )
DeleteSelectedVirtualFolder();
}
/*!
* wxEVT_UPDATE_UI event handler for ID_EDIT_DELETE
*/
void CMainFrame::OnEditDeleteUpdate( wxUpdateUIEvent& event )
{
event.Enable( IsEditDeleteEnabled() );
}
void CMainFrame::DeleteSelectedVirtualFolder() {
if( !CUtils::MsgAskNo( _("This command will delete the selected virtual folder, but it will not change the folders in the physical view.\n\nDo you really want to delete the selected virtual folder?") ) )
return;
wxTreeCtrl *tctl = GetTreeVirtualControl();
wxTreeItemId item = tctl->GetSelection();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
// deletes from the database
CVirtualPaths vp;
vp.PathID = itemData->GetPathID();
vp.DbDelete();
// deletes from the tree control
tctl->DeleteChildren(item);
GetListControl()->DeleteAllItems();
tctl->Delete(item);
CBaseDB::GetDatabase()->UpdateStatistics( CBaseDB::usVirtual );
}
void CMainFrame::DeleteSelectedVolume() {
wxTreeCtrl *tctl = GetTreePhysicalControl();
wxTreeItemId item = tctl->GetSelection();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
if( !CUtils::MsgAskNo( _("This command will delete this volume:\n\n") + tctl->GetItemText(item) + _("\n\nfrom the VVV catalog. It will not delete any file from your disk.\n\nDo you really want to delete this volume?") ) )
return;
CVolumes vol;
vol.VolumeID = itemData->GetVolumeID();
try {
vol.DbDelete();
}
catch( CDataErrorException& e ) {
if( e.GetErrorCause() == CDataErrorException::ecReferentialIntegrity ) {
CUtils::MsgErr( _("Unable to delete this volume: at least one of its files is used in the virtual view") );
return;
}
else
throw;
}
CBaseDB::GetDatabase()->UpdateStatistics( CBaseDB::usAll );
// removes the item from the tree control
GetListControl()->DeleteAllItems();
tctl->Delete(item);
}
void CMainFrame::RenameSelectedVolume() {
wxTreeCtrl *tctl = GetTreePhysicalControl();
wxTreeItemId item = tctl->GetSelection();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
wxString oldName = itemData->GetDesc();
// asks for the new volume name
wxTextEntryDialog ted( this, _("Enter the new volume name"), _("Rename volume"), oldName, wxOK | wxCANCEL );
if( ted.ShowModal() != wxID_OK ) return;
wxString newName = ted.GetValue();
if( newName == oldName || newName.empty() ) return;
// changes the volume name in the database
CVolumes vol( itemData->GetVolumeID() ); // loads the current data
vol.VolumeName = newName;
try {
vol.DbUpdate();
}
catch( CDataErrorException& e ) {
if( e.GetErrorCause() == CDataErrorException::ecUnique ) {
CUtils::MsgErr( _("The new volume name is already present in the database") );
return;
}
else
throw;
}
// changes the volume name in the tree control
tctl->SetItemText( item, CreateVolumeLabel(newName, itemData->GetObjectDescription()) );
itemData->SetDesc( newName );
}
void CMainFrame::RenameSelectedVirtualFolder() {
wxTreeCtrl *tctl = GetTreeVirtualControl();
wxTreeItemId item = tctl->GetSelection();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
wxString oldName = tctl->GetItemText(item);
// asks for the new volume name
wxTextEntryDialog ted( this, _("Enter the new folder name"), _("Rename virtual folder"), oldName, wxOK | wxCANCEL );
if( ted.ShowModal() != wxID_OK ) return;
wxString newName = ted.GetValue();
if( newName == oldName || newName.empty() ) return;
// changes the folder name in the database
try {
CVirtualPaths::Rename( itemData->GetPathID(), newName );
}
catch( CDataErrorException& e ) {
if( e.GetErrorCause() == CDataErrorException::ecUnique ) {
CUtils::MsgErr( _("The new folder name is already present in the database") );
return;
}
else
throw;
}
// changes the volume name in the tree control
tctl->SetItemText( item, newName );
}
bool CMainFrame::IsEditRenameEnabled() {
if( CBaseDB::GetDatabase() == NULL || m_ListViewHasFocus ) {
return false;
}
bool enableItem = false;
if( m_CurrentView == cvPhysical ) {
bool hideElement = false;
wxTreeCtrl *tctl = GetTreePhysicalControl();
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
if( tctl->GetItemParent(item) != tctl->GetRootItem() ) hideElement = true;
}
else {
hideElement = true;
}
}
else
hideElement = true;
enableItem = !hideElement;
}
if( m_CurrentView == cvVirtual ) {
bool isEnabled = true;
if( isEnabled ) {
wxTreeCtrl* tctl = GetTreeVirtualControl();
isEnabled = (tctl->GetCount() > 0);
if( isEnabled ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
if( itemData == NULL ) {
isEnabled = false;
}
else {
isEnabled = itemData->GetPhysPathID().IsNull();
}
}
else
isEnabled = false;
}
}
enableItem = isEnabled;
}
return enableItem;
}
bool CMainFrame::IsEditDeleteEnabled() {
if( CBaseDB::GetDatabase() == NULL ) {
return false;
}
bool enableItem = false;
if( m_ListViewHasFocus && m_CurrentView == cvVirtual ) {
enableItem = AreOnlyVirtualFilesSelected();
}
if( !m_ListViewHasFocus && m_CurrentView == cvPhysical ) {
bool hideElement = false;
wxTreeCtrl *tctl = GetTreePhysicalControl();
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
if( tctl->GetItemParent(item) != tctl->GetRootItem() ) hideElement = true;
}
else {
hideElement = true;
}
}
else
hideElement = true;
enableItem = !hideElement;
}
if( !m_ListViewHasFocus && m_CurrentView == cvVirtual ) {
bool isEnabled = true;
if( isEnabled ) {
wxTreeCtrl* tctl = GetTreeVirtualControl();
isEnabled = (tctl->GetCount() > 0);
if( isEnabled ) {
wxTreeItemId item = tctl->GetSelection();
isEnabled = item.IsOk();
}
}
enableItem = isEnabled;
}
return enableItem;
}
void CMainFrame::DeleteSelectedVirtualFiles() {
wxASSERT( m_ListViewHasFocus );
if( !CUtils::MsgAskNo( _("This command will delete the selected files from the virtual view, but it will not change the files in the physical view.\n\nDo you really want to delete the selected virtual files?") ) )
return;
// loops over all the selected items
wxListCtrl* lctl = GetListControl();
long item = -1;
for( ;; ) {
item = lctl->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
if( item == -1 ) break;
MyListItemData *itemData = (MyListItemData *) lctl->GetItemData( item );
wxASSERT( !itemData->IsFolder() );
CVirtualFiles vf;
vf.FileID = itemData->GetVirtualFileID();
vf.DbDelete();
delete itemData;
lctl->DeleteItem( item );
}
CBaseDB::GetDatabase()->UpdateStatistics( CBaseDB::usVirtual );
m_ListViewHasFocus = true; // make sure that the value is correct (it might have been lost showing the dialog)
}
bool CMainFrame::AreOnlyVirtualFilesSelected() {
if( !m_ListViewHasFocus ) return false;
if( !m_CurrentView == cvVirtual ) return false;
bool retVal = true;
long item = -1;
wxListCtrl* lctl = GetListControl();
for( ;; ) {
item = lctl->GetNextItem( item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
if( item == -1 ) break;
MyListItemData *itemData = (MyListItemData *) lctl->GetItemData( item );
retVal = !itemData->IsFolder();
if( !retVal ) break;
}
return retVal;
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_FILE_EXPORT
*/
void CMainFrame::OnFileExportClick( wxCommandEvent& WXUNUSED(event) )
{
long selectedVolume = -1, selectedPhysicalFolder = -1, selectedVirtualFolder = -1;
if( m_CurrentView == cvPhysical ) {
wxTreeCtrl *tctl = GetTreePhysicalControl();
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
// generic treecontrol bug: if nothing is selected the item looks ok but itemData is NULL
if( itemData != NULL ) {
if( tctl->GetItemParent(item) == tctl->GetRootItem() ) {
// we are on a volume
selectedVolume = itemData->GetVolumeID();
}
else {
// we are on a folder
selectedPhysicalFolder = itemData->GetPathID();
selectedVolume = itemData->GetVolumeID();
}
}
}
}
}
if( m_CurrentView == cvVirtual ) {
wxTreeCtrl* tctl = GetTreeVirtualControl();
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
if( itemData != NULL ) {
selectedVirtualFolder = itemData->GetPathID();
}
}
}
}
CDialogExportData dlg( this );
dlg.SetSelectedVolumeId( selectedVolume );
dlg.SetSelectedPhysicalFolderId( selectedPhysicalFolder );
dlg.SetSelectedVirtualFolderId( selectedVirtualFolder );
dlg.ShowModal();
}
/*!
* wxEVT_UPDATE_UI event handler for ID_FILE_EXPORT
*/
void CMainFrame::OnFileExportUpdate( wxUpdateUIEvent& event )
{
if( CBaseDB::GetDatabase() == NULL ) {
event.Enable(false);
return;
}
event.Enable( m_CurrentView != cvSearch );
}
wxString CMainFrame::RestoreDatabase( wxString caption, wxString backupName ) {
wxString databaseFile = wxEmptyString;
wxString serverName, userName, password;
if( !DBConnectionData.connectToServer ) {
// create a local file
wxString wildcard = _("VVV files (*.vvv)|*.vvv|All files (*.*)|*.*");
wxFileDialog fd( this, caption, wxGetApp().GetDefaultDataFolder(), wxEmptyString, wildcard, wxFD_SAVE );
if( fd.ShowModal() == wxID_OK )
databaseFile = fd.GetPath();
} else {
CDialogOpenCatalog dlg( this );
dlg.SetAction( wxT("N") );
dlg.SetShowBrowseButton( DBConnectionData.IsLocalhost() );
if( dlg.ShowModal() == wxID_OK )
databaseFile = dlg.GetCatalogName();
}
if ( databaseFile.empty() ) return wxEmptyString;
// add an extension if needed
{
wxFileName fn(databaseFile);
if( fn.GetExt().empty() )
databaseFile += wxT(".vvv");
}
// check if the database already exists
if( wxFileExists(databaseFile) ) {
CUtils::MsgErr( _("Unable to continue. You have choosen an existing file:\n\n") + databaseFile + _("\n\nYou must type the name of a non-existing file.") );
return wxEmptyString;
}
// check if we can create the database
wxFile f;
{
wxLogNull ln;
if( !f.Create(databaseFile) ) {
CUtils::MsgErr( _("Unable to continue: you have choosen a folder where you do not have the right to create a file.") );
return wxEmptyString;
}
}
f.Close();
wxRemoveFile(databaseFile);
wxBusyCursor wait;
// restore the database
DBConnectionData.GetConnectionData( serverName, userName, password );
CBaseDB::CreateFirebirdDatabaseOnDisk( serverName, userName, password, backupName, databaseFile );
// since under Windows the restore process creates an all-uppercase file name, rename it to the original name
#ifdef __WXMSW__
{
wxFileName fn(databaseFile);
wxString name = fn.GetFullName();
wxString path = fn.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
wxString ucDatabaseFile = path + name.Upper();
wxString tmpDatabaseFile = ucDatabaseFile + wxT("$$tmp$$");
if( wxFileExists(tmpDatabaseFile) )
wxRemoveFile( tmpDatabaseFile );
wxRenameFile( ucDatabaseFile, tmpDatabaseFile, false );
wxRenameFile( tmpDatabaseFile, databaseFile, false );
}
#endif
return databaseFile;
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_FILE_BACKUP
*/
void CMainFrame::OnFileBackupClick( wxCommandEvent& WXUNUSED(event) )
{
wxString backupFile = wxEmptyString;
wxString serverName, userName, password;
if( !DBConnectionData.connectToServer ) {
// create a local file
wxString wildcard = _("VVV backup files (*.vvvbk)|*.vvvbk|All files (*.*)|*.*");
wxFileDialog fd( this, _("Backup catalog"), wxGetApp().GetDefaultDataFolder(), wxEmptyString, wildcard, wxFD_SAVE );
if( fd.ShowModal() == wxID_OK )
backupFile = fd.GetPath();
} else {
CDialogOpenCatalog dlg( this );
dlg.SetAction( wxT("B") );
dlg.SetShowBrowseButton( DBConnectionData.IsLocalhost() );
if( dlg.ShowModal() == wxID_OK )
backupFile = dlg.GetCatalogName();
}
if ( backupFile.empty() ) return;
// add an extension if needed
{
wxFileName fn(backupFile);
if( fn.GetExt().empty() )
backupFile += wxT(".vvvbk");
}
// check if the file already exists
if( wxFileExists(backupFile) ) {
CUtils::MsgErr( _("Unable to continue. You have choosen an existing file:\n\n") + backupFile + _("\n\nYou must type the name of a non-existing file.") );
return;
}
// check if we can create the file
wxFile f;
{
wxLogNull ln;
if( !f.Create(backupFile) ) {
CUtils::MsgErr( _("Unable to continue: you have choosen a folder where you do not have the right to create a file.") );
return;
}
}
f.Close();
wxRemoveFile(backupFile);
wxBusyCursor wait;
wxYield();
// backup the database
DBConnectionData.GetConnectionData( serverName, userName, password );
CBaseDB::BackupFirebirdDatabase( serverName, userName, password, backupFile, CBaseDB::GetDatabase()->GetDatabaseName() );
CUtils::MsgInfo( _("Backup completed") );
}
/*!
* wxEVT_UPDATE_UI event handler for ID_FILE_BACKUP
*/
void CMainFrame::OnFileBackupUpdate( wxUpdateUIEvent& event )
{
event.Enable(CBaseDB::GetDatabase() != NULL);
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_FILE_RESTORE
*/
void CMainFrame::OnFileRestoreClick( wxCommandEvent& WXUNUSED(event) )
{
if( DBConnectionData.connectToServer && !DBConnectionData.IsLocalhost() ) {
CUtils::MsgErr( _("Unable to restore.\n\nYou are connecting to a database server on another computer. You must execute this command on the server to be able to restore a catalog.") );
return;
}
wxString backupFile, databaseFile;
wxString serverName, userName, password;
CDialogRestore dlg( this );
if( dlg.ShowModal() != wxID_OK ) return;
backupFile = dlg.GetBackupName();
databaseFile = dlg.GetCatalogName();
if( databaseFile.empty() ) {
CUtils::MsgErr( _("The catalog name is missing") );
return;
}
if( backupFile.empty() ) {
CUtils::MsgErr( _("The backup name is missing") );
return;
}
// add extensions as needed
{
wxFileName fn(backupFile);
if( fn.GetExt().empty() )
backupFile += wxT(".vvvbk");
}
{
wxFileName fn(databaseFile);
if( fn.GetExt().empty() )
databaseFile += wxT(".vvv");
}
// check if the database already exists
if( wxFileExists(databaseFile) ) {
CUtils::MsgErr( _("Unable to continue. You have choosen an existing catalog:\n\n") + databaseFile + _("\n\nYou must type the name of a non-existing file.") );
return;
}
// check if we can create the database
wxFile f;
{
wxLogNull ln;
if( !f.Create(databaseFile) ) {
CUtils::MsgErr( _("Unable to continue: you have choosen a folder where you do not have the right to create a file.") );
return;
}
}
f.Close();
wxRemoveFile(databaseFile);
wxBusyCursor wait;
wxYield();
DBConnectionData.GetConnectionData( serverName, userName, password );
CBaseDB::CreateFirebirdDatabaseOnDisk( serverName, userName, password, backupFile, databaseFile );
// since under Windows the restore process creates an all-uppercase file name, rename it to the original name
#ifdef __WXMSW__
{
wxFileName fn(databaseFile);
wxString name = fn.GetFullName();
wxString path = fn.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
wxString ucDatabaseFile = path + name.Upper();
wxString tmpDatabaseFile = ucDatabaseFile + wxT("$$tmp$$");
if( wxFileExists(tmpDatabaseFile) )
wxRemoveFile( tmpDatabaseFile );
wxRenameFile( ucDatabaseFile, tmpDatabaseFile, false );
wxRenameFile( tmpDatabaseFile, databaseFile, false );
}
#endif
CUtils::MsgInfo( _("Restore completed") );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_UPDATE_VOLUME
*/
void CMainFrame::OnUpdateVolumeClick( wxCommandEvent& WXUNUSED(event) )
{
wxTreeCtrl *tctl = GetTreePhysicalControl();
wxTreeItemId item = tctl->GetSelection();
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData(item);
if( !itemData->IsVolume() ) return;
wxString volumeName = itemData->GetDesc();
long volumeID = itemData->GetVolumeID();
CDialogUpdateVolume dialog( this );
dialog.SetCatalogAudioMetadata( m_CatalogAudioMetadata );
dialog.SetVolumeData( volumeName, volumeID );
if( dialog.ShowModal() == wxID_OK )
LoadTreeControl();
DeleteAllListControlItems();
}
/*!
* wxEVT_UPDATE_UI event handler for ID_UPDATE_VOLUME
*/
void CMainFrame::OnUpdateVolumeUpdate( wxUpdateUIEvent& event )
{
if( CBaseDB::GetDatabase() == NULL ) {
event.Enable( false );
return;
}
bool enableItem = false;
if( !m_ListViewHasFocus && m_CurrentView == cvPhysical ) {
bool hideElement = false;
wxTreeCtrl *tctl = GetTreePhysicalControl();
if( tctl->GetCount() > 0 ) {
wxTreeItemId item = tctl->GetSelection();
if( item.IsOk() ) {
if( tctl->GetItemParent(item) != tctl->GetRootItem() ) hideElement = true;
}
else {
hideElement = true;
}
}
else
hideElement = true;
enableItem = !hideElement;
}
event.Enable( enableItem );
}
void CMainFrame::CDBConnectionData::GetConnectionData( wxString& serverName, wxString& userName, wxString& password ) {
if( this->connectToServer ) {
serverName = this->serverName;
userName = this->userName;
password = this->password;
}
else {
// parameters for embedded server
serverName = wxEmptyString;
userName = wxT("SYSDBA");
password = wxT("masterkey");
}
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_VIEW_EXPAND
*/
void CMainFrame::OnViewExpandClick( wxCommandEvent& WXUNUSED(event) )
{
if( m_ListViewHasFocus) return;
wxTreeCtrl* tctl = NULL;
if( m_CurrentView == cvPhysical )
tctl = GetTreePhysicalControl();
if( m_CurrentView == cvVirtual )
tctl = GetTreeVirtualControl();
if( tctl == NULL ) return;
if( tctl->GetCount() == 0 ) return;
wxTreeItemId item = tctl->GetSelection();
if( !item.IsOk() ) return;
wxBusyCursor bc;
tctl->Freeze();
tctl->ExpandAllChildren( item );
tctl->Thaw();
}
/*!
* wxEVT_UPDATE_UI event handler for ID_VIEW_EXPAND
*/
void CMainFrame::OnViewExpandUpdate( wxUpdateUIEvent& event )
{
event.Enable( IsExpandCollapseEnabled() );
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_VIEW_COLLAPSE
*/
void CMainFrame::OnViewCollapseClick( wxCommandEvent& WXUNUSED(event) )
{
if( m_ListViewHasFocus) return;
wxTreeCtrl* tctl = NULL;
if( m_CurrentView == cvPhysical )
tctl = GetTreePhysicalControl();
if( m_CurrentView == cvVirtual )
tctl = GetTreeVirtualControl();
if( tctl == NULL ) return;
if( tctl->GetCount() == 0 ) return;
wxTreeItemId item = tctl->GetSelection();
if( !item.IsOk() ) return;
wxBusyCursor bc;
tctl->Freeze();
tctl->CollapseAllChildren( item );
tctl->Thaw();
}
/*!
* wxEVT_UPDATE_UI event handler for ID_VIEW_COLLAPSE
*/
void CMainFrame::OnViewCollapseUpdate( wxUpdateUIEvent& event )
{
event.Enable( IsExpandCollapseEnabled() );
}
bool CMainFrame::IsExpandCollapseEnabled() {
if( CBaseDB::GetDatabase() == NULL ) {
return false;
}
bool enableItem = false;
if( !m_ListViewHasFocus) {
wxTreeCtrl* tctl = NULL;
if( m_CurrentView == cvPhysical )
tctl = GetTreePhysicalControl();
if( m_CurrentView == cvVirtual )
tctl = GetTreeVirtualControl();
if( tctl != NULL ) {
enableItem = (tctl->GetCount() > 0);
if( enableItem ) {
wxTreeItemId item = tctl->GetSelection();
enableItem = item.IsOk();
}
}
}
return enableItem;
}
void CMainFrame::CreateMacToolbar()
{
const int bmpSize = 32; // size of the toolbar bitmaps
CMainFrame* itemFrame1 = this;
// this code is copied from the CreateControls() code. The only difference is that it uses larger toolbar
// to make them look better in the Mac version
m_ToolbarCtrl = CreateToolBar( wxTB_FLAT|wxTB_HORIZONTAL|wxTB_TEXT, ID_TOOLBAR1 );
m_ToolbarCtrl->SetToolBitmapSize(wxSize(bmpSize, bmpSize));
wxBitmap itemtool3Bitmap( CUtils::EnlargeBitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_new.xpm")), bmpSize, bmpSize) );
wxBitmap itemtool3BitmapDisabled;
m_ToolbarCtrl->AddTool(wxID_NEW, _("New"), itemtool3Bitmap, itemtool3BitmapDisabled, wxITEM_NORMAL, _("Create a new catalog"), wxEmptyString);
wxBitmap itemtool4Bitmap( CUtils::EnlargeBitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_open.xpm")), bmpSize, bmpSize) );
wxBitmap itemtool4BitmapDisabled;
m_ToolbarCtrl->AddTool(wxID_OPEN, _("Open"), itemtool4Bitmap, itemtool4BitmapDisabled, wxITEM_NORMAL, _("Open an existing catalog"), wxEmptyString);
wxBitmap itemtool5Bitmap( CUtils::EnlargeBitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_catalog.png")), bmpSize, bmpSize) );
wxBitmap itemtool5BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_CATALOG_VOLUME, _("Catalog"), itemtool5Bitmap, itemtool5BitmapDisabled, wxITEM_NORMAL, _("Catalog a new volume"), wxEmptyString);
wxBitmap itemtool6Bitmap( CUtils::EnlargeBitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_up.xpm")), bmpSize, bmpSize) );
wxBitmap itemtool6BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_UP_ONE_FOLDER, _("Up"), itemtool6Bitmap, itemtool6BitmapDisabled, wxITEM_NORMAL, _("Move up one level"), wxEmptyString);
m_ToolbarCtrl->AddSeparator();
wxBitmap itemtool8Bitmap( CUtils::EnlargeBitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_physical.xpm")), bmpSize, bmpSize) );
wxBitmap itemtool8BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_VIEW_PHYSICAL, _("Physical"), itemtool8Bitmap, itemtool8BitmapDisabled, wxITEM_RADIO, _("Show the physical view"), wxEmptyString);
wxBitmap itemtool9Bitmap( CUtils::EnlargeBitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_virtual.xpm")), bmpSize, bmpSize) );
wxBitmap itemtool9BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_VIEW_VIRTUAL, _("Virtual"), itemtool9Bitmap, itemtool9BitmapDisabled, wxITEM_RADIO, _("Show the virtual view"), wxEmptyString);
wxBitmap itemtool10Bitmap( CUtils::EnlargeBitmap(itemFrame1->GetBitmapResource(wxT("graphics/tlb_search.xpm")), bmpSize, bmpSize) );
wxBitmap itemtool10BitmapDisabled;
m_ToolbarCtrl->AddTool(ID_VIEW_SEARCH, _("Search"), itemtool10Bitmap, itemtool10BitmapDisabled, wxITEM_RADIO, _("Show the search view"), wxEmptyString);
m_ToolbarCtrl->Realize();
itemFrame1->SetToolBar(m_ToolbarCtrl);
}
/*!
* wxEVT_CLOSE_WINDOW event handler for ID_MAIN_FRAME
*/
void CMainFrame::OnCloseWindow( wxCloseEvent& event )
{
// empty the tree control (the default code is very slow so I need to do this manually)
m_treePhysicalCtl->Freeze();
m_treePhysicalCtl->DeleteAllItems();
m_treePhysicalCtl->Thaw();
m_treeVirtualCtl->Freeze();
m_treeVirtualCtl->DeleteAllItems();
m_treeVirtualCtl->Thaw();
event.Skip();
}
/*!
* wxEVT_COMMAND_MENU_SELECTED event handler for ID_VIEW_SHOW_IN_PHYSICAL
*/
void CMainFrame::OnViewShowInPhysicalViewClick( wxCommandEvent& event )
{
// get the physical path for this item
wxListCtrl *lctl = GetListControl();
int nSelectedObjects = lctl->GetSelectedItemCount();
wxASSERT( nSelectedObjects == 1 );
long item = -1;
item = lctl->GetNextItem( item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
MyListItemData *itemData = (MyListItemData *) lctl->GetItemData( item );
wxString physPath = itemData->GetFullPhysicalPath();
wxChar sep = wxFileName::GetPathSeparator();
if( itemData->IsFolder() ) {
if( !physPath.IsEmpty() ) {
physPath = physPath + sep;
}
physPath += itemData->GetName();
}
if( physPath.IsEmpty() ) return;
// switch to the physical view
wxSplitterWindow* sw = GetSplitterWindow();
long sp = sw->GetSashPosition();
sw->Unsplit();
switch( m_CurrentView ) {
case cvVirtual:
HideVirtualView();
break;
case cvSearch:
HideSearchView();
break;
default:
wxASSERT(false);
}
ShowPhysicalView();
sw->SplitVertically( GetTreePhysicalControl(), lctl );
sw->SetSashPosition( sp );
UpdateStatusBar( nPhysicalFiles, sizePhysicalFiles );
// move to the physical path
wxTreeCtrl* tctl = GetTreePhysicalControl();
wxTreeItemId fatherID = tctl->GetRootItem();
int i;
do {
// extract a path folder
wxString folderName;
i = physPath.Find( sep );
if( i == wxNOT_FOUND ) {
folderName = physPath;
}
else {
folderName = physPath.Left( i );
physPath = physPath.Mid( i + 1 );
}
// select that folder
wxTreeItemIdValue cookie;
wxTreeItemId childID = tctl->GetFirstChild( fatherID, cookie );
while( childID.IsOk() ) {
MyTreeItemData *itemData = (MyTreeItemData *) tctl->GetItemData( childID );
wxString treeFolderName = itemData->GetDesc();
if( treeFolderName == folderName ) {
// found! select this item
tctl->SelectItem( childID );
fatherID = childID;
break;
}
childID = tctl->GetNextChild( fatherID, cookie );
if( !childID.IsOk() )
return; // we did not find the folder
}
} while( i != wxNOT_FOUND );
}
/*!
* wxEVT_UPDATE_UI event handler for ID_VIEW_SHOW_IN_PHYSICAL
*/
void CMainFrame::OnViewShowInPhysicalViewUpdate( wxUpdateUIEvent& event )
{
bool enabled = false;
if( m_ListViewHasFocus && (m_CurrentView == cvVirtual || m_CurrentView == cvSearch) ) {
if( GetListControl()->GetSelectedItemCount() == 1 ) {
enabled = true;
}
}
event.Enable( enabled );
}