diff --git a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h index edb893873..2ae3fa4bf 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h +++ b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.39 $ + Version : $Revision: 1.40 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Playlist.h,v $ ------------------------------------------------------------------------------*/ @@ -128,7 +128,7 @@ using namespace boost::posix_time; * * * @author $Author: fgerlits $ - * @version $Revision: 1.39 $ + * @version $Revision: 1.40 $ */ class Playlist : public Configurable, public Playable @@ -176,17 +176,6 @@ class Playlist : public Configurable, */ Ptr::Ref elementList; - /** - * Add a new playlist element to the playlist. - * - * @param playlistElement the new playlist element to be added - * @exception std::invalid_argument if the playlist already contains - * a playlist element with the same relative offset - */ - void - addPlaylistElement(Ptr::Ref playlistElement) - throw (std::invalid_argument); - /** * A saved copy of this playlist. */ @@ -626,6 +615,15 @@ class Playlist : public Configurable, = Ptr::Ref()) throw (); + /** + * Add a new playlist element to the playlist. + * + * @param playlistElement the new playlist element to be added + */ + void + addPlaylistElement(Ptr::Ref playlistElement) + throw (); + /** * Set the fade in / fade out info for a playlist element. * diff --git a/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h b/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h index 4c3ce0e63..f123fb6e8 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h +++ b/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.13 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.14 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h,v $ ------------------------------------------------------------------------------*/ @@ -103,8 +103,8 @@ class Playlist; * <!ATTLIST playlistElement relativeOffset NMTOKEN #REQUIRED > * * - * @author $Author: maroy $ - * @version $Revision: 1.13 $ + * @author $Author: fgerlits $ + * @version $Revision: 1.14 $ */ class PlaylistElement : public Configurable { @@ -297,6 +297,21 @@ class PlaylistElement : public Configurable return id; } + /** + * Set the relative offset of the playlist element. + * Note: this is very dangerous; use only if you know what you are + * doing. Never ever change the relative offset of a PlaylistElement + * which is contained in a Playlist. + * + * @param newOffset the new relative offset of the element. + */ + void + setRelativeOffset(Ptr::Ref newOffset) + throw () + { + relativeOffset = newOffset; + } + /** * Return the relative offset of the playlist element. * diff --git a/livesupport/modules/core/src/Playlist.cxx b/livesupport/modules/core/src/Playlist.cxx index f0d8c5188..cd3b83b67 100644 --- a/livesupport/modules/core/src/Playlist.cxx +++ b/livesupport/modules/core/src/Playlist.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.38 $ + Version : $Revision: 1.39 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Playlist.cxx,v $ ------------------------------------------------------------------------------*/ @@ -431,7 +431,7 @@ Playlist :: configure(const xmlpp::Element & element) *----------------------------------------------------------------------------*/ void Playlist::addPlaylistElement(Ptr::Ref playlistElement) - throw (std::invalid_argument) + throw () { Ptr::Ref relativeOffset = playlistElement->getRelativeOffset(); diff --git a/livesupport/products/gLiveSupport/src/ScratchpadWindow.cxx b/livesupport/products/gLiveSupport/src/ScratchpadWindow.cxx index a91d4484d..d9b62ee7b 100644 --- a/livesupport/products/gLiveSupport/src/ScratchpadWindow.cxx +++ b/livesupport/products/gLiveSupport/src/ScratchpadWindow.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.26 $ + Version : $Revision: 1.27 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/gLiveSupport/src/ScratchpadWindow.cxx,v $ ------------------------------------------------------------------------------*/ @@ -387,19 +387,7 @@ ScratchpadWindow :: onEntryClicked (GdkEventButton * event) throw () /*------------------------------------------------------------------------------ - * Event handler for the Remove menu item selected from the entry conext menu - *----------------------------------------------------------------------------*/ -void -ScratchpadWindow :: onRemoveItem(void) throw () -{ - Ptr::Ref playable = currentRow[modelColumns.playableColumn]; - removeItem(playable->getId()); - showContents(); -} - - -/*------------------------------------------------------------------------------ - * Event handler for the Up menu item selected from the entry conext menu + * Event handler for the Up menu item selected from the entry context menu *----------------------------------------------------------------------------*/ void ScratchpadWindow :: onUpItem(void) throw () @@ -435,7 +423,7 @@ ScratchpadWindow :: onUpItem(void) throw () /*------------------------------------------------------------------------------ - * Event handler for the Down menu item selected from the entry conext menu + * Event handler for the Down menu item selected from the entry context menu *----------------------------------------------------------------------------*/ void ScratchpadWindow :: onDownItem(void) throw () @@ -473,6 +461,18 @@ ScratchpadWindow :: onDownItem(void) throw () } +/*------------------------------------------------------------------------------ + * Event handler for the Remove menu item selected from the entry context menu + *----------------------------------------------------------------------------*/ +void +ScratchpadWindow :: onRemoveItem(void) throw () +{ + Ptr::Ref playable = currentRow[modelColumns.playableColumn]; + removeItem(playable->getId()); + showContents(); +} + + /*------------------------------------------------------------------------------ * Remove an item from the Scratchpad *----------------------------------------------------------------------------*/ diff --git a/livesupport/products/gLiveSupport/src/ScratchpadWindow.h b/livesupport/products/gLiveSupport/src/ScratchpadWindow.h index 32ed3b24f..af3eae5eb 100644 --- a/livesupport/products/gLiveSupport/src/ScratchpadWindow.h +++ b/livesupport/products/gLiveSupport/src/ScratchpadWindow.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.10 $ + Version : $Revision: 1.11 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/gLiveSupport/src/ScratchpadWindow.h,v $ ------------------------------------------------------------------------------*/ @@ -73,7 +73,7 @@ using namespace LiveSupport::Widgets; * playlists. * * @author $Author: fgerlits $ - * @version $Revision: 1.10 $ + * @version $Revision: 1.11 $ */ class ScratchpadWindow : public WhiteWindow, public LocalizedObject @@ -87,7 +87,7 @@ class ScratchpadWindow : public WhiteWindow, * Lists one clip per row. * * @author $Author: fgerlits $ - * @version $Revision: 1.10 $ + * @version $Revision: 1.11 $ */ class ModelColumns : public PlayableTreeModelColumnRecord { @@ -216,19 +216,13 @@ class ScratchpadWindow : public WhiteWindow, /** * Signal handler for the mouse clicked on one of the entries. + * This is used to pop up the right-click context menu. * * @param event the button event recieved */ virtual void onEntryClicked(GdkEventButton * event) throw (); - /** - * Signal handler for the "remove" menu item selected from - * the entry context menu. - */ - virtual void - onRemoveItem(void) throw (); - /** * Signal handler for the "up" menu item selected from * the entry context menu. @@ -243,6 +237,13 @@ class ScratchpadWindow : public WhiteWindow, virtual void onDownItem(void) throw (); + /** + * Signal handler for the "remove" menu item selected from + * the entry context menu. + */ + virtual void + onRemoveItem(void) throw (); + /** * Signal handler for the "edit playlist" menu item selected from * the entry context menu. diff --git a/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx b/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx index 7f92bade3..d813b5005 100644 --- a/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx +++ b/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.24 $ + Version : $Revision: 1.25 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx,v $ ------------------------------------------------------------------------------*/ @@ -69,8 +69,8 @@ SimplePlaylistManagementWindow :: SimplePlaylistManagementWindow ( Colors::White, WidgetFactory::getInstance()->getWhiteWindowCorners()), LocalizedObject(bundle), - gLiveSupport(gLiveSupport), - isPlaylistModified(false) + isPlaylistModified(false), + gLiveSupport(gLiveSupport) { Ptr::Ref wf = WidgetFactory::getInstance(); @@ -128,9 +128,33 @@ SimplePlaylistManagementWindow :: SimplePlaylistManagementWindow ( std::exit(1); } + entriesView->signal_button_press_event().connect_notify(sigc::mem_fun( + *this, &SimplePlaylistManagementWindow::onEntryClicked )); entriesView->signalCellEdited().connect(sigc::mem_fun( *this, &SimplePlaylistManagementWindow::onFadeInfoEdited )); + // create the right-click entry context menu + rightClickMenu = Gtk::manage(new Gtk::Menu()); + Gtk::Menu::MenuList& rightClickMenuList = rightClickMenu->items(); + + try { + rightClickMenuList.push_back(Gtk::Menu_Helpers::MenuElem( + *getResourceUstring("upMenuItem"), + sigc::mem_fun(*this, + &SimplePlaylistManagementWindow::onUpItem))); + rightClickMenuList.push_back(Gtk::Menu_Helpers::MenuElem( + *getResourceUstring("downMenuItem"), + sigc::mem_fun(*this, + &SimplePlaylistManagementWindow::onDownItem))); + rightClickMenuList.push_back(Gtk::Menu_Helpers::MenuElem( + *getResourceUstring("removeMenuItem"), + sigc::mem_fun(*this, + &SimplePlaylistManagementWindow::onRemoveItem))); + } catch (std::invalid_argument &e) { + std::cerr << e.what() << std::endl; + std::exit(1); + } + // construct the "lock fades" check button Ptr::Ref lockFadesCheckButtonLabel; try { @@ -355,25 +379,25 @@ SimplePlaylistManagementWindow :: showContents(void) throw () entriesModel->clear(); rowNumber = 0; for (it = playlist->begin(); it != playlist->end(); ++it) { - Ptr::Ref - playlistElem = it->second; - Ptr::Ref playable = playlistElem->getPlayable(); - Gtk::TreeModel::Row row = *(entriesModel->append()); + Ptr::Ref playlistElement + = it->second; + Ptr::Ref playable = playlistElement->getPlayable(); + Gtk::TreeModel::Row row = *(entriesModel->append()); + row[modelColumns.playlistElementColumn] + = playlistElement; row[modelColumns.rowNumberColumn] = rowNumber++; - row[modelColumns.idColumn] - = playable->getId(); row[modelColumns.startColumn] = *TimeConversion::timeDurationToHhMmSsString( - playlistElem->getRelativeOffset()); + playlistElement->getRelativeOffset()); row[modelColumns.titleColumn] = Glib::Markup::escape_text(*playable->getTitle()); row[modelColumns.lengthColumn] = *TimeConversion::timeDurationToHhMmSsString( - playable->getPlaylength()); + playable->getPlaylength()); - Ptr::Ref fadeInfo = playlistElem->getFadeInfo(); + Ptr::Ref fadeInfo = playlistElement->getFadeInfo(); Ptr::Ref fadeIn, fadeOut; if (fadeInfo) { fadeIn = fadeInfo->getFadeIn(); @@ -546,3 +570,140 @@ SimplePlaylistManagementWindow :: onPlaylistModified(void) throw() isPlaylistModified = true; } + +/*------------------------------------------------------------------------------ + * Event handler for an entry being clicked in the list + *----------------------------------------------------------------------------*/ +void +SimplePlaylistManagementWindow :: 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 = entriesView->get_path_at_pos( + int(event->x), int(event->y), + currentPath, column, + cell_x, cell_y); + + if (foundValidRow) { + currentItem = entriesModel->get_iter(currentPath); + if (currentItem) { + rightClickMenu->popup(event->button, event->time); + } + } + } +} + + +/*------------------------------------------------------------------------------ + * Event handler for the Up menu item selected from the context menu. + *----------------------------------------------------------------------------*/ +void +SimplePlaylistManagementWindow :: onUpItem(void) throw() +{ + if (currentItem && currentItem != entriesModel->children().begin()) { + Gtk::TreeIter previousItem = currentItem; + --previousItem; + swapPlaylistElements(previousItem, currentItem); + isPlaylistModified = true; + showContents(); + } +} + + +/*------------------------------------------------------------------------------ + * Event handler for the Down menu item selected from the context menu. + *----------------------------------------------------------------------------*/ +void +SimplePlaylistManagementWindow :: onDownItem(void) throw() +{ + if (currentItem) { + Gtk::TreeIter nextItem = currentItem; + ++nextItem; + if (nextItem) { + swapPlaylistElements(currentItem, nextItem); + isPlaylistModified = true; + showContents(); + } + } +} + + +/*------------------------------------------------------------------------------ + * Swap two playlist elements in the edited playlist. + *----------------------------------------------------------------------------*/ +void +SimplePlaylistManagementWindow :: swapPlaylistElements( + Gtk::TreeIter firstIter, + Gtk::TreeIter secondIter) + throw() +{ + Ptr::Ref + firstElement = (*firstIter) [modelColumns.playlistElementColumn]; + Ptr::Ref + secondElement = (*secondIter)[modelColumns.playlistElementColumn]; + + // remove the two playlist elements + Ptr::Ref playlist = gLiveSupport->getEditedPlaylist(); + playlist->removePlaylistElement(firstElement->getId()); + playlist->removePlaylistElement(secondElement->getId()); + + // swap the relative offsets so that elt2.begin <-- elt1.begin + // and elt1.end <-- elt2.end + Ptr::Ref firstStart = firstElement->getRelativeOffset(); + Ptr::Ref secondStart(new time_duration( + *secondElement->getRelativeOffset() + + *secondElement->getPlayable() + ->getPlaylength() + - *firstElement->getPlayable() + ->getPlaylength() )); + firstElement->setRelativeOffset(secondStart); + secondElement->setRelativeOffset(firstStart); + + // move fades around if they seem to be simple crossfades + Ptr::Ref beginFade = firstElement->getFadeInfo() + ->getFadeIn(); + Ptr::Ref midFade1 = firstElement->getFadeInfo() + ->getFadeOut(); + Ptr::Ref midFade2 = secondElement->getFadeInfo() + ->getFadeIn(); + Ptr::Ref endFade = secondElement->getFadeInfo() + ->getFadeOut(); + + if (*midFade1 == *midFade2) { + Ptr::Ref firstFadeInfo (new FadeInfo(beginFade, midFade1)); + Ptr::Ref secondFadeInfo(new FadeInfo(midFade1, endFade )); + + firstElement->setFadeInfo(secondFadeInfo); + secondElement->setFadeInfo(firstFadeInfo); + } + + // add the playlist elements back in + playlist->addPlaylistElement(firstElement); + playlist->addPlaylistElement(secondElement); + + // Note: + // removing and then adding is necessary to make sure that the playlist + // elements are correctly indexed by their relative offset in the playlist. +} + + +/*------------------------------------------------------------------------------ + * Event handler for the Remove menu item selected from the context menu. + *----------------------------------------------------------------------------*/ +void +SimplePlaylistManagementWindow :: onRemoveItem(void) throw() +{ + Ptr::Ref playlist = gLiveSupport->getEditedPlaylist(); + Ptr::Ref playlistElement + = (*currentItem)[modelColumns.playlistElementColumn]; + + playlist->removePlaylistElement(playlistElement->getId()); + + isPlaylistModified = true; + showContents(); +} + diff --git a/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h b/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h index 5d7da2706..86e506f05 100644 --- a/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h +++ b/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.12 $ + Version : $Revision: 1.13 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h,v $ ------------------------------------------------------------------------------*/ @@ -88,7 +88,7 @@ using namespace LiveSupport::Widgets; * * * @author $Author: fgerlits $ - * @version $Revision: 1.12 $ + * @version $Revision: 1.13 $ */ class SimplePlaylistManagementWindow : public WhiteWindow, public LocalizedObject @@ -101,6 +101,24 @@ class SimplePlaylistManagementWindow : public WhiteWindow, enum { fadeInColumnId, fadeOutColumnId }; + /** + * A flag set to true when the edited playlist is modified. + */ + bool isPlaylistModified; + + /** + * A flag controlled by the "lock fades" check button. + * This determines whether the fade-out of a clip is assumed to + * be equal to the fade-in of the next clip. + */ + bool areFadesLocked; + + /** + * An iterator pointing to the current row, for popup functions. + * It is set by onEntryClicked(), before popping up the menu. + */ + Gtk::TreeIter currentItem; + /** * Signal handler for the title being edited. */ @@ -125,6 +143,65 @@ class SimplePlaylistManagementWindow : public WhiteWindow, void onPlaylistModified(void) throw(); + /** + * Signal handler for the mouse clicked on one of the entries. + * This is used to pop up the right-click context menu. + * + * @param event the button event recieved + */ + void + onEntryClicked(GdkEventButton * event) throw (); + + /** + * Signal handler for the save button clicked. + */ + void + onSaveButtonClicked(void) throw (); + + /** + * Signal handler for the close button clicked. + */ + void + onCloseButtonClicked(void) throw (); + + /** + * Signal handler for the "lock fades" check button toggled. + */ + void + onLockFadesCheckButtonClicked(void) throw (); + + /** + * Signal handler for the "up" menu item selected from + * the right-click context menu. + */ + void + onUpItem(void) throw (); + + /** + * Signal handler for the "down" menu item selected from + * the right-click context menu. + */ + void + onDownItem(void) throw (); + + /** + * Swap two playlist elements in the edited playlist. + * This is used by onUpItem() and onDownItem(). + * + * @param firstIter the first item, to be swapped... + * @param secondIter ... with this second item + */ + void + swapPlaylistElements(Gtk::TreeIter firstIter, + Gtk::TreeIter secondIter) throw (); + + /** + * Signal handler for the "remove" menu item selected from + * the right-click context menu. + */ + virtual void + onRemoveItem(void) throw (); + /** * Set the fade in of a playlist element. */ @@ -165,6 +242,14 @@ class SimplePlaylistManagementWindow : public WhiteWindow, void closeWindow(void) throw(); + /** + * Save the edited playlist. + * + * @return true if the playlist was saved successully. + */ + virtual bool + savePlaylist(void) throw (); + protected: @@ -173,16 +258,11 @@ class SimplePlaylistManagementWindow : public WhiteWindow, * Lists one playlist entry per row. * * @author $Author: fgerlits $ - * @version $Revision: 1.12 $ + * @version $Revision: 1.13 $ */ class ModelColumns : public ZebraTreeModelColumnRecord { public: - /** - * The column for the id of the audio clip or playlist. - */ - Gtk::TreeModelColumn::Ref> idColumn; - /** * The column for the start of the playlist entry. */ @@ -208,17 +288,23 @@ class SimplePlaylistManagementWindow : public WhiteWindow, */ Gtk::TreeModelColumn fadeOutColumn; + /** + * The column for the pointer to the playlist element. + */ + Gtk::TreeModelColumn::Ref> + playlistElementColumn; + /** * Constructor. */ ModelColumns(void) throw () { - add(idColumn); add(startColumn); add(titleColumn); add(fadeInColumn); add(lengthColumn); add(fadeOutColumn); + add(playlistElementColumn); } }; @@ -279,42 +365,10 @@ class SimplePlaylistManagementWindow : public WhiteWindow, Ptr::Ref dialogWindow; /** - * A flag set to true when the edited playlist is modified. + * The right-click context menu that comes up when right-clicking + * a playlist element. */ - bool isPlaylistModified; - - /** - * A flag controlled by the "lock fades" check button. - * This determines whether the fade-out of a clip is assumed to - * be equal to the fade-in of the next clip. - */ - bool areFadesLocked; - - /** - * Save the edited playlist. - * - * @return true if the playlist was saved successully. - */ - virtual bool - savePlaylist(void) throw (); - - /** - * Signal handler for the save button clicked. - */ - virtual void - onSaveButtonClicked(void) throw (); - - /** - * Signal handler for the close button clicked. - */ - virtual void - onCloseButtonClicked(void) throw (); - - /** - * Signal handler for the "lock fades" check button toggled. - */ - virtual void - onLockFadesCheckButtonClicked(void) throw (); + Gtk::Menu * rightClickMenu; public: diff --git a/livesupport/products/gLiveSupport/var/root.txt b/livesupport/products/gLiveSupport/var/root.txt index 1bf22d8ff..41bd29227 100644 --- a/livesupport/products/gLiveSupport/var/root.txt +++ b/livesupport/products/gLiveSupport/var/root.txt @@ -120,6 +120,11 @@ root:table lockFadesCheckButtonLabel:string { "Lock fade-out to following fade-in" } statusBar:string { "status bar" } + + upMenuItem:string { "Move _Up" } + downMenuItem:string { "Move D_own" } + removeMenuItem:string { "_Remove" } + playlistSavedMsg:string { "Saved playlist ''{0}''." } savePlaylistDialogMsg:string { "Do you want to save the playlist?" } emptyTitleErrorMsg:string { "Please enter a title." }