some refactoring to reduce the amount of copy-paste later

This commit is contained in:
fgerlits 2007-10-23 12:37:29 +00:00
parent f741c1bd4f
commit 932be3d827
5 changed files with 425 additions and 196 deletions

View File

@ -287,7 +287,8 @@ G_LIVESUPPORT_OBJS = ${TMP_DIR}/GLiveSupport.o \
${TMP_DIR}/RestoreBackupWindow.o \
${TMP_DIR}/TaskbarIcons.o \
${TMP_DIR}/RdsView.o \
${TMP_DIR}/RdsEntry.o
${TMP_DIR}/RdsEntry.o \
${TMP_DIR}/DndMethods.o
G_LIVESUPPORT_RES = ${TMP_STUDIO-LOCALIZATION_DIR}/root.res \
${TMP_STUDIO-LOCALIZATION_DIR}/en.res \

View File

@ -0,0 +1,185 @@
/*------------------------------------------------------------------------------
Copyright (c) 2004 Media Development Loan Fund
This file is part of the Campcaster project.
http://campcaster.campware.org/
To report bugs, send an e-mail to bugs@campware.org
Campcaster is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Campcaster is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Campcaster; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author : $Author$
Version : $Revision$
Location : $URL$
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#include <iostream>
#include <stdexcept>
#include <cassert>
#include "DndMethods.h"
using namespace LiveSupport::Core;
using namespace LiveSupport::GLiveSupport;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Set up the D'n'D callbacks.
*----------------------------------------------------------------------------*/
void
DndMethods :: setupDndCallbacks (void) throw ()
{
Gtk::TreeView * treeView = getTreeViewForDnd();
std::list<Gtk::TargetEntry> targets;
targets.push_back(Gtk::TargetEntry("STRING",
Gtk::TARGET_SAME_APP));
// set up the tree view as a d'n'd source
treeView->enable_model_drag_source(targets);
treeView->signal_drag_data_get().connect(sigc::mem_fun(*this,
&DndMethods::onTreeViewDragDataGet));
// set up the tree view as a d'n'd target
treeView->enable_model_drag_dest(targets);
treeView->signal_drag_data_received().connect(sigc::mem_fun(*this,
&DndMethods::onTreeViewDragDataReceived));
}
/*------------------------------------------------------------------------------
* The callback for supplying the data for the drag and drop.
*----------------------------------------------------------------------------*/
void
DndMethods :: onTreeViewDragDataGet (
const Glib::RefPtr<Gdk::DragContext> & context,
Gtk::SelectionData & selectionData,
guint info,
guint time)
throw ()
{
Glib::ustring dropString = getWindowNameForDnd();
Ptr<Playable>::Ref playable = getFirstSelectedPlayable();
while ((playable = getNextSelectedPlayable())) {
dropString += " ";
dropString += std::string(*playable->getId());
}
selectionData.set(selectionData.get_target(),
8 /* 8 bits format*/,
(const guchar *) dropString.c_str(),
dropString.bytes());
}
/*------------------------------------------------------------------------------
* The callback for processing the data delivered by drag and drop.
*----------------------------------------------------------------------------*/
void
DndMethods :: onTreeViewDragDataReceived(
const Glib::RefPtr<Gdk::DragContext> & context,
int x,
int y,
const Gtk::SelectionData & selectionData,
guint info,
guint time)
throw ()
{
Glib::ustring windowName = getWindowNameForDnd();
if (selectionData.get_length() < 0 || selectionData.get_format() != 8) {
std::cerr << "unknown type of data dropped on the tree view in "
<< windowName << std::endl;
context->drag_finish(false, false, time);
return;
}
Glib::ustring data = selectionData.get_data_as_string();
std::stringstream dataStream(data);
Glib::ustring sourceWindow;
dataStream >> sourceWindow;
Gtk::TreeIter iter = insertRowAtPos(x, y);
Glib::ustring idAsString;
dataStream >> idAsString; // only works for 1 item, for now
Ptr<UniqueId>::Ref id(new UniqueId(idAsString));
addItem(iter, id);
if (sourceWindow == windowName) {
context->drag_finish(true, true, time); // delete the original
} else {
context->drag_finish(true, false, time); // don't delete the original
}
}
/*------------------------------------------------------------------------------
* Insert a row into the tree model at the given tree view position.
*----------------------------------------------------------------------------*/
Gtk::TreeIter
DndMethods :: insertRowAtPos (int x,
int y) throw ()
{
Gtk::TreeView * treeView = getTreeViewForDnd();
Glib::RefPtr<Gtk::ListStore>
treeModel = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(
treeView->get_model() );
Gtk::TreePath destPath;
Gtk::TreeViewDropPosition destPos;
bool pathIsValid = treeView->get_dest_row_at_pos(
x, y, destPath, destPos);
// get_drag_dest_row() does not work here, for some strange reason
Gtk::TreeIter newIter;
if (pathIsValid) {
assert (!destPath.empty());
Gtk::TreeIter destination = treeModel->get_iter(destPath);
if (destPos == Gtk::TREE_VIEW_DROP_BEFORE
|| destPos == Gtk::TREE_VIEW_DROP_INTO_OR_BEFORE) {
newIter = treeModel->insert(destination);
} else if (destPos == Gtk::TREE_VIEW_DROP_AFTER
|| destPos == Gtk::TREE_VIEW_DROP_INTO_OR_AFTER) {
newIter = treeModel->insert_after(destination);
} else {
assert (false);
}
} else {
newIter = treeModel->append();
}
return newIter;
}

