[2] | 1 | /*
|
---|
| 2 | * groupchatdlg.cpp - dialogs for handling groupchat
|
---|
| 3 | * Copyright (C) 2001, 2002 Justin Karneges
|
---|
| 4 | *
|
---|
| 5 | * This program is free software; you can redistribute it and/or
|
---|
| 6 | * modify it under the terms of the GNU General Public License
|
---|
| 7 | * as published by the Free Software Foundation; either version 2
|
---|
| 8 | * of the License, or (at your option) any later version.
|
---|
| 9 | *
|
---|
| 10 | * This program is distributed in the hope that it will be useful,
|
---|
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 13 | * GNU General Public License for more details.
|
---|
| 14 | *
|
---|
| 15 | * You should have received a copy of the GNU General Public License
|
---|
| 16 | * along with this library; if not, write to the Free Software
|
---|
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
| 18 | *
|
---|
| 19 | */
|
---|
| 20 |
|
---|
| 21 | #include"groupchatdlg.h"
|
---|
| 22 |
|
---|
| 23 | #include<qlabel.h>
|
---|
| 24 | #include<qlayout.h>
|
---|
| 25 | #include<qpushbutton.h>
|
---|
| 26 | #include<qgroupbox.h>
|
---|
| 27 | #include<qmessagebox.h>
|
---|
| 28 | #include<qtextedit.h>
|
---|
| 29 | #include<qsplitter.h>
|
---|
| 30 | #include<qtimer.h>
|
---|
| 31 | #include<qheader.h>
|
---|
| 32 | #include<qtoolbutton.h>
|
---|
| 33 | #include<qinputdialog.h>
|
---|
| 34 | #include<qguardedptr.h>
|
---|
| 35 | #include<qaction.h>
|
---|
| 36 | #include<qobjectlist.h>
|
---|
| 37 | #include<qpopupmenu.h>
|
---|
| 38 | #include<qcursor.h>
|
---|
| 39 | #include"psicon.h"
|
---|
| 40 | #include"psiaccount.h"
|
---|
| 41 | #include"userlist.h"
|
---|
| 42 | #include"statusdlg.h"
|
---|
| 43 | #include"busywidget.h"
|
---|
| 44 | #include"common.h"
|
---|
| 45 | #include"msgmle.h"
|
---|
| 46 | #include"iconwidget.h"
|
---|
| 47 | #include"iconselect.h"
|
---|
| 48 | #include"psitoolbar.h"
|
---|
| 49 | #include"iconaction.h"
|
---|
| 50 |
|
---|
| 51 | #ifdef Q_WS_WIN
|
---|
| 52 | #include<windows.h>
|
---|
| 53 | #endif
|
---|
| 54 |
|
---|
| 55 |
|
---|
| 56 | //----------------------------------------------------------------------------
|
---|
| 57 | // GCJoinDlg
|
---|
| 58 | //----------------------------------------------------------------------------
|
---|
| 59 | class GCJoinDlg::Private
|
---|
| 60 | {
|
---|
| 61 | public:
|
---|
| 62 | Private() {}
|
---|
| 63 |
|
---|
| 64 | PsiCon *psi;
|
---|
| 65 | PsiAccount *pa;
|
---|
| 66 | AccountsComboBox *cb_ident;
|
---|
| 67 | BusyWidget *busy;
|
---|
| 68 | QStringList rl;
|
---|
| 69 | Jid jid;
|
---|
| 70 | };
|
---|
| 71 |
|
---|
| 72 | GCJoinDlg::GCJoinDlg(PsiCon *psi, PsiAccount *pa)
|
---|
| 73 | :GCJoinUI(0, 0, false, WDestructiveClose)
|
---|
| 74 | {
|
---|
| 75 | d = new Private;
|
---|
| 76 | d->psi = psi;
|
---|
| 77 | d->pa = 0;
|
---|
| 78 | d->psi->dialogRegister(this);
|
---|
| 79 | d->busy = busy;
|
---|
| 80 |
|
---|
| 81 | updateIdentity(pa);
|
---|
| 82 |
|
---|
| 83 | d->cb_ident = d->psi->accountsComboBox(this,true);
|
---|
| 84 | connect(d->cb_ident, SIGNAL(activated(PsiAccount *)), SLOT(updateIdentity(PsiAccount *)));
|
---|
| 85 | d->cb_ident->setAccount(pa);
|
---|
| 86 | replaceWidget(lb_ident, d->cb_ident);
|
---|
| 87 |
|
---|
| 88 | d->rl = d->psi->recentGCList();
|
---|
| 89 | for(QStringList::ConstIterator it = d->rl.begin(); it != d->rl.end(); ++it) {
|
---|
| 90 | Jid j(*it);
|
---|
| 91 | QString s = tr("%1 on %2").arg(j.resource()).arg(j.userHost());
|
---|
| 92 | cb_recent->insertItem(s);
|
---|
| 93 | }
|
---|
| 94 |
|
---|
| 95 | setCaption(CAP(caption()));
|
---|
| 96 | pb_join->setDefault(true);
|
---|
| 97 | connect(pb_close, SIGNAL(clicked()), SLOT(close()));
|
---|
| 98 | connect(pb_join, SIGNAL(clicked()), SLOT(doJoin()));
|
---|
| 99 | connect(cb_recent, SIGNAL(activated(int)), SLOT(recent_activated(int)));
|
---|
| 100 | if(d->rl.isEmpty()) {
|
---|
| 101 | cb_recent->setEnabled(false);
|
---|
| 102 | le_host->setFocus();
|
---|
| 103 | }
|
---|
| 104 | else
|
---|
| 105 | recent_activated(0);
|
---|
| 106 | }
|
---|
| 107 |
|
---|
| 108 | GCJoinDlg::~GCJoinDlg()
|
---|
| 109 | {
|
---|
| 110 | if(d->psi)
|
---|
| 111 | d->psi->dialogUnregister(this);
|
---|
| 112 | if(d->pa)
|
---|
| 113 | d->pa->dialogUnregister(this);
|
---|
| 114 | delete d;
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 | /*void GCJoinDlg::closeEvent(QCloseEvent *e)
|
---|
| 118 | {
|
---|
| 119 | e->ignore();
|
---|
| 120 | reject();
|
---|
| 121 | }*/
|
---|
| 122 |
|
---|
| 123 | void GCJoinDlg::done(int r)
|
---|
| 124 | {
|
---|
| 125 | if(d->busy->isActive()) {
|
---|
| 126 | int n = QMessageBox::information(this, tr("Warning"), tr("Are you sure you want to cancel joining groupchat?"), tr("&Yes"), tr("&No"));
|
---|
| 127 | if(n != 0)
|
---|
| 128 | return;
|
---|
| 129 | d->pa->groupChatLeave(d->jid.host(), d->jid.user());
|
---|
| 130 | }
|
---|
| 131 | QDialog::done(r);
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | void GCJoinDlg::updateIdentity(PsiAccount *pa)
|
---|
| 135 | {
|
---|
| 136 | if(d->pa)
|
---|
| 137 | disconnect(d->pa, SIGNAL(disconnected()), this, SLOT(pa_disconnected()));
|
---|
| 138 |
|
---|
| 139 | d->pa = pa;
|
---|
| 140 | pb_join->setEnabled(d->pa);
|
---|
| 141 |
|
---|
| 142 | if(!d->pa) {
|
---|
| 143 | d->busy->stop();
|
---|
| 144 | return;
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 | connect(d->pa, SIGNAL(disconnected()), this, SLOT(pa_disconnected()));
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | void GCJoinDlg::pa_disconnected()
|
---|
| 151 | {
|
---|
| 152 | if(d->busy->isActive()) {
|
---|
| 153 | d->busy->stop();
|
---|
| 154 | }
|
---|
| 155 | }
|
---|
| 156 |
|
---|
| 157 | void GCJoinDlg::recent_activated(int x)
|
---|
| 158 | {
|
---|
| 159 | int n = 0;
|
---|
| 160 | bool found = false;
|
---|
| 161 | QString str;
|
---|
| 162 | for(QStringList::ConstIterator it = d->rl.begin(); it != d->rl.end(); ++it) {
|
---|
| 163 | if(n == x) {
|
---|
| 164 | found = true;
|
---|
| 165 | str = *it;
|
---|
| 166 | break;
|
---|
| 167 | }
|
---|
| 168 | ++n;
|
---|
| 169 | }
|
---|
| 170 | if(!found)
|
---|
| 171 | return;
|
---|
| 172 |
|
---|
| 173 | Jid j(str);
|
---|
| 174 | le_host->setText(j.host());
|
---|
| 175 | le_room->setText(j.user());
|
---|
| 176 | le_nick->setText(j.resource());
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 | void GCJoinDlg::doJoin()
|
---|
| 180 | {
|
---|
| 181 | if(!d->pa->checkConnected(this))
|
---|
| 182 | return;
|
---|
| 183 |
|
---|
| 184 | QString host = le_host->text();
|
---|
| 185 | QString room = le_room->text();
|
---|
| 186 | QString nick = le_nick->text();
|
---|
| 187 |
|
---|
| 188 | if(host.isEmpty() || room.isEmpty() || nick.isEmpty()) {
|
---|
| 189 | QMessageBox::information(this, tr("Error"), tr("You must fill out the fields in order to join."));
|
---|
| 190 | return;
|
---|
| 191 | }
|
---|
| 192 |
|
---|
| 193 | Jid j = room + '@' + host + '/' + nick;
|
---|
| 194 | if(!j.isValid()) {
|
---|
| 195 | QMessageBox::information(this, tr("Error"), tr("You entered an invalid room name."));
|
---|
| 196 | return;
|
---|
| 197 | }
|
---|
| 198 |
|
---|
| 199 | if(!d->pa->groupChatJoin(host, room, nick)) {
|
---|
| 200 | QMessageBox::information(this, tr("Error"), tr("You are in or joining this room already!"));
|
---|
| 201 | return;
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | d->psi->dialogUnregister(this);
|
---|
| 205 | d->jid = room + '@' + host + '/' + nick;
|
---|
| 206 | d->pa->dialogRegister(this, d->jid);
|
---|
| 207 |
|
---|
| 208 | disableWidgets();
|
---|
| 209 | d->busy->start();
|
---|
| 210 | }
|
---|
| 211 |
|
---|
| 212 | void GCJoinDlg::disableWidgets()
|
---|
| 213 | {
|
---|
| 214 | d->cb_ident->setEnabled(false);
|
---|
| 215 | cb_recent->setEnabled(false);
|
---|
| 216 | gb_info->setEnabled(false);
|
---|
| 217 | pb_join->setEnabled(false);
|
---|
| 218 | }
|
---|
| 219 |
|
---|
| 220 | void GCJoinDlg::enableWidgets()
|
---|
| 221 | {
|
---|
| 222 | d->cb_ident->setEnabled(true);
|
---|
| 223 | if(!d->rl.isEmpty())
|
---|
| 224 | cb_recent->setEnabled(true);
|
---|
| 225 | gb_info->setEnabled(true);
|
---|
| 226 | pb_join->setEnabled(true);
|
---|
| 227 | }
|
---|
| 228 |
|
---|
| 229 | void GCJoinDlg::joined()
|
---|
| 230 | {
|
---|
| 231 | d->psi->recentGCAdd(d->jid.full());
|
---|
| 232 | d->busy->stop();
|
---|
| 233 |
|
---|
| 234 | closeDialogs(this);
|
---|
| 235 | deleteLater();
|
---|
| 236 | }
|
---|
| 237 |
|
---|
| 238 | void GCJoinDlg::error(int, const QString &str)
|
---|
| 239 | {
|
---|
| 240 | d->busy->stop();
|
---|
| 241 | enableWidgets();
|
---|
| 242 |
|
---|
| 243 | pb_join->setFocus();
|
---|
| 244 |
|
---|
| 245 | d->pa->dialogUnregister(this);
|
---|
| 246 | d->psi->dialogRegister(this);
|
---|
| 247 |
|
---|
| 248 | QMessageBox::information(this, tr("Error"), tr("Unable to join groupchat.\nReason: %1").arg(str));
|
---|
| 249 | }
|
---|
| 250 |
|
---|
| 251 |
|
---|
| 252 | //----------------------------------------------------------------------------
|
---|
| 253 | // GCUserView
|
---|
| 254 | //----------------------------------------------------------------------------
|
---|
| 255 | GCUserViewItem::GCUserViewItem(QListView *par)
|
---|
| 256 | :QListViewItem(par)
|
---|
| 257 | {
|
---|
| 258 | }
|
---|
| 259 |
|
---|
| 260 | GCUserView::GCUserView(QWidget *parent, const char *name)
|
---|
| 261 | :QListView(parent, name), QToolTip(viewport())
|
---|
| 262 | {
|
---|
| 263 | setResizeMode(QListView::AllColumns);
|
---|
| 264 | setSorting(0);
|
---|
| 265 | header()->hide();
|
---|
| 266 | addColumn("");
|
---|
| 267 |
|
---|
| 268 | connect(this, SIGNAL(doubleClicked(QListViewItem *)), SLOT(qlv_doubleClicked(QListViewItem *)));
|
---|
| 269 | connect(this, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), SLOT(qlv_contextMenuRequested(QListViewItem *, const QPoint &, int)));
|
---|
| 270 | }
|
---|
| 271 |
|
---|
| 272 | GCUserView::~GCUserView()
|
---|
| 273 | {
|
---|
| 274 | }
|
---|
| 275 |
|
---|
| 276 | void GCUserView::updateAll()
|
---|
| 277 | {
|
---|
| 278 | for(GCUserViewItem *i = (GCUserViewItem *)firstChild(); i; i = (GCUserViewItem *)i->nextSibling())
|
---|
| 279 | i->setPixmap(0, is->status(i->s));
|
---|
| 280 | }
|
---|
| 281 |
|
---|
| 282 | QStringList GCUserView::nickList() const
|
---|
| 283 | {
|
---|
| 284 | QStringList list;
|
---|
| 285 |
|
---|
| 286 | for(QListViewItem *lvi = firstChild(); lvi; lvi = lvi->nextSibling())
|
---|
| 287 | list << lvi->text(0);
|
---|
| 288 |
|
---|
| 289 | qstringlistisort(list); // caseless sorting
|
---|
| 290 | return list;
|
---|
| 291 | }
|
---|
| 292 |
|
---|
| 293 | QListViewItem *GCUserView::findEntry(const QString &nick)
|
---|
| 294 | {
|
---|
| 295 | for(QListViewItem *lvi = firstChild(); lvi; lvi = lvi->nextSibling()) {
|
---|
| 296 | if(lvi->text(0) == nick)
|
---|
| 297 | return lvi;
|
---|
| 298 | }
|
---|
| 299 | return 0;
|
---|
| 300 | }
|
---|
| 301 |
|
---|
| 302 | void GCUserView::updateEntry(const QString &nick, const Status &s)
|
---|
| 303 | {
|
---|
| 304 | GCUserViewItem *lvi = (GCUserViewItem *)findEntry(nick);
|
---|
| 305 | if(!lvi) {
|
---|
| 306 | lvi = new GCUserViewItem(this);
|
---|
| 307 | lvi->setText(0, nick);
|
---|
| 308 | }
|
---|
| 309 |
|
---|
| 310 | lvi->s = s;
|
---|
| 311 | lvi->setPixmap(0, is->status(lvi->s));
|
---|
| 312 | }
|
---|
| 313 |
|
---|
| 314 | void GCUserView::removeEntry(const QString &nick)
|
---|
| 315 | {
|
---|
| 316 | QListViewItem *lvi = findEntry(nick);
|
---|
| 317 | if(lvi)
|
---|
| 318 | delete lvi;
|
---|
| 319 | }
|
---|
| 320 |
|
---|
| 321 | void GCUserView::maybeTip(const QPoint &pos)
|
---|
| 322 | {
|
---|
| 323 | GCUserViewItem *lvi = (GCUserViewItem *)itemAt(pos);
|
---|
| 324 | if(!lvi)
|
---|
| 325 | return;
|
---|
| 326 |
|
---|
| 327 | QRect r(itemRect(lvi));
|
---|
| 328 |
|
---|
| 329 | const QString &nick = lvi->text(0);
|
---|
| 330 | const Status &s = lvi->s;
|
---|
| 331 | UserListItem u;
|
---|
| 332 | // SICK SICK SICK SICK
|
---|
| 333 | u.setJid(((GCMainDlg *)topLevelWidget())->jid().withResource(nick));
|
---|
| 334 | u.setName(nick);
|
---|
| 335 |
|
---|
| 336 | // make a resource so the contact appears online
|
---|
| 337 | UserResource ur;
|
---|
| 338 | ur.setName(nick);
|
---|
| 339 | ur.setStatus(s);
|
---|
| 340 | u.userResourceList().append(ur);
|
---|
| 341 |
|
---|
| 342 | tip(r, u.makeTip());
|
---|
| 343 | }
|
---|
| 344 |
|
---|
| 345 | void GCUserView::qlv_doubleClicked(QListViewItem *i)
|
---|
| 346 | {
|
---|
| 347 | GCUserViewItem *lvi = (GCUserViewItem *)i;
|
---|
| 348 | if(!lvi)
|
---|
| 349 | return;
|
---|
| 350 |
|
---|
| 351 | if(option.defaultAction == 0)
|
---|
| 352 | action(lvi->text(0), lvi->s, 0);
|
---|
| 353 | else
|
---|
| 354 | action(lvi->text(0), lvi->s, 1);
|
---|
| 355 | }
|
---|
| 356 |
|
---|
| 357 | void GCUserView::qlv_contextMenuRequested(QListViewItem *i, const QPoint &pos, int)
|
---|
| 358 | {
|
---|
| 359 | GCUserViewItem *lvi = (GCUserViewItem *)i;
|
---|
| 360 | if(!lvi)
|
---|
| 361 | return;
|
---|
| 362 |
|
---|
| 363 | QPopupMenu *pm = new QPopupMenu;
|
---|
| 364 | pm->insertItem(IconsetFactory::icon("psi/sendMessage"), tr("Send &message"), 0);
|
---|
| 365 | pm->insertItem(IconsetFactory::icon("psi/start-chat"), tr("Open &chat window"), 1);
|
---|
| 366 | pm->insertSeparator();
|
---|
| 367 | //pm->insertItem(tr("Send &file"), 4);
|
---|
| 368 | //pm->insertSeparator();
|
---|
| 369 | pm->insertItem(tr("Check &Status"), 2);
|
---|
| 370 | pm->insertItem(IconsetFactory::icon("psi/vCard"), tr("User &Info"), 3);
|
---|
| 371 | int x = pm->exec(pos);
|
---|
| 372 | delete pm;
|
---|
| 373 |
|
---|
| 374 | if(x == -1)
|
---|
| 375 | return;
|
---|
| 376 | action(lvi->text(0), lvi->s, x);
|
---|
| 377 | }
|
---|
| 378 |
|
---|
| 379 |
|
---|
| 380 | //----------------------------------------------------------------------------
|
---|
| 381 | // GCMainDlg
|
---|
| 382 | //----------------------------------------------------------------------------
|
---|
| 383 | class GCMainDlg::Private : public QObject
|
---|
| 384 | {
|
---|
| 385 | Q_OBJECT
|
---|
| 386 | public:
|
---|
| 387 | enum { Connecting, Connected, Idle };
|
---|
| 388 | Private(GCMainDlg *d) {
|
---|
| 389 | dlg = d;
|
---|
| 390 | nickSeparator = ":";
|
---|
| 391 | typingStatus = Typing_Normal;
|
---|
| 392 | }
|
---|
| 393 |
|
---|
| 394 | GCMainDlg *dlg;
|
---|
| 395 | int state;
|
---|
| 396 | PsiAccount *pa;
|
---|
| 397 | Jid jid;
|
---|
| 398 | QString self;
|
---|
| 399 | ChatView *te_log;
|
---|
| 400 | ChatEdit *mle;
|
---|
| 401 | QLineEdit *le_topic;
|
---|
| 402 | GCUserView *lv_users;
|
---|
| 403 | QPushButton *pb_topic;
|
---|
| 404 | PsiToolBar *toolbar;
|
---|
| 405 | IconAction *act_find, *act_clear, *act_icon;
|
---|
| 406 | QPopupMenu *pm_settings;
|
---|
| 407 | bool smallChat;
|
---|
| 408 | int pending;
|
---|
| 409 |
|
---|
| 410 | bool trackBar;
|
---|
| 411 | int trackBarParagraph;
|
---|
| 412 |
|
---|
| 413 | QTimer *flashTimer;
|
---|
| 414 | int flashCount;
|
---|
| 415 |
|
---|
| 416 | QStringList hist;
|
---|
| 417 | int histAt;
|
---|
| 418 |
|
---|
| 419 | QGuardedPtr<GCFindDlg> findDlg;
|
---|
| 420 | QString lastSearch;
|
---|
| 421 |
|
---|
| 422 | public slots:
|
---|
| 423 | void addEmoticon(const Icon *icon) {
|
---|
| 424 | if ( !dlg->isActiveWindow() )
|
---|
| 425 | return;
|
---|
| 426 |
|
---|
| 427 | QString text;
|
---|
| 428 |
|
---|
| 429 | QDict<QString> itext = icon->text();
|
---|
| 430 | QDictIterator<QString> it ( itext );
|
---|
| 431 | for ( ; it.current(); ++it) {
|
---|
| 432 | if ( it.current() && !it.current()->isEmpty() ) {
|
---|
| 433 | text = *(it.current()) + " ";
|
---|
| 434 | break;
|
---|
| 435 | }
|
---|
| 436 | }
|
---|
| 437 |
|
---|
| 438 | if ( !text.isEmpty() )
|
---|
| 439 | mle->insert( text );
|
---|
| 440 | }
|
---|
| 441 |
|
---|
| 442 | void addEmoticon(QString text) {
|
---|
| 443 | if ( !dlg->isActiveWindow() )
|
---|
| 444 | return;
|
---|
| 445 |
|
---|
| 446 | mle->insert( text + " " );
|
---|
| 447 | }
|
---|
| 448 |
|
---|
| 449 | void deferredScroll() {
|
---|
| 450 | //QTimer::singleShot(250, this, SLOT(slotScroll()));
|
---|
| 451 | te_log->scrollToBottom();
|
---|
| 452 | }
|
---|
| 453 |
|
---|
| 454 | protected slots:
|
---|
| 455 | void slotScroll() {
|
---|
| 456 | te_log->scrollToBottom();
|
---|
| 457 | }
|
---|
| 458 |
|
---|
| 459 | public:
|
---|
| 460 | // Nick auto-completion code follows...
|
---|
| 461 | enum TypingStatus {
|
---|
| 462 | Typing_Normal = 0,
|
---|
| 463 | Typing_TabPressed,
|
---|
| 464 | Typing_TabbingNicks,
|
---|
| 465 | Typing_MultipleSuggestions
|
---|
| 466 | };
|
---|
| 467 | TypingStatus typingStatus;
|
---|
| 468 | QString lastReferrer; // contains nick of last person, who have said "yourNick: ..."
|
---|
| 469 | QString nickSeparator; // in case of "nick: ...", it equals ":"
|
---|
| 470 | QStringList suggestedNicks;
|
---|
| 471 | int suggestedIndex;
|
---|
| 472 | bool suggestedFromStart;
|
---|
| 473 |
|
---|
| 474 | QString beforeNickText(QString text) {
|
---|
| 475 | int i;
|
---|
| 476 | for (i = text.length() - 1; i >= 0; --i)
|
---|
| 477 | if ( text[i].isSpace() )
|
---|
| 478 | break;
|
---|
| 479 |
|
---|
| 480 | QString beforeNick = text.left(i+1);
|
---|
| 481 | return beforeNick;
|
---|
| 482 | }
|
---|
| 483 |
|
---|
| 484 | QStringList suggestNicks(QString text, bool fromStart) {
|
---|
| 485 | QString nickText = text;
|
---|
| 486 | QString beforeNick;
|
---|
| 487 | if ( !fromStart ) {
|
---|
| 488 | beforeNick = beforeNickText(text);
|
---|
| 489 | nickText = text.mid(beforeNick.length());
|
---|
| 490 | }
|
---|
| 491 |
|
---|
| 492 | QStringList nicks = lv_users->nickList();
|
---|
| 493 | QStringList::Iterator it = nicks.begin();
|
---|
| 494 | QStringList suggestedNicks;
|
---|
| 495 | for ( ; it != nicks.end(); ++it) {
|
---|
| 496 | if ( (*it).left(nickText.length()).lower() == nickText.lower() ) {
|
---|
| 497 | if ( fromStart )
|
---|
| 498 | suggestedNicks << *it;
|
---|
| 499 | else
|
---|
| 500 | suggestedNicks << beforeNick + *it;
|
---|
| 501 | }
|
---|
| 502 | }
|
---|
| 503 |
|
---|
| 504 | return suggestedNicks;
|
---|
| 505 | }
|
---|
| 506 |
|
---|
| 507 | QString longestSuggestedString(QStringList suggestedNicks) {
|
---|
| 508 | QString testString = suggestedNicks.first();
|
---|
| 509 | while ( testString.length() > 0 ) {
|
---|
| 510 | bool found = true;
|
---|
| 511 | QStringList::Iterator it = suggestedNicks.begin();
|
---|
| 512 | for ( ; it != suggestedNicks.end(); ++it) {
|
---|
| 513 | if ( (*it).left(testString.length()).lower() != testString.lower() ) {
|
---|
| 514 | found = false;
|
---|
| 515 | break;
|
---|
| 516 | }
|
---|
| 517 | }
|
---|
| 518 |
|
---|
| 519 | if ( found )
|
---|
| 520 | break;
|
---|
| 521 |
|
---|
| 522 | testString = testString.left( testString.length() - 1 );
|
---|
| 523 | }
|
---|
| 524 |
|
---|
| 525 | return testString;
|
---|
| 526 | }
|
---|
| 527 |
|
---|
| 528 | QString insertNick(bool fromStart, QString beforeNick = "") {
|
---|
| 529 | typingStatus = Typing_MultipleSuggestions;
|
---|
| 530 | suggestedFromStart = fromStart;
|
---|
| 531 | suggestedNicks = lv_users->nickList();
|
---|
| 532 | QStringList::Iterator it = suggestedNicks.begin();
|
---|
| 533 | for ( ; it != suggestedNicks.end(); ++it)
|
---|
| 534 | *it = beforeNick + *it;
|
---|
| 535 |
|
---|
| 536 | QString newText;
|
---|
| 537 | if ( !lastReferrer.isEmpty() ) {
|
---|
| 538 | newText = beforeNick + lastReferrer;
|
---|
| 539 | suggestedIndex = -1;
|
---|
| 540 | }
|
---|
| 541 | else {
|
---|
| 542 | newText = suggestedNicks.first();
|
---|
| 543 | suggestedIndex = 0;
|
---|
| 544 | }
|
---|
| 545 |
|
---|
| 546 | if ( fromStart ) {
|
---|
| 547 | newText += nickSeparator;
|
---|
| 548 | newText += " ";
|
---|
| 549 | }
|
---|
| 550 |
|
---|
| 551 | return newText;
|
---|
| 552 | }
|
---|
| 553 |
|
---|
| 554 | QString suggestNick(bool fromStart, QString origText, bool *replaced) {
|
---|
| 555 | suggestedFromStart = fromStart;
|
---|
| 556 | suggestedNicks = suggestNicks(origText, fromStart);
|
---|
| 557 | suggestedIndex = -1;
|
---|
| 558 |
|
---|
| 559 | QString newText;
|
---|
| 560 | if ( suggestedNicks.count() ) {
|
---|
| 561 | if ( suggestedNicks.count() == 1 ) {
|
---|
| 562 | newText = suggestedNicks.first();
|
---|
| 563 | if ( fromStart ) {
|
---|
| 564 | newText += nickSeparator;
|
---|
| 565 | newText += " ";
|
---|
| 566 | }
|
---|
| 567 | }
|
---|
| 568 | else {
|
---|
| 569 | newText = longestSuggestedString(suggestedNicks);
|
---|
| 570 | if ( !newText.length() )
|
---|
| 571 | return origText;
|
---|
| 572 |
|
---|
| 573 | typingStatus = Typing_MultipleSuggestions;
|
---|
| 574 | // TODO: display a tooltip that will contain all suggestedNicks
|
---|
| 575 | }
|
---|
| 576 |
|
---|
| 577 | *replaced = true;
|
---|
| 578 | }
|
---|
| 579 |
|
---|
| 580 | return newText;
|
---|
| 581 | }
|
---|
| 582 |
|
---|
| 583 | void doAutoNickInsertion() {
|
---|
| 584 | int para, index;
|
---|
| 585 | mle->getCursorPosition(¶, &index);
|
---|
| 586 | QString paraText = mle->text(para);
|
---|
| 587 | QString origText = paraText.left(index);
|
---|
| 588 | QString newText;
|
---|
| 589 |
|
---|
| 590 | bool replaced = false;
|
---|
| 591 |
|
---|
| 592 | if ( typingStatus == Typing_MultipleSuggestions ) {
|
---|
| 593 | suggestedIndex++;
|
---|
| 594 | if ( suggestedIndex >= (int)suggestedNicks.count() )
|
---|
| 595 | suggestedIndex = 0;
|
---|
| 596 |
|
---|
| 597 | newText = suggestedNicks[suggestedIndex];
|
---|
| 598 | if ( suggestedFromStart ) {
|
---|
| 599 | newText += nickSeparator;
|
---|
| 600 | newText += " ";
|
---|
| 601 | }
|
---|
| 602 |
|
---|
| 603 | replaced = true;
|
---|
| 604 | }
|
---|
| 605 |
|
---|
| 606 | if ( !para && !replaced ) {
|
---|
| 607 | if ( !index && typingStatus == Typing_TabbingNicks ) {
|
---|
| 608 | newText = insertNick(true, "");
|
---|
| 609 | replaced = true;
|
---|
| 610 | }
|
---|
| 611 | else {
|
---|
| 612 | newText = suggestNick(true, origText, &replaced);
|
---|
| 613 | }
|
---|
| 614 | }
|
---|
| 615 |
|
---|
| 616 | if ( !replaced ) {
|
---|
| 617 | if ( (!index || origText[index-1].isSpace()) && typingStatus == Typing_TabbingNicks ) {
|
---|
| 618 | newText = insertNick(false, beforeNickText(origText));
|
---|
| 619 | replaced = true;
|
---|
| 620 | }
|
---|
| 621 | else {
|
---|
| 622 | newText = suggestNick(false, origText, &replaced);
|
---|
| 623 | }
|
---|
| 624 | }
|
---|
| 625 |
|
---|
| 626 | if ( replaced ) {
|
---|
| 627 | mle->setUpdatesEnabled( false );
|
---|
| 628 | QString newParaText = newText + paraText.mid(index, paraText.length() - index - 1);
|
---|
| 629 | mle->insertParagraph(newParaText, para);
|
---|
| 630 | mle->removeParagraph(para+1);
|
---|
| 631 | mle->setCursorPosition(para, newText.length());
|
---|
| 632 | mle->setUpdatesEnabled( true );
|
---|
| 633 | mle->viewport()->update();
|
---|
| 634 | }
|
---|
| 635 | }
|
---|
| 636 |
|
---|
| 637 | bool eventFilter( QObject *obj, QEvent *ev ) {
|
---|
| 638 | if ( obj == mle && ev->type() == QEvent::KeyPress ) {
|
---|
| 639 | QKeyEvent *e = (QKeyEvent *)ev;
|
---|
| 640 |
|
---|
| 641 | if ( e->key() == Key_Tab ) {
|
---|
| 642 | switch ( typingStatus ) {
|
---|
| 643 | case Typing_Normal:
|
---|
| 644 | typingStatus = Typing_TabPressed;
|
---|
| 645 | break;
|
---|
| 646 | case Typing_TabPressed:
|
---|
| 647 | typingStatus = Typing_TabbingNicks;
|
---|
| 648 | break;
|
---|
| 649 | default:
|
---|
| 650 | break;
|
---|
| 651 | }
|
---|
| 652 |
|
---|
| 653 | doAutoNickInsertion();
|
---|
| 654 | return TRUE;
|
---|
| 655 | }
|
---|
| 656 |
|
---|
| 657 | typingStatus = Typing_Normal;
|
---|
| 658 |
|
---|
| 659 | return FALSE;
|
---|
| 660 | }
|
---|
| 661 |
|
---|
| 662 | return QObject::eventFilter( obj, ev );
|
---|
| 663 | }
|
---|
| 664 | };
|
---|
| 665 |
|
---|
| 666 | GCMainDlg::GCMainDlg(PsiAccount *pa, const Jid &j)
|
---|
| 667 | :AdvancedWidget<QWidget>(0, 0, WDestructiveClose)
|
---|
| 668 | {
|
---|
| 669 | nicknumber=0;
|
---|
| 670 | d = new Private(this);
|
---|
| 671 | d->pa = pa;
|
---|
| 672 | d->jid = j.userHost();
|
---|
| 673 | d->self = j.resource();
|
---|
| 674 | d->pa->dialogRegister(this, d->jid);
|
---|
| 675 | connect(d->pa, SIGNAL(updatedActivity()), SLOT(pa_updatedActivity()));
|
---|
| 676 |
|
---|
| 677 | d->pending = 0;
|
---|
| 678 | d->flashTimer = 0;
|
---|
| 679 |
|
---|
| 680 | d->histAt = 0;
|
---|
| 681 | d->findDlg = 0;
|
---|
| 682 |
|
---|
| 683 | d->trackBar = false;
|
---|
| 684 | d->trackBarParagraph = 0;
|
---|
| 685 |
|
---|
| 686 | d->state = Private::Connected;
|
---|
| 687 |
|
---|
| 688 | #ifndef Q_WS_MAC
|
---|
| 689 | setIcon(IconsetFactory::icon("psi/groupChat"));
|
---|
| 690 | #endif
|
---|
| 691 |
|
---|
| 692 | QVBoxLayout *dlg_layout = new QVBoxLayout(this, 4);
|
---|
| 693 |
|
---|
| 694 | QWidget *vsplit;
|
---|
| 695 | if ( !option.chatLineEdit ) {
|
---|
| 696 | vsplit = new QSplitter(this);
|
---|
| 697 | ((QSplitter *)vsplit)->setOrientation( QSplitter::Vertical );
|
---|
| 698 | dlg_layout->addWidget(vsplit);
|
---|
| 699 | }
|
---|
| 700 | else
|
---|
| 701 | vsplit = this;
|
---|
| 702 |
|
---|
| 703 | // --- top part ---
|
---|
| 704 | QWidget *sp_top = new QWidget(vsplit);
|
---|
| 705 | sp_top->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
|
---|
| 706 | if ( option.chatLineEdit )
|
---|
| 707 | dlg_layout->addWidget( sp_top );
|
---|
| 708 | QVBoxLayout *vb_top = new QVBoxLayout(sp_top, 0, 4);
|
---|
| 709 |
|
---|
| 710 | // top row
|
---|
| 711 | QWidget *sp_top_top = new QWidget( sp_top );
|
---|
| 712 | vb_top->addWidget( sp_top_top );
|
---|
| 713 | QHBoxLayout *hb_top = new QHBoxLayout( sp_top_top, 0, 4 );
|
---|
| 714 |
|
---|
| 715 | d->pb_topic = new QPushButton(tr("Topic:"), sp_top_top);
|
---|
| 716 | connect(d->pb_topic, SIGNAL(clicked()), SLOT(doTopic()));
|
---|
| 717 | hb_top->addWidget(d->pb_topic);
|
---|
| 718 |
|
---|
| 719 | d->le_topic = new QLineEdit(sp_top_top);
|
---|
| 720 | d->le_topic->setReadOnly(true);
|
---|
| 721 | hb_top->addWidget(d->le_topic);
|
---|
| 722 |
|
---|
| 723 | d->act_find = new IconAction(tr("Find"), "psi/search", tr("&Find"), CTRL+Key_F, this);
|
---|
| 724 | connect(d->act_find, SIGNAL(activated()), SLOT(openFind()));
|
---|
| 725 | d->act_find->addTo( sp_top_top );
|
---|
| 726 |
|
---|
| 727 | QLabel *lb_ident = d->pa->accountLabel(sp_top_top, true);
|
---|
| 728 | lb_ident->setSizePolicy(QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ));
|
---|
| 729 | hb_top->addWidget(lb_ident);
|
---|
| 730 |
|
---|
| 731 | // bottom row
|
---|
| 732 | QSplitter *hsp = new QSplitter(sp_top);
|
---|
| 733 | hsp->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
|
---|
| 734 | vb_top->addWidget(hsp);
|
---|
| 735 | hsp->setOrientation(QSplitter::Horizontal);
|
---|
| 736 |
|
---|
| 737 | d->te_log = new ChatView(hsp);
|
---|
| 738 | d->te_log->setTextFormat( RichText );
|
---|
| 739 | #ifdef Q_WS_MAC
|
---|
| 740 | connect(d->te_log,SIGNAL(selectionChanged()),SLOT(logSelectionChanged()));
|
---|
| 741 | d->te_log->setFocusPolicy(QWidget::NoFocus);
|
---|
| 742 | #endif
|
---|
| 743 |
|
---|
| 744 | d->lv_users = new GCUserView(hsp);
|
---|
| 745 | d->lv_users->setMinimumWidth(20);
|
---|
| 746 | connect(d->lv_users, SIGNAL(action(const QString &, const Status &, int)), SLOT(lv_action(const QString &, const Status &, int)));
|
---|
| 747 |
|
---|
| 748 | // --- bottom part ---
|
---|
| 749 | QWidget *sp_bottom = new QWidget(vsplit);
|
---|
| 750 | sp_bottom->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );
|
---|
| 751 | if ( option.chatLineEdit )
|
---|
| 752 | dlg_layout->addWidget( sp_bottom );
|
---|
| 753 | QVBoxLayout *vb_bottom = new QVBoxLayout(sp_bottom);
|
---|
| 754 |
|
---|
| 755 | // toolbar
|
---|
| 756 | d->act_clear = new IconAction (tr("Clear chat window"), "psi/clearChat", tr("Clear chat window"), 0, this);
|
---|
| 757 | connect( d->act_clear, SIGNAL( activated() ), SLOT( doClearButton() ) );
|
---|
| 758 |
|
---|
| 759 | connect(pa->psi()->iconSelectPopup(), SIGNAL(textSelected(QString)), d, SLOT(addEmoticon(QString)));
|
---|
| 760 | d->act_icon = new IconAction( tr( "Select icon" ), "psi/smile", tr( "Select icon" ), 0, this );
|
---|
| 761 | d->act_icon->setPopup( pa->psi()->iconSelectPopup() );
|
---|
| 762 |
|
---|
| 763 | d->toolbar = new PsiToolBar( tr("Groupchat toolbar"), 0, sp_bottom );
|
---|
| 764 | d->toolbar->setCustomizeable( false ); // it isn't ready now, and we don't want segfaults
|
---|
| 765 | d->toolbar->setFrameShape( QFrame::NoFrame );
|
---|
| 766 | vb_bottom->addWidget( d->toolbar );
|
---|
| 767 |
|
---|
| 768 | d->act_clear->addTo( d->toolbar );
|
---|
| 769 | d->toolbar->setStretchableWidget(new StretchWidget(d->toolbar));
|
---|
| 770 | d->act_icon->addTo( d->toolbar );
|
---|
| 771 |
|
---|
| 772 | // chat edit
|
---|
| 773 | if ( !option.chatLineEdit ) {
|
---|
| 774 | d->mle = new ChatEdit(sp_bottom);
|
---|
| 775 | vb_bottom->addWidget(d->mle);
|
---|
| 776 | }
|
---|
| 777 | else {
|
---|
| 778 | QHBoxLayout *hb5 = new QHBoxLayout( dlg_layout );
|
---|
| 779 | d->mle = new LineEdit( vsplit );
|
---|
| 780 | #ifdef Q_WS_MAC
|
---|
| 781 | hb5->addSpacing( 16 );
|
---|
| 782 | #endif
|
---|
| 783 | hb5->addWidget( d->mle );
|
---|
| 784 | #ifdef Q_WS_MAC
|
---|
| 785 | hb5->addSpacing( 16 );
|
---|
| 786 | #endif
|
---|
| 787 | }
|
---|
| 788 |
|
---|
| 789 | d->mle->installEventFilter( d );
|
---|
| 790 |
|
---|
| 791 | d->pm_settings = new QPopupMenu(this);
|
---|
| 792 | connect(d->pm_settings, SIGNAL(aboutToShow()), SLOT(buildMenu()));
|
---|
| 793 |
|
---|
| 794 | // resize the horizontal splitter
|
---|
| 795 | QValueList<int> list;
|
---|
| 796 | list << 500;
|
---|
| 797 | list << 80;
|
---|
| 798 | hsp->setSizes(list);
|
---|
| 799 |
|
---|
| 800 | list.clear();
|
---|
| 801 | list << 324;
|
---|
| 802 | list << 10;
|
---|
| 803 | if ( !option.chatLineEdit )
|
---|
| 804 | (( QSplitter *)vsplit)->setSizes(list);
|
---|
| 805 |
|
---|
| 806 | resize(580,420);
|
---|
| 807 |
|
---|
| 808 | d->smallChat = option.smallChats;
|
---|
| 809 | X11WM_CLASS("groupchat");
|
---|
| 810 |
|
---|
| 811 | d->mle->setFocus();
|
---|
| 812 |
|
---|
| 813 | setLooks();
|
---|
| 814 | updateCaption();
|
---|
| 815 | }
|
---|
| 816 |
|
---|
| 817 | GCMainDlg::~GCMainDlg()
|
---|
| 818 | {
|
---|
| 819 | if(d->state != Private::Idle)
|
---|
| 820 | d->pa->groupChatLeave(d->jid.host(), d->jid.user());
|
---|
| 821 |
|
---|
| 822 | //QMimeSourceFactory *m = d->te_log->mimeSourceFactory();
|
---|
| 823 | //d->te_log->setMimeSourceFactory(0);
|
---|
| 824 | //delete m;
|
---|
| 825 |
|
---|
| 826 | d->pa->dialogUnregister(this);
|
---|
| 827 | delete d;
|
---|
| 828 | }
|
---|
| 829 |
|
---|
| 830 | void GCMainDlg::keyPressEvent(QKeyEvent *e)
|
---|
| 831 | {
|
---|
| 832 | if(e->key() == Key_Return || e->key() == Key_Enter || (e->key() == Key_S && (e->state() & AltButton)))
|
---|
| 833 | mle_returnPressed();
|
---|
[49] | 834 | else if(e->key() == Key_Escape && e->state() == 0)
|
---|
| 835 | showMinimized();
|
---|
[2] | 836 | else if(e->key() == Key_PageUp && (e->state() & ShiftButton))
|
---|
| 837 | d->te_log->setContentsPos(d->te_log->contentsX(), d->te_log->contentsY() - d->te_log->visibleHeight()/2);
|
---|
| 838 | else if(e->key() == Key_PageDown && (e->state() & ShiftButton))
|
---|
| 839 | d->te_log->setContentsPos(d->te_log->contentsX(), d->te_log->contentsY() + d->te_log->visibleHeight()/2);
|
---|
| 840 | else
|
---|
| 841 | e->ignore();
|
---|
| 842 | }
|
---|
| 843 |
|
---|
| 844 | void GCMainDlg::closeEvent(QCloseEvent *e)
|
---|
| 845 | {
|
---|
| 846 | e->accept();
|
---|
| 847 | }
|
---|
| 848 |
|
---|
| 849 | void GCMainDlg::windowActivationChange(bool oldstate)
|
---|
| 850 | {
|
---|
| 851 | QWidget::windowActivationChange(oldstate);
|
---|
| 852 |
|
---|
| 853 | // if we're bringing it to the front, get rid of the '*' if necessary
|
---|
| 854 | if(isActiveWindow()) {
|
---|
| 855 | if(d->pending > 0) {
|
---|
| 856 | d->pending = 0;
|
---|
| 857 | updateCaption();
|
---|
| 858 | }
|
---|
| 859 | doFlash(false);
|
---|
| 860 |
|
---|
| 861 | d->mle->setFocus();
|
---|
| 862 | d->trackBar = false;
|
---|
| 863 | } else {
|
---|
| 864 | d->trackBar = true;
|
---|
| 865 | }
|
---|
| 866 | }
|
---|
| 867 |
|
---|
| 868 |
|
---|
| 869 | void GCMainDlg::logSelectionChanged()
|
---|
| 870 | {
|
---|
| 871 | #ifdef Q_WS_MAC
|
---|
| 872 | // A hack to only give the message log focus when text is selected
|
---|
| 873 | if (d->te_log->hasSelectedText())
|
---|
| 874 | d->te_log->setFocus();
|
---|
| 875 | else
|
---|
| 876 | d->mle->setFocus();
|
---|
| 877 | #endif
|
---|
| 878 | }
|
---|
| 879 |
|
---|
| 880 | void GCMainDlg::mle_returnPressed()
|
---|
| 881 | {
|
---|
| 882 | if(d->mle->text().isEmpty())
|
---|
| 883 | return;
|
---|
| 884 |
|
---|
| 885 | QString str = d->mle->text();
|
---|
| 886 | if(str == "/clear") {
|
---|
| 887 | doClear();
|
---|
| 888 |
|
---|
| 889 | d->histAt = 0;
|
---|
| 890 | d->hist.prepend(str);
|
---|
| 891 | d->mle->setText("");
|
---|
| 892 | return;
|
---|
| 893 | }
|
---|
| 894 |
|
---|
| 895 | if(str.lower().startsWith("/nick ")) {
|
---|
| 896 | QString nick = str.mid(6).stripWhiteSpace();
|
---|
| 897 | if ( !nick.isEmpty() ) {
|
---|
| 898 | d->self = nick;
|
---|
| 899 | d->pa->groupChatChangeNick(d->jid.host(), d->jid.user(), d->self, d->pa->status());
|
---|
| 900 | }
|
---|
| 901 | d->mle->setText("");
|
---|
| 902 | return;
|
---|
| 903 | }
|
---|
| 904 |
|
---|
| 905 | if(d->state != Private::Connected)
|
---|
| 906 | return;
|
---|
| 907 |
|
---|
| 908 | Message m(d->jid);
|
---|
| 909 | m.setType("groupchat");
|
---|
| 910 | m.setBody(str);
|
---|
| 911 | m.setTimeStamp(QDateTime::currentDateTime());
|
---|
| 912 |
|
---|
| 913 | aSend(m);
|
---|
| 914 |
|
---|
| 915 | d->histAt = 0;
|
---|
| 916 | d->hist.prepend(str);
|
---|
| 917 | d->mle->setText("");
|
---|
| 918 | }
|
---|
| 919 |
|
---|
| 920 | /*void GCMainDlg::le_upPressed()
|
---|
| 921 | {
|
---|
| 922 | if(d->histAt < (int)d->hist.count()) {
|
---|
| 923 | ++d->histAt;
|
---|
| 924 | d->le_input->setText(d->hist[d->histAt-1]);
|
---|
| 925 | }
|
---|
| 926 | }
|
---|
| 927 |
|
---|
| 928 | void GCMainDlg::le_downPressed()
|
---|
| 929 | {
|
---|
| 930 | if(d->histAt > 0) {
|
---|
| 931 | --d->histAt;
|
---|
| 932 | if(d->histAt == 0)
|
---|
| 933 | d->le_input->setText("");
|
---|
| 934 | else
|
---|
| 935 | d->le_input->setText(d->hist[d->histAt-1]);
|
---|
| 936 | }
|
---|
| 937 | }*/
|
---|
| 938 |
|
---|
| 939 | void GCMainDlg::doTopic()
|
---|
| 940 | {
|
---|
| 941 | bool ok = false;
|
---|
| 942 | QString str = QInputDialog::getText(
|
---|
| 943 | tr("Set Groupchat Topic"),
|
---|
| 944 | tr("Enter a topic:"),
|
---|
| 945 | QLineEdit::Normal, d->le_topic->text(), &ok, this);
|
---|
| 946 |
|
---|
| 947 | if(ok) {
|
---|
| 948 | Message m(d->jid);
|
---|
| 949 | m.setType("groupchat");
|
---|
| 950 | m.setSubject(str);
|
---|
| 951 | m.setBody(QString("/me ") + tr("has set the topic to: %1").arg(str));
|
---|
| 952 | m.setTimeStamp(QDateTime::currentDateTime());
|
---|
| 953 | aSend(m);
|
---|
| 954 | }
|
---|
| 955 | }
|
---|
| 956 |
|
---|
| 957 | void GCMainDlg::doClear()
|
---|
| 958 | {
|
---|
| 959 | d->te_log->setText("");
|
---|
| 960 | }
|
---|
| 961 |
|
---|
| 962 | void GCMainDlg::doClearButton()
|
---|
| 963 | {
|
---|
| 964 | int n = QMessageBox::information(this, tr("Warning"), tr("Are you sure you want to clear the chat window?\n(note: does not affect saved history)"), tr("&Yes"), tr("&No"));
|
---|
| 965 | if(n == 0)
|
---|
| 966 | doClear();
|
---|
| 967 | }
|
---|
| 968 |
|
---|
| 969 | void GCMainDlg::openFind()
|
---|
| 970 | {
|
---|
| 971 | if(d->findDlg)
|
---|
| 972 | bringToFront(d->findDlg);
|
---|
| 973 | else {
|
---|
| 974 | d->findDlg = new GCFindDlg(0, 0, d->lastSearch, this);
|
---|
| 975 | connect(d->findDlg, SIGNAL(find(int, int, const QString &)), SLOT(doFind(int, int, const QString &)));
|
---|
| 976 | d->findDlg->show();
|
---|
| 977 | }
|
---|
| 978 | }
|
---|
| 979 |
|
---|
| 980 | void GCMainDlg::doFind(int para, int index, const QString &str)
|
---|
| 981 | {
|
---|
| 982 | d->lastSearch = str;
|
---|
| 983 |
|
---|
| 984 | if(!d->te_log->find(str, false, false, true, ¶, &index))
|
---|
| 985 | d->findDlg->error(str);
|
---|
| 986 | else {
|
---|
| 987 | // pass one character over
|
---|
| 988 | d->findDlg->found(para, index+1);
|
---|
| 989 | }
|
---|
| 990 | }
|
---|
| 991 |
|
---|
| 992 | void GCMainDlg::goDisc()
|
---|
| 993 | {
|
---|
| 994 | if(d->state != Private::Idle) {
|
---|
| 995 | d->state = Private::Idle;
|
---|
| 996 | d->pb_topic->setEnabled(false);
|
---|
| 997 | appendSysMsg(tr("Disconnected."), true);
|
---|
| 998 | }
|
---|
| 999 | }
|
---|
| 1000 |
|
---|
| 1001 | void GCMainDlg::goConn()
|
---|
| 1002 | {
|
---|
| 1003 | if(d->state == Private::Idle) {
|
---|
| 1004 | d->state = Private::Connecting;
|
---|
| 1005 | appendSysMsg(tr("Reconnecting..."), true);
|
---|
| 1006 |
|
---|
| 1007 | QString host = d->jid.host();
|
---|
| 1008 | QString room = d->jid.user();
|
---|
| 1009 | QString nick = d->self;
|
---|
| 1010 |
|
---|
| 1011 | if(!d->pa->groupChatJoin(host, room, nick)) {
|
---|
| 1012 | appendSysMsg(tr("Error: You are in or joining this room already!"), true);
|
---|
| 1013 | d->state = Private::Idle;
|
---|
| 1014 | }
|
---|
| 1015 | }
|
---|
| 1016 | }
|
---|
| 1017 |
|
---|
| 1018 | void GCMainDlg::pa_updatedActivity()
|
---|
| 1019 | {
|
---|
| 1020 | if(!d->pa->loggedIn())
|
---|
| 1021 | goDisc();
|
---|
| 1022 | else {
|
---|
| 1023 | if(d->state == Private::Idle)
|
---|
| 1024 | goConn();
|
---|
| 1025 | else if(d->state == Private::Connected)
|
---|
| 1026 | d->pa->groupChatSetStatus(d->jid.host(), d->jid.user(), d->pa->status());
|
---|
| 1027 | }
|
---|
| 1028 | }
|
---|
| 1029 |
|
---|
| 1030 | Jid GCMainDlg::jid() const
|
---|
| 1031 | {
|
---|
| 1032 | return d->jid;
|
---|
| 1033 | }
|
---|
| 1034 |
|
---|
| 1035 | void GCMainDlg::error(int, const QString &str)
|
---|
| 1036 | {
|
---|
| 1037 | d->pb_topic->setEnabled(false);
|
---|
| 1038 |
|
---|
| 1039 | if(d->state == Private::Connecting)
|
---|
| 1040 | appendSysMsg(tr("Unable to join groupchat. Reason: %1").arg(str), true);
|
---|
| 1041 | else
|
---|
| 1042 | appendSysMsg(tr("Unexpected groupchat error: %1").arg(str), true);
|
---|
| 1043 |
|
---|
| 1044 | d->state = Private::Idle;
|
---|
| 1045 | }
|
---|
| 1046 |
|
---|
| 1047 | void GCMainDlg::presence(const QString &nick, const Status &s)
|
---|
| 1048 | {
|
---|
| 1049 | if(s.isAvailable()) {
|
---|
| 1050 | /*if ((option.showJoins)&&(d->lv_users->findEntry(nick)==0)) {
|
---|
| 1051 | //contact joining
|
---|
| 1052 | QString m=nick+tr(" has joined the channel");
|
---|
| 1053 | appendSysMsg(m, false, QDateTime::currentDateTime());
|
---|
| 1054 | }*/
|
---|
| 1055 | d->lv_users->updateEntry(nick, s);
|
---|
| 1056 | } else {
|
---|
| 1057 | /*if (option.showJoins) {
|
---|
| 1058 | //contact leaving
|
---|
| 1059 | QString m=nick+tr(" has left the channel");
|
---|
| 1060 | appendSysMsg(m, false, QDateTime::currentDateTime());
|
---|
| 1061 | }*/
|
---|
| 1062 | d->lv_users->removeEntry(nick);
|
---|
| 1063 | }
|
---|
| 1064 | }
|
---|
| 1065 |
|
---|
| 1066 | void GCMainDlg::message(const Message &m)
|
---|
| 1067 | {
|
---|
| 1068 | QString from = m.from().resource();
|
---|
| 1069 | bool alert = false;
|
---|
| 1070 |
|
---|
| 1071 | if(!m.subject().isEmpty()) {
|
---|
| 1072 | d->le_topic->setText(m.subject());
|
---|
| 1073 | d->le_topic->setCursorPosition(0);
|
---|
| 1074 | QToolTip::add(d->le_topic, QString("<qt><p>%1</p></qt>").arg(m.subject()));
|
---|
| 1075 | }
|
---|
| 1076 |
|
---|
| 1077 | // code to determine if the speaker was addressing this client in chat
|
---|
| 1078 | if(m.body().contains(d->self) > 0)
|
---|
| 1079 | alert = true;
|
---|
| 1080 |
|
---|
| 1081 | if (m.body().left(d->self.length()) == d->self)
|
---|
| 1082 | d->lastReferrer = m.from().resource();
|
---|
| 1083 |
|
---|
| 1084 | if(option.gcHighlighting) {
|
---|
| 1085 | for(QStringList::Iterator it=option.gcHighlights.begin();it!=option.gcHighlights.end();it++) {
|
---|
| 1086 | if(m.body().contains((*it),false) > 0) {
|
---|
| 1087 | alert = true;
|
---|
| 1088 | }
|
---|
| 1089 | }
|
---|
| 1090 | }
|
---|
| 1091 |
|
---|
| 1092 | // play sound?
|
---|
| 1093 | if(from == d->self) {
|
---|
| 1094 | if(!m.spooled())
|
---|
| 1095 | d->pa->playSound(option.onevent[eSend]);
|
---|
| 1096 | }
|
---|
| 1097 | else {
|
---|
| 1098 | if(alert || (!option.noGCSound && !m.spooled() && !from.isEmpty()) )
|
---|
| 1099 | d->pa->playSound(option.onevent[eChat2]);
|
---|
| 1100 | }
|
---|
| 1101 |
|
---|
| 1102 | if(from.isEmpty())
|
---|
| 1103 | appendSysMsg(m.body(), alert, m.timeStamp());
|
---|
| 1104 | else
|
---|
| 1105 | appendMessage(m, alert);
|
---|
| 1106 | }
|
---|
| 1107 |
|
---|
| 1108 | void GCMainDlg::joined()
|
---|
| 1109 | {
|
---|
| 1110 | if(d->state == Private::Connecting) {
|
---|
| 1111 | d->lv_users->QListView::clear();
|
---|
| 1112 | d->state = Private::Connected;
|
---|
| 1113 | d->pb_topic->setEnabled(true);
|
---|
| 1114 | appendSysMsg(tr("Connected."), true);
|
---|
| 1115 | }
|
---|
| 1116 | }
|
---|
| 1117 |
|
---|
| 1118 | void GCMainDlg::appendSysMsg(const QString &str, bool alert, const QDateTime &ts)
|
---|
| 1119 | {
|
---|
| 1120 | bool atBottom = d->te_log->contentsY() >= d->te_log->contentsHeight() - d->te_log->visibleHeight();
|
---|
| 1121 |
|
---|
| 1122 | QString hr ="";
|
---|
| 1123 | if (d->trackBar) {
|
---|
| 1124 | hr = QString("<hr>");
|
---|
| 1125 | d->trackBar = false;
|
---|
| 1126 |
|
---|
| 1127 | if ( d->trackBarParagraph ) {
|
---|
| 1128 | d->te_log->setUpdatesEnabled( false );
|
---|
| 1129 | d->te_log->setSelection(d->trackBarParagraph, 0, d->trackBarParagraph, 1, 1);
|
---|
| 1130 | d->te_log->removeSelectedText(1);
|
---|
| 1131 | d->te_log->setUpdatesEnabled( true );
|
---|
| 1132 | }
|
---|
| 1133 | d->trackBarParagraph = d->te_log->paragraphs();
|
---|
| 1134 | }
|
---|
| 1135 |
|
---|
| 1136 | QString timestr;
|
---|
| 1137 | if (!option.gcHighlighting)
|
---|
| 1138 | alert=false;
|
---|
| 1139 |
|
---|
| 1140 | QDateTime time;
|
---|
| 1141 | if(!ts.isNull())
|
---|
| 1142 | time = ts;
|
---|
| 1143 | else
|
---|
| 1144 | time = QDateTime::currentDateTime();
|
---|
| 1145 |
|
---|
| 1146 | //timestr.sprintf("%02d:%02d:%02d", time.time().hour(), time.time().minute(), time.time().second());
|
---|
| 1147 | timestr = time.time().toString(LocalDate);
|
---|
| 1148 |
|
---|
| 1149 | /*int y = d->te_log->contentsHeight() - d->te_log->visibleHeight();
|
---|
| 1150 | if(y < 0)
|
---|
| 1151 | y = 0;
|
---|
| 1152 | bool atBottom = (d->te_log->contentsY() < y - 32) ? false: true;*/
|
---|
| 1153 |
|
---|
| 1154 | d->te_log->append(hr + QString("<font color=\"#00A000\">[%1]").arg(timestr) + QString(" *** %1</font>").arg(expandEntities(str)));
|
---|
| 1155 |
|
---|
| 1156 | if(atBottom)
|
---|
| 1157 | d->deferredScroll();
|
---|
| 1158 |
|
---|
| 1159 | if(alert)
|
---|
| 1160 | doAlert();
|
---|
| 1161 | }
|
---|
| 1162 |
|
---|
| 1163 | QString GCMainDlg::getNickColor(QString nick)
|
---|
| 1164 | {
|
---|
| 1165 | int sender;
|
---|
| 1166 | if(nick == d->self||nick.isEmpty())
|
---|
| 1167 | sender = -1;
|
---|
| 1168 | else {
|
---|
| 1169 | if (!nicks.contains(nick)) {
|
---|
| 1170 | //not found in map
|
---|
| 1171 | nicks.insert(nick,nicknumber);
|
---|
| 1172 | nicknumber++;
|
---|
| 1173 | }
|
---|
| 1174 | sender=nicks[nick];
|
---|
| 1175 | }
|
---|
| 1176 |
|
---|
| 1177 | if(!option.gcNickColoring || option.gcNickColors.empty()) {
|
---|
| 1178 | return "#000000";
|
---|
| 1179 | }
|
---|
| 1180 | else if(sender == -1 || option.gcNickColors.size() == 1) {
|
---|
| 1181 | return option.gcNickColors[option.gcNickColors.size()-1];
|
---|
| 1182 | }
|
---|
| 1183 | else {
|
---|
| 1184 | int n = sender % (option.gcNickColors.size()-1);
|
---|
| 1185 | return option.gcNickColors[n];
|
---|
| 1186 | }
|
---|
| 1187 | }
|
---|
| 1188 |
|
---|
| 1189 | void GCMainDlg::appendMessage(const Message &m, bool alert)
|
---|
| 1190 | {
|
---|
| 1191 | //QString who, color;
|
---|
| 1192 | if (!option.gcHighlighting)
|
---|
| 1193 | alert=false;
|
---|
| 1194 | QString who, textcolor, nickcolor,alerttagso,alerttagsc;
|
---|
| 1195 |
|
---|
| 1196 | bool atBottom = d->te_log->contentsY() >= d->te_log->contentsHeight() - d->te_log->visibleHeight();
|
---|
| 1197 |
|
---|
| 1198 | who = m.from().resource();
|
---|
| 1199 | QString hr = "";
|
---|
| 1200 | if (d->trackBar&&m.from().resource() != d->self&&!m.spooled()) {
|
---|
| 1201 | hr = QString("<hr>");
|
---|
| 1202 | d->trackBar = false;
|
---|
| 1203 |
|
---|
| 1204 | if ( d->trackBarParagraph ) {
|
---|
| 1205 | d->te_log->setUpdatesEnabled( false );
|
---|
| 1206 | d->te_log->setSelection(d->trackBarParagraph, 0, d->trackBarParagraph, 1, 1);
|
---|
| 1207 | d->te_log->removeSelectedText(1);
|
---|
| 1208 | d->te_log->setUpdatesEnabled( true );
|
---|
| 1209 | }
|
---|
| 1210 | d->trackBarParagraph = d->te_log->paragraphs();
|
---|
| 1211 | }
|
---|
| 1212 | /*if(local) {
|
---|
| 1213 | color = "#FF0000";
|
---|
| 1214 | }
|
---|
| 1215 | else {
|
---|
| 1216 | color = "#0000FF";
|
---|
| 1217 | }*/
|
---|
| 1218 | nickcolor = getNickColor(who);
|
---|
| 1219 | textcolor = d->te_log->palette().active().text().name();
|
---|
| 1220 | if(alert) {
|
---|
| 1221 | textcolor = "#FF0000";
|
---|
| 1222 | alerttagso = "<b>";
|
---|
| 1223 | alerttagsc = "</b>";
|
---|
| 1224 | }
|
---|
| 1225 | if(m.spooled())
|
---|
| 1226 | nickcolor = "#008000"; //color = "#008000";
|
---|
| 1227 |
|
---|
| 1228 | QString timestr;
|
---|
| 1229 | QDateTime time = m.timeStamp();
|
---|
| 1230 | //timestr.sprintf("%02d:%02d:%02d", time.time().hour(), time.time().minute(), time.time().second());
|
---|
| 1231 | timestr = time.time().toString(LocalDate);
|
---|
| 1232 |
|
---|
| 1233 | /*int y = d->te_log->contentsHeight() - d->te_log->visibleHeight();
|
---|
| 1234 | if(y < 0)
|
---|
| 1235 | y = 0;
|
---|
| 1236 | bool atBottom = (d->te_log->contentsY() < y - 32) ? false: true;*/
|
---|
| 1237 |
|
---|
| 1238 | bool emote = false;
|
---|
| 1239 | if(m.body().left(4) == "/me ")
|
---|
| 1240 | emote = true;
|
---|
| 1241 |
|
---|
| 1242 | QString txt;
|
---|
| 1243 | if(emote)
|
---|
| 1244 | txt = plain2rich(m.body().mid(4));
|
---|
| 1245 | else
|
---|
| 1246 | txt = plain2rich(m.body());
|
---|
| 1247 |
|
---|
| 1248 | txt = linkify(txt);
|
---|
| 1249 |
|
---|
| 1250 | if(option.useEmoticons)
|
---|
| 1251 | txt = emoticonify(txt);
|
---|
| 1252 |
|
---|
| 1253 | if(emote) {
|
---|
| 1254 | //d->te_log->append(QString("<font color=\"%1\">").arg(color) + QString("[%1]").arg(timestr) + QString(" *%1 ").arg(expandEntities(who)) + txt + "</font>");
|
---|
| 1255 | d->te_log->append(hr + QString("<font color=\"%1\">").arg(nickcolor) + QString("[%1]").arg(timestr) + QString(" *%1 ").arg(expandEntities(who)) + alerttagso + txt + alerttagsc + "</font>");
|
---|
| 1256 | }
|
---|
| 1257 | else {
|
---|
| 1258 | if(option.chatSays) {
|
---|
| 1259 | //d->te_log->append(QString("<font color=\"%1\">").arg(color) + QString("[%1] ").arg(timestr) + QString("%1 says:").arg(expandEntities(who)) + "</font><br>" + txt);
|
---|
| 1260 | d->te_log->append(hr + QString("<font color=\"%1\">").arg(nickcolor) + QString("[%1] ").arg(timestr) + QString("%1 says:").arg(expandEntities(who)) + "</font><br>" + QString("<font color=\"%1\">").arg(textcolor) + alerttagso + txt + alerttagsc + "</font>");
|
---|
| 1261 | }
|
---|
| 1262 | else {
|
---|
| 1263 | //d->te_log->append(QString("<font color=\"%1\">").arg(color) + QString("[%1] <").arg(timestr) + expandEntities(who) + QString("></font> ") + txt);
|
---|
| 1264 | d->te_log->append(hr + QString("<font color=\"%1\">").arg(nickcolor) + QString("[%1] <").arg(timestr) + expandEntities(who) + QString("></font> ") + QString("<font color=\"%1\">").arg(textcolor) + alerttagso + txt + alerttagsc +"</font>");
|
---|
| 1265 | }
|
---|
| 1266 | }
|
---|
| 1267 |
|
---|
| 1268 | //if(local || atBottom)
|
---|
| 1269 | if(m.from().resource() == d->self || atBottom)
|
---|
| 1270 | d->deferredScroll();
|
---|
| 1271 |
|
---|
| 1272 | // if we're not active, notify the user by changing the title
|
---|
| 1273 | if(!isActiveWindow()) {
|
---|
| 1274 | ++d->pending;
|
---|
| 1275 | updateCaption();
|
---|
| 1276 | }
|
---|
| 1277 |
|
---|
| 1278 | //if someone directed their comments to us, notify the user
|
---|
| 1279 | if(alert)
|
---|
| 1280 | doAlert();
|
---|
| 1281 |
|
---|
| 1282 | //if the message spoke to us, alert the user before closing this window
|
---|
| 1283 | //except that keepopen doesn't seem to be implemented for this class yet.
|
---|
| 1284 | /*if(alert) {
|
---|
| 1285 | d->keepOpen = true;
|
---|
| 1286 | QTimer::singleShot(1000, this, SLOT(setKeepOpenFalse()));
|
---|
| 1287 | }*/
|
---|
| 1288 | }
|
---|
| 1289 |
|
---|
| 1290 | void GCMainDlg::doAlert()
|
---|
| 1291 | {
|
---|
| 1292 | if(!isActiveWindow())
|
---|
| 1293 | doFlash(true);
|
---|
| 1294 | }
|
---|
| 1295 |
|
---|
| 1296 | void GCMainDlg::updateCaption()
|
---|
| 1297 | {
|
---|
| 1298 | QString cap = "";
|
---|
| 1299 |
|
---|
| 1300 | if(d->pending > 0) {
|
---|
| 1301 | cap += "* ";
|
---|
| 1302 | if(d->pending > 1)
|
---|
| 1303 | cap += QString("[%1] ").arg(d->pending);
|
---|
| 1304 | }
|
---|
| 1305 | cap += d->jid.full();
|
---|
| 1306 |
|
---|
| 1307 | // if taskbar flash, then we need to erase first and redo
|
---|
| 1308 | #ifdef Q_WS_WIN
|
---|
| 1309 | bool on = false;
|
---|
| 1310 | if(d->flashTimer)
|
---|
| 1311 | on = d->flashCount & 1;
|
---|
| 1312 | if(on)
|
---|
| 1313 | FlashWindow(winId(), true);
|
---|
| 1314 | #endif
|
---|
| 1315 | setCaption(cap);
|
---|
| 1316 | #ifdef Q_WS_WIN
|
---|
| 1317 | if(on)
|
---|
| 1318 | FlashWindow(winId(), true);
|
---|
| 1319 | #endif
|
---|
| 1320 | }
|
---|
| 1321 |
|
---|
| 1322 | #ifdef Q_WS_WIN
|
---|
| 1323 | void GCMainDlg::doFlash(bool yes)
|
---|
| 1324 | {
|
---|
| 1325 | if(yes) {
|
---|
| 1326 | if(d->flashTimer)
|
---|
| 1327 | return;
|
---|
| 1328 | d->flashTimer = new QTimer(this);
|
---|
| 1329 | connect(d->flashTimer, SIGNAL(timeout()), SLOT(flashAnimate()));
|
---|
| 1330 | d->flashCount = 0;
|
---|
| 1331 | flashAnimate(); // kick the first one immediately
|
---|
| 1332 | d->flashTimer->start(500);
|
---|
| 1333 | }
|
---|
| 1334 | else {
|
---|
| 1335 | if(d->flashTimer) {
|
---|
| 1336 | delete d->flashTimer;
|
---|
| 1337 | d->flashTimer = 0;
|
---|
| 1338 | FlashWindow(winId(), false);
|
---|
| 1339 | }
|
---|
| 1340 | }
|
---|
| 1341 | }
|
---|
| 1342 | #else
|
---|
| 1343 | void GCMainDlg::doFlash(bool)
|
---|
| 1344 | {
|
---|
| 1345 | }
|
---|
| 1346 | #endif
|
---|
| 1347 |
|
---|
| 1348 | void GCMainDlg::flashAnimate()
|
---|
| 1349 | {
|
---|
| 1350 | #ifdef Q_WS_WIN
|
---|
| 1351 | FlashWindow(winId(), true);
|
---|
| 1352 | ++d->flashCount;
|
---|
| 1353 | if(d->flashCount == 5)
|
---|
| 1354 | d->flashTimer->stop();
|
---|
| 1355 | #endif
|
---|
| 1356 | }
|
---|
| 1357 |
|
---|
| 1358 | void GCMainDlg::setLooks()
|
---|
| 1359 | {
|
---|
| 1360 | // update the fonts
|
---|
| 1361 | QFont f;
|
---|
| 1362 | f.fromString(option.font[fChat]);
|
---|
| 1363 | d->te_log->setFont(f);
|
---|
| 1364 | d->mle->setFont(f);
|
---|
| 1365 |
|
---|
| 1366 | f.fromString(option.font[fRoster]);
|
---|
| 1367 | d->lv_users->QListView::setFont(f);
|
---|
| 1368 |
|
---|
| 1369 | if ( d->smallChat ) {
|
---|
| 1370 | d->toolbar->hide();
|
---|
| 1371 | }
|
---|
| 1372 | else {
|
---|
| 1373 | d->toolbar->show();
|
---|
| 1374 | }
|
---|
| 1375 |
|
---|
| 1376 | // update the widget icon
|
---|
| 1377 | #ifndef Q_WS_MAC
|
---|
| 1378 | setIcon(IconsetFactory::icon("psi/groupChat"));
|
---|
| 1379 | #endif
|
---|
| 1380 | }
|
---|
| 1381 |
|
---|
| 1382 | void GCMainDlg::optionsUpdate()
|
---|
| 1383 | {
|
---|
| 1384 | /*QMimeSourceFactory *m = d->te_log->mimeSourceFactory();
|
---|
| 1385 | d->te_log->setMimeSourceFactory(is->emoticons.generateFactory());
|
---|
| 1386 | delete m;*/
|
---|
| 1387 |
|
---|
| 1388 | setLooks();
|
---|
| 1389 |
|
---|
| 1390 | // update status icons
|
---|
| 1391 | d->lv_users->updateAll();
|
---|
| 1392 | }
|
---|
| 1393 |
|
---|
| 1394 | void GCMainDlg::lv_action(const QString &nick, const Status &s, int x)
|
---|
| 1395 | {
|
---|
| 1396 | if(x == 0) {
|
---|
| 1397 | d->pa->invokeGCMessage(d->jid.withResource(nick));
|
---|
| 1398 | }
|
---|
| 1399 | else if(x == 1) {
|
---|
| 1400 | d->pa->invokeGCChat(d->jid.withResource(nick));
|
---|
| 1401 | }
|
---|
| 1402 | else if(x == 2) {
|
---|
| 1403 | UserListItem u;
|
---|
| 1404 | u.setJid(d->jid.withResource(nick));
|
---|
| 1405 | u.setName(nick);
|
---|
| 1406 |
|
---|
| 1407 | // make a resource so the contact appears online
|
---|
| 1408 | UserResource ur;
|
---|
| 1409 | ur.setName(nick);
|
---|
| 1410 | ur.setStatus(s);
|
---|
| 1411 | u.userResourceList().append(ur);
|
---|
| 1412 |
|
---|
| 1413 | StatusShowDlg *w = new StatusShowDlg(u);
|
---|
| 1414 | w->show();
|
---|
| 1415 | }
|
---|
| 1416 | else if(x == 3) {
|
---|
| 1417 | d->pa->invokeGCInfo(d->jid.withResource(nick));
|
---|
| 1418 | }
|
---|
| 1419 | else if(x == 4) {
|
---|
| 1420 | d->pa->invokeGCFile(d->jid.withResource(nick));
|
---|
| 1421 | }
|
---|
| 1422 | }
|
---|
| 1423 |
|
---|
| 1424 | void GCMainDlg::contextMenuEvent(QContextMenuEvent *)
|
---|
| 1425 | {
|
---|
| 1426 | d->pm_settings->exec(QCursor::pos());
|
---|
| 1427 | }
|
---|
| 1428 |
|
---|
| 1429 | void GCMainDlg::buildMenu()
|
---|
| 1430 | {
|
---|
| 1431 | // Dialog menu
|
---|
| 1432 | d->pm_settings->clear();
|
---|
| 1433 | d->pm_settings->insertItem(tr("Toggle Compact/Full Size"), this, SLOT(toggleSmallChat()));
|
---|
| 1434 |
|
---|
| 1435 | d->act_clear->addTo( d->pm_settings );
|
---|
| 1436 | d->pm_settings->insertSeparator();
|
---|
| 1437 |
|
---|
| 1438 | d->act_icon->addTo( d->pm_settings );
|
---|
| 1439 | }
|
---|
| 1440 |
|
---|
| 1441 | void GCMainDlg::toggleSmallChat()
|
---|
| 1442 | {
|
---|
| 1443 | d->smallChat = !d->smallChat;
|
---|
| 1444 | setLooks();
|
---|
| 1445 | }
|
---|
| 1446 |
|
---|
| 1447 | //----------------------------------------------------------------------------
|
---|
| 1448 | // GCFindDlg
|
---|
| 1449 | //----------------------------------------------------------------------------
|
---|
| 1450 | GCFindDlg::GCFindDlg(int startPara, int startIndex, const QString &str, QWidget *parent, const char *name)
|
---|
| 1451 | :QDialog(parent, name, false, WDestructiveClose)
|
---|
| 1452 | {
|
---|
| 1453 | para = startPara;
|
---|
| 1454 | index = startIndex;
|
---|
| 1455 |
|
---|
| 1456 | setCaption(tr("Find"));
|
---|
| 1457 | QVBoxLayout *vb = new QVBoxLayout(this, 4);
|
---|
| 1458 | QHBoxLayout *hb = new QHBoxLayout(vb);
|
---|
| 1459 | QLabel *l = new QLabel(tr("Find:"), this);
|
---|
| 1460 | hb->addWidget(l);
|
---|
| 1461 | le_input = new QLineEdit(this);
|
---|
| 1462 | hb->addWidget(le_input);
|
---|
| 1463 | vb->addStretch(1);
|
---|
| 1464 |
|
---|
| 1465 | QFrame *Line1 = new QFrame(this);
|
---|
| 1466 | Line1->setFrameShape( QFrame::HLine );
|
---|
| 1467 | Line1->setFrameShadow( QFrame::Sunken );
|
---|
| 1468 | Line1->setFrameShape( QFrame::HLine );
|
---|
| 1469 | vb->addWidget(Line1);
|
---|
| 1470 |
|
---|
| 1471 | hb = new QHBoxLayout(vb);
|
---|
| 1472 | hb->addStretch(1);
|
---|
| 1473 | QPushButton *pb_close = new QPushButton(tr("&Close"), this);
|
---|
| 1474 | connect(pb_close, SIGNAL(clicked()), SLOT(close()));
|
---|
| 1475 | hb->addWidget(pb_close);
|
---|
| 1476 | QPushButton *pb_find = new QPushButton(tr("&Find"), this);
|
---|
| 1477 | pb_find->setDefault(true);
|
---|
| 1478 | connect(pb_find, SIGNAL(clicked()), SLOT(doFind()));
|
---|
| 1479 | hb->addWidget(pb_find);
|
---|
| 1480 | pb_find->setAutoDefault(true);
|
---|
| 1481 |
|
---|
| 1482 | resize(200, minimumSize().height());
|
---|
| 1483 |
|
---|
| 1484 | le_input->setText(str);
|
---|
| 1485 | le_input->setFocus();
|
---|
| 1486 | }
|
---|
| 1487 |
|
---|
| 1488 | GCFindDlg::~GCFindDlg()
|
---|
| 1489 | {
|
---|
| 1490 | }
|
---|
| 1491 |
|
---|
| 1492 | void GCFindDlg::found(int _para, int _index)
|
---|
| 1493 | {
|
---|
| 1494 | para = _para;
|
---|
| 1495 | index = _index;
|
---|
| 1496 | }
|
---|
| 1497 |
|
---|
| 1498 | void GCFindDlg::error(const QString &str)
|
---|
| 1499 | {
|
---|
| 1500 | QMessageBox::warning(this, tr("Find"), tr("Search string '%1' not found.").arg(str));
|
---|
| 1501 | le_input->setFocus();
|
---|
| 1502 | }
|
---|
| 1503 |
|
---|
| 1504 | void GCFindDlg::doFind()
|
---|
| 1505 | {
|
---|
| 1506 | emit find(para, index, le_input->text());
|
---|
| 1507 | }
|
---|
| 1508 |
|
---|
| 1509 | #include "groupchatdlg.moc"
|
---|