2
* wbdlg.cpp - dialog for whiteboarding
3
* Copyright (C) 2006 Joonas Govenius
5
* Originally developed from:
6
* chatdlg.cpp - dialog for handling chats
7
* Copyright (C) 2001, 2002 Justin Karneges
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License
11
* as published by the Free Software Foundation; either version 2
12
* of the License, or (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this library; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
#include <QMessageBox>
28
#include <QHBoxLayout>
29
#include <QVBoxLayout>
30
#include <QColorDialog>
32
#include "accountlabel.h"
33
#include "stretchwidget.h"
36
//----------------------------------------------------------------------------
38
//----------------------------------------------------------------------------
40
WbDlg::WbDlg(SxeSession* session, PsiAccount* pa) {
41
if ( PsiOptions::instance()->getOption("options.ui.mac.use-brushed-metal-windows").toBool() )
42
setAttribute(Qt::WA_MacMetalStyle);
44
groupChat_ = session->groupChat();
51
QVBoxLayout *vb1 = new QVBoxLayout(this);
54
le_jid_ = new QLineEdit(this);
55
le_jid_->setReadOnly(true);
56
le_jid_->setFocusPolicy(Qt::NoFocus);
57
le_jid_->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
58
lb_ident_ = new AccountLabel(this);
59
lb_ident_->setAccount(pa);
60
lb_ident_->setShowJid(false);
61
lb_ident_->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
62
QHBoxLayout *hb1 = new QHBoxLayout();
63
hb1->addWidget(le_jid_);
64
hb1->addWidget(lb_ident_);
68
wbWidget_ = new WbWidget(session, this);
69
wbWidget_->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
70
vb1->addWidget(wbWidget_);
73
act_save_ = new IconAction(tr("Save session"), "psi/save", tr("Save the contents of the whiteboard"), 0, this );
74
act_geometry_ = new IconAction(tr("Change the geometry"), "psi/whiteboard", tr("Change the geometry"), 0, this );
75
act_clear_ = new IconAction(tr("End session"), "psi/clearChat", tr("Clear the whiteboard"), 0, this );
76
act_end_ = new IconAction(tr("End session"), "psi/closetab", tr("End session"), 0, this );
78
// Black is the default color
79
QPixmap pixmap(16, 16);
80
pixmap.fill(QColor(Qt::black));
81
act_color_ = new QAction(QIcon(pixmap), tr("Stroke color"), this);
82
pixmap.fill(QColor(Qt::lightGray));
83
act_fill_ = new QAction(QIcon(pixmap), tr("Fill color"), this);
85
act_widths_ = new IconAction(tr("Stroke width" ), "psi/drawPaths", tr("Stroke width"), 0, this );
86
act_modes_ = new IconAction(tr("Edit mode" ), "psi/select", tr("Edit mode"), 0, this );
87
group_widths_ = new QActionGroup(this);
88
group_modes_ = new QActionGroup(this);
90
connect(act_color_, SIGNAL(triggered()), SLOT(setStrokeColor()));
91
connect(act_fill_, SIGNAL(triggered()), SLOT(setFillColor()));
92
connect(group_widths_, SIGNAL(triggered(QAction *)), SLOT(setStrokeWidth(QAction *)));
93
connect(group_modes_, SIGNAL(triggered(QAction *)), SLOT(setMode(QAction *)));
94
connect(act_save_, SIGNAL(activated()), SLOT(save()));
95
connect(act_geometry_, SIGNAL(activated()), SLOT(setGeometry()));
96
connect(act_clear_, SIGNAL(activated()), wbWidget_, SLOT(clear()));
97
connect(act_end_, SIGNAL(activated()), SLOT(endSession()));
99
pixmap = QPixmap(2, 2);
100
pixmap.fill(QColor(Qt::black));
101
QAction* widthaction = new QAction(QIcon(pixmap), tr("Thin stroke"), group_widths_);
102
widthaction->setData(QVariant(1));
103
widthaction->setCheckable(true);
104
widthaction->trigger();
105
pixmap = QPixmap(6, 6);
106
pixmap.fill(QColor(Qt::black));
107
widthaction = new QAction(QIcon(pixmap), tr("Medium stroke"), group_widths_);
108
widthaction->setData(QVariant(3));
109
widthaction->setCheckable(true);
110
pixmap = QPixmap(12, 12);
111
pixmap.fill(QColor(Qt::black));
112
widthaction = new QAction(QIcon(pixmap), tr("Thick stroke"), group_widths_);
113
widthaction->setData(QVariant(6));
114
widthaction->setCheckable(true);
117
action = new IconAction(tr("Select"), "psi/select", tr("Select"), 0, group_modes_ );
118
action->setData(QVariant(WbWidget::Select));
119
action->setCheckable(true);
120
action = new IconAction(tr( "Translate"), "psi/translate", tr("Translate"), 0, group_modes_ );
121
action->setData(QVariant(WbWidget::Translate));
122
action->setCheckable(true);
123
action = new IconAction(tr( "Rotate"), "psi/rotate", tr("Rotate"), 0, group_modes_ );
124
action->setData(QVariant(WbWidget::Rotate));
125
action->setCheckable(true);
126
action = new IconAction(tr( "Scale"), "psi/scale", tr("Scale"), 0, group_modes_ );
127
action->setData(QVariant(WbWidget::Scale));
128
action->setCheckable(true);
129
action = new IconAction(tr( "Erase"), "psi/erase", tr("Erase"), 0, group_modes_ );
130
action->setData(QVariant(WbWidget::Erase));
131
action->setCheckable(true);
132
QAction *separator = new QAction(group_modes_);
133
separator->setSeparator(true);
134
action = new IconAction(tr( "Scroll view"), "psi/scroll", tr("Scroll"), 0, group_modes_ );
135
action->setData(QVariant(WbWidget::Scroll));
136
action->setCheckable(true);
137
separator = new QAction(group_modes_);
138
separator->setSeparator(true);
139
action = new IconAction(tr( "Draw paths"), "psi/drawPaths", tr("Draw paths"), 0, group_modes_ );
140
action->setData(QVariant(WbWidget::DrawPath));
141
action->setCheckable(true);
143
// action = new IconAction(tr( "Draw lines"), "psi/drawLines", tr("Draw lines"), 0, group_modes_ );
144
// action->setData(QVariant(WbWidget::DrawLine));
145
// action->setCheckable(true);
146
// action = new IconAction(tr( "Draw ellipses"), "psi/drawEllipses", tr("Draw ellipses"), 0, group_modes_ );
147
// action->setData(QVariant(WbWidget::DrawEllipse));
148
// action->setCheckable(true);
149
// action = new IconAction(tr( "Draw circles"), "psi/drawCircles", tr("Draw circles"), 0, group_modes_ );
150
// action->setData(QVariant(WbWidget::DrawCircle));
151
// action->setCheckable(true);
152
// action = new IconAction(tr( "Draw rectangles"), "psi/drawRectangles", tr("Draw rectangles"), 0, group_modes_ );
153
// action->setData(QVariant(WbWidget::DrawRectangle));
154
// action->setCheckable(true);
155
// action = new IconAction(tr( "Add text"), "psi/addText", tr("Add text"), 0, group_modes_ );
156
// action->setData(QVariant(WbWidget::DrawText));
157
// action->setCheckable(true);
158
action = new IconAction(tr( "Add images"), "psi/addImage", tr("Add images"), 0, group_modes_ );
159
action->setData(QVariant(WbWidget::DrawImage));
160
action->setCheckable(true);
162
menu_widths_ = new QMenu(this);
163
menu_widths_->addActions(group_widths_->actions());
164
act_widths_->setMenu(menu_widths_);
166
menu_modes_ = new QMenu(this);
167
menu_modes_->addActions(group_modes_->actions());
168
act_modes_->setMenu(menu_modes_);
170
toolbar_ = new QToolBar(tr("Whiteboard toolbar"), this);
171
toolbar_->setIconSize(QSize(16,16));
172
toolbar_->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
173
toolbar_->addAction(act_end_);
174
toolbar_->addAction(act_clear_);
175
toolbar_->addAction(act_save_);
176
toolbar_->addAction(act_geometry_);
177
toolbar_->addWidget(new StretchWidget(this));
178
toolbar_->addAction(act_fill_);
179
toolbar_->addAction(act_color_);
180
toolbar_->addAction(act_widths_);
181
toolbar_->addAction(act_modes_);
182
vb1->addWidget(toolbar_);
185
pm_settings_ = new QMenu(this);
186
connect(pm_settings_, SIGNAL(aboutToShow()), SLOT(buildMenu()));
188
X11WM_CLASS("whiteboard");
190
// set the Jid -> le_jid.
191
le_jid_->setText(QString("%1 (session: %2)").arg(session->target().full()).arg(session->session()));
192
le_jid_->setCursorPosition(0);
193
le_jid_->setToolTip(session->target().full());
195
// update the widget icon
197
setWindowIcon(IconsetFactory::icon("psi/whiteboard").icon());
200
setWindowOpacity(double(qMax(MINIMUM_OPACITY, PsiOptions::instance()->getOption("options.ui.chat.opacity").toInt())) / 100);
202
resize(PsiOptions::instance()->getOption("options.ui.chat.size").toSize());
206
// terminate the underlying SXE session
207
session()->endSession();
209
emit sessionEnded(this);
212
SxeSession* WbDlg::session() const {
213
return wbWidget_->session();
216
bool WbDlg::allowEdits() const {
220
void WbDlg::setAllowEdits(bool a) {
223
wbWidget_->setMode(WbWidget::Scroll);
226
void WbDlg::peerLeftSession(const Jid &peer) {
227
le_jid_->setText(tr("%1 left (session: %2).").arg(peer.full()).arg(session()->session()));
230
void WbDlg::endSession() {
231
if(sender() == act_end_) {
232
int n = QMessageBox::information(this, tr("Warning"), tr("Are you sure you want to end the session?\nThe contents of the whiteboard will be lost."), tr("&Yes"), tr("&No"));
236
setAttribute(Qt::WA_DeleteOnClose);
240
void WbDlg::activated() {
248
void WbDlg::keyPressEvent(QKeyEvent *e) {
249
if(e->key() == Qt::Key_Escape && !PsiOptions::instance()->getOption("options.ui.tabs.use-tabs").toBool())
251
else if(e->key() == Qt::Key_W && e->state() & Qt::ControlButton && !PsiOptions::instance()->getOption("options.ui.tabs.use-tabs").toBool())
257
void WbDlg::closeEvent(QCloseEvent *e) {
259
if(testAttribute(Qt::WA_DeleteOnClose))
262
int n = QMessageBox::information(this, tr("Warning"), tr("A new whiteboard message was just received.\nDo you still want to close the window?"), tr("&Yes"), tr("&No"));
269
// destroy the dialog if delChats is dcClose
270
if(PsiOptions::instance()->getOption("options.ui.chat.delete-contents-after").toString() == "instant")
273
if(PsiOptions::instance()->getOption("options.ui.chat.delete-contents-after").toString() == "hour")
275
else if(PsiOptions::instance()->getOption("options.ui.chat.delete-contents-after").toString() == "day")
276
setSelfDestruct(60 * 24);
280
void WbDlg::resizeEvent(QResizeEvent *e) {
281
if (PsiOptions::instance()->getOption("options.ui.remember-window-sizes").toBool()) {
282
PsiOptions::instance()->setOption("options.ui.chat.size", e->size());
286
void WbDlg::showEvent(QShowEvent *) {
290
void WbDlg::changeEvent(QEvent *e) {
291
if (e->type() == QEvent::ActivationChange && isActiveWindow()) {
297
void WbDlg::setStrokeColor() {
298
QColor newColor = QColorDialog::getColor();
299
if(newColor.isValid()) {
300
QPixmap pixmap(16, 16);
301
pixmap.fill(newColor);
302
act_color_->setIcon(QIcon(pixmap));
303
wbWidget_->setStrokeColor(newColor);
307
void WbDlg::setFillColor() {
308
QColor newColor = QColorDialog::getColor();
309
if(newColor.isValid()) {
310
QPixmap pixmap(16, 16);
311
pixmap.fill(newColor);
312
act_fill_->setIcon(QIcon(pixmap));
313
wbWidget_->setFillColor(newColor);
317
void WbDlg::setStrokeWidth(QAction *a) {
318
wbWidget_->setStrokeWidth(a->data().toInt());
321
void WbDlg::setMode(QAction *a) {
323
wbWidget_->setMode(WbWidget::Mode(a->data().toInt()));
325
wbWidget_->setMode(WbWidget::Scroll);
328
void WbDlg::setKeepOpenFalse() {
332
void WbDlg::buildMenu()
334
pm_settings_->clear();
335
pm_settings_->addAction(act_modes_);
336
pm_settings_->addAction(act_widths_);
337
pm_settings_->addAction(act_color_);
338
pm_settings_->insertSeparator();
339
pm_settings_->addAction(act_save_);
340
pm_settings_->addAction(act_clear_);
341
pm_settings_->addAction(act_end_);
344
void WbDlg::setGeometry() {
345
// TODO: make a proper dialog
349
size.setWidth(QInputDialog::getInteger(this, tr("Set new width:"), tr("Width:"), static_cast<int>(wbWidget_->scene()->sceneRect().width()), 10, 100000, 10, &ok));
353
size.setHeight(QInputDialog::getInteger(this, tr("Set new height:"), tr("Height:"), static_cast<int>(wbWidget_->scene()->sceneRect().height()), 10, 100000, 10, &ok));
357
wbWidget_->setSize(size);
361
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Whitebaord"),
363
tr("Scalable Vector Graphics (*.svg)"));
364
fileName = fileName.trimmed();
365
if(!fileName.endsWith(".svg", Qt::CaseInsensitive))
368
QFile file(fileName);
369
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
372
QTextStream stream(&file);
373
wbWidget_->session()->document().save(stream, 2);
378
void WbDlg::contextMenuEvent(QContextMenuEvent * e) {
379
pm_settings_->exec(QCursor::pos());
383
void WbDlg::setSelfDestruct(int minutes) {
386
delete selfDestruct_;
393
selfDestruct_ = new QTimer(this);
394
connect(selfDestruct_, SIGNAL(timeout()), SLOT(endSession()));
397
selfDestruct_->start(minutes * 60000);
400
void WbDlg::updateCaption() {
406
cap += QString("[%1] ").arg(pending_);
408
cap += session()->target().full();