From 06e190c27d6faf4120fcd5fdee8fd95cfa2edd6f Mon Sep 17 00:00:00 2001 From: fgerlits Date: Tue, 2 May 2006 17:38:31 +0000 Subject: [PATCH] progress towards #1595 ([2027] and [2029] were that, too) --- .../LiveSupport/Widgets/ZebraTreeView.h | 13 + .../src/modules/widgets/src/ZebraTreeView.cxx | 23 +- .../gLiveSupport/src/GLiveSupport.cxx | 15 +- .../products/gLiveSupport/src/GLiveSupport.h | 10 + .../gLiveSupport/src/MasterPanelWindow.cxx | 26 +- .../gLiveSupport/src/SearchWindow.cxx | 369 +++++++++++++++--- .../products/gLiveSupport/src/SearchWindow.h | 99 ++++- .../src/products/gLiveSupport/var/root.txt | 7 + 8 files changed, 489 insertions(+), 73 deletions(-) diff --git a/livesupport/src/modules/widgets/include/LiveSupport/Widgets/ZebraTreeView.h b/livesupport/src/modules/widgets/include/LiveSupport/Widgets/ZebraTreeView.h index df6f0a397..53c0fb55c 100644 --- a/livesupport/src/modules/widgets/include/LiveSupport/Widgets/ZebraTreeView.h +++ b/livesupport/src/modules/widgets/include/LiveSupport/Widgets/ZebraTreeView.h @@ -396,6 +396,19 @@ class ZebraTreeView : public Gtk::TreeView { return signalCellEditedObject; } + + /** + * Manually connect the 'model has changed' signals to the tree view. + * This is useful if you want to use the same ZebraTreeView object + * to alternately display two (or more) different tree models. + * + * @param treeModel the tree model whose changes should trigger + * a redraw of the tree view object + */ + void + connectModelSignals(Glib::RefPtr treeModel) + throw (); + }; diff --git a/livesupport/src/modules/widgets/src/ZebraTreeView.cxx b/livesupport/src/modules/widgets/src/ZebraTreeView.cxx index 96a99ea99..c979bd12f 100644 --- a/livesupport/src/modules/widgets/src/ZebraTreeView.cxx +++ b/livesupport/src/modules/widgets/src/ZebraTreeView.cxx @@ -63,12 +63,7 @@ ZebraTreeView :: ZebraTreeView(Glib::RefPtr treeModel) throw () : Gtk::TreeView(treeModel) { - treeModel->signal_row_inserted().connect(sigc::mem_fun(*this, - &ZebraTreeView::onRowInserted)); - treeModel->signal_row_deleted().connect(sigc::mem_fun(*this, - &ZebraTreeView::onRowDeleted)); - treeModel->signal_rows_reordered().connect(sigc::mem_fun(*this, - &ZebraTreeView::onRowsReordered)); + connectModelSignals(treeModel); this->signal_row_expanded().connect(sigc::mem_fun(*this, &ZebraTreeView::onRowExpanded)); this->signal_row_collapsed().connect(sigc::mem_fun(*this, @@ -565,3 +560,19 @@ ZebraTreeView :: renumberRows(void) throw () } } + +/*------------------------------------------------------------------------------ + * Manually connect the 'model has changed' signals to the tree view. + *----------------------------------------------------------------------------*/ +void +ZebraTreeView :: connectModelSignals(Glib::RefPtr treeModel) + throw () +{ + treeModel->signal_row_inserted().connect(sigc::mem_fun(*this, + &ZebraTreeView::onRowInserted)); + treeModel->signal_row_deleted().connect(sigc::mem_fun(*this, + &ZebraTreeView::onRowDeleted)); + treeModel->signal_rows_reordered().connect(sigc::mem_fun(*this, + &ZebraTreeView::onRowsReordered)); +} + diff --git a/livesupport/src/products/gLiveSupport/src/GLiveSupport.cxx b/livesupport/src/products/gLiveSupport/src/GLiveSupport.cxx index e9efc886f..16e70cdd6 100644 --- a/livesupport/src/products/gLiveSupport/src/GLiveSupport.cxx +++ b/livesupport/src/products/gLiveSupport/src/GLiveSupport.cxx @@ -1310,12 +1310,23 @@ Ptr::Ref LiveSupport :: GLiveSupport :: GLiveSupport :: search(Ptr::Ref criteria) throw (XmlRpcException) +{ + storage->search(sessionId, criteria); + + return readSearchResults(); +} + + +/*------------------------------------------------------------------------------ + * Return the Playable items found by the latest search (local or remote). + *----------------------------------------------------------------------------*/ +Ptr::Ref +LiveSupport :: GLiveSupport :: +GLiveSupport :: readSearchResults(void) throw (XmlRpcException) { Ptr::Ref results(new PlayableList); - storage->search(sessionId, criteria); - Ptr::Ref> >::Ref audioClipIds = getAudioClipIds(); std::vector::Ref>::const_iterator it; for (it = audioClipIds->begin(); it != audioClipIds->end(); ++it) { diff --git a/livesupport/src/products/gLiveSupport/src/GLiveSupport.h b/livesupport/src/products/gLiveSupport/src/GLiveSupport.h index 012cad986..73ac77e6d 100644 --- a/livesupport/src/products/gLiveSupport/src/GLiveSupport.h +++ b/livesupport/src/products/gLiveSupport/src/GLiveSupport.h @@ -945,6 +945,16 @@ class GLiveSupport : public LocalizedConfigurable, search(Ptr::Ref criteria) throw (XmlRpcException); + /** + * Return the Playable items found by the latest search. + * + * @return the list of audio clips and playlists found. + * @exception XmlRpcException passed on from getAudioClip() or + * getPlaylist(). + */ + Ptr::Ref + readSearchResults(void) throw (XmlRpcException); + /** * Browse in the local storage. * diff --git a/livesupport/src/products/gLiveSupport/src/MasterPanelWindow.cxx b/livesupport/src/products/gLiveSupport/src/MasterPanelWindow.cxx index 39bb90604..e276024a7 100644 --- a/livesupport/src/products/gLiveSupport/src/MasterPanelWindow.cxx +++ b/livesupport/src/products/gLiveSupport/src/MasterPanelWindow.cxx @@ -65,6 +65,12 @@ const Glib::ustring windowName = "masterPanelWindow"; */ const int updateTimeConstant = 20; +/** + * The delay between two checks on the progress of an asynchronous method + * (in seconds). + */ +const int asyncUpdateFrequency = 10; + } /* =============================================== local function prototypes */ @@ -382,17 +388,25 @@ MasterPanelWindow :: onUpdateTime(int dummy) throw () nowPlayingWidget->onUpdateTime(); + // check on the progress of the async methods static int backupCounter = 0; - if (backupCounter++ == updateTimeConstant * 10) { + if (backupCounter++ == updateTimeConstant * asyncUpdateFrequency) { backupCounter = 0; } - if (backupCounter == 0 && optionsWindow) { - BackupList * backupList = optionsWindow->getBackupList(); - if (backupList) { - backupList->updateSilently(); + + if (backupCounter == 0) { + if (optionsWindow) { + BackupList * backupList = optionsWindow->getBackupList(); + if (backupList) { + backupList->updateSilently(); + } + } + + if (searchWindow) { + searchWindow->onTimer(); } } - + return true; } diff --git a/livesupport/src/products/gLiveSupport/src/SearchWindow.cxx b/livesupport/src/products/gLiveSupport/src/SearchWindow.cxx index eee226ace..eac2676bf 100644 --- a/livesupport/src/products/gLiveSupport/src/SearchWindow.cxx +++ b/livesupport/src/products/gLiveSupport/src/SearchWindow.cxx @@ -58,6 +58,19 @@ using namespace LiveSupport::GLiveSupport; /* ================================================ local constants & macros */ +namespace { + +/*------------------------------------------------------------------------------ + * The 'search where' combo box key for local searches. + *----------------------------------------------------------------------------*/ +const std::string searchWhereLocalKey = "searchWhereLocal"; + +/*------------------------------------------------------------------------------ + * The 'search where' combo box key for remote searches. + *----------------------------------------------------------------------------*/ +const std::string searchWhereRemoteKey = "searchWhereRemote"; + +} /* =============================================== local function prototypes */ @@ -76,9 +89,11 @@ SearchWindow :: SearchWindow (Ptr::Ref gLiveSupport, WidgetConstants::searchWindowTitleImage, windowOpenerButton) { - Gtk::Box * simpleSearchView = constructSimpleSearchView(); + Gtk::Box * searchWhereBox = constructSearchWhereBox(); + + Gtk::Box * simpleSearchView = constructSimpleSearchView(); Gtk::Box * advancedSearchView = constructAdvancedSearchView(); - Gtk::Box * browseView = constructBrowseView(); + Gtk::Box * browseView = constructBrowseView(); ScrolledNotebook * searchInput = Gtk::manage(new ScrolledNotebook); try { @@ -94,21 +109,18 @@ SearchWindow :: SearchWindow (Ptr::Ref gLiveSupport, std::exit(1); } - // set up the search results box - ZebraTreeView * searchResultsView = constructSearchResultsView(); - Gtk::ScrolledWindow * searchResults = Gtk::manage( - new Gtk::ScrolledWindow); - searchResults->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - searchResults->add(*searchResultsView); + // set up the search results box + ScrolledWindow * searchResultsView = constructSearchResultsView(); // set the sizes of the two parts of the window - searchInput ->set_size_request(750, 240); - searchResults->set_size_request(750, 300); + searchInput ->set_size_request(750, 240); + searchResultsView->set_size_request(750, 300); // put them in one big box Gtk::VBox * bigBox = Gtk::manage(new Gtk::VBox); - bigBox->pack_start(*searchInput, Gtk::PACK_SHRINK); - bigBox->pack_start(*searchResults); + bigBox->pack_start(*searchWhereBox, Gtk::PACK_SHRINK); + bigBox->pack_start(*searchInput, Gtk::PACK_SHRINK); + bigBox->pack_start(*searchResultsView); add(*bigBox); // show @@ -128,6 +140,52 @@ SearchWindow :: ~SearchWindow (void) throw () } +/*------------------------------------------------------------------------------ + * Construct the transport type selection box. + *----------------------------------------------------------------------------*/ +Gtk::VBox* +SearchWindow :: constructSearchWhereBox(void) throw () +{ + Ptr::Ref wf = WidgetFactory::getInstance(); + + Gtk::Label * searchWhereLabel; + try { + searchWhereLabel = Gtk::manage(new Gtk::Label( + *getResourceUstring("searchWhereLabel") )); + searchWhereEntry = Gtk::manage(wf->createComboBoxText()); + + Ptr::Ref localKey(new Glib::ustring( + searchWhereLocalKey)); + Ptr::Ref remoteKey(new Glib::ustring( + searchWhereRemoteKey)); + + searchWhereEntry->appendPair(getResourceUstring(searchWhereLocalKey), + localKey); + searchWhereEntry->appendPair(getResourceUstring(searchWhereRemoteKey), + remoteKey); + } catch (std::invalid_argument &e) { + std::cerr << e.what() << std::endl; + std::exit(1); + } + + searchWhereEntry->set_active(0); + searchWhereEntry->signalSelectionChanged().connect(sigc::mem_fun( + *this, &SearchWindow::onSearchWhereChanged )); + + Gtk::HBox * hBox = Gtk::manage(new Gtk::HBox); + hBox->pack_start(*searchWhereLabel, Gtk::PACK_SHRINK, 5); + hBox->pack_start(*searchWhereEntry, Gtk::PACK_SHRINK); + + Gtk::HBox * padding = Gtk::manage(new Gtk::HBox); + + Gtk::VBox * vBox = Gtk::manage(new Gtk::VBox); + vBox->pack_start(*hBox, Gtk::PACK_SHRINK, 5); + vBox->pack_start(*padding, Gtk::PACK_SHRINK, 5); + + return vBox; +} + + /*------------------------------------------------------------------------------ * Construct the simple search view. *----------------------------------------------------------------------------*/ @@ -231,33 +289,41 @@ SearchWindow :: constructBrowseView(void) throw () /*------------------------------------------------------------------------------ * Construct the search results display. *----------------------------------------------------------------------------*/ -ZebraTreeView * +ScrolledWindow * SearchWindow :: constructSearchResultsView(void) throw () { Ptr::Ref wf = WidgetFactory::getInstance(); - treeModel = Gtk::ListStore::create(modelColumns); - searchResults = Gtk::manage(wf->createTreeView(treeModel)); + localSearchResults = Gtk::ListStore::create(modelColumns); + remoteSearchResults = Gtk::ListStore::create(modelColumns); + + searchResultsTreeView = Gtk::manage(wf->createTreeView(localSearchResults)); + searchResultsTreeView->connectModelSignals(remoteSearchResults); // add the TreeView's view columns try { - searchResults->appendColumn(*getResourceUstring("typeColumnLabel"), - modelColumns.typeColumn, 20); - searchResults->appendColumn(*getResourceUstring("titleColumnLabel"), - modelColumns.titleColumn, 360); - searchResults->appendColumn(*getResourceUstring("creatorColumnLabel"), - modelColumns.creatorColumn, 260); - searchResults->appendColumn(*getResourceUstring("lengthColumnLabel"), - modelColumns.lengthColumn, 50); + searchResultsTreeView->appendColumn( + *getResourceUstring("typeColumnLabel"), + modelColumns.typeColumn, 20); + searchResultsTreeView->appendColumn( + *getResourceUstring("titleColumnLabel"), + modelColumns.titleColumn, 360); + searchResultsTreeView->appendColumn( + *getResourceUstring("creatorColumnLabel"), + modelColumns.creatorColumn, 260); + searchResultsTreeView->appendColumn( + *getResourceUstring("lengthColumnLabel"), + modelColumns.lengthColumn, 50); } catch (std::invalid_argument &e) { std::cerr << e.what() << std::endl; std::exit(1); } // register the signal handler for treeview entries being clicked - searchResults->signal_button_press_event().connect_notify(sigc::mem_fun( + searchResultsTreeView->signal_button_press_event().connect_notify( + sigc::mem_fun( *this, &SearchWindow::onEntryClicked)); - searchResults->signal_row_activated().connect(sigc::mem_fun( + searchResultsTreeView->signal_row_activated().connect(sigc::mem_fun( *this, &SearchWindow::onDoubleClick)); // create the right-click entry context menu @@ -284,7 +350,13 @@ SearchWindow :: constructSearchResultsView(void) throw () } contextMenu->accelerate(*this); - return searchResults; + + // put the tree view inside a scrolled window + ScrolledWindow * view = Gtk::manage(new ScrolledWindow); + view->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + view->add(*searchResultsTreeView); + + return view; } @@ -301,7 +373,7 @@ SearchWindow :: onSimpleSearch(void) throw () MetadataTypeContainer::Vector::const_iterator it = metadataTypes->begin(); - Ptr::Ref criteria(new SearchCriteria("all", "or")); + Ptr::Ref criteria(new SearchCriteria("all", "or")); Ptr::Ref metadata; if (it != metadataTypes->end()) { @@ -349,6 +421,24 @@ SearchWindow :: onBrowse(void) throw () void SearchWindow :: onSearch(Ptr::Ref criteria) throw () +{ + Ptr::Ref searchWhere + = searchWhereEntry->getActiveKey(); + + if (*searchWhere == searchWhereLocalKey) { + localSearch(criteria); + } else { + remoteSearchOpen(criteria); + } +} + + +/*------------------------------------------------------------------------------ + * Search in the local storage. + *----------------------------------------------------------------------------*/ +void +SearchWindow :: localSearch(Ptr::Ref criteria) + throw () { Ptr::Ref> >::Ref searchResults; try { @@ -357,11 +447,26 @@ SearchWindow :: onSearch(Ptr::Ref criteria) std::cerr << e.what() << std::endl; return; } + + displaySearchResults(searchResults, localSearchResults); +} + +/*------------------------------------------------------------------------------ + * Display the search results. + *----------------------------------------------------------------------------*/ +void +SearchWindow :: displaySearchResults( + Ptr::Ref> >::Ref searchResults, + Glib::RefPtr treeModel) + throw () +{ + treeModel->clear(); + searchResultsTreeView->set_model(treeModel); + Ptr::Ref widgetFactory = WidgetFactory::getInstance(); std::list::Ref>::const_iterator it; - treeModel->clear(); for (it = searchResults->begin(); it != searchResults->end(); ++it) { Ptr::Ref playable = *it; @@ -401,6 +506,126 @@ SearchWindow :: onSearch(Ptr::Ref criteria) } +/*------------------------------------------------------------------------------ + * Search on the network hub (initiate the async operation). + *----------------------------------------------------------------------------*/ +void +SearchWindow :: remoteSearchOpen(Ptr::Ref criteria) + throw () +{ + displayMessage("pleaseWaitMsg", remoteSearchResults); + + Ptr::Ref + storage = gLiveSupport->getStorageClient(); + Ptr::Ref sessionId = gLiveSupport->getSessionId(); + + if (remoteSearchToken) { + try { + storage->cancelTransport(sessionId, remoteSearchToken); + } catch (XmlRpcException &e) { + gLiveSupport->displayMessageWindow(formatMessage( + "remoteSearchErrorMsg", + e.what() )); + return; + } + } + + try { + remoteSearchToken = storage->remoteSearchOpen(sessionId, criteria); + } catch (XmlRpcException &e) { + gLiveSupport->displayMessageWindow(formatMessage( + "remoteSearchErrorMsg", + e.what() )); + } +} + + +/*------------------------------------------------------------------------------ + * Search on the network hub (finish the async operation). + *----------------------------------------------------------------------------*/ +void +SearchWindow :: remoteSearchClose(void) + throw () +{ + if (remoteSearchToken) { + Ptr::Ref + storage = gLiveSupport->getStorageClient(); + Ptr::Ref sessionId = gLiveSupport->getSessionId(); + + StorageClientInterface::TransportState state; + Ptr::Ref errorMessage; + try { + state = storage->checkTransport(remoteSearchToken, errorMessage); + } catch (XmlRpcException &e) { + gLiveSupport->displayMessageWindow(formatMessage( + "remoteSearchErrorMsg", + e.what() )); + return; + } + + Ptr::Ref> >::Ref results; + + switch (state) { + case StorageClientInterface::initState : + break; + + case StorageClientInterface::pendingState : + break; + + case StorageClientInterface::finishedState : + try { + storage->remoteSearchClose(remoteSearchToken); + } catch (XmlRpcException &e) { + gLiveSupport->displayMessageWindow(formatMessage( + "remoteSearchErrorMsg", + e.what() )); + return; + } + remoteSearchToken.reset(); + + try { + results = gLiveSupport->readSearchResults(); + } catch (XmlRpcException &e) { + gLiveSupport->displayMessageWindow(formatMessage( + "remoteSearchErrorMsg", + e.what() )); + return; + } + + displaySearchResults(results, remoteSearchResults); + break; + + case StorageClientInterface::closedState : + remoteSearchToken.reset(); + displayMessage("remoteSearchErrorMsg", remoteSearchResults); + break; + + case StorageClientInterface::failedState : + remoteSearchToken.reset(); + displayMessage(*errorMessage, remoteSearchResults); + break; + } + } +} + + +/*------------------------------------------------------------------------------ + * Display a (usually error) message in the search results tree view. + *----------------------------------------------------------------------------*/ +void +SearchWindow :: displayMessage(const Glib::ustring & messageKey, + Glib::RefPtr treeModel) + throw () +{ + treeModel->clear(); + + Gtk::TreeModel::Row row = *treeModel->append(); + row[modelColumns.titleColumn] = *getResourceUstring(messageKey); + + searchResultsTreeView->set_model(treeModel); +} + + /*------------------------------------------------------------------------------ * Event handler for an entry being clicked in the list *----------------------------------------------------------------------------*/ @@ -409,7 +634,7 @@ SearchWindow :: onEntryClicked (GdkEventButton * event) throw () { if (event->type == GDK_BUTTON_PRESS && event->button == 3) { Glib::RefPtr refSelection = - searchResults->get_selection(); + searchResultsTreeView->get_selection(); if (refSelection) { Gtk::TreeModel::iterator iter = refSelection->get_selected(); @@ -419,7 +644,7 @@ SearchWindow :: onEntryClicked (GdkEventButton * event) throw () Gtk::TreeViewColumn * column; int cell_x, cell_y; - if (searchResults->get_path_at_pos( + if (searchResultsTreeView->get_path_at_pos( int(event->x), int(event->y), path, column, cell_x, cell_y )) { @@ -431,18 +656,20 @@ SearchWindow :: onEntryClicked (GdkEventButton * event) throw () if (iter) { Ptr::Ref playable = (*iter)[modelColumns.playableColumn]; + + if (playable) { + switch (playable->getType()) { + case Playable::AudioClipType: + contextMenu->popup(event->button, event->time); + break; + + case Playable::PlaylistType: + contextMenu->popup(event->button, event->time); + break; - switch (playable->getType()) { - case Playable::AudioClipType: - contextMenu->popup(event->button, event->time); - break; - - case Playable::PlaylistType: - contextMenu->popup(event->button, event->time); - break; - - default: - break; + default: + break; + } } } } @@ -457,11 +684,14 @@ void SearchWindow :: onAddToScratchpad(void) throw () { Glib::RefPtr refSelection = - searchResults->get_selection(); + searchResultsTreeView->get_selection(); Gtk::TreeModel::iterator iter = refSelection->get_selected(); + if (iter) { Ptr::Ref playable = (*iter)[modelColumns.playableColumn]; - gLiveSupport->addToScratchpad(playable); + if (playable) { + gLiveSupport->addToScratchpad(playable); + } } } @@ -473,12 +703,15 @@ void SearchWindow :: onAddToLiveMode(void) throw () { Glib::RefPtr refSelection = - searchResults->get_selection(); + searchResultsTreeView->get_selection(); Gtk::TreeModel::iterator iter = refSelection->get_selected(); + if (iter) { Ptr::Ref playable = (*iter)[modelColumns.playableColumn]; - gLiveSupport->addToLiveMode(playable); - gLiveSupport->addToScratchpad(playable); + if (playable) { + gLiveSupport->addToLiveMode(playable); + gLiveSupport->addToScratchpad(playable); + } } } @@ -490,19 +723,22 @@ void SearchWindow :: onExportPlaylist(void) throw () { Glib::RefPtr - refSelection = searchResults->get_selection(); - Gtk::TreeModel::iterator iter = refSelection->get_selected(); + refSelection = searchResultsTreeView->get_selection(); + Gtk::TreeModel::iterator + iter = refSelection->get_selected(); if (iter) { Ptr::Ref playable = (*iter)[modelColumns.playableColumn]; - Ptr::Ref playlist = playable->getPlaylist(); - if (playlist) { - exportPlaylistWindow.reset(new ExportPlaylistWindow( + if (playable) { + Ptr::Ref playlist = playable->getPlaylist(); + if (playlist) { + exportPlaylistWindow.reset(new ExportPlaylistWindow( gLiveSupport, gLiveSupport->getBundle("exportPlaylistWindow"), playlist)); - exportPlaylistWindow->set_transient_for(*this); - Gtk::Main::run(*exportPlaylistWindow); + exportPlaylistWindow->set_transient_for(*this); + Gtk::Main::run(*exportPlaylistWindow); + } } } } @@ -533,3 +769,30 @@ SearchWindow :: on_hide(void) throw () GuiWindow::on_hide(); } + +/*------------------------------------------------------------------------------ + * Change the displayed search results (local or remote). + *----------------------------------------------------------------------------*/ +void +SearchWindow :: onSearchWhereChanged(void) throw () +{ + Ptr::Ref searchWhere + = searchWhereEntry->getActiveKey(); + + if (*searchWhere == searchWhereLocalKey) { + searchResultsTreeView->set_model(localSearchResults); + } else { + searchResultsTreeView->set_model(remoteSearchResults); + } +} + + +/*------------------------------------------------------------------------------ + * Perform the periodic checks on the asynchronous methods. + *----------------------------------------------------------------------------*/ +void +SearchWindow :: onTimer(void) throw () +{ + remoteSearchClose(); +} + diff --git a/livesupport/src/products/gLiveSupport/src/SearchWindow.h b/livesupport/src/products/gLiveSupport/src/SearchWindow.h index 588fc9b78..2b3be37a8 100644 --- a/livesupport/src/products/gLiveSupport/src/SearchWindow.h +++ b/livesupport/src/products/gLiveSupport/src/SearchWindow.h @@ -49,6 +49,7 @@ #include "LiveSupport/Core/LocalizedObject.h" #include "LiveSupport/Widgets/Button.h" #include "LiveSupport/Widgets/PlayableTreeModelColumnRecord.h" +#include "LiveSupport/Widgets/ScrolledWindow.h" #include "GuiWindow.h" #include "AdvancedSearchEntry.h" #include "BrowseEntry.h" @@ -80,6 +81,11 @@ class SearchWindow : public GuiWindow { private: + /** + * The "search where" input field. + */ + ComboBoxText * searchWhereEntry; + /** * The simple search input field. */ @@ -100,6 +106,16 @@ class SearchWindow : public GuiWindow */ Ptr::Ref exportPlaylistWindow; + /** + * Construct the "search where" box. + * This contains a combo box, where the user can choose between + * local search or hub search. + * + * @return a pointer to the new box (already Gtk::manage()'ed) + */ + Gtk::VBox* + constructSearchWhereBox(void) throw (); + /** * Construct the simple search view. * If you enter a string in theGtk::VBox simple search view and @@ -135,7 +151,7 @@ class SearchWindow : public GuiWindow * * @return a pointer to the new tree view (already Gtk::manage()'ed) */ - ZebraTreeView * + ScrolledWindow * constructSearchResultsView(void) throw (); /** @@ -158,9 +174,51 @@ class SearchWindow : public GuiWindow /** * Do the searching. + * Calls either localSearch() or remoteSearch(). + * + * @param criteria the search criteria. */ void - onSearch(Ptr::Ref criteria) throw (); + onSearch(Ptr::Ref criteria) throw (); + + /** + * Change the displayed search results (local or remote). + */ + void + onSearchWhereChanged(void) throw (); + + /** + * Search in the local storage. + * + * @param criteria the search criteria. + */ + void + localSearch(Ptr::Ref criteria) throw (); + + /** + * Search on the network hub (initiate the async operation). + * + * @param criteria the search criteria. + */ + void + remoteSearchOpen(Ptr::Ref criteria) throw (); + + /** + * Search on the network hub (finish the async operation). + */ + void + remoteSearchClose(void) throw (); + + /** + * Display the search results. + * The most important metadata are shown in the rows of the given + * tree model. + */ + void + displaySearchResults( + Ptr::Ref> >::Ref searchResults, + Glib::RefPtr treeModel) + throw (); /** * Signal handler for the mouse clicked on one of the entries. @@ -258,21 +316,42 @@ class SearchWindow : public GuiWindow ModelColumns modelColumns; /** - * The tree model, as a GTK reference. + * The tree model, as a GTK reference, for the local search results. */ - Glib::RefPtr treeModel; + Glib::RefPtr localSearchResults; + + /** + * The tree model, as a GTK reference, for the remote search results. + */ + Glib::RefPtr remoteSearchResults; /** * The tree view showing the search results. */ - ZebraTreeView * searchResults; + ZebraTreeView * searchResultsTreeView; + + /** + * The transport token used when a remote search is pending. + */ + Ptr::Ref remoteSearchToken; /** * The pop-up context menu for found items. */ Gtk::Menu * contextMenu; - + + /** + * Display a (usually error) message in the search results tree view. + * + * @param messageKey the localization key for the message. + * @param treeModel the tree model to display the message in. + */ + void + displayMessage(const Glib::ustring & messageKey, + Glib::RefPtr treeModel) + throw (); + public: /** @@ -295,6 +374,14 @@ class SearchWindow : public GuiWindow */ virtual ~SearchWindow(void) throw (); + + /** + * Perform the periodic checks on the asynchronous methods. + * This is called every few seconds by the onUpdateTime() function + * in the MasterPanelWindow. + */ + void + onTimer(void) throw (); }; /* ================================================= external data structures */ diff --git a/livesupport/src/products/gLiveSupport/var/root.txt b/livesupport/src/products/gLiveSupport/var/root.txt index d6426fb99..010b2e04d 100644 --- a/livesupport/src/products/gLiveSupport/var/root.txt +++ b/livesupport/src/products/gLiveSupport/var/root.txt @@ -184,6 +184,10 @@ root:table searchWindow:table { windowTitle:string { "Search/Browse" } + + searchWhereLabel:string { "Search or browse on: " } + searchWhereLocal:string { "local storage" } + searchWhereRemote:string { "network hub" } simpleSearchTab:string { "Search" } advancedSearchTab:string { "Advanced Search" } @@ -201,6 +205,9 @@ root:table addToScratchpadMenuItem:string { "_Add To Scratchpad" } addToLiveModeMenuItem:string { "Add To _Live Mode" } exportPlaylistMenuItem:string { "E_xport Playlist" } + + pleaseWaitMsg:string { "Please wait..." } + remoteSearchErrorMsg:string { "Search failed: {0}." } } advancedSearchEntry:table {