From 7b23ed6103783de3c72b7c42ab4f0bf1c77c1d59 Mon Sep 17 00:00:00 2001 From: fgerlits Date: Mon, 30 Oct 2006 12:43:30 +0000 Subject: [PATCH] Fixing #1895, first draft. Known problems: * no paging in the network hub results (see SearchWindow.cxx:703); * row coloring problem #1902. --- .../include/LiveSupport/Core/SearchCriteria.h | 23 +++ .../products/gLiveSupport/src/BrowseItem.cxx | 2 +- .../gLiveSupport/src/GLiveSupport.cxx | 6 +- .../products/gLiveSupport/src/GLiveSupport.h | 7 +- .../gLiveSupport/src/SearchWindow.cxx | 168 ++++++++++++++++-- .../products/gLiveSupport/src/SearchWindow.h | 135 +++++++++++++- 6 files changed, 311 insertions(+), 30 deletions(-) diff --git a/campcaster/src/modules/core/include/LiveSupport/Core/SearchCriteria.h b/campcaster/src/modules/core/include/LiveSupport/Core/SearchCriteria.h index 76fe4a79b..984af5ad5 100644 --- a/campcaster/src/modules/core/include/LiveSupport/Core/SearchCriteria.h +++ b/campcaster/src/modules/core/include/LiveSupport/Core/SearchCriteria.h @@ -318,6 +318,17 @@ class SearchCriteria condition->value); } + /** + * Get the limit field. + * + * @return the maximum number of search results to be returned + */ + int + getLimit() throw() + { + return limit; + } + /** * Set the limit field. * @@ -335,6 +346,18 @@ class SearchCriteria } } + /** + * Get the offset field. + * + * @return the index of the first matching condition + * to be returned (first = 0) + */ + int + getOffset() throw() + { + return offset; + } + /** * Set the offset field. * diff --git a/campcaster/src/products/gLiveSupport/src/BrowseItem.cxx b/campcaster/src/products/gLiveSupport/src/BrowseItem.cxx index fd3f649ea..8505f53be 100644 --- a/campcaster/src/products/gLiveSupport/src/BrowseItem.cxx +++ b/campcaster/src/products/gLiveSupport/src/BrowseItem.cxx @@ -82,7 +82,7 @@ BrowseItem :: BrowseItem( metadataValues = Gtk::manage(wf->createTreeView(treeModel)); metadataValues->appendColumn("", modelColumns.column, 200); - metadataValues->set_size_request(230,150); + metadataValues->set_size_request(230, 150); metadataValues->set_headers_visible(false); metadataValues->signal_cursor_changed().connect(sigc::mem_fun(*this, &BrowseItem::emitSignalSelectionChanged )); diff --git a/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx b/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx index fea8bb07c..d3a4fa5e3 100644 --- a/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx +++ b/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx @@ -1391,14 +1391,12 @@ GLiveSupport :: detachCueAudioListener(AudioPlayerEventListener * listener) /*------------------------------------------------------------------------------ * Search in the local storage. *----------------------------------------------------------------------------*/ -Ptr::Ref +int LiveSupport :: GLiveSupport :: GLiveSupport :: search(Ptr::Ref criteria) throw (XmlRpcException) { - storage->search(sessionId, criteria); - - return getSearchResults(); + return storage->search(sessionId, criteria); } diff --git a/campcaster/src/products/gLiveSupport/src/GLiveSupport.h b/campcaster/src/products/gLiveSupport/src/GLiveSupport.h index d7776fa53..2dd736ddf 100644 --- a/campcaster/src/products/gLiveSupport/src/GLiveSupport.h +++ b/campcaster/src/products/gLiveSupport/src/GLiveSupport.h @@ -962,13 +962,16 @@ class GLiveSupport : public LocalizedConfigurable, /** * Search in the local storage. + * Note that the return value (number of items found) will not be + * the same as the size of getSearchResults() if the limit and offset + * fields in the criteria parameter are not zero. * * @param criteria the search conditions to use. - * @return the list of audio clips and playlists found. + * @return the number of audio clips and playlists found. * @exception XmlRpcException thrown by * StorageClientInterface::search() */ - Ptr::Ref + int search(Ptr::Ref criteria) throw (XmlRpcException); diff --git a/campcaster/src/products/gLiveSupport/src/SearchWindow.cxx b/campcaster/src/products/gLiveSupport/src/SearchWindow.cxx index 9d890e151..c159628da 100644 --- a/campcaster/src/products/gLiveSupport/src/SearchWindow.cxx +++ b/campcaster/src/products/gLiveSupport/src/SearchWindow.cxx @@ -62,12 +62,27 @@ namespace { /*------------------------------------------------------------------------------ * The 'search where' combo box key for local searches. *----------------------------------------------------------------------------*/ -const std::string searchWhereLocalKey = "searchWhereLocal"; +const std::string searchWhereLocalKey = "searchWhereLocal"; /*------------------------------------------------------------------------------ * The 'search where' combo box key for remote searches. *----------------------------------------------------------------------------*/ -const std::string searchWhereRemoteKey = "searchWhereRemote"; +const std::string searchWhereRemoteKey = "searchWhereRemote"; + +/*------------------------------------------------------------------------------ + * The number of items which can be shown in the search results. + *----------------------------------------------------------------------------*/ +const int searchResultsSize = 10; + +/*------------------------------------------------------------------------------ + * The label for the Backward button. + *----------------------------------------------------------------------------*/ +const Glib::ustring backwardButtonText = "⇧"; + +/*------------------------------------------------------------------------------ + * The label for the Forward button. + *----------------------------------------------------------------------------*/ +const Glib::ustring forwardButtonText = "⇩"; } @@ -111,16 +126,16 @@ SearchWindow :: SearchWindow (Ptr::Ref gLiveSupport, } // set up the search results box - ScrolledWindow * searchResultsView = constructSearchResultsView(); + Gtk::Box * searchResultsView = constructSearchResultsView(); // set the sizes of the two parts of the window - searchInput ->set_size_request(750, 240); - searchResultsView->set_size_request(750, 300); + searchInput ->set_size_request(750, 231); + searchResultsView->set_size_request(750, 340); // put them in one big box Gtk::VBox * bigBox = Gtk::manage(new Gtk::VBox); bigBox->pack_start(*searchWhereBox, Gtk::PACK_SHRINK); - bigBox->pack_start(*searchInput, Gtk::PACK_SHRINK); + bigBox->pack_start(*searchInput, Gtk::PACK_SHRINK); bigBox->pack_start(*searchResultsView); add(*bigBox); @@ -318,7 +333,7 @@ SearchWindow :: constructTransportsView(void) throw () /*------------------------------------------------------------------------------ * Construct the search results display. *----------------------------------------------------------------------------*/ -ScrolledWindow * +Gtk::Box * SearchWindow :: constructSearchResultsView(void) throw () { Ptr::Ref wf = WidgetFactory::getInstance(); @@ -341,16 +356,16 @@ SearchWindow :: constructSearchResultsView(void) throw () modelColumns.typeColumn, 20); searchResultsTreeView->appendColumn( *getResourceUstring("titleColumnLabel"), - modelColumns.titleColumn, 320); + modelColumns.titleColumn, 300); searchResultsTreeView->appendColumn( *getResourceUstring("creatorColumnLabel"), modelColumns.creatorColumn, 200); searchResultsTreeView->appendColumn( *getResourceUstring("sourceColumnLabel"), - modelColumns.sourceColumn, 150); + modelColumns.sourceColumn, 145); searchResultsTreeView->appendCenteredColumn( *getResourceUstring("lengthColumnLabel"), - modelColumns.lengthColumn, 50); + modelColumns.lengthColumn, 55); } catch (std::invalid_argument &e) { std::cerr << e.what() << std::endl; std::exit(1); @@ -368,11 +383,27 @@ SearchWindow :: constructSearchResultsView(void) throw () constructRemoteContextMenu(); // 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); + ScrolledWindow * resultsWindow = Gtk::manage(new ScrolledWindow); + resultsWindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + resultsWindow->add(*searchResultsTreeView); + + // create the page backward and forward buttons + backwardButton = Gtk::manage(wf->createButton(backwardButtonText)); + forwardButton = Gtk::manage(wf->createButton(forwardButtonText)); + + backwardButton->signal_clicked().connect(sigc::mem_fun(*this, + &SearchWindow::onBackwardButtonClicked)); + forwardButton->signal_clicked().connect(sigc::mem_fun(*this, + &SearchWindow::onForwardButtonClicked)); + updateBackwardAndForwardButtons(); - return view; + // pack everything in a box + Gtk::Box * view = Gtk::manage(new Gtk::VBox); + view->pack_start(*backwardButton, Gtk::PACK_SHRINK, 2); + view->pack_start(*resultsWindow, Gtk::PACK_EXPAND_WIDGET, 0); + view->pack_start(*forwardButton, Gtk::PACK_SHRINK, 2); + + return view; } @@ -407,7 +438,7 @@ SearchWindow :: onSimpleSearch(void) throw () criteria->addCondition(*metadata->getDcName(), "partial", value); } - onSearch(criteria); + onInitialSearch(criteria); } @@ -417,7 +448,7 @@ SearchWindow :: onSimpleSearch(void) throw () void SearchWindow :: onAdvancedSearch(void) throw () { - onSearch(advancedSearchEntry->getSearchCriteria()); + onInitialSearch(advancedSearchEntry->getSearchCriteria()); } @@ -427,7 +458,33 @@ SearchWindow :: onAdvancedSearch(void) throw () void SearchWindow :: onBrowse(void) throw () { - onSearch(browseEntry->getSearchCriteria()); + onInitialSearch(browseEntry->getSearchCriteria()); +} + + +/*------------------------------------------------------------------------------ + * Do the searching (first set of results). + *----------------------------------------------------------------------------*/ +void +SearchWindow :: onInitialSearch(Ptr::Ref criteria) + throw () +{ + criteria->setOffset(0); + criteria->setLimit(getSearchResultsSize()); + onSearch(criteria); +} + + +/*------------------------------------------------------------------------------ + * Do the searching (after paging backward or forward). + *----------------------------------------------------------------------------*/ +void +SearchWindow :: onContinuedSearch(int offset) + throw () +{ + Ptr::Ref criteria = getSearchCriteria(); + criteria->setOffset(offset); + onSearch(criteria); } @@ -458,12 +515,15 @@ SearchWindow :: localSearch(Ptr::Ref criteria) Ptr::Ref searchResults; try { - searchResults = gLiveSupport->search(criteria); + localSearchResultsCount = gLiveSupport->search(criteria); + searchResults = gLiveSupport->getSearchResults(); } catch (XmlRpcException &e) { displayLocalSearchError(e); return; } + localSearchCriteria = criteria; + displaySearchResults(searchResults, localSearchResults); } @@ -479,6 +539,7 @@ SearchWindow :: displaySearchResults( { treeModel->clear(); searchResultsTreeView->set_model(treeModel); + updateBackwardAndForwardButtons(); Ptr::Ref widgetFactory = WidgetFactory::getInstance(); @@ -595,6 +656,8 @@ SearchWindow :: remoteSearchOpen(Ptr::Ref criteria) } catch (XmlRpcException &e) { displayRemoteSearchError(e); } + + remoteSearchCriteria = criteria; } @@ -637,6 +700,7 @@ SearchWindow :: remoteSearchClose(void) return; } + remoteSearchResultsCount = results->size(); // FIXME displaySearchResults(results, remoteSearchResults); } else if (state == AsyncState::closedState) { @@ -971,6 +1035,8 @@ SearchWindow :: onSearchWhereChanged(void) throw () } else { searchResultsTreeView->set_model(remoteSearchResults); } + + updateBackwardAndForwardButtons(); } @@ -1073,3 +1139,69 @@ SearchWindow :: constructRemoteContextMenu(void) throw () remoteContextMenu->accelerate(*this); } + +/*------------------------------------------------------------------------------ + * Return the number of search results which can be displayed. + *----------------------------------------------------------------------------*/ +int +SearchWindow :: getSearchResultsSize(void) throw () +{ + return searchResultsSize; +} + + +/*------------------------------------------------------------------------------ + * Event handler for a click on the Backward button. + *----------------------------------------------------------------------------*/ +void +SearchWindow :: onBackwardButtonClicked(void) throw () +{ + Ptr::Ref criteria = getSearchCriteria(); + int offset = criteria->getOffset(); + + if (offset > 0) { + int newOffset = offset - getSearchResultsSize(); + if (newOffset < 0) { + newOffset = 0; + } + onContinuedSearch(newOffset); + } +} + + +/*------------------------------------------------------------------------------ + * Event handler for a click on the Forward button. + *----------------------------------------------------------------------------*/ +void +SearchWindow :: onForwardButtonClicked(void) throw () +{ + Ptr::Ref criteria = getSearchCriteria(); + int offset = criteria->getOffset(); + int count = getSearchResultsCount(); + + int newOffset = offset + getSearchResultsSize(); + if (newOffset < count) { + onContinuedSearch(newOffset); + } +} + + +/*------------------------------------------------------------------------------ + * Enable or disable the Backward and Forward buttons. + *----------------------------------------------------------------------------*/ +void +SearchWindow :: updateBackwardAndForwardButtons(void) throw () +{ + Ptr::Ref criteria = getSearchCriteria(); + + if (criteria) { + int offset = criteria->getOffset(); + int count = getSearchResultsCount(); + backwardButton->setDisabled(offset == 0); + forwardButton->setDisabled(offset + getSearchResultsSize() >= count); + } else { + backwardButton->setDisabled(true); + forwardButton->setDisabled(true); + } +} + diff --git a/campcaster/src/products/gLiveSupport/src/SearchWindow.h b/campcaster/src/products/gLiveSupport/src/SearchWindow.h index ffb1cd5e9..5a082a74d 100644 --- a/campcaster/src/products/gLiveSupport/src/SearchWindow.h +++ b/campcaster/src/products/gLiveSupport/src/SearchWindow.h @@ -83,6 +83,26 @@ class SearchWindow : public GuiWindow { private: + /** + * The criteria for the last local search. + */ + Ptr::Ref localSearchCriteria; + + /** + * The criteria for the last remote search. + */ + Ptr::Ref remoteSearchCriteria; + + /** + * The number of items found by the last local search. + */ + int localSearchResultsCount; + + /** + * The number of items found by the last remote search. + */ + int remoteSearchResultsCount; + /** * The "search where" input field. */ @@ -108,6 +128,16 @@ class SearchWindow : public GuiWindow */ TransportList * transportList; + /** + * The button for paging in the search results backward. + */ + Button * backwardButton; + + /** + * The button for paging in the search results forward. + */ + Button * forwardButton; + /** * The Export Playlist pop-up window. */ @@ -164,9 +194,9 @@ class SearchWindow : public GuiWindow /** * Construct the search results display. * - * @return a pointer to the new tree view (already Gtk::manage()'ed) + * @return a pointer to the new view (already Gtk::manage()'ed) */ - ScrolledWindow * + Gtk::Box * constructSearchResultsView(void) throw (); /** @@ -206,6 +236,24 @@ class SearchWindow : public GuiWindow void onBrowse(void) throw (); + /** + * Do the searching (first set of results). + * Sets the offset to 0, and calls onSearch(). + * + * @param criteria the search criteria. + */ + void + onInitialSearch(Ptr::Ref criteria) throw (); + + /** + * Do the searching (after paging backward or forward). + * Sets the offset to the given value, and calls onSearch(). + * + * @param offset the new offset to use for this search. + */ + void + onContinuedSearch(int offset) throw (); + /** * Do the searching. * Calls either localSearch() or remoteSearch(). @@ -221,6 +269,55 @@ class SearchWindow : public GuiWindow bool searchIsLocal(void) throw (); + /** + * Get the search criteria used for the last search + * of the currently selected kind. + * Returns either localSearchCriteria or remoteSearchCriteria + * depending on the value of searchIsLocal(). + * + * @return the saved search criteria of the appropriate kind; + * or a 0 pointer if nothing has been saved yet. + */ + Ptr::Ref + getSearchCriteria(void) throw () + { + return searchIsLocal() ? localSearchCriteria + : remoteSearchCriteria; + } + + /** + * Set the search criteria for the currently selected kind. + * Sets either localSearchCriteria or remoteSearchCriteria + * depending on the value of searchIsLocal(). + * + * @param criteria the new criteria to be saved. + */ + void + setSearchCriteria(Ptr::Ref criteria) throw () + { + if (searchIsLocal()) { + localSearchCriteria = criteria; + } else { + remoteSearchCriteria = criteria; + } + } + + /** + * Get the number of search results found by the last search + * of the currently selected kind. + * Returns either localSearchResultsCount or remoteSearchResultsCount + * depending on the value of searchIsLocal(). + * + * @return the saved search result count of the appropriate kind; + * undefined if nothing has been saved yet. + */ + int + getSearchResultsCount(void) throw () + { + return searchIsLocal() ? localSearchResultsCount + : remoteSearchResultsCount; + } + /** * Change the displayed search results (local or remote). */ @@ -260,6 +357,12 @@ class SearchWindow : public GuiWindow Glib::RefPtr treeModel) throw (); + /** + * Enable or disable the Backward and Forward buttons. + */ + void + updateBackwardAndForwardButtons(void) throw (); + /** * Sorting function for the search results. * @@ -311,21 +414,33 @@ class SearchWindow : public GuiWindow * Signal handler for the "export playlist" menu item selected from * the entry context menu. */ - virtual void + void onExportPlaylist(void) throw (); /** * Signal handler for "upload to hub" in the context menu. */ - virtual void + void onUploadToHub(void) throw (); /** * Signal handler for "download from hub" in the context menu. */ - virtual void + void onDownloadFromHub(void) throw (); + /** + * Event handler for a click on the Backward button. + */ + void + onBackwardButtonClicked(void) throw (); + + /** + * Event handler for a click on the Forward button. + */ + void + onForwardButtonClicked(void) throw (); + /** * Event handler called when the the window gets hidden. * @@ -469,6 +584,16 @@ class SearchWindow : public GuiWindow displayRemoteSearchError(const XmlRpcException & error) throw (); + /** + * Return the number of search results which can be displayed. + * As currently implemented, this returns a constant 10. + * + * @return the number of rows which can be displayed in the + * search results section of the window. + */ + int + getSearchResultsSize(void) throw (); + public: