~ubuntu-branches/ubuntu/wily/psi/wily

« back to all changes in this revision

Viewing changes to src/discodlg.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2010-02-19 09:37:12 UTC
  • mfrom: (6.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100219093712-e225xvm1wjcf1cgi
Tags: 0.14-2
* comment out only function which uses va_list to work around build
  problems on armel
* Set Standards-Version to 3.8.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include "discodlg.h"
22
22
 
23
 
#include <q3listview.h>
24
 
#include <q3popupmenu.h>
25
 
#include <Q3PtrList>
 
23
#include <QTreeWidget>
 
24
#include <QHeaderView>
 
25
#include <QMenu>
26
26
 
27
27
#include <QComboBox>
28
28
#include <QCheckBox>
148
148
        : QObject(parent) {}
149
149
 
150
150
signals:
151
 
        void itemUpdated(Q3ListViewItem *);
 
151
        void itemUpdated(QTreeWidgetItem *);
152
152
 
153
153
private:
154
154
        friend class DiscoListItem;
173
173
// DiscoListItem
174
174
//----------------------------------------------------------------------------
175
175
 
176
 
class DiscoListItem : public QObject, public Q3ListViewItem
 
176
class DiscoListItem : public QObject, public QTreeWidgetItem
177
177
{
178
178
        Q_OBJECT
179
179
public:
180
 
        DiscoListItem(DiscoItem it, DiscoData *d, Q3ListView *parent);
181
 
        DiscoListItem(DiscoItem it, DiscoData *d, Q3ListViewItem *parent);
 
180
        DiscoListItem(DiscoItem it, DiscoData *d, QTreeWidget *parent);
 
181
        DiscoListItem(DiscoItem it, DiscoData *d, QTreeWidgetItem *parent);
182
182
        ~DiscoListItem();
183
183
 
184
 
        QString text(int columns) const;
185
 
        void setOpen(bool open);
 
184
        void setExpanded(bool expand);
186
185
        const DiscoItem &item() const;
187
186
 
188
187
        void itemSelected();
220
219
        // helper functions
221
220
        void init(DiscoItem it, DiscoData *dd);
222
221
 
 
222
        void hideChildIndicator();
 
223
 
223
224
        bool autoItemsEnabled() const;
224
225
        bool autoInfoEnabled() const;
225
226
        DiscoDlg *dlg() const;
226
227
};
227
228
 
228
 
DiscoListItem::DiscoListItem(DiscoItem it, DiscoData *_d, Q3ListView *parent)
229
 
: Q3ListViewItem (parent)
 
229
DiscoListItem::DiscoListItem(DiscoItem it, DiscoData *_d, QTreeWidget *parent)
 
230
: QTreeWidgetItem (parent)
230
231
{
231
232
        isRoot = true;
232
233
 
233
234
        init(it, _d);
234
235
}
235
236
 
236
 
DiscoListItem::DiscoListItem(DiscoItem it, DiscoData *_d, Q3ListViewItem *parent)
237
 
: Q3ListViewItem (parent)
 
237
DiscoListItem::DiscoListItem(DiscoItem it, DiscoData *_d, QTreeWidgetItem *parent)
 
238
: QTreeWidgetItem (parent)
238
239
{
239
240
        isRoot = false;
240
241
 
254
255
        alreadyItems = alreadyInfo = false;
255
256
 
256
257
        if ( !autoItemsEnabled() )
257
 
                setExpandable (true);
 
258
                setChildIndicatorPolicy(ShowIndicator);
258
259
 
259
260
        autoInfo = false;
260
261
        if ( autoInfoEnabled() || isRoot ) {
309
310
                }
310
311
        }
311
312
 
312
 
        bool pixmapOk = false;
 
313
        setText(0, di.name().simplified());
 
314
        setText(1, di.jid().full());
 
315
        setText(2, di.node().simplified());
 
316
 
 
317
        bool iconOk = false;
313
318
        if ( !di.identities().isEmpty() ) {
314
319
                DiscoItem::Identity id = di.identities().first();
315
320
 
316
321
                if ( !id.category.isEmpty() ) {
317
 
                        PsiIcon ic = category2icon(id.category, id.type);
 
322
                        QIcon icon = category2icon(id.category, id.type).icon();
318
323
 
319
 
                        if ( !ic.impix().isNull() ) {
320
 
                                setPixmap (0, ic.impix());
321
 
                                pixmapOk = true;
 
324
                        if ( !icon.isNull() ) {
 
325
                                setIcon(0, icon);
 
326
                                iconOk = true;
322
327
                        }
323
328
                }
324
329
        }
325
330
 
326
 
        if ( !pixmapOk )
327
 
                setPixmap(0, PsiIconset::instance()->status(di.jid(), STATUS_ONLINE).impix());
328
 
 
329
 
        repaint();
 
331
        if ( !iconOk )
 
332
                setIcon(0, PsiIconset::instance()->status(di.jid(), STATUS_ONLINE).icon());
330
333
 
331
334
        if ( isSelected() ) // update actions
332
335
                emit d->d->itemUpdated( this );
333
336
}
334
337
 
335
 
QString DiscoListItem::text (int c) const
336
 
{
337
 
        if (c == 0)
338
 
                return di.name().simplified();
339
 
        else if (c == 1)
340
 
                return di.jid().full();
341
 
        else if (c == 2)
342
 
                return di.node().simplified();
343
 
        return "";
344
 
}
345
 
 
346
338
QString DiscoListItem::getErrorInfo() const
347
339
{
348
340
        return errorInfo;
355
347
 
356
348
DiscoDlg *DiscoListItem::dlg() const
357
349
{
358
 
        return (DiscoDlg *)listView()->parent();
 
350
        return (DiscoDlg *)treeWidget()->parent();
359
351
}
360
352
 
361
353
bool DiscoListItem::autoItemsEnabled() const
368
360
        return dlg()->ck_autoInfo->isChecked();
369
361
}
370
362
 
371
 
void DiscoListItem::setOpen (bool o)
 
363
void DiscoListItem::setExpanded (bool expand)
372
364
{
373
 
        if ( o ) {
 
365
        if ( expand ) {
374
366
                if ( !alreadyItems )
375
367
                        updateItems();
376
368
                else
377
369
                        autoItemsChildren();
378
370
        }
379
371
 
380
 
        Q3ListViewItem::setOpen(o);
 
372
        QTreeWidgetItem::setExpanded(expand);
381
373
}
382
374
 
383
375
void DiscoListItem::itemSelected()
575
567
        return ret;
576
568
}
577
569
 
 
570
void DiscoListItem::hideChildIndicator()
 
571
{
 
572
        setChildIndicatorPolicy(DontShowIndicator);
 
573
#if QT_VERSION >= 0x040500
 
574
        emitDataChanged();
 
575
#else
 
576
        Qt::ItemFlags tmp = flags();
 
577
        setFlags(0);
 
578
        setFlags(tmp);
 
579
#endif
 
580
}
 
581
 
578
582
void DiscoListItem::updateItemsFinished(const DiscoList &list)
579
583
{
580
 
        Q3Dict<DiscoListItem> children;
581
 
        DiscoListItem *child = (DiscoListItem *)firstChild();
582
 
        while ( child ) {
 
584
        treeWidget()->setUpdatesEnabled(false);
 
585
 
 
586
        QHash<QString, DiscoListItem*> children;
 
587
        DiscoListItem *child = (DiscoListItem *)QTreeWidgetItem::child(0);
 
588
        for ( int i = 1; child; ++i ) {
583
589
                children.insert( child->hash(), child );
584
590
 
585
 
                child = (DiscoListItem *)child->nextSibling();
 
591
                child = (DiscoListItem *)QTreeWidgetItem::child(i);
586
592
        }
587
593
 
588
594
        // add/update items
590
596
                const DiscoItem a = *it;
591
597
 
592
598
                QString key = computeHash(a.jid().full(), a.node());
593
 
                DiscoListItem *child = children[ key ];
 
599
                child = children[ key ];
594
600
 
595
601
                if ( child ) {
596
602
                        child->copyItem ( a );
602
608
        }
603
609
 
604
610
        // remove all items that are not on new DiscoList
605
 
        children.setAutoDelete( true );
 
611
        qDeleteAll(children);
606
612
        children.clear();
607
613
 
608
 
        if ( autoItems && isOpen() )
 
614
        if ( autoItems && isExpanded() )
609
615
                autoItemsChildren();
610
616
 
611
 
        // don't forget to remove '+' (or '-') sign in case, that the child list is empty
612
 
        setExpandable ( !list.isEmpty() );
613
 
 
614
 
        repaint();
 
617
        if (list.isEmpty()) {
 
618
                hideChildIndicator();
 
619
        }
615
620
 
616
621
        // root item is initially hidden
617
 
        if ( isRoot && !isVisible() )
618
 
                setVisible (true);
 
622
        if ( isRoot && isHidden() )
 
623
                setHidden(false);
 
624
 
 
625
        treeWidget()->setUpdatesEnabled(true);
619
626
}
620
627
 
621
628
void DiscoListItem::autoItemsChildren() const
623
630
        if ( !autoItemsEnabled() )
624
631
                return;
625
632
 
626
 
        DiscoListItem *child = (DiscoListItem *)firstChild();
627
 
        while ( child ) {
 
633
        DiscoListItem *child = (DiscoListItem *)QTreeWidgetItem::child(0);
 
634
        for ( int i = 1; child; ++i ) {
628
635
                child->updateItems(true);
629
636
 
630
 
                child = (DiscoListItem *)child->nextSibling();
 
637
                child = (DiscoListItem *)QTreeWidgetItem::child(i);
631
638
        }
632
639
}
633
640
 
653
660
        else {
654
661
                QString error_str = jt->statusString();
655
662
                int error_code = jt->statusCode();
656
 
                setExpandable(false);
 
663
                hideChildIndicator();
657
664
 
658
665
                // we change the icon for the items with disco#info returning type=="cancel" || type=="wait" error codes
659
666
                // based on http://www.jabber.org/jeps/jep-0086.html
661
668
                // FIXME: use another method for checking XMPP error-types when Iris will provide one
662
669
                if ( error_code==400 || error_code==404 || error_code==405 || error_code==409 ||
663
670
                     error_code==500 || error_code==501 || error_code==503 || error_code==504 ) {
664
 
                        bool pixmapOk = false;
 
671
                        bool iconOk = false;
665
672
                        if ( !di.identities().isEmpty() ) {
666
673
                                DiscoItem::Identity id = di.identities().first();
667
674
                                if ( !id.category.isEmpty() ) {
668
 
                                        PsiIcon ic = category2icon(id.category, id.type, STATUS_ERROR);
 
675
                                        QIcon icon = category2icon(id.category, id.type, STATUS_ERROR).icon();
669
676
 
670
 
                                        if ( !ic.impix().isNull() ) {
671
 
                                                setPixmap (0, ic.impix());
672
 
                                                pixmapOk = true;
 
677
                                        if ( !icon.isNull() ) {
 
678
                                                setIcon (0, icon);
 
679
                                                iconOk = true;
673
680
                                        }
674
681
                                }
675
682
                        }
676
 
                        if ( !pixmapOk )
677
 
                                setPixmap(0, PsiIconset::instance()->status(di.jid(), STATUS_ERROR).impix());
678
 
                } else {
679
 
                        repaint(); //for setExpandable() called earlier
 
683
                        if ( !iconOk )
 
684
                                setIcon(0, PsiIconset::instance()->status(di.jid(), STATUS_ERROR).icon());
680
685
                }
681
686
 
682
687
                errorInfo=QString("%1").arg(QString(error_str).replace('\n', "<br>"));
694
699
{
695
700
        copyItem( item );
696
701
 
697
 
        if ( isRoot && !isVisible() )
698
 
                setVisible (true);
 
702
        if ( isRoot && isHidden() )
 
703
                setHidden(false);
699
704
}
700
705
 
701
706
//----------------------------------------------------------------------------
702
707
// DiscoList
703
708
//----------------------------------------------------------------------------
704
709
 
705
 
class DiscoListView : public Q3ListView
 
710
class DiscoListView : public QTreeWidget
706
711
{
707
712
        Q_OBJECT
708
713
public:
717
722
};
718
723
 
719
724
DiscoListView::DiscoListView(QWidget *parent)
720
 
: Q3ListView(parent)
 
725
: QTreeWidget(parent)
721
726
{
722
 
        addColumn( tr( "Name" ) );
723
 
        addColumn( tr( "JID" ) );
724
 
        addColumn( tr( "Node" ) );
725
 
        for (int i = 0; i < 3; i++)
726
 
                setColumnWidthMode(i, Q3ListView::Manual);
727
 
        header()->setStretchEnabled(true, 0);
 
727
        installEventFilter(this);
 
728
        setHeaderLabels( QStringList() << tr( "Name" ) << tr( "JID" ) << tr( "Node" ) );
 
729
//      header()->setResizeMode(0, QHeaderView::Stretch);
 
730
//      header()->setResizeMode(1, QHeaderView::ResizeToContents);
 
731
//      header()->setResizeMode(2, QHeaderView::ResizeToContents);
 
732
        header()->setStretchLastSection(false);
 
733
        setRootIsDecorated(false);
728
734
}
729
735
 
730
736
void DiscoListView::resizeEvent(QResizeEvent* e)
731
737
{
732
 
        Q3ListView::resizeEvent(e);
733
 
 
734
 
        setColumnWidth(2, header()->fontMetrics().width(columnText(2)) * 2);
735
 
        float remainingWidth = visibleWidth() - columnWidth(2);
736
 
        setColumnWidth(1, int(remainingWidth * 0.3));
737
 
 
738
 
        header()->adjustHeaderSize();
 
738
        QTreeWidget::resizeEvent(e);
 
739
 
 
740
        QHeaderView* h = header();
 
741
        h->resizeSection(2, h->fontMetrics().width(headerItem()->text(2)) * 2);
 
742
        float remainingWidth = viewport()->width() - h->sectionSize(2);
 
743
        h->resizeSection(1, int(remainingWidth * 0.3));
 
744
        h->resizeSection(0, int(remainingWidth * 0.7));
 
745
 
 
746
        //h->adjustHeaderSize();
739
747
}
740
748
 
741
749
/**
816
824
        }
817
825
 
818
826
        text += "</qt>";
819
 
        QRect r( itemRect(i) );
 
827
        QRect r( visualItemRect(i) );
820
828
        PsiToolTip::showText(pos, text, this);
821
829
        return true;
822
830
}
829
837
                maybeTip(w->mapToGlobal(he->pos()));
830
838
                return true;
831
839
        }
832
 
        return Q3ListView::eventFilter(o, e);
 
840
        return QTreeWidget::eventFilter(o, e);
833
841
}
834
842
 
835
843
//----------------------------------------------------------------------------
859
867
 
860
868
        // helper class to store browser history
861
869
        class History {
862
 
        private:
863
 
                Q3ListViewItem *item;
864
870
        public:
865
 
                History(Q3ListViewItem *it) {
866
 
                        item = it;
867
 
                }
868
 
 
869
 
                ~History() {
870
 
                        if ( item )
871
 
                                delete item;
872
 
                }
873
 
 
874
 
                Q3ListViewItem *takeItem() {
875
 
                        Q3ListViewItem *i = item;
876
 
                        item = 0;
877
 
                        return i;
878
 
                }
 
871
                History(const XMPP::Jid& _jid, const QString& _node)
 
872
                        : jid(_jid)
 
873
                        , node(_node)
 
874
                {}
 
875
 
 
876
                XMPP::Jid jid;
 
877
                QString node;
879
878
        };
880
879
 
881
880
public: // data
891
890
        // custom actions, that will be added to toolbar and context menu
892
891
        IconAction *actRegister, *actSearch, *actJoin, *actAHCommand, *actVCard, *actAdd;
893
892
 
894
 
        typedef Q3PtrList<History> HistoryList;
 
893
        typedef QList<History*> HistoryList;
895
894
        HistoryList backHistory, forwardHistory;
896
895
 
897
896
        BusyWidget *busy;
901
900
        ~Private();
902
901
 
903
902
public slots:
904
 
        void doDisco(QString host = QString::null, QString node = QString::null);
 
903
        void doDisco(QString host = QString::null, QString node = QString::null, bool doHistory = true);
905
904
 
906
905
        void actionStop();
907
906
        void actionRefresh();
910
909
        void actionBack();
911
910
        void actionForward();
912
911
        void updateBackForward();
913
 
        void backForwardHelper(Q3ListViewItem *);
914
912
 
915
913
        void updateComboBoxes(Jid j, QString node);
916
914
 
920
918
        void disableButtons();
921
919
        void enableButtons(const DiscoItem &);
922
920
 
923
 
        void itemSelected (Q3ListViewItem *);
924
 
        void itemDoubleclicked (Q3ListViewItem *);
 
921
        void itemSelected (QTreeWidgetItem *);
 
922
        void itemExpanded (QTreeWidgetItem *);
 
923
        void itemDoubleclicked (QTreeWidgetItem *);
925
924
        bool eventFilter (QObject *, QEvent *);
926
925
 
927
926
        void setProtocol(int);
943
942
        connect(data.tasks, SIGNAL(started()),  SLOT(itemUpdateStarted()));
944
943
        connect(data.tasks, SIGNAL(finished()), SLOT(itemUpdateFinished()));
945
944
        data.d = new DiscoConnector(this);
946
 
        connect(data.d, SIGNAL(itemUpdated(Q3ListViewItem *)), SLOT(itemSelected (Q3ListViewItem *)));
 
945
        connect(data.d, SIGNAL(itemUpdated(QTreeWidgetItem *)), SLOT(itemSelected (QTreeWidgetItem *)));
947
946
        data.protocol = DiscoData::Auto;
948
947
 
949
 
        backHistory.setAutoDelete(true);
950
 
        forwardHistory.setAutoDelete(true);
951
 
 
952
948
        // mess with widgets
953
949
        busy = parent->busy;
954
950
        connect(busy, SIGNAL(destroyed(QObject *)), SLOT(objectDestroyed(QObject *)));
955
951
 
956
 
        Q3ListView *lv_discoOld = dlg->lv_disco;
 
952
        QTreeWidget *lv_discoOld = dlg->lv_disco;
957
953
        dlg->lv_disco = new DiscoListView(dlg);
958
954
        replaceWidget(lv_discoOld, dlg->lv_disco);
959
955
 
960
956
        dlg->lv_disco->installEventFilter (this);
961
 
        connect(dlg->lv_disco, SIGNAL(selectionChanged (Q3ListViewItem *)), SLOT(itemSelected (Q3ListViewItem *)));;
962
 
        connect(dlg->lv_disco, SIGNAL(doubleClicked (Q3ListViewItem *)),    SLOT(itemDoubleclicked (Q3ListViewItem *)));;
 
957
        connect(dlg->lv_disco, SIGNAL(currentItemChanged (QTreeWidgetItem *, QTreeWidgetItem *)), SLOT(itemSelected (QTreeWidgetItem *)));;
 
958
        connect(dlg->lv_disco, SIGNAL(itemExpanded (QTreeWidgetItem *)), SLOT(itemExpanded (QTreeWidgetItem *)));
 
959
        connect(dlg->lv_disco, SIGNAL(itemDoubleClicked (QTreeWidgetItem *, int)), SLOT(itemDoubleclicked (QTreeWidgetItem *)));;
963
960
 
964
961
        // protocol actions
965
962
        QSignalMapper *pm = new QSignalMapper(this);
1058
1055
 
1059
1056
DiscoDlg::Private::~Private()
1060
1057
{
 
1058
        qDeleteAll(backHistory);
 
1059
        qDeleteAll(forwardHistory);
1061
1060
        delete data.tasks;
1062
1061
}
1063
1062
 
1064
 
void DiscoDlg::Private::doDisco(QString _host, QString _node)
 
1063
void DiscoDlg::Private::doDisco(QString _host, QString _node, bool doHistory)
1065
1064
{
1066
1065
        PsiAccount *pa = data.pa;
1067
1066
        if ( !pa->checkConnected(dlg) )
1072
1071
        QString host = _host;
1073
1072
        if ( host.isEmpty() )
1074
1073
                host = dlg->cb_address->currentText();
1075
 
        j = host.stripWhiteSpace();
 
1074
        j = host.trimmed();
1076
1075
        if ( !j.isValid() )
1077
1076
                return;
1078
1077
 
1079
 
        QString n = _node.stripWhiteSpace();
 
1078
        QString n = _node.trimmed();
1080
1079
        if ( n.isEmpty() )
1081
 
                n = dlg->cb_node->currentText().stripWhiteSpace();
 
1080
                n = dlg->cb_node->currentText().trimmed();
1082
1081
 
1083
1082
        // check, whether we need to update history
1084
1083
        if ( (jid.full() != j.full()) || (node != n) ) {
1085
 
                Q3ListViewItem *item = dlg->lv_disco->firstChild(); // get the root item
1086
 
 
1087
 
                if ( item ) {
1088
 
                        dlg->lv_disco->takeItem( item );
1089
 
 
1090
 
                        backHistory.append( new History(item) );
 
1084
                if (doHistory) {
 
1085
                        backHistory.append(new History(jid, node));
 
1086
                        qDeleteAll(forwardHistory);
1091
1087
                        forwardHistory.clear();
1092
1088
                }
1093
1089
        }
1109
1105
        di.setNode( node );
1110
1106
 
1111
1107
        DiscoListItem *root = new DiscoListItem (di, &data, dlg->lv_disco);
1112
 
        root->setVisible (false); // don't confuse users with empty root
1113
 
 
1114
 
        root->setOpen(true); // begin browsing
 
1108
        root->setHidden (false); // don't confuse users with empty root
 
1109
        root->setExpanded(true); // begin browsing
1115
1110
}
1116
1111
 
1117
1112
void DiscoDlg::Private::updateComboBoxes(Jid j, QString n)
1118
1113
{
1119
1114
        data.pa->psi()->recentBrowseAdd( j.full() );
1120
1115
        dlg->cb_address->clear();
1121
 
        dlg->cb_address->insertStringList(data.pa->psi()->recentBrowseList());
 
1116
        dlg->cb_address->addItems(data.pa->psi()->recentBrowseList());
1122
1117
 
1123
1118
        data.pa->psi()->recentNodeAdd( n );
1124
1119
        dlg->cb_node->clear();
1125
 
        dlg->cb_node->insertStringList(data.pa->psi()->recentNodeList());
 
1120
        dlg->cb_node->addItems(data.pa->psi()->recentNodeList());
1126
1121
}
1127
1122
 
1128
1123
void DiscoDlg::Private::actionStop()
1132
1127
 
1133
1128
void DiscoDlg::Private::actionRefresh()
1134
1129
{
1135
 
        DiscoListItem *it = (DiscoListItem *)dlg->lv_disco->selectedItem();
 
1130
        DiscoListItem *it = (DiscoListItem *)dlg->lv_disco->currentItem();
1136
1131
        if ( !it )
1137
1132
                return;
1138
1133
 
1142
1137
 
1143
1138
void DiscoDlg::Private::actionBrowse()
1144
1139
{
1145
 
        DiscoListItem *it = (DiscoListItem *)dlg->lv_disco->selectedItem();
 
1140
        DiscoListItem *it = (DiscoListItem *)dlg->lv_disco->currentItem();
1146
1141
        if ( !it )
1147
1142
                return;
1148
1143
 
1151
1146
 
1152
1147
void DiscoDlg::Private::actionBack()
1153
1148
{
1154
 
        // add current selection to forward history
1155
 
        Q3ListViewItem *item = dlg->lv_disco->firstChild();
1156
 
        if ( item ) {
1157
 
                dlg->lv_disco->takeItem( item );
1158
 
 
1159
 
                forwardHistory.append( new History(item) );
1160
 
        }
1161
 
 
1162
 
        // now, take info from back history...
1163
 
        Q3ListViewItem *i = backHistory.last()->takeItem();
1164
 
        backHistory.removeLast();
1165
 
 
1166
 
        // and restore view
1167
 
        backForwardHelper(i);
 
1149
        forwardHistory.append(new History(jid, node));
 
1150
        History *h = backHistory.takeLast();
 
1151
        doDisco(h->jid.full(), h->node, false);
 
1152
        delete h;
1168
1153
}
1169
1154
 
1170
1155
void DiscoDlg::Private::actionForward()
1171
1156
{
1172
 
        // add current selection to back history
1173
 
        Q3ListViewItem *item = dlg->lv_disco->firstChild();
1174
 
        if ( item ) {
1175
 
                dlg->lv_disco->takeItem( item );
1176
 
 
1177
 
                backHistory.append( new History(item) );
1178
 
        }
1179
 
 
1180
 
        // now, take info from forward history...
1181
 
        Q3ListViewItem *i = forwardHistory.last()->takeItem();
1182
 
        forwardHistory.removeLast();
1183
 
 
1184
 
        // and restore view
1185
 
        backForwardHelper(i);
1186
 
}
1187
 
 
1188
 
void DiscoDlg::Private::backForwardHelper(Q3ListViewItem *root)
1189
 
{
1190
 
        DiscoListItem *i = (DiscoListItem *)root;
1191
 
 
1192
 
        jid  = i->item().jid();
1193
 
        node = i->item().node();
1194
 
 
1195
 
        updateComboBoxes(jid, node);
1196
 
 
1197
 
        data.tasks->clear(); // also will call all all necessary functions
1198
 
        disableButtons();
1199
 
        updateBackForward();
1200
 
 
1201
 
        dlg->lv_disco->insertItem( root );
1202
 
 
1203
 
        // fixes multiple selection bug
1204
 
        Q3ListViewItemIterator it( dlg->lv_disco );
1205
 
        while ( it.current() ) {
1206
 
                Q3ListViewItem *item = it.current();
1207
 
                ++it;
1208
 
 
1209
 
                if ( item->isSelected() )
1210
 
                        for (int i = 0; i <= 1; i++) // it's boring to write same line twice :-)
1211
 
                                dlg->lv_disco->setSelected(item, (bool)i);
1212
 
        }
 
1157
        backHistory.append(new History(jid, node));
 
1158
        History *h = forwardHistory.takeLast();
 
1159
        doDisco(h->jid.full(), h->node, false);
 
1160
        delete h;
1213
1161
}
1214
1162
 
1215
1163
void DiscoDlg::Private::updateBackForward()
1254
1202
        actAHCommand->setEnabled( f.canCommand() );
1255
1203
}
1256
1204
 
1257
 
void DiscoDlg::Private::itemSelected (Q3ListViewItem *item)
 
1205
void DiscoDlg::Private::itemSelected (QTreeWidgetItem *item)
1258
1206
{
1259
1207
        DiscoListItem *it = (DiscoListItem *)item;
1260
1208
        if ( !it ) {
1268
1216
        enableButtons ( di );
1269
1217
}
1270
1218
 
1271
 
void DiscoDlg::Private::itemDoubleclicked (Q3ListViewItem *item)
 
1219
void DiscoDlg::Private::itemExpanded (QTreeWidgetItem *item)
 
1220
{
 
1221
        DiscoListItem *it = (DiscoListItem *)item;
 
1222
        if (it)
 
1223
                it->setExpanded(true);
 
1224
}
 
1225
 
 
1226
void DiscoDlg::Private::itemDoubleclicked (QTreeWidgetItem *item)
1272
1227
{
1273
1228
        DiscoListItem *it = (DiscoListItem *)item;
1274
1229
        if ( !it )
1302
1257
        }
1303
1258
 
1304
1259
        if ( id > 0 ) {
1305
 
                if ( !it->isOpen() ) {
1306
 
                        if ( it->isExpandable() || it->childCount() )
1307
 
                                it->setOpen( true );
 
1260
                if ( !it->isExpanded() ) {
 
1261
                        if ( it->childCount() )
 
1262
                                it->setExpanded( true );
1308
1263
                }
1309
1264
                else {
1310
 
                        it->setOpen( false );
 
1265
                        it->setExpanded( false );
1311
1266
                }
1312
1267
                emit dlg->featureActivated( Features::feature(id), d.jid(), d.node() );
1313
1268
        }
1319
1274
                if ( event->type() == QEvent::ContextMenu ) {
1320
1275
                        QContextMenuEvent *e = (QContextMenuEvent *)event;
1321
1276
 
1322
 
                        DiscoListItem *it = (DiscoListItem *)dlg->lv_disco->selectedItem();
 
1277
                        DiscoListItem *it = (DiscoListItem *)dlg->lv_disco->currentItem();
1323
1278
                        if ( !it )
1324
1279
                                return true;
1325
1280
 
1357
1312
                        }
1358
1313
 
1359
1314
                        // prepare popup menu
1360
 
                        Q3PopupMenu p;
 
1315
                        QMenu p;
1361
1316
 
1362
1317
                        actBrowse->addTo (&p);
1363
1318
                        actRefresh->addTo (&p);
1364
1319
                        actStop->addTo (&p);
1365
1320
 
1366
1321
                        // custom actions
1367
 
                        p.insertSeparator();
 
1322
                        p.addSeparator();
1368
1323
                        actRegister->addTo(&p);
1369
1324
                        actSearch->addTo(&p);
1370
1325
                        actJoin->addTo(&p);
1371
1326
 
1372
 
                        p.insertSeparator();
 
1327
                        p.addSeparator();
1373
1328
                        actAdd->addTo(&p);
1374
1329
                        actVCard->addTo(&p);
1375
1330
                        actAHCommand->addTo(&p);
1376
1331
 
1377
1332
                        // popup with all available features
1378
 
                        Q3PopupMenu *fm = new Q3PopupMenu(&p);
 
1333
                        QMenu *fm = new QMenu(&p);
 
1334
                        QHash<QAction*, int> actions;
1379
1335
                        {
1380
1336
                                QList<long>::Iterator it = ids.begin();
1381
1337
                                for ( ; it != ids.end(); ++it)
1382
 
                                        fm->insertItem(Features::name(*it), *it + 10000); // TODO: add pixmap
 
1338
                                        actions.insert(fm->addAction(Features::name(*it)), *it + 10000); // TODO: add pixmap
1383
1339
                        }
1384
1340
 
1385
1341
                        //p.insertSeparator();
1388
1344
 
1389
1345
                        // display popup
1390
1346
                        e->accept();
1391
 
                        int r = p.exec ( e->globalPos() );
 
1347
                        int r = actions.value(p.exec ( e->globalPos() ));
1392
1348
 
1393
1349
                        if ( r > 10000 )
1394
1350
                                actionActivated(r-10000);
1402
1358
 
1403
1359
void DiscoDlg::Private::actionActivated(int id)
1404
1360
{
1405
 
        DiscoListItem *it = (DiscoListItem *)dlg->lv_disco->selectedItem();
 
1361
        DiscoListItem *it = (DiscoListItem *)dlg->lv_disco->currentItem();
1406
1362
        if ( !it )
1407
1363
                return;
1408
1364
 
1439
1395
        d->node = node;
1440
1396
        d->data.pa->dialogRegister(this);
1441
1397
 
1442
 
        setWindowTitle(CAP(caption()));
 
1398
        //setWindowTitle(CAP(caption()));
1443
1399
        setWindowIcon(PsiIconset::instance()->transportStatus("transport", STATUS_ONLINE).icon());
1444
1400
        X11WM_CLASS("disco");
1445
1401
 
1451
1407
        pb_close->setDefault(false);
1452
1408
        pb_close->setAutoDefault(false);
1453
1409
 
1454
 
        cb_address->insertStringList(pa->psi()->recentBrowseList()); // FIXME
 
1410
        cb_address->addItems(pa->psi()->recentBrowseList()); // FIXME
1455
1411
        cb_address->setFocus();
1456
1412
        connect(cb_address, SIGNAL(activated(const QString &)), d, SLOT(doDisco()));
1457
 
        cb_address->setCurrentText(d->jid.full());
 
1413
        cb_address->setEditText(d->jid.full());
1458
1414
 
1459
 
        cb_node->insertStringList(pa->psi()->recentNodeList());
 
1415
        cb_node->addItems(pa->psi()->recentNodeList());
1460
1416
        connect(cb_node, SIGNAL(activated(const QString &)), d, SLOT(doDisco()));
1461
 
        cb_node->setCurrentText(node);
 
1417
        cb_node->setCurrentIndex(cb_node->findText(node));
1462
1418
 
1463
1419
        if ( pa->loggedIn() )
1464
1420
                doDisco();