root/trunk/qt4-gui/src/dialogs/awaymsgdlg.cpp

Revision 6466, 8.4 kB (checked in by flynd, 4 months ago)

Use const pointer for owner objects that are fetched only for read access.

  • Property svn:eol-style set to native
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of Licq, an instant messaging client for UNIX.
4 * Copyright (C) 1999-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// written by Graham Roff <graham@licq.org>
22// enhanced by Dirk A. Mueller <dmuell@gmx.net>
23// -----------------------------------------------------------------------------
24
25#include "awaymsgdlg.h"
26
27#include <QCloseEvent>
28#include <QDialogButtonBox>
29#include <QEvent>
30#include <QHBoxLayout>
31#include <QMenu>
32#include <QPushButton>
33#include <QTextCodec>
34#include <QTimer>
35#include <QVBoxLayout>
36
37#include <licq_icqd.h>
38#include <licq_log.h>
39#include <licq_sar.h>
40#include <licq_user.h>
41
42#include "core/licqgui.h"
43
44#include "helpers/licqstrings.h"
45#include "helpers/support.h"
46#include "helpers/usercodec.h"
47
48#include "settings/settingsdlg.h"
49
50#include "widgets/mledit.h"
51
52#include "hintsdlg.h"
53
54using namespace LicqQtGui;
55/* TRANSLATOR LicqQtGui::AwayMsgDlg */
56
57AwayMsgDlg* AwayMsgDlg::myInstance = NULL;
58
59void AwayMsgDlg::showAwayMsgDlg(unsigned short status, bool autoClose,
60    unsigned long ppid, bool invisible, bool setStatus)
61{
62  if (myInstance == NULL)
63    myInstance = new AwayMsgDlg();
64  else
65    myInstance->raise();
66
67  myInstance->selectAutoResponse(status, autoClose, ppid, invisible, setStatus);
68}
69
70AwayMsgDlg::AwayMsgDlg(QWidget* parent)
71  : QDialog(parent),
72    myAutoCloseCounter(-1)
73{
74  Support::setWidgetProps(this, "AwayMessageDialog");
75  setAttribute(Qt::WA_DeleteOnClose, true);
76
77  installEventFilter(this);
78
79  QVBoxLayout* top_lay = new QVBoxLayout(this);
80
81  myAwayMsg = new MLEdit(true);
82  myAwayMsg->setSizeHintLines(5);
83  connect(myAwayMsg, SIGNAL(clicked()), SLOT(autoCloseStop()));
84  connect(myAwayMsg, SIGNAL(ctrlEnterPressed()), SLOT(ok()));
85  myAwayMsg->installEventFilter(this);
86  top_lay->addWidget(myAwayMsg);
87
88  myMenu = new QMenu(this);
89  connect(myMenu, SIGNAL(aboutToShow()), SLOT(autoCloseStop()));
90
91  myButtons = new QDialogButtonBox(
92      QDialogButtonBox::Ok |
93      QDialogButtonBox::Cancel |
94      QDialogButtonBox::Help);
95
96  myButtons->button(QDialogButtonBox::Help)->setText(tr("&Hints"));
97  myButtons->addButton(tr("&Select"), QDialogButtonBox::ActionRole)->setMenu(myMenu);
98
99  connect(myButtons, SIGNAL(accepted()), SLOT(ok()));
100  connect(myButtons, SIGNAL(rejected()), SLOT(close()));
101  connect(myButtons, SIGNAL(helpRequested()), SLOT(autoCloseStop()));
102  connect(myButtons, SIGNAL(helpRequested()), SLOT(hints()));
103
104  myOkText = myButtons->button(QDialogButtonBox::Ok)->text();
105
106  top_lay->addWidget(myButtons);
107}
108
109AwayMsgDlg::~AwayMsgDlg()
110{
111  myInstance = NULL;
112}
113
114void AwayMsgDlg::selectAutoResponse(unsigned short status, bool autoClose,
115    unsigned long ppid, bool invisible, bool setStatus)
116{
117  switch (status & 0x00FF)
118  {
119    case ICQ_STATUS_ONLINE: // Fall through
120    case ICQ_STATUS_OFFLINE:
121      status = (status & 0xFF00) | ICQ_STATUS_AWAY;
122      break;
123  }
124
125  myStatus = status;
126  myInvisible = invisible;
127  myPpid = ppid;
128  mySetStatus = setStatus;
129
130  // Fill in the select menu
131  myMenu->clear();
132  switch (myStatus)
133  {
134    case ICQ_STATUS_NA:
135      mySAR = SAR_NA;
136      break;
137    case ICQ_STATUS_OCCUPIED:
138      mySAR = SAR_OCCUPIED;
139      break;
140    case ICQ_STATUS_DND:
141      mySAR = SAR_DND;
142      break;
143    case ICQ_STATUS_FREEFORCHAT:
144      mySAR = SAR_FFC;
145      break;
146    case ICQ_STATUS_AWAY: // Fall through
147    default:
148      mySAR = SAR_AWAY;
149  }
150
151  if (mySAR >= 0)
152  {
153    SARList& sar = gSARManager.Fetch(mySAR);
154    for (unsigned i = 0; i < sar.size(); i++)
155    {
156      QAction* a = myMenu->addAction(
157          QString::fromLocal8Bit(sar[i]->Name()),
158          this, SLOT(selectMessage()));
159      a->setData(i);
160    }
161    gSARManager.Drop();
162  }
163
164  myMenu->addSeparator();
165  QAction* a = myMenu->addAction(tr("&Edit Items"), this, SLOT(selectMessage()));
166  a->setData(999);
167
168  const ICQOwner* o = gUserManager.FetchOwner(LICQ_PPID, LOCK_R);
169  if (o == NULL)
170    return;
171
172  setWindowTitle(QString(tr("Set %1 Response for %2"))
173      .arg(LicqStrings::getStatus(myStatus, false))
174      .arg(QString::fromUtf8(o->GetAlias())));
175
176  QTextCodec* codec = UserCodec::defaultEncoding();
177  if (*o->AutoResponse())
178    myAwayMsg->setText(codec->toUnicode(o->AutoResponse()));
179  else
180    myAwayMsg->setText(tr("I'm currently %1, %a.\n"
181          "You can leave me a message.\n"
182          "(%m messages pending from you).")
183        .arg(LicqStrings::getStatus(myStatus, false)));
184  gUserManager.DropOwner(o);
185
186  myAwayMsg->setFocus();
187  QTimer::singleShot(0, myAwayMsg, SLOT(selectAll()));
188
189  if (autoClose)
190  {
191    myAutoCloseCounter = 9;
192    autoCloseTick();
193  }
194
195  if (!isVisible())
196    show();
197}
198
199void AwayMsgDlg::showAutoResponseHints(QWidget* parent)
200{
201  QString h = tr(
202    "<h2>Hints for Setting<br>your Auto-Response</h2><hr>"
203    "<ul>"
204    "<li>You can include any of the % expansions (described in the main hints page).</li>"
205
206    "<li>Any line beginning with a pipe (|) will be treated as a command "
207    "to be run.  The line will be replaced by the output of the command. "
208    "The command is parsed by /bin/sh so any shell commands or meta-characters "
209    "are allowed.  For security reasons, any % expansions are automatically "
210    "passed to the command surrounded by single quotes to prevent shell parsing "
211    "of any meta-characters included in an alias.<br>"
212    "Examples of popular uses include:"
213    "<ul>"
214    "<li><tt>|date</tt>: Will replace that line by the current date</li>"
215    "<li><tt>|fortune</tt>: Show a fortune, as a tagline for example</li>"
216    "<li><tt>|myscript.sh %u %a</tt>: Run a script, passing the uin and alias</li>"
217    "<li><tt>|myscript.sh %u %a > /dev/null</tt>: Run the same script but ignore the output"
218        " (for tracking auto response checks or something)</li>"
219    "<li><tt>|if [ %u -lt 100000 ]; then echo \"You are special\"; fi</tt>"
220        ": Useless, but shows how you can use shell script.</li>"
221    "</ul>"
222    "Of course, multiple \"|\" can appear in the auto response, and commands and regular "
223    "text can be mixed line by line.</li>"
224
225    "<hr><p> For more information, see the Licq webpage (<tt>http://www.licq.org</tt>).</p>");
226
227  new HintsDlg(h, parent);
228}
229
230bool AwayMsgDlg::eventFilter(QObject* /* watched */, QEvent* event)
231{
232  if (event->type() == QEvent::KeyPress ||
233      event->type() == QEvent::MouseButtonPress ||
234      event->type() == QEvent::Shortcut)
235    autoCloseStop();
236
237  return false;
238}
239
240void AwayMsgDlg::ok()
241{
242  myAutoCloseCounter = -1;
243
244  if (mySetStatus)
245  {
246    if (myPpid == 0)
247      LicqGui::instance()->changeStatus(myStatus, myInvisible);
248    else
249      LicqGui::instance()->changeStatus(myStatus, myPpid, myInvisible);
250  }
251
252  QString s = myAwayMsg->toPlainText().trimmed();
253
254  ICQOwner* o = gUserManager.FetchOwner(LICQ_PPID, LOCK_W);
255  if (o != NULL)
256  {
257    QTextCodec* codec = UserCodec::defaultEncoding();
258    o->SetAutoResponse(codec->fromUnicode(s));
259    gUserManager.DropOwner(o);
260  }
261
262  close();
263}
264
265void AwayMsgDlg::autoCloseTick()
266{
267  if (myAutoCloseCounter >= 0)
268  {
269    myButtons->button(QDialogButtonBox::Ok)->
270      setText(tr("(Closing in %1)").arg(myAutoCloseCounter--));
271
272    if (myAutoCloseCounter < 0)
273      ok();
274    else
275      QTimer::singleShot(1000, this, SLOT(autoCloseTick()));
276  }
277}
278
279void AwayMsgDlg::autoCloseStop()
280{
281  if (myAutoCloseCounter >= 0)
282  {
283     myAutoCloseCounter = -1;
284     myButtons->button(QDialogButtonBox::Ok)->setText(myOkText);
285  }
286}
287
288void AwayMsgDlg::hints()
289{
290  showAutoResponseHints(this);
291}
292
293void AwayMsgDlg::selectMessage()
294{
295  QAction* a = qobject_cast<QAction*>(sender());
296  if (a == NULL)
297    return;
298
299  unsigned int result = a->data().toUInt();
300
301  if (result == 999) // User chose "Edit Items"
302    SettingsDlg::show(SettingsDlg::RespMsgPage);
303  else
304  {
305    SARList& sar = gSARManager.Fetch(mySAR);
306    if (result < sar.size())
307      myAwayMsg->setText(QString::fromLocal8Bit(sar[result]->AutoResponse()));
308
309    gSARManager.Drop();
310  }
311}
Note: See TracBrowser for help on using the browser.