View File

@ -0,0 +1,194 @@
/*------------------------------------------------------------------------------
Copyright (c) 2004 Media Development Loan Fund
This file is part of the Campcaster project.
http://campcaster.campware.org/
To report bugs, send an e-mail to bugs@campware.org
Campcaster is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Campcaster is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Campcaster; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author : $Author$
Version : $Revision$
Location : $URL$
------------------------------------------------------------------------------*/
#ifndef DndMethods_h
#define DndMethods_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#include <gtkmm.h>
#include "LiveSupport/Core/Playable.h"
namespace LiveSupport {
namespace GLiveSupport {
using namespace LiveSupport::Core;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* An abstract class containing template methods which implement drag and drop.
*
* To implement d'n'd in a GuiWindow, inherit from this class, implement the
* pure abstract methods declared in this class (see the requirements at the
* method declarations), and call setupDndCallbacks() after the tree view has
* been constructed.
*
* @author $Author$
* @version $Revision$
*/
class DndMethods
{
protected:
/**
* The tree view we want to implement d'n'd on.
*/
virtual Gtk::TreeView *
getTreeViewForDnd (void) throw ()
= 0;
/**
* The name of the window.
*/
virtual Glib::ustring
getWindowNameForDnd (void) throw ()
= 0;
/**
* Return the topmost selected row in the tree view.
*
* @return the first selected playable item.
*/
virtual Ptr<Playable>::Ref
getFirstSelectedPlayable(void) throw ()
= 0;
/**
* Used to iterate over the selected rows in the tree view.
*
* @return the next selected playable item.
*/
virtual Ptr<Playable>::Ref
getNextSelectedPlayable(void) throw ()
= 0;
/**
* Add an item to the d'n'd tree view at the given position.
*
* @param iter the iterator pointing to the row to be filled in.
* @param id the ID of the item to add.
*/
virtual void
addItem (Gtk::TreeIter iter,
Ptr<const UniqueId>::Ref id) throw ()
= 0;
/**
* Insert a row into the tree model at the given tree view position.
* Creates the new row; the caller should fill it with data.
*
* @param x the x coordinate of the location of the new row.
* @param y the y coordinate of the location of the new row.
* @return an iterator pointing to the newly created row.
*/
Gtk::TreeIter
insertRowAtPos (int x,
int y) throw ();
/**
* Set up the D'n'D callbacks.
*/
void
setupDndCallbacks (void) throw ();
/**
* The callback for supplying the data for the drag and drop.
*
* @param context the drag context.
* @param selectionData the data (filled in by this function).
* @param info not used.
* @param time timestamp for the d'n'd operation.
*/
void
onTreeViewDragDataGet (
const Glib::RefPtr<Gdk::DragContext> & context,
Gtk::SelectionData & selectionData,
guint info,
guint time)
throw ();
/**
* The callback for processing the data delivered by drag and drop.
*
* @param context the drag context.
* @param x the x coord where the data was dropped.
* @param y the y coord where the data was dropped.
* @param selectionData the data.
* @param info not used.
* @param time timestamp for the d'n'd operation.
*/
virtual void
onTreeViewDragDataReceived (
const Glib::RefPtr<Gdk::DragContext> & context,
int x,
int y,
const Gtk::SelectionData & selectionData,
guint info,
guint time)
throw ();
/**
* Constructor.
*/
DndMethods (void) throw ()
{
}
/**
* Virtual destructor.
*/
virtual
~DndMethods(void) throw ()
{
}
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace GLiveSupport
} // namespace LiveSupport
#endif // DndMethods_h

View File

@ -622,126 +622,12 @@ ScratchpadWindow :: hide(void) throw ()
/*------------------------------------------------------------------------------
* Set up the D'n'D callbacks.
* The name of the window for the d'n'd methods.
*----------------------------------------------------------------------------*/
void
ScratchpadWindow :: setupDndCallbacks (void) throw ()
Glib::ustring
ScratchpadWindow :: getWindowNameForDnd (void) throw ()
{
std::list<Gtk::TargetEntry> targets;
targets.push_back(Gtk::TargetEntry("STRING",
Gtk::TARGET_SAME_APP));
// set up the tree view as a d'n'd source
treeView->enable_model_drag_source(targets);
treeView->signal_drag_data_get().connect(sigc::mem_fun(*this,
&ScratchpadWindow::onTreeViewDragDataGet));
// set up the tree view as a d'n'd target
treeView->enable_model_drag_dest(targets);
treeView->signal_drag_data_received().connect(sigc::mem_fun(*this,
&ScratchpadWindow::onTreeViewDragDataReceived));
}
/*------------------------------------------------------------------------------
* The callback for supplying the data for the drag and drop.
*----------------------------------------------------------------------------*/
void
ScratchpadWindow :: onTreeViewDragDataGet(
const Glib::RefPtr<Gdk::DragContext> & context,
Gtk::SelectionData & selectionData,
guint info,
guint time)
throw ()
{
Glib::ustring dropString = bundleName;
Ptr<Playable>::Ref playable = getFirstSelectedPlayable();
while ((playable = getNextSelectedPlayable())) {
dropString += " ";
dropString += std::string(*playable->getId());
}
selectionData.set(selectionData.get_target(),
8 /* 8 bits format*/,
(const guchar *) dropString.c_str(),
dropString.bytes());
}
/*------------------------------------------------------------------------------
* The callback for processing the data delivered by drag and drop.
*----------------------------------------------------------------------------*/
void
ScratchpadWindow :: onTreeViewDragDataReceived(
const Glib::RefPtr<Gdk::DragContext> & context,
int x,
int y,
const Gtk::SelectionData & selectionData,
guint info,
guint time)
throw ()
{
if (selectionData.get_length() < 0 || selectionData.get_format() != 8) {
std::cerr << "unknown type of data dropped on the tree view in "
<< bundleName << std::endl;
context->drag_finish(false, false, time);
return;
}
Glib::ustring data = selectionData.get_data_as_string();
std::stringstream dataStream(data);
Glib::ustring sourceWindow;
dataStream >> sourceWindow;
Gtk::TreeIter iter = insertRowAtPos(x, y);
Glib::ustring idAsString;
dataStream >> idAsString; // only works for 1 item, for now
Ptr<UniqueId>::Ref id(new UniqueId(idAsString));
addItem(iter, id);
if (sourceWindow == bundleName) {
context->drag_finish(true, true, time); // delete the original
} else {
context->drag_finish(true, false, time); // don't delete the original
}
}
/*------------------------------------------------------------------------------
* Insert a row into the tree model at the given tree view position.
*----------------------------------------------------------------------------*/
Gtk::TreeIter
ScratchpadWindow :: insertRowAtPos (int x,
int y) throw ()
{
Gtk::TreePath destPath;
Gtk::TreeViewDropPosition destPos;
bool pathIsValid = treeView->get_dest_row_at_pos(
x, y, destPath, destPos);
// get_drag_dest_row() does not work here, for some strange reason
Gtk::TreeIter newIter;
if (pathIsValid) {
assert (!destPath.empty());
Gtk::TreeIter destination = treeModel->get_iter(destPath);
if (destPos == Gtk::TREE_VIEW_DROP_BEFORE
|| destPos == Gtk::TREE_VIEW_DROP_INTO_OR_BEFORE) {
newIter = treeModel->insert(destination);
} else if (destPos == Gtk::TREE_VIEW_DROP_AFTER
|| destPos == Gtk::TREE_VIEW_DROP_INTO_OR_AFTER) {
newIter = treeModel->insert_after(destination);
} else {
assert (false);
}
} else {
newIter = treeModel->append();
}
return newIter;
return bundleName;
}

View File

@ -49,6 +49,7 @@
#include "ContentsStorable.h"
#include "ExportPlaylistWindow.h"
#include "SchedulePlaylistWindow.h"
#include "DndMethods.h"
#include "GuiWindow.h"
@ -75,7 +76,8 @@ using namespace LiveSupport::Widgets;
* @version $Revision$
*/
class ScratchpadWindow : public GuiWindow,
public ContentsStorable
public ContentsStorable,
public DndMethods
{
private:
@ -105,26 +107,6 @@ class ScratchpadWindow : public GuiWindow,
*/
std::vector<Gtk::TreePath>::const_iterator selectedIter;
/**
* Return the topmost selected row.
* Sets selectedPaths and selectedIter; does not increment it.
*
* @return the first selected playable item.
*/
Ptr<Playable>::Ref
getFirstSelectedPlayable(void) throw ();
/**
* 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 playable item.
*/
Ptr<Playable>::Ref
getNextSelectedPlayable(void) throw ();
/**
* Check whether exactly one row is selected.
*
@ -147,34 +129,6 @@ class ScratchpadWindow : public GuiWindow,
void
removeItem(Ptr<const UniqueId>::Ref id) throw ();
/**
* Set up the D'n'D callbacks.
*/
void
setupDndCallbacks (void) throw ();
/**
* Insert a row into the tree model at the given tree view position.
* Creates the new row; the caller should fill it with data.
*
* @param x the x coordinate of the location of the new row.
* @param y the y coordinate of the location of the new row.
* @return an iterator pointing to the newly created row.
*/
Gtk::TreeIter
insertRowAtPos (int x,
int y) throw ();
/**
* Add an item to the Scratchpad at the given position.
*
* @param iter the iterator pointing to the row to be filled in.
* @param id the ID of the item to add.
*/
void
addItem(Gtk::TreeIter iter,
Ptr<const UniqueId>::Ref id) throw ();
protected:
@ -335,40 +289,49 @@ class ScratchpadWindow : public GuiWindow,
onRemoveMenuOption(void) throw ();
/**
* The callback for supplying the data for the drag and drop.
*
* @param context the drag context.
* @param selectionData the data (filled in by this function).
* @param info not used.
* @param time timestamp for the d'n'd operation.
* The tree view we want to implement d'n'd on.
*/
void
onTreeViewDragDataGet(
const Glib::RefPtr<Gdk::DragContext> & context,
Gtk::SelectionData & selectionData,
guint info,
guint time)
throw ();
virtual Gtk::TreeView *
getTreeViewForDnd (void) throw ()
{
return treeView;
}
/**
* The callback for processing the data delivered by drag and drop.
* The name of the window for the d'n'd methods.
*/
virtual Glib::ustring
getWindowNameForDnd (void) throw ();
/**
* Return the topmost selected row.
* Sets selectedPaths and selectedIter; does not increment it.
*
* @param context the drag context.
* @param x the x coord where the data was dropped.
* @param y the y coord where the data was dropped.
* @param selectionData the data.
* @param info not used.
* @param time timestamp for the d'n'd operation.
* @return the first selected playable item.
*/
virtual Ptr<Playable>::Ref
getFirstSelectedPlayable(void) throw ();
/**
* 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 playable item.
*/
virtual Ptr<Playable>::Ref
getNextSelectedPlayable(void) throw ();
/**
* Add an item to the Scratchpad at the given position.
*
* @param iter the iterator pointing to the row to be filled in.
* @param id the ID of the item to add.
*/
virtual void
onTreeViewDragDataReceived(
const Glib::RefPtr<Gdk::DragContext> & context,
int x,
int y,
const Gtk::SelectionData & selectionData,
guint info,
guint time)
throw ();
addItem(Gtk::TreeIter iter,
Ptr<const UniqueId>::Ref id) throw ();
public: