From b7e25b5a33a1f6e37b887b14bd1ecfef4ef8298e Mon Sep 17 00:00:00 2001 From: fgerlits Date: Thu, 11 Oct 2007 16:28:57 +0000 Subject: [PATCH] multiple selection for right-click in the Scratchpad window --- .../gLiveSupport/src/ScratchpadWindow.cxx | 141 +++++++++--------- .../gLiveSupport/src/ScratchpadWindow.h | 42 ++++-- 2 files changed, 99 insertions(+), 84 deletions(-) diff --git a/campcaster/src/products/gLiveSupport/src/ScratchpadWindow.cxx b/campcaster/src/products/gLiveSupport/src/ScratchpadWindow.cxx index 43a6d1b8f..d973c4a44 100644 --- a/campcaster/src/products/gLiveSupport/src/ScratchpadWindow.cxx +++ b/campcaster/src/products/gLiveSupport/src/ScratchpadWindow.cxx @@ -100,8 +100,9 @@ ScratchpadWindow :: ScratchpadWindow ( treeView->connectModelSignals(treeModel); // register the signal handlers for treeview - treeView->signal_button_press_event().connect_notify(sigc::mem_fun(*this, - &ScratchpadWindow::onEntryClicked)); + treeView->signal_button_press_event().connect(sigc::mem_fun(*this, + &ScratchpadWindow::onEntryClicked), + false /* call this first */); treeView->signal_row_activated().connect(sigc::mem_fun(*this, &ScratchpadWindow::onDoubleClick)); treeView->signal_key_press_event().connect(sigc::mem_fun(*this, @@ -183,66 +184,62 @@ ScratchpadWindow :: ScratchpadWindow ( /*------------------------------------------------------------------------------ * Event handler for an entry being clicked in the list *----------------------------------------------------------------------------*/ -void +bool ScratchpadWindow :: onEntryClicked (GdkEventButton * event) throw () { if (event->type == GDK_BUTTON_PRESS && event->button == 3) { - Gtk::TreePath currentPath; - Gtk::TreeViewColumn * column; - int cell_x, - cell_y; - bool foundValidRow = treeView->get_path_at_pos( - int(event->x), int(event->y), - currentPath, column, - cell_x, cell_y); + Glib::RefPtr + selection = treeView->get_selection(); + selectedPaths.reset(new std::vector( + selection->get_selected_rows())); - if (foundValidRow) { - Gtk::TreeIter iter = treeModel->get_iter(currentPath); - if (iter) { - currentRow = *iter; - + if (selectedPaths->size() > 0) { + selectedIter = selectedPaths->begin(); + + if (selectedPaths->size() == 1) { + Gtk::TreeRow row = *(treeModel->get_iter(*selectedIter)); Ptr::Ref - playable = currentRow[modelColumns.playableColumn]; + playable = row[modelColumns.playableColumn]; - switch (playable->getType()) { - case Playable::AudioClipType: - audioClipMenu->popup(event->button, event->time); - break; - - case Playable::PlaylistType: - playlistMenu->popup(event->button, event->time); - break; - - default: - break; + if (playable->getType() == Playable::AudioClipType) { + audioClipMenu->popup(event->button, event->time); + return true; + + } else if (playable->getType() == Playable::PlaylistType) { + playlistMenu->popup(event->button, event->time); + return true; } + + } else { // selectedPaths.size() > 1 + audioClipMenu->popup(event->button, event->time); + return true; } } } + + return false; } /*------------------------------------------------------------------------------ - * Select the row which contains the playable specified. + * Return the next selected playable item. *----------------------------------------------------------------------------*/ -void -ScratchpadWindow :: selectRow(Ptr::Ref playable) throw () +Ptr::Ref +ScratchpadWindow :: getNextSelectedPlayable(void) throw () { - Gtk::TreeModel::const_iterator it; - - for (it = treeModel->children().begin(); - it != treeModel->children().end(); ++it) { - - Gtk::TreeRow row = *it; - Ptr::Ref currentPlayable = row[modelColumns.playableColumn]; - - if (*playable->getId() == *currentPlayable->getId()) { - Glib::RefPtr - selection = treeView->get_selection(); - selection->select(it); - return; + Ptr::Ref playable; + + if (selectedPaths) { + if (selectedIter != selectedPaths->end()) { + Gtk::TreeRow row = *(treeModel->get_iter(*selectedIter)); + playable = row[modelColumns.playableColumn]; + ++selectedIter; + } else { + selectedPaths.reset(); } } + + return playable; } @@ -275,7 +272,8 @@ ScratchpadWindow :: removeItem(Ptr::Ref id) throw () void ScratchpadWindow :: onEditPlaylist(void) throw () { - Ptr::Ref playable = currentRow[modelColumns.playableColumn]; + Ptr::Ref playable = getNextSelectedPlayable(); + try { gLiveSupport->openPlaylistForEditing(playable->getId()); } catch (XmlRpcException &e) { @@ -292,7 +290,7 @@ ScratchpadWindow :: onEditPlaylist(void) throw () void ScratchpadWindow :: onSchedulePlaylist(void) throw () { - Ptr::Ref playable = currentRow[modelColumns.playableColumn]; + Ptr::Ref playable = getNextSelectedPlayable(); Ptr::Ref playlist = playable->getPlaylist(); if (playlist) { @@ -309,7 +307,7 @@ ScratchpadWindow :: onSchedulePlaylist(void) throw () void ScratchpadWindow :: onExportPlaylist(void) throw () { - Ptr::Ref playable = currentRow[modelColumns.playableColumn]; + Ptr::Ref playable = getNextSelectedPlayable(); Ptr::Ref playlist = playable->getPlaylist(); if (playlist) { @@ -327,13 +325,16 @@ ScratchpadWindow :: onExportPlaylist(void) throw () void ScratchpadWindow :: onAddToPlaylist(void) throw () { - Ptr::Ref playable = currentRow[modelColumns.playableColumn]; - try { - gLiveSupport->addToPlaylist(playable->getId()); - } catch (XmlRpcException &e) { - std::cerr << "error in ScratchpadWindow::onAddToPlaylist(): " - << e.what() << std::endl; - return; + Ptr::Ref playable; + + while ((playable = getNextSelectedPlayable())) { + try { + gLiveSupport->addToPlaylist(playable->getId()); + } catch (XmlRpcException &e) { + std::cerr << "error in ScratchpadWindow::onAddToPlaylist(): " + << e.what() << std::endl; + return; + } } } @@ -345,8 +346,11 @@ ScratchpadWindow :: onAddToPlaylist(void) throw () void ScratchpadWindow :: onAddToLiveMode(void) throw () { - Ptr::Ref playable = currentRow[modelColumns.playableColumn]; - gLiveSupport->addToLiveMode(playable); + Ptr::Ref playable; + + while ((playable = getNextSelectedPlayable())) { + gLiveSupport->addToLiveMode(playable); + } } @@ -356,8 +360,11 @@ ScratchpadWindow :: onAddToLiveMode(void) throw () void ScratchpadWindow :: onUploadToHub(void) throw () { - Ptr::Ref playable = currentRow[modelColumns.playableColumn]; - gLiveSupport->uploadToHub(playable); + Ptr::Ref playable; + + while ((playable = getNextSelectedPlayable())) { + gLiveSupport->uploadToHub(playable); + } } @@ -403,9 +410,13 @@ ScratchpadWindow :: onDoubleClick(const Gtk::TreeModel::Path & path, const Gtk::TreeViewColumn * column) throw () { - Gtk::TreeIter iter = treeModel->get_iter(path); - if (iter) { - currentRow = *iter; + Glib::RefPtr + selection = treeView->get_selection(); + selectedPaths.reset(new std::vector( + selection->get_selected_rows())); + + if (selectedPaths->size() > 0) { + selectedIter = selectedPaths->begin(); onAddToLiveMode(); } } @@ -460,13 +471,7 @@ ScratchpadWindow :: isSelectionSingle(void) throw () std::vector selectedRows = selection->get_selected_rows(); - if (selectedRows.size() == 1) { - Gtk::TreeIter iter = treeModel->get_iter(selectedRows.at(0)); - currentRow = *iter; - return true; - } else { - return false; - } + return (selectedRows.size() == 1); } diff --git a/campcaster/src/products/gLiveSupport/src/ScratchpadWindow.h b/campcaster/src/products/gLiveSupport/src/ScratchpadWindow.h index a670dc55f..6cbfb1ee5 100644 --- a/campcaster/src/products/gLiveSupport/src/ScratchpadWindow.h +++ b/campcaster/src/products/gLiveSupport/src/ScratchpadWindow.h @@ -95,24 +95,25 @@ class ScratchpadWindow : public GuiWindow, Ptr::Ref schedulePlaylistWindow; /** - * Check whether exactly one row is selected, and if so, set - * the currentRow variable to point to it. + * Used to iterate over the selected rows. + * Reset to the first row by onEntryClicked(). + * Returns a 0 pointer if nothing is selected or we have reached + * the end of the list of selected rows. + * + * @return the next selected item. + */ + Ptr::Ref + getNextSelectedPlayable(void) throw (); + + /** + * Check whether exactly one row is selected. * * This is an auxilliary function used by onKeyPressed(). * * @return true if a single row is selected, false if not. */ bool - isSelectionSingle(void) throw (); - - /** - * Select the (first) row which contains the playable specified. - * If no such row is found, then it does nothing. - * - * @param playable the playable to be selected. - */ - void - selectRow(Ptr::Ref playable) throw (); + isSelectionSingle(void) throw (); /** * Remove an item from the Scratchpad. @@ -124,7 +125,7 @@ class ScratchpadWindow : public GuiWindow, * @param id the id of the item to remove. */ void - removeItem(Ptr::Ref id) throw (); + removeItem(Ptr::Ref id) throw (); protected: @@ -184,9 +185,16 @@ class ScratchpadWindow : public GuiWindow, ZebraTreeView * treeView; /** - * The model row at the mouse pointer, set by onEntryClicked() + * The list of selected rows, as path references (row numbers). + * Reset by onEntryClicked(); */ - Gtk::TreeRow currentRow; + Ptr >::Ref + selectedPaths; + /** + * One of the selected rows, set to the first one by onEntryClicked(). + */ + std::vector::const_iterator + selectedIter; /** * The cue player widget controlling the audio buttons. @@ -210,8 +218,10 @@ class ScratchpadWindow : public GuiWindow, * This is used to pop up the right-click context menu. * * @param event the button event recieved + * @return true if the event has been handled (a popup displayed), + * false otherwise */ - virtual void + virtual bool onEntryClicked(GdkEventButton * event) throw (); /**