summaryrefslogtreecommitdiffstats
path: root/konqueror/keditbookmarks/commands.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'konqueror/keditbookmarks/commands.cpp')
-rw-r--r--konqueror/keditbookmarks/commands.cpp745
1 files changed, 745 insertions, 0 deletions
diff --git a/konqueror/keditbookmarks/commands.cpp b/konqueror/keditbookmarks/commands.cpp
new file mode 100644
index 000000000..e545df54e
--- /dev/null
+++ b/konqueror/keditbookmarks/commands.cpp
@@ -0,0 +1,745 @@
+// -*- indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <[email protected]>
+ Copyright (C) 2002-2003 Alexander Kellett <[email protected]>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This program 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 this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "commands.h"
+
+#include "kinsertionsort.h"
+
+#include "toplevel.h"
+#include "listview.h"
+
+#include <assert.h>
+#include <qvaluevector.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <kbookmarkdrag.h>
+#include <kbookmarkmanager.h>
+
+#include <kurldrag.h>
+#include <kdesktopfile.h>
+
+QString KEBMacroCommand::affectedBookmarks() const
+{
+ QPtrListIterator<KCommand> it(m_commands);
+ QString affectBook;
+ if(it.current())
+ affectBook = dynamic_cast<IKEBCommand *>(it.current())->affectedBookmarks();
+ ++it;
+ for ( ; it.current() ; ++it )
+ affectBook = KBookmark::commonParent( affectBook, dynamic_cast<IKEBCommand *>(it.current())->affectedBookmarks());
+ return affectBook;
+}
+
+QString DeleteManyCommand::prevOrParentAddress(QString addr)
+{
+ QString prev = KBookmark::previousAddress( addr );
+ if( CurrentMgr::bookmarkAt(prev).hasParent())
+ return prev;
+ else
+ return KBookmark::parentAddress( addr );
+}
+
+QString DeleteManyCommand::preOrderNextAddress(QString addr)
+{
+ QString rootAdr = CurrentMgr::self()->mgr()->root().address();
+ while(addr != rootAdr)
+ {
+ QString next = KBookmark::nextAddress(addr);
+ if(CurrentMgr::bookmarkAt( next ).hasParent() )
+ return next;
+ addr = KBookmark::parentAddress( addr );
+ }
+ return QString::null;
+}
+
+bool DeleteManyCommand::isConsecutive(const QValueList<QString> & addresses)
+{
+ QValueList<QString>::const_iterator it, end;
+ it = addresses.begin();
+ end = addresses.end();
+ QString addr = *(addresses.begin());
+ for( ; it != end; ++it)
+ {
+ if( *it != addr )
+ return false;
+ addr = KBookmark::nextAddress(addr);
+ }
+ return true;
+}
+
+
+DeleteManyCommand::DeleteManyCommand(const QString &name, const QValueList<QString> & addresses)
+ : KEBMacroCommand(name)
+{
+ QValueList<QString>::const_iterator it, begin;
+ begin = addresses.begin();
+ it = addresses.end();
+ while(begin != it)
+ {
+ --it;
+ DeleteCommand * dcmd = new DeleteCommand(*it);
+ addCommand(dcmd);
+ }
+
+ // Set m_currentAddress
+ if( addresses.count() == 1)
+ {
+ // First try next bookmark
+ if( CurrentMgr::bookmarkAt( KBookmark::nextAddress( *begin ) ).hasParent() )
+ m_currentAddress = *begin;
+ else
+ {
+ m_currentAddress = preOrderNextAddress( KBookmark::parentAddress( *begin ) );
+ if(m_currentAddress == QString::null)
+ m_currentAddress = prevOrParentAddress( *begin );
+ }
+ }
+ else // multi selection
+ {
+ // Check if all bookmarks are consecutive
+ if(isConsecutive(addresses)) // Mark next bookmark after all selected
+ { // That's a little work...
+ QValueList<QString>::const_iterator last = addresses.end();
+ --last;
+ if( CurrentMgr::bookmarkAt( KBookmark::nextAddress(*last) ).hasParent() )
+ m_currentAddress = *begin;
+ else
+ {
+ m_currentAddress = preOrderNextAddress( KBookmark::parentAddress( *begin ) );
+ if( m_currentAddress == QString::null)
+ m_currentAddress = prevOrParentAddress( *begin );
+ }
+ }
+ else // not consecutive, select the common parent (This could be more clever)
+ {
+ QValueList<QString>::const_iterator jt, end;
+ end = addresses.end();
+ m_currentAddress = *begin;
+ for( jt = addresses.begin(); jt != end; ++jt)
+ m_currentAddress = KBookmark::commonParent(m_currentAddress, *jt);
+ }
+ }
+}
+
+QString DeleteManyCommand::currentAddress() const
+{
+ return m_currentAddress;
+}
+
+
+QString CreateCommand::name() const {
+ if (m_separator) {
+ return i18n("Insert Separator");
+ } else if (m_group) {
+ return i18n("Create Folder");
+ } else if (!m_originalBookmark.isNull()) {
+ return i18n("Copy %1").arg(m_mytext);
+ } else {
+ return i18n("Create Bookmark");
+ }
+}
+
+void CreateCommand::execute() {
+ QString parentAddress = KBookmark::parentAddress(m_to);
+ KBookmarkGroup parentGroup =
+ CurrentMgr::bookmarkAt(parentAddress).toGroup();
+
+ QString previousSibling = KBookmark::previousAddress(m_to);
+
+ // kdDebug() << "CreateCommand::execute previousSibling="
+ // << previousSibling << endl;
+ KBookmark prev = (previousSibling.isEmpty())
+ ? KBookmark(QDomElement())
+ : CurrentMgr::bookmarkAt(previousSibling);
+
+ KBookmark bk = KBookmark(QDomElement());
+
+ if (m_separator) {
+ bk = parentGroup.createNewSeparator();
+
+ } else if (m_group) {
+ Q_ASSERT(!m_text.isEmpty());
+ bk = parentGroup.createNewFolder(CurrentMgr::self()->mgr(),
+ m_text, false);
+ bk.internalElement().setAttribute("folded", (m_open ? "no" : "yes"));
+ if (!m_iconPath.isEmpty()) {
+ bk.internalElement().setAttribute("icon", m_iconPath);
+ }
+
+ } else if (!m_originalBookmark.isNull()) {
+ // umm.. moveItem needs bk to be a child already!
+ bk = m_originalBookmark;
+
+ } else {
+ bk = parentGroup.addBookmark(CurrentMgr::self()->mgr(),
+ m_text, m_url,
+ m_iconPath, false);
+ }
+
+ // move to right position
+ parentGroup.moveItem(bk, prev);
+ if (!(name().isEmpty()) && !parentAddress.isEmpty() ) {
+ // open the parent (useful if it was empty) - only for manual commands
+ Q_ASSERT( parentGroup.internalElement().tagName() != "xbel" );
+ parentGroup.internalElement().setAttribute("folded", "no");
+ }
+
+ Q_ASSERT(bk.address() == m_to);
+}
+
+QString CreateCommand::finalAddress() const {
+ Q_ASSERT( !m_to.isEmpty() );
+ return m_to;
+}
+
+void CreateCommand::unexecute() {
+ // kdDebug() << "CreateCommand::unexecute deleting " << m_to << endl;
+
+ KBookmark bk = CurrentMgr::bookmarkAt(m_to);
+ Q_ASSERT(!bk.isNull() && !bk.parentGroup().isNull());
+
+ ListView::self()->invalidate(bk.address());
+
+ bk.parentGroup().deleteBookmark(bk);
+}
+
+QString CreateCommand::affectedBookmarks() const
+{
+ return KBookmark::parentAddress(m_to);
+}
+
+QString CreateCommand::currentAddress() const
+{
+ QString bk = KBookmark::previousAddress( m_to );
+ if(CurrentMgr::bookmarkAt( bk).hasParent())
+ return bk;
+ else
+ return KBookmark::parentAddress( m_to );
+}
+
+/* -------------------------------------- */
+
+QString EditCommand::name() const {
+ return i18n("%1 Change").arg(m_mytext);
+}
+
+void EditCommand::execute() {
+ KBookmark bk = CurrentMgr::bookmarkAt(m_address);
+ Q_ASSERT(!bk.isNull());
+
+ m_reverseEditions.clear();
+
+ QValueList<Edition>::Iterator it = m_editions.begin();
+
+ for ( ; it != m_editions.end() ; ++it) {
+ // backup current value
+ m_reverseEditions.append( Edition((*it).attr,
+ bk.internalElement().attribute((*it).attr)));
+ // set new value
+ bk.internalElement().setAttribute((*it).attr, (*it).value);
+ }
+}
+
+void EditCommand::unexecute() {
+ // code reuse
+ EditCommand cmd(m_address, m_reverseEditions);
+ cmd.execute();
+ // get the editions back from it,
+ // in case they changed
+ // (hmm, shouldn't happen - TODO CHECK!)
+ m_editions = cmd.m_reverseEditions;
+}
+
+QString EditCommand::affectedBookmarks() const
+{
+ return KBookmark::parentAddress(m_address);
+}
+
+void EditCommand::modify(const QString & a, const QString & v)
+{
+ QValueList<Edition>::Iterator it = m_editions.begin();
+ QValueList<Edition>::Iterator end = m_editions.end();
+ for ( ; it != end; ++it)
+ {
+ if( (*it).attr == a)
+ (*it).value = v;
+ }
+}
+
+/* -------------------------------------- */
+
+QString NodeEditCommand::name() const {
+ // TODO - make dynamic
+ return i18n("Renaming");
+}
+
+QString NodeEditCommand::getNodeText(KBookmark bk, const QStringList &nodehier) {
+ QDomNode subnode = bk.internalElement();
+ for (QStringList::ConstIterator it = nodehier.begin();
+ it != nodehier.end(); ++it)
+ {
+ subnode = subnode.namedItem((*it));
+ if (subnode.isNull())
+ return QString::null;
+ }
+ return (subnode.firstChild().isNull())
+ ? QString::null
+ : subnode.firstChild().toText().data();
+}
+
+QString NodeEditCommand::setNodeText(KBookmark bk, const QStringList &nodehier,
+ const QString newValue) {
+ QDomNode subnode = bk.internalElement();
+ for (QStringList::ConstIterator it = nodehier.begin();
+ it != nodehier.end(); ++it)
+ {
+ subnode = subnode.namedItem((*it));
+ if (subnode.isNull()) {
+ subnode = bk.internalElement().ownerDocument().createElement((*it));
+ bk.internalElement().appendChild(subnode);
+ }
+ }
+
+ if (subnode.firstChild().isNull()) {
+ QDomText domtext = subnode.ownerDocument().createTextNode("");
+ subnode.appendChild(domtext);
+ }
+
+ QDomText domtext = subnode.firstChild().toText();
+
+ QString oldText = domtext.data();
+ domtext.setData(newValue);
+ return oldText;
+}
+
+void NodeEditCommand::execute() {
+ // DUPLICATED HEAVILY FROM KIO/BOOKMARKS
+ KBookmark bk = CurrentMgr::bookmarkAt(m_address);
+ Q_ASSERT(!bk.isNull());
+ m_oldText = setNodeText(bk, QStringList() << m_nodename, m_newText);
+}
+
+void NodeEditCommand::unexecute() {
+ // reuse code
+ NodeEditCommand cmd(m_address, m_oldText, m_nodename);
+ cmd.execute();
+ // get the old text back from it, in case they changed
+ // (hmm, shouldn't happen)
+ // AK - DUP'ed from above???
+ m_newText = cmd.m_oldText;
+}
+
+void NodeEditCommand::modify(const QString & newText)
+{
+ m_newText = newText;
+}
+
+QString NodeEditCommand::affectedBookmarks() const
+{
+ return KBookmark::parentAddress(m_address);
+}
+
+/* -------------------------------------- */
+
+void DeleteCommand::execute() {
+ // kdDebug() << "DeleteCommand::execute " << m_from << endl;
+
+ KBookmark bk = CurrentMgr::bookmarkAt(m_from);
+ Q_ASSERT(!bk.isNull());
+
+ if (m_contentOnly) {
+ QDomElement groupRoot = bk.internalElement();
+
+ QDomNode n = groupRoot.firstChild();
+ while (!n.isNull()) {
+ QDomElement e = n.toElement();
+ if (!e.isNull()) {
+ // kdDebug() << e.tagName() << endl;
+ }
+ QDomNode next = n.nextSibling();
+ groupRoot.removeChild(n);
+ n = next;
+ }
+ return;
+ }
+
+ // TODO - bug - unparsed xml is lost after undo,
+ // we must store it all therefore
+ if (!m_cmd) {
+ if (bk.isGroup()) {
+ m_cmd = new CreateCommand(
+ m_from, bk.fullText(), bk.icon(),
+ bk.internalElement().attribute("folded") == "no");
+ m_subCmd = deleteAll(bk.toGroup());
+ m_subCmd->execute();
+
+ } else {
+ m_cmd = (bk.isSeparator())
+ ? new CreateCommand(m_from)
+ : new CreateCommand(m_from, bk.fullText(),
+ bk.icon(), bk.url());
+ }
+ }
+
+ m_cmd->unexecute();
+}
+
+void DeleteCommand::unexecute() {
+ // kdDebug() << "DeleteCommand::unexecute " << m_from << endl;
+
+ if (m_contentOnly) {
+ // TODO - recover saved metadata
+ return;
+ }
+
+ m_cmd->execute();
+
+ if (m_subCmd) {
+ m_subCmd->unexecute();
+ }
+}
+
+QString DeleteCommand::affectedBookmarks() const
+{
+ return KBookmark::parentAddress(m_from);
+}
+
+KEBMacroCommand* DeleteCommand::deleteAll(const KBookmarkGroup & parentGroup) {
+ KEBMacroCommand *cmd = new KEBMacroCommand(QString::null);
+ QStringList lstToDelete;
+ // we need to delete from the end, to avoid index shifting
+ for (KBookmark bk = parentGroup.first();
+ !bk.isNull(); bk = parentGroup.next(bk))
+ lstToDelete.prepend(bk.address());
+ for (QStringList::Iterator it = lstToDelete.begin();
+ it != lstToDelete.end(); ++it)
+ cmd->addCommand(new DeleteCommand((*it)));
+ return cmd;
+}
+
+/* -------------------------------------- */
+
+QString MoveCommand::name() const {
+ return i18n("Move %1").arg(m_mytext);
+}
+
+void MoveCommand::execute() {
+ // kdDebug() << "MoveCommand::execute moving from=" << m_from
+ // << " to=" << m_to << endl;
+
+ KBookmark bk = CurrentMgr::bookmarkAt(m_from);
+ Q_ASSERT(!bk.isNull());
+
+ // look for m_from in the QDom tree
+ KBookmark oldParent =
+ CurrentMgr::bookmarkAt(KBookmark::parentAddress(m_from));
+ bool wasFirstChild = (KBookmark::positionInParent(m_from) == 0);
+
+ KBookmark oldPreviousSibling = wasFirstChild
+ ? KBookmark(QDomElement())
+ : CurrentMgr::bookmarkAt(
+ KBookmark::previousAddress(m_from));
+
+ // look for m_to in the QDom tree
+ QString parentAddress = KBookmark::parentAddress(m_to);
+
+ KBookmark newParent = CurrentMgr::bookmarkAt(parentAddress);
+ Q_ASSERT(!newParent.isNull());
+ Q_ASSERT(newParent.isGroup());
+
+ bool isFirstChild = (KBookmark::positionInParent(m_to) == 0);
+
+ if (isFirstChild) {
+ newParent.toGroup().moveItem(bk, QDomElement());
+
+ } else {
+ QString afterAddress = KBookmark::previousAddress(m_to);
+
+ // kdDebug() << "MoveCommand::execute afterAddress="
+ // << afterAddress << endl;
+ KBookmark afterNow = CurrentMgr::bookmarkAt(afterAddress);
+ Q_ASSERT(!afterNow.isNull());
+
+ bool movedOkay = newParent.toGroup().moveItem(bk, afterNow);
+ Q_ASSERT(movedOkay);
+
+ // kdDebug() << "MoveCommand::execute after moving in the dom tree"
+ // ": item=" << bk.address() << endl;
+ }
+
+ // because we moved stuff around, the from/to
+ // addresses can have changed, update
+ m_to = bk.address();
+ m_from = (wasFirstChild)
+ ? (oldParent.address() + "/0")
+ : KBookmark::nextAddress(oldPreviousSibling.address());
+ // kdDebug() << "MoveCommand::execute : new addresses from="
+ // << m_from << " to=" << m_to << endl;
+}
+
+QString MoveCommand::finalAddress() const {
+ Q_ASSERT( !m_to.isEmpty() );
+ return m_to;
+}
+
+void MoveCommand::unexecute() {
+ // let's not duplicate code.
+ MoveCommand undoCmd(m_to, m_from);
+ undoCmd.execute();
+ // get the addresses back from that command, in case they changed
+ m_from = undoCmd.m_to;
+ m_to = undoCmd.m_from;
+}
+
+QString MoveCommand::affectedBookmarks() const
+{
+ return KBookmark::commonParent(KBookmark::parentAddress(m_from), KBookmark::parentAddress(m_to));
+}
+
+/* -------------------------------------- */
+
+class SortItem {
+ public:
+ SortItem(const KBookmark & bk) : m_bk(bk) { ; }
+
+ bool operator == (const SortItem & s) {
+ return (m_bk.internalElement() == s.m_bk.internalElement()); }
+
+ bool isNull() const {
+ return m_bk.isNull(); }
+
+ SortItem previousSibling() const {
+ return m_bk.parentGroup().previous(m_bk); }
+
+ SortItem nextSibling() const {
+ return m_bk.parentGroup().next(m_bk); }
+
+ const KBookmark& bookmark() const {
+ return m_bk; }
+
+ private:
+ KBookmark m_bk;
+};
+
+class SortByName {
+ public:
+ static QString key(const SortItem &item) {
+ return (item.bookmark().isGroup() ? "a" : "b")
+ + (item.bookmark().fullText().lower());
+ }
+};
+
+/* -------------------------------------- */
+
+void SortCommand::execute() {
+ if (m_commands.isEmpty()) {
+ KBookmarkGroup grp = CurrentMgr::bookmarkAt(m_groupAddress).toGroup();
+ Q_ASSERT(!grp.isNull());
+ SortItem firstChild(grp.first());
+ // this will call moveAfter, which will add
+ // the subcommands for moving the items
+ kInsertionSort<SortItem, SortByName, QString, SortCommand>
+ (firstChild, (*this));
+
+ } else {
+ // don't execute for second time on addCommand(cmd)
+ KEBMacroCommand::execute();
+ }
+}
+
+void SortCommand::moveAfter(const SortItem &moveMe,
+ const SortItem &afterMe) {
+ QString destAddress =
+ afterMe.isNull()
+ // move as first child
+ ? KBookmark::parentAddress(moveMe.bookmark().address()) + "/0"
+ // move after "afterMe"
+ : KBookmark::nextAddress(afterMe.bookmark().address());
+
+ MoveCommand *cmd = new MoveCommand(moveMe.bookmark().address(),
+ destAddress);
+ cmd->execute();
+ this->addCommand(cmd);
+}
+
+void SortCommand::unexecute() {
+ KEBMacroCommand::unexecute();
+}
+
+QString SortCommand::affectedBookmarks() const
+{
+ return m_groupAddress;
+}
+
+/* -------------------------------------- */
+
+KEBMacroCommand* CmdGen::setAsToolbar(const KBookmark &bk) {
+ KEBMacroCommand *mcmd = new KEBMacroCommand(i18n("Set as Bookmark Toolbar"));
+
+ KBookmarkGroup oldToolbar = CurrentMgr::self()->mgr()->toolbar();
+ if (!oldToolbar.isNull()) {
+ QValueList<EditCommand::Edition> lst;
+ lst.append(EditCommand::Edition("toolbar", "no"));
+ lst.append(EditCommand::Edition("icon", ""));
+ EditCommand *cmd1 = new EditCommand(oldToolbar.address(), lst);
+ mcmd->addCommand(cmd1);
+ }
+
+ QValueList<EditCommand::Edition> lst;
+ lst.append(EditCommand::Edition("toolbar", "yes"));
+ lst.append(EditCommand::Edition("icon", "bookmark_toolbar"));
+ // TODO - see below
+ EditCommand *cmd2 = new EditCommand(bk.address(), lst);
+ mcmd->addCommand(cmd2);
+
+ return mcmd;
+}
+
+bool CmdGen::shownInToolbar(const KBookmark &bk) {
+ return (bk.internalElement().attribute("showintoolbar") == "yes");
+}
+
+KEBMacroCommand* CmdGen::setShownInToolbar(const QValueList<KBookmark> &bks, bool show) {
+ QString i18n_name = i18n("%1 in Bookmark Toolbar").arg(show ? i18n("Show")
+ : i18n("Hide"));
+ KEBMacroCommand *mcmd = new KEBMacroCommand(i18n_name);
+
+ QValueList<KBookmark>::ConstIterator it, end;
+ end = bks.end();
+ for(it = bks.begin(); it != end; ++it)
+ {
+ QValueList<EditCommand::Edition> lst;
+ lst.append(EditCommand::Edition("showintoolbar", show ? "yes" : "no"));
+ EditCommand *cmd = new EditCommand((*it).address(), lst);
+ mcmd->addCommand(cmd);
+ }
+ return mcmd;
+}
+
+KEBMacroCommand* CmdGen::insertMimeSource(
+ const QString &cmdName, QMimeSource *_data, const QString &addr
+) {
+ QMimeSource *data = _data;
+ bool modified = false;
+ const char *format = 0;
+ for (int i = 0; format = data->format(i), format; i++) {
+ // qt docs don't say if encodedData(blah) where
+ // blah is not a stored mimetype should return null
+ // or not. so, we search. sucky...
+ if (strcmp(format, "GALEON_BOOKMARK") == 0) {
+ modified = true;
+ QStoredDrag *mydrag = new QStoredDrag("application/x-xbel");
+ mydrag->setEncodedData(data->encodedData("GALEON_BOOKMARK"));
+ data = mydrag;
+ break;
+ } else if( strcmp(format, "application/x-xbel" )==0) {
+ /* nothing we created a kbbookmarks drag when we copy element (slotcopy/slotpaste)*/
+ break;
+ } else if (strcmp(format, "text/uri-list") == 0) {
+ KURL::List uris;
+ if (!KURLDrag::decode(data, uris))
+ continue; // break out of format loop
+ KURL::List::ConstIterator uit = uris.begin();
+ KURL::List::ConstIterator uEnd = uris.end();
+ QValueList<KBookmark> urlBks;
+ for ( ; uit != uEnd ; ++uit ) {
+ if (!(*uit).url().endsWith(".desktop")) {
+ urlBks << KBookmark::standaloneBookmark((*uit).prettyURL(), (*uit));
+ continue;
+ }
+ KDesktopFile df((*uit).path(), true);
+ QString title = df.readName();
+ KURL url(df.readURL());
+ if (title.isNull())
+ title = url.prettyURL();
+ urlBks << KBookmark::standaloneBookmark(title, url, df.readIcon());
+ }
+ KBookmarkDrag *mydrag = KBookmarkDrag::newDrag(urlBks, 0);
+ modified = true;
+ data = mydrag;
+ }
+ }
+ if (!KBookmarkDrag::canDecode(data))
+ {
+ if (modified) // Shouldn't happen
+ delete data;
+ return 0;
+ }
+ KEBMacroCommand *mcmd = new KEBMacroCommand(cmdName);
+ QString currentAddress = addr;
+ QValueList<KBookmark> bookmarks = KBookmarkDrag::decode(data);
+ for (QValueListConstIterator<KBookmark> it = bookmarks.begin();
+ it != bookmarks.end(); ++it) {
+ CreateCommand *cmd = new CreateCommand(currentAddress, (*it));
+ cmd->execute();
+ mcmd->addCommand(cmd);
+ currentAddress = KBookmark::nextAddress(currentAddress);
+ }
+ if (modified)
+ delete data;
+ return mcmd;
+}
+
+KEBMacroCommand* CmdGen::itemsMoved(const QValueVector<KEBListViewItem *> & items,
+ const QString &newAddress, bool copy) {
+ KEBMacroCommand *mcmd = new KEBMacroCommand(copy ? i18n("Copy Items")
+ : i18n("Move Items"));
+
+ QValueList<KBookmark> list = ListView::self()->itemsToBookmarks( items );
+ QValueList<KBookmark>::const_iterator it, end;
+ it = list.begin();
+ end = list.end();
+
+ QString bkInsertAddr = newAddress;
+ for (; it != end; ++it) {
+ if (copy) {
+ CreateCommand *cmd;
+ cmd = new CreateCommand(
+ bkInsertAddr,
+ (*it).internalElement()
+ .cloneNode(true).toElement(),
+ (*it).text());
+
+ cmd->execute();
+ mcmd->addCommand(cmd);
+
+ bkInsertAddr = cmd->finalAddress();
+
+ } else /* if (move) */ {
+ QString oldAddress = (*it).address();
+ if (bkInsertAddr.startsWith(oldAddress)) //FIXME uses internal representation of address
+ continue;
+
+ MoveCommand *cmd = new MoveCommand(oldAddress, bkInsertAddr,
+ (*it).text());
+ cmd->execute();
+ mcmd->addCommand(cmd);
+
+ bkInsertAddr = cmd->finalAddress();
+ }
+
+ bkInsertAddr = KBookmark::nextAddress(bkInsertAddr);
+ }
+
+ return mcmd;
+}