You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kmplayer/src/playlistview.cpp

721 lines
28 KiB

/**
* Copyright (C) 2006 by Koos Vriezen <koos.vriezen@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
* Boston, MA 02110-1301, USA.
**/
#include <stdio.h>
#include <config.h>
// include files for TQt
#include <tqapplication.h>
#include <tqclipboard.h>
#include <tqpopupmenu.h>
#include <tqdrawutil.h>
#include <tqpainter.h>
#include <tqiconset.h>
#include <tqpixmap.h>
#include <tqheader.h>
#include <tqstyle.h>
#include <tqtimer.h>
#include <kiconloader.h>
#include <kfinddialog.h>
#include <kurldrag.h>
#include <tdeaction.h>
#include <tdelocale.h>
#include <kdebug.h>
#include "playlistview.h"
#include "kmplayerview.h"
#include "kmplayercontrolpanel.h"
using namespace KMPlayer;
//-------------------------------------------------------------------------
namespace KMPlayer {
KDE_NO_EXPORT bool isDragValid (TQDropEvent * de) {
if (KURLDrag::canDecode (de))
return true;
if (TQTextDrag::canDecode (de)) {
TQString text;
if (TQTextDrag::decode (de, text) && KURL (text).isValid ())
return true;
}
return false;
}
}
//-----------------------------------------------------------------------------
KDE_NO_CDTOR_EXPORT PlayListItem::PlayListItem (TQListViewItem *p, const NodePtr & e, PlayListView * lv) : TQListViewItem (p), node (e), listview (lv) {}
KDE_NO_CDTOR_EXPORT PlayListItem::PlayListItem (TQListViewItem *p, const AttributePtr & a, PlayListView * lv) : TQListViewItem (p), m_attr (a), listview (lv) {}
KDE_NO_CDTOR_EXPORT
PlayListItem::PlayListItem (PlayListView *v, const NodePtr &e, TQListViewItem *b)
: TQListViewItem (v, b), node (e), listview (v) {}
KDE_NO_CDTOR_EXPORT void PlayListItem::paintCell (TQPainter * p, const TQColorGroup & cg, int column, int width, int align) {
if (node && node->state == Node::state_began) {
TQColorGroup mycg (cg);
mycg.setColor (TQColorGroup::Foreground, listview->activeColor ());
mycg.setColor (TQColorGroup::Text, listview->activeColor ());
TQListViewItem::paintCell (p, mycg, column, width, align);
} else
TQListViewItem::paintCell (p, cg, column, width, align);
}
KDE_NO_CDTOR_EXPORT void PlayListItem::paintBranches (TQPainter * p, const TQColorGroup &, int w, int, int h) {
p->fillRect (0, 0, w, h, listview->paletteBackgroundColor());
}
//-----------------------------------------------------------------------------
KDE_NO_CDTOR_EXPORT
RootPlayListItem::RootPlayListItem (int _id, PlayListView *v, const NodePtr & e, TQListViewItem * before, int flgs)
: PlayListItem (v, e, before),
id (_id),
flags (flgs),
show_all_nodes (false),
have_dark_nodes (false) {}
KDE_NO_CDTOR_EXPORT void RootPlayListItem::paintCell (TQPainter * p, const TQColorGroup & cg, int column, int width, int align) {
TQColorGroup mycg (cg);
mycg.setColor (TQColorGroup::Base, listview->topLevelWidget()->paletteBackgroundColor());
mycg.setColor (TQColorGroup::Highlight, mycg.base ());
mycg.setColor (TQColorGroup::Text, listview->topLevelWidget()->paletteForegroundColor());
mycg.setColor (TQColorGroup::HighlightedText, mycg.text ());
TQListViewItem::paintCell (p, mycg, column, width, align);
qDrawShadeRect (p, 0, 0, width -1, height () -1, mycg, !isOpen ());
}
//-----------------------------------------------------------------------------
KDE_NO_CDTOR_EXPORT PlayListView::PlayListView (TQWidget * parent, View * view, TDEActionCollection * ac)
: TDEListView (parent, "kde_kmplayer_playlist"),
m_view (view),
m_find_dialog (0L),
m_active_color (30, 0, 255),
last_id (0),
last_drag_tree_id (0),
m_ignore_expanded (false) {
addColumn (TQString ());
header()->hide ();
//setRootIsDecorated (true);
setSorting (-1);
setAcceptDrops (true);
setDropVisualizer (true);
setItemsRenameable (true);
setItemMargin (2);
setPaletteBackgroundColor (TQColor (0, 0, 0));
setPaletteForegroundColor (TQColor (0xB2, 0xB2, 0xB2));
m_itemmenu = new TQPopupMenu (this);
folder_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("folder"), TDEIcon::Small);
auxiliary_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("folder_grey"), TDEIcon::Small);
video_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("video"), TDEIcon::Small);
info_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("messagebox_info"), TDEIcon::Small);
img_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("colorize"), TDEIcon::Small);
unknown_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("unknown"), TDEIcon::Small);
menu_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("player_playlist"), TDEIcon::Small);
config_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("configure"), TDEIcon::Small);
url_pix = TDEGlobal::iconLoader ()->loadIcon (TQString ("www"), TDEIcon::Small);
m_find = KStdAction::find (TQT_TQOBJECT(this), TQT_SLOT (slotFind ()), ac, "find");
m_find_next = KStdAction::findNext (TQT_TQOBJECT(this), TQT_SLOT(slotFindNext()), ac, "next");
m_find_next->setEnabled (false);
connect (this, TQT_SIGNAL (contextMenuRequested (TQListViewItem *, const TQPoint &, int)), this, TQT_SLOT (contextMenuItem (TQListViewItem *, const TQPoint &, int)));
connect (this, TQT_SIGNAL (expanded (TQListViewItem *)),
this, TQT_SLOT (itemExpanded (TQListViewItem *)));
connect (this, TQT_SIGNAL (dropped (TQDropEvent *, TQListViewItem *)),
this, TQT_SLOT (itemDropped (TQDropEvent *, TQListViewItem *)));
connect (this, TQT_SIGNAL (itemRenamed (TQListViewItem *)),
this, TQT_SLOT (itemIsRenamed (TQListViewItem *)));
connect (this, TQT_SIGNAL (selectionChanged (TQListViewItem *)),
this, TQT_SLOT (itemIsSelected (TQListViewItem *)));
}
KDE_NO_CDTOR_EXPORT PlayListView::~PlayListView () {
}
int PlayListView::addTree (NodePtr root, const TQString & source, const TQString & icon, int flags) {
//kdDebug () << "addTree " << source << " " << root->mrl()->src << endl;
RootPlayListItem * ritem = new RootPlayListItem (++last_id, this, root, lastChild(), flags);
ritem->source = source;
ritem->icon = icon;
ritem->setPixmap (0, !ritem->icon.isEmpty ()
? TDEGlobal::iconLoader ()->loadIcon (ritem->icon, TDEIcon::Small)
: url_pix);
updateTree (ritem, 0L, false);
return last_id;
}
KDE_NO_EXPORT PlayListItem * PlayListView::populate
(NodePtr e, NodePtr focus, RootPlayListItem *root, PlayListItem * pitem, PlayListItem ** curitem) {
root->have_dark_nodes |= !e->expose ();
if (pitem && !root->show_all_nodes && !e->expose ()) {
for (NodePtr c = e->lastChild (); c; c = c->previousSibling ())
populate (c, focus, root, pitem, curitem);
return pitem;
}
PlayListItem * item = pitem ? new PlayListItem (pitem, e, this) : root;
Mrl * mrl = e->mrl ();
TQString text (e->nodeName());
if (mrl && !root->show_all_nodes) {
if (mrl->pretty_name.isEmpty ()) {
if (!mrl->src.isEmpty())
text = KURL(mrl->src).prettyURL (0, KURL::StripFileProtocol);
else if (e->isDocument ())
text = e->hasChildNodes () ? i18n ("unnamed") : i18n ("none");
} else
text = mrl->pretty_name;
} else if (e->id == id_node_text)
text = e->nodeValue ();
item->setText(0, text);
if (focus == e)
*curitem = item;
if (e->active ())
ensureItemVisible (item);
for (NodePtr c = e->lastChild (); c; c = c->previousSibling ())
populate (c, focus, root, item, curitem);
if (e->isElementNode ()) {
AttributePtr a = convertNode<Element> (e)->attributes ()->first ();
if (a) {
root->have_dark_nodes = true;
if (root->show_all_nodes) {
PlayListItem * as = new PlayListItem (item, e, this);
as->setText (0, i18n ("[attributes]"));
as->setPixmap (0, menu_pix);
for (; a; a = a->nextSibling ()) {
PlayListItem * ai = new PlayListItem (as, a, this);
ai->setText (0, TQString ("%1=%2").arg (
a->name ().toString ()).arg (a->value ()));
ai->setPixmap (0, config_pix);
}
}
}
}
if (item != root) {
Node::PlayType pt = e->playType ();
TQPixmap * pix;
switch (pt) {
case Node::play_type_image:
pix = &img_pix;
break;
case Node::play_type_info:
pix = &info_pix;
break;
default:
if (pt > Node::play_type_none)
pix = &video_pix;
else
pix = item->firstChild ()
? e->auxiliaryNode ()
? &auxiliary_pix : &folder_pix
: &unknown_pix;
}
item->setPixmap (0, *pix);
if (root->flags & PlayListView::AllowDrag)
item->setDragEnabled (true);
}
return item;
}
void PlayListView::updateTree (int id, NodePtr root, NodePtr active,
bool select, bool open) {
// TODO, if root is same as rootitems->node and treeversion is the same
// and show all nodes is unchanged then only update the cells
TQWidget * w = focusWidget ();
if (w && w != this)
w->clearFocus ();
//setSelected (firstChild (), true);
RootPlayListItem * ritem = static_cast <RootPlayListItem *> (firstChild ());
RootPlayListItem * before = 0L;
for (; ritem; ritem =static_cast<RootPlayListItem*>(ritem->nextSibling())) {
if (ritem->id == id) {
if (!root)
root = ritem->node;
break; // found based on id
}
if (id == -1) { // wildcard id
for (NodePtr n = root; n; n = n->parentNode ())
if (n == ritem->node) {
root = n;
break;
}
if (root == ritem->node) {
id = ritem->id;
break; // found based on matching (ancestor) node
}
}
if (ritem->id < id)
before = ritem;
}
if (!root) {
delete ritem;
return;
}
if (!ritem) {
ritem =new RootPlayListItem(id, this, root, before,AllowDrops|TreeEdit);
ritem->setPixmap (0, url_pix);
} else
ritem->node = root;
m_find_next->setEnabled (!!m_current_find_elm);
bool need_timer = !tree_update;
tree_update = new TreeUpdate (ritem, active, select, open, tree_update);
if (need_timer)
TQTimer::singleShot (0, this, TQT_SLOT (updateTrees ()));
}
KDE_NO_EXPORT void PlayListView::updateTrees () {
for (; tree_update; tree_update = tree_update->next) {
updateTree (tree_update->root_item, tree_update->node, tree_update->select);
if (tree_update->open) // FIXME for non-root nodes lazy loading
setOpen (tree_update->root_item, true);
}
}
void PlayListView::updateTree (RootPlayListItem * ritem, NodePtr active, bool select) {
bool set_open = ritem->id == 0 || (ritem ? ritem->isOpen () : false);
m_ignore_expanded = true;
PlayListItem * curitem = 0L;
while (ritem->firstChild ())
delete ritem->firstChild ();
if (!ritem->node)
return;
populate (ritem->node, active, ritem, 0L, &curitem);
if (set_open && ritem->firstChild () && !ritem->isOpen ())
setOpen (ritem, true);
if (curitem && select) {
setSelected (curitem, true);
ensureItemVisible (curitem);
}
if (!ritem->have_dark_nodes && ritem->show_all_nodes && !m_view->editMode())
toggleShowAllNodes (); // redo, because the user can't change it anymore
m_ignore_expanded = false;
}
void PlayListView::selectItem (const TQString & txt) {
TQListViewItem * item = selectedItem ();
if (item && item->text (0) == txt)
return;
item = findItem (txt, 0);
if (item) {
setSelected (item, true);
ensureItemVisible (item);
}
}
KDE_NO_EXPORT TQDragObject * PlayListView::dragObject () {
PlayListItem * item = static_cast <PlayListItem *> (selectedItem ());
if (item && item->node) {
TQString txt = item->node->isPlayable ()
? item->node->mrl ()->src : item->node->outerXML ();
TQTextDrag * drag = new TQTextDrag (txt, this);
last_drag_tree_id = rootItem (item)->id;
m_last_drag = item->node;
drag->setPixmap (*item->pixmap (0));
if (!item->node->isPlayable ())
drag->setSubtype ("xml");
return drag;
}
return 0;
}
KDE_NO_EXPORT void PlayListView::setFont (const TQFont & fnt) {
setTreeStepSize (TQFontMetrics (fnt).boundingRect ('m').width ());
TDEListView::setFont (fnt);
}
KDE_NO_EXPORT void PlayListView::contextMenuItem (TQListViewItem * vi, const TQPoint & p, int) {
if (vi) {
PlayListItem * item = static_cast <PlayListItem *> (vi);
if (item->node || item->m_attr) {
RootPlayListItem * ritem = rootItem (vi);
if (m_itemmenu->count () > 0) {
m_find->unplug (m_itemmenu);
m_find_next->unplug (m_itemmenu);
m_itemmenu->clear ();
}
m_itemmenu->insertItem (TDEGlobal::iconLoader ()->loadIconSet
(TQString ("editcopy"), TDEIcon::Small, 0, true),
i18n ("&Copy to Clipboard"),
this, TQT_SLOT (copyToClipboard ()), 0, 0);
if (item->m_attr ||
(item->node && (item->node->isPlayable () ||
item->node->isDocument ()) &&
item->node->mrl ()->bookmarkable))
m_itemmenu->insertItem (TDEGlobal::iconLoader ()->loadIconSet
(TQString ("bookmark_add"), TDEIcon::Small, 0, true),
i18n ("&Add Bookmark"),
this, TQT_SLOT (addBookMark ()), 0, 1);
if (ritem->have_dark_nodes) {
m_itemmenu->insertItem (i18n ("&Show all"),
this, TQT_SLOT (toggleShowAllNodes ()), 0, 2);
m_itemmenu->setItemChecked (2, ritem->show_all_nodes);
}
m_itemmenu->insertSeparator ();
m_find->plug (m_itemmenu);
m_find_next->plug (m_itemmenu);
emit prepareMenu (item, m_itemmenu);
m_itemmenu->exec (p);
}
} else
m_view->controlPanel ()->popupMenu ()->exec (p);
}
void PlayListView::itemExpanded (TQListViewItem * item) {
if (!m_ignore_expanded && item->childCount () == 1) {
PlayListItem * child_item = static_cast<PlayListItem*>(item->firstChild ());
child_item->setOpen (rootItem (item)->show_all_nodes ||
(child_item->node && child_item->node->expose ()));
}
}
RootPlayListItem * PlayListView::rootItem (TQListViewItem * item) const {
if (!item)
return 0L;
while (item->parent ())
item = item->parent ();
return static_cast <RootPlayListItem *> (item);
}
RootPlayListItem * PlayListView::rootItem (int id) const {
RootPlayListItem * ri = static_cast <RootPlayListItem *> (firstChild ());
for (; ri; ri = static_cast <RootPlayListItem *> (ri->nextSibling ())) {
if (ri->id == id)
return ri;
}
return 0L;
}
void PlayListView::copyToClipboard () {
PlayListItem * item = currentPlayListItem ();
TQString text = item->text (0);
if (item->node) {
Mrl * mrl = item->node->mrl ();
if (mrl && !mrl->src.isEmpty ())
text = mrl->src;
}
TQApplication::clipboard()->setText (text);
}
void PlayListView::addBookMark () {
PlayListItem * item = currentPlayListItem ();
if (item->node) {
Mrl * mrl = item->node->mrl ();
KURL url (mrl ? mrl->src : TQString (item->node->nodeName ()));
emit addBookMark (mrl->pretty_name.isEmpty () ? url.prettyURL () : mrl->pretty_name, url.url ());
}
}
void PlayListView::toggleShowAllNodes () {
PlayListItem * cur_item = currentPlayListItem ();
if (cur_item) {
RootPlayListItem * ritem = rootItem (cur_item);
showAllNodes (rootItem (cur_item), !ritem->show_all_nodes);
}
}
KDE_NO_EXPORT void PlayListView::showAllNodes(RootPlayListItem *ri, bool show) {
if (ri && ri->show_all_nodes != show) {
PlayListItem * cur_item = currentPlayListItem ();
ri->show_all_nodes = show;
updateTree (ri->id, ri->node, cur_item->node, true, false);
if (m_current_find_elm &&
ri->node->document() == m_current_find_elm->document() &&
!ri->show_all_nodes) {
if (!m_current_find_elm->expose ())
m_current_find_elm = 0L;
m_current_find_attr = 0L;
}
}
}
KDE_NO_EXPORT bool PlayListView::acceptDrag (TQDropEvent * de) const {
TQListViewItem * item = itemAt (contentsToViewport (de->pos ()));
if (item && (de->source () == this || isDragValid (de))) {
RootPlayListItem * ritem = rootItem (item);
return ritem->flags & AllowDrops;
}
return false;
}
KDE_NO_EXPORT void PlayListView::itemDropped (TQDropEvent * de, TQListViewItem *after) {
if (!after) { // could still be a descendent
after = itemAt (contentsToViewport (de->pos ()));
if (after)
after = after->parent ();
}
if (after) {
RootPlayListItem * ritem = rootItem (after);
if (ritem->id > 0)
return;
NodePtr n = static_cast <PlayListItem *> (after)->node;
bool valid = n && (!n->isDocument () || n->hasChildNodes ());
KURL::List sl;
if (KURLDrag::canDecode (de)) {
KURLDrag::decode (de, sl);
} else if (TQTextDrag::canDecode (de)) {
TQString text;
TQTextDrag::decode (de, text);
sl.push_back (KURL (text));
}
if (valid && sl.size () > 0) {
bool as_child = n->isDocument () || n->hasChildNodes ();
NodePtr d = n->document ();
for (int i = sl.size (); i > 0; i--) {
Node * ni = new KMPlayer::GenericURL (d, sl[i-1].url ());
if (as_child)
n->insertBefore (ni, n->firstChild ());
else
n->parentNode ()->insertBefore (ni, n->nextSibling ());
}
PlayListItem * citem = currentPlayListItem ();
NodePtr cn;
if (citem)
cn = citem->node;
updateTree (ritem, cn, true);
}
} else
m_view->dropEvent (de);
}
KDE_NO_EXPORT void PlayListView::itemIsRenamed (TQListViewItem * qitem) {
PlayListItem * item = static_cast <PlayListItem *> (qitem);
if (item->node) {
RootPlayListItem * ri = rootItem (qitem);
if (!ri->show_all_nodes && item->node->isEditable ()) {
item->node->setNodeName (item->text (0));
if (item->node->mrl ()->pretty_name.isEmpty ())
item->setText (0, KURL (item->node->mrl ()->src).prettyURL (0, KURL::StripFileProtocol));
} else // restore damage ..
updateTree (ri, item->node, true);
} else if (item->m_attr) {
TQString txt = item->text (0);
int pos = txt.find (TQChar ('='));
if (pos > -1) {
item->m_attr->setName (txt.left (pos));
item->m_attr->setValue (txt.mid (pos + 1));
} else {
item->m_attr->setName (txt);
item->m_attr->setValue (TQString (""));
}
PlayListItem * pi = static_cast <PlayListItem *> (item->parent ());
if (pi && pi->node)
pi->node->document ()->m_tree_version++;
}
}
KDE_NO_EXPORT void PlayListView::itemIsSelected (TQListViewItem * qitem) {
RootPlayListItem * ri = rootItem (qitem);
setItemsRenameable (ri && (ri->flags & TreeEdit) && ri != qitem);
}
KDE_NO_EXPORT void PlayListView::rename (TQListViewItem * qitem, int c) {
PlayListItem * item = static_cast <PlayListItem *> (qitem);
if (rootItem (qitem)->show_all_nodes && item && item->m_attr) {
PlayListItem * pi = static_cast <PlayListItem *> (qitem->parent ());
if (pi && pi->node && pi->node->isEditable ())
TDEListView::rename (item, c);
} else if (item && item->node && item->node->isEditable ()) {
if (!rootItem (qitem)->show_all_nodes &&
item->node->isPlayable () &&
item->node->mrl ()->pretty_name.isEmpty ())
// populate() has crippled src, restore for editing
item->setText (0, item->node->mrl ()->src);
TDEListView::rename (item, c);
}
}
KDE_NO_EXPORT void PlayListView::editCurrent () {
TQListViewItem * qitem = selectedItem ();
if (qitem) {
RootPlayListItem * ri = rootItem (qitem);
if (ri && (ri->flags & TreeEdit) && ri != qitem)
rename (qitem, 0);
}
}
KDE_NO_EXPORT void PlayListView::slotFind () {
m_current_find_elm = 0L;
if (!m_find_dialog) {
m_find_dialog = new KFindDialog (false, this, "kde_kmplayer_find", KFindDialog::CaseSensitive);
m_find_dialog->setHasSelection (false);
connect(m_find_dialog, TQT_SIGNAL(okClicked ()), this, TQT_SLOT(slotFindOk ()));
} else
m_find_dialog->setPattern (TQString ());
m_find_dialog->show ();
}
static TQListViewItem * findNodeInTree (NodePtr n, TQListViewItem * item) {
//kdDebug () << "item:" << item->text (0) << " n:" << (n ? n->nodeName () : "null" ) <<endl;
PlayListItem * pi = static_cast <PlayListItem *> (item);
if (!n || !pi->node)
return 0L;
if (n == pi->node)
return item;
for (TQListViewItem * ci = item->firstChild(); ci; ci = ci->nextSibling ()) {
//kdDebug () << "ci:" << ci->text (0) << " n:" << n->nodeName () <<endl;
TQListViewItem * vi = findNodeInTree (n, ci);
if (vi)
return vi;
}
return 0L;
}
KDE_NO_EXPORT void PlayListView::slotFindOk () {
if (!m_find_dialog)
return;
m_find_dialog->hide ();
long opt = m_find_dialog->options ();
current_find_tree_id = 0;
if (opt & KFindDialog::FromCursor && currentItem ()) {
PlayListItem * lvi = currentPlayListItem ();
if (lvi && lvi->node) {
m_current_find_elm = lvi->node;
current_find_tree_id = rootItem (lvi)->id;
} else if (lvi && lvi->m_attr) {
PlayListItem*pi=static_cast<PlayListItem*>(currentItem()->parent());
if (pi) {
m_current_find_attr = lvi->m_attr;
m_current_find_elm = pi->node;
}
}
} else if (!(opt & KFindDialog::FindIncremental))
m_current_find_elm = 0L;
if (!m_current_find_elm) {
PlayListItem * lvi = static_cast <PlayListItem *> (firstChild ());
if (lvi)
m_current_find_elm = lvi->node;
}
if (m_current_find_elm)
slotFindNext ();
}
/* A bit tricky, but between the find's PlayListItems might be gone, so
* try to match on the generated tree following the source's document tree
*/
KDE_NO_EXPORT void PlayListView::slotFindNext () {
if (!m_find_dialog)
return;
TQString str = m_find_dialog->pattern();
if (!m_current_find_elm || str.isEmpty ())
return;
long opt = m_find_dialog->options ();
TQRegExp regexp;
if (opt & KFindDialog::RegularExpression)
regexp = str;
bool cs = (opt & KFindDialog::CaseSensitive);
bool found = false;
NodePtr node, n = m_current_find_elm;
RootPlayListItem * ri = rootItem (current_find_tree_id);
while (!found && n) {
if (ri->show_all_nodes || n->expose ()) {
bool elm = n->isElementNode ();
TQString val = n->nodeName ();
if (elm && !ri->show_all_nodes) {
Mrl * mrl = n->mrl ();
if (mrl) {
if (mrl->pretty_name.isEmpty ()) {
if (!mrl->src.isEmpty())
val = KURL(mrl->src).prettyURL();
} else
val = mrl->pretty_name;
}
} else if (!elm)
val = n->nodeValue ();
if (((opt & KFindDialog::RegularExpression) &&
val.find (regexp, 0) > -1) ||
(!(opt & KFindDialog::RegularExpression) &&
val.find (str, 0, cs) > -1)) {
node = n;
m_current_find_attr = 0L;
found = true;
} else if (elm && ri->show_all_nodes) {
for (AttributePtr a = convertNode <Element> (n)->attributes ()->first (); a; a = a->nextSibling ()) {
TQString attr = a->name ().toString ();
if (((opt & KFindDialog::RegularExpression) &&
(attr.find (regexp, 0) || a->value ().find (regexp, 0) > -1)) ||
(!(opt & KFindDialog::RegularExpression) &&
(attr.find (str, 0, cs) > -1 || a->value ().find (str, 0, cs) > -1))) {
node = n;
m_current_find_attr = a;
found = true;
break;
}
}
}
}
if (n) { //set pointer to next
if (opt & KFindDialog::FindBackwards) {
if (n->lastChild ()) {
n = n->lastChild ();
} else if (n->previousSibling ()) {
n = n->previousSibling ();
} else {
for (n = n->parentNode (); n; n = n->parentNode ())
if (n->previousSibling ()) {
n = n->previousSibling ();
break;
}
while (!n && current_find_tree_id > 0) {
ri = rootItem (--current_find_tree_id);
if (ri)
n = ri->node;
}
}
} else {
if (n->firstChild ()) {
n = n->firstChild ();
} else if (n->nextSibling ()) {
n = n->nextSibling ();
} else {
for (n = n->parentNode (); n; n = n->parentNode ())
if (n->nextSibling ()) {
n = n->nextSibling ();
break;
}
while (!n) {
ri = rootItem (++current_find_tree_id);
if (!ri)
break;
n = ri->node;
}
}
}
}
}
m_current_find_elm = n;
kdDebug () << " search for " << str << "=" << (node ? node->nodeName () : "not found") << " next:" << (n ? n->nodeName () : " not found") << endl;
if (found) {
TQListViewItem * fc = findNodeInTree (node, ri);
if (!fc) {
m_current_find_elm = 0L;
kdDebug () << "node not found in tree tree:" << ri->id << endl;
} else {
setSelected (fc, true);
if (m_current_find_attr && fc->firstChild () && fc->firstChild ()->firstChild ())
ensureItemVisible (fc->firstChild ()->firstChild ());
ensureItemVisible (fc);
}
}
m_find_next->setEnabled (!!m_current_find_elm);
}
#include "playlistview.moc"