This keyword is not expanded by Git which means it's not replaced with the correct revision value in the releases made using git-based scripts and it's confusing to have lines with unexpanded "$Id$" in the released files. As expanding them with Git is not that simple (it could be done with git archive and export-subst attribute) and there are not many benefits in having them in the first place, just remove all these lines. If nothing else, this will make an eventual transition to Git simpler. Closes #14487. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
463 lines
13 KiB
C++
463 lines
13 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/common/artprov.cpp
|
|
// Purpose: wxArtProvider class
|
|
// Author: Vaclav Slavik
|
|
// Modified by:
|
|
// Created: 18/03/2002
|
|
// Copyright: (c) Vaclav Slavik
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// headers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#if defined(__BORLANDC__)
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#include "wx/artprov.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/list.h"
|
|
#include "wx/log.h"
|
|
#include "wx/hashmap.h"
|
|
#include "wx/image.h"
|
|
#include "wx/module.h"
|
|
#endif
|
|
|
|
// ===========================================================================
|
|
// implementation
|
|
// ===========================================================================
|
|
|
|
#include "wx/listimpl.cpp"
|
|
WX_DECLARE_LIST(wxArtProvider, wxArtProvidersList);
|
|
WX_DEFINE_LIST(wxArtProvidersList)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Cache class - stores already requested bitmaps
|
|
// ----------------------------------------------------------------------------
|
|
|
|
WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxBitmap, wxArtProviderBitmapsHash);
|
|
WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxIconBundle, wxArtProviderIconBundlesHash);
|
|
|
|
class WXDLLEXPORT wxArtProviderCache
|
|
{
|
|
public:
|
|
bool GetBitmap(const wxString& full_id, wxBitmap* bmp);
|
|
void PutBitmap(const wxString& full_id, const wxBitmap& bmp)
|
|
{ m_bitmapsHash[full_id] = bmp; }
|
|
|
|
bool GetIconBundle(const wxString& full_id, wxIconBundle* bmp);
|
|
void PutIconBundle(const wxString& full_id, const wxIconBundle& iconbundle)
|
|
{ m_iconBundlesHash[full_id] = iconbundle; }
|
|
|
|
void Clear();
|
|
|
|
static wxString ConstructHashID(const wxArtID& id,
|
|
const wxArtClient& client,
|
|
const wxSize& size);
|
|
|
|
static wxString ConstructHashID(const wxArtID& id,
|
|
const wxArtClient& client);
|
|
|
|
private:
|
|
wxArtProviderBitmapsHash m_bitmapsHash; // cache of wxBitmaps
|
|
wxArtProviderIconBundlesHash m_iconBundlesHash; // cache of wxIconBundles
|
|
};
|
|
|
|
bool wxArtProviderCache::GetBitmap(const wxString& full_id, wxBitmap* bmp)
|
|
{
|
|
wxArtProviderBitmapsHash::iterator entry = m_bitmapsHash.find(full_id);
|
|
if ( entry == m_bitmapsHash.end() )
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
*bmp = entry->second;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool wxArtProviderCache::GetIconBundle(const wxString& full_id, wxIconBundle* bmp)
|
|
{
|
|
wxArtProviderIconBundlesHash::iterator entry = m_iconBundlesHash.find(full_id);
|
|
if ( entry == m_iconBundlesHash.end() )
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
*bmp = entry->second;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void wxArtProviderCache::Clear()
|
|
{
|
|
m_bitmapsHash.clear();
|
|
m_iconBundlesHash.clear();
|
|
}
|
|
|
|
/* static */ wxString
|
|
wxArtProviderCache::ConstructHashID(const wxArtID& id,
|
|
const wxArtClient& client)
|
|
{
|
|
return id + wxT('-') + client;
|
|
}
|
|
|
|
|
|
/* static */ wxString
|
|
wxArtProviderCache::ConstructHashID(const wxArtID& id,
|
|
const wxArtClient& client,
|
|
const wxSize& size)
|
|
{
|
|
return ConstructHashID(id, client) + wxT('-') +
|
|
wxString::Format(wxT("%d-%d"), size.x, size.y);
|
|
}
|
|
|
|
// ============================================================================
|
|
// wxArtProvider class
|
|
// ============================================================================
|
|
|
|
IMPLEMENT_ABSTRACT_CLASS(wxArtProvider, wxObject)
|
|
|
|
wxArtProvidersList *wxArtProvider::sm_providers = NULL;
|
|
wxArtProviderCache *wxArtProvider::sm_cache = NULL;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxArtProvider ctors/dtor
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxArtProvider::~wxArtProvider()
|
|
{
|
|
Remove(this);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxArtProvider operations on provider stack
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*static*/ void wxArtProvider::CommonAddingProvider()
|
|
{
|
|
if ( !sm_providers )
|
|
{
|
|
sm_providers = new wxArtProvidersList;
|
|
sm_cache = new wxArtProviderCache;
|
|
}
|
|
|
|
sm_cache->Clear();
|
|
}
|
|
|
|
/*static*/ void wxArtProvider::Push(wxArtProvider *provider)
|
|
{
|
|
CommonAddingProvider();
|
|
sm_providers->Insert(provider);
|
|
}
|
|
|
|
/*static*/ void wxArtProvider::PushBack(wxArtProvider *provider)
|
|
{
|
|
CommonAddingProvider();
|
|
sm_providers->Append(provider);
|
|
}
|
|
|
|
/*static*/ bool wxArtProvider::Pop()
|
|
{
|
|
wxCHECK_MSG( sm_providers, false, wxT("no wxArtProvider exists") );
|
|
wxCHECK_MSG( !sm_providers->empty(), false, wxT("wxArtProviders stack is empty") );
|
|
|
|
delete sm_providers->GetFirst()->GetData();
|
|
sm_cache->Clear();
|
|
return true;
|
|
}
|
|
|
|
/*static*/ bool wxArtProvider::Remove(wxArtProvider *provider)
|
|
{
|
|
wxCHECK_MSG( sm_providers, false, wxT("no wxArtProvider exists") );
|
|
|
|
if ( sm_providers->DeleteObject(provider) )
|
|
{
|
|
sm_cache->Clear();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*static*/ bool wxArtProvider::Delete(wxArtProvider *provider)
|
|
{
|
|
// provider will remove itself from the stack in its dtor
|
|
delete provider;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*static*/ void wxArtProvider::CleanUpProviders()
|
|
{
|
|
if ( sm_providers )
|
|
{
|
|
while ( !sm_providers->empty() )
|
|
delete *sm_providers->begin();
|
|
|
|
wxDELETE(sm_providers);
|
|
wxDELETE(sm_cache);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxArtProvider: retrieving bitmaps/icons
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*static*/ wxBitmap wxArtProvider::GetBitmap(const wxArtID& id,
|
|
const wxArtClient& client,
|
|
const wxSize& size)
|
|
{
|
|
// safety-check against writing client,id,size instead of id,client,size:
|
|
wxASSERT_MSG( client.Last() == wxT('C'), wxT("invalid 'client' parameter") );
|
|
|
|
wxCHECK_MSG( sm_providers, wxNullBitmap, wxT("no wxArtProvider exists") );
|
|
|
|
wxString hashId = wxArtProviderCache::ConstructHashID(id, client, size);
|
|
|
|
wxBitmap bmp;
|
|
if ( !sm_cache->GetBitmap(hashId, &bmp) )
|
|
{
|
|
for (wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst();
|
|
node; node = node->GetNext())
|
|
{
|
|
bmp = node->GetData()->CreateBitmap(id, client, size);
|
|
if ( bmp.IsOk() )
|
|
break;
|
|
}
|
|
|
|
wxSize sizeNeeded = size;
|
|
if ( !bmp.IsOk() )
|
|
{
|
|
// no bitmap created -- as a fallback, try if we can find desired
|
|
// icon in a bundle
|
|
wxIconBundle iconBundle = DoGetIconBundle(id, client);
|
|
if ( iconBundle.IsOk() )
|
|
{
|
|
if ( sizeNeeded == wxDefaultSize )
|
|
sizeNeeded = GetNativeSizeHint(client);
|
|
|
|
wxIcon icon(iconBundle.GetIcon(sizeNeeded));
|
|
if ( icon.IsOk() )
|
|
{
|
|
// this icon may be not of the correct size, it will be
|
|
// rescaled below in such case
|
|
bmp.CopyFromIcon(icon);
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we didn't get the correct size, resize the bitmap
|
|
#if wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB)
|
|
if ( bmp.IsOk() && sizeNeeded != wxDefaultSize )
|
|
{
|
|
if ( bmp.GetSize() != sizeNeeded )
|
|
{
|
|
wxImage img = bmp.ConvertToImage();
|
|
img.Rescale(sizeNeeded.x, sizeNeeded.y);
|
|
bmp = wxBitmap(img);
|
|
}
|
|
}
|
|
#endif // wxUSE_IMAGE
|
|
|
|
sm_cache->PutBitmap(hashId, bmp);
|
|
}
|
|
|
|
return bmp;
|
|
}
|
|
|
|
/*static*/
|
|
wxIconBundle wxArtProvider::GetIconBundle(const wxArtID& id, const wxArtClient& client)
|
|
{
|
|
wxIconBundle iconbundle(DoGetIconBundle(id, client));
|
|
|
|
if ( iconbundle.IsOk() )
|
|
{
|
|
return iconbundle;
|
|
}
|
|
else
|
|
{
|
|
// fall back to single-icon bundle
|
|
return wxIconBundle(GetIcon(id, client));
|
|
}
|
|
}
|
|
|
|
/*static*/
|
|
wxIconBundle wxArtProvider::DoGetIconBundle(const wxArtID& id, const wxArtClient& client)
|
|
{
|
|
// safety-check against writing client,id,size instead of id,client,size:
|
|
wxASSERT_MSG( client.Last() == wxT('C'), wxT("invalid 'client' parameter") );
|
|
|
|
wxCHECK_MSG( sm_providers, wxNullIconBundle, wxT("no wxArtProvider exists") );
|
|
|
|
wxString hashId = wxArtProviderCache::ConstructHashID(id, client);
|
|
|
|
wxIconBundle iconbundle;
|
|
if ( !sm_cache->GetIconBundle(hashId, &iconbundle) )
|
|
{
|
|
for (wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst();
|
|
node; node = node->GetNext())
|
|
{
|
|
iconbundle = node->GetData()->CreateIconBundle(id, client);
|
|
if ( iconbundle.IsOk() )
|
|
break;
|
|
}
|
|
|
|
sm_cache->PutIconBundle(hashId, iconbundle);
|
|
}
|
|
|
|
return iconbundle;
|
|
}
|
|
|
|
/*static*/ wxIcon wxArtProvider::GetIcon(const wxArtID& id,
|
|
const wxArtClient& client,
|
|
const wxSize& size)
|
|
{
|
|
wxBitmap bmp = GetBitmap(id, client, size);
|
|
|
|
if ( !bmp.IsOk() )
|
|
return wxNullIcon;
|
|
|
|
wxIcon icon;
|
|
icon.CopyFromBitmap(bmp);
|
|
return icon;
|
|
}
|
|
|
|
/* static */
|
|
wxArtID wxArtProvider::GetMessageBoxIconId(int flags)
|
|
{
|
|
switch ( flags & wxICON_MASK )
|
|
{
|
|
default:
|
|
wxFAIL_MSG(wxT("incorrect message box icon flags"));
|
|
// fall through
|
|
|
|
case wxICON_ERROR:
|
|
return wxART_ERROR;
|
|
|
|
case wxICON_INFORMATION:
|
|
return wxART_INFORMATION;
|
|
|
|
case wxICON_WARNING:
|
|
return wxART_WARNING;
|
|
|
|
case wxICON_QUESTION:
|
|
return wxART_QUESTION;
|
|
}
|
|
}
|
|
|
|
/*static*/ wxSize wxArtProvider::GetSizeHint(const wxArtClient& client,
|
|
bool platform_dependent)
|
|
{
|
|
if (!platform_dependent)
|
|
{
|
|
wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst();
|
|
if (node)
|
|
return node->GetData()->DoGetSizeHint(client);
|
|
}
|
|
|
|
return GetNativeSizeHint(client);
|
|
}
|
|
|
|
#ifndef wxHAS_NATIVE_ART_PROVIDER_IMPL
|
|
/*static*/
|
|
wxSize wxArtProvider::GetNativeSizeHint(const wxArtClient& WXUNUSED(client))
|
|
{
|
|
// rather than returning some arbitrary value that doesn't make much
|
|
// sense (as 2.8 used to do), tell the caller that we don't have a clue:
|
|
return wxDefaultSize;
|
|
}
|
|
|
|
/*static*/
|
|
void wxArtProvider::InitNativeProvider()
|
|
{
|
|
}
|
|
#endif // !wxHAS_NATIVE_ART_PROVIDER_IMPL
|
|
|
|
|
|
/* static */
|
|
bool wxArtProvider::HasNativeProvider()
|
|
{
|
|
#ifdef __WXGTK20__
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// deprecated wxArtProvider methods
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#if WXWIN_COMPATIBILITY_2_6
|
|
|
|
/* static */ void wxArtProvider::PushProvider(wxArtProvider *provider)
|
|
{
|
|
Push(provider);
|
|
}
|
|
|
|
/* static */ void wxArtProvider::InsertProvider(wxArtProvider *provider)
|
|
{
|
|
PushBack(provider);
|
|
}
|
|
|
|
/* static */ bool wxArtProvider::PopProvider()
|
|
{
|
|
return Pop();
|
|
}
|
|
|
|
/* static */ bool wxArtProvider::RemoveProvider(wxArtProvider *provider)
|
|
{
|
|
// RemoveProvider() used to delete the provider being removed so this is
|
|
// not a typo, we must call Delete() and not Remove() here
|
|
return Delete(provider);
|
|
}
|
|
|
|
#endif // WXWIN_COMPATIBILITY_2_6
|
|
|
|
#if WXWIN_COMPATIBILITY_2_8
|
|
/* static */ void wxArtProvider::Insert(wxArtProvider *provider)
|
|
{
|
|
PushBack(provider);
|
|
}
|
|
#endif // WXWIN_COMPATIBILITY_2_8
|
|
|
|
// ============================================================================
|
|
// wxArtProviderModule
|
|
// ============================================================================
|
|
|
|
class wxArtProviderModule: public wxModule
|
|
{
|
|
public:
|
|
bool OnInit()
|
|
{
|
|
// The order here is such that the native provider will be used first
|
|
// and the standard one last as all these default providers add
|
|
// themselves to the bottom of the stack.
|
|
wxArtProvider::InitNativeProvider();
|
|
#if wxUSE_ARTPROVIDER_TANGO
|
|
wxArtProvider::InitTangoProvider();
|
|
#endif // wxUSE_ARTPROVIDER_TANGO
|
|
#if wxUSE_ARTPROVIDER_STD
|
|
wxArtProvider::InitStdProvider();
|
|
#endif // wxUSE_ARTPROVIDER_STD
|
|
return true;
|
|
}
|
|
void OnExit()
|
|
{
|
|
wxArtProvider::CleanUpProviders();
|
|
}
|
|
|
|
DECLARE_DYNAMIC_CLASS(wxArtProviderModule)
|
|
};
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxArtProviderModule, wxModule)
|