00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <ncbi_pch.hpp>
00033
00034 #include <gui/widgets/object_list/object_text.hpp>
00035
00036 #include <gui/widgets/text_widget/plain_text_item.hpp>
00037 #include <gui/widgets/text_widget/composite_text_item.hpp>
00038 #include <gui/widgets/text_widget/selection_helper.hpp>
00039 #include <gui/widgets/wx/simple_clipboard.hpp>
00040
00041 #include <gui/objutils/label.hpp>
00042
00043 #include <objects/seqalign/Seq_align.hpp>
00044 #include <objects/seqfeat/Seq_feat.hpp>
00045 #include <objects/seqloc/Seq_loc.hpp>
00046 #include <objects/general/Object_id.hpp>
00047 #include <objects/general/User_object.hpp>
00048 #include <objects/general/User_field.hpp>
00049
00050 #include <connect/ncbi_conn_stream.hpp>
00051
00052 #include <objects/seqalign/Seq_align_set.hpp>
00053 #include <objects/seqalign/Dense_seg.hpp>
00054 #include <objects/seqalign/Std_seg.hpp>
00055
00056 #include <serial/iterator.hpp>
00057 #include <objmgr/util/sequence.hpp>
00058 #include <objmgr/util/feature.hpp>
00059 #include <objtools/format/flat_file_config.hpp>
00060 #include <objtools/format/flat_file_generator.hpp>
00061
00062 #include <wx/sstream.h>
00063 #include <wx/txtstrm.h>
00064
00065
00066 BEGIN_NCBI_SCOPE
00067 USING_SCOPE(objects);
00068
00069 class CSelectableMainGroup : public CCompositeTextItem
00070 {
00071 DECLARE_EVENT_TABLE()
00072 public:
00073
00074 virtual void FillContextMenu( wxMenu& menu ) const;
00075
00076 void OnMenuCommand( wxCommandEvent& event );
00077 void OnMenuCommandUpdateUI( wxUpdateUIEvent& event );
00078 };
00079
00080 BEGIN_EVENT_TABLE( CSelectableMainGroup, CCompositeTextItem )
00081 EVT_MENU( wxID_COPY, CSelectableMainGroup::OnMenuCommand )
00082 EVT_UPDATE_UI( wxID_COPY, CSelectableMainGroup::OnMenuCommandUpdateUI )
00083 END_EVENT_TABLE()
00084
00085
00086 class CSelectableObjectItem : public CCompositeTextItem
00087 {
00088 DECLARE_EVENT_TABLE()
00089
00090 public:
00091 CSelectableObjectItem( const CObject* object ) : m_Object( object ) {
00092 }
00093
00094 virtual const CConstRef<CObject> GetAssosiatedObject() const { return m_Object; }
00095 virtual int GetTextOffset( CTextPanelContext* context ) const;
00096
00097 virtual void FillContextMenu( wxMenu& menu ) const;
00098
00099 protected:
00100 void OnCopy( wxCommandEvent& event );
00101 void OnCopyUpdateUI( wxUpdateUIEvent& event );
00102
00103 private:
00104 CConstRef<CObject> m_Object;
00105 };
00106
00107 BEGIN_EVENT_TABLE( CSelectableObjectItem, CCompositeTextItem )
00108 EVT_MENU( wxID_COPY, CSelectableObjectItem::OnCopy )
00109 EVT_UPDATE_UI( wxID_COPY, CSelectableObjectItem::OnCopyUpdateUI )
00110
00111 END_EVENT_TABLE()
00112
00113 void CSelectableMainGroup::FillContextMenu( wxMenu& menu ) const
00114 {
00115 menu.Append( wxID_COPY, _T("&Copy") );
00116 }
00117
00118 void CSelectableMainGroup::OnMenuCommand( wxCommandEvent& event )
00119 {
00120 if( event.GetId() == wxID_COPY ){
00121 CTextItemPanel* panel = static_cast<CTextItemPanel*>( event.GetEventObject() );
00122 CTextPanelContext* context = panel->GetContext();
00123 if( panel->IsTextSelected() ){
00124 CTextBlock block = panel->GetTextSelection().Normalized();
00125
00126 wxStringOutputStream stream;
00127 wxTextOutputStream os( stream );
00128 GetText( os, block, context );
00129
00130 CSimpleClipboard::Instance().Set( stream.GetString() );
00131 }
00132 }
00133 }
00134
00135 void CSelectableMainGroup::OnMenuCommandUpdateUI( wxUpdateUIEvent& event )
00136 {
00137 if( event.GetId() == wxID_COPY ){
00138 CTextItemPanel* panel = (CTextItemPanel*)event.GetEventObject();
00139 event.Enable( panel->IsTextSelected() );
00140 }
00141 }
00142
00143
00144 int CSelectableObjectItem::GetTextOffset( CTextPanelContext* context ) const
00145 {
00146 return
00147 CCompositeTextItem::GetTextOffset( context )
00148 + context->GetLeftMargin()
00149 ;
00150 }
00151
00152 void CSelectableObjectItem::FillContextMenu( wxMenu& menu ) const
00153 {
00154 menu.Append( wxID_COPY, _T("&Copy") );
00155 }
00156
00157 void CSelectableObjectItem::OnCopy( wxCommandEvent& event )
00158 {
00159 CTextItemPanel* panel = static_cast<CTextItemPanel*>( event.GetEventObject() );
00160 CTextPanelContext* context = panel->GetContext();
00161 if( panel->IsTextSelected() ){
00162 CTextBlock block = panel->GetTextSelection().Normalized();
00163
00164 wxStringOutputStream stream;
00165 wxTextOutputStream os( stream );
00166 GetText( os, block, context );
00167
00168 CSimpleClipboard::Instance().Set( stream.GetString() );
00169 }
00170 }
00171
00172 void CSelectableObjectItem::OnCopyUpdateUI( wxUpdateUIEvent& event )
00173 {
00174 CTextItemPanel* panel = (CTextItemPanel*)event.GetEventObject();
00175 event.Enable( panel->IsTextSelected() );
00176 }
00177
00178
00179
00180 CObjectTextWidget::CObjectTextWidget()
00181 : CTextItemPanel()
00182 , m_Brief( false )
00183 , m_Scope( NULL )
00184 {
00185 }
00186
00187 CObjectTextWidget::CObjectTextWidget(
00188 wxWindow* parent,
00189 wxWindowID id,
00190 const wxPoint& pos,
00191 const wxSize& size
00192 )
00193 : CTextItemPanel( parent, id, pos, size )
00194 , m_Brief( false )
00195 , m_Scope( NULL )
00196 {
00197 SetBackgroundColour( wxColor(_T("white")) );
00198
00199
00200 int pointSize = 8;
00201 wxFontFamily fontFamily = wxFONTFAMILY_MODERN;
00202 SetFont(wxFont(pointSize, fontFamily, wxNORMAL, wxNORMAL));
00203 }
00204
00205 void CObjectTextWidget::Init( TConstScopedObjects& objects, bool brief )
00206 {
00207 m_Objects = objects;
00208 m_Brief = brief;
00209
00210 if( objects.size() > 0 ){
00211 m_Scope = objects[0].scope;
00212 }
00213
00214 vector<ITextItem*> items;
00215
00216 x_GenerateTextItemsFromObjects( items );
00217
00218 SetData( new CSelectableMainGroup(), new CTextPanelContext(2) );
00219 AddItems( items );
00220 }
00221
00222 void CObjectTextWidget::GetSelection( TConstScopedObjects& objects )
00223 {
00224 vector< CConstRef<CObject> > objs;
00225
00226 GetContext()->GetSelectedObjects( objs );
00227
00228 for( int i = 0; i < (int)objs.size(); ++i ){
00229 const CObject* obj = objs[i];
00230 objects.push_back( SConstScopedObject(*obj, *m_Scope) );
00231 }
00232 }
00233
00234
00235
00236
00237 void CObjectTextWidget::x_GenerateTextItemsFromObjects( vector<ITextItem*>& items )
00238 {
00239 int obj_num = m_Objects.size();
00240
00241 for( int i = 0; i < obj_num; i++ ){
00242 if( i > 0 ){
00243 CPlainTextItem* item = new CPlainTextItem();
00244 item->AddLine( " " );
00245 items.push_back( item );
00246 }
00247
00248 SConstScopedObject& obj = m_Objects[i];
00249
00250 x_GetItems_Object( *obj.object, obj.scope, items );
00251 }
00252 }
00253
00254 static void s_GetItems_PairwiseAlign(
00255 const CSeq_align& align, CScope* scope, vector<ITextItem*>& items
00256 ){
00257 string text;
00258
00259 switch( align.GetSegs().Which() ){
00260 case CSeq_align::TSegs::e_Denseg:
00261 break;
00262
00263 case CSeq_align::TSegs::e_Std:
00264 break;
00265
00266 case CSeq_align::TSegs::e_Disc:
00267 {{
00268
00269
00270 ITERATE( CSeq_align::TSegs::TDisc::Tdata, iter, align.GetSegs().GetDisc().Get() ){
00271 }
00272 }}
00273 break;
00274
00275 default:
00276 CLabel::GetLabel( align, &text, CLabel::eDescription, scope );
00277 break;
00278 }
00279
00280 CPlainTextItem* item = new CPlainTextItem();
00281 item->AddLine( text );
00282 items.push_back( item );
00283 }
00284
00285
00286 static void s_GetItems_GenericAlign(
00287 const CSeq_align& align, CScope* scope, vector<ITextItem*>& items
00288 ){
00289 string text;
00290 CLabel::GetLabel( align, &text, CLabel::eDescription, scope );
00291
00292 CPlainTextItem* item = new CPlainTextItem();
00293 item->AddLine( text );
00294 items.push_back( item );
00295 }
00296
00297
00298 static void s_GetItems_Align(
00299 const CSeq_align& align, CScope* scope, vector<ITextItem*>& items
00300 ){
00301 string preamble;
00302 string ids;
00303
00304 set<CSeq_id_Handle> id_set;
00305 CTypeConstIterator<CSeq_id> id_iter( align );
00306 for( ; id_iter; ++id_iter ){
00307 CSeq_id_Handle idh = CSeq_id_Handle::GetHandle( *id_iter );
00308 if( id_set.insert(idh).second ){
00309 if( !ids.empty() ){
00310 ids += " x ";
00311 }
00312
00313 if( scope ){
00314 idh = sequence::GetId( idh, *scope, sequence::eGetId_Best );
00315 }
00316 idh.GetSeqId()->GetLabel( &ids );
00317 }
00318 }
00319
00320 string text;
00321
00322 text = "Alignment: " + ids;
00323 CPlainTextItem* item = new CPlainTextItem();
00324 item->AddLine( text );
00325 items.push_back( item );
00326
00327 if( id_set.size() == 2 ){
00328 s_GetItems_PairwiseAlign( align, scope, items );
00329 } else {
00330 s_GetItems_GenericAlign(align, scope, items );
00331 }
00332 }
00333
00334
00335 static void s_AccListToItem(const CUser_field::TData::TStrs& item_data,
00336 const string& title,
00337 CPlainTextItem* item)
00338 {
00339 string s(title);
00340 if ( !s.empty() ) {
00341 s += ": ";
00342 }
00343
00344 list<string> refseq;
00345 list<string> non_refseq;
00346 ITERATE (CUser_field::TData::TStrs, it, item_data) {
00347 CSeq_id::EAccessionInfo info = CSeq_id::IdentifyAccession(*it);
00348 if ((info & CSeq_id::eAcc_type_mask) == CSeq_id::e_Other) {
00349 refseq.push_back(*it);
00350 } else {
00351 non_refseq.push_back(*it);
00352 }
00353 }
00354
00355 string accs;
00356 if (refseq.size()) {
00357 accs += NStr::Join(refseq, ", ");
00358 }
00359
00360 if (non_refseq.size()) {
00361 if ( !accs.empty() ) {
00362 accs += ", ";
00363 }
00364 accs += NStr::Join(non_refseq, ", ");
00365 }
00366
00367 if ( !accs.empty() ) {
00368 s += accs;
00369 } else {
00370 s += "<unknown>";
00371 }
00372
00373 list<string> lines;
00374 NStr::Wrap(s, 78, lines);
00375 if ( !lines.empty() ) {
00376 ITERATE (list<string>, iter, lines) {
00377 if (iter != lines.begin()) {
00378 item->AddLine(" " + *iter);
00379 } else {
00380 item->AddLine(*iter);
00381 }
00382 }
00383 }
00384 }
00385
00386 static void s_GetItems_Feat_Evidence(
00387 const CSeq_feat& feat, CScope* scope, vector<ITextItem*>& items)
00388 {
00389 if ( !feat.IsSetExt() && !feat.IsSetExts()) {
00390 return;
00391 }
00392
00393 list< CConstRef<CUser_object> > objs;
00394 if (feat.IsSetExt()) {
00395 CConstRef<CUser_object> o(&feat.GetExt());
00396 if (o->IsSetType() && o->GetType().IsStr() && o->GetType().GetStr() == "CombinedFeatureUserObjects") {
00397 ITERATE (CUser_object::TData, it, o->GetData()) {
00398 const CUser_field& field = **it;
00399 CConstRef<CUser_object> sub_o(&field.GetData().GetObject());
00400 objs.push_back(sub_o);
00401 }
00402 } else {
00403 objs.push_back(o);
00404 }
00405 }
00406 if (feat.IsSetExts()) {
00407 copy(feat.GetExts().begin(), feat.GetExts().end(), back_inserter(objs));
00408 }
00409
00410 CPlainTextItem* item = new CPlainTextItem();
00411
00412 ITERATE (list< CConstRef<CUser_object> >, obj_it, objs) {
00413 const CUser_object& obj = **obj_it;
00414 if ( !obj.IsSetType() ||
00415 !obj.GetType().IsStr() ||
00416 obj.GetType().GetStr() != "ModelEvidence") {
00417 continue;
00418 }
00419
00420 string s;
00421 CConstRef<CUser_field> f;
00422
00423 item->AddLine("");
00424
00425
00426
00427 string method;
00428 s = "Model Generation Method: ";
00429 f = obj.GetFieldRef("Method");
00430 if (f) {
00431 method = f->GetData().GetStr();
00432 s += method;
00433 } else {
00434 s += "<unknown>";
00435 }
00436 item->AddLine(s);
00437
00438
00439
00440 if (method == "Chainer" || method == "Gnomon") {
00441
00442
00443
00444 f = obj.GetFieldRef("Support");
00445 if (f) {
00446 string core;
00447 ITERATE (CUser_field::TData::TFields, it, f->GetData().GetFields()) {
00448 const CUser_field& this_f = **it;
00449 if (this_f.GetLabel().GetStr() == "Core") {
00450 if ( !core.empty() ) {
00451 core += ", ";
00452 }
00453 core += this_f.GetData().GetStr();
00454 }
00455 }
00456 if ( !core.empty() ) {
00457 s = "Model Based On: ";
00458 s += core;
00459 item->AddLine(s);
00460 }
00461 }
00462
00463
00464
00465 f = obj.GetFieldRef("Support.Proteins");
00466 if (f) {
00467 s_AccListToItem(f->GetData().GetStrs(),
00468 "Source Proteins", item);
00469 }
00470
00471
00472
00473 f = obj.GetFieldRef("Support.mRNAs");
00474 if (f) {
00475 s_AccListToItem(f->GetData().GetStrs(),
00476 "Source mRNAs", item);
00477 }
00478 }
00479 }
00480
00481 items.push_back( item );
00482 }
00483
00484
00485
00486 static void s_GetItems_Feat(
00487 const CSeq_feat& feat, CScope* scope, vector<ITextItem*>& items
00488 ){
00489 string text;
00490 CPlainTextItem* item;
00491
00492 try {
00493
00494 CLabel::GetLabel( feat, &text, CLabel::eDescription, scope );
00495 item = new CPlainTextItem();
00496 item->AddLine( text );
00497 items.push_back( item );
00498
00499
00500 TSeqRange range = feat.GetLocation().GetTotalRange();
00501 text = "Total Range: ";
00502 switch( sequence::GetStrand(feat.GetLocation(), scope) ){
00503 case eNa_strand_plus:
00504 text += "(+) ";
00505 break;
00506 case eNa_strand_minus:
00507 text += "(-) ";
00508 break;
00509
00510 default:
00511 break;
00512 }
00513
00514 text += NStr::IntToString(range.GetFrom() + 1, NStr::fWithCommas);
00515 text += " - ";
00516 text += NStr::IntToString(range.GetTo() + 1, NStr::fWithCommas);
00517
00518 item = new CPlainTextItem();
00519 item->AddLine( text );
00520 items.push_back( item );
00521
00522 text = "Total Length: ";
00523 text += NStr::IntToString(range.GetLength(), NStr::fWithCommas);
00524
00525 item = new CPlainTextItem();
00526 item->AddLine( text );
00527 items.push_back( item );
00528
00529 text = "Processed Length: ";
00530 text += NStr::IntToString(sequence::GetLength(feat.GetLocation(), scope),
00531 NStr::fWithCommas);
00532
00533 item = new CPlainTextItem();
00534 item->AddLine( text );
00535 items.push_back( item );
00536
00537 if (feat.IsSetProduct() && scope) {
00538 try {
00539 string prod_len_str;
00540 CBioseq_Handle h = scope->GetBioseqHandle(feat.GetProduct());
00541 if (h) {
00542 text = "Product Length: ";
00543 text += NStr::IntToString(h.GetBioseqLength(),
00544 NStr::fWithCommas);
00545
00546 item = new CPlainTextItem();
00547 item->AddLine( text );
00548 items.push_back( item );
00549 }
00550 }
00551 catch (CException&) {
00552 }
00553 }
00554
00555 item = new CPlainTextItem();
00556 item->AddLine( " " );
00557 items.push_back( item );
00558
00559
00560 CFlatFileConfig cfg;
00561 cfg.SetNeverTranslateCDS();
00562
00563 if( scope ){
00564 string s = CFlatFileGenerator::GetSeqFeatText(feat, *scope, cfg);
00565 string::size_type pos = s.find_first_not_of(" \n\r\t");
00566 if( pos != string::npos ){
00567 s.erase(0, pos);
00568 }
00569
00570 item = new CPlainTextItem();
00571
00572 string::size_type lpos = -1;
00573 do {
00574 pos = lpos +1;
00575 lpos = s.find_first_of("\n\r", pos );
00576
00577 if( lpos == string::npos ){
00578 text = s.substr( pos );
00579 } else {
00580 text = s.substr( pos, lpos - pos );
00581 }
00582 item->AddLine( text );
00583
00584 } while( lpos != string::npos );
00585
00586 items.push_back( item );
00587 }
00588
00589
00590 s_GetItems_Feat_Evidence(feat, scope, items);
00591 }
00592 catch (CException&) {
00593 }
00594 }
00595
00596 static void s_GetItems_Loc(
00597 const CSeq_loc& loc, CScope* scope, vector<ITextItem*>& items
00598 ){
00599 string text;
00600 CLabel::GetLabel( loc, &text, CLabel::eDescription, scope );
00601
00602 CPlainTextItem* item = new CPlainTextItem();
00603 item->AddLine( text );
00604 items.push_back( item );
00605 }
00606
00607 void CObjectTextWidget::x_GetItems_Object(
00608 const CObject& object, CScope* scope, vector<ITextItem*>& items
00609 ){
00610 if( m_Brief ){
00611 string text;
00612 CLabel::GetLabel(
00613 object, &text, CLabel::eDescriptionBrief, scope
00614 );
00615
00616 CPlainTextItem* item = new CPlainTextItem();
00617 item->AddLine( text );
00618 items.push_back( item );
00619 } else {
00620 const CSerialObject* cso = dynamic_cast<const CSerialObject*>(&object);
00621
00622 if( cso ){
00623
00624 CSelectableObjectItem* comp_item = new CSelectableObjectItem( cso );
00625 vector<ITextItem*> comp_items;
00626
00627 if( cso->GetThisTypeInfo() == CSeq_align::GetTypeInfo() ){
00628 s_GetItems_Align((const CSeq_align&)*cso, scope, comp_items);
00629
00630 } else if (cso->GetThisTypeInfo() == CSeq_feat::GetTypeInfo()) {
00631 s_GetItems_Feat((const CSeq_feat&)*cso, scope, comp_items);
00632
00633 } else if (cso->GetThisTypeInfo() == CSeq_loc::GetTypeInfo()) {
00634 s_GetItems_Loc((const CSeq_loc&)*cso, scope, comp_items);
00635 } else {
00636 string text;
00637 CLabel::GetLabel( object, &text, CLabel::eDescription, scope );
00638
00639 CPlainTextItem* item = new CPlainTextItem();
00640 item->AddLine( text );
00641 comp_items.push_back( item );
00642 }
00643
00644 NON_CONST_ITERATE( vector<ITextItem*>, item_iter, comp_items ){
00645 comp_item->AddItem( *item_iter );
00646 }
00647
00648 items.push_back( comp_item );
00649 }
00650 }
00651 }
00652
00653 END_NCBI_SCOPE
00654
00655