NCBI C++ ToolKit
app_tasks.cpp
Go to the documentation of this file.
00001 /*  $Id: app_tasks.cpp 25238 2012-02-14 16:11:43Z ucko $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data, the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties, express or implied, including
00019  *  warranties of performance, merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Authors:  Andrey Yazhuk
00027  *
00028  */
00029 
00030 #include <ncbi_pch.hpp>
00031 
00032 #include <objects/seq/Seq_inst.hpp>
00033 #include <objects/seq/Seq_hist.hpp>
00034 #include <objects/seq/Seq_hist_rec.hpp>
00035 #include <objects/seq/Bioseq.hpp>
00036 #include <objects/seqloc/Seq_loc.hpp>
00037 #include <objects/seqloc/Seq_id.hpp>
00038 
00039 #include <serial/typeinfo.hpp>
00040 
00041 #include <gui/core/app_tasks.hpp>
00042 
00043 #include <gui/core/ui_data_source_service.hpp>
00044 #include <gui/core/selection_service_impl.hpp>
00045 #include <gui/core/project_service.hpp>
00046 
00047 #include <gui/core/ui_export_tool.hpp>
00048 
00049 #include <gui/core/open_dlg.hpp>
00050 #include <gui/core/run_tool_dlg.hpp>
00051 #include <gui/core/open_view_dlg.hpp>
00052 
00053 #include <gui/framework/workbench.hpp>
00054 #include <gui/framework/app_task_service.hpp>
00055 #include <gui/framework/view_manager_service.hpp>
00056 
00057 #include <gui/widgets/wx/message_box.hpp>
00058 #include <gui/widgets/wx/ui_command.hpp>
00059 #include <gui/widgets/wx/async_call.hpp>
00060 
00061 #include <gui/utils/extension_impl.hpp>
00062 #include <gui/objutils/obj_convert.hpp>
00063 #include <gui/objutils/gi_cache.hpp>
00064 
00065 #include <gui/core/async_obj_convert.hpp>
00066 
00067 #include <wx/frame.h>
00068 #include <wx/utils.h>
00069 
00070 
00071 BEGIN_NCBI_SCOPE
00072 USING_SCOPE(objects);
00073 
00074 ///////////////////////////////////////////////////////////////////////////////
00075 /// COpenDlgTask
00076 static const char* kOpenDlgTaskDescr = "Show \"Open\" dialog.";
00077 
00078 COpenDlgTask::COpenDlgTask(IWorkbench* workbench)
00079 :   CAppTask(kOpenDlgTaskDescr, false),
00080     m_Workbench(workbench)
00081 {
00082     _ASSERT(m_Workbench);
00083 }
00084 
00085 COpenDlgTask::COpenDlgTask(IWorkbench* workbench, const string& loader_label)
00086 :   CAppTask(kOpenDlgTaskDescr, false),
00087     m_Workbench(workbench),
00088     m_LoaderLabel(loader_label)
00089 {
00090     _ASSERT(m_Workbench);
00091 }
00092 
00093 
00094 COpenDlgTask::COpenDlgTask(IWorkbench* workbench, const vector<wxString>& filenames)
00095 :   CAppTask(kOpenDlgTaskDescr, true),
00096     m_Workbench(workbench),
00097     m_Filenames(filenames)
00098 {
00099     _ASSERT(m_Workbench);
00100 }
00101 
00102 
00103 IAppTask::ETaskState COpenDlgTask::x_Run()
00104 {   
00105     // obtain the list of Load Managers
00106     CUIDataSourceService::TUIToolManagerVec managers;
00107     CIRef<CUIDataSourceService> srv = m_Workbench->GetServiceByType<CUIDataSourceService>();
00108     srv->GetLoadManagers(managers);
00109 
00110     // create "Open" dialog
00111     wxWindow* parent = m_Workbench->GetMainWindow();
00112 
00113     COpenDlg dlg(parent);
00114     dlg.SetSize(710, 480);
00115     dlg.SetServiceLocator(m_Workbench);
00116     dlg.SetManagers(managers);
00117 
00118     if( ! m_LoaderLabel.empty())    {
00119         dlg.SelectOptionByLabel(m_LoaderLabel);
00120     }
00121     if( ! m_Filenames.empty())   {
00122         dlg.SetFilenames(m_Filenames);
00123     }
00124     dlg.SetRegistryPath("OpenDialog"); //TODO
00125 
00126     if(dlg.ShowModal() == wxID_OK)  {
00127         // get the loading task and add it to Task Manager queue
00128         CIRef<IAppTask> loading_task = dlg.GetLoadingTask();
00129         if(loading_task)    {
00130             m_Workbench->GetAppTaskService()->AddTask(*loading_task);
00131         }
00132     }
00133 
00134     return eCompleted;
00135 }
00136 
00137 
00138 ///////////////////////////////////////////////////////////////////////////////
00139 /// CRunToolDlgTask
00140 static const char* kRunToolDlgTaskDescr = "Show \"Run Tool\" dialog.";
00141 static const char* kRunToolDlgSection = ".RunToolDialog";
00142 
00143 CRunToolDlgTask::CRunToolDlgTask(IWorkbench* workbench)
00144 :   CAppTask(kRunToolDlgTaskDescr, false),
00145     m_Workbench(workbench)
00146 {
00147     _ASSERT(m_Workbench);
00148 }
00149 
00150 
00151 
00152 IAppTask::ETaskState CRunToolDlgTask::x_Run()
00153 {   
00154     typedef CIRef<IUIToolManager>   TManagerRef;
00155 
00156     /// obtain current selection
00157     TConstScopedObjects objects;
00158     CIRef<CSelectionService> sel_srv = m_Workbench->GetServiceByType<CSelectionService>();
00159     sel_srv->GetCurrentSelection(objects);
00160 
00161     if(objects.empty()) {
00162         NcbiInfoBox("Please select objects you would like to run a tool on!");
00163         return eCompleted;
00164     }
00165 
00166     /// get available tools
00167     vector< CIRef<IUIAlgoToolManager> > managers;
00168     GetExtensionAsInterface("ui_algo_tool_manager", managers);
00169 
00170     /// show Run Tool dialog
00171     CRunToolDlg dlg(m_Workbench->GetMainWindow());
00172     dlg.SetServiceLocator(m_Workbench);
00173     dlg.SetManagers(managers);
00174 
00175     string reg_path = m_Workbench->GetRegistrySectionPath(IWorkbench::eDialogs);
00176     dlg.SetRegistryPath(reg_path + kRunToolDlgSection);
00177 
00178     dlg.SetInputObjects(objects);
00179 
00180     if(dlg.ShowModal() == wxID_OK)   {
00181         // schedule tool execution
00182         CIRef<IAppTask> tool_task = dlg.GetToolTask();
00183         if(tool_task)    {
00184             m_Workbench->GetAppTaskService()->AddTask(*tool_task);
00185         }
00186     }
00187     return eCompleted;
00188 }
00189 
00190 
00191 
00192 ///////////////////////////////////////////////////////////////////////////////
00193 /// COpenViewlDlgTask
00194 static const char* kOpenViewDlgTaskDescr = "Show \"Open View\" dialog.";
00195 static const char* kOpenViewDlgSection = ".OpenViewDialog";
00196 
00197 COpenViewlDlgTask::COpenViewlDlgTask(IWorkbench* workbench, bool openDefault)
00198     : CAppTask(kOpenViewDlgTaskDescr, false), m_OpenDefault(openDefault)
00199     , m_Workbench(workbench)
00200 {
00201     _ASSERT(m_Workbench);
00202 }
00203 
00204 class CPrefetchHandles_local : public CAsyncCall::Call
00205 {
00206 public:
00207     CPrefetchHandles_local( TConstScopedObjects& objects ) : m_Objects( objects ) {}
00208 
00209     virtual void Execute();
00210 
00211 private:
00212     TConstScopedObjects& m_Objects;
00213 };
00214 
00215 void CPrefetchHandles_local::Execute()
00216 {
00217     NON_CONST_ITERATE( TConstScopedObjects, itr, m_Objects ){
00218 
00219         const CSeq_id* id = dynamic_cast<const CSeq_id*>( itr->object.GetPointer() );
00220         if( id ){
00221             itr->scope->GetBioseqHandle(*id);
00222             continue;
00223         }
00224 
00225         const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>( itr->object.GetPointer() );
00226         if( loc ){
00227             itr->scope->GetBioseqHandle(*loc);
00228             continue;
00229         }
00230 
00231         const CBioseq* seq = dynamic_cast<const CBioseq*>( itr->object.GetPointer() );
00232         if( seq ){
00233             itr->scope->GetBioseqHandle(*seq);
00234             continue;
00235         }
00236 
00237         /* CSeq_annot is just a container - no prefetch.
00238 
00239         const CSeq_annot* annot = dynamic_cast<const CSeq_annot*>( itr->object.GetPointer() );
00240         if( annot ){
00241             itr->scope->GetSeq_annotHandle(*annot);
00242             continue;
00243         }
00244         */
00245 
00246         const CSeq_feat* feat = dynamic_cast<const CSeq_feat*>( itr->object.GetPointer() );
00247         if( feat ){
00248             itr->scope->GetSeq_featHandle(*feat);
00249             continue;
00250         }
00251     }
00252 }
00253 
00254 IAppTask::ETaskState COpenViewlDlgTask::x_Run()
00255 {   
00256     /// obtain current selection
00257     TConstScopedObjects objects;
00258     CIRef<CSelectionService> sel_srv = m_Workbench->GetServiceByType<CSelectionService>();
00259     sel_srv->GetCurrentSelection( objects );
00260 
00261     if( objects.empty() ){
00262         NcbiWarningBox( "Please select objects you would like to view." );
00263         return eCompleted;
00264     }
00265 
00266     /// get all View Factories
00267     IViewManagerService* srv = m_Workbench->GetViewManagerService();
00268     IViewManagerService::TFactories factories;
00269     srv->GetFactories( factories );
00270 
00271     string defaultFactoryLabel;
00272     CIRef<IProjectViewFactory> defaultFactory;
00273 
00274     string reg_path = m_Workbench->GetRegistrySectionPath( IWorkbench::eDialogs ) + kOpenViewDlgSection;
00275 
00276     if (m_OpenDefault) {
00277         defaultFactoryLabel = COpenViewDlg::GetDefaultFactoryLabel(reg_path, objects);
00278     }
00279 
00280     /// select Project View Factories only
00281     COpenViewDlg::TFactories prj_factories;
00282     for( size_t i = 0; i < factories.size();  i++ ){
00283         IProjectViewFactory* prj_fc = dynamic_cast<IProjectViewFactory*>( &*factories[i] );
00284         if( prj_fc ){
00285             CIRef<IProjectViewFactory> ref( prj_fc );
00286             prj_factories.push_back(ref);
00287             
00288             if (m_OpenDefault && prj_fc->GetViewTypeDescriptor().GetLabel() == defaultFactoryLabel) {
00289                 int test = prj_fc->TestInputObjects( objects );
00290                 if (test&IProjectViewFactory::fCanShowAll)
00291                     defaultFactory.Reset(prj_fc);
00292             }
00293         }
00294     }
00295 
00296     if (m_OpenDefault && defaultFactory) {
00297         const CProjectViewTypeDescriptor& pvt_desc = defaultFactory->GetProjectViewTypeDescriptor();
00298         string view_name = pvt_desc.GetLabel();
00299         bool prefetch_needed = pvt_desc.IsPrefetchNeeded();
00300 
00301         CProjectService* prj_srv = m_Workbench->GetServiceByType<CProjectService>();
00302 
00303         if( prefetch_needed ){
00304             CPrefetchHandles_local prefetch( objects );
00305             CAsyncCall::Execute(prefetch);
00306 
00307             for( size_t j = 0; j < objects.size(); j++ ){
00308                 x_CheckDataStatus( objects[j] );
00309             }
00310         }
00311 
00312         try {
00313             prj_srv->AddProjectView( view_name, objects[0] );
00314         
00315         } catch( CException& ex ){
00316             //! CUserException should be used
00317             NcbiErrorBox( "Open View: " + ex.GetMsg() );
00318         }
00319 
00320         return eCompleted;
00321     }
00322 
00323     /// setup the dialog
00324     COpenViewDlg dlg( m_Workbench->GetMainWindow() );
00325 
00326     /*
00327     wxAcceleratorEntry entries[1];
00328     entries[0].Set( wxACCEL_CTRL, (int) 'A', wxID_SELECTALL );
00329     wxAcceleratorTable accel( 1, entries );
00330     dlg.SetAcceleratorTable( accel );
00331     */
00332 
00333     dlg.SetRegistryPath( reg_path );
00334 
00335     dlg.SetInputObjects( objects );
00336     dlg.SetFactories( prj_factories );
00337 
00338     if( dlg.ShowModal() == wxID_OK ){
00339         CIRef<IProjectViewFactory> factory = dlg.GetSelectedFactory();
00340         const CProjectViewTypeDescriptor& pvt_desc = factory->GetProjectViewTypeDescriptor();
00341 
00342         string view_name = pvt_desc.GetLabel();
00343         EPVObjectsAccepted multi_accepted = pvt_desc.GetObjectsAccepted();
00344         bool prefetch_needed = pvt_desc.IsPrefetchNeeded();
00345 
00346         CProjectService* prj_srv = m_Workbench->GetServiceByType<CProjectService>();
00347 
00348         // create a view for every item
00349 
00350         objects = dlg.GetOutputObjects();
00351         vector<int> indices = dlg.GetOutputIndices();
00352 
00353         _ASSERT( indices.size() <= objects.size() );
00354 
00355         //! HACK
00356         if( multi_accepted == eAnyObjectsAccepted ){
00357             NON_CONST_ITERATE( vector<int>, ix_itr, indices ){
00358                 if( *ix_itr > 0 ){
00359                     *ix_itr = 1;
00360                 }
00361             }
00362         }
00363 
00364         if( prefetch_needed ){
00365             CPrefetchHandles_local prefetch( objects );
00366             CAsyncCall::Execute(prefetch);
00367 
00368             for( size_t j = 0; j < objects.size(); j++ ){
00369                 x_CheckDataStatus( objects[j] );
00370             }
00371         }
00372 
00373         set<int> opened_groups;
00374 
00375         for( size_t ix = 0; ix < objects.size(); ix++ ){
00376             int group_ix = ix < indices.size() ? indices[ix] : -1;
00377 
00378             if( group_ix < 0 ){
00379                 try {
00380                     prj_srv->AddProjectView( view_name, objects[ix] );
00381                 
00382                 } catch( CException& ex ){
00383                     //! CUserException should be used
00384                     NcbiErrorBox( "Open View: " + ex.GetMsg() );
00385                 }
00386 
00387             } else if( opened_groups.find( group_ix ) == opened_groups.end() ){
00388                 opened_groups.insert( group_ix );
00389 
00390 #               ifdef _DEBUG
00391                 CStopWatch watch( CStopWatch::eStart );
00392 #               endif
00393 
00394                 TConstScopedObjects obj_group;
00395                 for( size_t j = ix; j < indices.size(); j++ ){
00396                     if( indices[j] == group_ix ){
00397                         obj_group.push_back( objects[j] );
00398                     }
00399                 }
00400 
00401 #               ifdef _DEBUG
00402                 watch.Stop();
00403                 LOG_POST( "Open View: grouping takes " << watch.AsSmartString() );
00404 #               endif
00405 
00406                 try {
00407                     prj_srv->AddProjectView( view_name, obj_group );
00408 
00409                 } catch( CException& ex ){
00410                     //! CUserException should be used
00411                     NcbiErrorBox( "Open View: " + ex.GetMsg() );
00412                 }
00413             }
00414         }
00415     }
00416 
00417     return eCompleted;
00418 }
00419 
00420 void COpenViewlDlgTask::x_CheckDataStatus( SConstScopedObject& object )
00421 {
00422     CBioseq_Handle handle;
00423     const CSeq_id* id = dynamic_cast<const CSeq_id*>( object.object.GetPointer() );
00424     const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>( object.object.GetPointer() );
00425     const CBioseq* seq = dynamic_cast<const CBioseq*>( object.object.GetPointer() );
00426 
00427     if( id ){
00428         handle = object.scope->GetBioseqHandle(*id);
00429 
00430     } else if( loc ){
00431         handle = object.scope->GetBioseqHandle(*loc);
00432 
00433     } else if( seq ){
00434         handle = object.scope->GetBioseqHandle(*seq);
00435     }
00436 
00437     if( handle && !CGiCache::GetInstance().RecordKnown( handle ) ){
00438         string warning_msg = kEmptyStr;
00439         if( handle.State_Withdrawn() || handle.State_Suppressed() ){
00440             warning_msg = "this record has been removed or withdrawn.";
00441 
00442         } else if(
00443             handle.IsSetInst()  
00444             && handle.GetInst().IsSetHist()  
00445             && handle.GetInst().GetHist().IsSetReplaced_by()
00446         ){
00447             const CSeq_hist_rec::TIds& ids = handle.GetInst().GetHist().GetReplaced_by().GetIds();
00448             warning_msg = "this record has been replaced by: ";
00449             ITERATE( CSeq_hist_rec::TIds,  iter,  ids ){
00450                 string id_label;
00451                 const CBioseq::TId& seq_ids = handle.GetScope().GetBioseqHandle(**iter).GetCompleteBioseq()->GetId();
00452                 ITERATE( CBioseq::TId, seq_iter, seq_ids ){
00453                     if(
00454                         (*seq_iter)->Which() == CSeq_id::e_Other  && (*seq_iter)->GetOther().IsSetAccession()
00455                     ){
00456                         id_label = (*seq_iter)->GetOther().GetAccession();
00457                         if( (*seq_iter)->GetOther().IsSetVersion() ){
00458                             id_label += "." + NStr::IntToString((*seq_iter)->GetOther().GetVersion());
00459                         }
00460                         break;
00461                     }
00462                 }
00463                 if( id_label.empty() ){
00464                     (*iter)->GetLabel( &id_label, CSeq_id::eFasta );
00465                 }
00466                 warning_msg += id_label + " ";
00467             }
00468         }
00469 
00470         if( !warning_msg.empty() ){
00471             string viewed_id_label;
00472             handle.GetCompleteBioseq()->GetLabel(&viewed_id_label, CBioseq::eContent);
00473             string base = "Opening record " + viewed_id_label + ".  Please be aware of that ";
00474             NcbiMessageBox( base + warning_msg, eDialog_Ok, eIcon_Exclamation, "Warning" );
00475         }
00476     }
00477 }
00478 
00479 ///////////////////////////////////////////////////////////////////////////////
00480 /// CExportDlgTask
00481 static const char* kExportDlgTaskDescr = "Show \"Export\" dialog.";
00482 
00483 CExportDlgTask::CExportDlgTask(IWorkbench* workbench)
00484 :   CAppTask(kExportDlgTaskDescr, false),
00485     m_Workbench(workbench)
00486 {
00487     _ASSERT(m_Workbench);
00488 }
00489 
00490 IAppTask::ETaskState CExportDlgTask::x_Run()
00491 {  
00492     ::wxBeginBusyCursor();
00493 
00494     /// obtain current selection
00495     TConstScopedObjects objects;
00496     CIRef<CSelectionService> sel_srv = m_Workbench->GetServiceByType<CSelectionService>();
00497     sel_srv->GetCurrentSelection(objects);
00498 
00499     if(objects.empty()) {
00500         NcbiInfoBox("Please select objects you would like to export!");
00501         return eCompleted;
00502     }
00503 
00504     vector<IExporterFactory*> factories;
00505     GetExtensionAsInterface(EXT_POINT__UI_EXPORTER_FACTORY, factories);
00506 
00507     TRelatedObjectsMap map;
00508     CAsyncObjConvert convertor(CSeq_loc::GetTypeInfo(), objects, map);
00509     CAsyncCall::Execute(convertor);
00510 
00511     CUIDataSourceService::TUIToolManagerVec managers;
00512 
00513     ITERATE(vector<IExporterFactory*>, it, factories) {
00514         if ((*it)->TestInputObjects(objects)) {
00515             CIRef<IUIExportTool> exporter((*it)->CreateInstance());
00516             exporter->SetObjects(map);
00517             exporter->SetObjects(objects);
00518             managers.push_back(CIRef<IUIToolManager>(exporter.GetPointer()));
00519         }
00520     }
00521 
00522     if (managers.empty()) {
00523         NcbiInfoBox("No exporters defined that can export selected objects!");
00524         return eCompleted;
00525     }
00526 
00527     // create "Open" dialog
00528     wxWindow* parent = m_Workbench->GetMainWindow();
00529 
00530     COpenDlg dlg(parent);
00531     dlg.SetSize(710, 480);
00532     dlg.SetServiceLocator(m_Workbench);
00533     dlg.SetManagers(managers);
00534     dlg.SetBaseTitle(wxT("Export"));
00535 
00536     dlg.SetRegistryPath("ExportDialog"); //TODO
00537 
00538     ::wxEndBusyCursor();
00539 
00540     if(dlg.ShowModal() == wxID_OK)  {
00541         // get the loading task and add it to Task Manager queue
00542         CIRef<IAppTask> loading_task = dlg.GetLoadingTask();
00543         if(loading_task)    {
00544             m_Workbench->GetAppTaskService()->AddTask(*loading_task);
00545         }
00546     }
00547 
00548     return eCompleted;
00549 }
00550 
00551 END_NCBI_SCOPE
Modified on Wed May 23 13:21:46 2012 by modify_doxy.py rev. 337098