Update of /cvsroot/mahogany/M/src/gui
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15288/src/gui
Modified Files:
wxFolderTree.cpp
Log Message:
implemented folder reordering in the tree by dragging them
Index: wxFolderTree.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxFolderTree.cpp,v
retrieving revision 1.227
retrieving revision 1.228
diff -b -u -2 -r1.227 -r1.228
--- wxFolderTree.cpp 12 Jan 2004 15:20:38 -0000 1.227
+++ wxFolderTree.cpp 13 Mar 2004 18:58:39 -0000 1.228
@@ -339,5 +339,7 @@
void UpdateColours();
- // callbacks
+ // tree event handlers
+ // -------------------
+
void OnKeyDown(wxTreeEvent& event);
void OnChar(wxKeyEvent& event);
@@ -357,4 +359,7 @@
void OnEndLabelEdit(wxTreeEvent&);
+ void OnTreeBeginDrag(wxTreeEvent& event);
+ void OnTreeEndDrag(wxTreeEvent& event);
+
void OnIdle(wxIdleEvent& event);
@@ -384,4 +389,16 @@
}
+ // (safely) get the folder from item id
+ MFolder *GetFolderFromTreeItem(const wxTreeItemId& item) const
+ {
+ wxFolderTreeNode *node = GetFolderTreeNode(item);
+ CHECK( node, NULL, _T("tree item without associated data?") );
+
+ MFolder *folder = node->GetFolder();
+ ASSERT_MSG( folder, _T("tree node without associated folder?") );
+
+ return folder;
+ }
+
protected:
// return true if the current folder may be opened
@@ -432,5 +449,5 @@
bool IsEditingInPlace() const;
- // reexpand branch - called when something in the tree changes
+ // reexpand branch -- called when something in the tree changes
void ReopenBranch(wxTreeItemId parent);
@@ -453,4 +470,16 @@
wxTreeItemId GetNextItem(wxTreeItemId id, bool next = true) const;
+ // reposition the src folder between its two siblings, the caller must call
+ // ReopenBranch() to refresh the tree if wanted
+ //
+ // idBefore may be invalid, the other 2 are always valid
+ void MoveFolderBetween(wxTreeItemId id,
+ wxTreeItemId idBefore,
+ wxTreeItemId idAfter) const;
+
+ // MoveFolderBetween() helpers, see comments in them
+ int SetIndicesBefore(wxTreeItemId id) const;
+ int OffsetIndicesAfter(wxTreeItemId id) const;
+
private:
class FolderMenu : public wxMenu
@@ -580,4 +609,8 @@
wxString m_suffix;
+
+ // the item currently being dragged or invalid item
+ wxTreeItemId m_idDragged;
+
#ifdef USE_TREE_ACTIVATE_BUGFIX
bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
@@ -712,4 +745,7 @@
EVT_TREE_END_LABEL_EDIT(-1, wxFolderTreeImpl::OnEndLabelEdit)
+ EVT_TREE_BEGIN_DRAG(-1, wxFolderTreeImpl::OnTreeBeginDrag)
+ EVT_TREE_END_DRAG(-1, wxFolderTreeImpl::OnTreeEndDrag)
+
EVT_RIGHT_DOWN(wxFolderTreeImpl::OnRightDown)
#ifdef USE_MIDDLE_CLICK_HACK
@@ -2446,4 +2482,255 @@
// ----------------------------------------------------------------------------
+// dragging items in the tree
+// ----------------------------------------------------------------------------
+
+// this function sets tree positions for all the siblings of the given folder
+// up to and including it and returns the new index of idThis
+int wxFolderTreeImpl::SetIndicesBefore(wxTreeItemId idThis) const
+{
+ static const int idxInvalid = GetNumericDefault(MP_FOLDER_TREEINDEX);
+
+ const wxTreeItemId idParent = GetItemParent(idThis);
+
+ int idxThis = 0;
+
+ wxTreeItemIdValue cookie;
+ wxTreeItemId id = GetFirstChild(idParent, cookie);
+ while ( id.IsOk() )
+ {
+ MFolder * const folder = GetFolderFromTreeItem(id);
+ if ( !folder )
+ return idxInvalid;
+
+ int idx = folder->GetTreeIndex();
+ if ( idx != idxInvalid )
+ {
+ // so far, so good: remember the highest previous index
+ ASSERT_MSG( idx >= idxThis, _T("inconsistent tree index values!") );
+
+ idxThis = idx;
+ }
+ else // item without defined position in the tree
+ {
+ // set it now
+ folder->SetTreeIndex(++idxThis);
+ }
+
+ if ( id == idThis )
+ break;
+
+ id = GetNextChild(idParent, cookie);
+ }
+
+ return idxThis;
+}
+
+// this functions moves up the tree positions of all the folders starting
+// (inclusively) from the given one and returns the new index of idThis
+int wxFolderTreeImpl::OffsetIndicesAfter(wxTreeItemId idThis) const
+{
+ static const int idxInvalid = GetNumericDefault(MP_FOLDER_TREEINDEX);
+
+ const wxTreeItemId idParent = GetItemParent(idThis);
+
+ wxTreeItemId id = GetLastChild(idParent);
+ while ( id.IsOk() )
+ {
+ MFolder * const folder = GetFolderFromTreeItem(id);
+ if ( !folder )
+ return idxInvalid;
+
+ int idx = folder->GetTreeIndex();
+ if ( idx != idxInvalid )
+ {
+ // bump the index up
+ folder->SetTreeIndex(idx + 1);
+ }
+ //else: nothing to do, leave it at the end of all the other items
+
+ if ( id == idThis )
+ {
+ // done, alll indices from this item up to the end are offset
+ ASSERT_MSG( idx != idxInvalid, _T("logic error") );
+
+ return idx + 1;
+ }
+
+ id = GetPrevSibling(id);
+ }
+
+ return idxInvalid;
+}
+
+void
+wxFolderTreeImpl::MoveFolderBetween(wxTreeItemId id,
+ wxTreeItemId idBefore,
+ wxTreeItemId idAfter) const
+{
+ static const int idxInvalid = GetNumericDefault(MP_FOLDER_TREEINDEX);
+
+ // the (new) index of the folder, must be in ]idxBefore, idxAfter[
+ int idx = idxInvalid;
+
+ const MFolder * const folderAfter = GetFolderFromTreeItem(idAfter);
+ if ( !folderAfter )
+ return;
+
+ int idxAfter = folderAfter->GetTreeIndex();
+ if ( idxAfter == idxInvalid )
+ {
+ if ( idBefore.IsOk() )
+ {
+ const MFolder * const folderBefore = GetFolderFromTreeItem(idBefore);
+ if ( !folderBefore )
+ return;
+
+ int idxBefore = folderBefore->GetTreeIndex();
+ if ( idxBefore == idxInvalid )
+ {
+ // we have to fix the indices of all the items before this one so
+ // make it position stick, otherwise it would bubble up to the top
+ idx = SetIndicesBefore(idBefore);
+ if ( idx == idxInvalid )
+ return;
+
+ idx++;
+ }
+ else // position just after idxBefore
+ {
+ idx = idxBefore + 1;
+ }
+ }
+ else // make folder the first child
+ {
+ idx = 0;
+ }
+ }
+ else // we must select an index less than idxAfter
+ {
+ if ( idBefore )
+ {
+ const MFolder * const folderBefore = GetFolderFromTreeItem(idBefore);
+ if ( !folderBefore )
+ return;
+
+ int idxBefore = folderBefore->GetTreeIndex();
+
+ // it can't possibly happen that an item without index is positioned
+ // before another item with index
+ ASSERT_MSG( idxBefore != idxInvalid, _T("confusion with tree indices!") );
+
+ // this might not be the final value, it will be tested below
+ idx = idxBefore + 1;
+ }
+ else // position just before idxAfter
+ {
+ // same as above: this value might be invalid
+ idx = idxAfter - 1;
+ }
+
+ // did we choose a valid value above?
+ if ( idx < 0 || idx >= idxAfter )
+ {
+ // we have to offset the indices of all subsequent items...
+ idx = OffsetIndicesAfter(idAfter);
+ if ( idx == idxInvalid )
+ return;
+
+ idx--;
+ }
+ }
+
+ // do change the folder position
+ ASSERT_MSG( idx != idxInvalid, _T("logic error in MoveFolderBetween()") );
+
+ MFolder * const folder = GetFolderFromTreeItem(id);
+ if ( !folder )
+ return;
+
+ folder->SetTreeIndex(idx);
+}
+
+void wxFolderTreeImpl::OnTreeBeginDrag(wxTreeEvent& event)
+{
+ // do we have something basically valid?
+ const wxTreeItemId idDragged = event.GetItem();
+ const MFolder * const folder = GetFolderFromTreeItem(idDragged);
+ if ( !folder )
+ return;
+
+ // determine if we can drag this item at all?
+ if ( folder->GetType() == MF_ROOT ||
+ (folder->GetFlags() & MF_FLAGS_DONTDELETE) )
+ {
+ wxLogStatus(GetFrame(this),
+ _("The folder \"%s\" cannot be moved."),
+ folder->GetFullName().c_str());
+ return;
+ }
+
+ // ok, allow the user to drag it
+ ASSERT_MSG( !m_idDragged.IsOk(), _T("didn't finish the previous drag?") );
+
+ m_idDragged = idDragged;
+ event.Allow();
+}
+
+void wxFolderTreeImpl::OnTreeEndDrag(wxTreeEvent& event)
+{
+ CHECK_RET( m_idDragged.IsOk(), _T("end drag without begin drag?") );
+
+ // get the source and destination folders
+ const wxTreeItemId idDst = event.GetItem();
+ const wxTreeItemId idSrc = m_idDragged;
+ m_idDragged.Unset();
+
+ if ( !idDst.IsOk() )
+ {
+ // happens if the user dragged the mouse completely outside the window,
+ // for example
+ return;
+ }
+
+ MFolder * const folderDst = GetFolderFromTreeItem(idDst);
+ MFolder * const folderSrc = GetFolderFromTreeItem(idSrc);
+
+ if ( !folderDst || !folderSrc )
+ {
+ // this is not supposed to happen (debug error message already given)
+ return;
+ }
+
+ // do we want to just change the item position among its siblings or move it?
+ if ( folderDst->GetParent() == folderSrc->GetParent() )
+ {
+ // just changing the order: put the src folder just before the dst one
+ // (not just after: this would make it impossible to reposition a folder
+ // to be the first one among its siblings, as dropping it on the parent
+ // would move it one level up)
+ MoveFolderBetween(idSrc, GetPrevSibling(idDst), idDst);
+
+ // reflect the changes in the tree
+ ReopenBranch(GetItemParent(idDst));
+ }
+ else // really moving
+ {
+ if ( !folderSrc->Move(folderDst) )
+ {
+ wxLogError(_("Failed to move the folder \"%s\" to \"%s\"."),
+ folderSrc->GetFullName().c_str(),
+ folderDst->GetFullName().c_str());
+ }
+ else // moved ok
+ {
+ wxLogStatus(GetFrame(this),
+ _("Successfully moved the folder \"%s\" to \"%s\"."),
+ folderSrc->GetFullName().c_str(),
+ folderDst->GetFullName().c_str());
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
// tree notifications
// ----------------------------------------------------------------------------
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates