hint_manager.cpp 24.3 KB
Newer Older
1 2
/*
 * %kadu copyright begin%
3 4
 * Copyright 2008, 2009, 2010, 2010, 2011, 2011, 2012 Piotr Galiszewski (piotr.galiszewski@kadu.im)
 * Copyright 2009, 2010, 2012 Wojciech Treter (juzefwt@gmail.com)
Rafał Malinowski's avatar
Rafał Malinowski committed
5 6 7
 * Copyright 2008, 2009 Tomasz Rostański (rozteck@interia.pl)
 * Copyright 2011 Piotr Dąbrowski (ultr@ultr.pl)
 * Copyright 2011 Sławomir Stępień (s.stepien@interia.pl)
8
 * Copyright 2008 Michał Podsiadlik (michal@kadu.net)
Rafał Malinowski's avatar
Rafał Malinowski committed
9 10
 * Copyright 2009, 2010 Maciej Płaza (plaza.maciej@gmail.com)
 * Copyright 2009, 2009 Bartłomiej Zimoń (uzi18@o2.pl)
11
 * Copyright 2004 Roman Krzystyniak (Ron_K@tlen.pl)
Rafał Malinowski's avatar
Rafał Malinowski committed
12
 * Copyright 2004 Adrian Smarzewski (adrian@kadu.net)
13
 * Copyright 2005 Paweł Płuciennik (pawel_p@kadu.net)
14 15
 * Copyright 2007, 2008, 2009, 2010, 2011, 2013, 2014 Rafał Malinowski (rafal.przemyslaw.malinowski@gmail.com)
 * Copyright 2010, 2011, 2012, 2013, 2014 Bartosz Brachaczek (b.brachaczek@gmail.com)
Rafał Malinowski's avatar
Rafał Malinowski committed
16
 * Copyright 2004, 2005, 2006 Marcin Ślusarz (joi@kadu.net)
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 * %kadu copyright end%
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
32

33 34 35 36 37
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QVBoxLayout>
38

39
#include "chat/chat-manager.h"
40
#include "configuration/configuration.h"
41
#include "configuration/deprecated-configuration-api.h"
Rafał Malinowski's avatar
Rafał Malinowski committed
42
#include "contacts/contact.h"
43
#include "core/application.h"
44
#include "core/core.h"
45
#include "gui/widgets/chat-widget/chat-widget-manager.h"
Rafał Malinowski's avatar
Rafał Malinowski committed
46
#include "gui/widgets/tool-tip-class-manager.h"
47
#include "message/message-manager.h"
48
#include "message/sorted-messages.h"
49
#include "message/unread-message-repository.h"
50 51
#include "misc/misc.h"
#include "notify/notification-manager.h"
Rafał Malinowski's avatar
Rafał Malinowski committed
52
#include "notify/notification/chat-notification.h"
53
#include "parser/parser.h"
54

Rafał Malinowski's avatar
Rafał Malinowski committed
55
#include "icons/icons-manager.h"
56
#include "activate.h"
57
#include "debug.h"
Kermit's avatar
Kermit committed
58
#include "hints-configuration-ui-handler.h"
59 60 61 62
#include "hints_configuration_widget.h"

#include "hint_manager.h"

63 64 65 66 67 68

/**
 * @ingroup hints
 * @{
 */
#define FRAME_WIDTH 1
69
#define BORDER_RADIUS 0
70

71
HintManager::HintManager(QObject *parent) :
72
		Notifier("Hints", "Hints", KaduIcon("kadu_icons/notify-hints"), parent), AbstractToolTip(),
73
		hint_timer(new QTimer(this)),
74
		tipFrame(0), hints()
75 76
{
	kdebugf();
77 78 79

	createDefaultConfiguration();

80
#ifdef Q_OS_MAC
81
	frame = new QFrame(0, Qt::FramelessWindowHint | Qt::SplashScreen | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint |Qt::MSWindowsOwnDC);
82
#else
83
	frame = new QFrame(0, Qt::FramelessWindowHint | Qt::Tool | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint |Qt::MSWindowsOwnDC);
84
#endif
85
	frame->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
86

87 88
	layout = new QVBoxLayout(frame);
	layout->setSpacing(0);
Piotr Henryk Dabrowski's avatar
Piotr Henryk Dabrowski committed
89
	layout->setMargin(0);
90 91

	connect(hint_timer, SIGNAL(timeout()), this, SLOT(oneSecond()));
92
	connect(ChatManager::instance(), SIGNAL(chatUpdated(Chat)), this, SLOT(chatUpdated(Chat)));
93

94 95 96
	const QString default_hints_syntax(QT_TRANSLATE_NOOP("HintManager", "<table>"
"<tr>"
"<td align=\"left\" valign=\"top\">"
97
"<img style=\"max-width:64px; max-height:64px;\" "
98
"src=\"{#{avatarPath} #{avatarPath}}{~#{avatarPath} @{kadu_icons/kadu:64x64}}\""
99 100 101 102
">"
"</td>"
"<td width=\"100%\">"
"<div>[<b>%a</b>][&nbsp;<b>(%g)</b>]</div>"
103 104 105
"[<div><img height=\"16\" width=\"16\" src=\"#{statusIconPath}\">&nbsp;&nbsp;%u</div>]"
"[<div><img height=\"16\" width=\"16\" src=\"@{phone:16x16}\">&nbsp;&nbsp;%m</div>]"
"[<div><img height=\"16\" width=\"16\" src=\"@{mail-message-new:16x16}\">&nbsp;&nbsp;%e</div>]"
106 107 108 109
"</td>"
"</tr>"
"</table>"
"[<hr><b>%s</b>][<b>:</b><br><small>%d</small>]"));
110 111
	if (Application::instance()->configuration()->deprecatedApi()->readEntry("Hints", "MouseOverUserSyntax").isEmpty())
		Application::instance()->configuration()->deprecatedApi()->writeEntry("Hints", "MouseOverUserSyntax", default_hints_syntax);
112

113
	connect(this, SIGNAL(searchingForTrayPosition(QPoint &)), Core::instance(), SIGNAL(searchingForTrayPosition(QPoint &)));
114

115
	NotificationManager::instance()->registerNotifier(this);
116 117
	ToolTipClassManager::instance()->registerToolTipClass(QT_TRANSLATE_NOOP("@default", "Hints"), this);

118 119 120
	configurationUpdated();

	// remember to call it after setting `Style' member
121
	UiHandler = new HintsConfigurationUiHandler(Style, this);
122

123 124 125 126 127 128 129
	kdebugf2();
}

HintManager::~HintManager()
{
	kdebugf();

130 131
	hint_timer->stop();

132
	ToolTipClassManager::instance()->unregisterToolTipClass("Hints");
133
	NotificationManager::instance()->unregisterNotifier(this);
134

135 136
	disconnect();
	disconnect(ChatManager::instance(), 0, this, 0);
137

138 139
	delete tipFrame;
	tipFrame = 0;
140 141 142 143 144 145 146 147 148 149 150 151 152 153

	delete frame;
	frame = 0;

	kdebugf2();
}

void HintManager::hintUpdated()
{
	setHint();
}

void HintManager::configurationUpdated()
{
154
	Style = QString("Hint {border-width: %1px; border-style: solid; border-color: %2; border-radius: %3px;}")
155 156
			.arg(Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "AllEvents_borderWidth", FRAME_WIDTH))
			.arg(Application::instance()->configuration()->deprecatedApi()->readColorEntry("Hints", "AllEvents_bdcolor").name())
157
			.arg(BORDER_RADIUS);
158
	frame->setStyleSheet(Style);
159

160
	Opacity = Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "AllEvents_transparency", 0);
161
	Opacity = 1 - Opacity/100;
162

163 164 165 166 167 168 169 170 171 172 173 174 175 176
	setHint();
}

void HintManager::setHint()
{
	kdebugf();

	if (hints.isEmpty())
	{
		hint_timer->stop();
		frame->hide();
		return;
	}

177 178
	int minimumWidth = Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "MinimumWidth", 285);
	int maximumWidth = Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "MaximumWidth", 500);
179

180 181 182
	minimumWidth = minimumWidth >= 285 ? minimumWidth : 285;
	maximumWidth = maximumWidth >= 285 ? maximumWidth : 285;

183 184 185
	QPoint newPosition;
	QPoint trayPosition;

186
	frame->adjustSize();
187
	QSize preferredSize = frame->sizeHint();
188 189 190 191
	if (preferredSize.width() < minimumWidth)
		preferredSize.setWidth(minimumWidth);
	if (preferredSize.width() > maximumWidth)
		preferredSize.setWidth(maximumWidth);
192 193 194
	QSize desktopSize = QApplication::desktop()->screenGeometry(frame).size();

	emit searchingForTrayPosition(trayPosition);
195
	if (Application::instance()->configuration()->deprecatedApi()->readBoolEntry("Hints", "UseUserPosition") || trayPosition.isNull())
196
	{
197
		newPosition = QPoint(Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "HintsPositionX"), Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "HintsPositionY"));
198

199
//		kdebugm(KDEBUG_INFO, "%d %d %d\n", Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "Corner"), preferredSize.width(), preferredSize.height());
200
		switch(Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "Corner"))
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
		{
			case 1: // "TopRight"
				newPosition -= QPoint(preferredSize.width(), 0);
				break;
			case 2: // "BottomLeft"
				newPosition -= QPoint(0, preferredSize.height());
				break;
			case 3: // "BottomRight"
				newPosition -= QPoint(preferredSize.width(), preferredSize.height());
				break;
			case 0: // "TopLeft"
				break;
		};

		if (newPosition.x() < 0) // when hints go out of the screen (on left)
			newPosition.setX(0);
		if (newPosition.y() < 0) //when hints go out of the screen (on top)
			newPosition.setY(0);

		if (newPosition.x() + preferredSize.width() >= desktopSize.width()) //when hints go out of the screen (on right)
			newPosition.setX(desktopSize.width() - preferredSize.width());
		if (newPosition.y() + preferredSize.height() >= desktopSize.height()) //when hints go out of the screen (on bottom)
			newPosition.setY(desktopSize.height() - preferredSize.height());
	}
	else
	{
		// those "strange" cases happens when "automatic panel hiding" is in use
		if (trayPosition.x() < 0)
			trayPosition.setX(0);
		else if (trayPosition.x() > desktopSize.width())
			trayPosition.setX(desktopSize.width() - 2);
		if (trayPosition.y() < 0)
			trayPosition.setY(0);
		else if (trayPosition.y() > desktopSize.height())
			trayPosition.setY(desktopSize.height() - 2);


		if (trayPosition.x() < desktopSize.width() / 2) // tray is on left
			newPosition.setX(trayPosition.x() + 32);
		else // tray is on right
			newPosition.setX(trayPosition.x() - preferredSize.width());

		if (trayPosition.y() < desktopSize.height() / 2) // tray is on top
			newPosition.setY(trayPosition.y() + 32);
		else // tray is on bottom
			newPosition.setY(trayPosition.y() - preferredSize.height());
	}

249
	frame->setWindowOpacity(Opacity);
250 251 252 253
	// Only setFixedSize() and move() (in this order) guarantees correct
	// placement on all platforms (at least those I tested).
	frame->setFixedSize(preferredSize);
	frame->move(newPosition);
254 255 256 257 258

	if (frame->isVisible())
		frame->update();
	else
		frame->show();
259

260 261 262 263 264 265 266
	kdebugf2();
}

void HintManager::deleteHint(Hint *hint)
{
	kdebugf();

Juzef's avatar
Juzef committed
267 268
	Notification *notification = hint->getNotification();

269
	DisplayedNotifications.removeAll(hint->getNotification()->identifier());
270
	hints.removeAll(hint);
271

272
	layout->removeWidget(hint);
Juzef's avatar
Juzef committed
273

274
	hint->deleteLater();
Juzef's avatar
Juzef committed
275
	notification->release(this);
276

277 278 279 280 281 282
	if (hints.isEmpty())
	{
		hint_timer->stop();
		frame->hide();
	}

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
	kdebugf2();
}

void HintManager::deleteHintAndUpdate(Hint *hint)
{
	deleteHint(hint);
	setHint();
}

void HintManager::oneSecond(void)
{
	kdebugf();

	bool removed = false;
	for (int i = 0; i < hints.count(); ++i)
	{
		hints.at(i)->nextSecond();

		if (hints.at(i)->isDeprecated())
		{
			deleteHint(hints.at(i));
			removed = true;
		}
	}

	if (removed)
		setHint();

	kdebugf2();
}

Kermit's avatar
Kermit committed
314 315 316 317 318 319
NotifierConfigurationWidget *HintManager::createConfigurationWidget(QWidget *parent)
{
	configurationWidget = new HintsConfigurationWidget(parent);
	return configurationWidget;
}

320 321
void HintManager::processButtonPress(const QString &buttonName, Hint *hint)
{
322
	kdebugmf(KDEBUG_FUNCTION_START, "%s\n", buttonName.toUtf8().constData());
323

324
	switch (Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", buttonName))
325 326 327 328 329 330
	{
		case 1:
			hint->acceptNotification();
			break;

		case 2:
331
			if (hint->chat() && Application::instance()->configuration()->deprecatedApi()->readBoolEntry("Hints", "DeletePendingMsgWhenHintDeleted"))
332
			{
333
				auto unreadMessages = Core::instance()->unreadMessageRepository()->unreadMessagesForChat(hint->chat());
334
				for (auto const &message : unreadMessages)
335
					Core::instance()->unreadMessageRepository()->removeUnreadMessage(message);
336
			}
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369

			hint->discardNotification();
			deleteHintAndUpdate(hint);
			break;

		case 3:
			deleteAllHints();
			setHint();
			break;
	}

	kdebugf2();
}

void HintManager::leftButtonSlot(Hint *hint)
{
	processButtonPress("LeftButton", hint);
}

void HintManager::rightButtonSlot(Hint *hint)
{
	processButtonPress("RightButton", hint);
}

void HintManager::midButtonSlot(Hint *hint)
{
	processButtonPress("MiddleButton", hint);
}

void HintManager::openChat(Hint *hint)
{
	kdebugf();

370
	if (!hint->chat())
371 372
		return;

373
	if (!Application::instance()->configuration()->deprecatedApi()->readBoolEntry("Hints", "OpenChatOnEveryNotification"))
374 375 376
		if ((hint->getNotification()->type() != "NewChat") && (hint->getNotification()->type() != "NewMessage"))
			return;

377
	Core::instance()->chatWidgetManager()->openChat(hint->chat(), OpenChatActivation::Activate);
378

379 380 381 382 383
	deleteHintAndUpdate(hint);

	kdebugf2();
}

384
void HintManager::chatUpdated(const Chat &chat)
385
{
386 387 388
	if (chat.unreadMessagesCount() > 0)
		return;

389
	foreach (Hint *h, hints)
390
	{
391
		if (h->chat() == chat && !h->requireManualClosing())
392 393 394 395 396 397 398 399 400 401 402
			deleteHint(h);
	}

	setHint();
}

void HintManager::deleteAllHints()
{
	kdebugf();
	hint_timer->stop();

403
	foreach (Hint *h, hints)
404
	{
405
		if (!h->requireManualClosing())
406 407
		{
			h->discardNotification();
408
			deleteHint(h);
409
		}
410 411 412 413 414 415 416 417 418 419 420 421
	}

	if (hints.isEmpty())
		frame->hide();

	kdebugf2();
}

Hint *HintManager::addHint(Notification *notification)
{
	kdebugf();

422 423
	if (DisplayedNotifications.contains(notification->identifier()))
	{
Rafał Malinowski's avatar
Rafał Malinowski committed
424 425
		for (auto hint : hints)
			if (hint->getNotification()->identifier() == notification->identifier())
426 427 428
			{
				//hope this refreshes this hint
				hint->notificationUpdated();
Rafał Malinowski's avatar
Rafał Malinowski committed
429
				return hint;
430 431
			}
	}
Juzef's avatar
Juzef committed
432

Rafał Malinowski's avatar
Rafał Malinowski committed
433
	notification->acquire(this);
434

Rafał Malinowski's avatar
Rafał Malinowski committed
435
	connect(notification, SIGNAL(closed(Notification *)), this, SLOT(notificationClosed(Notification *)));
436

Rafał Malinowski's avatar
Rafał Malinowski committed
437 438
	auto hint = new Hint(frame, notification);
	hints.append(hint);
439

Rafał Malinowski's avatar
Rafał Malinowski committed
440 441
	setLayoutDirection();
	layout->addWidget(hint);
442

Rafał Malinowski's avatar
Rafał Malinowski committed
443 444 445 446 447 448
	connect(hint, SIGNAL(leftButtonClicked(Hint *)), this, SLOT(leftButtonSlot(Hint *)));
	connect(hint, SIGNAL(rightButtonClicked(Hint *)), this, SLOT(rightButtonSlot(Hint *)));
	connect(hint, SIGNAL(midButtonClicked(Hint *)), this, SLOT(midButtonSlot(Hint *)));
	connect(hint, SIGNAL(closing(Hint *)), this, SLOT(deleteHintAndUpdate(Hint *)));
	connect(hint, SIGNAL(updated(Hint *)), this, SLOT(hintUpdated()));
	setHint();
449

Rafał Malinowski's avatar
Rafał Malinowski committed
450 451
	if (!hint_timer->isActive())
		hint_timer->start(1000);
452

Rafał Malinowski's avatar
Rafał Malinowski committed
453
	DisplayedNotifications.append(notification->identifier());
454 455 456 457 458 459 460 461

	return hint;
}

void HintManager::setLayoutDirection()
{
	kdebugf();
	QPoint trayPosition;
462
	QSize desktopSize = QApplication::desktop()->screenGeometry(frame).size();
463
	emit searchingForTrayPosition(trayPosition);
464
	switch (Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "NewHintUnder"))
465 466
	{
		case 0:
467
			if (trayPosition.isNull() || Application::instance()->configuration()->deprecatedApi()->readBoolEntry("Hints","UseUserPosition"))
468
			{
469
				if (Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints","HintsPositionY") < desktopSize.height()/2)
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
					layout->setDirection(QBoxLayout::Down);
				else
					layout->setDirection(QBoxLayout::Up);
			}
			else
			{
				if (trayPosition.y() < desktopSize.height()/2)
					layout->setDirection(QBoxLayout::Down);
				else
					layout->setDirection(QBoxLayout::Up);
			}
			break;
		case 1:
			layout->setDirection(QBoxLayout::Up);
			break;
		case 2:
			layout->setDirection(QBoxLayout::Down);
			break;
	}
	kdebugf2();
}

492
void HintManager::prepareOverUserHint(QFrame *tipFrame, QLabel *tipLabel, Talkable talkable)
493
{
494
	auto syntax = Application::instance()->configuration()->deprecatedApi()->readEntry("Hints", "MouseOverUserSyntax");
495
	// file:/// is added by parser where required
496
	syntax = syntax.remove("file:///");
497

498
	auto text = Parser::parse(syntax, talkable, ParserEscape::HtmlEscape);
499
	while (text.endsWith(QLatin1String("<br/>")))
500
		text.resize(text.length() - 5 /* 5 == QString("<br/>").length()*/);
501
	while (text.startsWith(QLatin1String("<br/>")))
502 503
		text = text.right(text.length() - 5 /* 5 == QString("<br/>").length()*/);

504 505 506 507
#ifdef Q_OS_UNIX
	text = text.remove("file://");
#endif

508
	tipLabel->setFont(Application::instance()->configuration()->deprecatedApi()->readFontEntry("Hints", "HintOverUser_font"));
509 510 511 512 513
	tipLabel->setText(text);

	tipFrame->setObjectName("tip_frame");
	QString style = QString("QFrame#tip_frame {border-width: %1px; border-style: solid; border-color: %2;"
				"border-radius: %3px; background-color: %4} QFrame { color: %5}")
514 515
			.arg(Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "HintOverUser_borderWidth", FRAME_WIDTH))
			.arg(Application::instance()->configuration()->deprecatedApi()->readColorEntry("Hints", "HintOverUser_bdcolor").name())
516
			.arg(BORDER_RADIUS)
517 518
			.arg(Application::instance()->configuration()->deprecatedApi()->readColorEntry("Hints", "HintOverUser_bgcolor").name())
			.arg(Application::instance()->configuration()->deprecatedApi()->readColorEntry("Hints", "HintOverUser_fgcolor").name());
519 520 521 522 523 524

	tipFrame->setStyleSheet(style);

	tipFrame->setFixedSize(tipLabel->sizeHint() + QSize(2 * FRAME_WIDTH, 2 * FRAME_WIDTH));
}

525
void HintManager::showToolTip(const QPoint &point, Talkable talkable)
526 527 528
{
	kdebugf();

529
	delete tipFrame;
530

531
#ifdef Q_OS_MAC
532
	tipFrame = new QFrame(0, Qt::FramelessWindowHint | Qt::SplashScreen | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint |Qt::MSWindowsOwnDC);
533
#else
534
	tipFrame = new QFrame(0, Qt::FramelessWindowHint | Qt::Tool | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint |Qt::MSWindowsOwnDC);
535
#endif
536 537 538 539

	QHBoxLayout *lay = new QHBoxLayout(tipFrame);
	lay->setMargin(10);
	lay->setSizeConstraint(QLayout::SetFixedSize);
540

541
	QLabel *tipLabel = new QLabel(tipFrame);
542
	tipLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
543
	tipLabel->setContentsMargins(10, 10, 10, 10);
544 545
	tipLabel->setTextFormat(Qt::RichText);
	tipLabel->setWordWrap(true);
546 547 548

	lay->addWidget(tipLabel);

549
	prepareOverUserHint(tipFrame, tipLabel, talkable);
550

551
	double opacity = Application::instance()->configuration()->deprecatedApi()->readNumEntry("Hints", "HintOverUser_transparency", 0);
552 553
	opacity = 1 - opacity/100;
	tipFrame->setWindowOpacity(opacity);
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583

	QPoint pos(point + QPoint(5, 5));

	QSize preferredSize = tipFrame->sizeHint();
	QSize desktopSize = QApplication::desktop()->screenGeometry(frame).size();
	if (pos.x() + preferredSize.width() > desktopSize.width())
		pos.setX(pos.x() - preferredSize.width() - 10);
	if (pos.y() + preferredSize.height() > desktopSize.height())
		pos.setY(pos.y() - preferredSize.height() - 10);

	tipFrame->move(pos);
	tipFrame->show();

	kdebugf2();
}

void HintManager::hideToolTip()
{
	if (tipFrame)
	{
		tipFrame->hide();
		tipFrame->deleteLater();
		tipFrame = 0;
	}
}

void HintManager::notify(Notification *notification)
{
	kdebugf();

584
	addHint(notification);
585 586 587 588 589 590

	kdebugf2();
}

void HintManager::notificationClosed(Notification *notification)
{
591
	Q_UNUSED(notification)
592 593 594 595
}

void HintManager::createDefaultConfiguration()
{
596
	// TODO: this should be more like: if (plugins.loaded(freedesktop_notify) && this_is_first_time_we_are_loaded_or_whatever)
597
#if !defined(Q_OS_UNIX) || defined(Q_OS_MAC)
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "ConnectionError_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "NewChat_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "NewMessage_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "StatusChanged_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "StatusChanged/ToFreeForChat_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "StatusChanged/ToOnline_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "StatusChanged/ToAway_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "StatusChanged/ToNotAvailable_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "StatusChanged/ToDoNotDisturb_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "StatusChanged/ToOffline_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "FileTransfer_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "FileTransfer/IncomingFile_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "FileTransfer/Finished_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "multilogon_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "multilogon/sessionConnected_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "multilogon/sessionDisconnected_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "Roster/ImportFailed_UseCustomSettings", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "Roster/ImportFailed_Hints", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "Roster/ExportFailed_UseCustomSettings", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Notify", "Roster/ExportFailed_Hints", true);
618
#endif
619

620 621 622
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "CiteSign", 50);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "Corner", 0);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "DeletePendingMsgWhenHintDeleted", true);
623

624 625 626 627 628
	//TODO:
	QStringList events;
	events << "ConnectionError" << "NewChat" << "NewMessage" << "StatusChanged"
		<<"StatusChanged/ToFreeForChat" << "StatusChanged/ToOnline"  << "StatusChanged/ToAway"
		<< "StatusChanged/ToNotAvailable"<< "StatusChanged/ToDoNotDisturb" << "StatusChanged/ToOffline"
629
		<< "FileTransfer" << "FileTransfer/IncomingFile" << "FileTransfer/Finished" << "InvalidPassword";
630 631
	foreach (const QString &event, events)
	{
632 633 634 635
		Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "Event_" + event + "_bgcolor", qApp->palette().window().color());
		Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "Event_" + event + "_fgcolor",qApp->palette().windowText().color());
		Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "Event_" + event + "_font", qApp->font());
		Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "Event_" + event + "_timeout", 10);
636
	}
637

638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintsPositionX", 0);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintsPositionY", 0);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "LeftButton", 1);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "RightButton", 2);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "MaximumWidth", 500);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "MiddleButton", 3);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "MinimumWidth", 285);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "MouseOverUserSyntax", QString());
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "NewHintUnder", 0);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "ShowContentMessage", true);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "UseUserPosition", false);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "OpenChatOnEveryNotification", false);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "MarginSize", 2);

	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "AllEvents_transparency", 0);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "AllEvents_iconSize", 32);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "AllEvents_borderWidth", FRAME_WIDTH);

	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintOverUser_transparency", 0);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintOverUser_iconSize", 32);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintOverUser_borderWidth", FRAME_WIDTH);
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintOverUser_bdcolor", qApp->palette().window().color());
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintOverUser_bgcolor", qApp->palette().window().color());
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintOverUser_fgcolor", qApp->palette().windowText().color());
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintOverUser_font", qApp->font());
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintOverUser_Geometry", "50, 50, 640, 610");
	Application::instance()->configuration()->deprecatedApi()->addVariable("Hints", "HintEventConfiguration_Geometry", "50, 50, 520, 345");
665 666
}

667
HintManager *hint_manager = NULL;
Bartosz Brachaczek's avatar
Bartosz Brachaczek committed
668 669

#include "moc_hint_manager.cpp"