packageinfo.cpp

00001 
00002 // Name:        packageinfo.cpp
00003 // Purpose:     wxPackageInfo
00004 // Author:      Julian Smart, Francesco Montorsi, Daniel J. Lauk
00005 // Modified by:
00006 // Created:     2004-11-07
00007 // RCS-ID:      $Id: packageinfo.cpp,v 1.22 2007/02/01 11:03:51 frm Exp $
00008 // Copyright:   (c) Julian Smart
00009 // Licence:     wxWidgets licence
00011 
00012 
00013 // For compilers that support precompilation, includes "wx/wx.h".
00014 #include "wx/wxprec.h"
00015 
00016 #ifdef __BORLANDC__
00017 #pragma hdrstop
00018 #endif
00019 
00020 #ifndef WX_PRECOMP
00021     #include "wx/wx.h"
00022 #endif
00023 
00024 // includes
00025 #include <wx/fileconf.h>
00026 #include <wx/filename.h>
00027 #include <wx/zipstrm.h>
00028 #include <wx/wfstream.h>
00029 #include <wx/ptr_scpd.h>
00030 #include <wx/dir.h>
00031 
00032 #include "wxp/package.h"
00033 #include "wxp/wxp.h"
00034 
00035 // static objects
00036 wxPackageHTMLOutputFormatHashMap wxPackageInfo::s_hashmapHTMLFormats;
00037 wxStringHashMap wxPackageInfo::s_hashmapKeywords;
00038 
00039 // definitions
00040 
00041 wxString wxPackageCategoryName[] =
00042 {
00043     _("Application"),
00044     _("Control"),
00045     _("Dialog"),
00046     _("Database"),
00047     _("Data container"),
00048     _("Graphics"),
00049     _("Import-export"),
00050     _("Miscellaneous"),
00051     _("Networking"),
00052     _("Printing"),
00053     _("Stream"),
00054     _("System"),
00055     _("Text processing"),
00056     _("Tutorial-documentation"),
00057     _("Window container"),
00058     _("Window layout"),
00059     _("Wrapper"),
00060     _("XRC")
00061 };
00062 
00063 wxString wxPackageLicenseTypeName[] =
00064 {
00065     _T("Open Source"),
00066     _T("Commercial"),
00067     _T("Shareware"),
00068     _T("Freeware"),
00069     _T("Other")
00070 };
00071 
00072 wxString wxPackageBuildSystemTypeName[] =
00073 {
00074     _T("Bakefile"),
00075     _T("CMake"),
00076     _T("Scons"),
00077     _T("Makefile")
00078 };
00079 
00080 wxString wxPackageDevelopmentStatusName[] =
00081 {
00082     _T("Alpha"),
00083     _T("Beta"),
00084     _T("Stable")
00085 };
00086 
00087 wxString wxPackageProgLanguageName[] =
00088 {
00089     _T("C++"),
00090     _T("Lua"),
00091     _T("Python"),
00092     _T("Ruby"),
00093     _T("Perl")
00094 };
00095 
00096 wxString wxPackageCompressionModeName[] =
00097 {
00098     _T("zip"),
00099     _T("tar.gz")
00100 };
00101 
00102 wxString wxPackageExcludeModeName[] =
00103 {
00104     _("file"),
00105     _("directory"),
00106     _("pattern")
00107 };
00108 
00109 // RTTI
00110 IMPLEMENT_DYNAMIC_CLASS(wxPackageInfo, wxObject)
00111 
00112 
00113 
00114 // ----------------------------------------------------------------------------
00115 // string2enum helpers
00116 // ----------------------------------------------------------------------------
00117 
00118 wxIMPLEMENT_STRING2ENUM(PackageCategory, wxPC_MAX)
00119 wxIMPLEMENT_STRING2ENUM(PackageLicenseType, wxPLT_MAX)
00120 wxIMPLEMENT_STRING2ENUM(PackageDevelopmentStatus, wxPDS_MAX)
00121 wxIMPLEMENT_STRING2ENUM(PackageProgLanguage, wxPPL_MAX)
00122 wxIMPLEMENT_STRING2ENUM(PackageCompressionMode, wxPCM_MAX)
00123 wxIMPLEMENT_STRING2ENUM(PackageExcludeMode, wxPEM_MAX)
00124 
00125 
00126 // ----------------------------------------------------------------------------
00127 // wxPackageInfo
00128 // ----------------------------------------------------------------------------
00129 
00130 wxPackageInfo::wxPackageInfo()
00131 {
00132     m_nLicenseType = wxPLT_INVALID;
00133     m_buildSystemType = wxPBST_INVALID;
00134     m_devStatus = wxPDS_INVALID;
00135     m_language = wxPPL_INVALID;
00136     m_catPrimary = wxPC_INVALID;
00137     m_catSecondary = wxPC_INVALID;
00138     m_compressMode = wxPCM_INVALID;
00139 
00140     m_nSamples = 0;
00141     m_nCompressedSize = 0;
00142     m_nSupportedFormats = 0;
00143 }
00144 
00145 bool wxPackageInfo::IsOk() const
00146 {
00147     if (!wxPackageId::IsOk())
00148         return false;
00149 
00150     // VERY IMPORTANT: the size and MD5 data can be empty, if the package
00151     //                 has not been loaded from a WXL file. Thus don't check
00152     //                 those variables!
00153 
00154     // all data of the BASIC section must be non-empty
00155     if (m_strDescription.IsEmpty() || m_arrKeywords.GetCount() == 0 ||
00156         m_strWebsite.IsEmpty())
00157         return false;
00158     if (!m_creationDate.IsValid())
00159         return false;
00160     if (m_catPrimary == wxPC_INVALID || m_catSecondary == wxPC_INVALID)
00161         return false;
00162 
00163     // the root of the package should not be empty
00164     if (m_strRoot.IsEmpty())
00165         return false;
00166     if (m_compressMode == wxPCM_INVALID)
00167         return false;
00168     if (m_strFileName.IsEmpty())
00169         return false;
00170 
00171     // also the build system type must be a valid value!
00172     if (m_buildSystemType == wxPBST_INVALID)
00173         return false;
00174 
00175     // and we must support at least one format for our build system
00176     // and for the current platform!
00177     bool atleastone = false;
00178     for (size_t i=0; i<wxPCF_MAX; i++)
00179     {
00180         if (SupportsBuildSysFormat(wxIdx2PackageCompilerFormat(i)))
00181         {
00182             atleastone = true;
00183             break;
00184         }
00185     }
00186     if (!atleastone)
00187         return false;
00188 
00189     // NOTE: the following arrays may also be empty:
00190     //           m_arrDownloadHref, m_arrDocumentation, m_arrScreenshots,
00191     //           m_arrTestedPort, m_arrTestedVersion, m_arrDependencies;
00192     //       having them empty does not mean the package is invalid, but
00193     //       still other GUI parts of the project will give out warnings
00194     //       (not errors) about them.
00195 
00196     // no supported versions of ports is an error
00197     if (m_arrSupportedPort.GetCount() == 0 || 
00198         m_arrSupportedVersion.GetCount() == 0)
00199         return false;
00200 
00201     for (size_t j=0; j<m_arrSupportedPort.GetCount(); j++)
00202         if (m_arrSupportedPort[j] == wxPORT_UNKNOWN)
00203             return false;
00204     for (size_t j=0; j<m_arrTestedPort.GetCount(); j++)
00205         if (m_arrTestedPort[j] == wxPORT_UNKNOWN)
00206             return false;
00207 
00208     // all arrays of non POD objects must be valid, too
00209 
00210     for (size_t j=0; j<m_arrSupportedVersion.GetCount(); j++)
00211         if (!m_arrSupportedVersion[j].IsOk())
00212             return false;
00213     for (size_t j=0; j<m_arrTestedVersion.GetCount(); j++)
00214         if (!m_arrTestedVersion[j].IsOk())
00215             return false;
00216 
00217     if (!m_arrDependencies.IsOk())
00218         return false;
00219     if (!m_opt.IsOk())
00220         return false;
00221 
00222     // check command array
00223     for (size_t i=0; i < wxPBSS_MAX; i++)
00224     {
00225         if (!m_arrCommands[i].IsOk())
00226             return false;
00227 
00228         const wxPackageCommandArray &arr = m_arrCommands[i];
00229         for (size_t j=0; j < arr.GetCount(); j++)
00230             if (!arr[j].GetCondition().IsValidForStage(wxIdx2PackageBuildSystemStage(i)))
00231                 return false;
00232     }
00233 
00234     // a package can't list itself as dependency,
00235     // regardless of the version of the dependency !
00236     if (!m_arrDependencies.IsOk() ||
00237         m_arrDependencies.ContainsDependencyNamed(GetName()))
00238         return false;
00239 
00240     return true;
00241 }
00242 
00243 bool wxPackageInfo::SupportsWxPort(wxPortId p, const wxVersion &ver) const
00244 {
00245     for (size_t i=0; i<m_arrSupportedPort.GetCount(); i++)
00246     {
00247         if (m_arrSupportedPort[i] != p)
00248             continue;
00249 
00250         if (m_arrSupportedVersion[i].Contains(ver))
00251             return true;
00252     }
00253 
00254     return false;
00255 }
00256 
00257 void wxPackageInfo::AddBuildSysCommand(long stages, const wxPackageCommand &cmd)
00258 {
00259     // NB: it's important to preserve all stages supported by each command
00260     //     even when they are copied in m_arrCommands[i] as wxPackageCommandSet
00261     //     relies on that to recognize a command which belongs to a commandset
00262 
00263     for (size_t i=0; i<wxPBSS_MAX; i++)
00264         if (stages & wxIdx2PackageBuildSystemStage(i))
00265             m_arrCommands[i].Add(cmd);
00266 }
00267 
00268 void wxPackageInfo::AddBuildSysCommands(const wxPackageCommandArray &arr)
00269 {
00270     for (size_t i=0; i<arr.GetCount(); i++)
00271         AddBuildSysCommand(arr[i].GetCondition().GetStages(), arr[i]);
00272 }
00273 
00274 wxPackageCommandArray wxPackageInfo::GetSubstCmdForStage(
00275                 wxPackageBuildSystemStage stage,
00276                 long flags,
00277                 const wxPackageCondition &cond) const
00278 {
00279     const wxPackageCommandArray &original =
00280         m_arrCommands[wxPackageBuildSystemStage2Idx(stage)];
00281     
00282     wxPackageCommandArray ret;
00283     for (size_t i=0; i < original.GetCount(); i++)
00284     {
00285         const wxPackageCommand &cmd = original.GetSubstitutedCmd(i);
00286 
00287         // the GetCmd() internal utility may be overridden:
00288         ret.Add(GetCmd(cmd, stage, flags, cond));
00289     }
00290 
00291     // copy available targets and selected one:
00292     ret.CopyTargets(original);
00293 
00294     return ret;
00295 }
00296 
00297 wxPackageCommandOptionArray wxPackageInfo::GetSubstBuildSysOptions() const
00298 {
00299     const wxPackageCommandOptionArray &original = m_opt;
00300     
00301     wxPackageCommandOptionArray ret;
00302     for (size_t i=0; i < original.GetCount(); i++)
00303     {
00304         wxPackageCommandOption opt = original[i];
00305 
00306         // VERY IMPORTANT: do not touch the default-value, specially if it
00307         //                 contains $(keys) which could be substituted!
00308         // If we touched the default value in fact, then when changing the
00309         // selected compiler format in the build dialog, the command option
00310         // values could not be updated correctly!
00311         opt.SetValue(SubstituteInfo(opt.GetValue()));
00312 
00313         ret.Add(opt);
00314     }
00315 
00316     // copy the description:
00317     ret.SetDescription(original.GetDescription());
00318 
00319     return ret;
00320 }
00321 
00322 wxPackageCommand wxPackageInfo::GetCmd(const wxPackageCommand &cmd, 
00323                                        wxPackageBuildSystemStage stage,
00324                                        long flags,
00325                                        const wxPackageCondition &cond) const
00326 {
00327     // get command
00328     wxPackageCommand ret(cmd);
00329     wxString subst(ret.GetCommand());
00330 
00331     // build the hashmap for the substitutions
00332     // FIXME: maybe this should be cached
00333     wxStringHashMap hash;
00334 
00335     // do $(*option*) substitutions
00336     wxStringHashMap opthash = m_opt.GetSubstitutionOptionsHashMap(flags, cond);
00337     wxMergeHashMap(hash, opthash);
00338 
00339     // do also the special $(stageoptions) substitution, getting its
00340     // value from the hashmap itself:
00341     wxString stagename = wxPackageBuildSystemStage2String(stage).Lower();
00342     wxString value = hash[stagename + wxT("options")];
00343 
00344     // note that value maybe the empty string but nonetheless, if 
00345     // GetSubstitutionOptionsHashMap() worked correctly, the key should be in the
00346     // hashmap!
00347     wxASSERT_MSG(hash.find(stagename + wxT("options")) != hash.end(), 
00348                  wxT("The selected stage should have a key in the hashmap;")
00349                  wxT("at the very least with an empty value!"));
00350 
00351     hash[wxT("stageoptions")] = value;
00352 
00353     ret.SetCommand(wxDoStringSubstitution(subst, hash));
00354     return ret;
00355 }
00356 
00357 bool wxPackageInfo::SupportsBuildSysFormat(wxPackageCompilerFormat fmt) const
00358 {
00359     if (!wxIsCompilerFormatSupportedBy(fmt, GetBuildSystemType()))
00360         return false;
00361 
00362     if (!wxIsCompilerFormatSupportedByThisPlatform(fmt))
00363         return false;
00364 
00365     return (m_nSupportedFormats & fmt) != 0;
00366 }
00367 
00368 wxArrayString wxPackageInfo::GetUsedOptionPresets() const
00369 {
00370     wxArrayString arr;
00371 
00372     wxPackageCommandOptionArrayHashMap::iterator it;
00373     for( it = wxPresetXMLDescriptor::s_hashmapOptions.begin();
00374          it != wxPresetXMLDescriptor::s_hashmapOptions.end(); ++it )
00375     {
00376         wxString name = it->first;
00377         wxPackageCommandOptionArray &value = it->second;
00378 
00379         if (m_opt.Contains(value))
00380             arr.Add(name);
00381     }
00382 
00383     return arr;
00384 }
00385 
00386 wxString wxPackageInfo::GetUsedCommandPreset(wxStringHashMap &h) const
00387 {
00388     wxPackageCommandSetHashMap::const_iterator it;
00389     for( it = wxPresetXMLDescriptor::s_hashmapCommands.begin();
00390          it != wxPresetXMLDescriptor::s_hashmapCommands.end(); ++it )
00391     {
00392         wxString name = it->first;
00393         const wxPackageCommandSet &set = it->second;
00394 
00395         // multiple command presets for the same package are not supported!
00396         if (set.IsUsedBy(m_arrCommands, h))
00397             return name;
00398     }
00399 
00400     return wxEmptyString;
00401 }
00402 
00403 /* static */
00404 bool wxPackageInfo::LoadStandardOutputFormats(const wxString &path)
00405 {
00406     wxDir dir(path);
00407     if ( !dir.IsOpened() )
00408         return false;
00409 
00410     // each directory under given path is considered to contain an
00411     // 'output format': i.e. two files "details.html" and "summary.html"
00412     // which allow to format wxPackageInfo data.
00413     wxString dirname;
00414     bool cont = dir.GetFirst(&dirname, wxEmptyString, wxDIR_DIRS);
00415     while ( cont )
00416     {
00417         wxPackageHTMLOutputFormat fmt;
00418         if (fmt.Load(path + wxFileName::GetPathSeparator() + dirname))
00419             s_hashmapHTMLFormats[dirname] = fmt;
00420 
00421         cont = dir.GetNext(&dirname);
00422     }
00423 
00424     return !s_hashmapHTMLFormats.empty();
00425 }
00426 
00427 wxString wxPackageInfo::GetProjectFolder(const wxString &wxppath) const
00428 {
00429     wxFileName fn(wxppath);
00430     if (!fn.IsOk() || !fn.IsAbsolute())
00431         return wxEmptyString;     // invalid filename!
00432 
00433     // transform the relative root of the package
00434     const wxChar sep = wxFileName::GetPathSeparator();
00435     wxString relroot = GetRelativeRoot();
00436     relroot.Replace(wxT("/"), wxString(sep, 1));
00437 
00438     if (!relroot.StartsWith(wxT("..")))
00439         return wxEmptyString;     // invalid relative root!
00440 
00441     relroot.Remove(0, 2);
00442     if (relroot[0] == sep)
00443         relroot.Remove(0, 1);
00444 
00445     fn = wxFileName::DirName(fn.GetPath(wxPATH_GET_SEPARATOR) + relroot);
00446     fn.Normalize();
00447 
00448     // returns an absolute path
00449     return fn.GetPath();
00450 }
00451 
00452 wxString wxPackageInfo::GetDownloadLink() const
00453 {
00454     if (!m_strDownloadFromRepoHref.IsEmpty())
00455         return SubstituteInfo(m_strDownloadFromRepoHref);
00456 
00457     size_t n = m_arrDownloadHref.GetCount();
00458     if (n == 0)
00459         return wxEmptyString;
00460 
00461     // choose a random mirror:
00462     double idx = ((double)rand()) / RAND_MAX * n; 
00463     size_t realIdx = wxClip((size_t)idx, 0, n);
00464 
00465     return SubstituteInfo(m_arrDownloadHref[realIdx]);
00466 }
00467 
00468 
00469 
00470 // ----------------------------------------------------------------------------
00471 // wxPackageInfo::SubstituteInfo and global utilities for formatting arrays
00472 // ----------------------------------------------------------------------------
00473 
00474 wxString FormatStringArrayWithHref(const wxArrayString &arr, const wxArrayString &href)
00475 {
00476     wxString ret = wxT("<ul>");
00477     for (size_t i=0; i < arr.GetCount(); i++)
00478     {
00479         if (href[i] != wxEmptyString)
00480             ret += wxString::Format(wxT("<li><a href='%s'>%s</a></li>"),
00481                                         href[i].c_str(), arr[i].c_str());
00482         else
00483             ret += wxT("<li>") + arr[i] + wxT("</li>");
00484     }
00485 
00486     ret += wxT("</ul>");
00487     return ret;
00488 }
00489 
00490 wxString FormatStringArrayWithHref(const wxPackageDataWithRefArray &arr,
00491                                    wxPackageSubstituteInfoContext ctx)
00492 {
00493     wxString ret = wxT("<ul>");
00494     for (size_t i=0; i < arr.GetCount(); i++)
00495     {
00496         wxString ref;
00497         switch (ctx)
00498         {
00499             case wxPSIC_WXHTML:
00500                 // we can safely use the "best" reference since our output will
00501                 // be (presumably) fetched to a wxHtmlWindow
00502                 ref = arr[i].GetBestRef();
00503                 break;
00504 
00505             case wxPSIC_XHTML:
00506                 // we _must_ use the href because the "best" reference may include
00507                 // protocols such as "wxz:" or anchors like "#zip:" which are not XHTML-valid
00508                 ref = arr[i].GetHref();
00509                 break;
00510 
00511             default:
00512                 wxASSERT(0);
00513         }
00514 
00515         if (ref != wxEmptyString)
00516         {
00517             wxString text = arr[i].GetData();
00518             if (text.IsEmpty())
00519                 text = ref;
00520 
00521             if (!text.IsEmpty())
00522                 ret += wxString::Format(wxT("<li><a href='%s'>%s</a></li>"),
00523                                         ref.c_str(), text.c_str());
00524         }
00525         else if (!arr[i].GetData().IsEmpty())
00526             ret += wxT("<li>") + arr[i].GetData() + wxT("</li>");
00527         //else: skip this reference as it's invalid!
00528     }
00529 
00530     ret += wxT("</ul>");
00531     return ret;
00532 }
00533 
00534 wxString FormatPortListWithVersions(bool all_same, const wxArrayInt &ports,
00535                                     const wxVersionRangeArray &versions, wxString &htmlstr)
00536 {
00537     if (all_same)
00538     {
00539         // don't write the list of _all_ supported/tested ports...
00540         wxString ret = wxT("all ports, version(s) ") + versions[0].GetAsString();
00541         htmlstr = wxT("<ul><li>") + ret + wxT("</li></ul>");
00542         return ret;
00543     }
00544 
00545     wxString ret;
00546     htmlstr = wxT("<ul>");
00547     for (size_t i=0; i < ports.GetCount(); i++)
00548     {
00549         wxPortId port = (wxPortId)ports[i];
00550         wxString str = wxPlatformInfo::GetPortIdName(port, false) +
00551                             wxT(" ") + versions[i].GetAsString();
00552 
00553         ret += str + wxT(", ");
00554         htmlstr += wxT("<li>") + str + wxT("</li>");
00555     }
00556 
00557     htmlstr += wxT("</ul>");
00558     if (ret.IsEmpty())
00559         ret = wxT("None");
00560     else
00561         ret = ret.Left(ret.Len()-2);
00562 
00563     return ret;
00564 }
00565 
00566 wxString StringOrNone(const wxString &str)
00567 {
00568     if (str.IsEmpty() || str == wxT("<ul></ul>"))
00569         return wxT("None");
00570     return str;
00571 }
00572 
00573 wxString wxPackageInfo::SubstituteInfo(const wxString &str, wxPackageSubstituteInfoContext ctx) const
00574 {
00575     wxASSERT(ctx > wxPSIC_INVALID && ctx < wxPSIC_MAX);
00576 
00577     if (!IsCachedSubstitutionHashMapValid(ctx))
00578         wx_const_cast(wxPackageInfo*, this)->UpdateSubstitutionHashMap(ctx);
00579 
00580     // hopefully the substitution hashmap is up2date:
00581     // if it isn't it's a bug because somewhere the InvalidateCachedSubstHashMap()
00582     // has not been called
00583     return wxDoStringSubstitution(str, m_hashmapSubstitution[ctx]);
00584 }
00585 
00586 void wxPackageInfo::InvalidateCachedSubstHashMap(wxPackageSubstituteInfoContext ctx)
00587 { 
00588     if (ctx == wxPSIC_INVALID)
00589     {
00590         // invalidate all hashmaps:
00591         for (size_t i=0; i<wxPSIC_MAX; i++)
00592             m_hashmapSubstitution[i].clear();
00593     }
00594     else
00595         m_hashmapSubstitution[ctx].clear();
00596 }
00597 
00598 void wxPackageInfo::UpdateSubstitutionHashMap(wxPackageSubstituteInfoContext ctx)
00599 {
00600     if (ctx == wxPSIC_INVALID)
00601     {
00602         for (size_t i=0; i<wxPSIC_MAX; i++)
00603         {
00604             wxPackageSubstituteInfoContext ctx = (wxPackageSubstituteInfoContext)i;
00605 
00606             DoUpdateSubstitutionHashMap(ctx);
00607             wxNormalizeSubstitutionHashMap(m_hashmapSubstitution[ctx]);
00608         }
00609     }
00610     else
00611     {
00612         DoUpdateSubstitutionHashMap(ctx);
00613         wxNormalizeSubstitutionHashMap(m_hashmapSubstitution[ctx]);
00614     }
00615 }
00616 
00617 void wxPackageInfo::DoUpdateSubstitutionHashMap(wxPackageSubstituteInfoContext ctx)
00618 {
00619     wxASSERT(ctx > wxPSIC_INVALID && ctx < wxPSIC_MAX);
00620 
00621 
00622     // 1) create the strings with the data to substitute
00623 
00624     // format some HTML helpers
00625     wxString authors_html = FormatStringArrayWithHref(GetAuthors(), GetAuthorsHref());
00626     wxString maintainers_html = FormatStringArrayWithHref(GetMaintainers(), GetMaintainersHref());
00627     wxString download_html = FormatStringArrayWithHref(GetDownloadHref(), GetDownloadHref());
00628     wxString docs_html = FormatStringArrayWithHref(GetDocumentation(), ctx);
00629     wxString screenshots_html = FormatStringArrayWithHref(GetScreenshots(), ctx);
00630 
00631     // truncate the package description if too long
00632     wxString truncdesc = GetDescription();
00633     if (truncdesc.Len() > 255)
00634         truncdesc = truncdesc.Truncate(255) +
00635                         wxString::Format(wxT("... [more info in the <a href='%s'>")
00636                                          wxT("project website</a>]"), GetWebsite().c_str());
00637 
00638     // build the supported/tested port lists
00639     bool allsame_supported_ports =
00640         GetSupportedPortFlag() == wxGetFullPortIdList() && HasSameSupportedPortVersions();
00641     bool allsame_tested_ports =
00642         GetTestedPortFlag() == wxGetFullPortIdList() && HasSameTestedPortVersions();
00643 
00644     wxString wxsupported_html, wxtested_html;
00645 
00646     wxString wxsupported = FormatPortListWithVersions(allsame_supported_ports,
00647                                 GetSupportedPorts(), GetSupportedVersions(), wxsupported_html);
00648     wxString wxtested = FormatPortListWithVersions(allsame_tested_ports,
00649                                 GetTestedPorts(), GetTestedVersions(), wxtested_html);
00650 
00651     // build the external dependencies list (both as HTML list and plain list)
00652     wxString extdep, extdep_html;
00653     size_t max = GetDependencies().GetCount();
00654     extdep_html = wxT("<ul>");
00655     for (size_t j=0; j < max; j++)
00656     {
00657         wxPackageDependency dep(GetDependencies().Item(j));
00658         extdep_html += wxString::Format(wxT("<li><b><a href='%s'>%s</a></b> %s</li>"),
00659                                         dep.GetResolutionHref().c_str(),
00660                                         dep.GetName().c_str(),
00661                                         dep.GetVersion().GetAsString().c_str());
00662         extdep += dep.GetName().c_str() + dep.GetVersion().GetAsString() + wxT(", ");
00663     }
00664 
00665     extdep_html += wxT("</ul>");
00666     if (extdep.EndsWith(wxT(", ")))
00667         extdep = extdep.Left(extdep.Len()-2);
00668 
00669     // logo keyword:
00670     wxString logo;
00671     switch (ctx)
00672     {
00673         case wxPSIC_WXHTML:
00674             // we can safely use the "best" reference since our output will
00675             // be (presumably) fetched to a wxHtmlWindow
00676             logo = GetLogoRef().GetBestRef();
00677 
00678             // if the logo for this package is missing, use a default one
00679             if (logo.IsEmpty())
00680                 logo = wxT("memory:wxlogo.png");
00681             break;
00682 
00683         case wxPSIC_XHTML:
00684             // we _must_ use the href because the "best" reference may include
00685             // protocols such as "wxz:" or anchors like "#zip:" which are not XHTML-valid
00686             logo = GetLogoRef().GetHref();
00687 
00688             // if the logo for this package is missing, use a default one
00689             if (logo.IsEmpty())
00690                 logo = wxT("missing-logo.png");
00691             break;
00692 
00693         default:
00694             wxASSERT(0);
00695     }
00696 
00697     // build system option list
00698     wxString opts;
00699     max = GetBuildSysOptions().GetCount();
00700     for (size_t j=0; j < max; j++)
00701         opts += GetBuildSysOptions().Item(j).GetName() + wxT(", ");
00702     if (opts.EndsWith(wxT(", ")))
00703         opts = opts.Left(opts.Len()-2);
00704 
00705 
00706     // 2) add the data to substitute to the hashmap
00707 
00708     // clean the hashmap
00709     wxStringHashMap &keywords = m_hashmapSubstitution[ctx];
00710     keywords.clear();
00711 
00712 #define ADD_KEYWORD(name, value)   \
00713     keywords[wxT(name)] = value;
00714 
00715     // BASIC data
00716     ADD_KEYWORD("package", GetName());      // $(package) and $(name) are synonims
00717     ADD_KEYWORD("name", GetName());
00718     ADD_KEYWORD("version", GetVersion());
00719     ADD_KEYWORD("id", GetName() + wxT(" ") + GetVersion());
00720     ADD_KEYWORD("primarycat", GetPrimaryCategoryStr());
00721     ADD_KEYWORD("secondarycat", GetSecondaryCategoryStr());
00722     ADD_KEYWORD("keywords", StringOrNone(GetKeywordsStr()));
00723     ADD_KEYWORD("description", wxStripOutHTML(GetDescription()));
00724     ADD_KEYWORD("website", GetWebsite());
00725     ADD_KEYWORD("creation-date", GetCreationDate().FormatDate());
00726 
00727     // PACKAGING data
00728     ADD_KEYWORD("root", GetRelativeRoot());
00729     ADD_KEYWORD("compression", GetCompressionModeStr());
00730     ADD_KEYWORD("filename", GetOutputFileName());
00731     ADD_KEYWORD("upload", GetUploadDestination());
00732 
00733     // LICENSING data
00734     ADD_KEYWORD("license", GetLicenseRef().GetData());
00735     ADD_KEYWORD("licensetype", GetLicenseTypeStr());
00736     ADD_KEYWORD("organization", GetOrganization());
00737     ADD_KEYWORD("organization-href", GetOrganizationHref());
00738     ADD_KEYWORD("authors", StringOrNone(wxArray2String(GetAuthors(), wxT(", "))));
00739     ADD_KEYWORD("maintainers", StringOrNone(wxArray2String(GetMaintainers(), wxT(", "))));
00740     ADD_KEYWORD("cost", StringOrNone(GetCost()));
00741     ADD_KEYWORD("credits", GetCredits());
00742     ADD_KEYWORD("copyright", GetCopyright());
00743 
00744     // DETAILS data
00745     ADD_KEYWORD("status", GetDevelopmentStatusStr());
00746     ADD_KEYWORD("proglanguage", GetProgLanguageStr());
00747     ADD_KEYWORD("rss", StringOrNone(GetRSSHref()));
00748     ADD_KEYWORD("logo", logo);
00749     ADD_KEYWORD("numsamples", wxString::Format(wxT("%d"), GetNumberOfSamples()));
00750 
00751     // DEPENDENCIES data
00752     ADD_KEYWORD("wxsupported", wxsupported);
00753     ADD_KEYWORD("wxtested", wxtested);
00754     ADD_KEYWORD("dependencies", StringOrNone(extdep));
00755 
00756     // BUILD SYSTEM data
00757     ADD_KEYWORD("buildsystemtype", GetBuildSystemTypeStr());
00758     ADD_KEYWORD("buildoptions", opts);
00759 
00760 
00761     // HTML-specific keywords:
00762 
00763     // BASIC keywords
00764 
00765     ADD_KEYWORD("description-html", GetDescription());
00766     ADD_KEYWORD("trunc-description-html", truncdesc);
00767 
00768     // LICENSING keywords
00769 
00770     ADD_KEYWORD("authors-html", StringOrNone(authors_html));
00771     ADD_KEYWORD("maintainers-html", StringOrNone(maintainers_html));
00772     ADD_KEYWORD("wxsupported-html", StringOrNone(wxsupported_html));
00773     ADD_KEYWORD("wxtested-html", StringOrNone(wxtested_html));
00774 
00775     // DETAILS keywords
00776 
00777     ADD_KEYWORD("downloads-html", StringOrNone(download_html));
00778     ADD_KEYWORD("documentation-html", StringOrNone(docs_html));
00779     ADD_KEYWORD("screenshots-html", StringOrNone(screenshots_html));
00780     ADD_KEYWORD("dependencies-html", StringOrNone(extdep_html));
00781 
00782 
00783     // add to the hashmap all the standard substitutions:
00784     wxMergeHashMap(keywords, GetStandardSubstitutionHashMap());
00785 }
00786 
00787 /* static */
00788 wxStringHashMap wxPackageInfo::GetStandardSubstitutionHashMap()
00789 {
00790     // copy the s_hashmapKeywords hashmap
00791     wxStringHashMap ret(s_hashmapKeywords);
00792 
00793     // add some standard things:
00794     ret[wxT("dollar")] = wxT("$");
00795     ret[wxT("dirsep")] = wxString(wxFileName::GetPathSeparator());
00796 
00797     return ret;
00798 }
00799 

Generated on Thu Feb 1 22:14:31 2007 for wxWidgets Package Manager by  doxygen 1.5.1-p1