root/trunk/qt4-gui/src/userevents/usereventtabdlg.cpp

Revision 6463, 7.5 kB (checked in by flynd, 4 months ago)

Use a const pointer for user objects that are only fetched for read access. Fixed some places where we changed the user even though we just had a read lock.

Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of Licq, an instant messaging client for UNIX.
4 * Copyright (C) 2000-2006 Licq developers
5 *
6 * Licq is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Licq is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Licq; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 */
20
21#include "usereventtabdlg.h"
22
23#include "config.h"
24
25#include <licq_message.h>
26
27#include <QTimer>
28#include <QVBoxLayout>
29
30#ifdef USE_KDE
31#include <KDE/KWindowSystem>
32#endif
33
34#include "config/chat.h"
35#include "config/iconmanager.h"
36
37#include "helpers/support.h"
38
39#include "widgets/tabwidget.h"
40
41#include "usereventcommon.h"
42#include "usersendcommon.h"
43
44using namespace LicqQtGui;
45/* TRANSLATOR LicqQtGui::UserEventTabDlg */
46
47using std::list;
48using std::string;
49
50UserEventTabDlg::UserEventTabDlg(QWidget* parent, const char* name)
51  : QWidget(parent)
52{
53  Support::setWidgetProps(this, name);
54  setAttribute(Qt::WA_DeleteOnClose, true);
55
56  QVBoxLayout* lay = new QVBoxLayout(this);
57  lay->setContentsMargins(0, 0, 0, 0);
58
59  if (Config::Chat::instance()->dialogRect().isValid())
60    setGeometry(Config::Chat::instance()->dialogRect());
61
62  myTabs = new TabWidget();
63  lay->addWidget(myTabs);
64
65  connect(myTabs, SIGNAL(currentChanged(int)), SLOT(currentChanged(int)));
66  connect(myTabs, SIGNAL(mouseMiddleClick(QWidget*)), SLOT(removeTab(QWidget*)));
67}
68
69UserEventTabDlg::~UserEventTabDlg()
70{
71  saveGeometry();
72  emit signal_done();
73}
74
75void UserEventTabDlg::addTab(UserEventCommon* tab, int index)
76{
77  const ICQUser* u = gUserManager.FetchUser(tab->id().toLatin1(), tab->ppid(), LOCK_R);
78  if (u == NULL)
79    return;
80
81  index = myTabs->insertTab(index, tab, QString::fromUtf8(u->GetAlias()));
82  updateTabLabel(tab, u);
83  gUserManager.DropUser(u);
84}
85
86void UserEventTabDlg::selectTab(QWidget* tab)
87{
88  myTabs->setCurrentIndex(myTabs->indexOf(tab));
89  updateTitle(tab);
90}
91
92void UserEventTabDlg::replaceTab(QWidget* oldTab, UserEventCommon* newTab)
93{
94  addTab(newTab, myTabs->indexOf(oldTab) + 1);
95  removeTab(oldTab);
96}
97
98bool UserEventTabDlg::tabIsSelected(QWidget* tab)
99{
100  return (myTabs->currentIndex() == myTabs->indexOf(tab));
101}
102
103bool UserEventTabDlg::tabExists(QWidget* tab)
104{
105  return (myTabs->indexOf(tab) != -1);
106}
107
108void UserEventTabDlg::updateConvoLabel(UserEventCommon* tab)
109{
110  // Show the list of users in the conversation
111  list<string> users = tab->convoUsers();
112  list<string>::iterator it;
113  QString newLabel = QString::null;
114
115  for (it = users.begin(); it != users.end(); ++it)
116  {
117    const ICQUser* u = gUserManager.FetchUser((*it).c_str(), tab->ppid(), LOCK_R);
118
119    if (!newLabel.isEmpty())
120      newLabel += ", ";
121
122    if (u == 0)
123      newLabel += tr("[UNKNOWN_USER]");
124    else
125    {
126      newLabel += QString::fromUtf8(u->GetAlias());
127      gUserManager.DropUser(u);
128    }
129  }
130
131  myTabs->setTabText(myTabs->indexOf(tab), newLabel);
132}
133
134void UserEventTabDlg::updateTabLabel(const ICQUser* u)
135{
136  if (u == NULL)
137    return;
138
139  for (int index = 0; index < myTabs->count(); index++)
140  {
141    UserEventCommon* tab = dynamic_cast<UserEventCommon*>(myTabs->widget(index));
142
143    if (tab->ppid() == u->PPID() &&
144        tab->isUserInConvo(u->IdString()))
145      updateTabLabel(tab, u);
146  }
147}
148
149void UserEventTabDlg::updateTabLabel(UserEventCommon* tab, const ICQUser* u)
150{
151  if (tab == NULL)
152    return;
153
154  bool fetched = false;
155  if (u == NULL ||
156      !tab->isUserInConvo(u->IdString()))
157  {
158    u = gUserManager.FetchUser(tab->id().toLatin1(), tab->ppid(), LOCK_R);
159    if (u == NULL)
160      return;
161    fetched = true;
162  }
163
164  QIcon icon;
165
166  if (u->NewMessages() > 0) // use an event icon
167  {
168    unsigned short SubCommand = ICQ_CMDxSUB_MSG;
169    for (unsigned short i = 0; i < u->NewMessages(); i++)
170      switch (u->EventPeek(i)->SubCommand())
171      {
172    case ICQ_CMDxSUB_FILE:
173      SubCommand = ICQ_CMDxSUB_FILE;
174      break;
175    case ICQ_CMDxSUB_CHAT:
176      if (SubCommand != ICQ_CMDxSUB_FILE)
177        SubCommand = ICQ_CMDxSUB_CHAT;
178      break;
179    case ICQ_CMDxSUB_URL:
180      if (SubCommand != ICQ_CMDxSUB_FILE &&
181          SubCommand != ICQ_CMDxSUB_CHAT)
182        SubCommand = ICQ_CMDxSUB_URL;
183      break;
184    case ICQ_CMDxSUB_CONTACTxLIST:
185      if (SubCommand != ICQ_CMDxSUB_FILE &&
186          SubCommand != ICQ_CMDxSUB_CHAT &&
187          SubCommand != ICQ_CMDxSUB_URL)
188        SubCommand = ICQ_CMDxSUB_CONTACTxLIST;
189      break;
190      }
191
192    icon = IconManager::instance()->iconForEvent(SubCommand);
193    myTabs->setTabColor(tab, QColor("blue"));
194
195    // to clear it..
196    tab->setTyping(u->GetTyping());
197  }
198  else // use status icon
199  {
200    icon = IconManager::instance()->iconForStatus(u->StatusFull(), u->IdString(), u->PPID());
201
202    if (u->GetTyping() == ICQ_TYPING_ACTIVE)
203      myTabs->setTabColor(tab, Config::Chat::instance()->tabTypingColor());
204    else
205      myTabs->setTabColor(tab, QColor("black"));
206  }
207
208  if (fetched)
209    gUserManager.DropUser(u);
210
211  int index = myTabs->indexOf(tab);
212  myTabs->setTabIcon(index, icon);
213  if (myTabs->currentIndex() == index)
214    setWindowIcon(icon);
215}
216
217void UserEventTabDlg::setTyping(const ICQUser* u, int convoId)
218{
219  for (int index = 0; index < myTabs->count(); index++)
220  {
221    UserEventCommon* tab = dynamic_cast<UserEventCommon*>(myTabs->widget(index));
222
223    if (tab->convoId() == static_cast<unsigned long>(convoId) &&
224        tab->ppid() == u->PPID() &&
225        tab->isUserInConvo(u->IdString()))
226      tab->setTyping(u->GetTyping());
227  }
228}
229
230#ifdef USE_KDE
231/* KDE 3.2 handles app-icon updates differently, since KDE 3.2 a simple setIcon() call
232   does no longer update the icon in kicker anymore :(
233   So we do it the "kde-way" here */
234void UserEventTabDlg::setIcon(const QPixmap& icon)
235{
236  KWindowSystem::setIcons(winId(), icon, icon);
237}
238#endif
239
240/*! This slot should get called when the current tab has
241 *  changed.
242 */
243void UserEventTabDlg::currentChanged(int index)
244{
245  QWidget* tab = myTabs->widget(index);
246  tab->setFocus();  // prevents users from accidentally typing in the wrong widget
247  updateTitle(tab);
248  clearEvents(tab);
249}
250
251void UserEventTabDlg::moveLeft()
252{
253  myTabs->setPreviousPage();
254}
255
256void UserEventTabDlg::moveRight()
257{
258  myTabs->setNextPage();
259}
260
261void UserEventTabDlg::removeTab(QWidget* tab)
262{
263  if (myTabs->count() > 1)
264  {
265    int index = myTabs->indexOf(tab);
266    myTabs->removeTab(index);
267    tab->close();
268    tab->setEnabled(false);
269    tab->deleteLater();
270  }
271  else
272    close();
273}
274
275void UserEventTabDlg::setMsgWinSticky(bool sticky)
276{
277  Support::changeWinSticky(winId(), sticky);
278}
279
280void UserEventTabDlg::updateTitle(QWidget* tab)
281{
282  QString title = tab->windowTitle();
283  if (!title.isEmpty())
284    setWindowTitle(title);
285
286  QIcon icon = myTabs->tabIcon(myTabs->indexOf(tab));
287  if (!icon.isNull())
288    setWindowIcon(icon);
289}
290
291void UserEventTabDlg::clearEvents(QWidget* tab)
292{
293  if (!isActiveWindow())
294    return;
295
296  UserSendCommon* e = dynamic_cast<UserSendCommon*>(tab);
297  QTimer::singleShot(e->clearDelay, e, SLOT(clearNewEvents()));
298}
299
300void UserEventTabDlg::saveGeometry()
301{
302  Config::Chat::instance()->setDialogRect(geometry());
303}
304
305void UserEventTabDlg::moveEvent(QMoveEvent* /* e */)
306{
307  saveGeometry();
308}
309
310void UserEventTabDlg::resizeEvent(QResizeEvent* /* e */)
311{
312  saveGeometry();
313}
Note: See TracBrowser for help on using the browser.