label.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:24k
- /*
- * ===========================================================================
- * PRODUCTION $Log: label.cpp,v $
- * PRODUCTION Revision 1000.0 2004/06/01 21:20:46 gouriano
- * PRODUCTION PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.4
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: label.cpp,v 1000.0 2004/06/01 21:20:46 gouriano Exp $
- * ===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Authors: Mike DiCuccio
- *
- * File Description:
- *
- */
- #include <ncbi_pch.hpp>
- #include <gui/objutils/label.hpp>
- #include <corelib/ncbimtx.hpp>
- #include <objects/seq/Bioseq.hpp>
- #include <objects/seq/Seq_annot.hpp>
- #include <objects/seq/Annot_descr.hpp>
- #include <objects/seq/Annotdesc.hpp>
- #include <objects/seqalign/Seq_align.hpp>
- #include <objects/seqalign/Dense_seg.hpp>
- #include <objects/seqfeat/Seq_feat.hpp>
- #include <objects/seqloc/Seq_id.hpp>
- #include <objects/seqloc/Seq_loc.hpp>
- #include <objects/seqloc/Seq_interval.hpp>
- #include <objects/seqloc/Seq_point.hpp>
- #include <objects/seqset/Seq_entry.hpp>
- #include <objects/seqset/Bioseq_set.hpp>
- #include <objmgr/util/sequence.hpp>
- #include <objmgr/util/feature.hpp>
- BEGIN_NCBI_SCOPE
- USING_SCOPE(objects);
- DEFINE_STATIC_MUTEX(sm_Mutex);
- CLabel::TLabelMap CLabel::sm_LabelMap;
- void CLabel::GetLabel(const CObject& obj, string* label,
- ELabelType type, CScope* scope)
- {
- if ( !label ) {
- return;
- }
- const CSerialObject* so = dynamic_cast<const CSerialObject*>(&obj);
- if (so) {
- TLabelMap::const_iterator iter =
- sm_LabelMap.find(so->GetThisTypeInfo()->GetName());
- if (iter != sm_LabelMap.end()) {
- iter->second->GetLabel(obj, label, type, scope);
- } else {
- *label = "CSerialObject";
- }
- } else {
- *label = "CObject";
- }
- }
- void CLabel::RegisterLabelHandler(const string& type,
- ILabelHandler& handler)
- {
- CMutexGuard LOCK(sm_Mutex);
- sm_LabelMap[type] = CRef<ILabelHandler>(&handler);
- }
- void CLabel::RegisterLabelHandler(const CTypeInfo& type,
- ILabelHandler& handler)
- {
- CMutexGuard LOCK(sm_Mutex);
- sm_LabelMap[type.GetName()] = CRef<ILabelHandler>(&handler);
- }
- //
- // label handlers
- //
- //
- // default format function for a seq-id
- // this is used by seq-id and seq-loc formatting
- //
- static inline
- void s_GetSeqLabel(const CSeq_id& id, string* label,
- CScope* scope, CLabel::ELabelType type)
- {
- const CSeq_id* id_ptr = &id;
- if (scope && id_ptr->IsGi() ) {
- CBioseq_Handle handle = scope->GetBioseqHandle(id);
- if (handle) {
- const CSeq_id& best_id =
- sequence::GetId(handle, sequence::eGetId_Best);
- id_ptr = &best_id;
- }
- }
- switch (type) {
- case CLabel::eType:
- id_ptr->GetLabel(label, CSeq_id::eType);
- break;
- default:
- case CLabel::eTooltipBrief:
- case CLabel::eContent:
- id_ptr->GetLabel(label, CSeq_id::eContent);
- break;
- case CLabel::eTooltipDetailed:
- case CLabel::eBoth:
- id_ptr->GetLabel(label, CSeq_id::eBoth);
- break;
- }
- }
- //
- // process a seq-interval
- //
- static inline
- void s_GetSeq_intervalLabel(const CSeq_interval& interval, string* label,
- CScope* scope, CLabel::ELabelType type,
- const CSeq_id* last_id = NULL)
- {
- if ( !last_id || !interval.GetId().Match(*last_id)) {
- if ( !label->empty() ) {
- *label += "; ";
- }
- s_GetSeqLabel(interval.GetId(), label, scope, type);
- *label += ": ";
- }
- *label += NStr::IntToString(interval.GetFrom());
- *label += "-";
- *label += NStr::IntToString(interval.GetTo());
- if (interval.IsSetStrand()) {
- switch (interval.GetStrand()) {
- case eNa_strand_plus:
- *label += " (+)";
- break;
- case eNa_strand_minus:
- *label += " (-)";
- break;
- default:
- *label += " (+)";
- break;
- }
- }
- }
- //
- // internal processing of seq-loc labels
- // seq-locs frequently refer to GIs only - we need to use sequence accessions
- // to make a more friendly label
- //
- static inline
- const CSeq_id* s_GetLabel(const CSeq_loc& loc, string* label,
- CScope* scope, CLabel::ELabelType type,
- const CSeq_id* last_id = NULL)
- {
- switch (loc.Which()) {
- case CSeq_loc::e_Whole:
- s_GetSeqLabel(loc.GetWhole(), label, scope, type);
- return &loc.GetWhole();
- case CSeq_loc::e_Int:
- s_GetSeq_intervalLabel(loc.GetInt(), label, scope, type, last_id);
- return &loc.GetInt().GetId();
- case CSeq_loc::e_Packed_int:
- {{
- CConstRef<CSeq_id> id(last_id);
- string str;
- ITERATE (CSeq_loc::TPacked_int::Tdata, iter,
- loc.GetPacked_int().Get()) {
- const CSeq_interval& ival = **iter;
- if ( !str.empty() ) {
- str += ", ";
- }
- s_GetSeq_intervalLabel(ival, &str, scope, type, id.GetPointer());
- id.Reset(&ival.GetId());
- }
- *label += str;
- return id.GetPointer();
- }}
- case CSeq_loc::e_Pnt:
- {{
- string str = NStr::IntToString(loc.GetPnt().GetPoint());
- if ( !last_id || !loc.GetPnt().GetId().Match(*last_id) ) {
- if ( !label->empty() ) {
- *label += "; ";
- }
- s_GetSeqLabel(loc.GetPnt().GetId(), label, scope, type);
- *label += ": ";
- } else if ( !label->empty() ) {
- *label += ", ";
- }
- *label += str;
- return &loc.GetPnt().GetId();
- }}
- case CSeq_loc::e_Packed_pnt:
- {{
- string str;
- ITERATE (CSeq_loc::TPacked_pnt::TPoints, iter,
- loc.GetPacked_pnt().GetPoints()) {
- if ( !str.empty() ) {
- str += ", ";
- }
- str += NStr::IntToString(*iter);
- }
- if ( !last_id || !loc.GetPnt().GetId().Match(*last_id) ) {
- if ( !label->empty() ) {
- *label += "; ";
- }
- s_GetSeqLabel(loc.GetPnt().GetId(), label, scope, type);
- *label += ": ";
- } else if ( !label->empty() ) {
- *label += ", ";
- }
- *label += str;
- return &loc.GetPnt().GetId();
- }}
- case CSeq_loc::e_Mix:
- {{
- string str;
- ITERATE (CSeq_loc::TMix::Tdata, iter, loc.GetMix().Get()) {
- if ( !str.empty() ) {
- str += ", ";
- }
- last_id = s_GetLabel(**iter, &str, scope, type, last_id);
- }
- *label += str;
- return last_id;
- }}
- default:
- loc.GetLabel(label);
- return NULL;
- }
- }
- //
- //
- // seq-id handler
- //
- //
- class CSeq_idHandler : public ILabelHandler
- {
- public:
- void GetLabel(const CObject& obj, string* label,
- CLabel::ELabelType type, CScope* scope) const
- {
- const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
- if (id) {
- s_GetSeqLabel(*id, label, scope, type);
- }
- }
- };
- //
- //
- // seq-loc handler
- //
- //
- class CSeq_locHandler : public ILabelHandler
- {
- public:
- void GetLabel(const CObject& obj, string* label,
- CLabel::ELabelType type, CScope* scope) const
- {
- const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
- if (loc) {
- s_GetLabel(*loc, label, scope, type);
- }
- }
- };
- //
- //
- // bioseq handler
- //
- //
- class CBioseqHandler : public ILabelHandler
- {
- public:
- void GetLabel(const CObject& obj, string* label,
- CLabel::ELabelType type, CScope* scope) const
- {
- const CBioseq* bioseq = dynamic_cast<const CBioseq*>(&obj);
- if (bioseq) {
- switch (type) {
- case CLabel::eType:
- bioseq->GetLabel(label, CBioseq::eType);
- break;
- case CLabel::eContent:
- bioseq->GetLabel(label, CBioseq::eContent);
- break;
- default:
- case CLabel::eTooltipBrief:
- case CLabel::eTooltipDetailed:
- case CLabel::eBoth:
- bioseq->GetLabel(label, CBioseq::eBoth);
- break;
- }
- }
- }
- };
- //
- //
- // Bioseq_set handler
- //
- //
- class CBioseq_setHandler : public ILabelHandler
- {
- public:
- void GetLabel(const CObject& obj, string* label,
- CLabel::ELabelType type, CScope* scope) const
- {
- const CBioseq_set* bioseq_set = dynamic_cast<const CBioseq_set*>(&obj);
- if (bioseq_set) {
- switch (type) {
- case CLabel::eType:
- bioseq_set->GetLabel(label, CBioseq_set::eType);
- break;
- case CLabel::eContent:
- bioseq_set->GetLabel(label, CBioseq_set::eContent);
- break;
- default:
- case CLabel::eTooltipBrief:
- case CLabel::eTooltipDetailed:
- case CLabel::eBoth:
- bioseq_set->GetLabel(label, CBioseq_set::eBoth);
- break;
- }
- }
- }
- };
- //
- //
- // seq-feat handler
- //
- //
- class CSeq_featHandler : public ILabelHandler
- {
- public:
- void GetLabel(const CObject& obj, string* label,
- CLabel::ELabelType type, CScope* scope) const
- {
- const CSeq_feat* feat = dynamic_cast<const CSeq_feat*>(&obj);
- if (feat) {
- switch (type) {
- case CLabel::eType:
- feature::GetLabel(*feat, label, feature::eType, scope);
- break;
- case CLabel::eContent:
- feature::GetLabel(*feat, label, feature::eContent, scope);
- break;
- default:
- case CLabel::eTooltipBrief:
- case CLabel::eTooltipDetailed:
- case CLabel::eBoth:
- feature::GetLabel(*feat, label, feature::eBoth, scope);
- break;
- }
- }
- }
- };
- //
- //
- // seq-entry handler
- //
- //
- class CSeq_entryHandler : public ILabelHandler
- {
- public:
- void GetLabel(const CObject& obj, string* label,
- CLabel::ELabelType type, CScope* scope) const
- {
- const CSeq_entry* entry = dynamic_cast<const CSeq_entry*>(&obj);
- if (entry) {
- if (entry->IsSet()) {
- CLabel::GetLabel(entry->GetSet(), label, type, scope);
- } else {
- CLabel::GetLabel(entry->GetSeq(), label, type, scope);
- }
- }
- }
- };
- //
- //
- // seq-annots are complicated
- //
- //
- static void s_GetAnnotType(const CSeq_annot& annot, string* label)
- {
- const CSeq_annot::TData& annot_data = annot.GetData();
- switch (annot_data.Which()) {
- case CSeq_annot::TData::e_Ftable:
- *label += "Feature Table";
- break;
- case CSeq_annot::TData::e_Align:
- *label += "Alignment";
- break;
- case CSeq_annot::TData::e_Graph:
- *label += "Graph";
- break;
- case CSeq_annot::TData::e_Ids:
- *label += "IDs";
- break;
- case CSeq_annot::TData::e_Locs:
- *label += "Locations";
- break;
- default:
- *label = "Annotation";
- return;
- }
- }
- static void s_GetAnnotContent(const CSeq_annot& annot, string* label)
- {
- //
- // check for formatted comments in descriptors first
- //
- if (annot.IsSetDesc()) {
- ITERATE (CSeq_annot::TDesc::Tdata, iter, annot.GetDesc().Get()) {
- switch ((*iter)->Which()) {
- case CAnnotdesc::e_Title:
- *label = (*iter)->GetTitle();
- return;
- default:
- break;
- }
- }
- }
- //
- // default handling
- //
- string str;
- size_t items = 0;
- const CSeq_annot::TData& annot_data = annot.GetData();
- switch (annot_data.Which()) {
- case CSeq_annot::TData::e_Ftable:
- str = "Feature Table, ";
- items = annot_data.GetFtable().size();
- break;
- case CSeq_annot::TData::e_Align:
- str = "Alignment, ";
- items = annot_data.GetAlign().size();
- break;
- case CSeq_annot::TData::e_Graph:
- str = "Graph, ";
- items = annot_data.GetGraph().size();
- break;
- case CSeq_annot::TData::e_Ids:
- str = "IDs, ";
- items = annot_data.GetIds().size();
- break;
- case CSeq_annot::TData::e_Locs:
- str = "Locations, ";
- items = annot_data.GetLocs().size();
- break;
- default:
- *label = "Annotation";
- return;
- }
- str += NStr::IntToString(items);
- if (items != 1) {
- str += " entries";
- } else {
- str += " entry";
- }
- *label += str;
- }
- class CSeq_annotHandler : public ILabelHandler
- {
- public:
- void GetLabel(const CObject& obj, string* label,
- CLabel::ELabelType type, CScope* scope) const
- {
- const CSeq_annot* annot = dynamic_cast<const CSeq_annot*> (&obj);
- if ( !annot ) {
- return;
- }
- switch (type) {
- case CLabel::eType:
- s_GetAnnotType(*annot, label);
- return;
- case CLabel::eContent:
- s_GetAnnotContent(*annot, label);
- return;
- case CLabel::eBoth:
- s_GetAnnotType(*annot, label);
- *label += ": ";
- s_GetAnnotContent(*annot, label);
- break;
- }
- }
- };
- static void s_GetAlignmentType(const CSeq_align& align, string* label)
- {
- switch (align.GetSegs().Which()) {
- default:
- case CSeq_align::TSegs::e_not_set:
- *label += "[Unknown]";
- break;
- case CSeq_align::TSegs::e_Denseg:
- *label += "[Dense-seg]";
- break;
- case CSeq_align::TSegs::e_Dendiag:
- *label += "[Dense-diag]";
- break;
- case CSeq_align::TSegs::e_Std:
- *label += "[Standard-seg]";
- break;
- case CSeq_align::TSegs::e_Packed:
- *label += "[Packed-seg]";
- break;
- case CSeq_align::TSegs::e_Disc:
- *label += "[Discontinuous]";
- break;
- }
- }
- static void s_GetAlignmentContent(const CSeq_align& align, string* label,
- CScope* scope)
- {
- switch (align.GetSegs().Which()) {
- default:
- case CSeq_align::TSegs::e_not_set:
- *label += "unknown contents";
- break;
- case CSeq_align::TSegs::e_Denseg:
- {{
- string str;
- size_t seqs = align.GetSegs().GetDenseg().GetIds().size();
- if (seqs < 4) {
- ITERATE (CDense_seg::TIds, iter,
- align.GetSegs().GetDenseg().GetIds()) {
- const CSeq_id* best_id = *iter;
- if (scope) {
- CBioseq_Handle handle =
- scope->GetBioseqHandle(**iter);
- if ( !handle ) {
- continue;
- }
- best_id = &sequence::GetId(handle,
- sequence::eGetId_Best);
- }
- if ( !str.empty() ) {
- str += " x ";
- }
- best_id->GetLabel(&str, CSeq_id::eContent);
- }
- } else {
- str = NStr::IntToString(seqs) + " sequences.";
- }
- *label += str;
- }}
- break;
- case CSeq_align::TSegs::e_Dendiag:
- *label += "[Dense-diag]";
- break;
- case CSeq_align::TSegs::e_Std:
- *label += "[Standard-seg]";
- break;
- case CSeq_align::TSegs::e_Packed:
- *label += "[Packed-seg]";
- break;
- case CSeq_align::TSegs::e_Disc:
- *label += "[Discontinuous]";
- break;
- }
- }
- class CSeq_alignHandler : public ILabelHandler
- {
- public:
- void GetLabel(const CObject& obj, string* label,
- CLabel::ELabelType type, CScope* scope) const
- {
- const CSeq_align* align = dynamic_cast<const CSeq_align*> (&obj);
- if ( !align ) {
- return;
- }
- switch (type) {
- case CLabel::eType:
- s_GetAlignmentType(*align, label);
- return;
- case CLabel::eContent:
- s_GetAlignmentContent(*align, label, scope);
- return;
- case CLabel::eBoth:
- s_GetAlignmentType(*align, label);
- *label += ' ';
- s_GetAlignmentContent(*align, label, scope);
- break;
- }
- }
- };
- #if 0
- // retrieve a string label for an abstract object
- string CSeqUtils::GetLabel(const CObject& obj, CScope* scope)
- {
- {{
- // standard seq-annot label formatting
- const CSeq_annot* annot = dynamic_cast<const CSeq_annot*> (&obj);
- if (annot) {
- const CSeq_annot::TData& annot_data = annot->GetData();
- string label;
- size_t items = 0;
- switch (annot_data.Which()) {
- case CSeq_annot::TData::e_Ftable:
- label = "Feature Table, ";
- items = annot_data.GetFtable().size();
- break;
- case CSeq_annot::TData::e_Align:
- label = "Alignment, ";
- items = annot_data.GetAlign().size();
- break;
- case CSeq_annot::TData::e_Graph:
- label = "Graph, ";
- items = annot_data.GetGraph().size();
- break;
- case CSeq_annot::TData::e_Ids:
- label = "IDs, ";
- items = annot_data.GetIds().size();
- break;
- case CSeq_annot::TData::e_Locs:
- label = "Locations, ";
- items = annot_data.GetLocs().size();
- break;
- default:
- return "Annotation";
- }
- label += NStr::IntToString(items);
- if (items != 1) {
- label += " entries";
- } else {
- label += " entry";
- }
- return label;
- }
- }}
- {{
- // standard seq-align label formatting
- const CSeq_align* align = dynamic_cast<const CSeq_align*> (&obj);
- if (align) {
- string label;
- switch (align->GetSegs().Which()) {
- case CSeq_align::TSegs::e_not_set:
- label = "Alignment: unknown type";
- break;
- case CSeq_align::TSegs::e_Denseg:
- {{
- size_t seqs = align->GetSegs().GetDenseg().GetIds().size();
- if (seqs < 4) {
- ITERATE (CDense_seg::TIds, iter,
- align->GetSegs().GetDenseg().GetIds()) {
- const CSeq_id* best_id = *iter;
- if (scope) {
- CBioseq_Handle handle =
- scope->GetBioseqHandle(**iter);
- if ( !handle ) {
- continue;
- }
- best_id =
- &sequence::GetId(handle,
- sequence::eGetId_Best);
- }
- if ( !label.empty() ) {
- label += " x ";
- }
- best_id->GetLabel(&label,
- CSeq_id::eContent);
- }
- label = "Alignment: " + label;
- } else {
- label = "Alignment: " +
- NStr::IntToString(seqs) +
- " sequences.";
- }
- }}
- break;
- case CSeq_align::TSegs::e_Dendiag:
- label = "Alignment: dense-diagonal";
- break;
- case CSeq_align::TSegs::e_Std:
- label = "Alignment: standard-seg";
- break;
- case CSeq_align::TSegs::e_Packed:
- label = "Alignment: packed-seg";
- break;
- case CSeq_align::TSegs::e_Disc:
- label = "Alignment: discontinuous";
- break;
- }
- return label;
- }
- }}
- {{
- // generic unhandled CSerialObject
- const CSerialObject* ser_obj =
- dynamic_cast<const CSerialObject*> (&obj);
- if (ser_obj) {
- return ser_obj->GetThisTypeInfo()->GetName();
- }
- }}
- /*{{ // should never be called that way: GetLabel(CLayoutObject obj);
- // layout objects
- const CLayoutObject* layout = dynamic_cast<const CLayoutObject*>(&obj);
- if (layout) {
- return GetLabel(layout->GetObject()), scope);
- }
- }}*/
- // generic object handling
- return ("Object");
- }
- #endif
- //
- // force registration at load
- //
- struct SForceRegister
- {
- SForceRegister()
- {
- CLabel::RegisterLabelHandler(*CSeq_id::GetTypeInfo(), *new CSeq_idHandler());
- CLabel::RegisterLabelHandler(*CSeq_loc::GetTypeInfo(), *new CSeq_locHandler());
- CLabel::RegisterLabelHandler(*CBioseq::GetTypeInfo(), *new CBioseqHandler());
- CLabel::RegisterLabelHandler(*CBioseq_set::GetTypeInfo(), *new CBioseq_setHandler());
- CLabel::RegisterLabelHandler(*CSeq_feat::GetTypeInfo(), *new CSeq_featHandler());
- CLabel::RegisterLabelHandler(*CSeq_entry::GetTypeInfo(), *new CSeq_entryHandler());
- CLabel::RegisterLabelHandler(*CSeq_annot::GetTypeInfo(), *new CSeq_annotHandler());
- CLabel::RegisterLabelHandler(*CSeq_align::GetTypeInfo(), *new CSeq_alignHandler());
- }
- };
- static SForceRegister sm_ForceRegistration;
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: label.cpp,v $
- * Revision 1000.0 2004/06/01 21:20:46 gouriano
- * PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.4
- *
- * Revision 1.4 2004/05/21 22:27:44 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.3 2004/05/14 14:23:15 dicuccio
- * When determining a label for a seq-id, only try to resolve GI-based seq-ids;
- * all others can be considered "good enough"
- *
- * Revision 1.2 2004/05/07 15:38:54 dicuccio
- * Fixed alignment labels lost in previous commit
- *
- * Revision 1.1 2004/04/30 11:48:16 dicuccio
- * Initial commit - split out from src/gui/utils
- *
- * Revision 1.1 2004/04/20 19:16:33 dicuccio
- * Initial revision
- *
- * ===========================================================================
- */