summaryrefslogtreecommitdiffstats
path: root/src/kvirc/ui
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 02:13:59 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 02:13:59 +0000
commita6d58bb6052ac8cb01805a48c4ad2f129126116f (patch)
treedd867a099fcbb263a8009a9fb22695b87855dad6 /src/kvirc/ui
downloadkvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.tar.gz
kvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.zip
Added KDE3 version of kvirc
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kvirc@1095341 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/kvirc/ui')
-rw-r--r--src/kvirc/ui/Makefile.am5
-rw-r--r--src/kvirc/ui/kvi_actiondrawer.cpp227
-rw-r--r--src/kvirc/ui/kvi_actiondrawer.h107
-rw-r--r--src/kvirc/ui/kvi_channel.cpp1628
-rw-r--r--src/kvirc/ui/kvi_channel.h313
-rw-r--r--src/kvirc/ui/kvi_colorwin.cpp122
-rw-r--r--src/kvirc/ui/kvi_colorwin.h47
-rw-r--r--src/kvirc/ui/kvi_console.cpp1283
-rw-r--r--src/kvirc/ui/kvi_console.h212
-rw-r--r--src/kvirc/ui/kvi_cryptcontroller.cpp390
-rw-r--r--src/kvirc/ui/kvi_cryptcontroller.h116
-rw-r--r--src/kvirc/ui/kvi_ctcppagedialog.cpp147
-rw-r--r--src/kvirc/ui/kvi_ctcppagedialog.h56
-rw-r--r--src/kvirc/ui/kvi_customtoolbar.cpp670
-rw-r--r--src/kvirc/ui/kvi_customtoolbar.h91
-rw-r--r--src/kvirc/ui/kvi_debugwindow.cpp132
-rw-r--r--src/kvirc/ui/kvi_debugwindow.h54
-rw-r--r--src/kvirc/ui/kvi_dynamictooltip.cpp61
-rw-r--r--src/kvirc/ui/kvi_dynamictooltip.h61
-rw-r--r--src/kvirc/ui/kvi_filedialog.cpp229
-rw-r--r--src/kvirc/ui/kvi_filedialog.h55
-rw-r--r--src/kvirc/ui/kvi_frame.cpp1450
-rw-r--r--src/kvirc/ui/kvi_frame.h259
-rw-r--r--src/kvirc/ui/kvi_historywin.cpp255
-rw-r--r--src/kvirc/ui/kvi_historywin.h61
-rw-r--r--src/kvirc/ui/kvi_htmldialog.cpp155
-rw-r--r--src/kvirc/ui/kvi_htmldialog.h87
-rw-r--r--src/kvirc/ui/kvi_imagedialog.cpp367
-rw-r--r--src/kvirc/ui/kvi_imagedialog.h109
-rw-r--r--src/kvirc/ui/kvi_input.cpp2680
-rw-r--r--src/kvirc/ui/kvi_input.h262
-rw-r--r--src/kvirc/ui/kvi_ipeditor.cpp453
-rw-r--r--src/kvirc/ui/kvi_ipeditor.h62
-rw-r--r--src/kvirc/ui/kvi_irctoolbar.cpp441
-rw-r--r--src/kvirc/ui/kvi_irctoolbar.h95
-rw-r--r--src/kvirc/ui/kvi_ircview.cpp5161
-rw-r--r--src/kvirc/ui/kvi_ircview.h252
-rw-r--r--src/kvirc/ui/kvi_ircviewprivate.h164
-rw-r--r--src/kvirc/ui/kvi_ircviewtools.cpp348
-rw-r--r--src/kvirc/ui/kvi_ircviewtools.h119
-rw-r--r--src/kvirc/ui/kvi_listview.cpp212
-rw-r--r--src/kvirc/ui/kvi_listview.h58
-rw-r--r--src/kvirc/ui/kvi_maskeditor.cpp350
-rw-r--r--src/kvirc/ui/kvi_maskeditor.h108
-rw-r--r--src/kvirc/ui/kvi_mdicaption.cpp285
-rw-r--r--src/kvirc/ui/kvi_mdicaption.h101
-rw-r--r--src/kvirc/ui/kvi_mdichild.cpp576
-rw-r--r--src/kvirc/ui/kvi_mdichild.h122
-rw-r--r--src/kvirc/ui/kvi_mdimanager.cpp1126
-rw-r--r--src/kvirc/ui/kvi_mdimanager.h144
-rw-r--r--src/kvirc/ui/kvi_menubar.cpp415
-rw-r--r--src/kvirc/ui/kvi_menubar.h83
-rw-r--r--src/kvirc/ui/kvi_modeeditor.cpp336
-rw-r--r--src/kvirc/ui/kvi_modeeditor.h70
-rwxr-xr-xsrc/kvirc/ui/kvi_modew.cpp175
-rwxr-xr-xsrc/kvirc/ui/kvi_modew.h57
-rw-r--r--src/kvirc/ui/kvi_msgbox.cpp89
-rw-r--r--src/kvirc/ui/kvi_msgbox.h53
-rw-r--r--src/kvirc/ui/kvi_optionswidget.cpp722
-rw-r--r--src/kvirc/ui/kvi_optionswidget.h163
-rw-r--r--src/kvirc/ui/kvi_query.cpp659
-rw-r--r--src/kvirc/ui/kvi_query.h95
-rw-r--r--src/kvirc/ui/kvi_scriptbutton.cpp98
-rw-r--r--src/kvirc/ui/kvi_scriptbutton.h79
-rw-r--r--src/kvirc/ui/kvi_scripteditor.cpp139
-rw-r--r--src/kvirc/ui/kvi_scripteditor.h69
-rw-r--r--src/kvirc/ui/kvi_selectors.cpp839
-rw-r--r--src/kvirc/ui/kvi_selectors.h367
-rw-r--r--src/kvirc/ui/kvi_splash.cpp222
-rw-r--r--src/kvirc/ui/kvi_splash.h72
-rw-r--r--src/kvirc/ui/kvi_statusbar.cpp643
-rw-r--r--src/kvirc/ui/kvi_statusbar.h130
-rw-r--r--src/kvirc/ui/kvi_statusbarapplet.cpp563
-rw-r--r--src/kvirc/ui/kvi_statusbarapplet.h195
-rw-r--r--src/kvirc/ui/kvi_styled_controls.cpp373
-rw-r--r--src/kvirc/ui/kvi_styled_controls.h113
-rw-r--r--src/kvirc/ui/kvi_taskbar.cpp1509
-rw-r--r--src/kvirc/ui/kvi_taskbar.h312
-rw-r--r--src/kvirc/ui/kvi_texticonwin.cpp283
-rw-r--r--src/kvirc/ui/kvi_texticonwin.h64
-rw-r--r--src/kvirc/ui/kvi_themedlabel.cpp154
-rw-r--r--src/kvirc/ui/kvi_themedlabel.h62
-rw-r--r--src/kvirc/ui/kvi_toolbar.cpp160
-rw-r--r--src/kvirc/ui/kvi_toolbar.h52
-rw-r--r--src/kvirc/ui/kvi_toolwindows_container.cpp140
-rw-r--r--src/kvirc/ui/kvi_toolwindows_container.h65
-rw-r--r--src/kvirc/ui/kvi_topicw.cpp834
-rw-r--r--src/kvirc/ui/kvi_topicw.h120
-rw-r--r--src/kvirc/ui/kvi_userlistview.cpp1972
-rw-r--r--src/kvirc/ui/kvi_userlistview.h259
-rw-r--r--src/kvirc/ui/kvi_window.cpp1518
-rw-r--r--src/kvirc/ui/kvi_window.h393
-rw-r--r--src/kvirc/ui/moc_kvi_actiondrawer.cpp238
-rw-r--r--src/kvirc/ui/moc_kvi_customtoolbar.cpp180
-rw-r--r--src/kvirc/ui/moc_kvi_debugwindow.cpp92
-rw-r--r--src/kvirc/ui/moc_kvi_htmldialog.cpp107
-rw-r--r--src/kvirc/ui/moc_kvi_imagedialog.cpp126
-rw-r--r--src/kvirc/ui/moc_kvi_ircviewtools.cpp116
-rw-r--r--src/kvirc/ui/moc_kvi_listview.cpp92
-rw-r--r--src/kvirc/ui/moc_kvi_mdicaption.cpp238
-rw-r--r--src/kvirc/ui/moc_kvi_mdichild.cpp141
-rw-r--r--src/kvirc/ui/moc_kvi_mdimanager.cpp191
-rw-r--r--src/kvirc/ui/moc_kvi_statusbar.cpp126
-rw-r--r--src/kvirc/ui/moc_kvi_statusbarapplet.cpp496
-rw-r--r--src/kvirc/ui/moc_kvi_toolwindows_container.cpp165
105 files changed, 38892 insertions, 0 deletions
diff --git a/src/kvirc/ui/Makefile.am b/src/kvirc/ui/Makefile.am
new file mode 100644
index 0000000..c84487e
--- /dev/null
+++ b/src/kvirc/ui/Makefile.am
@@ -0,0 +1,5 @@
+###############################################################################
+# KVirc IRC client Makefile - 16.12.98 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+EXTRA_DIST = *.cpp *.h
diff --git a/src/kvirc/ui/kvi_actiondrawer.cpp b/src/kvirc/ui/kvi_actiondrawer.cpp
new file mode 100644
index 0000000..a465914
--- /dev/null
+++ b/src/kvirc/ui/kvi_actiondrawer.cpp
@@ -0,0 +1,227 @@
+//=============================================================================
+//
+// File : kvi_actiondrawer.cpp
+// Created on Sun 21 Nov 2004 05:44:22 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2004 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_actiondrawer.h"
+#include "kvi_action.h"
+#include "kvi_actionmanager.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+//#include <qscrollview.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#ifdef COMPILE_USE_QT4
+ #include <q3header.h>
+ #include <q3simplerichtext.h>
+ #include <qmime.h>
+ #include <qevent.h>
+#else
+ #include <qheader.h>
+ #include <qsimplerichtext.h>
+#endif
+
+#include "kvi_draganddrop.h"
+
+#define LVI_ICON_SIZE 32
+#define LVI_BORDER 4
+#define LVI_SPACING 8
+#define LVI_MINIMUM_TEXT_WIDTH 300
+#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER)
+
+KviActionDrawerPageListViewItem::KviActionDrawerPageListViewItem(KviTalListView * v,KviAction * a)
+: KviTalListViewItem(v,"")
+{
+ m_pListView = v;
+ setDragEnabled(true);
+ m_szName = a->name();
+ QString t = "<b>" + a->visibleName() + "</b>";
+ if(a->isKviUserActionNeverOverrideThis())
+ t += " <font color=\"#a0a0a0\">[" + __tr2qs("Script") + "]</font>";
+ t += "<br><font size=\"-1\">" + a->description()+ "</font>";
+ m_szKey = a->visibleName().upper();
+#ifdef COMPILE_USE_QT4
+ m_pText = new Q3SimpleRichText(t,v->font());
+#else
+ m_pText = new QSimpleRichText(t,v->font());
+#endif
+ QPixmap * p = a->bigIcon();
+ m_pIcon = p ? new QPixmap(*p) : new QPixmap(LVI_ICON_SIZE,LVI_ICON_SIZE);
+}
+
+KviActionDrawerPageListViewItem::~KviActionDrawerPageListViewItem()
+{
+ delete m_pIcon;
+ delete m_pText;
+}
+
+QString KviActionDrawerPageListViewItem::key(int,bool) const
+{
+ return m_szKey;
+}
+
+void KviActionDrawerPageListViewItem::setup()
+{
+ KviTalListViewItem::setup();
+ int iWidth = m_pListView->visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ iWidth -= LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER;
+ m_pText->setWidth(iWidth);
+ int iHeight = m_pText->height() + (2 * LVI_BORDER);
+ if(iHeight < (LVI_ICON_SIZE + (2 * LVI_BORDER)))iHeight = LVI_ICON_SIZE + (2 * LVI_BORDER);
+ setHeight(iHeight);
+}
+
+void KviActionDrawerPageListViewItem::paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align)
+{
+ KviTalListViewItem::paintCell(p,cg,column,width,align);
+ //p->fillRect(QRect(0,0,width,height()),isSelected() ? cg.highlight() : cg.base());
+ p->drawPixmap(LVI_BORDER,LVI_BORDER,*m_pIcon);
+ int afterIcon = LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING;
+ int www = m_pListView->visibleWidth() - (afterIcon + LVI_BORDER);
+ m_pText->setWidth(www);
+ if(isSelected())
+ {
+ QColorGroup cg2(cg);
+ cg2.setColor(QColorGroup::HighlightedText,cg.text());
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,height() - (LVI_BORDER * 2)),cg2);
+ } else {
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,height() - (LVI_BORDER * 2)),cg);
+ }
+}
+
+KviActionDrawerPageListView::KviActionDrawerPageListView(KviActionDrawerPage * pParent)
+: KviListView(pParent)
+{
+ QPixmap * p = g_pIconManager->getImage("kvi_actiondrawer.png");
+ if(p)setBackgroundOverlayPixmap(p,Qt::AlignRight | Qt::AlignBottom);
+
+// m_pPage = pParent;
+ setSelectionMode(Single);
+ header()->hide();
+ int iWidth = visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ addColumn("",iWidth);
+ setSorting(0,true);
+}
+
+KviActionDrawerPageListView::~KviActionDrawerPageListView()
+{
+}
+
+
+void KviActionDrawerPageListView::contentsMousePressEvent(QMouseEvent * e)
+{
+ KviListView::contentsMousePressEvent(e);
+ KviActionDrawerPageListViewItem * i = (KviActionDrawerPageListViewItem *)itemAt(QPoint(5,contentsToViewport(e->pos()).y()));
+ if(!i)return;
+ KviTextDrag * dr = new KviTextDrag(i->name(),this); // does this leak memory ?
+ if(i->icon())dr->setPixmap(*(i->icon()),QPoint(3,3));
+ dr->dragCopy();
+}
+
+void KviActionDrawerPageListView::resizeEvent(QResizeEvent * e)
+{
+ KviListView::resizeEvent(e);
+ int iWidth = visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ setColumnWidth(0,iWidth);
+}
+
+
+KviActionDrawerPage::KviActionDrawerPage(QWidget * pParent,const QString &szDescription)
+: QWidget(pParent)
+{
+ QGridLayout * g = new QGridLayout(this,2,1,4,4);
+
+ QString t = "<b>" + szDescription + "</b>";
+ QLabel * l = new QLabel(t,this);
+ g->addWidget(l,0,0);
+
+ m_pListView = new KviActionDrawerPageListView(this);
+
+ g->addWidget(m_pListView,1,0);
+
+ g->setRowStretch(1,1);
+}
+
+KviActionDrawerPage::~KviActionDrawerPage()
+{
+}
+
+void KviActionDrawerPage::add(KviAction * a)
+{
+ (void)new KviActionDrawerPageListViewItem(m_pListView,a);
+}
+
+KviActionDrawer::KviActionDrawer(QWidget * pParent)
+: QTabWidget(pParent)
+{
+ setMinimumWidth(400);
+ setMinimumHeight(300);
+}
+
+KviActionDrawer::~KviActionDrawer()
+{
+}
+
+void KviActionDrawer::fill()
+{
+ KviActionManager::loadAllAvailableActions();
+
+ KviPointerHashTable<QString,KviActionDrawerPage> pages;
+ pages.setAutoDelete(false);
+
+ KviPointerHashTable<QString,KviAction> * d = KviActionManager::instance()->actions();
+ if(!d)return; // ooops
+
+ KviPointerHashTableIterator<QString,KviAction> it(*d);
+ while(KviAction * a = it.current())
+ {
+ KviActionCategory * c = a->category();
+ if(!c)c = KviActionManager::categoryGeneric();
+ KviActionDrawerPage * p = pages.find(c->visibleName());
+ if(!p)
+ {
+ p = new KviActionDrawerPage(this,c->description());
+ pages.replace(c->visibleName(),p);
+ addTab(p,c->visibleName());
+ //p->show();
+ }
+ p->add(a);
+ ++it;
+ }
+
+ KviActionDrawerPage * p = pages.find(KviActionManager::categoryIrc()->visibleName());
+ if(p)
+ {
+ int iii = indexOf(p);
+ if(iii >= 0)setCurrentPage(iii);
+ }
+}
+
+
diff --git a/src/kvirc/ui/kvi_actiondrawer.h b/src/kvirc/ui/kvi_actiondrawer.h
new file mode 100644
index 0000000..d9cd277
--- /dev/null
+++ b/src/kvirc/ui/kvi_actiondrawer.h
@@ -0,0 +1,107 @@
+#ifndef _KVI_ACTIONDRAWER_H_
+#define _KVI_ACTIONDRAWER_H_
+//=============================================================================
+//
+// File : kvi_actiondrawer.h
+// Created on Sun 21 Nov 2004 05:44:22 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2004 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_qstring.h"
+
+#include <qwidget.h>
+#include <qtabwidget.h>
+
+#include "kvi_listview.h"
+
+class KviActionDrawerPage;
+class QPixmap;
+#ifdef COMPILE_USE_QT4
+ class Q3SimpleRichText;
+#else
+ class QSimpleRichText;
+#endif
+class KviAction;
+
+class KVIRC_API KviActionDrawerPageListViewItem : public KviTalListViewItem
+{
+public:
+ KviActionDrawerPageListViewItem(KviTalListView * v,KviAction * a);
+ ~KviActionDrawerPageListViewItem();
+protected:
+ QString m_szName;
+#ifdef COMPILE_USE_QT4
+ Q3SimpleRichText * m_pText;
+#else
+ QSimpleRichText * m_pText;
+#endif
+ QPixmap * m_pIcon;
+ KviTalListView * m_pListView;
+ QString m_szKey;
+public:
+ QPixmap * icon(){ return m_pIcon; };
+ const QString & name(){ return m_szName; };
+protected:
+ virtual void paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align);
+ virtual void setup();
+ virtual QString key(int,bool) const;
+};
+
+class KVIRC_API KviActionDrawerPageListView : public KviListView
+{
+ friend class KviActionDrawerPage;
+ Q_OBJECT
+protected:
+ KviActionDrawerPageListView(KviActionDrawerPage * pParent);
+public:
+ ~KviActionDrawerPageListView();
+//protected:
+// KviActionDrawerPage * m_pPage;
+protected:
+ virtual void resizeEvent(QResizeEvent * e);
+ virtual void contentsMousePressEvent(QMouseEvent * e);
+};
+
+class KVIRC_API KviActionDrawerPage : public QWidget
+{
+ friend class KviActionDrawer;
+ Q_OBJECT
+protected:
+ KviActionDrawerPage(QWidget * pParent,const QString &szDescription);
+public:
+ ~KviActionDrawerPage();
+protected:
+ KviActionDrawerPageListView * m_pListView;
+protected:
+ void add(KviAction * a);
+};
+
+class KVIRC_API KviActionDrawer : public QTabWidget
+{
+ Q_OBJECT
+public:
+ KviActionDrawer(QWidget * pParent);
+ ~KviActionDrawer();
+public:
+ void fill();
+};
+
+#endif //!_KVI_ACTIONDRAWER_H_
diff --git a/src/kvirc/ui/kvi_channel.cpp b/src/kvirc/ui/kvi_channel.cpp
new file mode 100644
index 0000000..a06ab14
--- /dev/null
+++ b/src/kvirc/ui/kvi_channel.cpp
@@ -0,0 +1,1628 @@
+//=============================================================================
+//
+// File : kvi_channel.cpp
+// Creation date : Tue Aug 1 2000 02:20:22 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+//
+// Channel widget : abstraction of an IRC channel
+//
+
+#define __KVIRC__
+
+#include "kvi_toolwindows_container.h"
+#include "kvi_styled_controls.h"
+#include "kvi_channel.h"
+#include "kvi_console.h"
+#include "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_input.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_topicw.h"
+#include "kvi_ircsocket.h"
+#include "kvi_out.h"
+#include "kvi_malloc.h"
+#include "kvi_taskbar.h"
+#include "kvi_frame.h"
+#include "kvi_config.h"
+#include "kvi_themedlabel.h"
+#include "kvi_maskeditor.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_settings.h"
+#include "kvi_parameterlist.h"
+#include "kvi_modeeditor.h"
+#include "kvi_app.h"
+#include "kvi_useraction.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionserverinfo.h"
+#include "kvi_defaults.h"
+#include "kvi_sparser.h"
+#include "kvi_modew.h"
+#include "kvi_mirccntrl.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ #include "kvi_crypt.h"
+ #include "kvi_cryptcontroller.h"
+#endif
+
+#include "kvi_kvs_script.h"
+#include "kvi_kvs_eventtriggers.h"
+
+#include <time.h>
+
+#include <qsplitter.h>
+#include <qtoolbutton.h>
+#include <qlabel.h>
+#include <qevent.h>
+
+#include <qpalette.h>
+#include "kvi_tal_popupmenu.h"
+#include "kvi_pointerhashtable.h"
+#include <qmessagebox.h>
+#include "kvi_tal_widgetstack.h"
+
+#ifndef AVERAGE_CHANNEL_USERS
+ #define AVERAGE_CHANNEL_USERS 101
+#endif
+
+
+
+// FIXME: #warning "+a Anonymous channel mode!"
+// FIXME: #warning "+r channel mode (reop)"
+// FIXME: #warning "OnChannelFlood event...."
+
+
+KviChannel::KviChannel(KviFrame * lpFrm,KviConsole * lpConsole,const char * name)
+: KviWindow(KVI_WINDOW_TYPE_CHANNEL,lpFrm,name,lpConsole)
+{
+ // Init some member variables
+ m_pInput = 0;
+ m_iStateFlags = 0;
+ m_pBanList = new KviPointerList<KviMaskEntry>;
+ m_pBanList->setAutoDelete(true);
+ m_pBanExceptionList = new KviPointerList<KviMaskEntry>;
+ m_pBanExceptionList->setAutoDelete(true);
+ m_pInviteList = new KviPointerList<KviMaskEntry>;
+ m_pInviteList->setAutoDelete(true);
+ m_pActionHistory = new KviPointerList<KviChannelAction>;
+ m_pActionHistory->setAutoDelete(true);
+ m_uActionHistoryHotActionCount = 0;
+
+ m_pTmpHighLighted = new KviPointerHashTable<const char *,QString>();
+ m_pTmpHighLighted->setAutoDelete(true);
+
+ // Register ourselves
+ connection()->registerChannel(this);
+ // And create the widgets layout
+ // Button box
+ m_pButtonBox = new KviTalHBox(this);
+
+ m_pTopSplitter = new QSplitter(Qt::Horizontal,m_pButtonBox);
+
+ m_pButtonBox->setStretchFactor(m_pTopSplitter,1);
+
+ m_pButtonContainer = new KviTalHBox(m_pButtonBox);
+
+ // Topic widget on the left
+ m_pTopicWidget = new KviTopicWidget(m_pTopSplitter,"topic_widget");
+
+ connect(m_pTopicWidget,SIGNAL(topicSelected(const QString &)),
+ this,SLOT(topicSelected(const QString &)));
+ // mode label follows the topic widget
+ m_pModeWidget = new KviModeWidget(m_pTopSplitter,this,"mode_");
+ KviTalToolTip::add(m_pModeWidget,__tr2qs("Channel mode"));
+
+ createTextEncodingButton(m_pButtonContainer);
+
+ // Central splitter
+ m_pSplitter = new QSplitter(Qt::Horizontal,this);
+ #ifdef COMPILE_USE_QT4
+ m_pSplitter->setObjectName(name);
+ #else
+ m_pSplitter->setName(name);
+ #endif
+ m_pSplitter->setOpaqueResize(false);
+ // Spitted vertially on the left
+ m_pVertSplitter = new QSplitter(Qt::Vertical,m_pSplitter);
+ m_pVertSplitter->setOpaqueResize(false);
+ // With the IRC view over
+ m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this);
+ #ifdef COMPILE_USE_QT4
+ m_pIrcView->setObjectName(name);
+ #else
+ m_pIrcView->setName(name);
+ #endif
+ connect(m_pIrcView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked()));
+ // And the double view (that may be unused)
+ m_pMessageView = 0;
+ // The userlist on the right
+ //m_pEditorsContainer= new KviToolWindowsContainer(m_pSplitter);
+
+
+ // and the related buttons
+ m_pDoubleViewButton = createToolButton(m_pButtonContainer,"double_view_button",KVI_SMALLICON_HIDEDOUBLEVIEW,KVI_SMALLICON_SHOWDOUBLEVIEW,__tr2qs("Split View"),false);
+ connect(m_pDoubleViewButton,SIGNAL(clicked()),this,SLOT(toggleDoubleView()));
+
+ m_pListViewButton = new KviWindowToolPageButton(KVI_SMALLICON_HIDELISTVIEW,KVI_SMALLICON_SHOWLISTVIEW,__tr2qs("User List"),buttonContainer(),true,"list_view_button");
+ connect(m_pListViewButton,SIGNAL(clicked()),this,SLOT(toggleListView()));
+ m_pBanEditorButton = new KviWindowToolPageButton(KVI_SMALLICON_UNBAN,KVI_SMALLICON_BAN,__tr2qs("Ban Editor"),buttonContainer(),false,"ban_editor_button");
+ connect(m_pBanEditorButton,SIGNAL(clicked()),this,SLOT(toggleBanEditor()));
+
+ if(m_pConsole->connection()->serverInfo()->supportedListModes().contains('e'))
+ {
+ m_pBanExceptionEditorButton =new KviWindowToolPageButton(KVI_SMALLICON_BANUNEXCEPT,KVI_SMALLICON_BANEXCEPT,__tr2qs("Ban Exception Editor"),buttonContainer(),false,"ban_exception_editor_button");
+ connect(m_pBanExceptionEditorButton,SIGNAL(clicked()),this,SLOT(toggleBanExceptionEditor()));
+ } else {
+ m_pBanExceptionEditorButton=0;
+ }
+ if(m_pConsole->connection()->serverInfo()->supportedListModes().contains('I'))
+ {
+ m_pInviteEditorButton =new KviWindowToolPageButton(KVI_SMALLICON_INVITEUNEXCEPT,KVI_SMALLICON_INVITEEXCEPT,__tr2qs("Invite Exception Editor"),buttonContainer(),false,"invite_exception_editor_button");
+ connect(m_pInviteEditorButton,SIGNAL(clicked()),this,SLOT(toggleInviteEditor()));
+ } else {
+ m_pInviteEditorButton = 0;
+ }
+ m_pModeEditorButton = new KviWindowToolPageButton(KVI_SMALLICON_CHANMODEHIDE,KVI_SMALLICON_CHANMODE,__tr2qs("Mode Editor"),buttonContainer(),false,"mode_editor_button");
+ connect(m_pModeEditorButton,SIGNAL(clicked()),this,SLOT(toggleModeEditor()));
+ m_pModeEditor = 0;
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ createCryptControllerButton(m_pButtonContainer);
+#endif
+
+ m_pHideToolsButton = new KviStyledToolButton(m_pButtonBox,"hide_container_button");
+
+#ifndef COMPILE_USE_QT4
+ m_pHideToolsButton->setUsesBigPixmap(false);
+#else
+ m_pHideToolsButton->setAutoRaise(true);
+#endif
+ m_pHideToolsButton->setFixedWidth(10);
+
+ if(g_pIconManager->getBigIcon("kvi_horizontal_left.png"))
+ m_pHideToolsButton->setPixmap(*(g_pIconManager->getBigIcon("kvi_horizontal_left.png")));
+
+ connect(m_pHideToolsButton,SIGNAL(clicked()),this,SLOT(toggleToolButtons()));
+
+ m_pUserListView = new KviUserListView(m_pSplitter,m_pListViewButton,connection()->userDataBase(),this,
+ AVERAGE_CHANNEL_USERS,__tr2qs("User List"),"user_list_view");
+// m_pEditorsContainer->addWidget(m_pUserListView);
+// m_pEditorsContainer->raiseWidget(m_pUserListView);
+ // And finally the input line on the bottom
+ m_pInput = new KviInput(this,m_pUserListView);
+ // no mask editors yet
+ m_pBanEditor = 0;
+ m_pBanExceptionEditor = 0;
+ m_pInviteEditor = 0;
+ // Ensure proper focusing
+ //setFocusHandler(m_pInput,this);
+ // And turn on the secondary IRC view if needed
+
+ if(KVI_OPTION_BOOL(KviOption_boolAutoLogChannels))m_pIrcView->startLogging();
+
+ applyOptions();
+ m_joinTime = QDateTime::currentDateTime();
+ m_tLastReceivedWhoReply = (kvi_time_t)m_joinTime.toTime_t();
+
+
+}
+
+KviChannel::~KviChannel()
+{
+ // Unregister ourself
+ if(type() == KVI_WINDOW_TYPE_DEADCHANNEL)context()->unregisterDeadChannel(this);
+ else connection()->unregisterChannel(this);
+ // Then remove all the users and free mem
+ m_pUserListView->enableUpdates(false);
+ m_pUserListView->partAll();
+ delete m_pActionHistory;
+ delete m_pBanList;
+ delete m_pBanExceptionList;
+ delete m_pInviteList;
+ delete m_pTmpHighLighted;
+}
+
+void KviChannel::toggleToolButtons()
+{
+ if(!buttonContainer()) return;
+ toggleButtonContainer();
+ QPixmap* pix= buttonContainer()->isVisible() ?
+ g_pIconManager->getBigIcon("kvi_horizontal_left.png") :
+ g_pIconManager->getBigIcon("kvi_horizontal_right.png");
+ if(pix)
+ m_pHideToolsButton->setPixmap(*pix);
+}
+
+void KviChannel::triggerCreationEvents()
+{
+ KVS_TRIGGER_EVENT_0(KviEvent_OnChannelWindowCreated,this);
+}
+
+void KviChannel::textViewRightClicked()
+{
+ KVS_TRIGGER_EVENT_0(KviEvent_OnChannelPopupRequest,this);
+}
+
+void KviChannel::getBaseLogFileName(QString &buffer)
+{
+ QString szChan(windowName());
+ szChan.replace(".","%2e");
+ if (console()->connection())
+ {
+ buffer=szChan;
+ buffer.append(".");
+ buffer.append(console()->currentNetworkName());
+ } else {
+ buffer=szChan;
+ buffer.append(".");
+ buffer.append(console()->ircContextId());
+ }
+}
+
+void KviChannel::applyOptions()
+{
+ m_pUserListView->applyOptions();
+ m_pTopicWidget->applyOptions();
+
+ if(m_pMessageView)m_pMessageView->applyOptions();
+
+ m_pModeWidget->applyOptions();
+
+ // this applies options for IrcView and Input and forces the window to relayout
+ KviWindow::applyOptions();
+}
+
+void KviChannel::getConfigGroupName(QString &buf)
+{
+ buf = windowName();
+}
+
+void KviChannel::saveProperties(KviConfig *cfg)
+{
+ KviWindow::saveProperties(cfg);
+ cfg->writeEntry("TopSplitter",m_pTopSplitter->sizes());
+ cfg->writeEntry("Splitter",m_pSplitter->sizes());
+#ifdef COMPILE_USE_QT4
+ QList<int> tmp = m_pVertSplitter->sizes();
+ KviValueList<int> tmp2;
+ for(QList<int>::Iterator it = tmp.begin();it != tmp.end();++it)
+ tmp2.append(*it);
+ cfg->writeEntry("VertSplitter",m_pMessageView ? tmp2 : m_VertSplitterSizesList);
+#else
+ cfg->writeEntry("VertSplitter",m_pMessageView ? m_pVertSplitter->sizes() : m_VertSplitterSizesList);
+#endif
+ cfg->writeEntry("PrivateBackground",m_privateBackground);
+ cfg->writeEntry("DoubleView",m_pMessageView ? true : false);
+ if(m_pUserListView)
+ cfg->writeEntry("UserListHidden",m_pUserListView->isHidden());
+ cfg->writeEntry("ToolButtonsHidden",buttonContainer()->isHidden());
+}
+
+void KviChannel::loadProperties(KviConfig *cfg)
+{
+ int w = width();
+ KviValueList<int> def;
+ def.append((w * 75) / 100);
+ def.append((w * 15) / 100);
+ def.append((w * 10) / 100);
+ m_pTopSplitter->setSizes(cfg->readIntListEntry("TopSplitter",def));
+ def.clear();
+ def.append((w * 82) / 100);
+ def.append((w * 18) / 100);
+ m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def));
+ //debug("SETTING DEFAULT SIZES");
+ def.clear();
+
+ def.append((w * 60) / 100);
+ def.append((w * 40) / 100);
+ m_VertSplitterSizesList=cfg->readIntListEntry("VertSplitter",def);
+ showDoubleView(cfg->readBoolEntry("DoubleView",false));
+ //def.append((w * 50) / 100);
+ //def.append((w * 50) / 100);
+
+ m_privateBackground = cfg->readPixmapEntry("PrivateBackground",KviPixmap());
+ if(m_privateBackground.pixmap())
+ {
+ m_pIrcView->setPrivateBackgroundPixmap(*(m_privateBackground.pixmap()));
+ if(m_pMessageView)m_pMessageView->setPrivateBackgroundPixmap(*(m_privateBackground.pixmap()));
+ }
+
+ KviWindow::loadProperties(cfg);
+ if(m_pUserListView)
+ {
+ bool bHidden=cfg->readBoolEntry("UserListHidden",0);
+ m_pUserListView->setHidden(bHidden);
+ resizeEvent(0);
+ }
+ if(cfg->readBoolEntry("ToolButtonsHidden",KVI_OPTION_BOOL(KviOption_boolHideWindowToolButtons))!=buttonContainer()->isHidden())
+ toggleToolButtons();
+}
+
+
+void KviChannel::showDoubleView(bool bShow)
+{
+ if(m_pMessageView)
+ {
+ if(bShow)return;
+ m_pIrcView->joinMessagesFrom(m_pMessageView);
+ m_VertSplitterSizesList=m_pVertSplitter->sizes();
+ delete m_pMessageView;
+ m_pMessageView = 0;
+ if(m_pDoubleViewButton->isOn())m_pDoubleViewButton->setOn(false);
+ } else {
+ if(!bShow)return;
+ m_pMessageView = new KviIrcView(m_pVertSplitter,m_pFrm,this);
+ m_pVertSplitter->setSizes(m_VertSplitterSizesList);
+ //setFocusHandler(m_pInput,m_pMessageView); //socket it!
+ if(!(m_pDoubleViewButton->isOn()))m_pDoubleViewButton->setOn(true);
+ if(m_privateBackground.pixmap())
+ {
+ m_pMessageView->setPrivateBackgroundPixmap(*(m_privateBackground.pixmap()));
+ }
+ connect(m_pMessageView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked()));
+ m_pMessageView->setMasterView(m_pIrcView);
+ m_pIrcView->splitMessagesTo(m_pMessageView);
+ m_pMessageView->show();
+ }
+}
+
+void KviChannel::toggleDoubleView()
+{
+ showDoubleView(!m_pMessageView);
+}
+
+void KviChannel::toggleListView()
+{
+ if(m_pUserListView->isVisible())
+ {
+ m_pUserListView->hide();
+ if(m_pListViewButton->isOn())m_pListViewButton->setOn(false);
+ } else {
+ m_pUserListView->show();
+ if(!(m_pListViewButton->isOn()))m_pListViewButton->setOn(true);
+ }
+}
+
+
+void KviChannel::toggleModeEditor()
+{
+ if(m_pModeEditor)
+ {
+ delete m_pModeEditor;
+ m_pModeEditor = 0;
+ m_pSplitter->setMinimumHeight(20); //gfgf
+ if(m_pModeEditorButton->isOn()) m_pModeEditorButton->setOn(false);
+ resizeEvent(0);
+ } else {
+ m_pModeEditor = new KviModeEditor(m_pSplitter,m_pModeEditorButton,"mode_editor",console(),m_szChannelMode,m_szChannelKey,m_szChannelLimit.ptr());
+ connect(m_pModeEditor,SIGNAL(setMode(const char *)),this,SLOT(setMode(const char *)));
+ connect(m_pModeEditor,SIGNAL(done()),this,SLOT(modeSelectorDone()));
+ m_pModeEditor->show();
+ //setFocusHandlerNoClass(m_pInput,m_pModeEditor,"QLineEdit");
+ if(!m_pModeEditorButton->isOn())m_pModeEditorButton->setOn(true);
+ }
+}
+
+void KviChannel::modeSelectorDone()
+{
+ if(m_pModeEditor)toggleModeEditor();
+}
+
+void KviChannel::setMode(const char * mode)
+{
+ if(!connection())return;
+ KviQCString tmp = connection()->encodeText(m_szName);
+ connection()->sendFmtData("MODE %s %s",tmp.data(),mode);
+}
+
+void KviChannel::toggleBanEditor()
+{
+ toggleEditor(&m_pBanEditor,&m_pBanEditorButton,
+ m_pBanList,'b',"ban_editor");
+}
+
+void KviChannel::toggleBanExceptionEditor()
+{
+ toggleEditor(&m_pBanExceptionEditor,&m_pBanExceptionEditorButton,
+ m_pBanExceptionList,'e',"ban_exception_editor");
+}
+
+void KviChannel::toggleInviteEditor()
+{
+ toggleEditor(&m_pInviteEditor,&m_pInviteEditorButton,
+ m_pInviteList,'I',"invite_exception_editor");
+}
+
+void KviChannel::toggleEditor(KviMaskEditor ** ppEd,KviWindowToolPageButton ** ppBtn,KviPointerList<KviMaskEntry> *l,char flag,const char *edName)
+{
+ if(*ppEd)
+ {
+ delete *ppEd;
+ *ppEd = 0;
+ if(!(*ppBtn))return;
+ if((*ppBtn)->isOn()) (*ppBtn)->setOn(false);
+ } else {
+ bool bHasList = true;
+ switch(flag)
+ {
+ case 'b':
+ if(!(bHasList = hasBanList()))
+ {
+ m_pBanList->clear();
+ setSentBanListRequest();
+ }
+ break;
+ case 'e':
+ if(!(bHasList = hasBanExceptionList()))
+ {
+ m_pBanExceptionList->clear();
+ setSentBanExceptionListRequest();
+ }
+ break;
+ case 'I':
+ if(!(bHasList = hasInviteList()))
+ {
+ m_pInviteList->clear();
+ setSentInviteListRequest();
+ }
+ break;
+ }
+ if(!bHasList)
+ {
+ if(connection())
+ {
+ KviQCString szName = connection()->encodeText(m_szName);
+ connection()->sendFmtData("MODE %s %c",szName.data(),flag);
+ }
+ }
+
+ *ppEd = new KviMaskEditor(m_pSplitter,*ppBtn,l,flag,edName);
+ connect(*ppEd,SIGNAL(removeMasks(KviMaskEditor *,KviPointerList<KviMaskEntry> *)),
+ this,SLOT(removeMasks(KviMaskEditor *,KviPointerList<KviMaskEntry> *)));
+ //setFocusHandler(m_pInput,*ppEd); //socket it!
+ (*ppEd)->show();
+ if(!(*ppBtn))return;
+ if(!((*ppBtn)->isOn()))(*ppBtn)->setOn(true);
+ }
+}
+
+void KviChannel::removeMasks(KviMaskEditor *ed,KviPointerList<KviMaskEntry> *l)
+{
+ KviStr masks;
+ KviStr flags;
+ unsigned int count = 0;
+ for(KviMaskEntry * e = l->first();e;e = l->next())
+ {
+ if(masks.hasData())masks.append(' ');
+ masks.append(e->szMask);
+ flags.append(ed->flag());
+ count++;
+ if(count == connection()->serverInfo()->maxModeChanges())
+ {
+ if(connection())
+ {
+ KviQCString szName = connection()->encodeText(m_szName);
+ connection()->sendFmtData("MODE %s -%s %s",szName.data(),flags.ptr(),connection()->encodeText(QString(masks)).data());
+ }
+ flags = "";
+ masks = "";
+ count = 0;
+ }
+ }
+ if(masks.hasData())
+ {
+ if(connection())
+ {
+ KviQCString szName = connection()->encodeText(m_szName);
+ connection()->sendFmtData("MODE %s -%s %s",szName.data(),flags.ptr(),connection()->encodeText(QString(masks)).data());
+ }
+ }
+}
+
+QPixmap * KviChannel::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon((m_iStateFlags & KVI_CHANNEL_STATE_DEADCHAN) ? KVI_SMALLICON_DEADCHANNEL : KVI_SMALLICON_CHANNEL);
+}
+
+void KviChannel::resizeEvent(QResizeEvent *e)
+{
+#ifdef COMPILE_USE_QT4
+ int hght = m_pInput->heightHint();
+ int hght2 = m_pTopicWidget->sizeHint().height();
+ m_pButtonBox->setGeometry(0,0,width(),hght2);
+ m_pSplitter->setGeometry(0,hght2,width(),height() - (hght + hght2));
+ m_pInput->setGeometry(0,height() - hght,width(),hght);
+#else
+ int hght = m_pInput->heightHint();
+ int hght2 = m_pButtonBox->sizeHint().height();
+ m_pButtonBox->setGeometry(0,0,width(),hght2);
+ m_pSplitter->setGeometry(0,hght2,width(),height() - (hght + hght2));
+ m_pInput->setGeometry(0,height() - hght,width(),hght);
+#endif
+}
+
+QSize KviChannel::sizeHint() const
+{
+ QSize ret(m_pSplitter->sizeHint().width(),
+ m_pIrcView->sizeHint().height() + m_pInput->heightHint() + m_pButtonBox->sizeHint().height());
+ return ret;
+}
+
+void KviChannel::setChannelMode(char mode,bool bAdd)
+{
+ if(!m_pConsole->connection()->serverInfo()->supportedListModes().contains(mode)){
+ if(bAdd)
+ {
+ if(!(m_szChannelMode.contains(mode)))m_szChannelMode.append(mode);
+ } else {
+ if(m_szChannelMode.contains(mode))
+ {
+ m_szChannelMode.replace(mode,"");
+ }
+ }
+ updateModeLabel();
+ updateCaption();
+ }
+}
+
+void KviChannel::setChannelKey(const char * key)
+{
+ m_szChannelKey = key;
+ updateModeLabel();
+ updateCaption();
+}
+
+void KviChannel::setChannelLimit(const char * limit)
+{
+ m_szChannelLimit = limit;
+ updateModeLabel();
+ updateCaption();
+}
+
+void KviChannel::addHighlightedUser(const char * nick)
+{
+ if(!m_pUserListView->findEntry(nick))return;
+ else
+ m_pTmpHighLighted->replace(nick,new QString());
+}
+
+void KviChannel::removeHighlightedUser(const char * nick)
+{
+ m_pTmpHighLighted->remove(nick);
+}
+
+void KviChannel::getChannelModeString(QString &buffer)
+{
+ buffer = m_szChannelMode;
+ if(!m_szChannelKey.isEmpty())buffer.append('k');
+ if(m_szChannelLimit.hasData())buffer.append('l');
+}
+
+void KviChannel::setDeadChan()
+{
+ m_iStateFlags |= KVI_CHANNEL_STATE_DEADCHAN;
+ m_iStateFlags &= ~(KVI_CHANNEL_STATE_NOCLOSEONPART | KVI_CHANNEL_STATE_SENTSYNCWHOREQUEST);
+
+ m_pUserListView->enableUpdates(false);
+ m_pUserListView->partAll();
+ m_pUserListView->enableUpdates(true);
+ m_pUserListView->setUserDataBase(0);
+
+ m_pBanList->clear();
+ m_pBanExceptionList->clear();
+ m_pInviteList->clear();
+
+ m_pActionHistory->clear();
+ m_uActionHistoryHotActionCount = 0;
+
+ m_szChannelMode = "";
+ m_szChannelKey = "";
+ m_szChannelLimit = "";
+
+ // this should be moved to irc context!
+ connection()->unregisterChannel(this);
+ context()->registerDeadChannel(this);
+
+ setType(KVI_WINDOW_TYPE_DEADCHANNEL);
+
+ updateIcon();
+ updateModeLabel();
+ updateCaption();
+}
+
+void KviChannel::setAliveChan()
+{
+ // Rise like phoenix!
+ m_iStateFlags = 0;
+ setType(KVI_WINDOW_TYPE_CHANNEL);
+ m_pUserListView->setUserDataBase(connection()->userDataBase());
+ m_joinTime = QDateTime::currentDateTime();
+ context()->unregisterDeadChannel(this);
+ connection()->registerChannel(this);
+ // Update log file name
+ if(m_pIrcView->isLogging())m_pIrcView->startLogging();
+ updateIcon();
+ updateCaption();
+ m_pTopicWidget->reset(); // reset the topic (fixes bug #20 signaled by Klaus Weidenbach)
+}
+
+void KviChannel::getTalkingUsersStats(QString &buffer,QStringList &l,bool bPast)
+{
+ if(l.count() < 1)return;
+
+ if(l.count() == 1)
+ {
+ buffer += "<b>";
+ buffer += l.first();
+ buffer += "</b>";
+ buffer += " ";
+ buffer += bPast ? __tr2qs("said something recently") : __tr2qs("is talking");
+ } else if(l.count() == 2)
+ {
+ buffer += "<b>";
+ buffer += l.first();
+ buffer += "</b> ";
+ buffer += __tr2qs("and");
+ buffer += " <b>";
+ l.remove(l.begin());
+ buffer += l.first();
+ buffer += "</b> ";
+ buffer += bPast ? __tr2qs("were talking recently") : __tr2qs("are talking");
+ } else {
+ buffer += "<b>";
+ buffer += l.first();
+ buffer += "</b>, <b>";
+ l.remove(l.begin());
+ buffer += l.first();
+ if(l.count() == 2)
+ {
+ buffer += "</b> ";
+ buffer += __tr2qs("and");
+ buffer += " <b>";
+ l.remove(l.begin());
+ buffer += l.first();
+ buffer += "</b>";
+ } else {
+ // (l.count() - 1) is > 1
+ buffer += "</b> ";
+ buffer += __tr2qs("and other %1 users").arg(l.count() - 1);
+ }
+ buffer += " ";
+ buffer += bPast ? __tr2qs("were talking recently") : __tr2qs("are talking");
+ }
+}
+
+void KviChannel::getTaskBarTipText(QString &buffer)
+{
+ static QString html_bold("<b>");
+ static QString html_tab("&nbsp;&nbsp;");
+ static QString html_eofbold("</b> ");
+ static QString p5(" (");
+ // p6 == p4
+ static QString p7(" (");
+ static QString p8(": ");
+ static QString p9(")");
+ static QString p10("<br>");
+
+ static QString end_of_doc = "</table></body></html>";
+ static QString end_of_fontboldrow = END_TABLE_BOLD_ROW;
+ static QString start_of_row = "<tr><td>";
+ static QString end_of_row = "</td></tr>";
+
+ buffer = "<html>" \
+ "<body>" \
+ "<table width=\"100%\">"\
+ START_TABLE_BOLD_ROW;
+
+ if(m_iStateFlags & KVI_CHANNEL_STATE_DEADCHAN)
+ {
+ buffer += __tr2qs("Dead channel");
+ buffer += end_of_fontboldrow;
+ buffer += end_of_doc;
+ return;
+ }
+
+ KviUserListViewUserStats s;
+ m_pUserListView->userStats(&s);
+
+
+ buffer += m_szPlainTextCaption;
+ buffer += end_of_fontboldrow;
+
+ buffer += start_of_row;
+
+ QString op = __tr2qs("operator");
+ QString ops = __tr2qs("operators");
+
+ //////////////////////
+
+ buffer += html_tab;
+ buffer += html_bold;
+
+ QString num;
+
+ num.setNum(s.uActive);
+ buffer += num;
+
+ buffer += html_eofbold;
+ buffer += (s.uActive == 1 ? __tr2qs("active user") : __tr2qs("active users"));
+
+ buffer += p5;
+ buffer += html_bold;
+
+ num.setNum(s.uActiveOp);
+
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uActiveOp == 1 ? op : ops);
+
+ buffer += p9;
+/*
+ * #warning FIXME: What is this supposed to mean?
+ buffer += "<font size=\"-1\">";
+ buffer += p7;
+
+ buffer += __tr2qs("humanity");
+
+ buffer += p8;
+ buffer += html_bold;
+
+ num.setNum(s.iAvgTemperature);
+
+ buffer += num;
+ buffer += "</bold>";
+
+ buffer += p9;
+*/
+ buffer += p10;
+ buffer += "</font>";
+
+
+
+ //////////////////////
+
+ buffer += html_tab;
+ buffer += html_bold;
+
+ num.setNum(s.uHot);
+ buffer += num;
+
+ buffer += html_eofbold;
+ buffer += (s.uHot == 1 ? __tr2qs("hot user") : __tr2qs("hot users"));
+
+ buffer += p5;
+ buffer += html_bold;
+
+ num.setNum(s.uHotOp);
+
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uHotOp == 1 ? op : ops);
+
+ buffer += p9;
+
+ /////////////
+
+ buffer += end_of_row;
+ buffer += start_of_row;
+
+ ///////////////////
+
+ if(s.uChanOwner > 0)
+ {
+ buffer += html_tab;
+ buffer += html_bold;
+ num.setNum(s.uChanOwner);
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uChanOwner == 1 ? __tr2qs("channel owner") : __tr2qs("channel owners"));
+ buffer += p10;
+ }
+
+ if(s.uChanAdmin > 0)
+ {
+ buffer += html_tab;
+ buffer += html_bold;
+ num.setNum(s.uChanAdmin);
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uChanAdmin == 1 ? __tr2qs("channel administrator") : __tr2qs("channel administrators"));
+ buffer += p10;
+ }
+
+ if(s.uOp > 0)
+ {
+ buffer += html_tab;
+ buffer += html_bold;
+ num.setNum(s.uOp);
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uOp == 1 ? op : ops);
+ buffer += p10;
+ }
+
+ if(s.uHalfOp > 0)
+ {
+ buffer += html_tab;
+ buffer += html_bold;
+ num.setNum(s.uHalfOp);
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uHalfOp == 1 ? __tr2qs("half-operator") : __tr2qs("half-operators"));
+ buffer += p10;
+ }
+
+ if(s.uVoiced > 0)
+ {
+ buffer += html_tab;
+ buffer += html_bold;
+ num.setNum(s.uVoiced);
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uVoiced == 1 ? __tr2qs("voiced user") : __tr2qs("voiced users"));
+ buffer += p10;
+ }
+
+ if(s.uUserOp > 0)
+ {
+ buffer += html_tab;
+ buffer += html_bold;
+ num.setNum(s.uUserOp);
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uUserOp == 1 ? __tr2qs("user-operator") : __tr2qs("user-operators"));
+ buffer += p10;
+ }
+
+ buffer += html_tab;
+ buffer += html_bold;
+ num.setNum(s.uTotal);
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += (s.uTotal == 1 ? __tr2qs("user total") : __tr2qs("users total"));
+
+ buffer += end_of_row;
+
+ KviChannelActivityStats cas;
+ getChannelActivityStats(&cas);
+
+
+ if(cas.lTalkingUsers.count() > 0)
+ {
+ if((cas.lTalkingUsers.count() < 3) && (cas.lWereTalkingUsers.count() > 0))
+ {
+ buffer += "<tr><td bgcolor=\"#E0E0E0\">";
+ getTalkingUsersStats(buffer,cas.lWereTalkingUsers,true);
+ buffer += end_of_row;
+ }
+ buffer += "<tr><td bgcolor=\"#E0E0E0\">";
+ getTalkingUsersStats(buffer,cas.lTalkingUsers,false);
+ buffer += end_of_row;
+ } else {
+ if(cas.lWereTalkingUsers.count() > 0)
+ {
+ buffer += "<tr><td bgcolor=\"#E0E0E0\">";
+ getTalkingUsersStats(buffer,cas.lWereTalkingUsers,true);
+ buffer += end_of_row;
+ }
+ }
+
+ buffer += "<tr><td bgcolor=\"#A0A0A0\"><b>";
+
+ if(cas.dActionsPerMinute < 0.1)buffer += __tr2qs("No activity");
+ else if(cas.dActionsPerMinute < 0.3)buffer += __tr2qs("Minimal activity");
+ else if(cas.dActionsPerMinute < 1.0)buffer += __tr2qs("Very low activity");
+ else if(cas.dActionsPerMinute < 3.0)buffer += cas.bStatsInaccurate ? __tr2qs("Might be low activity") : __tr2qs("Low activity");
+ else if(cas.dActionsPerMinute < 10.0)buffer += cas.bStatsInaccurate ? __tr2qs("Might be medium activity") : __tr2qs("Medium activity");
+ else if(cas.dActionsPerMinute < 30.0)buffer += cas.bStatsInaccurate ? __tr2qs("Might be high activity") : __tr2qs("High activity");
+ else if(cas.dActionsPerMinute < 60.0)buffer += cas.bStatsInaccurate ? __tr2qs("Might be very high activity") : __tr2qs("Very high activity");
+ else buffer += cas.bStatsInaccurate ? __tr2qs("Might be flooded with messages") : __tr2qs("Flooded with messages");
+
+
+ if(cas.dActionsPerMinute >= 0.1)
+ {
+ QString num;
+ num.sprintf(" [%u%% ",cas.uHotActionPercent);
+ buffer += num;
+ buffer += __tr2qs("human");
+ buffer += "]";
+ }
+
+
+ buffer += "</b></td></tr>";
+
+ buffer += end_of_doc;
+}
+
+void KviChannel::fillCaptionBuffers()
+{
+ static QString begin("<nobr><font color=\"");
+ static QString boldbegin("\"><b>");
+ static QString endofbold("</b></font> <font color=\"");
+ static QString endoffont("\">");
+ static QString end("</font></nobr>");
+
+ if(!connection())
+ {
+ QString dead = __tr2qs("[Dead channel]");
+
+ m_szNameWithUserFlag = m_szName;
+
+ m_szPlainTextCaption = m_szName;
+ m_szPlainTextCaption += " : ";
+ m_szPlainTextCaption += dead;
+
+ m_szHtmlActiveCaption = begin;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += boldbegin;
+ m_szHtmlActiveCaption += m_szName;
+ m_szHtmlActiveCaption += endofbold;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name();
+ m_szHtmlActiveCaption += endoffont;
+ m_szHtmlActiveCaption += dead;
+ m_szHtmlActiveCaption += end;
+
+ m_szHtmlInactiveCaption = begin;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += boldbegin;
+ m_szHtmlInactiveCaption += m_szName;
+ m_szHtmlInactiveCaption += endofbold;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name();
+ m_szHtmlInactiveCaption += endoffont;
+ m_szHtmlInactiveCaption += dead;
+ m_szHtmlInactiveCaption += end;
+ return;
+ }
+
+ char uFlag = getUserFlag(connection()->currentNickName());
+
+
+ if(uFlag)
+ {
+ m_szNameWithUserFlag = QChar(uFlag);
+ m_szNameWithUserFlag += m_szName;
+ } else {
+ m_szNameWithUserFlag = m_szName;
+ }
+
+ QString szChanMode;
+ getChannelModeString(szChanMode);
+
+ m_szPlainTextCaption = m_szNameWithUserFlag;
+ if(!szChanMode.isEmpty())
+ {
+ m_szPlainTextCaption += " (+";
+ m_szPlainTextCaption += szChanMode;
+ m_szPlainTextCaption += QChar(')');
+ }
+
+ QString szNickOnServer = QChar('[');
+ szNickOnServer += connection()->currentNickName();
+ szNickOnServer += __tr2qs(" on ");
+ szNickOnServer += connection()->currentServerName();
+ szNickOnServer += QChar(']');
+
+ m_szPlainTextCaption += QChar(' ');
+ m_szPlainTextCaption += szNickOnServer;
+
+ m_szHtmlActiveCaption = begin;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += boldbegin;
+ m_szHtmlActiveCaption += m_szNameWithUserFlag;
+ m_szHtmlActiveCaption += endofbold;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name();
+ m_szHtmlActiveCaption += endoffont;
+ m_szHtmlActiveCaption += szNickOnServer;
+ m_szHtmlActiveCaption += end;
+
+ m_szHtmlInactiveCaption = begin;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += boldbegin;
+ m_szHtmlInactiveCaption += m_szNameWithUserFlag;
+ m_szHtmlInactiveCaption += endofbold;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name();
+ m_szHtmlInactiveCaption += endoffont;
+ m_szHtmlInactiveCaption += szNickOnServer;
+ m_szHtmlInactiveCaption += end;
+}
+
+void KviChannel::ownMessage(const QString &buffer)
+{
+ if(!connection())return;
+
+ KviQCString szName = connection()->encodeText(windowName());
+ KviQCString szData = encodeText(buffer);
+ const char * d = szData.data();
+ if(!d)return;
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ if(cryptSessionInfo())
+ {
+ if(cryptSessionInfo()->bDoEncrypt)
+ {
+ if(*d != KVI_TEXT_CRYPTESCAPE)
+ {
+ KviStr encrypted;
+ cryptSessionInfo()->pEngine->setMaxEncryptLen(500 - szName.length());
+ switch(cryptSessionInfo()->pEngine->encrypt(d,encrypted))
+ {
+ case KviCryptEngine::Encrypted:
+ if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),encrypted.ptr()))return;
+ m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSGCRYPTED,
+ QString::null,QString::null,QString::null,buffer,KviConsole::NoNotifications);
+ break;
+ case KviCryptEngine::Encoded:
+ {
+ if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),encrypted.ptr()))return;
+ // ugly ,but we must redecode here
+ QString szRedecoded = decodeText(encrypted.ptr());
+ m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,
+ QString::null,QString::null,QString::null,szRedecoded,KviConsole::NoNotifications);
+ }
+ break;
+ default: // also case KviCryptEngine::EncryptError
+ {
+ QString szEngineError = cryptSessionInfo()->pEngine->lastError();
+ output(KVI_OUT_SYSTEMERROR,
+ __tr2qs("The crypto engine was unable to encrypt the current message (%Q): %Q, no data sent to the server"),
+ &buffer,&szEngineError);
+ }
+ break;
+ }
+ userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG);
+ return;
+ } else {
+ d++; //eat the escape code
+ QString tmp = buffer.right(buffer.length() - 1);
+ if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),d))return;
+ m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,QString::null,QString::null,QString::null,tmp,KviConsole::NoNotifications);
+ userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG);
+ return;
+ }
+ }
+ }
+#endif
+
+ if(connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),d))
+ {
+ m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,QString::null,QString::null,QString::null,buffer,KviConsole::NoNotifications);
+ userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG);
+ }
+}
+
+void KviChannel::ownAction(const QString &buffer)
+{
+ if(!connection())return;
+ KviQCString szName = connection()->encodeText(m_szName);
+ KviQCString szData = encodeText(buffer);
+ const char * d = szData.data();
+ if(!d)return;
+ if(!connection()->sendFmtData("PRIVMSG %s :%cACTION %s%c",szName.data(),0x01,d,0x01))return;
+ if(KVS_TRIGGER_EVENT_1_HALTED(KviEvent_OnMeAction,this,QString(d)))return;
+ QString szBuffer = "\r!nc\r";
+ szBuffer += connection()->currentNickName();
+ szBuffer += "\r ";
+ szBuffer += buffer;
+ outputMessage(KVI_OUT_ACTION,szBuffer);
+ userAction(connection()->currentNickName(),KVI_USERACTION_ACTION);
+}
+
+bool KviChannel::nickChange(const QString &oldNick,const QString &newNick)
+{
+ bool bWasHere = m_pUserListView->nickChange(oldNick,newNick);
+ if(bWasHere)channelAction(newNick,KVI_USERACTION_NICK,kvi_getUserActionTemperature(KVI_USERACTION_NICK));
+ return bWasHere;
+}
+
+bool KviChannel::part(const QString &nick)
+{
+ bool bWasHere = m_pUserListView->part(nick);
+ if(bWasHere)channelAction(nick,KVI_USERACTION_PART,kvi_getUserActionTemperature(KVI_USERACTION_PART));
+ return bWasHere;
+}
+
+
+#define KVI_CHANACTIVITY_LIMIT_ICE 5
+#define KVI_CHANACTIVITY_LIMIT_VERYCOLD 10
+#define KVI_CHANACTIVITY_LIMIT_COLD 20
+#define KVI_CHANACTIVITY_LIMIT_UNDEFINED 30
+#define KVI_CHANACTIVITY_LIMIT_HOT 50
+#define KVI_CHANACTIVITY_LIMIT_VERYHOT 70
+
+
+bool KviChannel::activityMeter(unsigned int * puActivityValue,unsigned int * puActivityTemperature)
+{
+ fixActionHistory();
+
+ unsigned int uHotActionPercent;
+ double dActionsPerMinute;
+
+ if(m_pActionHistory->count() < 1)
+ {
+ // nothing is happening
+ uHotActionPercent = 0;
+ dActionsPerMinute = 0;
+ } else {
+ kvi_time_t tNow = kvi_unixTime();
+
+ KviChannelAction * a = m_pActionHistory->last();
+
+ double dSpan = (double)(tNow - a->tTime);
+
+ if(m_pActionHistory->count() < KVI_CHANNEL_ACTION_HISTORY_MAX_COUNT)
+ {
+ if(m_joinTime.secsTo(QDateTime::currentDateTime()) < KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN)
+ {
+ // we can't exactly estimate
+ if(dSpan < 60.0)dSpan = 60.0;
+ } else {
+ // there are less actions at all or they have been pushed out because of the timespan
+ dSpan = KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN;
+ }
+ } // else the actions have been pushed out of the history because they were too much
+
+ if(dSpan > 0.0)
+ dActionsPerMinute = (((double)(m_pActionHistory->count())) / (dSpan)) * 60.0;
+ else
+ dActionsPerMinute = (double)(m_pActionHistory->count()); // ???
+
+ uHotActionPercent = (m_uActionHistoryHotActionCount * 100) / (m_pActionHistory->count());
+ }
+
+
+ if(dActionsPerMinute < 0.3)*puActivityValue = KVI_ACTIVITY_NONE;
+ else if(dActionsPerMinute < 1.0)*puActivityValue = KVI_ACTIVITY_VERYLOW;
+ else if(dActionsPerMinute < 4.0)*puActivityValue = KVI_ACTIVITY_LOW;
+ else if(dActionsPerMinute < 10.0)*puActivityValue = KVI_ACTIVITY_MEDIUM;
+ else if(dActionsPerMinute < 30.0)*puActivityValue = KVI_ACTIVITY_HIGH;
+ else *puActivityValue = KVI_ACTIVITY_VERYHIGH;
+
+ if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_ICE)*puActivityTemperature = KVI_ACTIVITY_ICE;
+ else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_VERYCOLD)*puActivityTemperature = KVI_ACTIVITY_VERYCOLD;
+ else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_COLD)*puActivityTemperature = KVI_ACTIVITY_COLD;
+ else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_UNDEFINED)*puActivityTemperature = KVI_ACTIVITY_UNDEFINED;
+ else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_HOT)*puActivityTemperature = KVI_ACTIVITY_HOT;
+ else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_VERYHOT)*puActivityTemperature = KVI_ACTIVITY_VERYHOT;
+ else *puActivityTemperature = KVI_ACTIVITY_FIRE;
+
+ return true;
+}
+
+
+void KviChannel::channelAction(const QString &nick,unsigned int uActionType,int iTemperature)
+{
+ KviChannelAction * a = new KviChannelAction;
+ a->tTime = kvi_unixTime();
+ a->uActionType = uActionType;
+ a->iTemperature = iTemperature;
+ a->szNick = nick;
+
+ if(iTemperature > 0)m_uActionHistoryHotActionCount++;
+
+ m_pActionHistory->append(a);
+ fixActionHistory();
+}
+
+void KviChannel::fixActionHistory()
+{
+ while(m_pActionHistory->count() > KVI_CHANNEL_ACTION_HISTORY_MAX_COUNT)m_pActionHistory->removeFirst();
+ KviChannelAction * a = m_pActionHistory->last();
+ if(!a)return;
+
+ kvi_time_t tMinimum = a->tTime - KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN;
+
+ KviChannelAction * act = m_pActionHistory->first();
+ while(act && (act->tTime < tMinimum))
+ {
+ if(act->iTemperature > 0)m_uActionHistoryHotActionCount--;
+ m_pActionHistory->removeFirst();
+ act = m_pActionHistory->first();
+ }
+}
+
+
+void KviChannel::lostUserFocus()
+{
+ KviWindow::lostUserFocus();
+ if(!m_pMessageView)return;
+ if(m_pMessageView->hasLineMark())m_pMessageView->clearLineMark(true);
+}
+
+
+void KviChannel::getChannelActivityStats(KviChannelActivityStats * s)
+{
+ fixActionHistory();
+
+ s->uActionCount = m_pActionHistory->count();
+ s->iAverageActionTemperature = 0;
+ s->uActionsInTheLastMinute = 0;
+ s->uHotActionCount = 0;
+ s->uHotActionPercent = 0;
+ s->bStatsInaccurate = false;
+
+ if(s->uActionCount < 1)
+ {
+ // nothing is happening
+ s->uLastActionTimeSpan = 0;
+ s->uFirstActionTimeSpan = 0;
+ s->dActionsPerMinute = 0;
+
+ return;
+ }
+
+ kvi_time_t tNow = kvi_unixTime();
+
+ KviChannelAction * a = m_pActionHistory->last();
+ s->uLastActionTimeSpan = tNow - a->tTime;
+
+ a = m_pActionHistory->first();
+ s->uFirstActionTimeSpan = tNow - a->tTime;
+
+ double dSpan = (double)s->uFirstActionTimeSpan;
+
+ if(s->uActionCount < KVI_CHANNEL_ACTION_HISTORY_MAX_COUNT)
+ {
+ if(m_joinTime.secsTo(QDateTime::currentDateTime()) < KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN)
+ {
+ // we can't exactly estimate
+ s->bStatsInaccurate = true;
+ if(dSpan < 60.0)dSpan = 60.0;
+ } else {
+ // there are less actions at all or they have been pushed out because of the timespan
+ dSpan = KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN;
+ }
+ } // else the actions have been pushed out of the history because they were too much
+
+ if(dSpan > 0.0)
+ s->dActionsPerMinute = (((double)s->uActionCount) / (dSpan)) * 60.0;
+ else
+ s->dActionsPerMinute = (double)s->uActionCount; // ???
+
+ kvi_time_t tTwoMinsAgo = tNow;
+ tTwoMinsAgo-= 120;
+ tNow -= 60;
+
+ KviPointerHashTable<QString,int> userDict;
+ userDict.setAutoDelete(false);
+
+ int fake;
+ s->lTalkingUsers.clear();
+ s->lWereTalkingUsers.clear();
+
+ for(a = m_pActionHistory->last();a;a = m_pActionHistory->prev())
+ {
+ if(a->tTime >= tNow)s->uActionsInTheLastMinute++;
+
+ if(a->iTemperature > 0)s->uHotActionCount++;
+ s->iAverageActionTemperature += a->iTemperature;
+
+ if((a->uActionType == KVI_USERACTION_PRIVMSG) ||
+ (a->uActionType == KVI_USERACTION_NOTICE) ||
+ (a->uActionType == KVI_USERACTION_ACTION))
+ {
+ if(!userDict.find(a->szNick))
+ {
+ if(isOn(a->szNick.ascii()))
+ {
+ if(a->tTime >= tTwoMinsAgo)s->lTalkingUsers.append(a->szNick);
+ else s->lWereTalkingUsers.append(a->szNick);
+ userDict.insert(a->szNick,&fake);
+ }
+ }
+ }
+ }
+
+ s->iAverageActionTemperature = s->iAverageActionTemperature / (int)s->uActionCount;
+
+ s->uHotActionPercent = (s->uHotActionCount * 100) / s->uActionCount;
+}
+
+
+
+void KviChannel::userAction(const QString &nick,const QString &user,const QString &host,unsigned int uActionType)
+{
+ int iTemperature = kvi_getUserActionTemperature(uActionType);
+ channelAction(nick,uActionType,iTemperature);
+ m_pUserListView->userAction(nick,user,host,iTemperature);
+}
+
+void KviChannel::userAction(const QString &nick,unsigned int uActionType)
+{
+ int iTemperature = kvi_getUserActionTemperature(uActionType);
+ channelAction(nick,uActionType,iTemperature);
+ m_pUserListView->userAction(nick,iTemperature);
+}
+
+void KviChannel::userAction(KviIrcMask * user,unsigned int uActionType)
+{
+ int iTemperature = kvi_getUserActionTemperature(uActionType);
+ channelAction(user->nick(),uActionType,iTemperature);
+ m_pUserListView->userAction(user,iTemperature);
+}
+
+void KviChannel::topicSelected(const QString & topic)
+{
+ if(!connection())return;
+ KviQCString szEncoded = encodeText(topic);
+ KviQCString szName = connection()->encodeText(m_szName);
+ connection()->sendFmtData("TOPIC %s :%s",szName.data(),szEncoded.length() ? szEncoded.data() : "");
+}
+
+void KviChannel::closeEvent(QCloseEvent *e)
+{
+ if((m_iStateFlags & KVI_CHANNEL_STATE_SENTPART) || (m_iStateFlags & KVI_CHANNEL_STATE_DEADCHAN) || !(m_pConsole->isConnected()))
+ {
+ m_pContext->unregisterDeadChannel(this);
+ KviWindow::closeEvent(e);
+ } else {
+ e->ignore();
+ // FIXME: #warning "THIS PART SHOULD BECOME A COMMAND /PART $option()..so the identifiers are parsed"
+ if(connection())
+ {
+ QString tmp = KVI_OPTION_STRING(KviOption_stringPartMessage);
+ tmp.replace(";","\\;");
+ tmp.replace("\n"," ");
+ KviKvsVariant vRet;
+
+ if(KviKvsScript::evaluate(tmp,this,0,&vRet))vRet.asString(tmp);
+
+ KviQCString dat = encodeText(tmp);
+ partMessageSent();
+ KviQCString szName = connection()->encodeText(m_szName);
+ connection()->sendFmtData("PART %s :%s",szName.data(),dat.data() ? dat.data() : "");
+ // be sure to not reference ourselves here.. we could be disconnected!
+ } else {
+ partMessageSent(); // huh ?
+ }
+ }
+}
+
+void KviChannel::partMessageSent(bool bCloseOnPart,bool bShowMessage)
+{
+ m_iStateFlags |= KVI_CHANNEL_STATE_SENTPART;
+ if(!bCloseOnPart)m_iStateFlags |= KVI_CHANNEL_STATE_NOCLOSEONPART;
+ if(bShowMessage)outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Sent part request, waiting for reply..."));
+}
+
+#define IS_FNC(__name,__ulvname) \
+bool KviChannel::__name(bool bAtLeast) \
+{ \
+ if(!connection())return false; \
+ return m_pUserListView->__ulvname(connection()->currentNickName(),bAtLeast); \
+}
+
+IS_FNC(isMeChanOwner,isChanOwner)
+IS_FNC(isMeChanAdmin,isChanAdmin)
+IS_FNC(isMeOp,isOp)
+IS_FNC(isMeVoice,isVoice)
+IS_FNC(isMeHalfOp,isHalfOp)
+IS_FNC(isMeUserOp,isUserOp)
+
+int KviChannel::myFlags()
+{
+ if(!connection())return 0;
+ return m_pUserListView->flags(connection()->currentNickName());
+}
+
+
+void KviChannel::setMask(char flag, const QString &mask,bool bAdd,const QString &setBy,unsigned int setAt)
+{
+ if(!connection())return;
+ KviPointerList<KviMaskEntry> * list = m_pBanList;
+ KviMaskEditor * editor = m_pBanEditor;
+ switch(flag)
+ {
+ case 'b':
+ m_iStateFlags ^= KVI_CHANNEL_STATE_HAVEBANLIST;
+ break;
+ case 'e':
+ m_iStateFlags ^= KVI_CHANNEL_STATE_HAVEBANEXCEPTIONLIST;
+ list = m_pBanExceptionList;
+ editor = m_pBanExceptionEditor;
+ break;
+ case 'I':
+ m_iStateFlags ^= KVI_CHANNEL_STATE_HAVEINVITELIST;
+ list = m_pInviteList;
+ editor = m_pInviteEditor;
+ break;
+ }
+
+ internalMask(mask,bAdd,setBy,setAt,list,&editor);
+ m_pUserListView->setMaskEntries(flag,(int)list->count());
+}
+
+void KviChannel::internalMask(const QString &mask,bool bAdd,const QString &setBy,unsigned int setAt,KviPointerList<KviMaskEntry> *l,KviMaskEditor **ppEd)
+{
+ KviMaskEntry * e = 0;
+ if(bAdd)
+ {
+ for(e = l->first();e;e = l->next())
+ {
+ if(KviQString::equalCI(e->szMask,mask))return; //already there
+ }
+ e = new KviMaskEntry;
+ e->szMask = mask;
+ e->szSetBy = (!setBy.isEmpty()) ? setBy : __tr2qs("(Unknown)");
+ e->uSetAt = setAt;
+ l->append(e);
+ if(*ppEd)(*ppEd)->addMask(e);
+ } else {
+ for(e = l->first();e;e = l->next())
+ {
+ if(KviQString::equalCI(e->szMask,mask))break;
+ }
+ if(e)
+ {
+ if(*ppEd)(*ppEd)->removeMask(e);
+ l->removeRef(e);
+ }
+ }
+}
+
+void KviChannel::updateModeLabel()
+{
+ QString tmp = m_szChannelMode;
+ QString tip = __tr2qs("<b>Channel mode:</b>");
+ //const char * aux = m_szChannelMode.utf8().data(); leaks memory and will not work with getChannelModeDescription() (can channel modes be multibyte ?)
+ KviStr mod = m_szChannelMode;
+ const char * aux = mod.ptr();
+ while(*aux)
+ {
+ KviQString::appendFormatted(tip,"<br>%c: %Q",*aux,&(m_pConsole->connection()->serverInfo()->getChannelModeDescription(*aux)));
+ ++aux;
+ }
+
+ if(!m_szChannelKey.isEmpty())
+ {
+ if(!tmp.isEmpty())tmp.append(' ');
+ KviQString::appendFormatted(tmp,"k:%s",m_szChannelKey.utf8().data());
+ KviQString::appendFormatted(tip,__tr2qs("<br><b>Key:</b> %s"),m_szChannelKey.utf8().data());
+ }
+
+ if(m_szChannelLimit.hasData())
+ {
+ if(!tmp.isEmpty())tmp.append(' ');
+ KviQString::appendFormatted(tmp,"l:%s",m_szChannelLimit.ptr());
+ KviQString::appendFormatted(tip,__tr2qs("<br><b>Limit:</b> %s"),m_szChannelLimit.ptr());
+ }
+
+ m_pModeWidget->refreshModes();
+ KviTalToolTip::remove(m_pModeWidget);
+ KviTalToolTip::add(m_pModeWidget,tip);
+}
+
+/*
+void KviChannel::outputMessage(int msg_type,const char *format,...)
+{
+ kvi_wchar_t txt_ptr[512]; //It should be enough for all outputs...
+ kvi_va_list list;
+ kvi_va_start(list,format);
+ if(kvi_wvsnprintcf(txt_ptr,512,format,list) < 0){
+ //Just in case...
+ kvi_va_end(list);
+ int len = 512;
+ kvi_wchar_t *long_txt_ptr = 0;
+ int result;
+ do{
+ len += 512;
+ //first time long_txt_ptr == 0 so it is equivalent to malloc
+ //At least the man page says that...
+ long_txt_ptr = (kvi_wchar_t *)kvi_realloc((void *)long_txt_ptr,len * sizeof(kvi_wchar_t));
+ kvi_va_start(list,format);
+ result = kvi_wvsnprintcf(long_txt_ptr,len,format,list);
+ kvi_va_end(list);
+ } while(result < 0);
+ internalOutput(m_pMessageView ? m_pMessageView : m_pIrcView,msg_type,long_txt_ptr);
+ kvi_free((void *)long_txt_ptr);
+ } else {
+ //Succesful vsnprintf
+ kvi_va_end(list);
+ internalOutput(m_pMessageView ? m_pMessageView : m_pIrcView,msg_type,txt_ptr);
+ }
+}
+*/
+
+void KviChannel::outputMessage(int msg_type,const QString &msg)
+{
+ QString szBuf(msg);
+ preprocessMessage(szBuf);
+ const QChar * pC = KviQString::nullTerminatedArray(szBuf);
+ if(!pC)return;
+ internalOutput(m_pMessageView ? m_pMessageView : m_pIrcView,msg_type,(const kvi_wchar_t *)pC);
+}
+
+
+
+void KviChannel::checkChannelSync()
+{
+ if(m_iStateFlags & KVI_CHANNEL_STATE_SYNCHRONIZED)return;
+
+ if(m_iStateFlags & KVI_CHANNEL_STATE_SENTWHOREQUEST)
+ {
+ if(!(m_iStateFlags & KVI_CHANNEL_STATE_HAVEWHOLIST))return;
+ }
+
+ if(m_iStateFlags & KVI_CHANNEL_STATE_SENTBANLISTREQUEST)
+ {
+ if(!(m_iStateFlags & KVI_CHANNEL_STATE_HAVEBANLIST))return;
+ }
+
+ if(m_iStateFlags & KVI_CHANNEL_STATE_SENTBANEXCEPTIONLISTREQUEST)
+ {
+ if(!(m_iStateFlags & KVI_CHANNEL_STATE_HAVEBANEXCEPTIONLIST))return;
+ }
+
+ if(m_iStateFlags & KVI_CHANNEL_STATE_SENTINVITELISTREQUEST)
+ {
+ if(!(m_iStateFlags & KVI_CHANNEL_STATE_HAVEINVITELIST))return;
+ }
+
+ m_iStateFlags |= KVI_CHANNEL_STATE_SYNCHRONIZED;
+ // we already have all the spontaneous server replies
+ // (so probably mode, topic (or no topic is set),names)
+ // we have already received the I and e lists (if requested)
+ kvs_int_t iSyncTime = m_joinTime.time().msecsTo(QTime::currentTime());
+ if(iSyncTime < 0)iSyncTime += 86400000;
+
+ bool bStop = KVS_TRIGGER_EVENT_1_HALTED(KviEvent_OnChannelSync,this,iSyncTime);
+
+ if(!bStop && KVI_OPTION_BOOL(KviOption_boolShowChannelSyncTime))
+ {
+ output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Channel synchronized in %d.%d seconds"),iSyncTime / 1000,iSyncTime % 1000);
+ }
+}
+
+bool KviChannel::eventFilter(QObject * o, QEvent * e)
+{
+ if(e->type() == QEvent::FocusOut && o == m_pTopicWidget && \
+ m_pTopicWidget->isVisible())
+ m_pTopicWidget->deactivate();
+
+ return KviWindow::eventFilter(o, e);
+}
+
+
+void KviChannel::preprocessMessage(QString & szMessage)
+{
+ QStringList strings = QStringList::split(" ",szMessage, TRUE);
+ for ( QStringList::Iterator it = strings.begin(); it != strings.end(); ++it ) {
+ if((*it).contains('\r')) continue;
+ QString tmp = KviMircCntrl::stripControlBytes(*it);
+ if( findEntry(*it) ) *it=QString("\r!n\r%1\r").arg(*it);
+ if(m_pConsole)
+ if(m_pConsole->connection())
+ if(m_pConsole->connection()->serverInfo()->supportedChannelTypes().contains(tmp[0]))
+ if((*it)==tmp)
+ *it=QString("\r!c\r%1\r").arg(*it);
+ else
+ *it=QString("\r!c%1\r%2\r").arg(tmp).arg(*it);
+ }
+ szMessage=strings.join(" ");
+}
+
+void KviChannel::unhighlight()
+{
+ if(!m_pTaskBarItem)return;
+ m_pTaskBarItem->unhighlight();
+}
+
+#include "kvi_channel.moc"
diff --git a/src/kvirc/ui/kvi_channel.h b/src/kvirc/ui/kvi_channel.h
new file mode 100644
index 0000000..0efdabb
--- /dev/null
+++ b/src/kvirc/ui/kvi_channel.h
@@ -0,0 +1,313 @@
+#ifndef _KVI_CHANNEL_H_
+#define _KVI_CHANNEL_H_
+//=============================================================================
+//
+// File : kvi_channel.h
+// Creation date : Tue Aug 1 2000 01:42:00 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+
+#include "kvi_console.h"
+#include "kvi_window.h"
+#include "kvi_string.h"
+#include "kvi_ircuserdb.h"
+#include "kvi_pixmap.h"
+#include "kvi_userlistview.h"
+#include "kvi_time.h"
+#include "kvi_modew.h"
+#include "kvi_valuelist.h"
+
+#include <qdatetime.h>
+#include "kvi_pointerhashtable.h"
+#include <qstringlist.h>
+
+class KviConsole;
+class QSplitter;
+class QToolButton;
+class KviTopicWidget;
+class KviIrcMask;
+class KviThemedLabel;
+class KviTalHBox;
+
+#ifdef COMPILE_ON_WINDOWS
+ // windows compiler wants this instead of the forward decl
+ #include "kvi_maskeditor.h"
+#else
+ typedef struct _KviMaskEntry KviMaskEntry; // kvi_maskeditor.h
+#endif
+class KviMaskEditor;
+class KviModeEditor;
+
+#define KVI_CHANNEL_STATE_HAVEALLNAMES 1
+#define KVI_CHANNEL_STATE_HAVEBANLIST (1 << 1)
+#define KVI_CHANNEL_STATE_HAVEWHOLIST (1 << 2)
+#define KVI_CHANNEL_STATE_HAVEBANEXCEPTIONLIST (1 << 3)
+#define KVI_CHANNEL_STATE_HAVEINVITELIST (1 << 4)
+#define KVI_CHANNEL_STATE_DEADCHAN (1 << 5)
+
+#define KVI_CHANNEL_STATE_SENTBANLISTREQUEST (1 << 6)
+#define KVI_CHANNEL_STATE_SENTBANEXCEPTIONLISTREQUEST (1 << 7)
+#define KVI_CHANNEL_STATE_SENTINVITELISTREQUEST (1 << 8)
+#define KVI_CHANNEL_STATE_SENTWHOREQUEST (1 << 9)
+
+#define KVI_CHANNEL_STATE_SENTPART (1 << 10)
+#define KVI_CHANNEL_STATE_SYNCHRONIZED (1 << 11)
+
+#define KVI_CHANNEL_STATE_NOCLOSEONPART (1 << 12)
+
+#define KVI_CHANNEL_STATE_SENTSYNCWHOREQUEST (1 << 13)
+
+typedef struct _KviChannelAction
+{
+ QString szNick; // action source nick
+ unsigned int uActionType; // type of the action
+ kvi_time_t tTime; // time of the action
+ int iTemperature; // temperature of the action
+} KviChannelAction;
+
+// this is the maximum count of actions that we keep in memory
+#define KVI_CHANNEL_ACTION_HISTORY_MAX_COUNT 40
+// this is the timespan of the oldest action that we keep in memory
+// 600 secs = 10 mins
+#define KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN 600
+
+typedef struct _KviChannelActivityStats
+{
+ unsigned int uActionCount; // number of actions in the history
+ bool bStatsInaccurate; // the stats are inaccurate because we have just joined the chan
+ unsigned int uLastActionTimeSpan; // the timespan between the last action and now
+ unsigned int uFirstActionTimeSpan; // the time span between the first and the last action
+ double dActionsPerMinute; // average number of actions per minute in the lastActionTimeSpan
+ unsigned int uActionsInTheLastMinute; // number of actions in the last minute
+ int iAverageActionTemperature; // the average chan temperature
+ unsigned int uHotActionCount;
+ unsigned int uHotActionPercent;
+ QStringList lTalkingUsers; // users that seem to be talking NOW
+ QStringList lWereTalkingUsers;
+} KviChannelActivityStats;
+
+class KVIRC_API KviChannel : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviChannel(KviFrame * lpFrm,KviConsole * lpConsole,const char * name);
+ ~KviChannel();
+protected:
+ QSplitter * m_pTopSplitter;
+ QSplitter * m_pVertSplitter;
+ BUTTON_CLASS * m_pDoubleViewButton;
+ KviWindowToolPageButton * m_pListViewButton;
+ KviWindowToolPageButton * m_pBanEditorButton;
+ KviWindowToolPageButton * m_pBanExceptionEditorButton;
+ KviWindowToolPageButton * m_pInviteEditorButton;
+ KviWindowToolPageButton * m_pModeEditorButton;
+ KviMaskEditor * m_pBanEditor;
+ KviMaskEditor * m_pBanExceptionEditor;
+ KviMaskEditor * m_pInviteEditor;
+ KviModeEditor * m_pModeEditor;
+ KviIrcView * m_pMessageView;
+ KviTopicWidget * m_pTopicWidget;
+ KviUserListView * m_pUserListView;
+ KviModeWidget * m_pModeWidget;
+ int m_iStateFlags;
+ QString m_szChannelMode;
+ QString m_szChannelKey;
+ KviStr m_szChannelLimit;
+ KviPointerList<KviMaskEntry> * m_pBanList;
+ KviPointerList<KviMaskEntry> * m_pBanExceptionList;
+ KviPointerList<KviMaskEntry> * m_pInviteList;
+ KviPixmap m_privateBackground;
+ QDateTime m_joinTime;
+ QString m_szNameWithUserFlag;
+ KviPointerHashTable<const char *,QString> * m_pTmpHighLighted;
+ unsigned int m_uActionHistoryHotActionCount;
+ KviPointerList<KviChannelAction> * m_pActionHistory;
+ kvi_time_t m_tLastReceivedWhoReply;
+ KviValueList<int> m_VertSplitterSizesList;
+ KviTalHBox * m_pButtonContainer;
+protected:
+ bool eventFilter(QObject *, QEvent *);
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void closeEvent(QCloseEvent *e);
+// virtual void fillContextPopup(KviTalPopupMenu * p);
+ virtual void getConfigGroupName(QString &buf);
+ virtual void saveProperties(KviConfig * cfg);
+ virtual void loadProperties(KviConfig * cfg);
+ virtual void applyOptions();
+ virtual void getBaseLogFileName(QString &buffer);
+ virtual void triggerCreationEvents();
+ void toggleEditor(KviMaskEditor ** ppEd,KviWindowToolPageButton ** ppBtn,KviPointerList<KviMaskEntry> *l,char flag,const char *edName);
+ void internalMask(const QString &mask,bool bAdd,const QString &setBy,unsigned int setAt,KviPointerList<KviMaskEntry> *l,KviMaskEditor **ppEd);
+ void checkChannelSync();
+ void showDoubleView(bool bShow);
+ void fixActionHistory();
+ void getTalkingUsersStats(QString &buffer,QStringList &l,bool bPast);
+public:
+ void getChannelActivityStats(KviChannelActivityStats * s);
+ //void getChannelActivityStatsDescription(QString &buffer);
+
+ KviPointerList<KviMaskEntry> * banList(){ return m_pBanList; };
+ KviPointerList<KviMaskEntry> * banExceptionList(){ return m_pBanExceptionList; };
+ KviPointerList<KviMaskEntry> * inviteList(){ return m_pInviteList; };
+
+ QString * firstSelectedNickname(){ return m_pUserListView->firstSelectedNickname(); };
+ QString * nextSelectedNickname(){ return m_pUserListView->nextSelectedNickname(); };
+
+ int selectedCount(){ return m_pUserListView->selectedCount(); };
+ int opCount(){ return m_pUserListView->opCount(); };
+ int voiceCount(){ return m_pUserListView->voiceCount(); };
+ int halfOpCount(){ return m_pUserListView->halfOpCount(); };
+ int userOpCount(){ return m_pUserListView->userOpCount(); };
+ int chanAdminCount(){ return m_pUserListView->chanAdminCount(); };
+ int chanOwnerCount(){ return m_pUserListView->chanOwnerCount(); };
+ unsigned int count(){ return m_pUserListView->count(); };
+
+ unsigned int banCount(){ return m_pBanList->count(); };
+ unsigned int banExceptionCount(){ return m_pBanExceptionList->count(); };
+ unsigned int inviteCount(){ return m_pInviteList->count(); };
+
+ const QString & nameWithUserFlag(){ return m_szNameWithUserFlag; };
+ virtual const QString & target(){ return windowName(); };
+// void appendSelectedNicknames(KviStr &buffer);
+ void setMask(char flag, const QString &mask,bool bAdd,const QString &setBy,unsigned int setAt);
+
+ kvi_time_t lastReceivedWhoReply(){ return m_tLastReceivedWhoReply; };
+ void setLastReceivedWhoReply(kvi_time_t tTime){ m_tLastReceivedWhoReply = tTime; };
+ void setSentSyncWhoRequest(){ m_iStateFlags |= KVI_CHANNEL_STATE_SENTSYNCWHOREQUEST; };
+ void clearSentSyncWhoRequest(){ m_iStateFlags ^= KVI_CHANNEL_STATE_SENTSYNCWHOREQUEST; };
+ bool sentSyncWhoRequest(){ return (m_iStateFlags & KVI_CHANNEL_STATE_SENTSYNCWHOREQUEST); };
+
+ bool sentWhoRequest(){ return (m_iStateFlags & KVI_CHANNEL_STATE_SENTWHOREQUEST); };
+ void setSentWhoRequest(){ m_iStateFlags |= KVI_CHANNEL_STATE_SENTWHOREQUEST; };
+ bool sentInviteListRequest(){ return (m_iStateFlags & KVI_CHANNEL_STATE_SENTINVITELISTREQUEST); };
+ void setSentInviteListRequest(){ m_iStateFlags |= KVI_CHANNEL_STATE_SENTINVITELISTREQUEST; };
+ void setInviteListDone(){ m_iStateFlags ^= KVI_CHANNEL_STATE_SENTINVITELISTREQUEST; };
+ bool sentBanListRequest(){ return (m_iStateFlags & KVI_CHANNEL_STATE_SENTBANLISTREQUEST); };
+ void setSentBanListRequest(){ m_iStateFlags |= KVI_CHANNEL_STATE_SENTBANLISTREQUEST; };
+ void setBanListDone(){ m_iStateFlags ^= KVI_CHANNEL_STATE_SENTBANLISTREQUEST; };
+ bool sentBanExceptionListRequest(){ return (m_iStateFlags & KVI_CHANNEL_STATE_SENTBANEXCEPTIONLISTREQUEST); };
+ void setSentBanExceptionListRequest(){ m_iStateFlags |= KVI_CHANNEL_STATE_SENTBANEXCEPTIONLISTREQUEST; };
+ void setBanExceptionListDone(){ m_iStateFlags ^= KVI_CHANNEL_STATE_SENTBANEXCEPTIONLISTREQUEST; };
+
+ bool hasAllNames(){ return (m_iStateFlags & KVI_CHANNEL_STATE_HAVEALLNAMES); };
+ void setHasAllNames(){ m_iStateFlags |= KVI_CHANNEL_STATE_HAVEALLNAMES; checkChannelSync(); };
+ bool hasInviteList(){ return (m_iStateFlags & KVI_CHANNEL_STATE_HAVEINVITELIST); checkChannelSync(); };
+ void setHasInviteList(){ m_iStateFlags |= KVI_CHANNEL_STATE_HAVEINVITELIST; };
+ bool hasWhoList(){ return (m_iStateFlags & KVI_CHANNEL_STATE_HAVEWHOLIST); };
+ void setHasWhoList(){ m_iStateFlags |= KVI_CHANNEL_STATE_HAVEWHOLIST; checkChannelSync(); };
+ bool hasBanList(){ return (m_iStateFlags & KVI_CHANNEL_STATE_HAVEBANLIST); };
+ void setHasBanList(){ m_iStateFlags |= KVI_CHANNEL_STATE_HAVEBANLIST; checkChannelSync(); };
+ bool hasBanExceptionList(){ return (m_iStateFlags & KVI_CHANNEL_STATE_HAVEBANEXCEPTIONLIST); };
+ void setHasBanExceptionList(){ m_iStateFlags |= KVI_CHANNEL_STATE_HAVEBANEXCEPTIONLIST; checkChannelSync(); };
+
+ bool closeOnPart(){ return !(m_iStateFlags & KVI_CHANNEL_STATE_NOCLOSEONPART); };
+ void partMessageSent(bool bCloseOnPart = true,bool bShowMessage = true);
+
+ virtual bool activityMeter(unsigned int * puActivityValue,unsigned int * puActivityTemperature);
+
+ void setDeadChan();
+ void setAliveChan();
+ void prependUserFlag(const QString &nick,QString &buffer){ m_pUserListView->prependUserFlag(nick,buffer); };
+ char getUserFlag(const QString &nick){ return m_pUserListView->getUserFlag(nick); };
+ bool isDeadChan(){ return (m_iStateFlags & KVI_CHANNEL_STATE_DEADCHAN); };
+ virtual QSize sizeHint() const;
+ void enableUserListUpdates(bool bEnable){ m_pUserListView->enableUpdates(bEnable); };
+ KviUserListEntry * join(const QString &nick,const QString &user = QString::null,const QString &host = QString::null,int iFlags = 0)
+ { return m_pUserListView->join(nick,user,host,iFlags); };
+ bool op(const QString &nick,bool bOp){ return m_pUserListView->op(nick,bOp); };
+ bool avatarChanged(const QString &nick){ return m_pUserListView->avatarChanged(nick); };
+ bool voice(const QString &nick,bool bVoice){ return m_pUserListView->voice(nick,bVoice); };
+ bool halfop(const QString &nick,bool bHalfOp){ return m_pUserListView->halfop(nick,bHalfOp); };
+ bool userop(const QString &nick,bool bUserOp){ return m_pUserListView->userop(nick,bUserOp); };
+ bool setChanOwner(const QString &nick,bool bChanOwner){ return m_pUserListView->setChanOwner(nick,bChanOwner); };
+ bool setChanAdmin(const QString &nick,bool bChanAdmin){ return m_pUserListView->setChanAdmin(nick,bChanAdmin); };
+ void userAction(KviIrcMask * user,unsigned int uActionType);
+ void userAction(const QString &nick,unsigned int uActionType);
+ void userAction(const QString &nick,const QString &user,const QString &host,unsigned int uActionType);
+ bool nickChange(const QString &oldNick,const QString &newNick);
+ void channelAction(const QString &nick,unsigned int uActionType,int iTemperature);
+ bool part(const QString &nick);
+ bool isOn(const QString &nick){ return (m_pUserListView->findEntry(nick) != 0); };
+ KviUserListEntry * findEntry(const QString &nick){ return m_pUserListView->findEntry(nick); };
+ KviUserListView * userListView(){ return m_pUserListView; };
+ bool isMeOp(bool bAtLeast = false);
+ bool isMeChanOwner(bool bAtLeast = false);
+ bool isMeChanAdmin(bool bAtLeast = false);
+ bool isMeVoice(bool bAtLeast = false);
+ bool isMeHalfOp(bool bAtLeast = false);
+ bool isMeUserOp(bool bAtLeast = false);
+ bool isOp(const QString &nick,bool bAtLeast = false){ return m_pUserListView->isOp(nick,bAtLeast); };
+ bool isVoice(const QString &nick,bool bAtLeast = false){ return m_pUserListView->isVoice(nick,bAtLeast); };
+ bool isHalfOp(const QString &nick,bool bAtLeast = false){ return m_pUserListView->isHalfOp(nick,bAtLeast); };
+ bool isUserOp(const QString &nick,bool bAtLeast = false){ return m_pUserListView->isUserOp(nick,bAtLeast); };
+ bool isChanOwner(const QString &nick,bool bAtLeast = false){ return m_pUserListView->isChanOwner(nick,bAtLeast); };
+ bool isChanAdmin(const QString &nick,bool bAtLeast = false){ return m_pUserListView->isChanAdmin(nick,bAtLeast); };
+ int myFlags();
+ void updateModeLabel();
+ KviTopicWidget * topicWidget(){ return m_pTopicWidget; };
+ virtual void outputMessage(int msg_type,const QString &msg);
+ void ownMessage(const QString &buffer);
+ void ownAction(const QString &buffer);
+ void setChannelMode(char mode,bool bAdd);
+ void setChannelKey(const char * key);
+ void setChannelLimit(const char * limit);
+
+ void getChannelModeString(QString &buffer);
+
+ KviStr & channelLimit(){ return m_szChannelLimit; };
+ bool hasChannelLimit(){ return m_szChannelLimit.hasData(); };
+
+ bool hasChannelKey() { return !m_szChannelKey.isEmpty(); };
+ QString & channelKey(){ return m_szChannelKey; };
+
+ void addHighlightedUser(const char * nick);
+ void removeHighlightedUser(const char * nick);
+ bool isHighlightedUser(const char * nick) { return m_pTmpHighLighted->find(nick); };
+ KviIrcView * messageView() const { return m_pMessageView; };
+ virtual void lostUserFocus();
+ virtual void getTaskBarTipText(QString &buffer);
+ QString channelMode() { return m_szChannelMode; };
+
+ void unhighlight();
+
+ QFrame * buttonContainer() { return (QFrame*)m_pButtonContainer; };
+private slots:
+ void toggleDoubleView();
+ void toggleListView();
+ void toggleBanEditor();
+ void toggleBanExceptionEditor();
+ void toggleInviteEditor();
+ void toggleModeEditor();
+ void topicSelected(const QString & topic);
+ void setMode(const char * mode);
+ void modeSelectorDone();
+ void textViewRightClicked();
+ void removeMasks(KviMaskEditor *ed,KviPointerList<KviMaskEntry> *l);
+ void toggleToolButtons();
+protected:
+ virtual void preprocessMessage(QString & szMessage);
+};
+
+#endif //_KVI_CHANNEL_H_
diff --git a/src/kvirc/ui/kvi_colorwin.cpp b/src/kvirc/ui/kvi_colorwin.cpp
new file mode 100644
index 0000000..9cc1c6e
--- /dev/null
+++ b/src/kvirc/ui/kvi_colorwin.cpp
@@ -0,0 +1,122 @@
+//=============================================================================
+//
+// File : kvi_colorwin.cpp
+// Creation date : Wed Jan 6 1999 04:30:20 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2007 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_colorwin.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+
+
+#include <qnamespace.h>
+#include <qpainter.h>
+#include <qstring.h>
+#include <qevent.h>
+
+
+KviColorWindow::KviColorWindow()
+:QWidget(0,"toplevel_color_window",Qt::WType_Popup)
+{
+#ifdef COMPILE_USE_QT4
+ setFocusPolicy(Qt::NoFocus);
+#else
+ setFocusPolicy(QWidget::NoFocus);
+#endif
+ setBackgroundMode(Qt::NoBackground);
+ setFixedSize(146,38);
+ m_pOwner = 0;
+ QFont fnt = QFont();
+ fnt.setStyleHint(QFont::TypeWriter);
+ fnt.setPointSize(10);
+ //QFont fnt("fixed",10);
+ setFont(fnt);
+ m_iTimerId = -1;
+}
+
+KviColorWindow::~KviColorWindow()
+{
+ if(m_iTimerId != -1)
+ killTimer(m_iTimerId);
+// if(m_pOwner)m_pOwner->setFocus();
+}
+
+void KviColorWindow::popup(QWidget *owner)
+{
+ m_pOwner = owner;
+ show();
+}
+
+
+void KviColorWindow::paintEvent(QPaintEvent *)
+{
+ static int clrIdx[16]={ 1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1 };
+ QPainter p(this);
+
+ for(int i=0;i<16;i++)
+ {
+ p.fillRect((i % 8) * 18,(i / 8) * 18,18,18,KVI_OPTION_MIRCCOLOR(i));
+ p.setPen(KVI_OPTION_MIRCCOLOR(clrIdx[i]));
+ KviStr szI(KviStr::Format,"%d",i);
+ p.drawText((i % 8) * 18,(i / 8) * 18,18,18,Qt::AlignVCenter | Qt::AlignHCenter,szI.ptr());
+ }
+}
+
+void KviColorWindow::keyPressEvent(QKeyEvent *e)
+{
+ if(m_iTimerId != -1)
+ killTimer(m_iTimerId);
+ hide();
+ if(m_pOwner)g_pApp->sendEvent(m_pOwner,e);
+}
+
+void KviColorWindow::mousePressEvent(QMouseEvent *e)
+{
+ QString str;
+ int key=e->x()/18;
+ if (e->x()<36 && e->y()>18) key +=8;
+ if (e->x()>36 && e->y()>18) key -=2;
+ int ascii=key+48;
+ str.setNum(key);
+ if (e->x()>36 && e->y()>18)
+ if(m_pOwner) g_pApp->sendEvent(m_pOwner,new QKeyEvent(QEvent::KeyPress,Qt::Key_1,49,Qt::NoButton,"1"));
+ if(m_pOwner) g_pApp->sendEvent(m_pOwner,new QKeyEvent(QEvent::KeyPress,key,ascii,Qt::NoButton,str));
+ if(m_iTimerId != -1)
+ killTimer(m_iTimerId);
+ hide();
+}
+void KviColorWindow::show()
+{
+ m_iTimerId = startTimer(10000); //10 sec ...seems enough
+ QWidget::show();
+}
+
+void KviColorWindow::timerEvent(QTimerEvent *)
+{
+ if(m_iTimerId != -1)
+ killTimer(m_iTimerId);
+ hide();
+}
+
+
+#include "kvi_colorwin.moc"
diff --git a/src/kvirc/ui/kvi_colorwin.h b/src/kvirc/ui/kvi_colorwin.h
new file mode 100644
index 0000000..21cf1ae
--- /dev/null
+++ b/src/kvirc/ui/kvi_colorwin.h
@@ -0,0 +1,47 @@
+#ifndef _KVI_COLORWIN_H_
+#define _KVI_COLORWIN_H_
+//
+// File : kvi_colorwin.h
+// Creation date : Wed Jan 6 1999 04:27:45 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#include "kvi_settings.h"
+
+#include <qwidget.h>
+
+class KVIRC_API KviColorWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ KviColorWindow();
+ ~KviColorWindow();
+private:
+ QWidget *m_pOwner;
+ int m_iTimerId;
+public:
+ void popup(QWidget *owner);
+private:
+ virtual void show();
+ virtual void paintEvent(QPaintEvent *);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void timerEvent(QTimerEvent *);
+};
+
+#endif //_KVI_COLORWIN_H_
diff --git a/src/kvirc/ui/kvi_console.cpp b/src/kvirc/ui/kvi_console.cpp
new file mode 100644
index 0000000..df0bd70
--- /dev/null
+++ b/src/kvirc/ui/kvi_console.cpp
@@ -0,0 +1,1283 @@
+//=============================================================================
+//
+// File : kvi_console.cpp
+// Creation date : Sun Jun 25 2000 15:01:34 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+
+// FIXME: The TextEncoding should be inherited from network!
+
+#define __KVIRC__
+
+#include "kvi_ircurl.h"
+#include "kvi_app.h"
+#include "kvi_console.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_ircview.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_input.h"
+#include "kvi_error.h"
+#include "kvi_proxydb.h"
+#include "kvi_netutils.h"
+#include "kvi_ircserver.h"
+#include "kvi_ircserverdb.h"
+#include "kvi_dns.h"
+#include "kvi_defaults.h"
+#include "kvi_ircuserdb.h"
+#include "kvi_channel.h"
+#include "kvi_query.h"
+#include "kvi_parameterlist.h"
+#include "kvi_regusersdb.h"
+#include "kvi_userlistview.h"
+#include "kvi_out.h"
+#include "kvi_config.h"
+#include "kvi_irctoolbar.h"
+#include "kvi_internalcmd.h"
+#include "kvi_sparser.h"
+#include "kvi_themedlabel.h"
+#include "kvi_garbage.h"
+#include "kvi_modulemanager.h"
+#include "kvi_fileutils.h"
+#include "kvi_irctoolbar.h"
+#include "kvi_time.h"
+#include "kvi_mexlinkfilter.h"
+#include "kvi_avatarcache.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_ircconnectionserverinfo.h"
+#include "kvi_ircconnectionstatedata.h"
+#include "kvi_ircconnectiontarget.h"
+#include "kvi_ircconnectionstatistics.h"
+#include "kvi_asynchronousconnectiondata.h"
+#include "kvi_ircdatastreammonitor.h"
+#include "kvi_toolwindows_container.h"
+#include "kvi_msgbox.h"
+
+#ifdef COMPILE_SSL_SUPPORT
+ #include "kvi_sslmaster.h"
+#endif
+
+#include "kvi_kvs_script.h"
+#include "kvi_kvs_eventtriggers.h"
+
+#include <qsplitter.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+#include <qtimer.h>
+#include "kvi_tal_hbox.h"
+#include "kvi_tal_popupmenu.h"
+#include <qmessagebox.h>
+#include <qstringlist.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <q3mimefactory.h>
+#endif
+
+#define __KVI_DEBUG__
+#include "kvi_debug.h"
+
+#ifdef COMPILE_USE_QT4
+ #include <QTextDocument>
+#else
+ #include <qstylesheet.h>
+#endif
+
+extern KVIRC_API KviIrcServerDataBase * g_pIrcServerDataBase;
+extern KVIRC_API KviProxyDataBase * g_pProxyDataBase;
+extern KVIRC_API KviGarbageCollector * g_pGarbageCollector;
+
+// %tmp[] = $str.grep("test",%array[])
+
+KviConsole::KviConsole(KviFrame * lpFrm,int iFlags)
+#ifdef COMPILE_ON_WINDOWS
+: KviWindow(KVI_WINDOW_TYPE_CONSOLE,lpFrm,"CONSOLE",0)
+#else
+: KviWindow(KVI_WINDOW_TYPE_CONSOLE,lpFrm,"CONSOLE",this)
+#endif
+{
+ m_pConsole = this;
+ m_pContext = new KviIrcContext(this);
+
+ m_iFlags = iFlags;
+ if(m_pContext->id() == 1)
+ {
+ m_iFlags |= KVI_CONSOLE_FLAG_FIRSTINAPP;
+ }
+
+ m_pButtonBox = new KviTalHBox(this);
+ m_pButtonBox->setSpacing(0);
+ m_pButtonBox->setMargin(0);
+ new QLabel(__tr2qs("Address:"),m_pButtonBox,"url_label");
+ m_pAddressEdit = new QComboBox(m_pButtonBox,"url_editor");
+ m_pAddressEdit->setAutoCompletion(true);
+ m_pAddressEdit->setDuplicatesEnabled(false);
+ m_pAddressEdit->setEditable(true);
+ m_pAddressEdit->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_URL)));
+ recentUrlsChanged();
+ m_pAddressEdit->setCurrentText("");
+ m_pAddressEdit->setInsertionPolicy(QComboBox::NoInsertion);
+ m_pAddressEdit->setMinimumHeight(24); //icon is 16px, + margins
+ m_pButtonBox->setStretchFactor(m_pAddressEdit,1);
+#ifdef COMPILE_USE_QT4
+ m_pButtonBox->setObjectName( QLatin1String( "kvi_window_button_box" ) );
+#endif
+ KviTalToolTip::add(m_pAddressEdit,__tr2qs("Current IRC URI"));
+ connect(m_pAddressEdit,SIGNAL(activated(const QString & )),this,SLOT(ircUriChanged(const QString & )));
+ connect(g_pApp,SIGNAL(recentUrlsChanged()),this,SLOT(recentUrlsChanged()));
+
+
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"splitter");
+ m_pIrcView = new KviIrcView(m_pSplitter,lpFrm,this);
+ connect(m_pIrcView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked()));
+
+ // FIXME: #warning "If notify list is disabled avoid to show this"
+ // FIXME: #warning "Button to show/hide the notifyListView (NOT DELETE RE_CREATE!)"
+ // The userlist on the right
+ //m_pEditorsContainer= new KviToolWindowsContainer(m_pSplitter);
+ m_pNotifyViewButton = new KviWindowToolPageButton(KVI_SMALLICON_HIDELISTVIEW,KVI_SMALLICON_SHOWLISTVIEW,__tr2qs("Notify List"),buttonContainer(),true,"list_view_button");
+ connect(m_pNotifyViewButton,SIGNAL(clicked()),this,SLOT(toggleNotifyView()));
+
+ m_pNotifyListView = new KviUserListView(m_pSplitter,m_pNotifyViewButton,0,this,19,__tr2qs("Notify List"),"notify_list_view");
+
+ m_pInput = new KviInput(this,m_pNotifyListView);
+
+ if(KVI_OPTION_BOOL(KviOption_boolAutoLogConsole))m_pIrcView->startLogging();
+
+}
+
+
+int KviConsole::selectedCount()
+{
+ return m_pNotifyListView->selectedCount();
+}
+
+void KviConsole::recentUrlsChanged(){
+ QString cur = m_pAddressEdit->currentText();
+ m_pAddressEdit->clear();
+ for (
+ QStringList::Iterator it = KVI_OPTION_STRINGLIST(KviOption_stringlistRecentIrcUrls).begin();
+ it != KVI_OPTION_STRINGLIST(KviOption_stringlistRecentIrcUrls).end();
+ ++it
+ ) {
+ m_pAddressEdit->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_URL)),*it);
+ }
+ m_pAddressEdit->setCurrentText(cur);
+}
+
+bool KviConsole::isNotConnected()
+{
+ return (context()->state() == KviIrcContext::Idle);
+}
+
+bool KviConsole::connectionInProgress()
+{
+ if(context()->asynchronousConnectionData() != 0)return true;
+ if(context()->state() != KviIrcContext::Idle)return true;
+ return false;
+}
+
+
+KviConsole::~KviConsole()
+{
+ // FIXME: #warning "WARNING : THIS SHOULD BECOME A COMMAND /QUIT $option() so the idents are parsed!"
+
+ // Force connection close: it will just return if no connection is present
+ context()->terminateConnectionRequest(true);
+
+ KVS_TRIGGER_EVENT_0(KviEvent_OnIrcContextDestroyed,this);
+
+ if(g_pFrame->consoleCount() <= 1)
+ {
+ KVS_TRIGGER_EVENT_0(KviEvent_OnFrameWindowDestroyed,this);
+ KVS_TRIGGER_EVENT_0(KviEvent_OnKVIrcShutdown,this);
+ }
+
+ //if(m_pLastIrcServer)delete m_pLastIrcServer;
+
+ delete m_pContext;
+ m_pContext = 0;
+}
+
+KviIrcSocket * KviConsole::socket()
+{
+ return connection() ? connection()->socket() : 0;
+}
+
+unsigned int KviConsole::ircContextId()
+{
+ return m_pContext->id();
+}
+
+QString KviConsole::currentNetworkName()
+{
+ return (connection() ? connection()->networkName() : QString::null);
+}
+
+
+void KviConsole::triggerCreationEvents()
+{
+ if(m_iFlags & KVI_CONSOLE_FLAG_FIRSTINAPP) // this is the first context in the application
+ {
+ KVS_TRIGGER_EVENT_0(KviEvent_OnKVIrcStartup,this);
+
+ if(KVI_OPTION_BOOL(KviOption_boolShowTipAtStartup))
+ g_pFrame->executeInternalCommand(KVI_INTERNALCOMMAND_TIP_OPEN);
+ }
+
+ if(m_iFlags & KVI_CONSOLE_FLAG_FIRSTINFRAME)
+ {
+ KVS_TRIGGER_EVENT_0(KviEvent_OnFrameWindowCreated,this);
+ }
+
+ KVS_TRIGGER_EVENT_0(KviEvent_OnIrcContextCreated,this);
+}
+
+
+void KviConsole::fillContextPopup(KviTalPopupMenu * p)
+{
+ int id;
+ int cc = 0;
+ int qc = 0;
+ // FIXME: add items to close dead queries and channels ?
+ if(connection())
+ {
+ cc = channelCount();
+ qc = queryCount();
+ p->insertSeparator();
+ id = p->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)),__tr2qs("Part All Channels"),connection(),SLOT(partAllChannels()));
+ if(!cc)p->setItemEnabled(id,false);
+ id = p->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUERY)),__tr2qs("Close All Queries"),connection(),SLOT(closeAllQueries()));
+ if(!qc)p->setItemEnabled(id,false);
+ }
+
+ p->insertSeparator();
+ p->insertItem(__tr2qs("Unhighlight All Windows"),context(),SLOT(unhighlightAllWindows()));
+ if(connection())
+ {
+ id = p->insertItem(__tr2qs("Unhighlight All Channels"),connection(),SLOT(unhighlightAllChannels()));
+ if(!cc)p->setItemEnabled(id,false);
+ id = p->insertItem(__tr2qs("Unhighlight All Queries"),connection(),SLOT(unhighlightAllQueries()));
+ if(!qc)p->setItemEnabled(id,false);
+ }
+}
+
+void KviConsole::completeChannel(const QString &word,KviPointerList<QString> * matches)
+{
+ // FIXME: first look in our context ?
+ /*
+ if(!connection())return;
+ for(KviChannel * c = connection()->channelList()->first();c;c = connection()->channelList()->next())
+ {
+ if(kvi_strEqualCIN(c->windowName(),word.ptr(),word.len()))matches->append(new KviStr((*it)
+ }
+ */
+ QStringList *pList = g_pApp->getRecentChannels(currentNetworkName());
+ if(pList)
+ {
+ for(QStringList::Iterator it = pList->begin(); it != pList->end(); ++it)
+ {
+ if(KviQString::equalCIN((*it),word,word.length()))matches->append(new QString(*it));
+ }
+ }
+}
+
+void KviConsole::completeServer(const QString &word, KviPointerList<QString> * matches)
+{
+ for(QStringList::Iterator it = KVI_OPTION_STRINGLIST(KviOption_stringlistRecentServers).begin(); it != KVI_OPTION_STRINGLIST(KviOption_stringlistRecentServers).end(); ++it)
+ {
+ QString srv((*it));
+
+ KviQString::cutToFirst(srv,'/');
+ while(srv.startsWith("/"))srv.remove(0,1);
+ KviQString::cutFromLast(srv,':');
+ //We should have a full server name here, without the irc:// and without the port
+ if(KviQString::equalCIN(srv,word,word.length()))
+ {
+ matches->append(new QString(srv));
+ }
+
+ }
+}
+
+void KviConsole::getUserTipText(const QString &nick,KviIrcUserEntry *e,QString &buffer)
+{
+ KviRegisteredMask *u = g_pRegisteredUserDataBase->findMatchingMask(nick,e->user(),e->host());
+
+ buffer = "<table width=\"100%\">" \
+ "<tr><td bgcolor=\"#303030\">" \
+ "<center><font color=\"#FFFFFF\"><b>";
+
+ buffer += nick;
+ buffer += "!";
+ buffer += e->user().isEmpty() ? QString("*") : e->user();
+ buffer += "@";
+ buffer += e->host().isEmpty() ? QString("*") : e->host();
+
+
+ buffer += "</b></font></center></td></tr>";
+ if(u)
+ {
+ QString szComment=u->user()->getProperty("comment");
+ if(!szComment.isEmpty())
+ {
+ buffer += "<tr bgcolor=\"#F0F0F0\"><td><center><font size=\"-1\">(";
+ buffer += szComment;
+ buffer += ")</font></center></td></tr>";
+ }
+ }
+ if(e->avatar())
+ {
+#ifdef COMPILE_USE_QT4
+ Q3MimeSourceFactory::defaultFactory()->setPixmap("ulv_avatar",*(e->avatar()->pixmap()));
+#else
+ QMimeSourceFactory::defaultFactory()->setPixmap("ulv_avatar",*(e->avatar()->pixmap()));
+#endif
+ buffer += QString("<tr><td><center><img src=\"ulv_avatar\" width=\"%1\"></center></td></tr>").arg(e->avatar()->pixmap()->width());
+ }
+
+ if(e->hasRealName())
+ {
+ buffer += "<tr><td><center><b>";
+ buffer += KviMircCntrl::stripControlBytes(e->realName());
+ buffer += "</b></center></td></tr>";
+ }
+
+ if(e->gender()!=KviIrcUserEntry::Unknown)
+ {
+ buffer += "<tr><td>";
+ buffer += __tr2qs("Gender:");
+ buffer += " ";
+ buffer += (e->gender()==KviIrcUserEntry::Male) ? __tr2qs("Male") : __tr2qs("Female");
+ buffer += "</td></tr>";
+ }
+
+ if(u)
+ {
+ QString mask;
+ u->mask()->mask(mask);
+ buffer += "<tr bgcolor=\"#F0F0F0\"><td>";
+ buffer += __tr2qs("Registered as");
+ buffer += " <b>";
+ buffer += u->user()->name();
+ buffer += "</b>; Group ";
+ buffer += u->user()->group();
+ buffer += "</td></tr><tr bgcolor=\"#F0F0F0\"><td><font size=\"-1\">";
+ buffer += __tr2qs("(Matched by");
+ buffer += " ";
+ buffer += mask;
+ buffer += ")</td></tr>";
+ }
+
+ if(connection())
+ {
+ QString chans;
+ if(connection()->getCommonChannels(nick,chans,false))
+ {
+ buffer += "<tr><td bgcolor=\"#F0F0F0\">";
+ buffer += __tr2qs("On <b>");
+ buffer += chans;
+ buffer += "</b></td></tr>";
+ }
+ }
+
+ if(e->hasServer())
+ {
+ buffer += "<tr><td bgcolor=\"#F0F0F0\"><nobr>";
+ buffer += __tr2qs("Using server <b>%1</b>").arg(e->server());
+
+ if(e->hasHops())
+ {
+ buffer += " (";
+ buffer += __tr2qs("%1 hops").arg(e->hops());
+ buffer += ")</nobr></td></tr>";
+ } else {
+ buffer += "</nobr></td></tr></table>";
+ }
+ }
+
+ if(e->isAway())
+ {
+ buffer += "<tr><td bgcolor=\"#F0F0F0\">";
+ buffer += __tr2qs("Probably Away");
+ buffer += "</td></tr>";
+ }
+}
+
+
+void KviConsole::toggleNotifyView()
+{
+ showNotifyList(!m_pNotifyListView->isVisible());
+}
+
+void KviConsole::executeInternalCommand(int index)
+{
+ KviKvsScript::run(kvi_getInternalCommandBuffer(index),this);
+}
+
+void KviConsole::saveProperties(KviConfig *cfg)
+{
+ KviWindow::saveProperties(cfg);
+ cfg->writeEntry("Splitter",m_pSplitter->sizes());
+ cfg->writeEntry("NotifyListViewVisible",m_pNotifyListView->isVisible());
+
+}
+
+void KviConsole::getBaseLogFileName(QString &buffer)
+{
+ buffer=QString("CONSOLE%1").arg(ircContextId());
+}
+
+void KviConsole::showNotifyList(bool bShow)
+{
+ if(!bShow)
+ {
+ m_pNotifyListView->hide();
+ if(m_pNotifyViewButton->isOn())m_pNotifyViewButton->setOn(false);
+ } else {
+ m_pNotifyListView->show();
+ if(!(m_pNotifyViewButton->isOn()))m_pNotifyViewButton->setOn(true);
+ }
+}
+
+void KviConsole::loadProperties(KviConfig *cfg)
+{
+ int w = width();
+ KviValueList<int> def;
+ def.append((w * 85) / 100);
+ def.append((w * 15) / 100);
+ KviValueList<int> cur = cfg->readIntListEntry("Splitter",def);
+ // check the size correctness
+ if(cur.count() != 2)cur = def;
+ else {
+ int i1 = cur[0];
+ int i2 = cur[1];
+ if(i1 < i2)cur = def;
+ }
+ m_pSplitter->setSizes(cur);
+ KviWindow::loadProperties(cfg);
+ showNotifyList(cfg->readBoolEntry("NotifyListViewVisible",false));
+}
+
+void KviConsole::textViewRightClicked()
+{
+ KVS_TRIGGER_EVENT_0(KviEvent_OnConsolePopupRequest,this);
+}
+
+
+KviWindow * KviConsole::activeWindow()
+{
+ if(!g_pActiveWindow)return this;
+ if(g_pActiveWindow->console() == this)return g_pActiveWindow;
+ return this;
+}
+
+void KviConsole::ircUriChanged(const QString & text){
+ if(KviIrcUrl::run(text,KviIrcUrl::CurrentContext,this) & KviIrcUrl::InvalidProtocol)
+ {
+ KviMessageBox::warning(__tr2qs("KVIrc can accept only irc://, irc6://, ircs:// or irc6s:// URL's\n"
+ "Your URL is invalid. Check spelling and try again"));
+ }
+}
+
+void KviConsole::updateUri()
+{
+ QString uri;
+ if(connection())
+ {
+ KviIrcServer* server = connection()->target()->server();
+ if(server)
+ {
+ KviIrcUrl::join(uri,server);
+ KviChannel * last =connection()->channelList()->last();
+ for(KviChannel * c = connection()->channelList()->first();c;c = connection()->channelList()->next())
+ {
+ uri.append(c->name());
+ if(c->hasChannelKey()) {
+ uri.append("?");
+ uri.append(c->channelKey());
+ }
+ if(c!=last) uri.append(",");
+ }
+ }
+ }
+ m_pAddressEdit->setCurrentText(uri);
+}
+
+void KviConsole::connectionAttached()
+{
+ //need to update URI
+ connect(m_pContext->connection(),SIGNAL(chanListChanged()),this,SLOT(updateUri()));
+ updateUri();
+ m_pNotifyListView->setUserDataBase(connection()->userDataBase());
+}
+
+void KviConsole::connectionDetached()
+{
+ //need to update URI?
+ m_pNotifyListView->partAll();
+ m_pNotifyListView->setUserDataBase(0); // this is rather for crash tests
+}
+
+bool KviConsole::isIpV6Connection()
+{
+ __range_valid(connection());
+ return connection()->server()->isIpV6();
+}
+
+void KviConsole::closeEvent(QCloseEvent *e)
+{
+ if(g_pFrame->consoleCount() > 1)
+ {
+ // there are other consoles beside this one
+ if(context()->state() == KviIrcContext::Connected)
+ {
+ if(!KVI_OPTION_BOOL(KviOption_boolAlwaysDisconnectClosingConnectedConsole))
+ {
+ switch(QMessageBox::warning(this,
+ __tr2qs("Confirmation - KVIrc"),
+ __tr2qs("You have just attempted to close a console window with an active connection inside.\n" \
+ "Are you sure you wish to terminate the connection?"),
+ __tr2qs("&Always"),
+ __tr2qs("&Yes"),
+ __tr2qs("&No"),
+ 2,2))
+ {
+ case 0:
+ KVI_OPTION_BOOL(KviOption_boolAlwaysDisconnectClosingConnectedConsole) = true;
+ break;
+ case 1:
+ // nothing here
+ break;
+ default: // 2 = no
+ return;
+ break;
+ }
+ }
+ // ask the context to terminate the connection gracefully
+ context()->terminateConnectionRequest(false);
+ // the close event will recall terminateConnectionRequest()
+ // to brutally interrupt it in a while
+ }
+
+ // just close
+ KviWindow::closeEvent(e);
+ return;
+ }
+
+ // this is the only console... ask if the user really wants to quit KVirc
+ if(!KVI_OPTION_BOOL(KviOption_boolAlwaysQuitKVIrcClosingLastConsole))
+ {
+ switch(QMessageBox::warning(this,
+ __tr2qs("Confirmation - KVIrc"),
+ __tr2qs("You have just attempted to close the last console window.\nAre you sure you wish to quit KVIrc?"),
+ __tr2qs("&Always"),
+ __tr2qs("&Yes"),
+ __tr2qs("&No"),
+ 2,2))
+ {
+ case 0:
+ KVI_OPTION_BOOL(KviOption_boolAlwaysQuitKVIrcClosingLastConsole) = true;
+ break;
+ case 1:
+ // nothing here
+ break;
+ default: // 2 = no
+ return;
+ break;
+ }
+ }
+
+ g_pApp->quit();
+}
+
+// internal helper for applyHighlighting
+int KviConsole::triggerOnHighlight(KviWindow *wnd,int type,const QString &nick,const QString &user,const QString &host,const QString &szMsg,const QString &trigger)
+{
+ if(!KVI_OPTION_STRING(KviOption_stringOnHighlightedMessageSound).isEmpty() && wnd!=g_pActiveWindow) KviKvsScript::run("snd.play $0",0,new KviKvsVariantList(new KviKvsVariant(KVI_OPTION_STRING(KviOption_stringOnHighlightedMessageSound))));
+ QString szMessageType;
+ KviQString::sprintf(szMessageType,"%d",type);
+ if(KVS_TRIGGER_EVENT_7_HALTED(KviEvent_OnHighlight,
+ wnd,nick,user,host,
+ szMsg,trigger,
+ szMessageType,(type == KVI_OUT_ACTION)))
+ return -1;
+ return KVI_OUT_HIGHLIGHT;
+}
+
+// if it returns -1 you should just return and not display the message
+int KviConsole::applyHighlighting(KviWindow *wnd,int type,const QString &nick,const QString &user,const QString &host,const QString &szMsg)
+{
+ QString szPattern=KVI_OPTION_STRING(KviOption_stringWordSplitters);
+ QString szSource;
+ QString szStripMsg=KviMircCntrl::stripControlBytes(szMsg);
+ QChar* aux=(QChar*)(szStripMsg.ucs2());
+ if(aux)
+ {
+ while(aux->unicode())
+ {
+ if( KVI_OPTION_STRING(KviOption_stringWordSplitters).find(*aux) > -1 )
+ szSource.append(' ');
+ else
+ szSource.append(*aux);
+ aux++;
+ }
+ } else {
+ szSource=szStripMsg;
+ }
+ szSource.append(' ');
+ szSource.prepend(' ');
+ if(KVI_OPTION_BOOL(KviOption_boolAlwaysHighlightNick) && connection())
+ {
+ if(szSource.find(QString(" %1 ").arg(connection()->userInfo()->nickName()),0,false) > -1)
+ return triggerOnHighlight(wnd,type,nick,user,host,szMsg,connection()->userInfo()->nickName());
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseWordHighlighting))
+ {
+ for(QStringList::Iterator it = KVI_OPTION_STRINGLIST(KviOption_stringlistHighlightWords).begin();
+ it != KVI_OPTION_STRINGLIST(KviOption_stringlistHighlightWords).end() ; ++it)
+ {
+ if((*it).isEmpty())
+ continue;
+ // FIXME : This is SLOOOOOOOOW (QString -> ascii translation!!) !!!!
+ if(szSource.find(QString(" %1 ").arg(*it),0,false) > -1)
+ {
+ return triggerOnHighlight(wnd,type,nick,user,host,szMsg,*it);
+ }
+ }
+ }
+
+ if(wnd->type() == KVI_WINDOW_TYPE_CHANNEL)
+ {
+ if(((KviChannel *)wnd)->isHighlightedUser(nick))
+ return triggerOnHighlight(wnd,type,nick,user,host,szMsg,nick);
+
+ // FIXME: this is for userhighlighing
+ // maybe mark the users as highlighted in the console user database
+ // and then lookup them there ? this would be potentially a lot faster
+ KviRegisteredUser * u = connection()->userDataBase()->registeredUser(nick,user,host);
+
+ // note that we're highlighting users only in channels since
+ // in a query (or DCC) highlighting the remote end is senseless.
+ if(u)
+ {
+ if(u->getBoolProperty("highlight"))
+ return triggerOnHighlight(wnd,type,nick,user,host,szMsg,nick);
+ }
+ }
+
+ return type;
+}
+
+#define KVI_NUM_NICK_COLORS 95
+
+static const char * g_nickColors[KVI_NUM_NICK_COLORS]=
+{
+ "0,1" ,"0,2" ,"0,3" ,"0,4" ,"0,5" ,"0,6" ,"0,10" ,"0,12" ,"0,14" , //9
+ "1,0" ,"1,4" ,"1,7" ,"1,8" ,"1,9" ,"1,11" ,"1,15" , //7
+ "2,0" ,"2,4" ,"2,7" ,"2,8" ,"2,9" ,"2,11" ,"2,15" , //7
+ "3,8" ,"3,9" ,"3,0" ,"3,15" , //4
+ "4,0" ,"4,1" ,"4,8" ,"4,9" ,"4,11" ,"4,15" , //6
+ "5,0" ,"5,7" ,"5,8" ,"5,15" , //4
+ "6,0" ,"6,7" ,"6,8" ,"6,9" ,"6,10" ,"6,11" ,"6,15" , //7
+ "7,1" ,"7,2" ,"7,5" ,"7,6" ,"7,14" , //5
+ "8,1" ,"8,2" ,"8,3" ,"8,4" ,"8,5" ,"8,6" ,"8,7" ,"8,10" ,"8,12" ,"8,14" , //10
+ "9,1" ,"9,2" ,"9,3" ,"9,5" ,"9,6" ,"9,14" , //6
+ "10,1" ,"10,2" , //2
+ "11,1" ,"11,2" ,"11,3" ,"11,5" ,"11,6" ,"11,14", //6
+ "12,0" ,"12,7" ,"12,8" ,"12,9" ,"12,10","12,11","12,15", //7
+ "13,0" ,"13,1" ,"13,6" ,"13,8" ,"13,11","13,15", //6
+ "14,0" ,"14,8" ,"14,11","14,15", //4
+ "15,1" ,"15,2" ,"15,3" ,"15,6" ,"15,14" //5
+};
+
+void KviConsole::outputPrivmsg(KviWindow *wnd,
+ int type,
+ const QString &daNick,
+ const QString &daUser,
+ const QString &daHost,
+ const QString &msg,
+ int iFlags,
+ const QString &prefix,
+ const QString &suffix)
+{
+ // FIXME: #warning "THIS IS USED BY WINDOWS THAT ARE NOT BOUND TO THIS IRC CONTEXT"
+ // FIXME: #warning "REMEMBER IT IN ESCAPE COMMANDS"
+ // __range_valid(wnd);
+
+ bool bIsChan = (wnd->type() == KVI_WINDOW_TYPE_CHANNEL);
+ bool bIsNotice = ((type == KVI_OUT_CHANNELNOTICE)||(type == KVI_OUT_CHANNELNOTICECRYPTED) \
+ ||(type == KVI_OUT_QUERYNOTICE)||(type == KVI_OUT_QUERYNOTICECRYPTED));
+
+ QString nick = daNick; // not that beautiful.. :/
+ QString user = daUser;
+ QString host = daHost;
+
+ if(connection())
+ {
+ if(nick.isEmpty())nick = connection()->userInfo()->nickName();
+ if(user.isEmpty())user = connection()->userInfo()->userName();
+ if(host.isEmpty())host = connection()->userInfo()->hostName();
+ }
+
+ QString szDecodedMessage = msg; // shallow copy
+
+ if(KVI_OPTION_BOOL(KviOption_boolStripMircColorsInUserMessages))
+ szDecodedMessage = KviMircCntrl::stripControlBytes(szDecodedMessage);
+
+ if(!(iFlags & NoHighlighting))
+ {
+ // HIGHLIGHTING BLOCK
+ int iSaveType = type;
+ type = applyHighlighting(wnd,type,nick,user,host,szDecodedMessage);
+ if(type < 0)return; // event stopped the message!
+ if(type == KVI_OUT_HIGHLIGHT)
+ {
+ if(!wnd->hasAttention())
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolFlashWindowOnHighlightedMessages) &&
+ (!(iFlags & NoWindowFlashing)))
+ {
+ wnd->demandAttention();
+ }
+ if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnHighlightedMessages) &&
+ (!(iFlags & NoNotifier)))
+ {
+ QString szMsg = "<b>&lt;";
+ szMsg += nick;
+ szMsg += "&gt;</b> ";
+ #ifdef COMPILE_USE_QT4
+ szMsg += Qt::escape(szDecodedMessage);
+ #else
+ szMsg += QStyleSheet::escape(szDecodedMessage);
+ #endif
+ //debug("kvi_console.cpp:629 debug: %s",szMsg.data());
+ g_pApp->notifierMessage(wnd,KVI_OPTION_MSGTYPE(iSaveType).pixId(),szMsg,90);
+ }
+ }
+ }
+ }
+
+ // <PREFIX>nick[!user@host]<POSTFIX>This is a test message
+
+ QString szNick;
+ KviQString::sprintf(szNick,"\r!nc\r%Q\r",&nick);
+
+ if(KVI_OPTION_BOOL(KviOption_boolShowUserAndHostInPrivmsgView))
+ KviQString::appendFormatted(szNick,"!%Q@\r!h\r%Q\r",&user,&host);
+
+ if(bIsChan && KVI_OPTION_BOOL(KviOption_boolShowChannelUserFlagInPrivmsgView))
+ ((KviChannel *)wnd)->prependUserFlag(nick,szNick);
+
+ if(KVI_OPTION_BOOL(KviOption_boolColorNicks))
+ {
+ int sum = 0;
+ int i = nick.length();
+ const QChar * aux = nick.unicode();
+ // FIXME: Shouldn't this be case insensitive ?
+ while(i > 0)
+ {
+ sum += aux->unicode();
+ aux++;
+ i--;
+ }
+ szNick.prepend(g_nickColors[sum % KVI_NUM_NICK_COLORS]);
+ szNick.prepend(KVI_TEXT_COLOR);
+ szNick.append(KVI_TEXT_COLOR);
+ }
+/* if(KVI_OPTION_BOOL(KviOption_boolUseUserListColorsAsNickColors) && bIsChan)
+ {
+ if(((KviChannel*)wnd)->userListView())
+ {
+ KviUserListEntry *e = ((KviChannel*)wnd)->userListView()->findEntry(nick);
+ if(e)
+ {
+ int sum = 0;
+ int i = nick.length();
+ const QChar * aux = nick.unicode();
+ // FIXME: Shouldn't this be case insensitive ?
+ while(i > 0)
+ {
+ sum += aux->unicode();
+ aux++;
+ i--;
+ }
+ int color;
+ if(e->flags() == 0)
+ {
+ color = KVI_COLOR_EXT_USER_NORMAL;
+ } else {
+ color = (e->flags() & KVI_USERFLAG_CHANOWNER) ? \
+ KVI_COLOR_EXT_USER_OWNER : ((e->flags() & KVI_USERFLAG_CHANADMIN) ? \
+ KVI_COLOR_EXT_USER_ADMIN : ((e->flags() & KVI_USERFLAG_OP) ? \
+ KVI_COLOR_EXT_USER_OP : ((e->flags() & KVI_USERFLAG_HALFOP) ? \
+ KVI_COLOR_EXT_USER_HALFOP : ((e->flags() & KVI_USERFLAG_VOICE) ? \
+ KVI_COLOR_EXT_USER_VOICE : KVI_COLOR_EXT_USER_USEROP))));
+ }
+ szNick.prepend(QString("%1").arg(color));
+ szNick.prepend(KVI_TEXT_COLOR);
+ szNick.append(KVI_TEXT_COLOR);
+ }
+ }
+ }*/
+ if(KVI_OPTION_BOOL(KviOption_boolBoldedNicks))
+ {
+ szNick.prepend(KVI_TEXT_BOLD);
+ szNick.append(KVI_TEXT_BOLD);
+ }
+
+ QString szMessage;
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseExtendedPrivmsgView))
+ {
+ szMessage = prefix.isEmpty() ? KVI_OPTION_STRING(KviOption_stringExtendedPrivmsgPrefix) : prefix;
+ szMessage += szNick;
+ szMessage += suffix.isEmpty() ? KVI_OPTION_STRING(KviOption_stringExtendedPrivmsgPostfix) : suffix;
+ } else {
+ if(bIsNotice)
+ {
+ static QString pre1("*");
+ static QString suf1("* ");
+ szMessage = prefix.isEmpty() ? pre1 : prefix;
+ szMessage += szNick;
+ szMessage += suffix.isEmpty() ? suf1 : suffix;
+ } else {
+ static QString pre2("<");
+ static QString suf2("> ");
+ szMessage = prefix.isEmpty() ? pre2 : prefix;
+ szMessage += szNick;
+ szMessage += suffix.isEmpty() ? suf2 : suffix;
+ }
+ }
+
+ szMessage += szDecodedMessage;
+
+ if(bIsChan)((KviChannel *)wnd)->outputMessage(type,szMessage);
+ else wnd->outputNoFmt(type,szMessage);
+}
+
+void KviConsole::avatarChangedUpdateWindows(const QString &nick,const QString &textLine)
+{
+ if(!connection())return; //ops...
+
+ // in quiet mode avoid bugging the user about avatar changes
+ bool bOut = ((!textLine.isEmpty()) && (!(_OUTPUT_QUIET)));
+
+ for(KviChannel * c = connection()->channelList()->first();c;c = connection()->channelList()->next())
+ {
+ if(c->avatarChanged(nick))
+ {
+ if(bOut)c->outputNoFmt(KVI_OUT_AVATAR,textLine);
+ }
+ }
+ for(KviQuery * q = connection()->queryList()->first();q;q = connection()->queryList()->next())
+ {
+ if(q->avatarChanged(nick))
+ {
+ if(bOut)q->outputNoFmt(KVI_OUT_AVATAR,textLine);
+ }
+ }
+ m_pNotifyListView->avatarChanged(nick); // recalc the item height here too!
+}
+
+void KviConsole::avatarChanged(KviAvatar * avatar,const QString &nick,const QString &user,const QString &host,const QString &textLine)
+{
+ if(!connection())return; //ops...
+
+ bool bRegisteredStuff = false;
+
+ if(KVI_OPTION_BOOL(KviOption_boolSetLastAvatarAsDefaultForRegisteredUsers))
+ {
+ // Don't even try to do it for myself
+ if(!KviQString::equalCI(nick,connection()->userInfo()->nickName()))
+ {
+ KviRegisteredUser * u = connection()->userDataBase()->registeredUser(nick,user,host);
+ if(u)
+ {
+ if(avatar)u->setProperty("avatar",avatar->identificationString());
+ else u->setProperty("avatar",QString::null);
+ bRegisteredStuff = true;
+ }
+ }
+ }
+
+ if(!bRegisteredStuff)
+ {
+ // cache it
+ if(avatar)
+ KviAvatarCache::instance()->replace(avatar->identificationString(),KviIrcMask(nick,user,host),currentNetworkName().utf8().data());
+ else
+ KviAvatarCache::instance()->remove(KviIrcMask(nick,user,host),currentNetworkName().utf8().data());
+ }
+
+ avatarChangedUpdateWindows(nick,textLine);
+}
+
+void KviConsole::checkDefaultAvatar(KviIrcUserEntry *e,const QString &nick,const QString &user,const QString &host)
+{
+ // look it up in the cache
+ QString szAvatar = KviAvatarCache::instance()->lookup(KviIrcMask(nick,user,host),currentNetworkName().utf8().data());
+ if(!szAvatar.isEmpty())
+ {
+ // got a cache hit... is it on disk ?
+ KviAvatar * avatar = g_pIconManager->getAvatar(QString::null,szAvatar);
+ if(avatar)
+ {
+ // cached image on disk
+ e->setAvatar(avatar);
+ avatarChangedUpdateWindows(nick,QString::null);
+ return;
+ } else {
+ // no cached image on disk.. will need to requery it anyway
+ // remove from cache
+ KviAvatarCache::instance()->remove(KviIrcMask(nick,user,host),currentNetworkName().utf8().data());
+ }
+ }
+
+ // registered ?
+ KviRegisteredUser * u = connection()->userDataBase()->registeredUser(nick,user,host);
+ if(u)
+ {
+ // the user is registered...
+ QString szAvatar;
+ if(u->getProperty("avatar",szAvatar))
+ {
+ // the user has a default avatar...
+ KviAvatar * avatar = g_pIconManager->getAvatar(QString::null,szAvatar);
+ if(avatar)
+ {
+ e->setAvatar(avatar);
+ avatarChangedUpdateWindows(nick,QString::null);
+ return;
+ }
+ }
+ }
+}
+
+void KviConsole::resetAvatarForMatchingUsers(KviRegisteredUser * u)
+{
+ if(!connection())return;
+
+ QString szAvatar;
+ if(!u->getProperty("avatar",szAvatar))return;
+
+ KviPointerHashTableIterator<QString,KviIrcUserEntry> it(*(connection()->userDataBase()->dict()));
+ while(KviIrcUserEntry * e = it.current())
+ {
+ if(e->hasHost())
+ {
+ if(u->matchesFixed(it.currentKey(),e->user(),e->host()))
+ {
+ KviAvatar * a = g_pIconManager->getAvatar(QString::null,szAvatar);
+ e->setAvatar(a);
+ avatarChangedUpdateWindows(it.currentKey(),QString::null);
+ }
+ }
+ ++it;
+ }
+}
+
+KviAvatar * KviConsole::setAvatar(const QString &nick,const QString &user,const QString &host,const QString &szLocalPath,const QString &szName)
+{
+ if(!connection())return 0;
+ KviIrcUserEntry * e = connection()->userDataBase()->find(nick);
+ if(e)
+ {
+ // User and host must match
+ if((!user.isEmpty()) && e->hasUser())
+ {
+ if(!KviQString::equalCI(user,e->user()))return 0;
+ }
+
+ if((!host.isEmpty()) && e->hasHost())
+ {
+ if(!KviQString::equalCI(host,e->host()))return 0;
+ }
+
+ // Ok...got it
+
+ KviAvatar * avatar = g_pIconManager->getAvatar(szLocalPath,szName);
+ if(avatar)
+ {
+ e->setAvatar(avatar);
+ avatarChanged(avatar,nick,user,host,QString::null);
+ return avatar;
+ } else {
+ if(_OUTPUT_PARANOIC)
+ output(KVI_OUT_VERBOSE,__tr2qs("Failed to load avatar with name \"%Q\" and local path \"%Q\""),&szName,&szLocalPath);
+ }
+ }
+ return 0;
+}
+
+KviAvatar * KviConsole::defaultAvatarFromOptions()
+{
+ QPixmap * avatar = KVI_OPTION_PIXMAP(KviOption_pixmapMyAvatar).pixmap();
+ if(!avatar)return 0;
+ if(avatar->isNull())return 0;
+ if(KVI_OPTION_STRING(KviOption_stringMyAvatar).isEmpty())return 0;
+ return new KviAvatar(KVI_OPTION_PIXMAP(KviOption_pixmapMyAvatar).path(),KVI_OPTION_STRING(KviOption_stringMyAvatar),new QPixmap(*avatar));
+}
+
+KviAvatar * KviConsole::currentAvatar()
+{
+ if(!connection())return 0;
+ KviIrcUserEntry * e = connection()->userDataBase()->find(connection()->userInfo()->nickName());
+ if(!e)return 0;
+ KviAvatar * a = e->avatar();
+ if(!a)
+ {
+ a = defaultAvatarFromOptions();
+ if(a)
+ {
+ e->setAvatar(a);
+ avatarChanged(a,connection()->userInfo()->nickName(),QString::null,QString::null,QString::null);
+ }
+ }
+ return a;
+}
+
+void KviConsole::setAvatarFromOptions()
+{
+ if(!connection())return;
+ KviIrcUserEntry * e = connection()->userDataBase()->find(connection()->userInfo()->nickName());
+ if(!e)return;
+ KviAvatar * a = defaultAvatarFromOptions();
+ if(a)
+ {
+ e->setAvatar(a);
+ avatarChanged(a,connection()->userInfo()->nickName(),QString::null,QString::null,QString::null);
+ }
+}
+
+void KviConsole::applyOptions()
+{
+ m_pNotifyListView->applyOptions();
+ m_pInput->applyOptions();
+ m_pIrcView->applyOptions();
+
+ KviWindow::applyOptions();
+
+ // trick
+ resize(width() - 1,height() - 1);
+ resize(width() + 1,height() + 1);
+}
+
+void KviConsole::resizeEvent(QResizeEvent *e)
+{
+ int hght = m_pInput->heightHint();
+ int hght2 = m_pButtonBox->sizeHint().height();
+ m_pButtonBox->setGeometry(0,0,width(),hght2);
+ m_pSplitter->setGeometry(0,hght2,width(),height() - (hght + hght2));
+ m_pInput->setGeometry(0,height() - hght,width(),hght);
+}
+
+QSize KviConsole::sizeHint() const
+{
+ QSize ret(m_pIrcView->sizeHint().height(),m_pIrcView->sizeHint().height() + m_pInput->heightHint());
+ return ret;
+}
+
+void KviConsole::fillStatusString()
+{
+ switch(context()->state())
+ {
+ case KviIrcContext::Idle: m_szStatusString = __tr2qs("No connection"); break;
+ case KviIrcContext::Connecting: m_szStatusString = __tr2qs("Connection in progress..."); break;
+ case KviIrcContext::LoggingIn: m_szStatusString = __tr2qs("Login in progress..."); break;
+ case KviIrcContext::Connected:
+ m_szStatusString = connection()->userInfo()->nickName();
+ if(!connection()->userInfo()->userMode().isEmpty())
+ {
+ m_szStatusString += " (+";
+ m_szStatusString += connection()->userInfo()->userMode();
+
+ if(connection()->userInfo()->isAway())
+ {
+ m_szStatusString += QChar(' ');
+ m_szStatusString += __tr2qs("away");
+ }
+ m_szStatusString += QChar(')');
+ } else {
+ if(connection()->userInfo()->isAway())
+ {
+ m_szStatusString += " (";
+ m_szStatusString += __tr2qs("away");
+ m_szStatusString += QChar(')');
+ }
+ }
+
+ m_szStatusString += __tr2qs(" on ");
+ m_szStatusString += connection()->serverInfo()->name();
+ break;
+ }
+}
+
+void KviConsole::fillCaptionBuffers()
+{
+ fillStatusString();
+
+ static QString begin("<nobr><font color=\"");
+ static QString boldbegin("\"><b>");
+ static QString endofbold("</b></font> <font color=\"");
+ static QString endoffont("\">");
+ static QString end("</font></nobr>");
+
+ m_szPlainTextCaption = windowName();
+ m_szPlainTextCaption += " [";
+ m_szPlainTextCaption += m_szStatusString;
+ m_szPlainTextCaption += QChar(']');
+
+ m_szHtmlActiveCaption = begin;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += boldbegin;
+ m_szHtmlActiveCaption += windowName();
+ m_szHtmlActiveCaption += endofbold;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name();
+ m_szHtmlActiveCaption += endoffont;
+ m_szHtmlActiveCaption += m_szStatusString;
+ m_szHtmlActiveCaption += end;
+
+ m_szHtmlInactiveCaption = begin;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += boldbegin;
+ m_szHtmlInactiveCaption += windowName();
+ m_szHtmlInactiveCaption += endofbold;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name();
+ m_szHtmlInactiveCaption += endoffont;
+ m_szHtmlInactiveCaption += m_szStatusString;
+ m_szHtmlInactiveCaption += end;
+}
+
+
+QPixmap * KviConsole::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(isConnected() ? KVI_SMALLICON_LINKS : KVI_SMALLICON_CONSOLE);
+}
+
+
+void KviConsole::getTaskBarTipText(QString &buffer)
+{
+ fillStatusString();
+
+ static QString html_bold("<b>");
+ static QString html_tab("&nbsp;&nbsp;");
+ static QString html_eofbold("</b>");
+ static QString html_hrbr("<br><hr>");
+ static QString html_channel(__tr2qs("channel"));
+ static QString html_channels(__tr2qs("channels"));
+ static QString html_query(__tr2qs("query"));
+ static QString html_queries(__tr2qs("queries"));
+ static QString html_space(" ");
+ static QString html_commaspace(", ");
+ static QString html_br("<br>");
+ static QString html_spaceparopen(" (");
+ static QString html_spaceparclosed(")");
+
+ buffer = "<table width=\"100%\">" \
+ START_TABLE_BOLD_ROW;
+ buffer += m_szStatusString;
+ buffer += END_TABLE_BOLD_ROW;
+ if((context()->state() == KviIrcContext::Connected) && connection())
+ {
+ QString num;
+
+ unsigned int uD;
+ unsigned int uH;
+
+ uD = connection()->channelList()->count();
+ uH = connection()->queryList()->count();
+
+ if(uD || uH > 0)
+ {
+ buffer += "<tr><td>";
+ buffer += html_tab;
+
+ if(uD > 0)
+ {
+ num.setNum(uD);
+
+ buffer += html_bold;
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += html_space;
+ buffer += uD > 1 ? html_channels : html_channel;
+ if(uH > 0)
+ buffer += html_commaspace;
+ }
+
+ if(uH > 0)
+ {
+ num.setNum(uH);
+ buffer += html_bold;
+ buffer += num;
+ buffer += html_eofbold;
+ buffer += html_space;
+ buffer += uH > 1 ? html_queries : html_query;
+ }
+ buffer += "</td></tr>";
+ }
+
+ QDateTime dt;
+ dt.setTime_t(connection()->statistics()->connectionStartTime());
+
+ buffer += START_TABLE_NORMAL_ROW;
+
+ buffer += __tr2qs("Connected since");
+ buffer += html_space;
+ buffer += html_br;
+ buffer += html_tab;
+ buffer += html_bold;
+ buffer += dt.toString();
+ buffer += html_eofbold;
+ buffer += html_br;
+
+ //buffer += html_spaceparopen;
+
+ QString tspan = KviTimeUtils::formatTimeInterval((unsigned int)(kvi_secondsSince(connection()->statistics()->connectionStartTime())),
+ KviTimeUtils::NoLeadingEmptyIntervals | KviTimeUtils::NoLeadingZeroes);
+
+ buffer += __tr2qs("Online for");
+ buffer += html_space;
+ buffer += html_bold;
+ buffer += tspan;
+ buffer += html_eofbold;
+ //buffer += html_spaceparclosed;
+
+ buffer += "</td></tr><tr><td bgcolor=\"#F0F0F0\">";
+
+ tspan = KviTimeUtils::formatTimeInterval((unsigned int)(kvi_secondsSince(connection()->statistics()->lastMessageTime())),
+ KviTimeUtils::NoLeadingEmptyIntervals | KviTimeUtils::NoLeadingZeroes);
+
+ buffer += __tr2qs("Server idle for");
+ buffer += html_space;
+ buffer += html_bold;
+ buffer += tspan;
+ buffer += "</b></td></tr>";
+ }
+
+ buffer += "</table>";
+}
+
+#include "kvi_console.moc"
diff --git a/src/kvirc/ui/kvi_console.h b/src/kvirc/ui/kvi_console.h
new file mode 100644
index 0000000..b9f494c
--- /dev/null
+++ b/src/kvirc/ui/kvi_console.h
@@ -0,0 +1,212 @@
+#ifndef _KVI_CONSOLE_H_
+#define _KVI_CONSOLE_H_
+//=============================================================================
+//
+// File : kvi_console.h
+// Creation date : Sun Jun 25 2000 15:00:20 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_ircconnection.h"
+#include "kvi_window.h"
+#include "kvi_ircsocket.h"
+#include "kvi_string.h"
+#include "kvi_irccontext.h"
+
+#include "kvi_pointerlist.h"
+
+#include <time.h>
+#include <qcombobox.h>
+
+
+class QToolBar;
+class QToolButton;
+
+class KviAvatar;
+class KviDns;
+class KviIrcUserDataBase;
+class KviIrcUserEntry;
+class KviIrcServer;
+class KviIrcNetwork;
+class KviProxy;
+#ifndef COMPILE_ON_WINDOWS
+ class KviChannel;
+ class KviQuery;
+#else
+ // windoze wants it to compile QList<KviChannel> and QList<KviQuery>
+ #include "kvi_channel.h"
+ #include "kvi_query.h"
+#endif
+class KviUserListView;
+class KviNotifyListManager;
+class KviRegisteredUser;
+class KviWindowToolPageButton;
+
+
+
+//=================================================================================================
+//
+// The console window
+//
+//=================================================================================================
+
+#define KVI_CONSOLE_FLAG_FIRSTINAPP 1
+#define KVI_CONSOLE_FLAG_FIRSTINFRAME 2
+
+
+class KVIRC_API KviConsole : public KviWindow
+{
+ friend class KviFrame;
+ friend class KviIrcSocket;
+ friend class KviChannel;
+ friend class KviQuery;
+ friend class KviIrcContext;
+ Q_OBJECT
+protected:
+ KviConsole(KviFrame * lpFrm,int iFlags);
+public:
+ ~KviConsole();
+protected:
+ int m_iFlags; // FIXME: make this a KviWindow property ?
+ // UI
+ KviUserListView * m_pNotifyListView;
+ KviWindowToolPageButton * m_pNotifyViewButton;
+ QComboBox * m_pAddressEdit;
+ QString m_szStatusString; // nick (flags) on server | not connected
+protected:
+ // UI
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void closeEvent(QCloseEvent *e);
+ virtual void getBaseLogFileName(QString &buffer);
+ virtual void getTaskBarTipText(QString &buffer);
+ virtual void fillContextPopup(KviTalPopupMenu * p);
+ virtual QSize sizeHint() const;
+ virtual void applyOptions();
+ virtual void triggerCreationEvents();
+ void fillStatusString();
+ //void socketError(int iError);
+ //void socketStateChange();
+ //void registerLinkMonitor(KviIrcSocketMonitor * m);
+ //void unregisterLinkMonitor(KviIrcSocketMonitor * m);
+ virtual void loadProperties(KviConfig * cfg);
+ virtual void saveProperties(KviConfig * cfg);
+
+ void destroyConnection();
+ // internal helper for applyHighlighting
+ int triggerOnHighlight(KviWindow *wnd,int type,const QString &nick,const QString &user,const QString &host,const QString &szMsg,const QString &trigger);
+
+ void showNotifyList(bool bShow);
+
+public:
+ // UI
+ KviUserListView * notifyListView(){ return m_pNotifyListView; };
+ int selectedCount();
+
+
+ //
+ // State
+ //
+ KviIrcContext::State state(){ return context()->state(); };
+ KVI_DEPRECATED KviIrcContext * ircContext(){ return context(); };
+ unsigned int ircContextId() KVI_DEPRECATED;
+ //
+ // Sock state
+ //
+ KviIrcSocket * socket() KVI_DEPRECATED;
+
+ // these should disappear!
+ bool isConnected(){ return context()->isConnected(); };
+ bool isIpV6Connection();
+ bool isNotConnected();
+ bool connectionInProgress();
+ //
+ // This connection info
+ //
+ QString currentNetworkName();
+ KviAvatar * currentAvatar();
+ //
+ // IRC Context wide helpers (connection related)
+ //
+ void getUserTipText(const QString &nick,KviIrcUserEntry *e,QString &buffer);
+ enum OutputPrivmsgFlags {
+ NoWindowFlashing = 1, // has meaning only if NoHighlighting is NOT given, otherwise it is implied
+ NoNotifier = 2, // has meaning only if NoHighlighitng is NOT given, otherwise it is implied
+ NoHighlighting = 4,
+ NoNotifications = 7 // this is 1|2|4 implies NoWindowFlashing and NoNotifier
+ };
+ void outputPrivmsg(KviWindow *wnd,int type,const QString &nick,
+ const QString &user,const QString &host,const QString &msg,int iFlags = 0,const QString &prefix = QString::null,const QString &suffix = QString::null);
+ // this applies highlighting to the specified message
+ // and triggers the OnHighlight event.
+ // it returns KVI_OUT_HIGHLIGHT if highlighting was applied
+ // and -1 if OnHighlight called halt
+ // otherwise it returns <type>
+ int applyHighlighting(KviWindow *wnd,int type,const QString &nick,const QString &user,const QString &host,const QString &szMsg);
+ // Avatar helpers (conneciton related)
+ void resetAvatarForMatchingUsers(KviRegisteredUser * u);
+ // this should be protected at least
+ void avatarChangedUpdateWindows(const QString &nick,const QString &textLine);
+ void avatarChanged(KviAvatar * avatar,const QString &nick,const QString &user,const QString &host,const QString &textLine);
+ KviAvatar * setAvatar(const QString &nick,const QString &user,const QString &host,const QString &szLocalPath,const QString &szName);
+ void checkDefaultAvatar(KviIrcUserEntry *e,const QString &nick,const QString &user,const QString &host);
+ void setAvatarFromOptions();
+
+ // This returns the default avatar for the current KVIrc user
+ // if he has choosen a valid avatar in the options dialog
+ // otherwise returns 0.
+ // The avatar is allocated with new and must be deleted
+ // when no longer needed.
+ KviAvatar * defaultAvatarFromOptions();
+
+ void terminateConnectionRequest(bool bForce = false,const char * quitMsg = 0);
+
+ // Status string (usermode + nick) (connection related too)
+ const QString & statusString(){ return m_szStatusString; };
+
+ // forwarders from KviIrcConnection
+ KVI_DEPRECATED KviPointerList<KviChannel> * channelList(){ return connection() ? connection()->channelList() : 0; };
+ KVI_DEPRECATED KviPointerList<KviQuery> * queryList(){ return connection() ? connection()->queryList() : 0; };
+ KVI_DEPRECATED unsigned int channelCount(){ return (connection() ? connection()->channelList()->count() : 0); };
+ KVI_DEPRECATED unsigned int queryCount(){ return (connection() ? connection()->queryList()->count() : 0); };
+
+ // Window management
+ //KVI_DEPRECATED KviChannel * findChannel(const char * name){ return connection() ? connection()->findChannel(name) : 0; };
+ //KVI_DEPRECATED KviQuery * findQuery(const char * nick){ return connection() ? connection()->findQuery(nick) : 0; };
+
+ KviWindow * activeWindow();
+ // User db, connection related
+ void completeChannel(const QString &word,KviPointerList<QString> * matches);
+ void completeServer(const QString &word,KviPointerList<QString> * matches);
+ void connectionAttached();
+ void connectionDetached();
+public slots:
+ void updateUri();
+ void executeInternalCommand(int index);
+ void recentUrlsChanged();
+protected slots:
+ void ircUriChanged(const QString & );
+ void toggleNotifyView();
+ void textViewRightClicked();
+};
+
+#endif //_KVI_CONSOLE_H_
diff --git a/src/kvirc/ui/kvi_cryptcontroller.cpp b/src/kvirc/ui/kvi_cryptcontroller.cpp
new file mode 100644
index 0000000..6cbdd5b
--- /dev/null
+++ b/src/kvirc/ui/kvi_cryptcontroller.cpp
@@ -0,0 +1,390 @@
+//
+// File : kvi_cryptcontroller.cpp
+// Creation date : Fri Nov 03 2000 14:16:33 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2005 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#define __KVIRC__
+
+#include "kvi_settings.h"
+
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+ #include "kvi_cryptcontroller.h"
+ #include "kvi_styled_controls.h"
+
+ #include "kvi_window.h"
+ #include "kvi_locale.h"
+ #include "kvi_out.h"
+ #include "kvi_iconmanager.h"
+ #include "kvi_modulemanager.h"
+ #include "kvi_module.h"
+ #include "kvi_malloc.h"
+ #include "kvi_memmove.h"
+ #include "kvi_toolwindows_container.h"
+
+ #include <qlayout.h>
+ #include "kvi_pointerhashtable.h"
+
+ // kvi_app.cpp
+ extern KVIRC_API KviCryptEngineManager * g_pCryptEngineManager;
+ extern KVIRC_API KviModuleManager * g_pModuleManager;
+
+ KviEngineListBoxItem::KviEngineListBoxItem(KviTalListBox * lb,KviCryptEngineDescription * d,const char * modName)
+ : KviTalListBoxText(lb,d->szName)
+ {
+ m_szName = d->szName;
+ m_szAuthor = d->szAuthor;
+ m_szDescription = d->szDescription;
+ m_iFlags = d->iFlags;
+ m_szModuleName = modName;
+ setText(d->szName);
+ }
+
+ KviEngineListBoxItem::~KviEngineListBoxItem()
+ {
+ }
+
+
+
+
+ KviCryptController::KviCryptController(QWidget * par,KviWindowToolPageButton* button,const char * name,KviWindow * wnd,KviCryptSessionInfo * cur)
+ : KviWindowToolWidget(par,button)
+ {
+// FIXME: #warning "Load the available modules here"
+
+ // Load the known encryption modules
+ (void)g_pModuleManager->loadModulesByCaps("crypt");
+// (void)g_pModuleManager->getModule("koi2win");
+// (void)g_pModuleManager->getModule("mircstrip");
+// (void)g_pModuleManager->getModule("texturizer");
+
+ m_pWindow = wnd;
+
+#ifdef COMPILE_USE_QT4
+ setFocusPolicy(Qt::ClickFocus);
+#else
+ setFocusPolicy(QWidget::ClickFocus);
+#endif
+
+ QGridLayout *g = new QGridLayout(this,10,4,2,2);
+
+ QLabel *l = new QLabel(this);
+ l->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LOCKED)));
+ g->addWidget(l,0,0);
+ l = new QLabel(__tr2qs("Cryptography/text transformation"),this);
+ g->addMultiCellWidget(l,0,0,1,3);
+
+ QFrame * frm = new QFrame(this);
+ frm->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ g->addMultiCellWidget(frm,1,1,0,3);
+
+ m_pEnableCheck = new KviStyledCheckBox(__tr2qs("Use the crypt engine"),this);
+ g->addMultiCellWidget(m_pEnableCheck,2,2,0,3);
+ connect(m_pEnableCheck,SIGNAL(toggled(bool)),this,SLOT(enableCheckToggled(bool)));
+
+ m_pListBox = new KviTalListBox(this);
+ connect(m_pListBox,SIGNAL(highlighted(KviTalListBoxItem *)),this,SLOT(engineHighlighted(KviTalListBoxItem *)));
+ g->addMultiCellWidget(m_pListBox,3,8,0,0);
+
+ m_pDescriptionLabel = new QLabel(this);
+ m_pDescriptionLabel->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+#ifdef COMPILE_USE_QT4
+ m_pDescriptionLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+#else
+ m_pDescriptionLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+#endif
+ g->addMultiCellWidget(m_pDescriptionLabel,3,3,1,3);
+
+ m_pAuthorLabel = new QLabel(this);
+ m_pAuthorLabel->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ g->addMultiCellWidget(m_pAuthorLabel,4,4,1,3);
+
+ m_pEnableEncrypt = new KviStyledCheckBox(__tr2qs("Enable encryption"),this);
+ g->addMultiCellWidget(m_pEnableEncrypt,5,5,1,3);
+
+ m_pEncryptKeyLabel = new QLabel(__tr2qs("Encrypt key:"),this);
+ g->addWidget(m_pEncryptKeyLabel,6,1);
+
+ m_pEncryptKeyEdit = new QLineEdit(this);
+ g->addWidget(m_pEncryptKeyEdit,6,2);
+
+ m_pEncryptHexKeyCheck = new KviStyledCheckBox(__tr2qs("Hex"),this);
+ g->addWidget(m_pEncryptHexKeyCheck,6,3);
+
+ m_pEnableDecrypt = new KviStyledCheckBox(__tr2qs("Enable decryption"),this);
+ g->addMultiCellWidget(m_pEnableDecrypt,7,7,1,3);
+
+ m_pDecryptKeyLabel = new QLabel(__tr2qs("Decrypt key:"),this);
+ g->addWidget(m_pDecryptKeyLabel,8,1);
+
+ m_pDecryptKeyEdit = new QLineEdit(this);
+ g->addWidget(m_pDecryptKeyEdit,8,2);
+
+ m_pDecryptHexKeyCheck = new KviStyledCheckBox(__tr2qs("Hex"),this);
+ g->addWidget(m_pDecryptHexKeyCheck,8,3);
+
+ m_pOkButton = new QPushButton(__tr2qs("OK"),this);
+ g->addMultiCellWidget(m_pOkButton,9,9,0,3);
+ connect(m_pOkButton,SIGNAL(clicked()),this,SLOT(okClicked()));
+
+ g->setRowStretch(3,1);
+ g->setColStretch(2,1);
+
+ m_pLastItem = 0;
+ m_pSessionInfo = 0;
+
+ fillEngineList();
+
+ if(cur)
+ {
+ KviTalListBoxItem * it = (KviTalListBoxItem *)m_pListBox->findItem(cur->szEngineName.ptr());
+ if(it)
+ {
+ m_pEnableCheck->setChecked(true);
+ m_pListBox->setCurrentItem(it);
+ engineHighlighted(it);
+ m_pEnableEncrypt->setChecked(cur->bDoEncrypt);
+ m_pEnableDecrypt->setChecked(cur->bDoDecrypt);
+ } else enableWidgets(false);
+ } else {
+ enableWidgets(false);
+ }
+ registerSelf();
+ }
+
+ KviCryptController::~KviCryptController()
+ {
+ if(m_pSessionInfo)
+ {
+ // huh ?
+ g_pCryptEngineManager->deallocateEngine(m_pSessionInfo->pEngine);
+ delete m_pSessionInfo;
+ }
+ // Unload the unused ones...
+ g_pModuleManager->cleanupUnusedModules();
+ }
+
+ void KviCryptController::fillEngineList()
+ {
+ const KviPointerHashTable<QString,KviCryptEngineDescription> * a = g_pCryptEngineManager->engineDict();
+ if(a)
+ {
+ KviPointerHashTableIterator<QString,KviCryptEngineDescription> it(*a);
+ while(it.current())
+ {
+ KviStr modName = it.current()->providerHandle ? ((KviModule *)(it.current()->providerHandle))->name() : "";
+ (void)(new KviEngineListBoxItem(m_pListBox,it.current(),modName.ptr()));
+ ++it;
+ }
+ if(m_pListBox->count() != 0)return;
+ }
+ noEnginesAvailable();
+ }
+
+ void KviCryptController::engineHighlighted(KviTalListBoxItem *it)
+ {
+ if(it)
+ {
+ KviEngineListBoxItem * eit = (KviEngineListBoxItem *)it;
+ m_pAuthorLabel->setText(eit->m_szAuthor.ptr());
+ QString des = "<p>";
+ des += eit->m_szDescription.ptr();
+ des += "<br><br>";
+ des += __tr2qs("If you dont want to encrypt a particular text line then just start it with the CTRL+P prefix");
+ m_pDescriptionLabel->setText(des);
+ m_pEnableEncrypt->setEnabled(eit->m_iFlags & KVI_CRYPTENGINE_CAN_ENCRYPT);
+ m_pEncryptKeyLabel->setEnabled((eit->m_iFlags & KVI_CRYPTENGINE_CAN_ENCRYPT) &&
+ (eit->m_iFlags & KVI_CRYPTENGINE_WANT_ENCRYPT_KEY));
+ m_pEncryptKeyEdit->setEnabled((eit->m_iFlags & KVI_CRYPTENGINE_CAN_ENCRYPT) &&
+ (eit->m_iFlags & KVI_CRYPTENGINE_WANT_ENCRYPT_KEY));
+ m_pEnableEncrypt->setChecked(m_pEncryptKeyEdit->isEnabled());
+ m_pEnableDecrypt->setEnabled(eit->m_iFlags & KVI_CRYPTENGINE_CAN_DECRYPT);
+ m_pEncryptHexKeyCheck->setEnabled(m_pEncryptKeyEdit->isEnabled());
+ m_pEncryptHexKeyCheck->setChecked(false);
+ m_pDecryptKeyLabel->setEnabled((eit->m_iFlags & KVI_CRYPTENGINE_CAN_DECRYPT) &&
+ (eit->m_iFlags & KVI_CRYPTENGINE_WANT_DECRYPT_KEY));
+ m_pDecryptKeyEdit->setEnabled((eit->m_iFlags & KVI_CRYPTENGINE_CAN_DECRYPT) &&
+ (eit->m_iFlags & KVI_CRYPTENGINE_WANT_DECRYPT_KEY));
+ m_pEnableDecrypt->setChecked(m_pDecryptKeyEdit->isEnabled());
+ m_pDecryptHexKeyCheck->setEnabled(m_pDecryptKeyEdit->isEnabled());
+ m_pDecryptHexKeyCheck->setChecked(false);
+ m_pLastItem = eit;
+ enableWidgets(true);
+ } else m_pLastItem = 0;
+ }
+
+ void KviCryptController::enableCheckToggled(bool bChecked)
+ {
+ enableWidgets(bChecked);
+ }
+
+ void KviCryptController::enableWidgets(bool bEnabled)
+ {
+ m_pListBox->setEnabled(bEnabled);
+ m_pAuthorLabel->setEnabled(bEnabled && m_pLastItem);
+ m_pDescriptionLabel->setEnabled(bEnabled && m_pLastItem);
+ bool bCanDecrypt = m_pLastItem ? m_pLastItem->m_iFlags & KVI_CRYPTENGINE_CAN_DECRYPT : false;
+ bool bCanEncrypt = m_pLastItem ? m_pLastItem->m_iFlags & KVI_CRYPTENGINE_CAN_ENCRYPT : false;
+ m_pEnableEncrypt->setEnabled(bEnabled && bCanEncrypt);
+ m_pEnableDecrypt->setEnabled(bEnabled && bCanDecrypt);
+ bool bWantDecryptKey = m_pLastItem ? (bCanDecrypt && (m_pLastItem->m_iFlags & KVI_CRYPTENGINE_WANT_DECRYPT_KEY)) : false;
+ bool bWantEncryptKey = m_pLastItem ? (bCanEncrypt && (m_pLastItem->m_iFlags & KVI_CRYPTENGINE_WANT_ENCRYPT_KEY)) : false;
+ m_pEncryptKeyLabel->setEnabled(bEnabled && m_pEnableEncrypt->isChecked() && bWantEncryptKey);
+ m_pDecryptKeyLabel->setEnabled(bEnabled && m_pEnableDecrypt->isChecked() && bWantDecryptKey);
+ m_pEncryptKeyEdit->setEnabled(m_pEncryptKeyLabel->isEnabled());
+ m_pDecryptKeyEdit->setEnabled(m_pDecryptKeyLabel->isEnabled());
+ m_pEncryptHexKeyCheck->setEnabled(m_pEncryptKeyLabel->isEnabled());
+ m_pDecryptHexKeyCheck->setEnabled(m_pDecryptKeyLabel->isEnabled());
+ }
+
+ void KviCryptController::noEnginesAvailable()
+ {
+
+ m_pEnableCheck->setEnabled(false);
+ enableWidgets(false);
+ m_pDescriptionLabel->setText(__tr2qs("Sorry, no crypt engines available"));
+ m_pDescriptionLabel->setEnabled(true); // we want this text to be visible.
+ m_pOkButton->setEnabled(false);
+ }
+
+ void KviCryptController::okClicked()
+ {
+ if(m_pEnableCheck->isChecked())
+ {
+ if(m_pLastItem)
+ {
+ if(m_pEnableEncrypt->isChecked() || m_pEnableDecrypt->isChecked())
+ {
+ m_pSessionInfo = allocateCryptSessionInfo();
+ // Reregister the module in case that it has been unloaded
+ // while this dialog was open
+ if(m_pLastItem->m_szModuleName.hasData())(void)g_pModuleManager->getModule(m_pLastItem->m_szModuleName.ptr());
+ m_pSessionInfo->pEngine = g_pCryptEngineManager->allocateEngine(m_pLastItem->m_szName.ptr());
+ if(!m_pSessionInfo->pEngine)
+ {
+ m_pWindow->output(KVI_OUT_SYSTEMERROR,__tr2qs("Crypt: Can't create an engine instance: crypting disabled"));
+ delete m_pSessionInfo;
+ m_pSessionInfo = 0;
+ } else {
+ // initialize the engine
+ if(!initializeEngine(m_pSessionInfo->pEngine))
+ {
+ KviStr errStr = m_pSessionInfo->pEngine->lastError();
+ g_pCryptEngineManager->deallocateEngine(m_pSessionInfo->pEngine);
+ delete m_pSessionInfo;
+ m_pSessionInfo = 0;
+ m_pWindow->output(KVI_OUT_SYSTEMERROR,__tr2qs("Crypt: Can't initialize the engine :%s"),errStr.ptr());
+ } else {
+ // ok, engine ready and waiting...
+ m_pSessionInfo->szEngineName = m_pLastItem->m_szName;
+ m_pSessionInfo->bDoEncrypt = m_pEnableEncrypt->isChecked();
+ m_pSessionInfo->bDoDecrypt = m_pEnableDecrypt->isChecked();
+ }
+ }
+ } else m_pWindow->output(KVI_OUT_SYSTEMERROR,__tr2qs("Crypt: You have to enable encryption and/or decryption for the engine to work"));
+ }
+ }
+ emit done();
+ }
+
+ bool KviCryptController::initializeEngine(KviCryptEngine * eng)
+ {
+ KviStr m_szEncryptKey;
+ KviStr m_szDecryptKey;
+
+ char * encKey = 0;
+ int encKeyLen = 0;
+
+ if(m_pEnableEncrypt->isChecked())
+ {
+ m_szEncryptKey = m_pEncryptKeyEdit->text();
+ if(m_pEncryptHexKeyCheck->isChecked())
+ {
+ char * tmpKey;
+ encKeyLen = m_szEncryptKey.hexToBuffer(&tmpKey,false);
+ if(encKeyLen > 0)
+ {
+ encKey = (char *)kvi_malloc(encKeyLen);
+ kvi_memmove(encKey,tmpKey,encKeyLen);
+ KviStr::freeBuffer(tmpKey);
+ }
+ } else {
+ encKey = (char *)kvi_malloc(m_szEncryptKey.len());
+ kvi_memmove(encKey,m_szEncryptKey.ptr(),m_szEncryptKey.len());
+ encKeyLen = m_szEncryptKey.len();
+ }
+ }
+
+ char * decKey = 0;
+ int decKeyLen = 0;
+
+ if(m_pEnableDecrypt->isChecked())
+ {
+ m_szDecryptKey = m_pDecryptKeyEdit->text();
+ if(m_pDecryptHexKeyCheck->isChecked())
+ {
+ char * tmpKey;
+ decKeyLen = m_szDecryptKey.hexToBuffer(&tmpKey,false);
+ if(decKeyLen > 0)
+ {
+ decKey = (char *)kvi_malloc(decKeyLen);
+ kvi_memmove(decKey,tmpKey,decKeyLen);
+ KviStr::freeBuffer(tmpKey);
+ }
+ } else {
+ decKey = (char *)kvi_malloc(m_szDecryptKey.len());
+ kvi_memmove(decKey,m_szDecryptKey.ptr(),m_szDecryptKey.len());
+ decKeyLen = m_szDecryptKey.len();
+ }
+ }
+
+ bool bRet = eng->init(encKey,encKeyLen,decKey,decKeyLen);
+ if(encKey)kvi_free(encKey);
+ if(decKey)kvi_free(decKey);
+
+ return bRet;
+ }
+
+ KviCryptSessionInfo * KviCryptController::getNewSessionInfo()
+ {
+ KviCryptSessionInfo * inf = m_pSessionInfo;
+ m_pSessionInfo = 0;
+ return inf;
+ }
+
+ KviCryptSessionInfo * KviCryptController::allocateCryptSessionInfo()
+ {
+ // this is mainly for modules wanting to alloc this
+ return new KviCryptSessionInfo();
+ }
+
+ void KviCryptController::destroyCryptSessionInfo(KviCryptSessionInfo ** inf)
+ {
+ if(!(*inf))return;
+ (*inf)->pEngine->disconnect(); // disconnect every signal (this is mainly for destroyed())
+ g_pCryptEngineManager->deallocateEngine((*inf)->pEngine); // kill the engine
+ delete *inf;
+ *inf = 0;
+ }
+
+ #include "kvi_cryptcontroller.moc"
+
+#endif //COMPILE_CRYPT_SUPPORT
diff --git a/src/kvirc/ui/kvi_cryptcontroller.h b/src/kvirc/ui/kvi_cryptcontroller.h
new file mode 100644
index 0000000..1d6afcb
--- /dev/null
+++ b/src/kvirc/ui/kvi_cryptcontroller.h
@@ -0,0 +1,116 @@
+#ifndef _KVI_CRYPTCONTROLLER_H_
+#define _KVI_CRYPTCONTROLLER_H_
+//=============================================================================
+//
+// File : kvi_cryptcontroller.h
+// Creation date : Fri Nov 03 2000 14:11:03 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+
+
+// Qt4 moc bails out on this ??????
+
+#if defined(COMPILE_CRYPT_SUPPORT) || defined(Q_MOC_RUN)
+ #include <qwidget.h>
+ #include "kvi_tal_listbox.h"
+ #include <qpushbutton.h>
+ #include <qcheckbox.h>
+ #include <qlabel.h>
+ #include <qlineedit.h>
+ #include "kvi_styled_controls.h"
+
+ #include "kvi_crypt.h"
+ #include "kvi_heapobject.h"
+ #include "kvi_toolwindows_container.h"
+
+ class KviWindow;
+
+ class KVIRC_API KviCryptSessionInfo : public KviHeapObject
+ {
+ public:
+ KviCryptEngine * pEngine;
+ KviStr szEngineName;
+ bool bDoEncrypt;
+ bool bDoDecrypt;
+ };
+
+ class KVIRC_API KviEngineListBoxItem : public KviTalListBoxText
+ {
+ friend class KviCryptController;
+ public:
+ KviEngineListBoxItem(KviTalListBox * lb,KviCryptEngineDescription * d,const char * modName);
+ ~KviEngineListBoxItem();
+ public:
+ KviStr m_szName;
+ KviStr m_szAuthor;
+ KviStr m_szDescription;
+ KviStr m_szModuleName;
+ int m_iFlags;
+ };
+
+
+ class KVIRC_API KviCryptController : public KviWindowToolWidget
+ {
+ Q_OBJECT
+ public:
+ KviCryptController(QWidget * parent,KviWindowToolPageButton* button,const char * name,KviWindow * wnd,KviCryptSessionInfo * cur);
+ ~KviCryptController();
+ protected:
+ KviWindow * m_pWindow;
+ KviTalListBox * m_pListBox;
+ QPushButton * m_pOkButton;
+ KviStyledCheckBox * m_pEnableCheck;
+ QLabel * m_pDescriptionLabel;
+ QLabel * m_pAuthorLabel;
+ KviStyledCheckBox * m_pEnableEncrypt;
+ QLabel * m_pEncryptKeyLabel;
+ QLineEdit * m_pEncryptKeyEdit;
+ KviStyledCheckBox * m_pEncryptHexKeyCheck;
+ KviStyledCheckBox * m_pEnableDecrypt;
+ QLabel * m_pDecryptKeyLabel;
+ QLineEdit * m_pDecryptKeyEdit;
+ KviStyledCheckBox * m_pDecryptHexKeyCheck;
+ KviEngineListBoxItem * m_pLastItem;
+ KviCryptSessionInfo * m_pSessionInfo;
+ private slots:
+ void enableCheckToggled(bool bChecked);
+ void engineHighlighted(KviTalListBoxItem *it);
+ void okClicked();
+ public:
+ KviCryptSessionInfo * getNewSessionInfo();
+ static KviCryptSessionInfo * allocateCryptSessionInfo();
+ static void destroyCryptSessionInfo(KviCryptSessionInfo ** inf);
+ private:
+ void fillEngineList();
+ void noEnginesAvailable();
+ void enableWidgets(bool bEnabled);
+ bool initializeEngine(KviCryptEngine * eng);
+ signals:
+ void done();
+ };
+
+
+#endif //COMPILE_CRYPT_SUPPORT
+
+
+#endif //!_KVI_CRYPTCONTROLLER_H_
diff --git a/src/kvirc/ui/kvi_ctcppagedialog.cpp b/src/kvirc/ui/kvi_ctcppagedialog.cpp
new file mode 100644
index 0000000..e6f392d
--- /dev/null
+++ b/src/kvirc/ui/kvi_ctcppagedialog.cpp
@@ -0,0 +1,147 @@
+//
+// File : kvi_ctcppagedialog.cpp
+// Creation date : Tue May 21 2002 22:09:45 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#define __KVIRC__
+
+#include "kvi_ctcppagedialog.h"
+
+#include "kvi_locale.h"
+#include "kvi_app.h"
+
+#include "kvi_iconmanager.h"
+
+#include <qdatetime.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qdesktopwidget.h>
+#endif
+
+// kvi_app.cpp
+extern KVIRC_API KviCtcpPageDialog * g_pCtcpPageDialog;
+
+KviCtcpPageDialog::KviCtcpPageDialog()
+: QWidget(0,"kvirc_ctcppage_dialog",
+#ifdef COMPILE_USE_QT4
+ Qt::WindowStaysOnTopHint | Qt::Tool | Qt::Dialog | Qt::Window)
+#else
+ WStyle_StaysOnTop | WStyle_Tool | WType_Dialog | WType_TopLevel)
+#endif
+{
+ QGridLayout * g = new QGridLayout(this,4,1,6,0);
+ m_pWidgetStack = new KviTalWidgetStack(this);
+ g->addWidget(m_pWidgetStack,0,0);
+ m_pTabBar = new QTabBar(this);
+ m_pTabBar->setShape(QTabBar::TriangularBelow);
+ connect(m_pTabBar,SIGNAL(selected(int)),this,SLOT(tabSelected(int)));
+ g->addWidget(m_pTabBar,1,0);
+
+ g->setRowStretch(0,1);
+
+ g->addRowSpacing(2,15);
+
+ m_pCloseButton = new QPushButton(__tr2qs("Close"),this);
+ connect(m_pCloseButton,SIGNAL(clicked()),this,SLOT(die()));
+ g->addWidget(m_pCloseButton,3,0);
+
+ setMinimumSize(300,200);
+ setMaximumSize(780,580);
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CTCPREQUESTREPLIED)));
+
+ setCaption(__tr2qs("CTCP Page - KVIrc"));
+}
+
+KviCtcpPageDialog::~KviCtcpPageDialog()
+{
+ g_pCtcpPageDialog = 0;
+}
+
+void KviCtcpPageDialog::center()
+{
+ move((g_pApp->desktop()->width() - width()) >> 1,
+ (g_pApp->desktop()->height() - height()) >> 1);
+}
+
+void KviCtcpPageDialog::die()
+{
+ delete this;
+}
+
+void KviCtcpPageDialog::tabSelected(int id)
+{
+ m_pWidgetStack->raiseWidget(id);
+}
+
+void KviCtcpPageDialog::addPage(const QString &szNick,const QString &szUser,const QString &szHost,const QString &szMsg)
+{
+#ifdef COMPILE_USE_QT4
+ int id = m_pTabBar->addTab(szNick);
+#else
+ int id = m_pTabBar->addTab(new QTab(szNick));
+#endif
+ QLabel * l = new QLabel(this);
+ l->setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
+ //l->setMaximumWidth(600);
+ QString date = QDateTime::currentDateTime().toString();
+
+ QString tmp = "<center>";
+ tmp += __tr2qs("You have been paged by");
+ tmp += "<br><b>";
+ tmp += szNick;
+ tmp += " [";
+ tmp += szUser;
+ tmp += "@";
+ tmp += szHost;
+ tmp += "]</b>:<br><br><b>";
+ tmp += szMsg;
+ tmp += "</b><br><br>[";
+ tmp += date;
+ tmp += "]</center>";
+
+ l->setText(tmp);
+ m_pWidgetStack->addWidget(l,id);
+ m_pWidgetStack->raiseWidget(l);
+ m_pTabBar->setCurrentTab(id);
+}
+
+void KviCtcpPageDialog::closeEvent(QCloseEvent *)
+{
+ delete this;
+}
+
+void KviCtcpPageDialog::popup()
+{
+ show();
+// raise();
+// setActiveWindow();
+ m_pCloseButton->setFocus();
+}
+
+void KviCtcpPageDialog::showEvent(QShowEvent *e)
+{
+ QWidget::showEvent(e);
+ center();
+}
+
+#include "kvi_ctcppagedialog.moc"
diff --git a/src/kvirc/ui/kvi_ctcppagedialog.h b/src/kvirc/ui/kvi_ctcppagedialog.h
new file mode 100644
index 0000000..ea61525
--- /dev/null
+++ b/src/kvirc/ui/kvi_ctcppagedialog.h
@@ -0,0 +1,56 @@
+#ifndef _KVI_CTCPPAGEDIALOG_H_
+#define _KVI_CTCPPAGEDIALOG_H_
+//
+// File : kvi_ctcppagedialog.h
+// Creation date : Tue May 21 2002 22:09:45 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+
+#include "kvi_string.h"
+
+#include "kvi_tal_widgetstack.h"
+#include <qtabbar.h>
+#include <qwidget.h>
+#include <qpushbutton.h>
+
+class KVIRC_API KviCtcpPageDialog : public QWidget
+{
+ Q_OBJECT
+public:
+ KviCtcpPageDialog();
+ ~KviCtcpPageDialog();
+protected:
+ KviTalWidgetStack * m_pWidgetStack;
+ QTabBar * m_pTabBar;
+ QPushButton * m_pCloseButton;
+public:
+ void popup();
+ void addPage(const QString &szNick,const QString &szUser,const QString &szHost,const QString &szMsg);
+protected slots:
+ void tabSelected(int id);
+ void die();
+protected:
+ void center();
+ virtual void showEvent(QShowEvent *e);
+ virtual void closeEvent(QCloseEvent *);
+};
+
+#endif //_KVI_CTCPPAGEDIALOG_H_
diff --git a/src/kvirc/ui/kvi_customtoolbar.cpp b/src/kvirc/ui/kvi_customtoolbar.cpp
new file mode 100644
index 0000000..7aa6f1c
--- /dev/null
+++ b/src/kvirc/ui/kvi_customtoolbar.cpp
@@ -0,0 +1,670 @@
+//=============================================================================
+//
+// File : kvi_customtoolbar.cpp
+// Created on Sun 21 Nov 2004 05:28:57 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2004 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_customtoolbar.h"
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_actionmanager.h"
+#include "kvi_customtoolbardescriptor.h"
+
+#include <qcursor.h>
+#include "kvi_tal_popupmenu.h"
+#include <qlayout.h>
+#include <qpixmap.h>
+#include <qcursor.h>
+#include <qtoolbutton.h>
+#include <qpainter.h>
+#include <qstyle.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qevent.h>
+ #include <q3dragobject.h>
+
+ #define QDragObject Q3DragObject
+ #define QTextDrag Q3TextDrag
+ #define QIconDrag Q3IconDrag
+
+ #include <qstyleoption.h>
+#else
+ #include <qobjectlist.h>
+ #include <qdragobject.h>
+#endif
+
+
+
+KviCustomToolBarSeparator::KviCustomToolBarSeparator(KviCustomToolBar *pParent,const char * name)
+: QWidget(pParent,name)
+{
+ m_pToolBar = pParent;
+ setBackgroundMode(pParent->backgroundMode());
+ setBackgroundOrigin(ParentOrigin);
+ setSizePolicy(QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum));
+}
+
+QSize KviCustomToolBarSeparator::sizeHint() const
+{
+#ifdef COMPILE_USE_QT4
+ QStyleOption opt;
+ opt.initFrom(this);
+ int extent = style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent,&opt,this);
+#else
+ int extent = style().pixelMetric(QStyle::PM_DockWindowSeparatorExtent,this);
+#endif
+ if(m_pToolBar->orientation() == Qt::Horizontal)return QSize(extent,0);
+ else return QSize(0,extent);
+}
+
+void KviCustomToolBarSeparator::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+#ifdef COMPILE_USE_QT4
+ QStyleOption opt;
+ opt.initFrom(this);
+ style()->drawPrimitive(QStyle::PE_Q3DockWindowSeparator,&opt,&p,this);
+#else
+ QStyle::SFlags flags = QStyle::Style_Default;
+ if(m_pToolBar->orientation() == Qt::Horizontal)flags |= QStyle::Style_Horizontal;
+ style().drawPrimitive(QStyle::PE_DockWindowSeparator,&p,rect(),colorGroup(),flags);
+#endif
+}
+
+
+KviCustomToolBar::KviCustomToolBar(KviCustomToolBarDescriptor * d,const QString &label,QT_TOOLBARDOCK_TYPE dock,bool bNewLine,const char * nam)
+: KviToolBar(label,dock,bNewLine,nam)
+{
+ m_pDescriptor = d;
+ m_pMovedChild = 0;
+ m_pDraggedChild = 0;
+ m_pFilteredChildren = 0;
+ setAcceptDrops(true);
+ connect(KviActionManager::instance(),SIGNAL(beginCustomizeToolBars()),this,SLOT(beginCustomize()));
+ connect(KviActionManager::instance(),SIGNAL(endCustomizeToolBars()),this,SLOT(endCustomize()));
+ setMinimumSize(20,20);
+ d->registerToolBar(this);
+ if(KviActionManager::customizingToolBars())
+ beginCustomize(); // because we will not get the signal
+}
+
+KviCustomToolBar::~KviCustomToolBar()
+{
+ if(KviActionManager::customizingToolBars())
+ syncDescriptor(); // because we will not get endCustomize()
+ m_pDescriptor->unregisterToolBar(this);
+ if(KviActionManager::customizingToolBars())
+ {
+ if(KviActionManager::currentToolBar() == this)
+ KviActionManager::instance()->setCurrentToolBar(0);
+ }
+ if(m_pFilteredChildren)delete m_pFilteredChildren;
+}
+
+void KviCustomToolBar::paintEvent(QPaintEvent * e)
+{
+ KviToolBar::paintEvent(e);
+ if(KviActionManager::customizingToolBars() && (KviActionManager::currentToolBar() == this))
+ {
+ QPainter p(this);
+ p.setPen(Qt::red);
+ p.drawRect(0,0,width(),height());
+ }
+}
+
+void KviCustomToolBar::filteredChildDestroyed()
+{
+ if(!m_pFilteredChildren)return;
+ const QObject * o = sender();
+ m_pFilteredChildren->remove((void *)o);
+}
+
+void KviCustomToolBar::filterChild(QObject * o)
+{
+ bool * b = new bool(((QWidget *)o)->isEnabled());
+ if(m_pFilteredChildren)
+ m_pFilteredChildren->insert(o,b);
+ if(!*b)((QWidget *)o)->setEnabled(true);
+ o->installEventFilter(this);
+ connect(o,SIGNAL(destroyed()),this,SLOT(filteredChildDestroyed()));
+}
+
+void KviCustomToolBar::unfilterChild(QObject * o)
+{
+ if(m_pFilteredChildren)
+ {
+ bool * b = m_pFilteredChildren->find(o);
+ if(b)
+ {
+ if(!*b)((QWidget *)o)->setEnabled(false);
+ o->removeEventFilter(this);
+ disconnect(o,SIGNAL(destroyed()),this,SLOT(filteredChildDestroyed()));
+ }
+ }
+}
+
+void KviCustomToolBar::beginCustomize()
+{
+ if(m_pFilteredChildren)delete m_pFilteredChildren;
+ m_pFilteredChildren = new KviPointerHashTable<void *,bool>;
+ m_pFilteredChildren->setAutoDelete(true);
+ // filter the events for all the children
+#ifdef COMPILE_USE_QT4
+ QList<QObject*> l = children();
+ for(QList<QObject*>::Iterator it = l.begin();it != l.end();++it)
+ {
+ if((*it)->isWidgetType())
+ filterChild(*it);
+ }
+#else
+ const QObjectList * l = children();
+ QObjectListIterator it(*l);
+ while(QObject * o = it.current())
+ {
+ if(o->isWidgetType())
+ filterChild(o);
+ ++it;
+ }
+#endif
+}
+
+void KviCustomToolBar::endCustomize()
+{
+ // stop filtering events
+#ifdef COMPILE_USE_QT4
+ QList<QObject*> l = children();
+ for(QList<QObject*>::Iterator it = l.begin();it != l.end();++it)
+ {
+ if((*it)->isWidgetType())
+ unfilterChild(*it);
+ }
+#else
+ const QObjectList * l = children();
+ QObjectListIterator it(*l);
+ while(QObject * o = it.current())
+ {
+ if(o->isWidgetType())
+ unfilterChild(o);
+ ++it;
+ }
+#endif
+ // FIXME: We SHOULD MAKE SURE that the children are re-enabled...
+ // this could be done by calling setEnabled(isEnabled()) on each action ?
+ if(m_pFilteredChildren)
+ {
+ delete m_pFilteredChildren;
+ m_pFilteredChildren = 0;
+ }
+ syncDescriptor();
+}
+
+void KviCustomToolBar::syncDescriptor()
+{
+ // store the item order in the descriptor
+ QBoxLayout * lay = boxLayout();
+ QLayoutIterator iter = lay->iterator();
+ QLayoutItem * i;
+ m_pDescriptor->actions()->clear();
+ while((i = iter.current()))
+ {
+ if(QWidget * w = i->widget())
+ m_pDescriptor->actions()->append(new QString(w->name()));
+ ++iter;
+ }
+}
+
+void KviCustomToolBar::childEvent(QChildEvent *e)
+{
+ if(KviActionManager::customizingToolBars())
+ {
+ // this is useful for droppped and dragged-out children
+ if(e->type() == QEvent::ChildInserted)
+ {
+ if(e->child()->isWidgetType())
+ filterChild(e->child());
+ goto done;
+ }
+
+ if(e->type() == QEvent::ChildRemoved)
+ {
+ if(e->child()->isWidgetType())
+ unfilterChild(e->child());
+ goto done;
+ }
+ }
+done:
+ KviToolBar::childEvent(e);
+}
+
+void KviCustomToolBar::dragEnterEvent(QDragEnterEvent *e)
+{
+ if(!KviActionManager::customizingToolBars())return;
+ KviActionManager::instance()->setCurrentToolBar(this);
+ QString text;
+ if(QTextDrag::decode(e,text))
+ {
+ if(!text.isEmpty())
+ {
+ KviAction * a = KviActionManager::instance()->getAction(text);
+ if(a)
+ {
+ e->accept(true);
+ int idx = dropIndexAt(mapFromGlobal(QCursor::pos()),0,0);
+ m_pDraggedChild = a->addToCustomToolBar(this);
+#ifdef COMPILE_USE_QT4
+ QWidget * pWidgetToMove = widgetAt(idx);
+ bool bDone = false;
+ QAction * a;
+ if(pWidgetToMove)
+ {
+ a = actionForWidget(pWidgetToMove);
+ if(a)
+ {
+ bDone = true;
+ a = insertWidget(a,m_pDraggedChild);
+ }
+ }
+ if(!bDone)
+ a = addWidget(m_pDraggedChild);
+ a->setVisible(true);
+#else
+ boxLayout()->remove(m_pDraggedChild); // in case it was already added
+ boxLayout()->insertWidget(idx,m_pDraggedChild);
+#ifdef COMPILE_KDE_SUPPORT
+ // bleah ://///
+ insertWidget(-1,m_pDraggedChild->sizeHint().width(),m_pDraggedChild,idx);
+#endif
+#endif
+ QEvent ev(QEvent::LayoutHint);
+ QApplication::sendEvent(this,&ev);
+ } else e->accept(false);
+ } else e->accept(false);
+ } else e->accept(false);
+}
+
+void KviCustomToolBar::dragMoveEvent(QDragMoveEvent *e)
+{
+ if(!m_pDraggedChild)return;
+ drag(m_pDraggedChild,mapFromGlobal(QCursor::pos()));
+}
+
+void KviCustomToolBar::dragLeaveEvent(QDragLeaveEvent *e)
+{
+ if(m_pDraggedChild)
+ {
+ if(m_pFilteredChildren)
+ m_pFilteredChildren->remove(m_pDraggedChild); // just to be sure
+ delete m_pDraggedChild;
+ m_pDraggedChild = 0;
+ }
+}
+
+void KviCustomToolBar::dropEvent(QDropEvent *e)
+{
+ if(!m_pDraggedChild)return;
+ m_pDraggedChild = 0;
+ e->accept();
+ // nuthin :)
+}
+
+int KviCustomToolBar::dropIndexAt(const QPoint &pnt,QWidget * exclude,int * excludeIdx)
+{
+ // find the widget at the current poisition
+ // treating exclude as if it was going to be removed
+ // find also the exclude index if needed
+#ifdef COMPILE_USE_QT4
+ QLayout * l = layout();
+#else
+ QBoxLayout * l = boxLayout();
+#endif
+ QLayoutItem * i = 0;
+ if(excludeIdx)*excludeIdx = -1;
+ int idx = 0;
+
+ if(!l)return 0;
+ QLayoutIterator it = l->iterator();
+
+ // find the children with minimum distance
+ int iMinDistIdx = -1;
+ QWidget * pMinDistW = 0;
+ unsigned int uMinDist = 0xffffffff;
+ int iExcludeIdx = -1;
+ QPoint pntExclude;
+ QWidget * w = 0;
+
+ while((i = it.current()))
+ {
+ if((w = i->widget()))
+ {
+ if(uMinDist != 0)
+ {
+ int iRight = w->x() + w->width();
+ int iBottom = w->y() + w->height();
+ if((pnt.x() >= w->x()) && (pnt.y() >= w->y()) && (pnt.x() <= iRight) && (pnt.y() <= iBottom))
+ {
+ // inside the widget
+ // distance 0
+ pMinDistW = w;
+ iMinDistIdx = idx;
+ uMinDist = 0;
+ } else {
+ // outside the widget
+ // compute the distance
+ unsigned int uXDist = (pnt.x() < w->x()) ? (w->x() - pnt.x()) : (pnt.x() > iRight ? (pnt.x() - iRight) : 0);
+ unsigned int uYDist = (pnt.y() < w->y()) ? (w->y() - pnt.y()) : (pnt.y() > iBottom ? (pnt.y() - iBottom) : 0);
+ if((uXDist < 8192) && (uYDist < 8192))
+ {
+ // it is in reasonable rect
+ unsigned int uDist = (uXDist * uXDist) + (uYDist * uYDist);
+ if(uDist < uMinDist)
+ {
+ // min distance for now
+ uMinDist = uDist;
+ pMinDistW = w;
+ iMinDistIdx = idx;
+ }
+ } // else the user has a really HUUUGE screen
+ }
+ } // else the minimum distance widget has already been found
+ if(w == exclude)
+ {
+ iExcludeIdx = idx;
+ pntExclude = w->pos();
+ }
+ }
+ idx++;
+ ++it;
+ }
+
+ if(!pMinDistW)
+ {
+ // ops.. not found at all (empty toolbar or really far from any button)
+ if(orientation() == Qt::Horizontal)
+ {
+ if(pnt.x() < (width() / 2))iMinDistIdx = 0; // insert at position 0
+ else iMinDistIdx = idx;
+ // else insert at the last position found
+ } else {
+ if(pnt.y() < (height() / 2))iMinDistIdx = 0; // insert at position 0
+ else iMinDistIdx = idx;
+ // else insert at the last position found
+ }
+ } else {
+ // got it, check for the exclude idx
+ if((iExcludeIdx == -1) || (iExcludeIdx != iMinDistIdx))
+ {
+ // would not put it over exclude idx
+ // check if we have to stay on right or left of the widget found
+ if(orientation() == Qt::Horizontal)
+ {
+ if(pnt.x() > (pMinDistW->x() + (pMinDistW->width() / 2)))
+ iMinDistIdx++; // need to put it on the right
+ } else {
+ if(pnt.y() > (pMinDistW->y() + (pMinDistW->height() / 2)))
+ iMinDistIdx++; // need to put it below
+ }
+ }
+
+ // ok , check again (we might have moved exactly over exclude idx now!)
+ if((iExcludeIdx != -1) && (iExcludeIdx != iMinDistIdx))
+ {
+ // got the exclude idx by the way and wouldn't put exactly over it
+ // check if exclude idx is "before" the current possible insert position
+ // if it is , then lower down the index by one
+ if(orientation() == Qt::Horizontal)
+ {
+ if(pnt.x() > pntExclude.x())
+ iMinDistIdx--; // removing exclude will move everything one step back
+ } else {
+ if(pnt.y() > pntExclude.y())
+ iMinDistIdx--; // removing exclude will move everything one step back
+ }
+ }
+ }
+
+ if(iMinDistIdx < 0)iMinDistIdx = 0;
+ if(excludeIdx)*excludeIdx = iExcludeIdx;
+
+ return iMinDistIdx;
+
+}
+
+#ifdef COMPILE_USE_QT4
+QWidget * KviCustomToolBar::widgetAt(int index)
+{
+ QLayout * l = layout();
+ if(!l)
+ return NULL;
+ QLayoutItem * it = l->itemAt(index);
+ if(!it)
+ return NULL;
+ return it->widget();
+}
+
+QAction * KviCustomToolBar::actionForWidget(QWidget * pWidget)
+{
+ return actionAt(pWidget->x() + 1,pWidget->y() + 1);
+}
+
+#endif
+
+void KviCustomToolBar::drag(QWidget * child,const QPoint &pnt)
+{
+ int me = -1;
+ int idx = dropIndexAt(pnt,child,&me);
+ debug("DROP INDEX IS %d, ME IS %d",idx,me);
+ if(idx == me)
+ return; // would move over itself
+#ifdef COMPILE_USE_QT4
+ QWidget * pWidgetToMove = widgetAt(idx > me ? idx-1 : idx);
+ debug("SEARCHING FOR WIDGET TO MOVE AT %d AND FOUND %x (ME=%x)",idx > me ? idx-1 : idx,pWidgetToMove,child);
+ if(pWidgetToMove == child)
+ return; // hmmm
+ bool bDone = false;
+ QAction * pMyOwnAction = actionForWidget(child);
+ if(!pMyOwnAction)
+ return;
+ QAction * a;
+ removeAction(pMyOwnAction);
+ if(pWidgetToMove)
+ {
+ a = actionForWidget(pWidgetToMove);
+ if(a)
+ {
+ debug("AND GOT ACTION FOR THAT WIDGET");
+
+ bDone = true;
+ a = insertWidget(a,child);
+ }
+ } else {
+ addAction(a);
+ }
+ if(!bDone)
+ a = addWidget(child);
+ a->setVisible(true);
+#else
+ boxLayout()->remove(child);
+ boxLayout()->insertWidget(idx,child);
+#ifdef COMPILE_KDE_SUPPORT
+ // bleah ://///
+ insertWidget(-1,child->width(),child,idx);
+#endif
+#endif
+ QEvent ev(QEvent::LayoutHint);
+ QApplication::sendEvent(this,&ev);
+}
+
+void KviCustomToolBar::mousePressEvent(QMouseEvent * e)
+{
+ if(KviActionManager::customizingToolBars())
+ KviActionManager::instance()->setCurrentToolBar(this);
+ KviToolBar::mousePressEvent(e);
+}
+
+bool KviCustomToolBar::eventFilter(QObject *o,QEvent *e)
+{
+ if(!KviActionManager::customizingToolBars())goto unhandled; // anything here is done when customizing only
+ if(e->type() == QEvent::Enter)
+ {
+ if(m_pMovedChild)return true; // kill it while moving other children
+ }
+ if(e->type() == QEvent::Leave)
+ {
+ if(m_pMovedChild)return true; // kill it while moving other children
+ }
+ if(e->type() == QEvent::MouseButtonPress)
+ {
+ KviActionManager::instance()->setCurrentToolBar(this);
+ QMouseEvent * ev = (QMouseEvent *)e;
+ if(ev->button() & Qt::LeftButton)
+ {
+ if(o->isWidgetType())
+ {
+ if(!(
+ o->inherits("KviTalPopupMenu") ||
+ o->inherits("QToolBarHandle") ||
+ o->inherits("QDockWindowHandle") ||
+ o->inherits("QDockWindowResizeHandle") ||
+ o->inherits("QToolBarExtensionWidget")
+ ))
+ {
+ m_pMovedChild = (QWidget *)o;
+ // allow resizing of children
+ // FIXME: do it only if the child is really resizable
+ if(m_pMovedChild->width() > 20) // might be an applet
+ {
+ if(ev->pos().x() > (m_pMovedChild->width() - 4))
+ {
+ m_pMovedChild = 0;
+ goto unhandled; // let the applet handle the event it
+ }
+ }
+ g_pApp->setOverrideCursor(Qt::sizeAllCursor);
+ return true;
+ }
+ }
+ }
+ goto unhandled;
+ }
+ if(e->type() == QEvent::MouseButtonRelease)
+ {
+ if(m_pMovedChild)
+ {
+ g_pApp->restoreOverrideCursor();
+ m_pMovedChild = 0;
+ return true;
+ }
+ goto unhandled;
+ }
+ if(e->type() == QEvent::MouseMove)
+ {
+ if(m_pMovedChild)
+ {
+ QMouseEvent * ev = (QMouseEvent *)e;
+
+ QPoint pnt = mapFromGlobal(m_pMovedChild->mapToGlobal(ev->pos()));
+ if((pnt.y() < 0) || (pnt.y() > height()) || (pnt.x() < 0) || (pnt.x() > width()))
+ {
+ // drag out!
+// FIXME: This is screwed up in Qt4.... :/
+#ifdef COMPILE_USE_QT4
+ QDrag * d = new QDrag(this);
+ QMimeData * m = new QMimeData();
+ m->setText(m_pMovedChild->name());
+ d->setMimeData(m);
+#else
+ QDragObject * d = new QTextDrag(m_pMovedChild->name(),this);
+#endif
+ KviAction * act = KviActionManager::instance()->getAction(m_pMovedChild->name());
+ if(act)
+ {
+ QPixmap * pixie = act->bigIcon();
+#ifdef COMPILE_USE_QT4
+ if(pixie)
+ {
+ d->setPixmap(*pixie);
+ d->setHotSpot(QPoint(3,3));
+ }
+#else
+ if(pixie)d->setPixmap(*pixie,QPoint(3,3));
+#endif
+ }
+ //d->setPixmap(QPixmap::grabWidget(m_pMovedChild),QPoint(m_pMovedChild->width() / 2,m_pMovedChild->height() / 2));
+ // throw it somewhere else for now
+ if(m_pFilteredChildren)
+ unfilterChild(m_pMovedChild);
+#ifdef COMPILE_USE_QT4
+ QAction * pActionForMovedChild = actionForWidget(m_pMovedChild);
+ if(pActionForMovedChild)
+ pActionForMovedChild->setVisible(false);
+ m_pMovedChild->hide();
+#else
+ m_pMovedChild->hide();
+ m_pMovedChild->reparent(g_pFrame,QPoint(-1000,-1000),false);
+#endif
+ QEvent ev(QEvent::LayoutHint);
+ QApplication::sendEvent(this,&ev);
+#ifdef COMPILE_USE_QT4
+ if(!d->exec(Qt::MoveAction) != Qt::MoveAction)
+#else
+ if(!d->dragMove())
+#endif
+ {
+ // the user has probably failed to remove the action from the toolbar
+ // flash the trashcan in the customize toolbars dialog
+ KviActionManager::instance()->emitRemoveActionsHintRequest();
+ // will filter it as ChildInserted
+#ifndef COMPILE_USE_QT4
+ m_pMovedChild->reparent(this,QPoint(0,0),false);
+#endif
+#ifdef COMPILE_USE_QT4
+ QAction * pActionForMovedChild = actionForWidget(m_pMovedChild);
+ if(pActionForMovedChild)
+ pActionForMovedChild->setVisible(false);
+#else
+ boxLayout()->insertWidget(0,m_pMovedChild);
+ m_pMovedChild->show();
+#ifdef COMPILE_KDE_SUPPORT
+ // bleah ://///
+ insertWidget(-1,m_pMovedChild->width(),m_pMovedChild,0);
+#endif
+#endif
+ QEvent ev(QEvent::LayoutHint);
+ QApplication::sendEvent(this,&ev);
+ } else {
+ QApplication::sendPostedEvents(m_pMovedChild,0);
+ m_pMovedChild->deleteLater();
+ m_pMovedChild = 0;
+ }
+ return true;
+ }
+
+ drag(m_pMovedChild,pnt);
+ return true;
+ }
+ goto unhandled;
+ }
+unhandled:
+ return KviToolBar::eventFilter(o,e);
+}
diff --git a/src/kvirc/ui/kvi_customtoolbar.h b/src/kvirc/ui/kvi_customtoolbar.h
new file mode 100644
index 0000000..64e9526
--- /dev/null
+++ b/src/kvirc/ui/kvi_customtoolbar.h
@@ -0,0 +1,91 @@
+#ifndef _KVI_CUSTOMTOOLBAR_H_
+#define _KVI_CUSTOMTOOLBAR_H_
+//=============================================================================
+//
+// File : kvi_customtoolbar.h
+// Created on Sun 21 Nov 2004 05:28:57 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2004 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_toolbar.h"
+#include "kvi_pointerhashtable.h"
+
+#ifdef COMPILE_ON_WINDOWS
+ #include "kvi_customtoolbardescriptor.h"
+#else
+ class KviCustomToolBarDescriptor;
+#endif
+class KviCustomToolBar;
+
+class KviCustomToolBarSeparator : public QWidget
+{
+ Q_OBJECT
+public:
+ KviCustomToolBarSeparator(KviCustomToolBar *pParent,const char * name);
+ QSize sizeHint() const;
+protected:
+ KviCustomToolBar * m_pToolBar;
+protected:
+ void paintEvent(QPaintEvent *e);
+};
+
+class KVIRC_API KviCustomToolBar : public KviToolBar
+{
+ friend class KviCustomToolBarDescriptor;
+ Q_OBJECT
+protected:
+ KviCustomToolBar(KviCustomToolBarDescriptor * d,const QString &label,QT_TOOLBARDOCK_TYPE dock = QT_DOCK_TOP,bool bNewLine = false,const char * nam = 0);
+public:
+ ~KviCustomToolBar();
+protected:
+ KviCustomToolBarDescriptor * m_pDescriptor;
+ QWidget * m_pMovedChild;
+ QWidget * m_pDraggedChild;
+ KviPointerHashTable<void *,bool> * m_pFilteredChildren;
+public:
+ KviCustomToolBarDescriptor * descriptor(){ return m_pDescriptor; };
+protected:
+ virtual void mousePressEvent(QMouseEvent * e);
+ virtual void dragEnterEvent(QDragEnterEvent *e);
+ virtual void dragMoveEvent(QDragMoveEvent *e);
+ virtual void dragLeaveEvent(QDragLeaveEvent *e);
+ virtual void dropEvent(QDropEvent *e);
+ virtual void childEvent(QChildEvent *e);
+ virtual bool eventFilter(QObject *o,QEvent *e);
+ int dropIndexAt(const QPoint &pnt,QWidget * exclude,int * excludeIdx);
+#ifdef COMPILE_USE_QT4
+ QWidget * widgetAt(int index);
+ QAction * actionForWidget(QWidget * pWidget);
+#endif
+ void drag(QWidget * child,const QPoint &pnt);
+ void filterChild(QObject * o);
+ void unfilterChild(QObject * o);
+ virtual void paintEvent(QPaintEvent * e);
+ void syncDescriptor();
+protected slots:
+ void beginCustomize();
+ void endCustomize();
+ void filteredChildDestroyed();
+};
+
+
+
+#endif //!_KVI_CUSTOMTOOLBAR_H_
diff --git a/src/kvirc/ui/kvi_debugwindow.cpp b/src/kvirc/ui/kvi_debugwindow.cpp
new file mode 100644
index 0000000..81067c0
--- /dev/null
+++ b/src/kvirc/ui/kvi_debugwindow.cpp
@@ -0,0 +1,132 @@
+//=============================================================================
+//
+// File : kvi_debugwindow.cpp
+// Creation date : Sun Jul 18 2005 14:12:22 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#include "kvi_debugwindow.h"
+#include "kvi_console.h"
+#include "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_input.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_config.h"
+
+#include "kvi_parameterlist.h"
+#include "kvi_frame.h"
+#include "kvi_valuelist.h"
+
+#include <qpixmap.h>
+#include <qsplitter.h>
+#include <qtoolbutton.h>
+
+KviDebugWindow * KviDebugWindow::m_pInstance = 0;
+
+
+KviDebugWindow::KviDebugWindow()
+: KviWindow(KVI_WINDOW_TYPE_DEBUG,g_pFrame,__tr2qs("Debug Messages"),0)
+{
+ m_pInstance = this;
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"main_splitter");
+ m_pIrcView = new KviIrcView(m_pSplitter,g_pFrame,this);
+ m_pInput = new KviInput(this,0);
+ updateCaption();
+}
+
+KviDebugWindow::~KviDebugWindow()
+{
+ m_pInstance = 0;
+}
+
+KviDebugWindow * KviDebugWindow::getInstance()
+{
+ if(m_pInstance)return m_pInstance;
+ m_pInstance = new KviDebugWindow();
+ g_pFrame->addWindow(m_pInstance,!KVI_OPTION_BOOL(KviOption_boolShowMinimizedDebugWindow));
+ if(KVI_OPTION_BOOL(KviOption_boolShowMinimizedDebugWindow))
+ m_pInstance->minimize();
+ return m_pInstance;
+}
+
+
+
+void KviDebugWindow::getBaseLogFileName(QString &buffer)
+{
+ buffer = "debug";
+}
+
+void KviDebugWindow::saveProperties(KviConfig *cfg)
+{
+ KviWindow::saveProperties(cfg);
+ cfg->writeEntry("Splitter",m_pSplitter->sizes());
+}
+
+void KviDebugWindow::loadProperties(KviConfig *cfg)
+{
+ int w = width();
+ KviWindow::loadProperties(cfg);
+ KviValueList<int> def;
+ def.append((w * 80) / 100);
+ def.append((w * 20) / 100);
+ m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def));
+}
+
+void KviDebugWindow::fillCaptionBuffers()
+{
+ static QString begin("<nobr><font color=\"");
+ static QString boldbegin("\"><b>");
+ static QString end("</b></font></nobr>");
+
+ m_szPlainTextCaption = windowName();
+
+ m_szHtmlActiveCaption = begin;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += boldbegin;
+ m_szHtmlActiveCaption += windowName();
+ m_szHtmlActiveCaption += end;
+
+ m_szHtmlInactiveCaption = begin;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += boldbegin;
+ m_szHtmlInactiveCaption += windowName();
+ m_szHtmlInactiveCaption += end;
+}
+
+QPixmap * KviDebugWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_BUG);
+}
+
+void KviDebugWindow::resizeEvent(QResizeEvent *e)
+{
+ int hght = m_pInput->heightHint();
+ m_pSplitter->setGeometry(0,0,width(),height() - hght);
+ m_pInput->setGeometry(0,height() - hght,width(),hght);
+}
+
+QSize KviDebugWindow::sizeHint() const
+{
+ QSize ret(m_pSplitter->sizeHint().width(),m_pIrcView->sizeHint().height() + m_pInput->heightHint());
+ return ret;
+}
+
diff --git a/src/kvirc/ui/kvi_debugwindow.h b/src/kvirc/ui/kvi_debugwindow.h
new file mode 100644
index 0000000..b9646e2
--- /dev/null
+++ b/src/kvirc/ui/kvi_debugwindow.h
@@ -0,0 +1,54 @@
+#ifndef _KVI_DEBUGWINDOW_H_
+#define _KVI_DEBUGWINDOW_H_
+//=============================================================================
+//
+// File : kvi_debugwindow.h
+// Creation date : Sun Jul 18 2005 14:14:00 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2005 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_window.h"
+#include "kvi_string.h"
+
+class QSplitter;
+
+class KVIRC_API KviDebugWindow : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviDebugWindow();
+ ~KviDebugWindow();
+protected:
+ static KviDebugWindow * m_pInstance;
+public:
+ static KviDebugWindow * instance(){ return m_pInstance; };
+ static KviDebugWindow * getInstance();
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void loadProperties(KviConfig * cfg);
+ virtual void saveProperties(KviConfig * cfg);
+ virtual void getBaseLogFileName(QString &buffer);
+ virtual QSize sizeHint() const;
+};
+
+#endif //_KVI_DEBUGWINDOW_H_
diff --git a/src/kvirc/ui/kvi_dynamictooltip.cpp b/src/kvirc/ui/kvi_dynamictooltip.cpp
new file mode 100644
index 0000000..3e6f22c
--- /dev/null
+++ b/src/kvirc/ui/kvi_dynamictooltip.cpp
@@ -0,0 +1,61 @@
+//
+// File : kvi_dynamictooltip.cpp
+// Creation date : Wed Nov 01 2000 15:25:11 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVIRC__
+#include "kvi_dynamictooltip.h"
+
+KviDynamicToolTipHelper::KviDynamicToolTipHelper(QWidget * parent,KviDynamicToolTip * parToolTip)
+: KviTalToolTip(parent)
+{
+ m_pParentToolTip = parToolTip;
+}
+
+KviDynamicToolTipHelper::~KviDynamicToolTipHelper()
+{
+}
+
+void KviDynamicToolTipHelper::maybeTip(const QPoint & pnt)
+{
+ m_pParentToolTip->maybeTip(pnt);
+}
+
+KviDynamicToolTip::KviDynamicToolTip(QWidget * parent,const char * name)
+: QObject(parent,name)
+{
+ m_pHelper = new KviDynamicToolTipHelper(parent,this);
+}
+
+KviDynamicToolTip::~KviDynamicToolTip()
+{
+ delete m_pHelper;
+}
+
+void KviDynamicToolTip::maybeTip(const QPoint &pnt)
+{
+ emit tipRequest(this,pnt);
+}
+
+void KviDynamicToolTip::tip(const QRect &rct,const QString & text)
+{
+ m_pHelper->tip(rct,text);
+}
+
+#include "kvi_dynamictooltip.moc"
diff --git a/src/kvirc/ui/kvi_dynamictooltip.h b/src/kvirc/ui/kvi_dynamictooltip.h
new file mode 100644
index 0000000..119c224
--- /dev/null
+++ b/src/kvirc/ui/kvi_dynamictooltip.h
@@ -0,0 +1,61 @@
+#ifndef _KVI_DYNAMICTOOLTIP_H_
+#define _KVI_DYNAMICTOOLTIP_H_
+
+//
+// File : kvi_dynamictooltip.h
+// Creation date : Wed Nov 01 2000 15:23:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+#include "kvi_tal_tooltip.h"
+#include <qobject.h>
+
+class KviDynamicToolTip;
+
+class KVIRC_API KviDynamicToolTipHelper : public KviTalToolTip
+{
+ friend class KviDynamicToolTip;
+protected:
+ KviDynamicToolTipHelper(QWidget * parent,KviDynamicToolTip * parToolTip);
+ virtual ~KviDynamicToolTipHelper();
+protected:
+ KviDynamicToolTip * m_pParentToolTip;
+protected:
+ virtual void maybeTip(const QPoint &pnt);
+};
+
+class KVIRC_API KviDynamicToolTip : public QObject
+{
+ friend class KviDynamicToolTipHelper;
+ Q_OBJECT
+public:
+ KviDynamicToolTip(QWidget * parent,const char * name = 0);
+ virtual ~KviDynamicToolTip();
+protected:
+ KviDynamicToolTipHelper * m_pHelper;
+public:
+ void tip(const QRect &rct,const QString & text);
+protected:
+ void maybeTip(const QPoint &pnt);
+signals:
+ void tipRequest(KviDynamicToolTip *tip,const QPoint &pnt);
+};
+
+#endif //!_KVI_DYNAMICTOOLTIP_H_
diff --git a/src/kvirc/ui/kvi_filedialog.cpp b/src/kvirc/ui/kvi_filedialog.cpp
new file mode 100644
index 0000000..99f9c16
--- /dev/null
+++ b/src/kvirc/ui/kvi_filedialog.cpp
@@ -0,0 +1,229 @@
+//
+// File : kvi_filedialog.cpp
+// Creation date : Mon Nov 20 2000 12:20:42 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVIRC__
+#include "kvi_filedialog.h"
+#include "kvi_mediatype.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_fileutils.h"
+#include "kvi_frame.h"
+#include "kvi_qstring.h"
+
+#include <qdir.h>
+#include "kvi_tal_tooltip.h"
+#include <qmessagebox.h>
+
+extern KviMediaManager * g_pMediaManager;
+
+
+KviFileDialog::KviFileDialog(const QString &dirName, const QString &filter,
+ QWidget *parent, const char *name, bool modal)
+: KviTalFileDialog(dirName,filter,parent,name,modal)
+{
+
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)));
+
+}
+
+KviFileDialog::~KviFileDialog()
+{
+}
+
+
+/*
+void KviFileDialog::goKvirc()
+{
+
+ KviStr tmp;
+ g_pApp->getLocalKvircDirectory(tmp,KviApp::None);
+ setDir(QDir(tmp.ptr()));
+
+}
+
+void KviFileDialog::goHome()
+{
+
+ setDir(QDir::home());
+
+}
+*/
+
+
+
+bool KviFileDialog::askForOpenFileName(QString &buffer,const QString &caption,const QString &initial,const QString &filter,bool showHidden, bool showNative,QWidget* parent)
+{
+#ifdef COMPILE_ON_WINDOWS
+ if(showNative)
+ {
+ buffer=QFileDialog::getOpenFileName(initial,filter,parent,"open_file_name_dialog",caption);
+ KviFileUtils::adjustFilePath(buffer);
+ return !buffer.isEmpty();
+ }
+#endif
+ KviFileDialog * d = new KviFileDialog(initial,filter,parent,"open_file_name_dialog",true);
+ d->setCaption(caption);
+ d->setMode(QFileDialog::ExistingFile);
+ //d->setShowHiddenFiles(showHidden);
+ if(d->exec() == QDialog::Accepted)
+ {
+ buffer = d->selectedFile();
+ KviFileUtils::adjustFilePath(buffer);
+ delete d;
+ return !buffer.isEmpty();
+ }
+ delete d;
+ return false;
+}
+
+
+bool KviFileDialog::askForSaveFileName(QString &buffer,const QString & caption,const QString &initial,const QString &filter,bool showHidden,bool bConfirmOverwrite,bool showNative,QWidget* parent)
+{
+ #ifdef COMPILE_ON_WINDOWS
+ if (showNative)
+ {
+ while (1)
+ {
+ buffer=QFileDialog::getSaveFileName(initial,filter,parent,"save_file_name_dialog",caption);
+ KviFileUtils::adjustFilePath(buffer);
+ //return !buffer.isEmpty();
+ if(buffer.isEmpty()) return false;
+ if(!bConfirmOverwrite) return true;
+ // Check for the file existence
+ if(!KviFileUtils::fileExists(buffer)) return true;
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("The file %s already exists.<br>Do you wish to overwrite it?"),buffer.utf8().data());
+ switch(QMessageBox::information(parent,__tr2qs("File Exists - KVIrc"),tmp,QMessageBox::Yes,QMessageBox::No | QMessageBox::Default,QMessageBox::Cancel | QMessageBox::Escape))
+ {
+ case QMessageBox::Cancel: return false; break;
+ case QMessageBox::Yes: return true; break;
+ }
+
+ }
+
+
+ }
+ #endif
+
+
+ KviFileDialog * d = new KviFileDialog(initial,filter,parent,"save_file_name_dialog",true);
+ d->setCaption(caption);
+ d->setMode(QFileDialog::AnyFile);
+ //d->setShowHiddenFiles(showHidden);
+
+ while(d->exec() == QDialog::Accepted)
+ {
+ buffer = d->selectedFile();
+ KviFileUtils::adjustFilePath(buffer);
+
+ if(!buffer.isEmpty())
+ {
+ if(!bConfirmOverwrite)
+ {
+ delete d;
+ return true;
+ }
+ // Check for the file existence
+ if(KviFileUtils::fileExists(buffer))
+ {
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("The file %s already exists.<br>Do you wish to overwrite it?"),buffer.utf8().data());
+ switch(QMessageBox::information(d,__tr2qs("File Exists - KVIrc"),tmp,QMessageBox::Yes,QMessageBox::No | QMessageBox::Default,QMessageBox::Cancel | QMessageBox::Escape))
+ {
+ case QMessageBox::Cancel: delete d; return false; break;
+ case QMessageBox::Yes: delete d; return true; break;
+ }
+ } else {
+ delete d;
+ return true; // ok...file not exists
+ }
+ } else {
+ delete d;
+ return false; // empty buffer
+ }
+ }
+
+ delete d;
+ return false;
+
+}
+
+bool KviFileDialog::askForDirectoryName(QString &buffer,const QString & caption,const QString & initial,const char * filter,bool showHidden,bool showNative,QWidget* parent)
+{
+#ifdef COMPILE_ON_WINDOWS
+ if(showNative)
+ {
+ buffer = QFileDialog::getExistingDirectory(initial,parent,"open_file_name_dialog",caption);
+ return !buffer.isEmpty();
+ }
+#else
+ #ifdef COMPILE_KDE_SUPPORT
+ // the KDE based dir selection dialog is now quite nice
+ buffer = KFileDialog::getExistingDirectory(initial,parent,caption);
+ return !buffer.isEmpty();
+ #endif
+#endif
+
+ KviFileDialog * d = new KviFileDialog(initial,
+ filter,parent,"directory_name_dialog",true);
+ d->setCaption(caption);
+ d->setMode(QFileDialog::Directory);
+ //d->setShowHiddenFiles(showHidden);
+ if(d->exec() == QDialog::Accepted)
+ {
+ buffer = d->selectedFile();
+ KviFileUtils::adjustFilePath(buffer);
+ delete d;
+ return !buffer.isEmpty();
+ }
+ delete d;
+
+ return false;
+}
+
+
+bool KviFileDialog::askForOpenFileNames(QStringList &buffer,const QString & caption,const QString & initial,const char * filter,bool showHidden,bool showNative,QWidget* parent)
+{
+ #ifdef COMPILE_ON_WINDOWS
+ if (showNative)
+ {
+ buffer=QFileDialog::getOpenFileNames(filter,initial,parent,"open_file_name_dialog",caption);
+ return (buffer.count()>0);
+ }
+
+ #endif
+ KviFileDialog * d = new KviFileDialog(initial,filter ? QString(filter) : QString::null,parent,"open_file_names_dialog",true);
+ d->setCaption(caption);
+ d->setMode(QFileDialog::ExistingFiles);
+ //d->setShowHiddenFiles(showHidden);
+ if(d->exec() == QDialog::Accepted)
+ {
+ buffer = d->selectedFiles();
+ delete d;
+ return (buffer.count() > 0);
+ }
+ delete d;
+ return false;
+}
+
+
+#include "kvi_filedialog.moc"
diff --git a/src/kvirc/ui/kvi_filedialog.h b/src/kvirc/ui/kvi_filedialog.h
new file mode 100644
index 0000000..985898d
--- /dev/null
+++ b/src/kvirc/ui/kvi_filedialog.h
@@ -0,0 +1,55 @@
+#ifndef _KVI_FILEDIALOG_H_
+#define _KVI_FILEDIALOG_H_
+
+//
+// File : kvi_filedialog.h
+// Creation date : Mon Nov 20 2000 03:52:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef Unsorted
+ #undef Unsorted
+#endif
+#include "kvi_settings.h"
+#include "kvi_string.h"
+
+
+#include "kvi_tal_filedialog.h"
+
+#include <qstringlist.h>
+
+
+class KVIRC_API KviFileDialog : public KviTalFileDialog
+{
+ Q_OBJECT
+public:
+ KviFileDialog(const QString &dirName, const QString &filter=QString::null,
+ QWidget *parent=0, const char *name=0, bool modal=false);
+ ~KviFileDialog();
+public:
+ static bool askForOpenFileName(QString &buffer,const QString & caption,const QString &initial = QString::null,const QString &filter = QString::null,bool showHidden = false,bool showNative = true,QWidget* parent=0);
+ static bool askForSaveFileName(QString &buffer,const QString & caption,const QString &initial = QString::null,const QString &filter = QString::null,bool showHidden = false,bool bConfirmOverwrite = false,bool showNative = true,QWidget* parent=0);
+
+ static bool askForDirectoryName(QString &buffer,const QString & caption,const QString & initial,const char * filter = 0,bool showHidden = false,bool showNative=true,QWidget* parent=0);
+ static bool askForOpenFileNames(QStringList &buffer,const QString & caption,const QString & initial,const char * filter = 0,bool showHidden = false,bool showNative=true,QWidget* parent=0);
+
+};
+
+
+#endif //_KVI_FILEDIALOG_H_
diff --git a/src/kvirc/ui/kvi_frame.cpp b/src/kvirc/ui/kvi_frame.cpp
new file mode 100644
index 0000000..e7b7c0b
--- /dev/null
+++ b/src/kvirc/ui/kvi_frame.cpp
@@ -0,0 +1,1450 @@
+//=============================================================================
+//
+// File : kvi_frame.cpp
+// Creation date : Sun Jun 18 2000 17:59:02 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#define _KVI_FRAME_CPP_
+
+#include "kvi_debug.h"
+#include "kvi_app.h"
+#include "kvi_settings.h"
+#include "kvi_frame.h"
+#include "kvi_options.h"
+#include "kvi_menubar.h"
+#include "kvi_mdimanager.h"
+#include "kvi_mdichild.h"
+#include "kvi_iconmanager.h"
+#include "kvi_window.h"
+#include "kvi_taskbar.h"
+#include "kvi_console.h"
+#include "kvi_config.h"
+#include "kvi_internalcmd.h"
+#include "kvi_console.h"
+#include "kvi_debug.h"
+#include "kvi_irctoolbar.h"
+#include "kvi_confignames.h"
+#include "kvi_parameterlist.h"
+#include "kvi_module.h"
+#include "kvi_mextoolbar.h"
+#include "kvi_locale.h"
+#include "kvi_irccontext.h"
+#include "kvi_statusbar.h"
+#include "kvi_customtoolbar.h"
+#include "kvi_customtoolbarmanager.h"
+#include "kvi_customtoolbardescriptor.h"
+#include "kvi_actionmanager.h"
+#include "kvi_defaults.h"
+#include "kvi_ircview.h"
+#include "kvi_tal_popupmenu.h"
+
+#include "kvi_kvs_script.h"
+#include "kvi_kvs_eventtriggers.h"
+
+#include <qsplitter.h>
+#include <qvariant.h>
+#include <qlineedit.h>
+#include <qmessagebox.h>
+#include <qcheckbox.h>
+
+#include <qtimer.h>
+#include <qlayout.h>
+
+#if QT_VERSION >= 300
+ #include <qfile.h>
+ #include <qtextstream.h>
+ #ifdef COMPILE_USE_QT4
+ #include <q3dockarea.h>
+ #define QDockArea Q3DockArea
+ #else
+ #include <qdockarea.h>
+ #endif
+#endif
+
+
+#ifdef COMPILE_USE_QT4
+ #include <qdesktopwidget.h>
+ #include <qevent.h>
+ #include <QShortcut>
+#else
+ #include <qaccel.h>
+#endif
+
+#include <time.h>
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ #include <qpixmap.h>
+ // kvi_app.h
+ extern QPixmap * g_pShadedParentGlobalDesktopBackground;
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+// FIXME: #warning "When a toolbar is moved , MdiManager is resized but does not update the MdiChild backgrounds"
+#endif
+
+// Declared and managed by KviApp (kvi_app.cpp)
+extern KviConfig * g_pWinPropertiesConfig;
+KVIRC_API KviFrame * g_pFrame = 0; // the one and only frame object
+
+KviFrame::KviFrame()
+: KviTalMainWindow(0,"kvirc_frame")
+{
+ g_pFrame = this;
+
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)));
+
+ m_pWinList = new KviPointerList<KviWindow>;
+ m_pWinList->setAutoDelete(false);
+
+ m_pModuleExtensionToolBarList = new KviPointerList<KviMexToolBar>;
+ m_pModuleExtensionToolBarList->setAutoDelete(false);
+
+ m_pActiveContext = 0;
+
+ m_pDockExtension = 0;
+
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"main_splitter");
+// m_pSplitter->setFrameShape(QFrame::NoFrame);
+
+ setCentralWidget(m_pSplitter);
+
+ setUsesBigPixmaps(KVI_OPTION_BOOL(KviOption_boolUseBigIcons));
+
+ m_pMdi = new KviMdiManager(m_pSplitter,this,"mdi_manager");
+ connect(m_pMdi,SIGNAL(enteredSdiMode()),this,SLOT(enteredSdiMode()));
+ connect(m_pMdi,SIGNAL(leftSdiMode()),this,SLOT(leftSdiMode()));
+
+ // This theoretically had to exists before KviMdiManager (that uses enterSdiMode)
+ m_pMenuBar = new KviMenuBar(this,"main_menu_bar");
+#ifdef COMPILE_USE_QT4
+ setMenuWidget(m_pMenuBar);
+#endif
+
+ if(KVI_OPTION_BOOL(KviOption_boolStatusBarVisible))
+ {
+ m_pStatusBar = new KviStatusBar(this);
+#ifdef COMPILE_USE_QT4
+ setStatusBar(m_pStatusBar);
+#endif
+ // torque: moved out of status bar constructor
+ // because module init functions exectued in load()
+ // couldn't access the status bar via g_pFrame->mainStatusBar()
+ // (assignment of m_pStatusBar happened after load() and
+ // the init function)
+ m_pStatusBar->load();
+
+ } else
+ m_pStatusBar = 0;
+
+ m_pTaskBar = 0;
+
+ createTaskBar();
+
+ if((KVI_OPTION_RECT(KviOption_rectFrameGeometry).width() < 100) || (KVI_OPTION_RECT(KviOption_rectFrameGeometry).height() < 100))
+ {
+ // Try to find some reasonable defaults
+ KVI_OPTION_RECT(KviOption_rectFrameGeometry) = QRect(10,10,g_pApp->desktop()->width() - 200,g_pApp->desktop()->height() - 150);
+ }
+
+ resize(KVI_OPTION_RECT(KviOption_rectFrameGeometry).width(),
+ KVI_OPTION_RECT(KviOption_rectFrameGeometry).height());
+ move(KVI_OPTION_RECT(KviOption_rectFrameGeometry).x(),
+ KVI_OPTION_RECT(KviOption_rectFrameGeometry).y());
+
+ applyOptions();
+
+
+ m_pAccel = new KviAccel(this);
+
+ installAccelerators(this);
+
+ layout()->setResizeMode(QLayout::FreeResize);
+}
+
+KviFrame::~KviFrame()
+{
+ KVI_OPTION_RECT(KviOption_rectFrameGeometry) = QRect(pos().x(),pos().y(),
+ size().width(),size().height());
+
+ KVI_OPTION_BOOL(KviOption_boolUseBigIcons) = usesBigPixmaps();
+ KVI_OPTION_BOOL(KviOption_boolMdiManagerInSdiMode) = m_pMdi->isInSDIMode();
+ KVI_OPTION_BOOL(KviOption_boolStatusBarVisible) = m_pStatusBar ? true : false;
+
+ KviCustomToolBarManager::instance()->storeVisibilityState();
+
+ saveToolBarPositions();
+ saveModuleExtensionToolBars();
+
+ // Call the frame destructor callback AFTER saving the toolbar positions
+ // This is because the destructor callback kills alls the KVS objects
+ // and thus the eventual user toolbar objects too and their position
+ // wouldn't be saved if they are shown at startup.
+
+ g_pApp->frameDestructorCallback();
+
+ // Now start killing stuff
+
+ // Explicitly kill all the module extension toolbars: qt has NOT to delete them: we must call their "die" method
+ while(KviMexToolBar * t = m_pModuleExtensionToolBarList->first())t->die();
+ delete m_pModuleExtensionToolBarList;
+
+ KVI_OPTION_BOOL(KviOption_boolShowDockExtension) = m_pDockExtension;
+
+ if(m_pDockExtension)
+ {
+ m_pDockExtension->die();
+ m_pDockExtension = 0;
+ }
+
+ // the really last thing to do : close all the windows
+ while(m_pWinList->first())
+ closeWindow(m_pWinList->first());
+ delete m_pWinList;
+
+ delete m_pAccel;
+ g_pFrame = 0;
+}
+
+int KviFrame::registerAccelerator(const QString &szKeySequence,QObject * recv,const char * slot)
+{
+ int id = m_pAccel->insertItem(szKeySequence);
+ m_pAccel->connectItem(id,recv,slot);
+ return id;
+}
+
+void KviFrame::unregisterAccelerator(int id)
+{
+ m_pAccel->removeItem(id);
+}
+
+void KviFrame::registerModuleExtensionToolBar(KviMexToolBar * t)
+{
+ m_pModuleExtensionToolBarList->append(t);
+}
+
+void KviFrame::unregisterModuleExtensionToolBar(KviMexToolBar * t)
+{
+ m_pModuleExtensionToolBarList->removeRef(t);
+}
+
+void KviFrame::restoreModuleExtensionToolBars()
+{
+ for(QStringList::Iterator it = KVI_OPTION_STRINGLIST(KviOption_stringlistModuleExtensionToolbars).begin();it != KVI_OPTION_STRINGLIST(KviOption_stringlistModuleExtensionToolbars).end();++it)
+ {
+ QString szEntry = *it;
+ int idx = szEntry.find(':');
+ if(idx != -1)
+ {
+ QString szMod = szEntry.left(idx);
+ szEntry.remove(0,idx + 1);
+ g_pModuleExtensionManager->allocateExtension("toolbar",KviStr(szEntry),firstConsole(),0,0,szMod);
+ }
+ }
+}
+
+void KviFrame::saveModuleExtensionToolBars()
+{
+ KVI_OPTION_STRINGLIST(KviOption_stringlistModuleExtensionToolbars).clear();
+
+ for(KviMexToolBar * t = m_pModuleExtensionToolBarList->first();t;t = m_pModuleExtensionToolBarList->next())
+ {
+ QString s = t->descriptor()->module()->name();
+ s += ":";
+ s += t->descriptor()->name().ptr();
+
+ //debug("FOUND TOOLBAR %s",t->descriptor()->name().ptr());
+
+ KVI_OPTION_STRINGLIST(KviOption_stringlistModuleExtensionToolbars).append(s);
+ }
+}
+
+KviMexToolBar * KviFrame::moduleExtensionToolBar(int extensionId)
+{
+ for(KviMexToolBar * t = m_pModuleExtensionToolBarList->first();t;t = m_pModuleExtensionToolBarList->next())
+ {
+ if(extensionId == t->descriptor()->id())return t;
+ }
+ return 0;
+}
+
+/*
+ @doc: keyboard
+ @type:
+ generic
+ @title:
+ Keyboard shortcuts
+ @keyterms:
+ Keyboard shortcuts
+ @short:
+ The list of the common keyboard shortcuts
+ @body:
+ [b]Ctrl+LeftArrow[/b]: Selection left to the previous word[br]
+ [b]Ctrl+RightArrow[/b]: Selection right to the next word[br]
+ [b]Ctrl+Shift+LeftArrow[/b]: Previous word[br]
+ [b]Ctrl+Shift+RightArrow[/b]: Next word[br]
+ [b]Alt+LeftArrow[/b]: Previous window[br]
+ [b]Alt+RightArrow[/b]: Next window[br]
+ [b]Alt+Shift+LeftArrow[/b]: Previous window in the same IRC context[/b]
+ [b]Alt+Shift+RightArrow[/b]: Next window in the same IRC context[/b]
+ [b]Ctrl+UpArrow[/b]: Maximize current window[br]
+ [b]Ctrl+DownArrow[/b] or [b]ESC[/b]: Minimize current window[br]
+ [b]Ctrl+&lt;digit&gt;[/b], [b]F1-F12[/b], [b]Shift+(F1-F12)[/b]: Script accelerators (see [event:onaccelkeypressed]OnAccelKeyPressed[/event])[br]
+ [b]Shift+&lt;F1-F12&gt;[/b] window switch[br]
+ [b]Tab in the first word of input[/b]: Completes nicknames in the current channel or query[br]
+ [b]Tab after a leading /[/b]: Completes commands[br]
+ [b]Tab after a / in the middle of input[/b]: Completes directories[br]
+ [b]Tab after a $[/b]: Completes function names[br]
+ [b]Shift+Tab after the first word of input[/b]: completes masks in the current channel or query[br]
+ [b]Ctrl+B[/b]: Inserts the 'bold' mIRC text control character[br]
+ [b]Ctrl+K[/b]: Inserts the 'color' mIRC text control character[br]
+ [b]Ctrl+R[/b]: Inserts the 'reverse' mIRC text control character[br]
+ [b]Ctrl+U[/b]: Inserts the 'underline' mIRC text control character[br]
+ [b]Ctrl+O[/b]: Inserts the 'reset' mIRC text control character[br]
+ [b]Ctrl+P[/b]: Inserts the 'non-crypt' (plain text) KVIrc control character used to disable encryption of the current text line[br]
+ [b]Ctrl+C[/b]: Copies the selected text to clipboard[br]
+ [b]Ctrl+X[/b]: Cuts the selected text[br]
+ [b]Ctrl+V[/b]: Pastes the clipboard contents (same as middle mouse click)[br]
+ [b]Ctrl+I[/b]: Inserts the 'icon' control code and pops up the icon list box
+ [b]CursorUp[/b]: Moves backward in the command history[br]
+ [b]CursorDown[/b]: Moves forward in the command history[br]
+ [b]Ctrl+PageUp[/b]: Opens the history popup[br]
+ [b]CursorRight[/b]: Moves the cursor to the right[br]
+ [b]CursorLeft[/b]: Moves the cursor to the left :)[br]
+ [b]Shift+CursorLeft[/b]: Moves the selection to the left[br]
+ [b]Shift+RightCursor[/b]: Moves the selection to the right[br]
+ [b]PageUp[/b]: Scrolls the output window up one page[br]
+ [b]PageDown[/b]: Scrolls the output window down one page[b]
+ [b]Shift+PageUp[/b]: Scrolls the output window up one line[br]
+ [b]Shift+PageDown[/b]: Scrolls the output window down one line[b]
+ [b]Alt+lt;numeric_sequence&gt;[/b]: Inserts the character by ASCII/Unicode code[br]
+ [b]Ctrl+Backspace[/b]: Shows or hides the multiline editor[br]
+ [b]Ctrl+F4[/b]: Closes the current window[br]
+ <example>
+ Alt+32: Inserts ASCII/Unicode character 32: ' ' (a space)
+ Alt+00032: Same as above :)
+ Alt+13: Inserts the Carriage Return (CR) control character
+ Alt+77: Inserts ASCII/Unicode character 77: 'M'
+ Alt+23566: Inserts Unicode character 23566 (an ideogram)
+ </example>
+*/
+
+KviAccel * KviFrame::installAccelerators(QWidget * wnd)
+{
+ QWidget * pParent = wnd ? (QWidget *)wnd : (QWidget *)this;
+#ifdef COMPILE_USE_QT4
+ new QShortcut(QKeySequence(Qt::Key_Left + Qt::ALT),pParent,SLOT(switchToPrevWindow()));
+ new QShortcut(QKeySequence(Qt::Key_Right + Qt::ALT),pParent,SLOT(switchToNextWindow()));
+ new QShortcut(QKeySequence(Qt::Key_Up + Qt::CTRL),pParent,SLOT(maximizeWindow()));
+ new QShortcut(QKeySequence(Qt::Key_Down + Qt::CTRL),pParent,SLOT(minimizeWindow()));
+ new QShortcut(QKeySequence(Qt::Key_Escape +Qt::CTRL),pParent,SLOT(minimizeWindow()));
+ new QShortcut(QKeySequence(Qt::Key_Left + Qt::ALT + Qt::SHIFT),pParent,SLOT(switchToPrevWindowInContext()));
+ new QShortcut(QKeySequence(Qt::Key_Right + Qt::ALT + Qt::SHIFT),pParent,SLOT(switchToNextWindowInContext()));
+#endif
+ KviAccel *ac = new KviAccel(pParent);
+
+ static int accel_table[] = {
+ Qt::Key_Left + Qt::ALT , // prev window
+ Qt::Key_Right + Qt::ALT , // next window
+ Qt::Key_Up + Qt::CTRL , // maximize window
+ Qt::Key_Down + Qt::CTRL , // minimize window
+ Qt::Key_Escape +Qt::CTRL, // minimize window
+ Qt::Key_Left + Qt::ALT + Qt::SHIFT , // prev window in context
+ Qt::Key_Right + Qt::ALT + Qt::SHIFT, // next window in context
+ Qt::Key_F4 + Qt::CTRL , // close current window
+ Qt::Key_1 + Qt::CTRL , // script accels...
+ Qt::Key_2 + Qt::CTRL ,
+ Qt::Key_3 + Qt::CTRL ,
+ Qt::Key_4 + Qt::CTRL ,
+ Qt::Key_5 + Qt::CTRL ,
+ Qt::Key_6 + Qt::CTRL ,
+ Qt::Key_7 + Qt::CTRL ,
+ Qt::Key_8 + Qt::CTRL ,
+ Qt::Key_9 + Qt::CTRL ,
+ Qt::Key_0 + Qt::CTRL ,
+ Qt::Key_F1 , // reserved for context sensitive help
+ Qt::Key_F2 ,
+ Qt::Key_F3 ,
+ Qt::Key_F4 ,
+ Qt::Key_F5 ,
+ Qt::Key_F6 ,
+ Qt::Key_F7 ,
+ Qt::Key_F8 ,
+ Qt::Key_F9 ,
+ Qt::Key_F10 ,
+ Qt::Key_F11 ,
+ Qt::Key_F12 ,
+/* Qt::Key_F1 + Qt::SHIFT , // window select...
+ Qt::Key_F2 + Qt::SHIFT ,
+ Qt::Key_F3 + Qt::SHIFT ,
+ Qt::Key_F4 + Qt::SHIFT ,
+ Qt::Key_F5 + Qt::SHIFT ,
+ Qt::Key_F6 + Qt::SHIFT ,
+ Qt::Key_F7 + Qt::SHIFT ,
+ Qt::Key_F8 + Qt::SHIFT ,
+ Qt::Key_F9 + Qt::SHIFT ,
+ Qt::Key_F10 + Qt::SHIFT ,
+ Qt::Key_F11 + Qt::SHIFT ,
+ Qt::Key_F12 + Qt::SHIFT ,*/
+ 0
+ };
+
+ int i=0;
+ int keys;
+ while((keys = accel_table[i]))
+ {
+ ac->insertItem(keys);
+ i++;
+ }
+
+ connect(ac,SIGNAL(activated(int)),this,SLOT(accelActivated(int)));
+ return ac;
+}
+
+void KviFrame::accelActivated(int id)
+{
+ KviAccel * acc = (KviAccel *)sender();
+
+ int keys = (int)(acc->key(id));
+ KviTaskBarItem *item = 0;
+ debug("accel");
+ switch(keys)
+ {
+ case (Qt::Key_Left+Qt::ALT): switchToPrevWindow(); break;
+ case (Qt::Key_Right+Qt::ALT): switchToNextWindow(); break;
+ case (Qt::Key_Up+Qt::CTRL): maximizeWindow(); break;
+ case (Qt::Key_Escape+Qt::CTRL):
+ case (Qt::Key_Down+Qt::CTRL): minimizeWindow(); break;
+ case (Qt::Key_Left+Qt::ALT+Qt::SHIFT): switchToPrevWindowInContext(); break;
+ case (Qt::Key_Right+Qt::ALT+Qt::SHIFT): switchToNextWindowInContext(); break;
+ case (Qt::Key_F4+Qt::CTRL): if(g_pActiveWindow)g_pActiveWindow->close(); break;
+ case (Qt::Key_F1): g_pApp->contextSensitiveHelp(); break;
+/* case(Qt::Key_F1 + SHIFT):
+ item = m_pTaskBar->item(0);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F2 + SHIFT):
+ item = m_pTaskBar->item(1);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F3 + SHIFT):
+ item = m_pTaskBar->item(2);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F4 + SHIFT):
+ item = m_pTaskBar->item(3);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F5 + SHIFT):
+ item = m_pTaskBar->item(4);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F6 + SHIFT):
+ item = m_pTaskBar->item(5);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F7 + SHIFT):
+ item = m_pTaskBar->item(6);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F8 + SHIFT):
+ item = m_pTaskBar->item(7);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F9 + SHIFT):
+ item = m_pTaskBar->item(8);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F10 + SHIFT):
+ item = m_pTaskBar->item(9);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F11 + SHIFT):
+ item = m_pTaskBar->item(10);
+ if(item) setActiveWindow(item->window());
+ break;
+ case(Qt::Key_F12 + SHIFT):
+ item = m_pTaskBar->item(11);
+ if(item) setActiveWindow(item->window());
+ break;*/
+ default:
+ {
+ KVS_TRIGGER_EVENT_1(KviEvent_OnAccelKeyPressed,g_pActiveWindow,(QString)(acc->key(id)));
+ }
+ break;
+ };
+}
+
+void KviFrame::executeInternalCommand(int index)
+{
+ KviKvsScript::run(kvi_getInternalCommandBuffer(index),firstConsole());
+}
+
+
+void KviFrame::saveWindowProperties(KviWindow * wnd,const char * szSection)
+{
+ g_pWinPropertiesConfig->setGroup(szSection);
+ g_pWinPropertiesConfig->writeEntry("EntryTimestamp",(unsigned int)time(0));
+
+ // Allow max 80 window properties to be floating around
+ while(g_pWinPropertiesConfig->groupsCount() > 80)
+ {
+ // Kill the oldest group
+ KviConfigIterator it(*(g_pWinPropertiesConfig->dict()));
+ KviStr minKey;
+ unsigned int minVal = time(0);
+ while(it.current() && minVal)
+ {
+ QString * pVal = it.current()->find("EntryTimestamp");
+ if(pVal)
+ {
+ bool bOk;
+ unsigned int uVal = pVal->toUInt(&bOk);
+ if(bOk)
+ {
+ if(uVal < minVal)
+ {
+ minVal = uVal;
+ minKey = it.currentKey();
+ }
+ } else {
+ minVal = 0;
+ minKey = it.currentKey();
+ }
+ } else {
+ minVal = 0;
+ minKey = it.currentKey();
+ }
+ ++it;
+ }
+
+ if(minKey.hasData())g_pWinPropertiesConfig->clearGroup(minKey.ptr());
+ else debug("Oops...no minimum key found!");
+ }
+
+ // The following line should NOT be needed...but just to be sure...
+ g_pWinPropertiesConfig->setGroup(szSection);
+
+ g_pWinPropertiesConfig->writeEntry("IsDocked",wnd->mdiParent());
+
+// KviWindow * top = g_pActiveWindow;
+// if(!top)top = wnd;
+// g_pWinPropertiesConfig->writeEntry("IsMaximized",top->isMaximized());
+
+ g_pWinPropertiesConfig->writeEntry("WinRect",wnd->externalGeometry());
+
+ wnd->saveProperties(g_pWinPropertiesConfig);
+}
+
+void KviFrame::closeWindow(KviWindow *wnd)
+{
+ // notify the destruction
+ wnd->triggerDestructionEvents();
+
+ // save it's properties
+ if(KVI_OPTION_BOOL(KviOption_boolWindowsRememberProperties)) // && (wnd->type() == KVI_WINDOW_TYPE_CHANNEL))
+ {
+ QString group;
+ wnd->getConfigGroupName(group);
+ // not uses default settings : store it always
+ saveWindowProperties(wnd,group);
+ }
+
+ // forget it...
+ m_pWinList->removeRef(wnd);
+
+ // hide it
+ if(wnd->mdiParent())wnd->mdiParent()->hide();
+ else wnd->hide();
+
+ if(wnd == g_pActiveWindow)
+ {
+ // we need another active window before destroying it
+ KviMdiChild * pMdiChild = wnd->mdiParent();
+ if(pMdiChild)
+ {
+ pMdiChild = m_pMdi->highestChildExcluding(pMdiChild);
+ } else {
+ // the best candidate for the new active window
+ // is the top mdiManager's child
+ pMdiChild = m_pMdi->topChild();
+ }
+ KviWindow * pCandidate;
+ if(pMdiChild)
+ {
+ pCandidate = (KviWindow *)(pMdiChild->client());
+ } else {
+ pCandidate = m_pWinList->first();
+ if(pCandidate == wnd)pCandidate = 0;
+ }
+
+ if(pCandidate)
+ childWindowActivated(pCandidate);
+ // else { m_pActiveWindow = 0; m_pActiveContext = 0; };
+ }
+
+ if(wnd == g_pActiveWindow) // ops... :/ ... this happens only at shutdown
+ {
+ g_pActiveWindow = 0;
+ m_pActiveContext = 0;
+ }
+
+ // and shut it down...
+ // KviWindow will call childWindowDestroyed() here
+ if(wnd->mdiParent())m_pMdi->destroyChild(wnd->mdiParent(),true);
+ else delete wnd;
+}
+
+
+void KviFrame::addWindow(KviWindow *wnd,bool bShow)
+{
+ m_pWinList->append(wnd);
+ wnd->createTaskBarItem(); // create the window taskbar item AFTER it has been constructed
+
+ QString group;
+ wnd->getConfigGroupName(group);
+
+ bool bGroupSettings = false;
+
+ if(g_pWinPropertiesConfig->hasGroup(group))
+ {
+ g_pWinPropertiesConfig->setGroup(group);
+ } else {
+ bGroupSettings = true;
+ if(g_pWinPropertiesConfig->hasGroup(wnd->typeString()))
+ {
+ g_pWinPropertiesConfig->setGroup(wnd->typeString());
+ } else {
+ g_pWinPropertiesConfig->setGroup("no_settings_group");
+ wnd->loadProperties(g_pWinPropertiesConfig); // load it anyway (will set defaults if windows don't remember properties)
+ goto default_docking; // no settings stored
+ }
+ }
+
+ {
+ wnd->loadProperties(g_pWinPropertiesConfig); // load it anyway (will set defaults if windows don't remember properties)
+
+ if(KVI_OPTION_BOOL(KviOption_boolWindowsRememberProperties))
+ {
+ bool bDocked = g_pWinPropertiesConfig->readBoolEntry("IsDocked",true);
+ //bool bMaximized = g_pWinPropertiesConfig->readBoolEntry("IsMaximized",false);
+ bool bMaximized;
+
+ if(KVI_OPTION_BOOL(KviOption_boolMdiManagerInSdiMode))
+ {
+ bMaximized = true;
+ //KVI_OPTION_BOOL(KviOption_boolMdiManagerInSdiMode) = false;
+ } else bMaximized = false;
+
+ QRect rect = g_pWinPropertiesConfig->readRectEntry("WinRect",QRect(10,10,500,380));
+
+ if(bDocked)
+ {
+ // when group settings are used , we always cascade the windows
+ // this means that windows that have no specialized config group name
+ // are always cascaded : this is true for consoles , queries (and other windows) but not channels (and some other windows)
+ KviMdiChild * lpC = dockWindow(wnd,false,bGroupSettings,&rect);
+ lpC->setRestoredGeometry(rect);
+ wnd->triggerCreationEvents();
+ if(bShow)
+ {
+ m_pMdi->showAndActivate(lpC);
+ if(bMaximized)wnd->maximize();
+ // Handle the special case of this top level widget not being the active one.
+ // In this situation the child will not get the focusInEvent
+ // and thus will not call out childWindowActivated() method
+ if(!isActiveWindow())childWindowActivated(wnd);
+ }
+ } else {
+ wnd->setGeometry(rect);
+ wnd->triggerCreationEvents();
+ if(bShow)
+ {
+ wnd->show();
+ if(bMaximized)wnd->maximize();
+ }
+ wnd->youAreUndocked();
+ if(bShow)
+ {
+ wnd->raise();
+ wnd->setFocus();
+ }
+ }
+ goto docking_done;
+ }
+ }
+
+default_docking:
+ {
+ KviMdiChild * lpC = dockWindow(wnd,false); //cascade it
+ wnd->triggerCreationEvents();
+ if(bShow)
+ {
+ m_pMdi->showAndActivate(lpC);
+ if(KVI_OPTION_BOOL(KviOption_boolMdiManagerInSdiMode)) wnd->maximize();
+ // Handle the special case of this top level widget not being the active one.
+ // In this situation the child will not get the focusInEvent
+ // and thus will not call out childWindowActivated() method
+ if(!isActiveWindow())childWindowActivated(wnd);
+ }
+ }
+docking_done:
+ // we like to have an active window.. but don't trigger the events until it is really shown
+ if(!g_pActiveWindow)
+ {
+ g_pActiveWindow = wnd;
+ m_pActiveContext = wnd->context();
+ }
+}
+
+KviMdiChild * KviFrame::dockWindow(KviWindow *wnd,bool bShow,bool bCascade,QRect *setGeom)
+{
+ if(wnd->mdiParent())return wnd->mdiParent();
+ KviMdiChild * lpC = new KviMdiChild(m_pMdi,"");
+ lpC->setClient(wnd);
+ wnd->youAreDocked();
+ m_pMdi->manageChild(lpC,bCascade,setGeom);
+ if(bShow)m_pMdi->showAndActivate(lpC);
+ return lpC;
+}
+
+void KviFrame::undockWindow(KviWindow *wnd)
+{
+ if(!(wnd->mdiParent()))return;
+ KviMdiChild * lpC = wnd->mdiParent();
+ lpC->unsetClient();
+ m_pMdi->destroyChild(lpC,false);
+ wnd->youAreUndocked();
+ wnd->raise();
+ wnd->setFocus();
+}
+
+
+void KviFrame::newConsole()
+{
+ createNewConsole();
+}
+
+KviConsole * KviFrame::createNewConsole(bool bFirstInFrame)
+{
+ // the first console must be created BEFORE the toolbars visible
+ // at startup otherwise we cannot execute script code
+ // which is necessary for the actions that are going to be added
+ // to the toolbars
+ KviConsole * c = new KviConsole(this,bFirstInFrame ? KVI_CONSOLE_FLAG_FIRSTINFRAME : 0);
+ addWindow(c);
+
+ if(bFirstInFrame)
+ {
+ restoreModuleExtensionToolBars();
+ KviCustomToolBarManager::instance()->createToolBarsVisibleAtStartup();
+ KviActionManager::instance()->delayedRegisterAccelerators();
+ restoreToolBarPositions();
+ }
+
+ return c;
+}
+
+unsigned int KviFrame::consoleCount()
+{
+ unsigned int count = 0;
+ for(KviWindow * wnd = m_pWinList->first();wnd;wnd = m_pWinList->next())
+ {
+ if(wnd->type() == KVI_WINDOW_TYPE_CONSOLE)count++;
+ }
+ return count;
+}
+
+KviConsole * KviFrame::firstConsole()
+{
+ for(KviWindow * wnd = m_pWinList->first();wnd;wnd = m_pWinList->next())
+ {
+ if(wnd->type() == KVI_WINDOW_TYPE_CONSOLE)return (KviConsole *)wnd;
+ }
+ __range_valid(false);
+ return 0; //should newer be here!.. but sometimes we are ?
+}
+
+KviConsole * KviFrame::firstNotConnectedConsole()
+{
+ for(KviWindow * wnd = m_pWinList->first();wnd;wnd = m_pWinList->next())
+ {
+ if(wnd->type() == KVI_WINDOW_TYPE_CONSOLE)
+ {
+ if(!((KviConsole *)wnd)->connectionInProgress())
+ return (KviConsole *)wnd;
+ }
+ }
+ return 0;
+}
+
+void KviFrame::childWindowCloseRequest(KviWindow *wnd)
+{
+ closeWindow(wnd);
+}
+
+void KviFrame::unhighlightWindowsOfContext(KviIrcContext * c)
+{
+ for(KviWindow *w = m_pWinList->first();w;w = m_pWinList->next())
+ if(w->context() == c)w->unhighlight();
+}
+
+void KviFrame::setActiveWindow(KviWindow *wnd)
+{
+ // ASSERT(m_pWinList->findRef(wnd))
+ if(wnd->isMinimized())wnd->restore();
+ if(wnd->mdiParent())wnd->setFocus();
+ else wnd->delayedAutoRaise();
+}
+
+KviIrcConnection * KviFrame::activeConnection()
+{
+ return m_pActiveContext ? m_pActiveContext->connection() : 0;
+}
+
+void KviFrame::childWindowSelectionStateChange(KviWindow * pWnd,bool bGotSelectionNow)
+{
+ if(pWnd != g_pActiveWindow)return;
+ emit activeWindowSelectionStateChanged(bGotSelectionNow);
+
+}
+
+void KviFrame::childContextStateChange(KviIrcContext * c)
+{
+ if(c != m_pActiveContext)return;
+ emit activeContextStateChanged();
+}
+
+void KviFrame::childConnectionLagChange(KviIrcConnection * c)
+{
+ KviIrcContext * ctx = c->context();
+ if(ctx != m_pActiveContext)return;
+ emit activeConnectionLagChanged();
+}
+
+void KviFrame::childConnectionServerInfoChange(KviIrcConnection * c)
+{
+ KviIrcContext * ctx = c->context();
+ if(ctx != m_pActiveContext)return;
+ emit activeConnectionServerInfoChanged();
+}
+
+void KviFrame::childConnectionNickNameChange(KviIrcConnection * c)
+{
+ KviIrcContext * ctx = c->context();
+ if(ctx != m_pActiveContext)return;
+ emit activeConnectionNickNameChanged();
+}
+
+void KviFrame::childConnectionAwayStateChange(KviIrcConnection * c)
+{
+ KviIrcContext * ctx = c->context();
+ if(ctx != m_pActiveContext)return;
+ emit activeConnectionAwayStateChanged();
+}
+
+void KviFrame::childConnectionUserModeChange(KviIrcConnection * c)
+{
+ KviIrcContext * ctx = c->context();
+ if(ctx != m_pActiveContext)return;
+ emit activeConnectionUserModeChanged();
+}
+
+
+void KviFrame::childWindowActivated(KviWindow *wnd)
+{
+ // ASSERT(m_pWinList->findRef(wnd))
+ if(g_pActiveWindow == wnd)return;
+ if(g_pActiveWindow)g_pActiveWindow->lostUserFocus();
+ // YES: it's HERE!
+ g_pActiveWindow = wnd;
+
+ bool bActiveContextChanged = (m_pActiveContext != wnd->context());
+ m_pActiveContext = wnd->context();
+
+ if(wnd->isMaximized() && wnd->mdiParent())updateCaption();
+ m_pTaskBar->setActiveItem(wnd->taskBarItem());
+
+ //wnd->gainedActiveWindowStatus(); // <-- atm unused
+
+ if(g_pActiveWindow->view())
+ g_pActiveWindow->view()->clearUnreaded();
+
+ emit activeWindowChanged();
+ if(bActiveContextChanged)emit activeContextChanged();
+
+ KVS_TRIGGER_EVENT_0(KviEvent_OnWindowActivated,wnd);
+}
+
+void KviFrame::windowActivationChange(bool bOldActive)
+{
+ // if we have just been activated by the WM
+ // then update the active window task bar item
+ // It will then reset its highlight state
+ // and hopefully make the dock widget work correctly
+ // in this case.
+ // This will also trigger the OnWindowActivated event :)
+ if(isActiveWindow())
+ {
+ if(!bOldActive)
+ {
+ if(g_pActiveWindow)
+ {
+ KviWindow * pTmp = g_pActiveWindow;
+ g_pActiveWindow = 0; // really ugly hack!
+ childWindowActivated(pTmp);
+ }
+ }
+ } else {
+ if(g_pActiveWindow)g_pActiveWindow->lostUserFocus();
+ }
+}
+
+void KviFrame::enteredSdiMode()
+{
+ updateCaption();
+}
+
+void KviFrame::leftSdiMode()
+{
+ updateCaption();
+}
+
+#define KVI_DEFAULT_FRAME_CAPTION "KVIrc " KVI_VERSION " " KVI_RELEASE_NAME
+
+void KviFrame::updateCaption()
+{
+ if(g_pActiveWindow)
+ {
+ if(g_pActiveWindow->isMaximized() && g_pActiveWindow->mdiParent())
+ {
+ QString tmp = g_pActiveWindow->plainTextCaption();
+ tmp += QChar(' ');
+ tmp += KVI_DEFAULT_FRAME_CAPTION;
+ setCaption(tmp);
+ return;
+ }
+ }
+ setCaption(KVI_DEFAULT_FRAME_CAPTION);
+}
+
+
+void KviFrame::closeEvent(QCloseEvent *e)
+{
+
+ if(KVI_OPTION_BOOL(KviOption_boolCloseInTray))
+ {
+ e->ignore();
+
+ if(!dockExtension())
+ {
+ executeInternalCommand(KVI_INTERNALCOMMAND_DOCKWIDGET_SHOW);
+ }
+ if(dockExtension())
+ {
+
+ dockExtension()->setPrevWindowState(windowState());
+ QTimer::singleShot( 0, this, SLOT(hide()) );
+ }
+ return;
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolConfirmCloseWhenThereAreConnections))
+ {
+ // check for running connections
+
+ bool bGotRunningConnection = false;
+ for(KviWindow * w = m_pWinList->first();w;w = m_pWinList->next())
+ {
+ if(w->type() == KVI_WINDOW_TYPE_CONSOLE)
+ {
+ if(((KviConsole *)w)->connectionInProgress())
+ {
+ bGotRunningConnection = true;
+ break;
+ }
+ }
+ }
+
+ if(bGotRunningConnection)
+ {
+ QString txt = "<p>";
+ txt += __tr2qs("There are active connections, are you sure you wish to ");
+ txt += __tr2qs("quit KVIrc?");
+ txt += "</p>";
+
+ switch(QMessageBox::warning(this,__tr2qs("Confirmation - KVIrc"),txt,__tr2qs("&Yes"),__tr2qs("&Always"),__tr2qs("&No"),2,2))
+ {
+ case 0:
+ // ok to close
+ break;
+ case 1:
+ // ok to close but don't ask again
+ KVI_OPTION_BOOL(KviOption_boolConfirmCloseWhenThereAreConnections) = false;
+ break;
+ case 2:
+ e->ignore();
+ return;
+ break;
+ }
+ }
+ }
+
+ e->accept();
+
+ if(g_pApp)
+ g_pApp->destroyFrame();
+}
+
+void KviFrame::resizeEvent(QResizeEvent *e)
+{
+ KVI_OPTION_RECT(KviOption_rectFrameGeometry) = QRect(pos().x(),pos().y(),
+ size().width(),size().height());
+ KviTalMainWindow::resizeEvent(e);
+}
+
+void KviFrame::updatePseudoTransparency()
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedParentGlobalDesktopBackground)m_pMdi->viewport()->update();
+
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ for(KviWindow * wnd = m_pWinList->first();wnd;wnd = m_pWinList->next())wnd->updateBackgrounds();
+ m_pTaskBar->updatePseudoTransparency();
+ }
+#endif
+}
+
+void KviFrame::moveEvent(QMoveEvent *e)
+{
+ KVI_OPTION_RECT(KviOption_rectFrameGeometry) = QRect(pos().x(),pos().y(),
+ size().width(),size().height());
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ updatePseudoTransparency();
+#endif
+ KviTalMainWindow::moveEvent(e);
+}
+
+void KviFrame::applyOptions()
+{
+ m_pMdi->update();
+ for(KviWindow * wnd = m_pWinList->first();wnd;wnd = m_pWinList->next())wnd->applyOptions();
+ updateCaption();
+
+ m_pTaskBar->applyOptions();
+}
+
+void KviFrame::toggleStatusBar()
+{
+ if(m_pStatusBar)
+ {
+ delete m_pStatusBar;
+ m_pStatusBar = 0;
+ } else {
+ //if(statusBar())delete statusBar(); // kill any existing status bar (QT BUG)
+
+ m_pStatusBar = new KviStatusBar(this);
+ m_pStatusBar->load();
+#ifdef COMPILE_USE_QT4
+ setStatusBar(m_pStatusBar);
+#endif
+ m_pStatusBar->show();
+#ifndef COMPILE_USE_QT4
+ setUpLayout();
+#endif //!COMPILE_USE_QT4
+ }
+}
+
+void KviFrame::fillToolBarsPopup(KviTalPopupMenu * p)
+{
+ p->clear();
+
+ disconnect(p,SIGNAL(activated(int)),this,SLOT(toolbarsPopupSelected(int))); // just to be sure
+ connect(p,SIGNAL(activated(int)),this,SLOT(toolbarsPopupSelected(int)));
+
+ int id;
+ int cnt = 0;
+
+ KviModuleExtensionDescriptorList * l = g_pModuleExtensionManager->getExtensionList("toolbar");
+ if(l)
+ {
+ for(KviModuleExtensionDescriptor * d = l->first();d;d = l->next())
+ {
+ QString label = __tr2qs("Show %1").arg(d->visibleName());
+ if(d->icon())id = p->insertItem(*(d->icon()),label);
+ else id = p->insertItem(label);
+ p->setItemChecked(id,moduleExtensionToolBar(d->id()));
+ p->setItemParameter(id,d->id());
+ cnt++;
+ }
+ }
+
+ // FIXME: Should this display "Hide %1" when the toolbar is already visible ?
+ KviPointerHashTableIterator<QString,KviCustomToolBarDescriptor> it2(*(KviCustomToolBarManager::instance()->descriptors()));
+ if(it2.current())
+ {
+ if(cnt > 0)p->insertSeparator();
+ while(KviCustomToolBarDescriptor * d = it2.current())
+ {
+ QString label = __tr2qs("Show %1").arg(d->label());
+ QString ico = d->iconId();
+ // use the icon only if there is no check
+ if(d->toolBar())
+ {
+ id = p->insertItem(label);
+ p->setItemChecked(id,true);
+ } else {
+ if(!ico.isEmpty())
+ {
+ QPixmap * pix = g_pIconManager->getImage(d->iconId());
+ if(pix)
+ {
+ id = p->insertItem(*pix,label);
+ } else {
+ id = p->insertItem(label);
+ }
+ } else {
+ id = p->insertItem(label);
+ }
+ }
+ p->setItemParameter(id,d->internalId());
+ ++it2;
+ cnt++;
+ }
+ }
+
+ if(cnt > 0)p->insertSeparator();
+ p->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TOOLBAR)),__tr2qs("Customize..."),this,SLOT(customizeToolBars()));
+}
+
+void KviFrame::customizeToolBars()
+{
+ KviKvsScript::run("toolbareditor.open",g_pActiveWindow);
+}
+
+void KviFrame::toolbarsPopupSelected(int id)
+{
+ const QObject * o = sender();
+ if(!o)return;
+ if(!o->inherits("KviTalPopupMenu"))return;
+ const KviTalPopupMenu * p = (const KviTalPopupMenu *)o;
+ int idext = p->itemParameter(id);
+
+ KviCustomToolBarDescriptor * dd = KviCustomToolBarManager::instance()->findDescriptorByInternalId(idext);
+ if(dd)
+ {
+ if(dd->toolBar())delete dd->toolBar();
+ else dd->createToolBar();
+ }
+
+ if(KviMexToolBar * t = moduleExtensionToolBar(idext))
+ {
+ t->die();
+ } else {
+ g_pModuleExtensionManager->allocateExtension("toolbar",idext,firstConsole());
+ }
+}
+
+
+
+bool KviFrame::focusNextPrevChild(bool next)
+{
+ //debug("FOCUS NEXT PREV CHILD");
+ QWidget * w = focusWidget();
+ if(w)
+ {
+#ifdef COMPILE_USE_QT4
+ if(w->focusPolicy() == Qt::StrongFocus)return false;
+#else
+ if(w->focusPolicy() == QWidget::StrongFocus)return false;
+#endif
+ //QVariant v = w->property("KviProperty_FocusOwner");
+ //if(v.isValid())return false; // Do NOT change the focus widget!
+
+ if(w->parent())
+ {
+ QVariant v = w->parent()->property("KviProperty_ChildFocusOwner");
+ if(v.isValid())return false; // Do NOT change the focus widget!
+ }
+ }
+ // try to focus the widget on top of the Mdi
+ if(m_pMdi->topChild())
+ {
+ m_pMdi->focusTopChild();
+ return false;
+ }
+ return KviTalMainWindow::focusNextPrevChild(next);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Toolbar positioning stuff
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void KviFrame::saveToolBarPositions()
+{
+ QString szTemp;
+ g_pApp->getLocalKvircDirectory(szTemp,KviApp::Config,KVI_CONFIGFILE_TOOLBARS);
+
+ QFile f(szTemp);
+ if(f.open(IO_WriteOnly | IO_Truncate))
+ {
+#ifdef COMPILE_USE_QT4
+ f.write(saveState(1));
+#else //!COMPILE_USE_QT4
+ QTextStream ts(&f);
+ ts << *this;
+ f.close();
+#endif //!COMPILE_USE_QT4
+ }
+}
+
+void KviFrame::restoreToolBarPositions()
+{
+ QString szTemp;
+ g_pApp->getLocalKvircDirectory(szTemp,KviApp::Config,KVI_CONFIGFILE_TOOLBARS);
+
+ QFile f(szTemp);
+
+ bool bNeedDefaults = false;
+
+ if(f.open(IO_ReadOnly))
+ {
+#ifdef COMPILE_USE_QT4
+ if(!restoreState(f.readAll(),1))
+ debug("Error while restoring toolbars position");
+#else //!COMPILE_USE_QT4
+ QTextStream ts(&f);
+ ts >> *this;
+ f.close();
+#endif //!COMPILE_USE_QT4
+ } else {
+ bNeedDefaults = true;
+ }
+
+ if(m_pTaskBar->inherits("KviTreeTaskBar"))
+ {
+#ifdef COMPILE_USE_QT4
+ // ensure that it is not too wide
+ m_pTaskBar->setMaximumWidth(600);
+ if(m_pTaskBar->width() > 600)
+ m_pTaskBar->setFixedWidth(250);
+#else //!COMPILE_USE_QT4
+ QDockArea * a = m_pTaskBar->area();
+ if((a == topDock()) || (a == bottomDock()))
+ {
+ // nope.... need to move it
+ a->removeDockWindow(m_pTaskBar,true,false);
+
+ //int iMaxWidth = m_pTaskBar->maximumWidth();
+ leftDock()->moveDockWindow(m_pTaskBar);
+ //m_pTaskBar->setMaximumWidth(iMaxWidth);
+ //m_pTaskBar->setOrientation(Vertical);
+ }
+ // ensure that it is not too wide
+ if(m_pTaskBar->width() > 600)
+ m_pTaskBar->setFixedExtentWidth(250);
+#endif //!COMPILE_USE_QT4
+ } /*else if(m_pTaskBar->inherits("KviClassicTaskBar"))
+ {
+ QDockArea * a = m_pTaskBar->area();
+ if((a == leftDock()) || (a == rightDock()))
+ {
+ // nope.... need to move it
+ a->removeDockWindow(m_pTaskBar,true,false);
+ bottomDock()->moveDockWindow(m_pTaskBar);
+ bottomDock()->lineUp(true);
+ }
+ }*/
+
+#ifndef COMPILE_USE_QT4
+ if(bNeedDefaults)
+ lineUpDockWindows(false);
+#endif //!COMPILE_USE_QT4
+}
+
+
+void KviFrame::createTaskBar()
+{
+ if(KVI_OPTION_BOOL(KviOption_boolUseTreeWindowListTaskBar))
+ {
+ m_pTaskBar = new KviTreeTaskBar();
+#ifdef COMPILE_USE_QT4
+ m_pTaskBar->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+ addDockWidget(Qt::LeftDockWidgetArea,m_pTaskBar);
+#else //!COMPILE_USE_QT4
+ setDockEnabled(m_pTaskBar,Qt::DockTop,false);
+ setDockEnabled(m_pTaskBar,Qt::DockBottom,false);
+#endif //!COMPILE_USE_QT4
+ } else {
+ m_pTaskBar = new KviClassicTaskBar();
+#ifdef COMPILE_USE_QT4
+ m_pTaskBar->setAllowedAreas(Qt::AllDockWidgetAreas);
+ addDockWidget(Qt::BottomDockWidgetArea,m_pTaskBar);
+#else //!COMPILE_USE_QT4
+ setDockEnabled(m_pTaskBar,Qt::DockTop,true);
+ setDockEnabled(m_pTaskBar,Qt::DockBottom,true);
+#endif //!COMPILE_USE_QT4
+ }
+#ifndef COMPILE_USE_QT4
+ setDockEnabled(m_pTaskBar,Qt::DockLeft,true);
+ setDockEnabled(m_pTaskBar,Qt::DockRight,true);
+#endif //!COMPILE_USE_QT4
+}
+
+void KviFrame::recreateTaskBar()
+{
+ QString szOldClass = m_pTaskBar->className();
+
+ saveToolBarPositions();
+ KviWindow * w;
+ for(w = m_pWinList->first();w;w = m_pWinList->next())
+ {
+ w->destroyTaskBarItem();
+ }
+#ifndef COMPILE_USE_QT4
+ removeDockWindow(m_pTaskBar);
+#endif //!COMPILE_USE_QT4
+ delete m_pTaskBar;
+ createTaskBar();
+ for(w = m_pWinList->first();w;w = m_pWinList->next())
+ {
+ w->createTaskBarItem();
+ }
+ restoreToolBarPositions();
+
+
+ /*
+ QString szNewClass = m_pTaskBar->className();
+ if(szOldClass != szNewClass)
+ {
+ // the class changed...
+ // make sure that the tree task bar is in the left or right dock
+ // and the classic one is in the top or bottom on
+
+ Qt::Dock dock;
+ int index;
+ bool nl;
+ int eo;
+ getLocation(m_pTaskBar,dock,index,nl,eo);
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseTreeWindowListTaskBar))
+ {
+ if((dock == Qt::Bottom) || (dock == Qt::Top))
+ moveDockWindow(m_pTaskBar,Qt::Left);
+ } else {
+ if((dock == Qt::Left) || (dock == Qt::Right))
+ moveDockWindow(m_pTaskBar,Qt::Bottom);
+ }
+ }
+ */
+
+ if(g_pActiveWindow)m_pTaskBar->setActiveItem(g_pActiveWindow->taskBarItem());
+}
+
+
+#if QT_VERSION == 0x030201
+unsigned int KviFrame::windowState()
+{
+ /* enum GNWindowState { WindowNoState = 0x00000000, WindowMinimized = 0x00000001,
+ WindowMaximized = 0x00000002, WindowFullScreen = 0x00000004, WindowActive = 0x00000008 };
+ GNWindowState GNWState;
+ if(isMinimized()) GNWState=WindowMinimized;
+ else if(isMaximized()) GNWState=WindowMaximized;
+ else if(isActiveWindow()) GNWState=WindowActive;
+ else if(isFullScreen()) GNWState=WindowFullScreen;
+ else GNWState=WindowNoState; */
+
+/* WindowNoState = 0x00000000 WindowMinimized = 0x00000001
+ WindowMaximized = 0x00000002 WindowFullScreen = 0x00000004 WindowActive = 0x00000008*/
+ if(isMinimized()) return 0x00000001;
+ else if(isMaximized()) return 0x00000002;
+ else if(isActiveWindow()) return 0x00000008;
+ else if(isFullScreen()) return 0x00000004;
+ else return 0x00000000;
+}
+void KviFrame::setWindowState(unsigned int GNWState)
+{
+ switch(GNWState)
+ {
+ case 0x00000001:
+ showMinimized();
+ break;
+ case 0x00000002:
+ showMaximized();
+ break;
+ } // switch
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Some accelerators
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void KviFrame::maximizeWindow(void)
+{
+ if(!g_pActiveWindow)return;
+ if(g_pActiveWindow->isMaximized())g_pActiveWindow->restore();
+ else g_pActiveWindow->maximize();
+}
+
+void KviFrame::minimizeWindow(void)
+{
+ if(g_pActiveWindow)g_pActiveWindow->minimize();
+}
+
+void KviFrame::switchToPrevWindow(void)
+{
+ m_pTaskBar->switchWindow(false,false);
+}
+
+void KviFrame::switchToNextWindow(void)
+{
+ m_pTaskBar->switchWindow(true,false);
+}
+
+void KviFrame::switchToPrevWindowInContext(void)
+{
+ m_pTaskBar->switchWindow(false,true);
+}
+
+void KviFrame::switchToNextWindowInContext(void)
+{
+ m_pTaskBar->switchWindow(true,true);
+}
+
+void KviFrame::hideEvent ( QHideEvent * e)
+{
+ if(KVI_OPTION_BOOL(KviOption_boolMinimizeInTray))
+ {
+ if(e->spontaneous())
+ {
+
+ if(!dockExtension())
+ {
+ executeInternalCommand(KVI_INTERNALCOMMAND_DOCKWIDGET_SHOW);
+ }
+ QTimer::singleShot( 0, this, SLOT(hide()) );
+ }
+
+ }
+}
+
+#include "kvi_frame.moc"
diff --git a/src/kvirc/ui/kvi_frame.h b/src/kvirc/ui/kvi_frame.h
new file mode 100644
index 0000000..d735a7c
--- /dev/null
+++ b/src/kvirc/ui/kvi_frame.h
@@ -0,0 +1,259 @@
+#ifndef _KVI_FRAME_H_
+#define _KVI_FRAME_H_
+//=============================================================================
+//
+// File : kvi_frame.h
+// Creation date : Sun Jun 18 2000 17:59:02 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+//=============================================================================
+//
+// KviFrame:
+// The main window for the KVIrc application
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+#include "kvi_tal_mainwindow.h"
+#include "kvi_qstring.h"
+#include "kvi_pointerlist.h"
+
+class KviMenuBar;
+class KviMdiManager;
+class KviMdiChild;
+class KviWindow;
+class KviConsole;
+class KviTaskBarBase;
+class QSplitter;
+class KviConfig;
+class KviMexToolBar;
+class KviIrcContext;
+class KviIrcConnection;
+class KviStatusBar;
+class KviTalPopupMenu;
+
+#include "kvi_accel.h" // we need this :/
+
+#ifdef COMPILE_ON_WINDOWS
+ // MSCV has problems with KviPointerList<KviWindow> otherwise
+ #include "kvi_window.h"
+#endif
+
+// base class for the dock extension applets..
+// this should be probably moved out of here
+class KVIRC_API KviDockExtension
+{
+protected:
+ unsigned int m_uStoredWindowState;
+public:
+ KviDockExtension() : m_uStoredWindowState(0){};
+ virtual ~KviDockExtension(){};
+public:
+ void setPrevWindowState(unsigned int state) { m_uStoredWindowState = state; };
+ unsigned int getPrevWindowState() { return m_uStoredWindowState; };
+
+ virtual void refresh(){};
+ virtual void die(){ delete this; };
+};
+
+
+
+class KVIRC_API KviFrame : public KviTalMainWindow // , public KviIrcContextManager
+{
+ friend class KviWindow;
+ friend class KviConsole;
+ friend class KviApp;
+ friend class KviServerParser;
+ friend class KviMexToolBar;
+ friend class KviMdiManager;
+ friend class KviIrcContext;
+ friend class KviIrcConnection;
+ friend class KviLagMeter;
+ friend class KviUserListView;
+ friend class KviUserListViewArea;
+ Q_OBJECT
+public:
+ KviFrame();
+ ~KviFrame();
+protected:
+ // subwindows
+ QSplitter * m_pSplitter; // the frame is splitted vertically and thus can host widgets
+ KviMenuBar * m_pMenuBar; // the main menu bar
+ KviMdiManager * m_pMdi; // the mdi manager widget (child of the splitter)
+ KviPointerList<KviMexToolBar> * m_pModuleExtensionToolBarList; // the module extension toolbars
+ KviTaskBarBase * m_pTaskBar; // the taskbar
+ KviStatusBar * m_pStatusBar;
+ // the mdi workspace child windows
+ KviPointerList<KviWindow> * m_pWinList; // the main list of windows
+ KviIrcContext * m_pActiveContext; // the context of the m_pActiveWindow
+ // other
+ KviDockExtension * m_pDockExtension; // the frame's dock extension: this should be prolly moved ?
+ KviAccel * m_pAccel; // the global accelelrator
+public:
+ // the mdi manager: handles mdi children
+ KviMdiManager * mdiManager(){ return m_pMdi; };
+ // the splitter is the central widget for this frame
+ QSplitter * splitter(){ return m_pSplitter; };
+ // KviTaskBarBase is the base class for KviTreeTaskBar and the KviClassicTaskBar
+ KviTaskBarBase * taskBar(){ return m_pTaskBar; };
+ // well.. the menu bar :D
+ KviMenuBar * mainMenuBar(){ return m_pMenuBar; };
+ KviStatusBar * mainStatusBar(){ return m_pStatusBar; };
+ // this function may return 0 if the active window has no irc context
+ KviIrcContext * activeContext(){ return m_pActiveContext; };
+ // shortcut to a = activeContext(); return a ? a->connection() : 0
+ KviIrcConnection * activeConnection();
+ // The list of the windows belonging to this frame
+ // Note that the windows may be also undocked, but they are still owned by the frame
+ KviPointerList<KviWindow> * windowList() { return m_pWinList; };
+ // Sets the specified window to be the active one
+ // Raises it and focuses it
+ void setActiveWindow(KviWindow *wnd);
+ // Adds a new KviWindow to this frame
+ // This should be done just after the KviWindow constructor has returned
+ // If bShow is false then the window is not explicitly shown
+ // otherwise it is set as active window.
+ void addWindow(KviWindow *wnd,bool bShow = true); // public for modules
+ // Checks if a specified window is still existing in this frame child
+ // window list. This is useful for asynchronous functions
+ // that keep a window pointer and need to ensure that it is still
+ // valid after an uncontrolled delay. (Think of a /timer implementation)
+ bool windowExists(KviWindow * wnd){ return (m_pWinList->findRef(wnd) != -1); };
+ // The number of consoles in this frame
+ unsigned int consoleCount();
+ // Creates a new console window. DON'T use the KviConsole constructor directly.
+ // (The script creation events are triggered from here)
+ KviConsole * createNewConsole(bool bFirstInFrame = false);
+ // Returns the first available console.
+ // There is almost always an available console.
+ // Exceptions are the startup and the shutdown (see activeWindow())
+ KviConsole * firstConsole();
+ // Returns the first console that has no connection in progress
+ // This function CAN return 0 if all the consoles are connected
+ KviConsole * firstNotConnectedConsole();
+ // this is explicitly dedicated to the DockExtension applets
+ void setDockExtension(KviDockExtension * e){ m_pDockExtension = e; };
+ // returns the dockExtension applet. Useful for calling refresh() when
+ // some particular event happens
+ KviDockExtension * dockExtension(){ return m_pDockExtension; };
+ // Updates the main window caption.
+ // Should be called when the active window changes
+ // and the active irc context changes state
+ void updateCaption();
+ // helper for saving the window properties
+ void saveWindowProperties(KviWindow * wnd,const char * szSection);
+ // finds the module extension toolbar with the specified identifier
+ // see kvi_moduleextension.h and kvi_mextoolbar.h
+ KviMexToolBar * moduleExtensionToolBar(int extensionId);
+ // Helper to fill the toolbars popup
+ // it is used by KviToolBar and KviMenuBar
+ void fillToolBarsPopup(KviTalPopupMenu * p);
+ int registerAccelerator(const QString &szKeySequence,QObject * recv,const char * slot);
+ void unregisterAccelerator(int id);
+
+#if QT_VERSION == 0x030201
+
+ unsigned int windowState();
+ void setWindowState(unsigned int GNWState);
+
+#endif
+
+public slots:
+ void newConsole();
+ void executeInternalCommand(int index);
+ void toggleStatusBar();
+ void customizeToolBars();
+protected:
+ void restoreModuleExtensionToolBars();
+ void saveModuleExtensionToolBars();
+ void registerModuleExtensionToolBar(KviMexToolBar * t);
+ void unregisterModuleExtensionToolBar(KviMexToolBar * t);
+
+ void unhighlightWindowsOfContext(KviIrcContext * c);
+
+ void createTaskBar();
+ void recreateTaskBar();
+
+ KviMdiChild * dockWindow(KviWindow *wnd,bool bShow = true,bool bCascade = true,QRect * setGeom = 0);
+ void undockWindow(KviWindow *wnd);
+
+ void closeWindow(KviWindow *wnd);
+
+ // called by KviWindow
+ void childWindowCloseRequest(KviWindow *wnd);
+ void childWindowActivated(KviWindow *wnd);
+
+ void childContextStateChange(KviIrcContext * c);
+ void childConnectionNickNameChange(KviIrcConnection * c);
+ void childConnectionAwayStateChange(KviIrcConnection * c);
+ void childConnectionUserModeChange(KviIrcConnection * c);
+ void childConnectionLagChange(KviIrcConnection * c);
+ void childConnectionServerInfoChange(KviIrcConnection * c);
+ void childWindowSelectionStateChange(KviWindow * pWnd,bool bGotSelectionNow);
+
+ virtual void closeEvent(QCloseEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void moveEvent(QMoveEvent *e);
+ virtual bool focusNextPrevChild(bool next);
+ virtual void windowActivationChange(bool bOldActive);
+
+ void updatePseudoTransparency();
+
+ KviAccel * installAccelerators(QWidget * wnd);
+
+ virtual void hideEvent ( QHideEvent * e);
+protected slots:
+ void switchToNextWindow();
+ void switchToPrevWindow();
+ void switchToNextWindowInContext();
+ void switchToPrevWindowInContext();
+
+ void maximizeWindow();
+ void minimizeWindow();
+
+ void accelActivated(int id);
+ void enteredSdiMode();
+ void leftSdiMode();
+ void toolbarsPopupSelected(int id);
+
+signals:
+ void activeWindowChanged(); // almost never 0.. but may be
+ void activeContextChanged(); // may be 0!
+ void activeContextStateChanged(); // emitted only when the active context is non 0 and it changes state
+ void activeConnectionNickNameChanged();
+ void activeConnectionUserModeChanged();
+ void activeConnectionAwayStateChanged();
+ void activeConnectionServerInfoChanged();
+ void activeConnectionLagChanged();
+ void activeWindowSelectionStateChanged(bool bGotSelectionNow);
+protected:
+ void applyOptions();
+private:
+ void saveToolBarPositions();
+ void restoreToolBarPositions();
+};
+
+#ifndef _KVI_FRAME_CPP_
+ extern KVIRC_API KviFrame * g_pFrame;
+#endif
+
+#endif //_KVI_FRAME_H_
diff --git a/src/kvirc/ui/kvi_historywin.cpp b/src/kvirc/ui/kvi_historywin.cpp
new file mode 100644
index 0000000..ba9ca31
--- /dev/null
+++ b/src/kvirc/ui/kvi_historywin.cpp
@@ -0,0 +1,255 @@
+#ifndef _KVI_HISTORYWIN_CPP_
+#define _KVI_HISTORYWIN_CPP_
+//
+// File : kvi_historywin.cpp
+// Creation date : Mon Aug 19 01:34:48 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+
+#define __KVIRC__
+
+#include "kvi_historywin.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_input.h"
+#include "kvi_mirccntrl.h"
+
+#include <qnamespace.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qevent.h>
+#endif
+
+#include <ctype.h>
+
+extern KviInputHistory * g_pInputHistory;
+
+KviHistoryWindow::KviHistoryWindow()
+#ifdef COMPILE_USE_QT4
+: KviTalListBox(0,Qt::Popup)
+#else
+: KviTalListBox(0,Qt::WType_Popup)
+#endif
+{
+ m_pOwner = 0;
+#ifdef COMPILE_USE_QT4
+ setHScrollBarMode(Q3ScrollView::AlwaysOff);
+#else
+ setHScrollBarMode(QScrollView::AlwaysOff);
+#endif
+ connect(this,SIGNAL(selected(const QString &)),this,SLOT(itemSelected(const QString &)));
+
+ m_iTimerId = -1;
+}
+
+KviHistoryWindow::~KviHistoryWindow()
+{
+ if(m_iTimerId != -1)
+ {
+ killTimer(m_iTimerId);
+ m_iTimerId = -1;
+ }
+}
+
+void KviHistoryWindow::fill()
+{
+ clear();
+ for(QString * s = g_pInputHistory->list()->last();s;s = g_pInputHistory->list()->prev())
+ {
+ insertItem(*s);
+ }
+ if(count() > 0)setCurrentItem(count() - 1);
+}
+
+void KviHistoryWindow::popup(KviInput *owner)
+{
+ if(m_pOwner)disconnect(m_pOwner,SIGNAL(destroyed()),this,SLOT(ownerDead()));
+ m_pOwner = owner;
+ connect(m_pOwner,SIGNAL(destroyed()),this,SLOT(ownerDead()));
+ fill();
+ show();
+}
+
+void KviHistoryWindow::mousePressEvent(QMouseEvent *e)
+{
+ if(e->pos().x() < 0)goto hideme;
+ if(e->pos().x() > width())goto hideme;
+ if(e->pos().y() < 0)goto hideme;
+ if(e->pos().y() > height())goto hideme;
+
+ KviTalListBox::mousePressEvent(e);
+ e->accept();
+ return;
+
+hideme:
+ doHide();
+}
+
+/*
+bool KviHistoryWindow::findTypedSeq()
+{
+ int cnt = count();
+ int max = 0;
+ int mit = -1;
+ bool bFullMax = false;
+ for(int i=0;i<cnt;i++)
+ {
+ KviStr szIt = text(i);
+ int j;
+ for(j=0;j<szIt.len();j++)
+ {
+ if(tolower(*(szIt.ptr() + j)) != tolower(*(m_szTypedSeq.ptr() + j)))break;
+ }
+ if(j < max)
+ {
+ goto got_mit;
+ } else {
+ if(j >= max)
+ {
+ bFullMax = (j == szIt.len());
+ max = j;
+ mit = i;
+ }
+ }
+ }
+got_mit:
+ setCurrentItem(mit);
+ m_szCurFullSeq = text(mit);
+ return bFullMax;
+}
+*/
+
+void KviHistoryWindow::keyPressEvent(QKeyEvent *e)
+{
+ switch(e->key())
+ {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Return:
+ KviTalListBox::keyPressEvent(e);
+ return;
+ break;
+ case Qt::Key_Escape:
+ doHide();
+ return;
+ break;
+/*
+ case Qt::Key_Backspace:
+ if(m_szTypedSeq.hasData())
+ {
+ m_szTypedSeq.cutRight(1);
+ findTypedSeq();
+ } else {
+ doHide();
+ if(m_pOwner)g_pApp->sendEvent(m_pOwner,e);
+ }
+ return;
+ break;
+*/
+/*
+ case Qt::Key_Space:
+ doHide();
+ if(findTypedSeq())
+ {
+ KviStr szItem = m_szTypedSeq;
+ szItem.append(' ');
+ if(m_pOwner)m_pOwner->insertText(szItem);
+ } else {
+ if(m_pOwner)g_pApp->sendEvent(m_pOwner,e);
+ }
+ return;
+ break;
+*/
+/*
+ case Qt::Key_Tab:
+ doHide();
+ findTypedSeq();
+ KviStr szItem = m_szCurFullSeq;
+ szItem.append(KVI_TEXT_ICON);
+ if(m_pOwner)m_pOwner->insertText(szItem);
+ return;
+ break;
+*/
+ }
+/*
+ int as = e->ascii();
+ if((as >= 'a' && as <= 'z') || (as >= 'A' && as <= 'Z') || (as >= '0' && as <= '9')
+ || (as == '?') || (as == '$') || (as == '.') || (as == ',') || (as == '!') || (as =='&'))
+ {
+ m_szTypedSeq.append((char)as);
+ findTypedSeq();
+ } else {
+*/
+ if(m_pOwner)g_pApp->sendEvent(m_pOwner,e);
+/*
+ }
+*/
+}
+
+void KviHistoryWindow::ownerDead()
+{
+ m_pOwner = 0;
+ doHide();
+}
+
+void KviHistoryWindow::show()
+{
+ m_iTimerId = startTimer(100000); //100 sec ...seems enough
+ QWidget::show();
+}
+
+void KviHistoryWindow::timerEvent(QTimerEvent *)
+{
+ m_pOwner = 0; // do not setFocus() to the owner after the timeout
+ doHide();
+}
+
+void KviHistoryWindow::doHide()
+{
+ if(m_iTimerId != -1)
+ {
+ killTimer(m_iTimerId);
+ m_iTimerId = -1;
+ }
+ hide();
+ if(m_pOwner)
+ m_pOwner->setFocus();
+}
+
+void KviHistoryWindow::itemSelected(const QString &str)
+{
+ doHide();
+ if(m_pOwner)m_pOwner->setText(str);
+}
+
+
+void KviHistoryWindow::hideEvent(QHideEvent *)
+{
+ if(m_iTimerId != -1)
+ {
+ killTimer(m_iTimerId);
+ m_iTimerId = -1;
+ }
+}
+
+#include "kvi_historywin.moc"
+#endif //_KVI_HISTORYWIN_CPP_
diff --git a/src/kvirc/ui/kvi_historywin.h b/src/kvirc/ui/kvi_historywin.h
new file mode 100644
index 0000000..9a17eec
--- /dev/null
+++ b/src/kvirc/ui/kvi_historywin.h
@@ -0,0 +1,61 @@
+#ifndef _KVI_HISTORYWIN_H_
+#define _KVI_HISTORYWIN_H_
+//
+// File : kvi_historywin.h
+// Creation date : Mon Aug 19 01:34:46 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+
+#include "kvi_settings.h"
+#include "kvi_string.h"
+
+#include "kvi_tal_listbox.h"
+
+class KviInput;
+
+#define KVI_HISTORY_WIN_HEIGHT 130
+
+class KVIRC_API KviHistoryWindow : public KviTalListBox
+{
+ Q_OBJECT
+public:
+ KviHistoryWindow();
+ ~KviHistoryWindow();
+private:
+ KviInput * m_pOwner;
+ int m_iTimerId;
+public:
+ void popup(KviInput *owner);
+// KviInput * owner(){ return m_pOwner; };
+ void doHide();
+private:
+ virtual void show();
+// bool findTypedSeq(); // returns true if it is a complete word
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void timerEvent(QTimerEvent *);
+ virtual void hideEvent ( QHideEvent * );
+ void fill();
+public slots:
+ void ownerDead();
+ void itemSelected(const QString &str);
+};
+
+#endif //_KVI_HISTORYWIN_H_
diff --git a/src/kvirc/ui/kvi_htmldialog.cpp b/src/kvirc/ui/kvi_htmldialog.cpp
new file mode 100644
index 0000000..6a8b437
--- /dev/null
+++ b/src/kvirc/ui/kvi_htmldialog.cpp
@@ -0,0 +1,155 @@
+//=============================================================================
+//
+// File : kvi_htmldialog.cpp
+// Created on Wed 03 Jan 2007 03:36:36 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2007 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+#define __KVIRC__
+
+#include "kvi_htmldialog.h"
+#include "kvi_locale.h"
+#include "kvi_tal_textedit.h"
+
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qtextbrowser.h>
+
+KviHtmlDialog::KviHtmlDialog(QWidget * pParent,KviHtmlDialogData * pData)
+: QDialog(pParent)
+{
+ m_pData = pData;
+
+ if(pData->szCaption.isEmpty())
+ setCaption("KVIrc");
+ else
+ setCaption(pData->szCaption);
+
+ if(!pData->pixIcon.isNull())
+ setIcon(pData->pixIcon);
+
+ QGridLayout * g = new QGridLayout(this,4,3,7,7);
+
+ QLabel * l;
+ QTextBrowser * te;
+ QPushButton * pb;
+
+ int iUp = 0;
+ int iDown = 2;
+
+ if(!pData->szUpperLabelText.isEmpty())
+ {
+ l = new QLabel(this);
+ l->setText(pData->szUpperLabelText);
+ g->addMultiCellWidget(l,0,0,0,2);
+ iUp = 1;
+ }
+
+ if(!pData->szLowerLabelText.isEmpty())
+ {
+ l = new QLabel(this);
+ l->setText(pData->szLowerLabelText);
+ g->addMultiCellWidget(l,2,2,0,2);
+ iDown = 1;
+ }
+
+ te = new QTextBrowser(this);
+ te->setText(pData->szHtmlText);
+ //te->setReadOnly(true);
+
+ if(pData->iFlags & KviHtmlDialogData::ForceMinimumSize)
+ te->setMinimumSize(pData->iMinimumWidth,pData->iMinimumHeight);
+
+ //te->setReadOnly(true);
+ g->addMultiCellWidget(te,iUp,iDown,0,2);
+
+ int iButtons = pData->szButton3Text.isEmpty() ? (pData->szButton2Text.isEmpty() ? 1 : 2) : 3;
+ if(pData->iCancelButton > iButtons)pData->iCancelButton = iButtons;
+ if(pData->iDefaultButton > iButtons)pData->iDefaultButton = iButtons;
+
+ pb = new QPushButton(this);
+ pb->setText(pData->szButton1Text.isEmpty() ? __tr2qs("OK") : pData->szButton1Text);
+ pb->setDefault(pData->iDefaultButton == 1);
+ int iCoord = iButtons == 1 ? 1 : 0;
+ g->addWidget(pb,3,iCoord);
+ connect(pb,SIGNAL(clicked()),this,SLOT(button1Pressed()));
+
+ if(!pData->szButton2Text.isEmpty())
+ {
+ pb = new QPushButton(this);
+ pb->setText(pData->szButton2Text);
+ pb->setDefault(pData->iDefaultButton == 2);
+ iCoord = iButtons == 2 ? 2 : 1;
+ g->addWidget(pb,3,iCoord);
+ connect(pb,SIGNAL(clicked()),this,SLOT(button2Pressed()));
+
+ if(!pData->szButton3Text.isEmpty())
+ {
+ pb = new QPushButton(this);
+ pb->setText(pData->szButton3Text);
+ pb->setDefault(pData->iDefaultButton == 3);
+ g->addWidget(pb,3,2);
+ connect(pb,SIGNAL(clicked()),this,SLOT(button3Pressed()));
+ }
+ }
+
+ g->setRowStretch(1,1);
+
+ m_pData->iSelectedButton = m_pData->iDefaultButton;
+}
+
+KviHtmlDialog::~KviHtmlDialog()
+{
+
+}
+
+void KviHtmlDialog::button1Pressed()
+{
+ m_pData->iSelectedButton = 1;
+ accept();
+}
+
+void KviHtmlDialog::button2Pressed()
+{
+ m_pData->iSelectedButton = 2;
+ accept();
+}
+
+void KviHtmlDialog::button3Pressed()
+{
+ m_pData->iSelectedButton = 3;
+ accept();
+}
+
+void KviHtmlDialog::reject()
+{
+ m_pData->iSelectedButton = m_pData->iCancelButton;
+ QDialog::reject();
+}
+
+int KviHtmlDialog::display(QWidget * pParent,KviHtmlDialogData * pData)
+{
+ KviHtmlDialog * pDialog = new KviHtmlDialog(pParent,pData);
+ pDialog->exec();
+ delete pDialog;
+ return pData->iSelectedButton;
+}
+
+
diff --git a/src/kvirc/ui/kvi_htmldialog.h b/src/kvirc/ui/kvi_htmldialog.h
new file mode 100644
index 0000000..3f9a6d2
--- /dev/null
+++ b/src/kvirc/ui/kvi_htmldialog.h
@@ -0,0 +1,87 @@
+#ifndef _KVI_HTMLDIALOG_H_
+#define _KVI_HTMLDIALOG_H_
+//=============================================================================
+//
+// File : kvi_htmldialog.h
+// Created on Wed 03 Jan 2007 03:36:36 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2007 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_qstring.h"
+#include "kvi_settings.h"
+
+
+#include <qpixmap.h>
+#include <qdialog.h>
+
+class KviHtmlDialogData
+{
+public:
+ // input
+
+ // mandatory fields
+ enum Flags { ForceMinimumSize = 1 };
+ int iFlags; // da flags :)
+ int iDefaultButton; // the button to use when Enter is pressed (1,2 or 3)
+ int iCancelButton; // the button to use when Esc is pressed (1,2 or 3)
+ QString szHtmlText; // Shouldn't be empty :D
+
+ // optional fields
+ QString szCaption; // KVIrc is used when this is empty
+ QString szUpperLabelText; // no label is shown if this is empty
+ QString szLowerLabelText; // no label is shown if this is empty
+ QString szButton1Text; // OK is used if this is empty
+ QString szButton2Text; // no button is shown if this is empty
+ QString szButton3Text; // no button is shown if this is empty
+
+ int iMinimumWidth;
+ int iMinimumHeight;
+
+ QPixmap pixIcon; // may be null
+
+ // output
+ int iSelectedButton; // returns 1,2 or 3
+};
+
+class KVIRC_API KviHtmlDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ // the dialog does NOT delete this structure and assumes that
+ // it remains alive until the dialog closes (i.e. it may access
+ // the structure in the destructor
+ KviHtmlDialog(QWidget * pParent,KviHtmlDialogData * pData);
+ ~KviHtmlDialog();
+protected:
+ KviHtmlDialogData * m_pData;
+public:
+ // displays the dialog as modal and returns 1,2 or 3
+ static int display(QWidget * pParent,KviHtmlDialogData * pData);
+protected slots:
+ void button1Pressed();
+ void button2Pressed();
+ void button3Pressed();
+protected:
+ virtual void reject();
+};
+
+
+
+#endif //!_KVI_HTMLDIALOG_H_
diff --git a/src/kvirc/ui/kvi_imagedialog.cpp b/src/kvirc/ui/kvi_imagedialog.cpp
new file mode 100644
index 0000000..adb33a1
--- /dev/null
+++ b/src/kvirc/ui/kvi_imagedialog.cpp
@@ -0,0 +1,367 @@
+//
+// File : kvi_imagedialog.cpp
+// Creation date : Sun Dec 22 2002 19:42 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#define __KVIRC__
+#include "kvi_imagedialog.h"
+
+#include "kvi_locale.h"
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+
+#include <qimage.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+
+#include <qpainter.h>
+
+#include "kvi_fileutils.h"
+
+#include "kvi_iconmanager.h"
+#include "kvi_options.h"
+
+#include "kvi_app.h"
+
+int KviImageDialogItem::height(const KviTalListBox *lb) const
+{
+ return pixmap()->height() + 12 + lb->fontMetrics().lineSpacing();
+}
+
+int KviImageDialogItem::width(const KviTalListBox *lb) const
+{
+ int w;
+ if(text().isEmpty())w = 24;
+ w = lb->fontMetrics().width(text()) + 4;
+ if(w > 100)w = 100;
+ if(w < 24)w = 24;
+ return QMAX(pixmap()->width() + 10,w);
+}
+
+void KviImageDialogItem::paint(QPainter * p)
+{
+ const QPixmap *pm = pixmap();
+ if(pm && !pm->isNull())p->drawPixmap(5,5, *pm);
+
+ if(!m_bIsFolder)
+ {
+ p->setPen(Qt::gray);
+ p->drawRect(3,3,pm->width() + 4,pm->height() + 4);
+ }
+
+ QRect daRect(listBox()->itemRect(this));
+
+ p->setPen(Qt::black);
+ p->drawRect(1,1,daRect.width() - 2,daRect.height() - 2);
+
+ if(text().isEmpty())return;
+
+ QString t = text();
+
+ QFontMetrics fm(p->fontMetrics());
+
+ int wdth = fm.width(t);
+
+ int idx = t.length();
+ while(wdth > (daRect.width() - 6) && idx > 3)
+ {
+ t = text();
+ t.truncate(idx);
+ t.append("...");
+ wdth = fm.width(t);
+ idx--;
+ }
+
+ p->drawText(3,pm->height() + 8,daRect.width() - 6,daRect.height() - (pm->height() + 6),Qt::AlignLeft | Qt::AlignTop,t);
+}
+
+
+KviImageDialog::KviImageDialog(QWidget * par,
+ const QString &szCaption,
+ int types,
+ int initialType,
+ const QString &szInitialDir,
+ int maxPreviewFileSize,bool modal)
+: QDialog(par)
+{
+ m_szInitialPath = szInitialDir;
+ setModal(modal);
+ m_iMaxPreviewFileSize = maxPreviewFileSize;
+
+ setCaption(szCaption.isEmpty() ? __tr2qs("Choose image ...") : szCaption);
+
+ m_pTimer = new QTimer(this);
+ connect(m_pTimer,SIGNAL(timeout()),this,SLOT(heartbeat()));
+
+ QGridLayout * g = new QGridLayout(this,4,3,5,3);
+
+ m_pTypeComboBox = new QComboBox(this);
+
+ g->addMultiCellWidget(m_pTypeComboBox,0,0,0,2);
+
+ m_pTypeList = new KviValueList<int>;
+
+ QString bi = __tr2qs("Builtin images");
+
+ QString tmp = bi;
+
+ if((types & KID_TYPE_ALL) == 0)types = KID_TYPE_FULL_PATH;
+
+ if(types & KID_TYPE_BUILTIN_IMAGES_SMALL)
+ {
+ tmp += ": ";
+ tmp += __tr2qs("Small icons");
+ m_pTypeComboBox->insertItem(tmp);
+ m_pTypeList->append(KID_TYPE_BUILTIN_IMAGES_SMALL);
+ }
+
+ if(types & KID_TYPE_FULL_PATH)
+ {
+ m_pTypeComboBox->insertItem(__tr2qs("Full path"));
+ m_pTypeList->append(KID_TYPE_FULL_PATH);
+ }
+
+ int idx = m_pTypeList->findIndex(initialType);
+ if(idx < 0)idx = 0;
+
+ QWidget * l = new QWidget(this);
+ g->addMultiCellWidget(l,1,1,0,2);
+
+
+ m_pListBox = new KviTalListBox(this);
+ m_pListBox->setColumnMode(KviTalListBox::FitToWidth);
+ m_pListBox->setRowMode(KviTalListBox::Variable);
+
+ m_pTip = new KviDynamicToolTip(m_pListBox->viewport());
+
+ g->addMultiCellWidget(m_pListBox,2,2,0,2);
+
+ QPushButton * b = new QPushButton(__tr2qs("Cancel"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+ g->addWidget(b,3,1);
+
+ b = new QPushButton(__tr2qs("Ok"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(okClicked()));
+ g->addWidget(b,3,2);
+
+ g->setRowStretch(2,1);
+ g->setColStretch(0,1);
+
+ connect(m_pTypeComboBox,SIGNAL(activated(int)),this,SLOT(jobTypeSelected(int)));
+ connect(m_pListBox,SIGNAL(doubleClicked(KviTalListBoxItem *)),this,SLOT(itemDoubleClicked(KviTalListBoxItem *)));
+ connect(m_pTip,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &)));
+
+ m_pTypeComboBox->setCurrentItem(idx);
+ jobTypeSelected(idx);
+
+ m_pListBox->setMinimumSize(420,350);
+}
+
+KviImageDialog::~KviImageDialog()
+{
+ delete m_pTimer;
+ delete m_pTypeList;
+}
+
+void KviImageDialog::jobTypeSelected(int index)
+{
+ if(index < 0)return;
+ if(index >= (int)(m_pTypeList->count()))index = (int)m_pTypeList->count();
+ if(m_szInitialPath.isEmpty())
+ startJob(*(m_pTypeList->at(index)),KVI_OPTION_STRING(KviOption_stringLastImageDialogPath));
+ else {
+ startJob(*(m_pTypeList->at(index)),m_szInitialPath);
+ m_szInitialPath = ""; // clear it so we will use the last path
+ }
+}
+
+void KviImageDialog::startJob(int type,const QString &szInitialPath)
+{
+ m_pTimer->stop();
+ m_iJobType = type;
+
+ m_iJobIndexHelper = 0;
+ if(m_iJobType == KID_TYPE_FULL_PATH)
+ {
+ QDir d(szInitialPath);
+ if(!d.exists())d = QDir::homeDirPath();
+ if(!d.exists())d = QDir::rootDirPath();
+ m_szJobPath = d.absPath();
+ KVI_OPTION_STRING(KviOption_stringLastImageDialogPath) = m_szJobPath;
+ m_lJobFileList = d.entryList(QDir::Hidden | QDir::All,QDir::DirsFirst | QDir::Name | QDir::IgnoreCase);
+ }
+
+ m_pTimer->start(100);
+}
+
+void KviImageDialog::jobTerminated()
+{
+ m_pTimer->stop();
+}
+
+void KviImageDialog::heartbeat()
+{
+ if(m_iJobIndexHelper == 0)m_pListBox->clear();
+
+
+ switch(m_iJobType)
+ {
+ case KID_TYPE_BUILTIN_IMAGES_SMALL:
+ {
+ if(m_iJobIndexHelper >= KVI_NUM_SMALL_ICONS)
+ {
+ jobTerminated();
+ return;
+ }
+ int max = m_iJobIndexHelper + 15;
+ if(max > KVI_NUM_SMALL_ICONS)max = KVI_NUM_SMALL_ICONS;
+ while(m_iJobIndexHelper < max)
+ {
+ QString id = g_pIconManager->getSmallIconName(m_iJobIndexHelper);
+ KviImageDialogItem * it;
+ QString tip;
+ KviQString::sprintf(tip,__tr2qs("Builtin $icon(%Q) [index %d]"),&id,m_iJobIndexHelper);
+ QString image_id = "$icon(";
+ image_id += id;
+ image_id += ")";
+ it = new KviImageDialogItem(m_pListBox,*(g_pIconManager->getSmallIcon(m_iJobIndexHelper)),id,image_id,tip);
+ m_iJobIndexHelper++;
+ }
+ }
+ break;
+ case KID_TYPE_FULL_PATH:
+ {
+ m_iJobIndexHelper++;
+ if(m_lJobFileList.isEmpty())
+ {
+ jobTerminated();
+ return;
+ }
+ int idx = 0;
+ while((idx < 20) && (!m_lJobFileList.isEmpty()))
+ {
+ QString szFile = m_lJobFileList.first();
+ m_lJobFileList.remove(szFile);
+ QString szPath = m_szJobPath;
+ szPath += KVI_PATH_SEPARATOR;
+ szPath += szFile;
+ QFileInfo fi(szPath);
+ idx += fi.size() / 128000; // we do less entries when have big files to read
+ if(fi.isDir())
+ {
+ if(szFile != ".")
+ {
+ QString tip = szFile;
+ tip += "<br><hr>";
+ tip += __tr2qs("directory");
+ KviImageDialogItem * it;
+ it = new KviImageDialogItem(m_pListBox,*(g_pIconManager->getBigIcon(KVI_BIGICON_FOLDER)),szFile,szPath,tip,true);
+ }
+ } else {
+ if(((int)fi.size()) < m_iMaxPreviewFileSize)
+ {
+ QImage i(szPath);
+ if(i.isNull())continue;
+ QPixmap pix;
+#ifdef COMPILE_USE_QT4
+ if((i.width() > 80) || (i.height() > 80))pix = i.scaled(80,80,Qt::KeepAspectRatio);
+#else
+ if((i.width() > 80) || (i.height() > 80))pix = i.scale(80,80,QImage::ScaleMin);
+#endif
+ else pix = i;
+
+ QString tip = szFile;
+ tip += "<br><hr>";
+ QString sz;
+ sz.setNum(i.width());
+ tip += sz;
+ tip += " x ";
+ sz.setNum(i.height());
+ tip += sz;
+ tip += " ";
+ tip += __tr2qs("pixels");
+ tip += "<br>";
+ sz.setNum(fi.size());
+ tip += sz;
+ tip += " ";
+ tip += __tr2qs("bytes");
+ tip += "<br>";
+
+ KviImageDialogItem * it;
+ it = new KviImageDialogItem(m_pListBox,pix,szFile,szPath,tip);
+ }
+ }
+ idx++;
+ }
+ }
+ break;
+ }
+}
+
+void KviImageDialog::okClicked()
+{
+ KviTalListBoxItem * it = 0;
+ int idx = m_pListBox->currentItem();
+ if(idx != -1)it = (KviTalListBoxItem *)m_pListBox->item(idx);
+ if(!it)return;
+ itemDoubleClicked(it);
+}
+
+void KviImageDialog::cancelClicked()
+{
+ m_szSelectedImage = QString::null;
+ reject();
+}
+
+void KviImageDialog::closeEvent(QCloseEvent * e)
+{
+ m_szSelectedImage = QString::null;
+ QDialog::closeEvent(e);
+}
+
+void KviImageDialog::itemDoubleClicked(KviTalListBoxItem * it)
+{
+ if(!it)return;
+ KviImageDialogItem * i = (KviImageDialogItem *)it;
+ if(i->isFolder())
+ {
+ startJob(KID_TYPE_FULL_PATH,i->imageId());
+ } else {
+ QString szImageId = i->imageId();
+ if(szImageId.length() > 0)
+ {
+ if(szImageId.at(0) == QChar('$'))
+ m_szSelectedImage = szImageId; // it's $icon(something)
+ else
+ g_pApp->mapImageFile(m_szSelectedImage,i->imageId()); // it's a file and we need to map it to our filesystem view
+ accept();
+ }
+ }
+}
+
+void KviImageDialog::tipRequest(KviDynamicToolTip *,const QPoint &pnt)
+{
+ KviTalListBoxItem * it = (KviTalListBoxItem *)m_pListBox->itemAt(pnt);
+ if(!it)return;
+ QRect r = m_pListBox->itemRect(it);
+ KviImageDialogItem * i = (KviImageDialogItem *)it;
+ m_pTip->tip(r,i->tipText());
+}
diff --git a/src/kvirc/ui/kvi_imagedialog.h b/src/kvirc/ui/kvi_imagedialog.h
new file mode 100644
index 0000000..7e1da54
--- /dev/null
+++ b/src/kvirc/ui/kvi_imagedialog.h
@@ -0,0 +1,109 @@
+#ifndef _KVI_IMAGEDIALOG_H_
+#define _KVI_IMAGEDIALOG_H_
+//
+// File : kvi_imagedialog.h
+// Creation date : Sun Dec 22 2002 19:42 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+
+
+
+
+#include <qdialog.h>
+#include <qcombobox.h>
+#include "kvi_tal_listbox.h"
+#include "kvi_valuelist.h"
+#include <qtimer.h>
+#include <qstringlist.h>
+
+#include "kvi_dynamictooltip.h"
+
+class KviImageDialogItem : public KviTalListBoxPixmap
+{
+public:
+ bool m_bIsFolder;
+ QString m_szImageId;
+ QString m_szTipText;
+public:
+ KviImageDialogItem(KviTalListBox * b,const QPixmap &thumb,const QString &szFile,const QString &image_id,const QString &szTipText = QString::null,bool bIsFolder = false)
+ : KviTalListBoxPixmap(b,thumb,szFile) , m_bIsFolder(bIsFolder) , m_szImageId(image_id) , m_szTipText(szTipText) {};
+ ~KviImageDialogItem(){};
+public:
+ bool isFolder(){ return m_bIsFolder; };
+ const QString & imageId(){ return m_szImageId; };
+ const QString & tipText(){ return m_szTipText; };
+ virtual int height(const KviTalListBox *) const;
+ virtual int width(const KviTalListBox *) const;
+ virtual void paint(QPainter * p);
+};
+
+
+#define KID_TYPE_BUILTIN_IMAGES_SMALL 1
+#define KID_TYPE_FULL_PATH 2
+
+#define KID_TYPE_ALL 3
+
+class KVIRC_API KviImageDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviImageDialog(QWidget * par,
+ const QString &szCaption = QString::null,
+ int types = KID_TYPE_ALL,
+ int initialType = 0,
+ const QString &szInitialDir = QString::null,
+ int maxPreviewFileSize = 256000, bool modal=false);
+ virtual ~KviImageDialog();
+protected:
+ QComboBox * m_pTypeComboBox;
+ KviValueList<int> * m_pTypeList;
+ KviTalListBox * m_pListBox;
+ QTimer * m_pTimer;
+ int m_iJobType;
+
+ int m_iMaxPreviewFileSize;
+
+ QString m_szJobPath;
+ QStringList m_lJobFileList;
+
+ int m_iJobIndexHelper;
+
+ QString m_szSelectedImage;
+
+ QString m_szInitialPath;
+
+ KviDynamicToolTip * m_pTip;
+public:
+ const QString & selectedImage(){ return m_szSelectedImage; };
+protected:
+ void startJob(int type,const QString &szInitialPath = QString::null);
+ void jobTerminated();
+ virtual void closeEvent(QCloseEvent *e);
+protected slots:
+ void okClicked();
+ void cancelClicked();
+ void heartbeat();
+ void jobTypeSelected(int index);
+ void itemDoubleClicked(KviTalListBoxItem * it);
+ void tipRequest(KviDynamicToolTip *,const QPoint &pnt);
+};
+
+#endif //_KVI_IMAGEDIALOG_H_
diff --git a/src/kvirc/ui/kvi_input.cpp b/src/kvirc/ui/kvi_input.cpp
new file mode 100644
index 0000000..c0fbbd9
--- /dev/null
+++ b/src/kvirc/ui/kvi_input.cpp
@@ -0,0 +1,2680 @@
+//=============================================================================
+//
+// File : kvi_input.cpp
+// Creation date : Sun Jan 3 1999 23:11:50 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2007 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+
+#define _KVI_INPUT_CPP_
+
+#include "kvi_options.h"
+#include "kvi_app.h"
+#include "kvi_settings.h"
+#include "kvi_defaults.h"
+#include "kvi_colorwin.h"
+#include "kvi_texticonwin.h"
+#include "kvi_window.h"
+
+#include "kvi_locale.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_userlistview.h"
+#include "kvi_ircview.h"
+#include "kvi_console.h"
+#include "kvi_out.h"
+#include "kvi_iconmanager.h"
+#include "kvi_scripteditor.h"
+#include "kvi_config.h"
+#include "kvi_historywin.h"
+#include "kvi_input.h"
+#include "kvi_userinput.h"
+#include "kvi_kvs_script.h"
+#include "kvi_kvs_kernel.h"
+#include "kvi_doublebuffer.h"
+#include "kvi_styled_controls.h"
+#include "kvi_texticonmanager.h"
+#include "kvi_draganddrop.h"
+
+#include <qlabel.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <qfiledialog.h>
+#include "kvi_tal_popupmenu.h"
+#include <qpainter.h>
+#include <qclipboard.h>
+#include <qstringlist.h>
+#include "kvi_pointerlist.h"
+#include <qapplication.h>
+#include <qclipboard.h>
+#include <qmessagebox.h>
+#include "kvi_tal_hbox.h"
+#include <qlayout.h>
+#include <qstyle.h>
+#include <qevent.h>
+
+
+#ifndef ACCEL_KEY
+#define ACCEL_KEY(k) "\t" + QString(QKeySequence( Qt::CTRL | Qt::Key_ ## k ))
+#endif
+
+// FIXME: #warning "This hack is temporary...later remove it"
+#if QT_VERSION >= 300
+ #ifndef QT_CLEAN_NAMESPACE
+ #define QT_CLEAN_NAMESPACE
+ #include <qcursor.h>
+ #undef QT_CLEAN_NAMESPACE
+ #else
+ #include <qcursor.h>
+ #endif
+#else
+ #include <qcursor.h>
+#endif
+
+
+
+//This comes from kvi_app.cpp
+extern KviColorWindow * g_pColorWindow;
+extern KviTextIconWindow * g_pTextIconWindow;
+extern KviHistoryWindow * g_pHistoryWindow;
+extern KviTalPopupMenu * g_pInputPopup;
+
+static QFontMetrics * g_pLastFontMetrics = 0;
+
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+#endif
+
+
+#define KVI_INPUT_MAX_GLOBAL_HISTORY_ENTRIES 100
+#define KVI_INPUT_MAX_LOCAL_HISTORY_ENTRIES 20
+
+
+extern KviInputHistory * g_pInputHistory;
+
+
+KviInputHistory::KviInputHistory()
+{
+ m_pStringList = new KviPointerList<QString>;
+ m_pStringList->setAutoDelete(true);
+}
+
+KviInputHistory::~KviInputHistory()
+{
+ delete m_pStringList;
+}
+
+void KviInputHistory::add(QString * s)
+{
+ m_pStringList->insert(0,s);
+ if(m_pStringList->count() > KVI_INPUT_MAX_GLOBAL_HISTORY_ENTRIES)m_pStringList->removeLast();
+}
+
+void KviInputHistory::load(const char * filename)
+{
+ KviConfig c(filename,KviConfig::Read);
+
+ int cnt = c.readIntEntry("Count",0);
+
+ if(cnt > KVI_INPUT_MAX_GLOBAL_HISTORY_ENTRIES)cnt = KVI_INPUT_MAX_GLOBAL_HISTORY_ENTRIES;
+
+ KviStr tmp;
+
+ for(int i=0;i<cnt;i++)
+ {
+ tmp.sprintf("S%d",i);
+ QString entry = c.readQStringEntry(tmp.ptr(),"");
+ if(!entry.isEmpty())add(new QString(entry));
+ }
+}
+
+void KviInputHistory::save(const char * filename)
+{
+ KviConfig c(filename,KviConfig::Write);
+ c.clear();
+
+ c.writeEntry("Count",m_pStringList->count());
+
+ KviStr tmp;
+ int idx = 0;
+
+ for(QString * s = m_pStringList->first();s;s = m_pStringList->next())
+ {
+ if(!s->isEmpty())
+ {
+ tmp.sprintf("S%d",idx);
+ c.writeEntry(tmp.ptr(),*s);
+ idx++;
+ }
+ }
+}
+
+//=============== KviInputEditor ==============//
+
+static int g_iInputFontCharWidth[256];
+static bool g_bInputFontMetricsDirty = true;
+
+
+KviInputEditor::KviInputEditor(QWidget * par,KviWindow *wnd,KviUserListView * view)
+:QFrame(par,"input")
+{
+ m_pIconMenu = 0;
+ m_pInputParent = par;
+ m_iMaxBufferSize = KVI_INPUT_MAX_BUFFER_SIZE;
+ m_iCursorPosition = 0; //Index of the char AFTER the cursor
+ m_iFirstVisibleChar = 0; //Index of the first visible character
+ m_iSelectionBegin = -1; //Index of the first char in the selection
+ m_iSelectionEnd = -1; //Index of the last char in the selection
+ m_bIMComposing = false; //Whether the input method is active (composing).
+ // for input method support
+ m_iIMStart = 0; //Index of the start of the preedit string.
+ m_iIMLength = 0; //Length of the preedit string.
+ m_iIMSelectionBegin = 0; //Index of the start of the selection in preedit string.
+ m_iIMSelectionLength = 0; //Length of the selection in preedit string.
+
+ m_bCursorOn = false; //Cursor state
+ m_iCursorTimer = 0; //Timer that iverts the cursor state
+ m_iDragTimer = 0; //Timer for drag selection updates
+ m_iLastCursorXPosition = KVI_INPUT_MARGIN; //Calculated in paintEvent
+ m_iSelectionAnchorChar = -1; //Character clicked at the beginning of the selection process
+ m_iCurHistoryIdx = -1; //No data in the history
+ m_bUpdatesEnabled = true;
+ m_pKviWindow = wnd;
+ m_pUserListView = view;
+ m_pHistory = new KviPointerList<QString>;
+ m_pHistory->setAutoDelete(true);
+ m_bReadOnly = FALSE;
+
+ setInputMethodEnabled(true);
+
+#ifdef COMPILE_USE_QT4
+ setAutoFillBackground(false);
+ setFocusPolicy(Qt::StrongFocus);
+#else
+ setBackgroundMode(Qt::NoBackground);
+ setFocusPolicy(QWidget::StrongFocus);
+#endif
+ setAcceptDrops(true);
+ setFrameStyle( LineEditPanel );
+ setFrameShadow( Plain );
+
+ m_pIconMenu = new KviTalPopupMenu();
+ connect(m_pIconMenu,SIGNAL(activated(int)),this,SLOT(iconPopupActivated(int)));
+
+#ifdef COMPILE_USE_QT4
+ setCursor(Qt::IBeamCursor);
+#else
+ setCursor(IbeamCursor);
+#endif
+}
+
+KviInputEditor::~KviInputEditor()
+{
+ if(g_pLastFontMetrics) delete g_pLastFontMetrics;
+ g_pLastFontMetrics = 0;
+ if(m_pIconMenu)delete m_pIconMenu;
+ delete m_pHistory;
+ if(m_iCursorTimer)killTimer(m_iCursorTimer);
+ killDragTimer();
+}
+
+void KviInputEditor::recalcFontMetrics(QFontMetrics * pFm)
+{
+ QFontMetrics fm(KVI_OPTION_FONT(KviOption_fontInput));
+ unsigned short i;
+ for(i=1;i<32;i++)
+ {
+ QChar c = getSubstituteChar(i);
+ g_iInputFontCharWidth[i] = fm.width(c);
+ if(c != QChar(i))g_iInputFontCharWidth[i] += 4;
+ }
+ for(i=32;i<256;i++)
+ {
+ g_iInputFontCharWidth[i] = fm.width(QChar(i));
+ }
+ g_bInputFontMetricsDirty = false;
+}
+
+void KviInputEditor::applyOptions()
+{
+ g_bInputFontMetricsDirty = true;
+ update();
+}
+
+void KviInputEditor::dragEnterEvent(QDragEnterEvent *e)
+{
+ if(KviUriDrag::canDecode(e))
+ {
+ e->accept(true);
+// FIXME: #warning "FIX THIS COMMENTED STUFF"
+/*
+ m_pKviWindow->m_pFrm->m_pStatusBar->tempText(__tr("Drop the file to /PARSE it"),5000);
+*/
+ } else e->accept(false);
+}
+
+void KviInputEditor::dropEvent(QDropEvent *e)
+{
+ QStringList list;
+ if(KviUriDrag::decodeLocalFiles(e,list))
+ {
+ //debug("Local files decoded");
+ if(!list.isEmpty())
+ {
+ //debug("List not empty");
+ QStringList::ConstIterator it = list.begin(); //kewl ! :)
+ for( ; it != list.end(); ++it )
+ {
+ QString tmp = *it; //wow :)
+#ifndef COMPILE_ON_WINDOWS
+ if(tmp.length() > 0)
+ {
+ if(tmp[0] != QChar('/'))tmp.prepend("/"); //HACK HACK HACK for Qt bug (?!?)
+ }
+#endif
+ tmp.prepend("/PARSE \"");
+ tmp.append("\"");
+ if(m_pKviWindow)
+ KviKvsScript::run(tmp,m_pKviWindow);
+ }
+ }
+ }
+}
+
+int KviInputEditor::heightHint() const
+{
+ return sizeHint().height();
+}
+
+QSize KviInputEditor::sizeHint() const
+{
+ //grabbed from qlineedit.cpp
+ constPolish();
+ QFontMetrics fm(KVI_OPTION_FONT(KviOption_fontInput));
+ int h = QMAX(fm.lineSpacing(), 14) + 2*2; /* innerMargin */
+ int w = fm.width( 'x' ) * 17; // "some"
+ int m = frameWidth() * 2;
+#ifdef COMPILE_USE_QT4
+ QStyleOption opt;
+ opt.initFrom(this);
+ return (style()->sizeFromContents(QStyle::CT_LineEdit,&opt,
+ QSize( w + m, h + m ).
+ expandedTo(QApplication::globalStrut()),this));
+#else
+ return (style().sizeFromContents(QStyle::CT_LineEdit, this,
+ QSize( w + m, h + m ).
+ expandedTo(QApplication::globalStrut())));
+#endif
+}
+
+#define KVI_INPUT_DEF_BACK 100
+#define KVI_INPUT_DEF_FORE 101
+
+#ifdef COMPILE_USE_QT4
+void KviInputEditor::paintEvent(QPaintEvent *e)
+{
+ QPainter p(this);
+ SET_ANTI_ALIASING(p);
+ drawFrame(&p);
+ drawContents(&p);
+}
+#endif
+
+void KviInputEditor::drawContents(QPainter *p)
+{
+ if(!isVisible())return;
+
+ QRect rect = contentsRect();
+ int widgetWidth = rect.width();
+ int widgetHeight = rect.height();
+
+ KviDoubleBuffer doublebuffer(widgetWidth,widgetHeight);
+ QPixmap * pDoubleBufferPixmap = doublebuffer.pixmap();
+
+ QPainter pa(pDoubleBufferPixmap);
+ SET_ANTI_ALIASING(pa);
+
+ pa.setFont(KVI_OPTION_FONT(KviOption_fontInput));
+
+ QFontMetrics fm(pa.fontMetrics());
+
+ if(!g_pLastFontMetrics)
+ g_pLastFontMetrics = new QFontMetrics(pa.fontMetrics());
+
+ if(g_bInputFontMetricsDirty)
+ recalcFontMetrics(&fm);
+
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = mapToGlobal(rect.topLeft());
+ pa.drawTiledPixmap(0,0,widgetWidth,widgetHeight,*g_pShadedChildGlobalDesktopBackground,pnt.x(),pnt.y());
+ } else {
+#endif
+ QPixmap *pix=KVI_OPTION_PIXMAP(KviOption_pixmapInputBackground).pixmap();
+
+ pa.fillRect(0,0,widgetWidth,widgetHeight,KVI_OPTION_COLOR(KviOption_colorInputBackground));
+ if(pix)
+ KviPixmapUtils::drawPixmapWithPainter(&pa,pix,KVI_OPTION_UINT(KviOption_uintInputPixmapAlign),rect,widgetWidth,widgetHeight);
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+
+
+ int curXPos = KVI_INPUT_MARGIN;
+ int maxXPos = widgetWidth-2*KVI_INPUT_MARGIN;
+ m_iCurBack = KVI_INPUT_DEF_BACK; //transparent
+ m_iCurFore = KVI_INPUT_DEF_FORE; //normal fore color
+ m_bCurBold = false;
+ m_bCurUnderline = false;
+
+ int bottom = widgetHeight-(widgetHeight-fm.height())/2;
+ int textBaseline = fm.ascent()+(widgetHeight-fm.height())/2;
+ int top = (widgetHeight-fm.height())/2;
+
+ runUpToTheFirstVisibleChar();
+
+ int charIdx = m_iFirstVisibleChar;
+
+ pa.setClipRect(0,0,widgetWidth,widgetHeight);
+
+ //Control the selection state
+ if((m_iSelectionEnd < m_iSelectionBegin) || (m_iSelectionEnd == -1) || (m_iSelectionBegin == -1))
+ {
+ m_iSelectionEnd = -1;
+ m_iSelectionBegin = -1;
+ }
+
+ if((m_iSelectionBegin != -1) && (m_iSelectionEnd >= m_iFirstVisibleChar))
+ {
+ int iSelStart = m_iSelectionBegin;
+
+ // TODO Refactor: write a function to combine this with the code determining iIMStart and iIMSelectionStart
+ if(iSelStart < m_iFirstVisibleChar)iSelStart = m_iFirstVisibleChar;
+ int xLeft = xPositionFromCharIndex(fm,iSelStart,TRUE);
+ int xRight = xPositionFromCharIndex(fm,m_iSelectionEnd + 1,TRUE);
+
+// pa.setRasterOp(Qt::NotROP);
+ pa.fillRect(xLeft,frameWidth(),xRight - xLeft,widgetWidth,KVI_OPTION_COLOR(KviOption_colorInputSelectionBackground));
+// pa.setRasterOp(Qt::CopyROP);
+ }
+
+ // When m_bIMComposing is true, the text between m_iIMStart and m_iIMStart+m_iIMLength should be highlighted to show that this is the active
+ // preedit area for the input method, and the text outside cannot be edited while
+ // composing. Maybe this can be implemented similarly as painting the selection?
+ // Also notice that inside the preedit, there can also be a selection, given by
+ // m_iSelectionBegin and m_iSelectionLength, and the widget needs to highlight that
+ // while in IM composition mode
+ if(m_bIMComposing && m_iIMLength > 0)
+ {
+ // TODO Write a function to combine IM selection drawing code. maybe the preedit area too.
+ int iIMSelectionStart = m_iIMSelectionBegin;
+ if(iIMSelectionStart < m_iFirstVisibleChar) iIMSelectionStart = m_iFirstVisibleChar;
+ int xIMSelectionLeft = xPositionFromCharIndex(fm,iIMSelectionStart,TRUE);
+ int xIMSelectionRight = xPositionFromCharIndex(fm,iIMSelectionStart + m_iIMSelectionLength,TRUE);
+// pa.setRasterOp(Qt::NotROP);
+ pa.fillRect(xIMSelectionLeft,0,xIMSelectionRight - xIMSelectionLeft, widgetWidth,KVI_OPTION_COLOR(KviOption_colorInputSelectionBackground));
+// pa.setRasterOp(Qt::CopyROP);
+
+ // highlight the IM selection
+ int iIMStart = m_iIMStart;
+ if(m_iIMStart < m_iFirstVisibleChar) m_iIMStart = m_iFirstVisibleChar;
+ int xIMLeft = xPositionFromCharIndex(fm,iIMStart,TRUE);
+ int xIMRight = xPositionFromCharIndex(fm,iIMStart + m_iIMLength,TRUE);
+
+ // underline the IM preedit
+ // Maybe should be put in drawTextBlock, similar to drawing underlined text
+ pa.drawLine(xIMLeft, bottom, xIMRight, bottom);
+ }
+
+ pa.setClipping(false);
+
+ while((charIdx < ((int)(m_szTextBuffer.length()))) && (curXPos < maxXPos))
+ {
+ extractNextBlock(charIdx,fm,curXPos,maxXPos);
+
+ if(m_bControlBlock)
+ {
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorInputControl));
+
+ QString s = getSubstituteChar(m_szTextBuffer[charIdx].unicode());
+
+ // the block width is 4 pixels more than the actual character
+
+ pa.drawText(curXPos + 2,textBaseline,s,1);
+
+ pa.drawRect(curXPos,top,m_iBlockWidth-1,bottom);
+ } else {
+ if(m_iSelectionBegin!=-1)
+ {
+ int iBlockEnd=charIdx+m_iBlockLen;
+ //block is selected (maybe partially)
+ if( iBlockEnd>m_iSelectionBegin && charIdx<=m_iSelectionEnd )
+ {
+ int iSubStart,iSubLen;
+ //in common it consists of 3 parts: unselected-selected-unselected
+ //some of thst parts can be empty (for example block is fully selected)
+
+ //first part start is always equal to the block start
+ iSubStart=charIdx;
+ iSubLen = m_iSelectionBegin>charIdx ? m_iSelectionBegin-charIdx : 0;
+
+
+ if(iSubLen)
+ {
+ drawTextBlock(&pa,fm,curXPos,textBaseline,iSubStart,iSubLen,FALSE);
+ curXPos += m_iBlockWidth;
+ m_iBlockWidth=0;
+ }
+
+ //second one
+ iSubStart+=iSubLen;
+ iSubLen=m_iSelectionEnd<iBlockEnd ? m_iSelectionEnd-iSubStart+1 : iBlockEnd-iSubStart;
+
+
+ if(iSubLen)
+ {
+ drawTextBlock(&pa,fm,curXPos,textBaseline,iSubStart,iSubLen,TRUE);
+ curXPos += m_iBlockWidth;
+ m_iBlockWidth=0;
+ }
+
+ if( m_iSelectionEnd<(iBlockEnd-1))
+ {
+ iSubStart+=iSubLen;
+ iSubLen=iBlockEnd-iSubStart;
+ drawTextBlock(&pa,fm,curXPos,textBaseline,iSubStart,iSubLen,FALSE);
+ }
+ } else {
+ drawTextBlock(&pa,fm,curXPos,textBaseline,charIdx,m_iBlockLen);
+ }
+ } else {
+ drawTextBlock(&pa,fm,curXPos,textBaseline,charIdx,m_iBlockLen);
+ }
+ }
+
+ curXPos += m_iBlockWidth;
+ charIdx += m_iBlockLen;
+ }
+
+ //Now the cursor
+
+ m_iLastCursorXPosition = KVI_INPUT_MARGIN;
+ m_iBlockLen = m_iFirstVisibleChar;
+
+ while(m_iBlockLen < m_iCursorPosition)
+ {
+ QChar c = m_szTextBuffer.at(m_iBlockLen);
+#ifdef COMPILE_USE_QT4
+ m_iLastCursorXPosition+= c.unicode() < 32 ? fm.width(getSubstituteChar(c.unicode())) + 3 : fm.width(c);
+#else
+ m_iLastCursorXPosition+= (c.unicode() < 256) ? g_iInputFontCharWidth[c.unicode()] : fm.width(c);
+#endif
+ m_iBlockLen++;
+ }
+
+ //m_iLastCursorXPosition = cur1XPos;
+
+ if(m_bCursorOn)
+ {
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorInputCursor));
+ pa.drawLine(m_iLastCursorXPosition,0,m_iLastCursorXPosition,widgetHeight);
+ } else {
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorInputForeground));
+ }
+
+#ifdef COMPILE_USE_QT4
+ // The other version of drawPixmap seems to be buggy
+ p->drawPixmap(rect.x(),rect.y(),rect.width(),rect.height(),*pDoubleBufferPixmap,0,0,widgetWidth,widgetHeight);
+#else
+ p->drawPixmap(rect.x(),rect.y(),*pDoubleBufferPixmap,0,0,widgetWidth,widgetHeight);
+#endif
+}
+
+void KviInputEditor::drawTextBlock(QPainter * pa,QFontMetrics & fm,int curXPos,int textBaseline,int charIdx,int len,bool bSelected)
+{
+ QString tmp = m_szTextBuffer.mid(charIdx,len);
+ m_iBlockWidth = fm.width(tmp);
+
+ QRect rect = contentsRect();
+ int widgetHeight = rect.height();
+
+ if(m_iCurFore == KVI_INPUT_DEF_FORE)
+ {
+ pa->setPen( bSelected ? KVI_OPTION_COLOR(KviOption_colorInputSelectionForeground) : KVI_OPTION_COLOR(KviOption_colorInputForeground));
+ } else {
+ if(((unsigned char)m_iCurFore) > 16)
+ {
+ pa->setPen(KVI_OPTION_COLOR(KviOption_colorInputBackground));
+ } else {
+ pa->setPen(KVI_OPTION_MIRCCOLOR((unsigned char)m_iCurFore));
+ }
+ }
+
+ if(m_iCurBack != KVI_INPUT_DEF_BACK)
+ {
+ if(((unsigned char)m_iCurBack) > 16)
+ {
+ pa->fillRect(curXPos,(widgetHeight-fm.height())/2,m_iBlockWidth,fm.height(),KVI_OPTION_COLOR(KviOption_colorInputForeground));
+ } else {
+ pa->fillRect(curXPos,(widgetHeight-fm.height())/2,m_iBlockWidth,fm.height(),KVI_OPTION_MIRCCOLOR((unsigned char)m_iCurBack));
+ }
+ }
+
+ pa->drawText(curXPos,textBaseline,tmp);
+
+ if(m_bCurBold)pa->drawText(curXPos+1,textBaseline,tmp);
+ if(m_bCurUnderline)
+ {
+ pa->drawLine(curXPos,textBaseline + fm.descent(),curXPos+m_iBlockWidth,textBaseline + fm.descent());
+ }
+
+}
+
+QChar KviInputEditor::getSubstituteChar(unsigned short control_code)
+{
+ switch(control_code)
+ {
+ case KVI_TEXT_COLOR:
+ return QChar('K');
+ break;
+ case KVI_TEXT_BOLD:
+ return QChar('B');
+ break;
+ case KVI_TEXT_RESET:
+ return QChar('O');
+ break;
+ case KVI_TEXT_REVERSE:
+ return QChar('R');
+ break;
+ case KVI_TEXT_UNDERLINE:
+ return QChar('U');
+ break;
+ case KVI_TEXT_CRYPTESCAPE:
+ return QChar('P');
+ break;
+ case KVI_TEXT_ICON:
+ return QChar('I');
+ break;
+ default:
+ return QChar(control_code);
+ break;
+ }
+}
+
+void KviInputEditor::extractNextBlock(int idx,QFontMetrics & fm,int curXPos,int maxXPos)
+{
+ m_iBlockLen = 0;
+ m_iBlockWidth = 0;
+
+ QChar c = m_szTextBuffer[idx];
+
+ if((c.unicode() > 32) ||
+ ((c != QChar(KVI_TEXT_COLOR)) &&
+ (c != QChar(KVI_TEXT_BOLD)) && (c != QChar(KVI_TEXT_UNDERLINE)) &&
+ (c != QChar(KVI_TEXT_RESET)) && (c != QChar(KVI_TEXT_REVERSE)) &&
+ (c != QChar(KVI_TEXT_CRYPTESCAPE)) && (c != QChar(KVI_TEXT_ICON))))
+ {
+ m_bControlBlock = false;
+ //Not a control code...run..
+ while((idx < ((int)(m_szTextBuffer.length()))) && (curXPos < maxXPos))
+ {
+ c = m_szTextBuffer[idx];
+ if((c.unicode() > 32) ||
+ ((c != QChar(KVI_TEXT_COLOR)) && (c != QChar(KVI_TEXT_BOLD)) &&
+ (c != QChar(KVI_TEXT_UNDERLINE)) && (c != QChar(KVI_TEXT_RESET)) &&
+ (c != QChar(KVI_TEXT_REVERSE)) && (c != QChar(KVI_TEXT_CRYPTESCAPE)) &&
+ (c != QChar(KVI_TEXT_ICON))))
+ {
+ m_iBlockLen++;
+#ifdef COMPILE_USE_QT4
+ int xxx = c.unicode() < 32 ? fm.width(getSubstituteChar(c.unicode())) + 3 : fm.width(c);;
+#else
+ int xxx = (c.unicode() < 256 ? g_iInputFontCharWidth[c.unicode()] : fm.width(c));
+#endif
+ m_iBlockWidth +=xxx;
+ curXPos +=xxx;
+ idx++;
+ } else break;
+ }
+ return;
+ } else {
+ m_bControlBlock = true;
+ m_iBlockLen = 1;
+ m_iBlockWidth = g_iInputFontCharWidth[c.unicode()];
+ //Control code
+ switch(c.unicode())
+ {
+ case KVI_TEXT_BOLD:
+ m_bCurBold = ! m_bCurBold;
+ break;
+ case KVI_TEXT_UNDERLINE:
+ m_bCurUnderline = ! m_bCurUnderline;
+ break;
+ case KVI_TEXT_RESET:
+ m_iCurFore = KVI_INPUT_DEF_FORE;
+ m_iCurBack = KVI_INPUT_DEF_BACK;
+ m_bCurBold = false;
+ m_bCurUnderline = false;
+ break;
+ case KVI_TEXT_REVERSE:
+ {
+ char auxClr = m_iCurFore;
+ m_iCurFore = m_iCurBack;
+ m_iCurBack = auxClr;
+ }
+ break;
+ case KVI_TEXT_CRYPTESCAPE:
+ case KVI_TEXT_ICON:
+ // makes a single block
+ break;
+ case KVI_TEXT_COLOR:
+ {
+ idx++;
+ if(idx >= ((int)(m_szTextBuffer.length())))return;
+ unsigned char fore;
+ unsigned char back;
+ idx = getUnicodeColorBytes(m_szTextBuffer,idx,&fore,&back);
+ if(fore != KVI_NOCHANGE)
+ {
+ m_iCurFore = fore;
+ if(back != KVI_NOCHANGE)m_iCurBack = back;
+ } else {
+ // ONLY a CTRL+K
+ m_iCurBack = KVI_INPUT_DEF_BACK;
+ m_iCurFore = KVI_INPUT_DEF_FORE;
+ }
+ }
+ break;
+ default:
+ debug("Ops..");
+ exit(0);
+ break;
+ }
+ }
+}
+
+void KviInputEditor::runUpToTheFirstVisibleChar()
+{
+ register int idx = 0;
+ while(idx < m_iFirstVisibleChar)
+ {
+ unsigned short c = m_szTextBuffer[idx].unicode();
+ if(c < 32)
+ {
+ switch(c)
+ {
+ case KVI_TEXT_BOLD:
+ m_bCurBold = ! m_bCurBold;
+ break;
+ case KVI_TEXT_UNDERLINE:
+ m_bCurUnderline = ! m_bCurUnderline;
+ break;
+ case KVI_TEXT_RESET:
+ m_iCurFore = KVI_INPUT_DEF_FORE;
+ m_iCurBack = KVI_INPUT_DEF_BACK;
+ m_bCurBold = false;
+ m_bCurUnderline = false;
+ break;
+ case KVI_TEXT_REVERSE:
+ {
+ char auxClr = m_iCurFore;
+ m_iCurFore = m_iCurBack;
+ m_iCurBack = auxClr;
+ }
+ break;
+ case KVI_TEXT_COLOR:
+ {
+ idx++;
+ if(idx >= ((int)(m_szTextBuffer.length())))return;
+ unsigned char fore;
+ unsigned char back;
+ idx = getUnicodeColorBytes(m_szTextBuffer,idx,&fore,&back);
+ idx--;
+ if(fore != KVI_NOCHANGE)m_iCurFore = fore;
+ else m_iCurFore = KVI_INPUT_DEF_FORE;
+ if(back != KVI_NOCHANGE)m_iCurBack = back;
+ else m_iCurBack = KVI_INPUT_DEF_BACK;
+ }
+ break;
+ case 0:
+ debug("KviInputEditor::Encountered invisible end of the string!");
+ exit(0);
+ break;
+ }
+ }
+ idx++;
+ }
+}
+
+
+void KviInputEditor::mousePressEvent(QMouseEvent *e)
+{
+ if(e->button() & Qt::LeftButton)
+ {
+ m_iCursorPosition = charIndexFromXPosition(e->pos().x());
+ //move the cursor to
+ int anchorX = xPositionFromCharIndex(m_iCursorPosition);
+ if(anchorX > (width()-frameWidth()))m_iFirstVisibleChar++;
+ m_iSelectionAnchorChar = m_iCursorPosition;
+ selectOneChar(-1);
+ //grabMouse(QCursor(crossCursor));
+ repaintWithCursorOn();
+ killDragTimer();
+ m_iDragTimer = startTimer(KVI_INPUT_DRAG_TIMEOUT);
+
+ } else if(e->button() & Qt::RightButton)
+ {
+ int type = g_pActiveWindow->type();
+
+ //Popup menu
+ g_pInputPopup->clear();
+
+ QString szClip;
+
+ QClipboard * c = QApplication::clipboard();
+ if(c)
+ {
+ szClip = c->text(QClipboard::Clipboard);
+
+#ifdef COMPILE_USE_QT4
+ int occ = szClip.count(QChar('\n'));
+#else
+ int occ = szClip.contains(QChar('\n'));
+#endif
+
+ if(!szClip.isEmpty())
+ {
+ if(szClip.length() > 60)
+ {
+ szClip.truncate(60);
+ szClip.append("...");
+ }
+ szClip.replace(QChar('&'),"&amp;");
+ szClip.replace(QChar('<'),"&lt;");
+ szClip.replace(QChar('>'),"&gt;");
+ szClip.replace(QChar('\n'),"<br>");
+
+ QString label = "<center><b>";
+ label += __tr2qs("Clipboard");
+ label += ":</b><br>";
+ label += szClip;
+ label += "<br><b>";
+
+ QString num;
+ num.setNum(occ);
+
+ label += num;
+ label += QChar(' ');
+ label += (occ == 1) ? __tr2qs("line break") : __tr2qs("line breaks");
+ label += "</b></center>";
+
+ QLabel * l = new QLabel(label,g_pInputPopup);
+ l->setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
+ l->setMargin(5);
+ // FIXME: This does NOT work under Qt 4.x (they seem to consider it as bad UI design)
+#ifndef COMPILE_USE_QT4
+ g_pInputPopup->insertItem(l);
+#else
+ delete l;
+#endif
+ }
+ }
+
+ int id = g_pInputPopup->insertItem(__tr2qs("Cu&t") + ACCEL_KEY(X),this,SLOT(cut()));
+ g_pInputPopup->setItemEnabled(id,hasSelection());
+ id = g_pInputPopup->insertItem(__tr2qs("&Copy") + ACCEL_KEY(C),this,SLOT(copyToClipboard()));
+ g_pInputPopup->setItemEnabled(id,hasSelection());
+ id = g_pInputPopup->insertItem(__tr2qs("&Paste") + ACCEL_KEY(V),this,SLOT(pasteClipboardWithConfirmation()));
+ g_pInputPopup->setItemEnabled(id,!szClip.isEmpty() && !m_bReadOnly);
+ id = g_pInputPopup->insertItem(__tr2qs("Paste (Slowly)"),this,SLOT(pasteSlow()));
+ if ((type == KVI_WINDOW_TYPE_CHANNEL) || (type == KVI_WINDOW_TYPE_QUERY) || (type == KVI_WINDOW_TYPE_DCCCHAT))
+ g_pInputPopup->setItemEnabled(id,!szClip.isEmpty() && !m_bReadOnly);
+ else
+ g_pInputPopup->setItemEnabled(id,false);
+ id = g_pInputPopup->insertItem(__tr2qs("Paste &File") + ACCEL_KEY(F),this,SLOT(pasteFile()));
+ if ((type != KVI_WINDOW_TYPE_CHANNEL) && (type != KVI_WINDOW_TYPE_QUERY) && (type != KVI_WINDOW_TYPE_DCCCHAT))
+ g_pInputPopup->setItemEnabled(id,false);
+ else
+ g_pInputPopup->setItemEnabled(id,!m_bReadOnly);
+ if(m_bSpSlowFlag ==true)
+ {
+ id = g_pInputPopup->insertItem(__tr2qs("Stop Paste"),this,SLOT(stopPasteSlow())); /*G&N 2005*/
+ }
+ id = g_pInputPopup->insertItem(__tr2qs("Clear"),this,SLOT(clear()));
+ g_pInputPopup->setItemEnabled(id,!m_szTextBuffer.isEmpty() && !m_bReadOnly);
+ g_pInputPopup->insertSeparator();
+ id = g_pInputPopup->insertItem(__tr2qs("Select All"),this,SLOT(selectAll()));
+ g_pInputPopup->setItemEnabled(id,(!m_szTextBuffer.isEmpty()));
+
+
+ g_pInputPopup->insertSeparator();
+ m_pIconMenu->clear();
+
+ KviPointerHashTable<QString,KviTextIcon> * d = g_pTextIconManager->textIconDict();
+ KviPointerHashTableIterator<QString,KviTextIcon> it(*d);
+ QStringList strList;
+ while(KviTextIcon * i = it.current())
+ {
+ strList.append(it.currentKey());
+ ++it;
+ }
+ strList.sort();
+ KviTextIcon * icon;
+ QPixmap *pix;
+
+ for(QStringList::Iterator iter = strList.begin(); iter != strList.end(); ++iter)
+ {
+ icon=g_pTextIconManager->lookupTextIcon(*iter);
+ if(icon)
+ {
+ pix = icon->pixmap();
+ if(pix) m_pIconMenu->insertItem(*pix,*iter);
+ }
+ }
+
+ g_pInputPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_BIGGRIN)),__tr2qs("Insert Icon"),m_pIconMenu);
+ g_pInputPopup->popup(mapToGlobal(e->pos()));
+ } else {
+ pasteSelectionWithConfirmation();
+ }
+}
+void KviInputEditor::iconPopupActivated(int id)
+{
+ if(!m_bReadOnly)
+ {
+ QString text = m_pIconMenu->text(id);
+ if(!text.isEmpty())
+ {
+ text.prepend(KVI_TEXT_ICON);
+ text.append(' ');
+ insertText(text);
+ }
+ }
+}
+
+bool KviInputEditor::hasSelection()
+{
+ return ((m_iSelectionBegin != -1)&&(m_iSelectionEnd != -1));
+}
+
+void KviInputEditor::copyToClipboard()
+{
+ if(!hasSelection())return;
+ QClipboard * c = QApplication::clipboard();
+ if(!c)return;
+ QString szTxt = m_szTextBuffer.mid(m_iSelectionBegin,(m_iSelectionEnd-m_iSelectionBegin)+1);
+ c->setText(szTxt,QClipboard::Clipboard);
+ repaintWithCursorOn();
+}
+
+void KviInputEditor::copyToSelection(bool bDonNotCopyToClipboard)
+{
+ if(!hasSelection())return;
+ QClipboard * c = QApplication::clipboard();
+ if(!c)return;
+ QString szTxt = m_szTextBuffer.mid(m_iSelectionBegin,(m_iSelectionEnd-m_iSelectionBegin)+1);
+ if(c->supportsSelection())
+ c->setText(szTxt,QClipboard::Selection);
+ else if(!bDonNotCopyToClipboard)
+ c->setText(szTxt,QClipboard::Clipboard);
+ repaintWithCursorOn();
+}
+
+
+void KviInputEditor::moveCursorTo(int idx,bool bRepaint)
+{
+ if(idx < 0)idx = 0;
+ if(idx > ((int)(m_szTextBuffer.length())))idx = m_szTextBuffer.length();
+ if(idx > m_iCursorPosition)
+ {
+ while(m_iCursorPosition < idx)
+ {
+ moveRightFirstVisibleCharToShowCursor();
+ m_iCursorPosition++;
+ }
+ } else {
+ m_iCursorPosition = idx;
+ if(m_iFirstVisibleChar > m_iCursorPosition)m_iFirstVisibleChar = m_iCursorPosition;
+ }
+ if(bRepaint)repaintWithCursorOn();
+}
+
+void KviInputEditor::removeSelected()
+{
+ if(!hasSelection())return;
+ m_szTextBuffer.remove(m_iSelectionBegin,(m_iSelectionEnd-m_iSelectionBegin)+1);
+ moveCursorTo(m_iSelectionBegin,false);
+ selectOneChar(-1);
+ repaintWithCursorOn();
+}
+
+void KviInputEditor::cut()
+{
+ if(!hasSelection())return;
+ QClipboard * c = QApplication::clipboard();
+ if(!c)return;
+ c->setText(m_szTextBuffer.mid(m_iSelectionBegin,(m_iSelectionEnd-m_iSelectionBegin)+1),QClipboard::Clipboard);
+ m_szTextBuffer.remove(m_iSelectionBegin,(m_iSelectionEnd-m_iSelectionBegin)+1);
+ moveCursorTo(m_iSelectionBegin,false);
+ selectOneChar(-1);
+ repaintWithCursorOn();
+}
+
+void KviInputEditor::insertText(const QString &text)
+{
+ QString szText = text; // crop away constness
+ if(szText.isEmpty())return;
+
+ //szText.replaceAll('\t'," "); //Do not paste tabs
+
+ //szText.replace(QRegExp("\t")," "); // do not paste tabs
+
+ m_bUpdatesEnabled = false;
+ removeSelected();
+ m_bUpdatesEnabled = true;
+
+ if(szText.find('\n') == -1)
+ {
+ m_szTextBuffer.insert(m_iCursorPosition,szText);
+ m_szTextBuffer.truncate(m_iMaxBufferSize);
+ moveCursorTo(m_iCursorPosition + szText.length());
+ } else {
+ //Multiline paste...do not execute commands here
+ QString szBlock;
+ while(!szText.isEmpty())
+ {
+ int idx = szText.find('\n');
+ if(idx != -1)
+ {
+ szBlock = szText.left(idx);
+ //else szBlock = QChar(KVI_TEXT_RESET);
+ szText.remove(0,idx+1);
+ } else {
+ szBlock = szText;
+ szText = "";
+ }
+
+ m_szTextBuffer.insert(m_iCursorPosition,szBlock);
+ m_szTextBuffer.truncate(m_iMaxBufferSize);
+
+ int pos = 0;
+ while((pos < ((int)(m_szTextBuffer.length()))) && (m_szTextBuffer[pos] < 33))pos++;
+ if((pos < ((int)(m_szTextBuffer.length()))) && (m_szTextBuffer[pos] == QChar('/')))m_szTextBuffer.insert(pos,"\\");
+
+ returnPressed(idx != -1);
+ }
+ }
+}
+
+// Replace (length) characters in the buffer from (start) with (text), returns
+// the length of the text inserted (different from text.length() only if the
+// buffer was truncated.
+int KviInputEditor::replaceSegment(int start, int length, const QString &text)
+{
+ m_szTextBuffer.remove(start, length);
+ m_szTextBuffer.insert(start, text);
+ m_szTextBuffer.truncate(m_iMaxBufferSize);
+ repaintWithCursorOn();
+
+ int iInsertedLength = text.length();
+ int iMaxInsertedLength = m_iMaxBufferSize - start;
+ if(iInsertedLength > iMaxInsertedLength) return iMaxInsertedLength;
+ return iInsertedLength;
+}
+
+void KviInputEditor::pasteClipboardWithConfirmation()
+{
+ QClipboard * c = QApplication::clipboard();
+ if(!c)return;
+ QString szText = c->text(QClipboard::Clipboard);
+
+ if(szText.contains(QChar('\n')) > 0)
+ {
+ if(m_pInputParent->inherits("KviInput"))
+ ((KviInput*)(m_pInputParent))->multiLinePaste(szText);
+ } else {
+ insertText(szText);
+ }
+}
+
+void KviInputEditor::pasteSelectionWithConfirmation()
+{
+ QClipboard * c = QApplication::clipboard();
+ if(!c)return;
+ QString szText = c->text(c->supportsSelection() ? QClipboard::Selection : QClipboard::Clipboard);
+
+ if(szText.contains(QChar('\n')) > 0)
+ {
+ if(m_pInputParent->inherits("KviInput"))
+ ((KviInput*)(m_pInputParent))->multiLinePaste(szText);
+ } else {
+ insertText(szText);
+ }
+}
+
+void KviInputEditor::pasteSlow()
+{
+ KviKvsScript::run("spaste.clipboard",g_pActiveWindow);
+ m_bSpSlowFlag = true;
+}
+
+void KviInputEditor::stopPasteSlow()
+{
+ KviKvsScript::run("spaste.stop",g_pActiveWindow);
+ m_bSpSlowFlag = false;
+}
+
+void KviInputEditor::pasteFile()
+{
+ QString stmp = QFileDialog::getOpenFileName("","",this,"Paste File", "Choose a file" );
+ if(stmp!="")
+ {
+ QString stmp1 = "spaste.file " + stmp ;
+ KviKvsScript::run(stmp1,g_pActiveWindow);
+ m_bSpSlowFlag = true;
+ }
+}
+
+void KviInputEditor::selectAll()
+{
+ if(m_szTextBuffer.length() > 0)
+ {
+ m_iSelectionBegin = 0;
+ m_iSelectionEnd = m_szTextBuffer.length()-1;
+ }
+ end();
+}
+
+void KviInputEditor::clear()
+{
+ m_szTextBuffer = "";
+ selectOneChar(-1);
+ home();
+}
+
+void KviInputEditor::setText(const QString text)
+{
+ m_szTextBuffer = text;
+ m_szTextBuffer.truncate(m_iMaxBufferSize);
+ selectOneChar(-1);
+ end();
+}
+
+void KviInputEditor::mouseReleaseEvent(QMouseEvent *)
+{
+ if(m_iDragTimer)
+ {
+ m_iSelectionAnchorChar =-1;
+ //releaseMouse();
+ killDragTimer();
+ }
+ if(hasSelection())
+ copyToSelection();
+}
+
+void KviInputEditor::killDragTimer()
+{
+ if(m_iDragTimer)
+ {
+ killTimer(m_iDragTimer);
+ m_iDragTimer = 0;
+ }
+}
+
+void KviInputEditor::timerEvent(QTimerEvent *e)
+{
+ if(e->timerId() == m_iCursorTimer)
+ {
+ if(!hasFocus() || !isVisibleToTLW())
+ {
+ killTimer(m_iCursorTimer);
+ m_iCursorTimer = 0;
+ m_bCursorOn = false;
+ } else m_bCursorOn = ! m_bCursorOn;
+ update();
+ } else {
+ //Drag timer
+ handleDragSelection();
+ }
+}
+
+void KviInputEditor::handleDragSelection()
+{
+ if(m_iSelectionAnchorChar == -1)return;
+
+ QPoint pnt = mapFromGlobal(QCursor::pos());
+
+
+ if(pnt.x() <= 0)
+ {
+ //Left side dragging
+ if(m_iFirstVisibleChar > 0)m_iFirstVisibleChar--;
+ m_iCursorPosition = m_iFirstVisibleChar;
+ } else if(pnt.x() >= width())
+ {
+ //Right side dragging...add a single character to the selection on the right
+ if(m_iCursorPosition < ((int)(m_szTextBuffer.length())))
+ {
+ moveRightFirstVisibleCharToShowCursor();
+ m_iCursorPosition++;
+ } //else at the end of the selection...don't move anything
+ } else {
+ //Inside the window...
+ m_iCursorPosition = charIndexFromXPosition(pnt.x());
+ }
+ if(m_iCursorPosition == m_iSelectionAnchorChar)selectOneChar(-1);
+ else {
+ if(m_iCursorPosition > m_iSelectionAnchorChar)
+ {
+ m_iSelectionBegin = m_iSelectionAnchorChar;
+ m_iSelectionEnd = m_iCursorPosition-1;
+ } else {
+ m_iSelectionBegin = m_iCursorPosition;
+ m_iSelectionEnd = m_iSelectionAnchorChar-1;
+ }
+ }
+ repaintWithCursorOn();
+}
+
+void KviInputEditor::returnPressed(bool bRepaint)
+{
+ if (!m_szTextBuffer.isEmpty() /* && (!m_pHistory->current() || m_szTextBuffer.compare(*(m_pHistory->current())))*/)
+ {
+ if(m_pInputParent->inherits("KviInput"))
+ g_pInputHistory->add(new QString(m_szTextBuffer));
+
+ m_pHistory->insert(0,new QString(m_szTextBuffer));
+ }
+
+ __range_valid(KVI_INPUT_MAX_LOCAL_HISTORY_ENTRIES > 1); //ABSOLUTELY NEEDED, if not, pHist will be destroyed...
+ if(m_pHistory->count() > KVI_INPUT_MAX_LOCAL_HISTORY_ENTRIES)m_pHistory->removeLast();
+
+ m_iCurHistoryIdx = -1;
+
+ // FIXME: ALL THIS STUFF SHOULD BE CONVERTED TO QString
+ /*
+ if(m_pInputParent->inherits("KviInput"))
+ {
+ QString szBuffer(m_szTextBuffer);
+ m_szTextBuffer="";
+ selectOneChar(-1);
+ m_iCursorPosition = 0;
+ m_iFirstVisibleChar = 0;
+ if(bRepaint)repaintWithCursorOn();
+ KviUserInput::parse(szBuffer,m_pKviWindow);
+ } else {
+ */
+ emit enterPressed();
+ /*
+ return;
+ }
+ */
+}
+
+void KviInputEditor::focusInEvent(QFocusEvent *)
+{
+ if(m_iCursorTimer==0)
+ {
+ m_iCursorTimer = startTimer(KVI_INPUT_BLINK_TIME);
+ m_bCursorOn = true;
+ update();
+ }
+ // XIM handling...
+#ifndef COMPILE_USE_QT4
+ // THIS SEEMS TO BE GONE IN Qt4.x ? (even if the documentation states that it *should* be there)
+ setMicroFocusHint(1,1,width() - 2,height() - 2,true,0);
+#endif
+}
+
+void KviInputEditor::focusOutEvent(QFocusEvent *)
+{
+ if(m_iCursorTimer)killTimer(m_iCursorTimer);
+ m_iCursorTimer = 0;
+ m_bCursorOn = false;
+ update();
+}
+
+
+void KviInputEditor::internalCursorRight(bool bShift)
+{
+ if(m_iCursorPosition >= ((int)(m_szTextBuffer.length())))return;
+ moveRightFirstVisibleCharToShowCursor();
+ //Grow the selection if needed
+ if(bShift)
+ {
+ if((m_iSelectionBegin > -1)&&(m_iSelectionEnd > -1))
+ {
+ if(m_iSelectionEnd == m_iCursorPosition-1)m_iSelectionEnd++;
+ else if(m_iSelectionBegin == m_iCursorPosition)m_iSelectionBegin++;
+ else selectOneChar(m_iCursorPosition);
+ } else selectOneChar(m_iCursorPosition);
+ } else selectOneChar(-1);
+ m_iCursorPosition++;
+}
+
+void KviInputEditor::internalCursorLeft(bool bShift)
+{
+ if(m_iCursorPosition <= 0)return;
+
+ if(bShift)
+ {
+ if((m_iSelectionBegin > -1)&&(m_iSelectionEnd > -1))
+ {
+ if(m_iSelectionBegin == m_iCursorPosition)m_iSelectionBegin--;
+ else if(m_iSelectionEnd == m_iCursorPosition-1)m_iSelectionEnd--;
+ else selectOneChar(m_iCursorPosition - 1);
+ } else selectOneChar(m_iCursorPosition - 1);
+ } else selectOneChar(-1);
+
+ m_iCursorPosition--;
+ if(m_iFirstVisibleChar > m_iCursorPosition)m_iFirstVisibleChar--;
+}
+
+// remember the text before and after the cursor at this point, and put them
+// before and after the text inserted by IM in imEndEvent.
+// hagabaka
+void KviInputEditor::imStartEvent(QIMEvent *e)
+{
+ removeSelected();
+ m_iIMStart = m_iIMSelectionBegin = m_iCursorPosition;
+ m_iIMLength = 0;
+ m_bIMComposing = true;
+ e->accept();
+}
+
+// Whenever the IM's preedit changes, update the visuals and internal data. refer to <http://doc.trolltech.com/3.3/qimevent.html> */
+// hagabaka
+void KviInputEditor::imComposeEvent(QIMEvent *e)
+{
+ // replace the old pre-edit string with e->text()
+ m_bUpdatesEnabled = false;
+#ifdef COMPILE_USE_QT4
+ // Qt 4.x ??????????
+ m_iIMLength = replaceSegment(m_iIMStart, m_iIMLength, e->commitString());
+
+ // update selection inside the pre-edit
+ m_iIMSelectionBegin = m_iIMStart + e->replacementStart();
+ m_iIMSelectionLength = e->replacementLength();
+ moveCursorTo(m_iIMSelectionBegin);
+
+#else
+ m_iIMLength = replaceSegment(m_iIMStart, m_iIMLength, e->text());
+
+ // update selection inside the pre-edit
+ m_iIMSelectionBegin = m_iIMStart + e->cursorPos();
+ m_iIMSelectionLength = e->selectionLength();
+ moveCursorTo(m_iIMSelectionBegin);
+#endif
+
+
+ // repaint
+ m_bUpdatesEnabled = true;
+ repaintWithCursorOn();
+ e->accept();
+}
+
+// Input method is done; put its resulting text to where the preedit area was
+// hagabaka
+void KviInputEditor::imEndEvent(QIMEvent *e)
+{
+ // replace the preedit area with the IM result text
+ m_bUpdatesEnabled = false;
+#ifdef COMPILE_USE_QT4
+ // Qt 4.x ??????????
+ m_iIMLength = replaceSegment(m_iIMStart, m_iIMLength, e->commitString());
+#else
+ m_iIMLength = replaceSegment(m_iIMStart, m_iIMLength, e->text());
+#endif
+
+ // move cursor to after the IM result text
+ moveCursorTo(m_iIMStart + m_iIMLength);
+
+ // repaint
+ m_bUpdatesEnabled = true;
+ repaintWithCursorOn();
+
+ // reset data
+ m_bIMComposing = false;
+ e->accept();
+}
+
+// FIXME According to <http://www.kde.gr.jp/~asaki/how-to-support-input-method.html>, if the XIM
+// style used is OverTheTop, code needs to be added in keyPressEvent handler */
+// hagabaka
+void KviInputEditor::keyPressEvent(QKeyEvent *e)
+{
+ // disable the keyPress handling when IM is in composition.
+ if(m_bIMComposing)
+ {
+ e->ignore();
+ return;
+ }
+ // completion thingies
+
+ if(!m_bReadOnly)
+ {
+ if((e->key() == Qt::Key_Tab) || (e->key() == Qt::Key_BackTab))
+ {
+ completion(e->state() & Qt::ShiftButton);
+ return;
+ } else {
+ m_bLastCompletionFinished=1;
+ }
+ }
+
+
+ if(e->key() == Qt::Key_Escape)
+ {
+ emit escapePressed();
+ return;
+ }
+
+ if((e->state() & Qt::AltButton) || (e->state() & Qt::ControlButton))
+ {
+ switch(e->key())
+ {
+ case Qt::Key_Backspace:
+ if(m_pInputParent->inherits("KviInput"))
+ {
+ ((KviInput*)(m_pInputParent))->multiLinePaste(m_szTextBuffer);
+ clear();
+ return;
+ }
+ break;
+ }
+ }
+
+//Make CtrlKey and CommandKey ("Apple") behave equally on MacOSX.
+//This way typical X11 and Apple shortcuts can be used simultanously within the input line.
+#ifndef Q_OS_MACX
+ if(e->state() & Qt::ControlButton)
+#else
+ if((e->state() & Qt::ControlButton) || (e->state() & Qt::MetaButton))
+#endif
+ {
+ switch(e->key())
+ {
+ case Qt::Key_Right:
+ if(m_iCursorPosition < ((int)(m_szTextBuffer.length())))
+ {
+ // skip whitespace
+ while(m_iCursorPosition < ((int)(m_szTextBuffer.length())))
+ {
+ if(!m_szTextBuffer.at(m_iCursorPosition).isSpace())break;
+ internalCursorRight(e->state() & Qt::ShiftButton);
+ }
+ // skip nonwhitespace
+ while(m_iCursorPosition < ((int)(m_szTextBuffer.length())))
+ {
+ if(m_szTextBuffer.at(m_iCursorPosition).isSpace())break;
+ internalCursorRight(e->state() & Qt::ShiftButton);
+ }
+ repaintWithCursorOn();
+ }
+ break;
+ case Qt::Key_Left:
+ if(m_iCursorPosition > 0)
+ {
+ // skip whitespace
+ while(m_iCursorPosition > 0)
+ {
+ if(!m_szTextBuffer.at(m_iCursorPosition - 1).isSpace())break;
+ internalCursorLeft(e->state() & Qt::ShiftButton);
+ }
+ // skip nonwhitespace
+ while(m_iCursorPosition > 0)
+ {
+ if(m_szTextBuffer.at(m_iCursorPosition - 1).isSpace())break;
+ internalCursorLeft(e->state() & Qt::ShiftButton);
+ }
+ repaintWithCursorOn();
+ }
+ break;
+ case Qt::Key_K:
+ {
+ if(!m_bReadOnly)
+ {
+ insertChar(KVI_TEXT_COLOR);
+ int xPos = xPositionFromCharIndex(m_iCursorPosition);
+ if(xPos > 24)xPos-=24;
+ if(!g_pColorWindow)g_pColorWindow = new KviColorWindow();
+ if(xPos+g_pColorWindow->width() > width())xPos = width()-(g_pColorWindow->width()+2);
+ g_pColorWindow->move(mapToGlobal(QPoint(xPos,-35)));
+ g_pColorWindow->popup(this);
+ }
+ }
+ break;
+ case Qt::Key_B:
+ if(!m_bReadOnly) insertChar(KVI_TEXT_BOLD);
+ break;
+ case Qt::Key_O:
+ if(!m_bReadOnly) insertChar(KVI_TEXT_RESET);
+ break;
+ case Qt::Key_U:
+ if(!m_bReadOnly) insertChar(KVI_TEXT_UNDERLINE);
+ break;
+ case Qt::Key_R:
+ if(!m_bReadOnly) insertChar(KVI_TEXT_REVERSE);
+ break;
+ case Qt::Key_P:
+ if(!m_bReadOnly) insertChar(KVI_TEXT_CRYPTESCAPE); // DO NOT CRYPT THIS STUFF
+ break;
+ case Qt::Key_I:
+ {
+ if(!m_bReadOnly)
+ {
+ insertChar(KVI_TEXT_ICON); // THE NEXT WORD IS AN ICON NAME
+ int xPos = xPositionFromCharIndex(m_iCursorPosition);
+ if(xPos > 24)xPos-=24;
+ if(!g_pTextIconWindow)g_pTextIconWindow = new KviTextIconWindow();
+ if(xPos+g_pTextIconWindow->width() > width())xPos = width()-(g_pTextIconWindow->width()+2);
+ g_pTextIconWindow->move(mapToGlobal(QPoint(xPos,-KVI_TEXTICON_WIN_HEIGHT)));
+ g_pTextIconWindow->popup(this);
+ }
+ }
+ break;
+ case Qt::Key_C:
+ copyToClipboard();
+ break;
+ case Qt::Key_X:
+ if(!m_bReadOnly) cut();
+ break;
+ case Qt::Key_V:
+ if(!m_bReadOnly) pasteClipboardWithConfirmation();
+ break;
+ //case Qt::Key_Backspace:
+ case Qt::Key_W:
+ if(m_iCursorPosition > 0 && !m_bReadOnly && !hasSelection())
+ {
+ // skip whitespace
+ while(m_iCursorPosition > 0)
+ {
+ if(!m_szTextBuffer.at(m_iCursorPosition - 1).isSpace())break;
+ m_szTextBuffer.remove(m_iCursorPosition-1,1);
+ m_iCursorPosition--;
+ if(m_iFirstVisibleChar > m_iCursorPosition)m_iFirstVisibleChar--;
+ }
+ // skip nonwhitespace
+ while(m_iCursorPosition > 0)
+ {
+ if(m_szTextBuffer.at(m_iCursorPosition - 1).isSpace())break;
+ m_szTextBuffer.remove(m_iCursorPosition-1,1);
+ m_iCursorPosition--;
+ if(m_iFirstVisibleChar > m_iCursorPosition)m_iFirstVisibleChar--;
+ }
+ repaintWithCursorOn();
+ }
+ break;
+ case Qt::Key_PageUp:
+ if(KVI_OPTION_BOOL(KviOption_boolDisableInputHistory)) break;
+ if(m_pInputParent->inherits("KviInput"))
+ ((KviInput*)(m_pInputParent))->historyButtonClicked();
+ break;
+ case Qt::Key_F:
+ if(m_pKviWindow)
+ if(m_pKviWindow->view())m_pKviWindow->view()->toggleToolWidget();
+ break;
+ case Qt::Key_A:
+ m_iSelectionBegin=0;
+ m_iSelectionEnd=m_szTextBuffer.length()-1;
+ m_iCursorPosition=m_szTextBuffer.length();
+ repaintWithCursorOn();
+ break;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ if(m_pInputParent->inherits("KviInput"))
+ {
+ QString szBuffer(m_szTextBuffer);
+ m_szTextBuffer="";
+ selectOneChar(-1);
+ m_iCursorPosition = 0;
+ m_iFirstVisibleChar = 0;
+ repaintWithCursorOn();
+ KviUserInput::parseNonCommand(szBuffer,m_pKviWindow);
+ if (!szBuffer.isEmpty())
+ {
+ g_pInputHistory->add(new QString(szBuffer));
+ m_pHistory->insert(0,new QString(szBuffer));
+ }
+
+ __range_valid(KVI_INPUT_MAX_LOCAL_HISTORY_ENTRIES > 1); //ABSOLUTELY NEEDED, if not, pHist will be destroyed...
+ if(m_pHistory->count() > KVI_INPUT_MAX_LOCAL_HISTORY_ENTRIES)m_pHistory->removeLast();
+
+ m_iCurHistoryIdx = -1;
+ }
+ break;
+ default:
+ if(!m_bReadOnly) insertText(e->text());
+ break;
+ }
+ return;
+ }
+
+ if((e->state() & Qt::AltButton) && (e->state() & Qt::Keypad))
+ {
+ // Qt::Key_Meta seems to substitute Qt::Key_Alt on some keyboards
+ if((e->key() == Qt::Key_Alt) || (e->key() == Qt::Key_Meta))
+ {
+ m_szAltKeyCode = "";
+ return;
+ } else if((e->ascii() >= '0') && (e->ascii() <= '9'))
+ {
+ m_szAltKeyCode += e->ascii();
+ return;
+ }
+
+ //debug("%c",e->ascii());
+ if(!m_bReadOnly) {
+ insertText(e->text());
+ }
+ return;
+ }
+
+ if(e->state() & Qt::ShiftButton)
+ {
+ switch(e->key())
+ {
+ case Qt::Key_Insert:
+ if(!m_bReadOnly) pasteClipboardWithConfirmation();
+ return;
+ break;
+ case Qt::Key_PageUp:
+ if(m_pKviWindow)
+ if(m_pKviWindow->view())m_pKviWindow->view()->prevLine();
+ return;
+ break;
+ case Qt::Key_PageDown:
+ if(m_pKviWindow)
+ if(m_pKviWindow->view())m_pKviWindow->view()->nextLine();
+ return;
+ break;
+ }
+ }
+
+ switch(e->key())
+ {
+ case Qt::Key_Right:
+ if(m_iCursorPosition < ((int)(m_szTextBuffer.length())))
+ {
+ internalCursorRight(e->state() & Qt::ShiftButton);
+ repaintWithCursorOn();
+ }
+ break;
+ case Qt::Key_Left:
+ if(m_iCursorPosition > 0)
+ {
+ internalCursorLeft(e->state() & Qt::ShiftButton);
+ repaintWithCursorOn();
+ }
+ break;
+ case Qt::Key_Backspace:
+ if(!m_bReadOnly)
+ {
+ if(hasSelection() && (m_iSelectionEnd >= m_iCursorPosition-1) && (m_iSelectionBegin <= m_iCursorPosition))
+ {
+ //remove the selection
+ m_szTextBuffer.remove(m_iSelectionBegin,(m_iSelectionEnd-m_iSelectionBegin)+1);
+ m_iCursorPosition = m_iSelectionBegin;
+ if(m_iFirstVisibleChar > m_iCursorPosition)m_iFirstVisibleChar = m_iCursorPosition;
+ } else if(m_iCursorPosition > 0) {
+ m_iCursorPosition--;
+ m_szTextBuffer.remove(m_iCursorPosition,1);
+ if(m_iFirstVisibleChar > m_iCursorPosition)m_iFirstVisibleChar--;
+ }
+ selectOneChar(-1);
+ repaintWithCursorOn();
+ }
+ break;
+ case Qt::Key_Delete:
+ if(!m_bReadOnly)
+ {
+ if(hasSelection()) removeSelected();
+ else if(m_iCursorPosition < (int)m_szTextBuffer.length())
+ {
+ m_szTextBuffer.remove(m_iCursorPosition,1);
+ selectOneChar(-1);
+ repaintWithCursorOn();
+ }
+ }
+ break;
+ case Qt::Key_Home:
+ if(m_iCursorPosition > 0)
+ {
+ if(e->state() & Qt::ShiftButton)
+ {
+ if((m_iSelectionBegin == -1)&&(m_iSelectionEnd == -1))m_iSelectionEnd = m_iCursorPosition - 1;
+ m_iSelectionBegin = 0;
+ } else {
+ selectOneChar(-1);
+ }
+ home();
+ }
+ break;
+ case Qt::Key_End://we should call it even the cursor is at the end for deselecting
+ if(e->state() & Qt::ShiftButton)
+ {
+ if((m_iSelectionBegin == -1)&&(m_iSelectionEnd == -1))m_iSelectionBegin = m_iCursorPosition;
+ m_iSelectionEnd = m_szTextBuffer.length()-1;
+ } else {
+ selectOneChar(-1);
+ }
+ end();
+ break;
+ case Qt::Key_Up:
+ if(!m_bReadOnly)
+ {
+ if(m_pHistory->count() > 0)
+ {
+ if(m_iCurHistoryIdx < 0)
+ {
+ m_szSaveTextBuffer = m_szTextBuffer;
+ m_szTextBuffer = *(m_pHistory->at(0));
+ m_iCurHistoryIdx = 0;
+ } else if(m_iCurHistoryIdx >= (int)(m_pHistory->count()-1))
+ {
+ m_szTextBuffer=m_szSaveTextBuffer;
+ m_iCurHistoryIdx = -1;
+ } else {
+ m_iCurHistoryIdx++;
+ m_szTextBuffer = *(m_pHistory->at(m_iCurHistoryIdx));
+ }
+ selectOneChar(-1);
+ if(KVI_OPTION_BOOL(KviOption_boolInputHistoryCursorAtEnd))end();
+ else home();
+ }
+ }
+ break;
+ case Qt::Key_Down:
+ if(!m_bReadOnly)
+ {
+ if(m_pHistory->count() > 0)
+ {
+ if(m_iCurHistoryIdx < 0)
+ {
+ m_szSaveTextBuffer = m_szTextBuffer;
+ m_szTextBuffer = *(m_pHistory->at(m_pHistory->count()-1));
+ m_iCurHistoryIdx =m_pHistory->count()-1;
+ } else if(m_iCurHistoryIdx == 0)
+ {
+ m_szTextBuffer=m_szSaveTextBuffer;
+ m_iCurHistoryIdx = -1;
+ } else {
+ m_iCurHistoryIdx--;
+ m_szTextBuffer = *(m_pHistory->at(m_iCurHistoryIdx));
+ }
+ selectOneChar(-1);
+ if(KVI_OPTION_BOOL(KviOption_boolInputHistoryCursorAtEnd))end();
+ else home();
+ }
+ }
+ break;
+ case Qt::Key_PageUp:
+ if(m_pKviWindow)
+ if(m_pKviWindow->view())m_pKviWindow->view()->prevPage();
+ break;
+ case Qt::Key_PageDown:
+ if(m_pKviWindow)
+ if(m_pKviWindow->view())m_pKviWindow->view()->nextPage();
+ break;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ returnPressed();
+ break;
+ case Qt::Key_Alt:
+ case Qt::Key_Meta:
+ m_szAltKeyCode = "";
+ break;
+ default:
+ if(!e->text().isEmpty() && !m_bReadOnly)
+ insertText(e->text());
+ break;
+ }
+}
+
+void KviInputEditor::keyReleaseEvent(QKeyEvent *e)
+{
+ if((e->key() == Qt::Key_Alt) || (e->key() == Qt::Key_Meta))
+ {
+ if(m_szAltKeyCode.hasData())
+ {
+ bool bOk;
+ unsigned short ch = m_szAltKeyCode.toUShort(&bOk);
+ if(bOk && ch != 0)
+ {
+ //debug("INSERTING CHAR %d",ch);
+ insertChar(QChar(ch));
+ e->accept();
+ }
+ }
+ m_szAltKeyCode = "";
+ }
+ e->ignore();
+}
+
+void KviInputEditor::getWordBeforeCursor(QString &buffer,bool * bIsFirstWordInLine)
+{
+ if(m_szTextBuffer.isEmpty() || m_iCursorPosition <= 0)
+ {
+ buffer = "";
+ return;
+ }
+
+ buffer = m_szTextBuffer.left(m_iCursorPosition);
+
+ int idx = buffer.findRev(' ');
+ int idx2 = buffer.findRev(','); // This is for comma separated lists...
+ int idx3 = buffer.findRev('(');
+ int idx4 = buffer.findRev('"');
+ if(idx2 > idx)idx = idx2;
+ if(idx3 > idx)idx = idx3;
+ if(idx4 > idx)idx = idx4;
+ *bIsFirstWordInLine = false;
+ if(idx > -1)buffer.remove(0,idx+1);
+ else *bIsFirstWordInLine = true;
+}
+
+void KviInputEditor::completion(bool bShift)
+{
+ // FIXME: Spaces in directory completion can mess everything completely
+ // On windows the KVI_PATH_SEPARATOR_CHARacters are breaking everything...
+ // Well.... :D
+
+ QString word;
+ QString match;
+
+ bool bFirstWordInLine;
+ getWordBeforeCursor(word,&bFirstWordInLine);
+ if(word.isEmpty())
+ {
+ if(m_szLastCompletedNick.isEmpty())return; // nothing to complete
+ else {
+ // this is standard nick completion continued
+ standardNickCompletion(bShift,word,bFirstWordInLine);
+ repaintWithCursorOn();
+ return;
+ }
+ }
+ KviPointerList<QString> tmp;
+ tmp.setAutoDelete(true);
+
+ bool bIsCommand = false;
+ bool bIsDir = false;
+ bool bIsNick = false;
+
+ unsigned short uc = word[0].unicode();
+
+ if(uc == '/')
+ {
+ if(bFirstWordInLine)
+ {
+ // command completion
+ word.remove(0,1);
+ if(word.isEmpty())return;
+ KviKvsKernel::instance()->completeCommand(word,&tmp);
+ bIsCommand = true;
+ } else {
+ // directory completion attempt
+ g_pApp->completeDirectory(word,&tmp);
+ bIsDir = true;
+ }
+ } else if(uc == '$')
+ {
+ // function/identifer completion
+ word.remove(0,1);
+ if(word.isEmpty())return;
+ KviKvsKernel::instance()->completeFunction(word,&tmp);
+ } else if(uc == '#' || uc == '&' || uc == '!')
+ {
+ if(m_pKviWindow)
+ {
+ if( (word.length()==1) && (m_pKviWindow->windowName()[0].unicode()==uc))
+ {
+ match=m_pKviWindow->windowName();
+ match.append(" ");
+ replaceWordBeforeCursor(word,match,false);
+ repaintWithCursorOn();
+ return;
+ } else {
+ if(m_pKviWindow->console())
+ m_pKviWindow->console()->completeChannel(word,&tmp);
+ }
+ }
+
+ //FIXME: Complete also on irc:// starting strings, not only irc.?
+ } else if(KviQString::equalCIN(word,"irc.",4))
+ {
+ // irc server name
+ if(m_pKviWindow)
+ if(m_pKviWindow->console())
+ m_pKviWindow->console()->completeServer(word,&tmp);
+ } else {
+ // empty word will end up here
+ if(m_pUserListView)
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolBashLikeNickCompletion))
+ {
+ m_pUserListView->completeNickBashLike(word,&tmp,bShift);
+ bIsNick = true;
+ } else {
+ standardNickCompletion(bShift,word,bFirstWordInLine);
+ repaintWithCursorOn();
+ return;
+ }
+ }
+ }
+
+ // Lookup the longest exact match
+
+ if(tmp.count() > 0)
+ {
+ if(tmp.count() == 1)
+ {
+ match = *(tmp.first());
+ if(bIsCommand)match.append(' ');
+ else if(bIsNick)
+ {
+ if(!KVI_OPTION_STRING(KviOption_stringNickCompletionPostfix).isEmpty())
+ {
+ if(bFirstWordInLine || (!KVI_OPTION_BOOL(KviOption_boolUseNickCompletionPostfixForFirstWordOnly)))
+ match.append(KVI_OPTION_STRING(KviOption_stringNickCompletionPostfix));
+ }
+ }
+ } else {
+ QString all;
+ QString * s = tmp.first();
+ match = *s;
+ int wLen = word.length();
+ for(;s;s = tmp.next())
+ {
+ if(s->length() < match.length())
+ match.remove(s->length(),match.length() - s->length());
+ // All the matches here have length >= word.len()!!!
+ const QChar * b1 = KviQString::nullTerminatedArray(*s) + wLen;
+ const QChar * b2 = KviQString::nullTerminatedArray(match) + wLen;
+ const QChar * c1 = b1;
+ const QChar * c2 = b2;
+ if(bIsDir)while(c1->unicode() && (c1->unicode() == c2->unicode()))c1++,c2++;
+ else while(c1->unicode() && (c1->lower().unicode() == c2->lower().unicode()))c1++,c2++;
+ int len = wLen + (c1 - b1);
+ if(len < ((int)(match.length())))match.remove(len,match.length() - len);
+ if(!all.isEmpty())all.append(", ");
+ all.append(*s);
+ }
+ if(m_pKviWindow)
+ m_pKviWindow->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("%d matches: %Q"),tmp.count(),&all);
+ }
+ } else
+ if(m_pKviWindow)
+ m_pKviWindow->outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("No matches"));
+
+ if(!match.isEmpty())
+ {
+ //if(!bIsDir && !bIsNick)match = match.lower(); <-- why? It is nice to have
+ // $module.someFunctionName instad
+ // of unreadable $module.somefunctionfame
+ replaceWordBeforeCursor(word,match,false);
+ }
+
+ repaintWithCursorOn();
+}
+
+void KviInputEditor::replaceWordBeforeCursor(const QString &word,const QString &replacement,bool bRepaint)
+{
+ selectOneChar(-1);
+ m_iCursorPosition -= word.length();
+ m_szTextBuffer.remove(m_iCursorPosition,word.length());
+ m_szTextBuffer.insert(m_iCursorPosition,replacement);
+ m_szTextBuffer.truncate(m_iMaxBufferSize);
+ moveCursorTo(m_iCursorPosition + replacement.length());
+ if(bRepaint)repaintWithCursorOn();
+}
+
+void KviInputEditor::standardNickCompletion(bool bAddMask,QString &word,bool bFirstWordInLine)
+{
+ // FIXME: this could be really simplified...
+ if(!m_pUserListView)return;
+ selectOneChar(-1);
+
+ QString buffer;
+ if(m_szLastCompletedNick.isEmpty())
+ {
+ // New completion session: we NEED sth to complete
+ if(word.isEmpty())return;
+ if(m_pUserListView->completeNickStandard(word,m_szLastCompletedNick,buffer,bAddMask))
+ {
+ // completed: save the buffer
+ m_szLastCompletionBuffer = m_szTextBuffer;
+ m_iLastCompletionCursorPosition = m_iCursorPosition;
+ m_iLastCompletionCursorXPosition = m_iLastCursorXPosition;
+ m_iLastCompletionFirstVisibleChar = m_iFirstVisibleChar;
+ m_szLastCompletedNick = buffer;
+ if(!KVI_OPTION_STRING(KviOption_stringNickCompletionPostfix).isEmpty())
+ {
+ if(bFirstWordInLine || (!KVI_OPTION_BOOL(KviOption_boolUseNickCompletionPostfixForFirstWordOnly)))
+ buffer.append(KVI_OPTION_STRING(KviOption_stringNickCompletionPostfix));
+ }
+ replaceWordBeforeCursor(word,buffer,false);
+ m_bLastCompletionFinished=0;
+ // REPAINT CALLED FROM OUTSIDE!
+ } // else no match at all
+ } else if(!m_bLastCompletionFinished) {
+ // Old session
+ // swap the buffers
+ m_szTextBuffer = m_szLastCompletionBuffer;
+ m_iCursorPosition = m_iLastCompletionCursorPosition;
+ m_iLastCursorXPosition = m_iLastCompletionCursorXPosition;
+ m_iFirstVisibleChar = m_iLastCompletionFirstVisibleChar;
+ // re-extract
+ //word = m_szTextBuffer.left(m_iCursorPosition);
+
+ getWordBeforeCursor(word,&bFirstWordInLine);
+ if(word.isEmpty())return;
+ if(m_pUserListView->completeNickStandard(word,m_szLastCompletedNick,buffer,bAddMask))
+ {
+ // completed
+ m_szLastCompletedNick = buffer;
+ if(!KVI_OPTION_STRING(KviOption_stringNickCompletionPostfix).isEmpty())
+ {
+ if(bFirstWordInLine || (!KVI_OPTION_BOOL(KviOption_boolUseNickCompletionPostfixForFirstWordOnly)))
+ buffer.append(KVI_OPTION_STRING(KviOption_stringNickCompletionPostfix));
+ }
+ replaceWordBeforeCursor(word,buffer,false);
+ m_bLastCompletionFinished=0;
+ // REPAINT CALLED FROM OUTSIDE!
+ } else {
+ m_bLastCompletionFinished=1;
+ m_szLastCompletedNick = "";
+ }
+ } else {
+ // Old session finished
+ // re-extract
+ //word = m_szTextBuffer.left(m_iCursorPosition);
+ //getWordBeforeCursor(word,&bFirstWordInLine);
+ if(word.isEmpty())return;
+ if(m_pUserListView->completeNickStandard(word,"",buffer,bAddMask))
+ {
+ // completed
+ m_szLastCompletionBuffer = m_szTextBuffer;
+ m_iLastCompletionCursorPosition = m_iCursorPosition;
+ m_iLastCompletionCursorXPosition = m_iLastCursorXPosition;
+ m_iLastCompletionFirstVisibleChar = m_iFirstVisibleChar;
+ m_szLastCompletedNick = buffer;
+ if(!KVI_OPTION_STRING(KviOption_stringNickCompletionPostfix).isEmpty())
+ {
+ if(bFirstWordInLine || (!KVI_OPTION_BOOL(KviOption_boolUseNickCompletionPostfixForFirstWordOnly)))
+ buffer.append(KVI_OPTION_STRING(KviOption_stringNickCompletionPostfix));
+ }
+ replaceWordBeforeCursor(word,buffer,false);
+ m_bLastCompletionFinished=0;
+ // REPAINT CALLED FROM OUTSIDE!
+ } else {
+ m_bLastCompletionFinished=1;
+ m_szLastCompletedNick = "";
+ }
+ }
+}
+
+
+//Funky helpers
+
+void KviInputEditor::end()
+{
+ m_iLastCursorXPosition = frameWidth();
+ m_iCursorPosition = 0;
+ m_iFirstVisibleChar = 0;
+ while(m_iCursorPosition < ((int)(m_szTextBuffer.length())))
+ {
+ moveRightFirstVisibleCharToShowCursor();
+ m_iCursorPosition++;
+ }
+ repaintWithCursorOn();
+}
+
+void KviInputEditor::home()
+{
+ m_iFirstVisibleChar = 0;
+ m_iCursorPosition = 0;
+ repaintWithCursorOn();
+}
+
+void KviInputEditor::insertChar(QChar c)
+{
+ if(m_szTextBuffer.length() >= m_iMaxBufferSize)return;
+
+ // Kill the selection
+ if((m_iSelectionBegin > -1) || (m_iSelectionEnd > -1))
+ {
+ if((m_iCursorPosition >= m_iSelectionBegin) && (m_iCursorPosition <= m_iSelectionEnd))
+ {
+ m_bUpdatesEnabled = false;
+ removeSelected();
+ m_bUpdatesEnabled = true;
+ }
+ }
+ selectOneChar(-1);
+ m_szTextBuffer.insert(m_iCursorPosition,c);
+ moveRightFirstVisibleCharToShowCursor();
+ m_iCursorPosition++;
+ repaintWithCursorOn();
+}
+
+void KviInputEditor::moveRightFirstVisibleCharToShowCursor()
+{
+ // :)
+ QFontMetrics fm(KVI_OPTION_FONT(KviOption_fontInput));
+
+ QChar c = m_szTextBuffer.at(m_iCursorPosition);
+
+#ifdef COMPILE_USE_QT4
+ m_iLastCursorXPosition += c.unicode() < 32 ? fm.width(getSubstituteChar(c.unicode())) + 3 : fm.width(c);;
+#else
+ m_iLastCursorXPosition += (c.unicode() < 256) ? g_iInputFontCharWidth[c.unicode()] : fm.width(c);
+#endif
+ while(m_iLastCursorXPosition >= contentsRect().width()-2*KVI_INPUT_MARGIN)
+ {
+ c = m_szTextBuffer.at(m_iFirstVisibleChar);
+#ifdef COMPILE_USE_QT4
+ m_iLastCursorXPosition -= c.unicode() < 32 ? fm.width(getSubstituteChar(c.unicode())) + 3 : fm.width(c);;
+#else
+ m_iLastCursorXPosition -= (c.unicode() < 256) ? g_iInputFontCharWidth[c.unicode()] : fm.width(c);
+#endif
+ m_iFirstVisibleChar++;
+ }
+}
+
+void KviInputEditor::repaintWithCursorOn()
+{
+ // :)
+ if(m_bUpdatesEnabled)
+ {
+ m_bCursorOn = true;
+ update();
+ }
+}
+
+void KviInputEditor::selectOneChar(int pos)
+{
+ m_iSelectionBegin = pos;
+ m_iSelectionEnd = pos;
+}
+
+int KviInputEditor::charIndexFromXPosition(int xPos)
+{
+ int curXPos = frameWidth()+KVI_INPUT_MARGIN;
+ int curChar = m_iFirstVisibleChar;
+ int bufLen = m_szTextBuffer.length();
+
+ QFontMetrics fm(KVI_OPTION_FONT(KviOption_fontInput));
+ while(curChar < bufLen)
+ {
+ QChar c = m_szTextBuffer.at(curChar);
+#ifdef COMPILE_USE_QT4
+ int widthCh = c.unicode() < 32 ? fm.width(getSubstituteChar(c.unicode())) + 3 : fm.width(c);;
+#else
+ int widthCh = (c.unicode() < 256) ? g_iInputFontCharWidth[c.unicode()] : fm.width(c);
+#endif
+ if(xPos < (curXPos+(widthCh/2)))return curChar;
+ else if(xPos < (curXPos+widthCh))return (curChar+1);
+ {
+ curXPos+=widthCh;
+ curChar++;
+ }
+ }
+ return curChar;
+}
+
+int KviInputEditor::xPositionFromCharIndex(QFontMetrics& fm,int chIdx,bool bContentsCoords)
+{
+ // FIXME: this could use fm.width(m_szTextBuffer,chIdx)
+ int curXPos = bContentsCoords ? KVI_INPUT_MARGIN : frameWidth()+KVI_INPUT_MARGIN;
+ int curChar = m_iFirstVisibleChar;
+ while(curChar < chIdx)
+ {
+ QChar c = m_szTextBuffer.at(curChar);
+#ifdef COMPILE_USE_QT4
+ curXPos += c.unicode() < 32 ? fm.width(getSubstituteChar(c.unicode())) + 3 : fm.width(c);;
+#else
+ curXPos += (c.unicode() < 256) ? g_iInputFontCharWidth[c.unicode()] : fm.width(c);
+#endif
+ curChar++;
+ }
+ return curXPos;
+}
+
+int KviInputEditor::xPositionFromCharIndex(int chIdx,bool bContentsCoords)
+{
+ // FIXME: this could use fm.width(m_szTextBuffer,chIdx)
+ int curXPos = bContentsCoords ? KVI_INPUT_MARGIN : frameWidth()+KVI_INPUT_MARGIN;
+ int curChar = m_iFirstVisibleChar;
+ //debug("%i",g_pLastFontMetrics);
+ if(!g_pLastFontMetrics) g_pLastFontMetrics = new QFontMetrics(KVI_OPTION_FONT(KviOption_fontInput));
+ while(curChar < chIdx)
+ {
+ QChar c = m_szTextBuffer.at(curChar);
+#ifdef COMPILE_USE_QT4
+ curXPos += c.unicode() < 32 ? g_pLastFontMetrics->width(getSubstituteChar(c.unicode())) + 3 : g_pLastFontMetrics->width(c);
+#else
+ curXPos += (c.unicode() < 256) ? g_iInputFontCharWidth[c.unicode()] : g_pLastFontMetrics->width(c);
+#endif
+ curChar++;
+ }
+ return curXPos;
+}
+
+/*
+ @doc: texticons
+ @type:
+ generic
+ @title:
+ The KVIrc TextIcons extension
+ @short:
+ The KVIrc TextIcons extension
+ @body:
+ Starting from version 3.0.0 KVIrc supports the TextIcon extension
+ to the standard IRC protocol. It is a mean for sending text enriched
+ of small images without sending the images themselves.[br]
+ The idea is quite simple: the IRC client (and it's user) associates
+ some small images to text strings (called icon tokens) and the strings are sent
+ in place of the images preceeded by a special escape character.[br]
+ The choosen escape character is 29 (hex 0x1d) which corresponds
+ to the ASCII group separator.[br]
+ So for example if a client has the association of the icon token "rose" with a small
+ icon containing a red rose flower then KVIrc could send the string
+ "&lt;0x1d&gt;rose" in the message stream to ask the remote parties to
+ display such an icon. If the remote parties don't have this association
+ then they will simply strip the control code and display the string "rose",
+ (eventually showing it in some enchanced way).[br]
+ The icon tokens can't contain spaces
+ so the receiving clients stop the extraction of the icon strings
+ when a space, an icon escape or the message termination is encountered.
+ [br]
+ &lt;icon escape&gt; := character 0x1d (ASCII group separator)[br]
+ &lt;icon token&gt; := any character with the exception of 0x1d, CR,LF and SPACE.[br]
+ [br]
+ Please note that this is a KVIrc extension and the remote clients
+ that don't support this feature will not display the icon (and will
+ eventually show the 0x1d character in the data stream).[br]
+ If you like this feature please either convince the remote users
+ to try KVIrc or tell them to write to their client developers asking
+ for this simple feature to be implemented.[br]
+*/
+
+
+/*
+ @doc: commandline
+ @title:
+ The Commandline Input Features
+ @type:
+ generic
+ @short:
+ Commandline input features
+ @body:
+ [big]Principles of operation[/big]
+ [p]
+ The idea is simple: anything that starts with a slash (/) character
+ is interpreted as a command. Anything else is plain text that is
+ sent to the target of the window (channel, query, dcc chat etc..).
+ [/p]
+ [big]The two operating modes[/big]
+ [p]
+ The commandline input has two operating modes: the "user friendly mode" and
+ the "kvs mode". In the user friendly mode all the parameters of the commands
+ are interpreted exactly like you type them. There is no special interpretation
+ of $,%,-,( and ; characters. This allows you to type "/me is happy ;)", for example.
+ In the kvs mode the full parameter interpretation is enabled and the commands
+ work just like in any other script editor. This means that anything that
+ starts with a $ is a function call, anything that starts with a % is a variable,
+ the dash characters after command names are interpreted as switches and ; is the
+ command separator. This in turn does NOT allow you to type "/me is happy ;)"
+ because ; is the command separator and ) will be interpreted as the beginning
+ of the next command. In KVS mode you obviously have to escape the ; character
+ by typing "/me is happy \;)". The user friendly mode is good for everyday chatting
+ and for novice users while the KVS mode is for experts that know that minimum about
+ scripting languages. Please note that in the user-friendly mode you're not allowed
+ to type multiple commands at once :).
+ [/p]
+ [big]Default Key Bindings:[/big][br]
+ Ctrl+B: Inserts the 'bold' mIRC text control character<br>
+ Ctrl+K: Inserts the 'color' mIRC text control character<br>
+ Ctrl+R: Inserts the 'reverse' mIRC text control character<br>
+ Ctrl+U: Inserts the 'underline' mIRC text control character<br>
+ Ctrl+O: Inserts the 'reset' mIRC text control character<br>
+ Ctrl+P: Inserts the 'non-crypt' (plain text) KVIrc control character used to disable encryption of the current text line<br>
+ Ctrl+C: Copies the selected text to clipboard<br>
+ Ctrl+X: Cuts the selected text<br>
+ Ctrl+V: Pastes the clipboard contents (same as middle mouse click)<br>
+ Ctrl+I: Inserts the 'icon' control code and pops up the icon list box<br>
+ Ctrl+A: Select all<br>
+ CursorUp: Moves backward in the command history<br>
+ CursorDown: Moves forward in the command history<br>
+ CursorRight: Moves the cursor to the right<br>
+ CursorLeft: Moves the cursor to the left :)<br>
+ Shift+CursorLeft: Moves the selection to the left<br>
+ Shift+RightCursor: Moves the selection to the right<br>
+ Ctrl+CursorLeft: Moves the cursor one word left<br>
+ Ctrl+CursorRight: Moves the cursor one word right<br>
+ Ctrl+Shift+CursorLeft: Moves the selection one word left<br>
+ Ctrl+Shift+CursorRight: Moves the selection one word right<br>
+ Tab: Nickname, function/command, or filename completion (see below)<br>
+ Shift+Tab: Hostmask or function/command completion (see below)<br>
+ Alt+&lt;numeric_sequence&gt;: Inserts the character by ASCII/Unicode code<br>
+ <example>
+ Alt+32: Inserts ASCII/Unicode character 32: ' ' (a space)
+ Alt+00032: Same as above :)
+ Alt+13: Inserts the Carriage Return (CR) control character
+ Alt+77: Inserts ASCII/Unicode character 77: 'M'
+ Alt+23566: Inserts Unicode character 23566 (an ideogram)
+ </example>
+ Also look at the <a href="shortcuts.kvihelp">global shortcuts</a> reference.<br>
+ If you drop a file on this widget, a <a href="parse.kvihelp">/PARSE &lt;filename&gt;</a> will be executed.<br>
+ You can enable word substitution in the preferences dialog.<br>
+ For example, if you choose to substitute "afaik" with "As far as I know",<br>
+ when you will type "afaik" somewhere in the command line, and then
+ press Space or Return, that word will be replaced with "As far as I know".<br>
+ Experiment with it :)<br>
+ The Tab key activates the completion of the current word.<br>
+ If a word is prefixed with a '/', it is treated as a command to be completed,
+ if it begins with '$', it is treated as a function or identifier to be completed,
+ otherwise it is treated as a nickname or filename to be completed.<br>
+ <example>
+ /ec&lt;Tab&gt; will produce /echo&lt;space&gt
+ /echo $loca&lt;Tab&gt; will produce /echo $localhost
+ </example>
+ Multiple matches are listed in the view window and the word is completed
+ to the common part of all the matches.<br>
+ <example>
+ $sel&lt;Tab;&gt; will find multiple matches and produce $selected
+ </example>
+ Experiment with that too :)
+*/
+
+
+
+KviInput::KviInput(KviWindow *par,KviUserListView * view)
+: QWidget(par,"input")
+{
+ QBoxLayout* pLayout=new QHBoxLayout(this);
+ pLayout->setAutoAdd(true);
+ pLayout->setDirection(QBoxLayout::RightToLeft);
+
+ pLayout->setMargin(0);
+ pLayout->setSpacing(0);
+
+ m_pWindow = par;
+ m_pMultiLineEditor = 0;
+
+ m_pHideToolsButton = new KviStyledToolButton(this,"hide_container_button");
+
+ m_pHideToolsButton->setUsesBigPixmap(false);
+ m_pHideToolsButton->setFixedWidth(10);
+
+ if(g_pIconManager->getBigIcon("kvi_horizontal_left.png"))
+ m_pHideToolsButton->setPixmap(*(g_pIconManager->getBigIcon("kvi_horizontal_left.png")));
+
+ connect(m_pHideToolsButton,SIGNAL(clicked()),this,SLOT(toggleToolButtons()));
+
+ m_pButtonContainer=new KviTalHBox(this);
+ m_pButtonContainer->setSpacing(0);
+
+#ifdef COMPILE_USE_QT4
+ m_pButtonContainer->setSizePolicy(QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Preferred));
+// if(m_pButtonContainer->layout())
+// m_pButtonContainer->layout()->setSizeConstraint(QLayout::SetMinimumSize);
+#endif
+
+ m_pHistoryButton = new KviStyledToolButton(m_pButtonContainer,"historybutton");
+ m_pHistoryButton->setUsesBigPixmap(false);
+ //m_pHistoryButton->setUpdatesEnabled(TRUE); ???
+ QIconSet is1;
+ if(!KVI_OPTION_BOOL(KviOption_boolDisableInputHistory))//G&N mar 2005
+ {
+ is1.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),QIconSet::Small);
+ m_pHistoryButton->setIconSet(is1);
+ KviTalToolTip::add(m_pHistoryButton,__tr2qs("Show History<br>&lt;Ctrl+PageUp&gt;"));
+ connect(m_pHistoryButton,SIGNAL(clicked()),this,SLOT(historyButtonClicked()));
+ }
+ else
+ {
+ is1.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUITSPLIT)),QIconSet::Small);
+ m_pHistoryButton->setIconSet(is1);
+ KviTalToolTip::add(m_pHistoryButton,__tr2qs("Input History Disabled"));
+ }
+
+ m_pIconButton = new KviStyledToolButton(m_pButtonContainer,"iconbutton");
+ m_pIconButton->setUsesBigPixmap(false);
+ QIconSet is3;
+ is3.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_BIGGRIN)),QIconSet::Small);
+ m_pIconButton->setIconSet(is3);
+ KviTalToolTip::add(m_pIconButton,__tr2qs("Show Icons Popup<br>&lt;Ctrl+I&gt;<br>See also /help texticons"));
+
+ connect(m_pIconButton,SIGNAL(clicked()),this,SLOT(iconButtonClicked()));
+
+
+ m_pCommandlineModeButton = new KviStyledToolButton(m_pButtonContainer,"commandlinemodebutton");
+ m_pCommandlineModeButton->setUsesBigPixmap(false);
+ m_pCommandlineModeButton->setToggleButton(true);
+ QIconSet is0;
+ is0.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SAYSMILE)),QIconSet::Small,QIconSet::Normal,QIconSet::On);
+ is0.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SAYKVS)),QIconSet::Small,QIconSet::Normal,QIconSet::Off);
+ m_pCommandlineModeButton->setIconSet(is0);
+ KviTalToolTip::add(m_pCommandlineModeButton,__tr2qs("User friendly commandline mode<br>See also /help commandline"));
+ if(KVI_OPTION_BOOL(KviOption_boolCommandlineInUserFriendlyModeByDefault))
+ m_pCommandlineModeButton->setOn(true);
+
+
+ m_pMultiEditorButton = new KviStyledToolButton(m_pButtonContainer,"multieditorbutton");
+ m_pMultiEditorButton->setToggleButton(true);
+ m_pMultiEditorButton->setUsesBigPixmap(false);
+ QIconSet is2;
+ is2.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TERMINAL)),QIconSet::Small,QIconSet::Normal,QIconSet::On);
+ is2.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TERMINAL)),QIconSet::Small,QIconSet::Normal,QIconSet::Off);
+ m_pMultiEditorButton->setIconSet(is2);
+ QString szTip = __tr2qs("Multi-line Editor<br>&lt;Alt+Backspace&gt;");
+ szTip += " - &lt;Ctrl+Backspace&gt;";
+ KviTalToolTip::add(m_pMultiEditorButton,szTip);
+
+ connect(m_pMultiEditorButton,SIGNAL(toggled(bool)),this,SLOT(multilineEditorButtonToggled(bool)));
+
+ m_pInputEditor = new KviInputEditor(this,par,view);
+ connect(m_pInputEditor,SIGNAL(enterPressed()),this,SLOT(inputEditorEnterPressed()));
+#ifdef COMPILE_USE_QT4
+ m_pInputEditor->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Ignored));
+#else
+ m_pInputEditor->setSizePolicy(QSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored));
+#endif
+
+
+#ifdef COMPILE_USE_QT4
+ m_pMultiEditorButton->setAutoRaise(true);
+ m_pCommandlineModeButton->setAutoRaise(true);
+ m_pIconButton->setAutoRaise(true);
+ m_pHistoryButton->setAutoRaise(true);
+ m_pHideToolsButton->setAutoRaise(true);
+#endif
+
+ pLayout->setStretchFactor(m_pInputEditor,100000);
+ pLayout->setStretchFactor(m_pButtonContainer,0);
+ pLayout->setStretchFactor(m_pHideToolsButton,0);
+}
+
+KviInput::~KviInput()
+{
+ if(m_pMultiLineEditor)KviScriptEditor::destroyInstance(m_pMultiLineEditor);
+}
+
+bool KviInput::isButtonsHidden()
+{
+ return m_pButtonContainer->isHidden();
+}
+
+void KviInput::setButtonsHidden(bool bHidden)
+{
+ if(!m_pHideToolsButton || !m_pButtonContainer) return;
+ if(bHidden==m_pButtonContainer->isHidden()) return;
+ m_pButtonContainer->setHidden(bHidden);
+ QPixmap* pix= bHidden ?
+ g_pIconManager->getBigIcon("kvi_horizontal_right.png") :
+ g_pIconManager->getBigIcon("kvi_horizontal_left.png");
+ if(pix)
+ m_pHideToolsButton->setPixmap(*pix);
+}
+
+void KviInput::toggleToolButtons()
+{
+ setButtonsHidden(!isButtonsHidden());
+}
+
+void KviInput::inputEditorEnterPressed()
+{
+ QString szText = m_pInputEditor->text();
+ KviUserInput::parse(szText,m_pWindow,QString::null,m_pCommandlineModeButton->isOn());
+ m_pInputEditor->setText("");
+}
+
+void KviInput::keyPressEvent(QKeyEvent *e)
+{
+ //debug("KviInput::keyPressEvent(key:%d,state:%d,text:%s)",e->key(),e->state(),e->text().isEmpty() ? "empty" : e->text().utf8().data());
+
+ if((e->state() & Qt::ControlButton) || (e->state() & Qt::AltButton) || (e->state() & Qt::MetaButton))
+ {
+ switch(e->key())
+ {
+ case Qt::Key_Backspace:
+ //if(m_pMultiLineEditor)
+ multilineEditorButtonToggled(!m_pMultiLineEditor);
+ break;
+ }
+ }
+
+ if(e->state() & Qt::ControlButton)
+ {
+ switch(e->key())
+ {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ {
+ if(m_pMultiLineEditor)
+ {
+ QString szText;
+ m_pMultiLineEditor->getText(szText);
+ if(szText.isEmpty())return;
+ if(KVI_OPTION_BOOL(KviOption_boolWarnAboutPastingMultipleLines))
+ {
+ if(szText.length() > 256)
+ {
+ if(szText[0] != '/')
+ {
+#ifdef COMPILE_USE_QT4
+ int nLines = szText.count('\n') + 1;
+#else
+ int nLines = szText.contains('\n') + 1;
+#endif
+ if(nLines > 15)
+ {
+ int nRet = QMessageBox::question(
+ this,
+ __tr2qs("Confirm Multiline Message"),
+ __tr2qs("You're about to send a message with %1 lines of text.<br><br>" \
+ "There is nothing wrong with it, this warning is<br>" \
+ "here to prevent you from accidentally sending<br>" \
+ "a really large message just because you didn't edit it<br>" \
+ "properly after pasting text from the clipboard.<br><br>" \
+ "Do you want the message to be sent?").arg(nLines),
+ __tr2qs("Yes, always"),
+ __tr2qs("Yes"),
+ __tr2qs("No"),
+ 1,2);
+ switch(nRet)
+ {
+ case 0:
+ KVI_OPTION_BOOL(KviOption_boolWarnAboutPastingMultipleLines) = false;
+ break;
+ case 2:
+ return;
+ break;
+ default: // also case 1
+ break;
+ }
+ }
+ }
+ }
+ }
+ KviUserInput::parse(szText,m_pWindow,QString::null,m_pCommandlineModeButton->isOn());
+ m_pMultiLineEditor->setText("");
+ }
+ }
+ break;
+ case Qt::Key_PageUp:
+ historyButtonClicked();
+ break;
+ }
+ }
+}
+
+void KviInput::multiLinePaste(const QString &text)
+{
+ if(!m_pMultiLineEditor)multilineEditorButtonToggled(true);
+ m_pMultiLineEditor->setText(text);
+}
+
+void KviInput::multilineEditorButtonToggled(bool bOn)
+{
+ if(m_pMultiLineEditor)
+ {
+ if(bOn)return;
+ KviScriptEditor::destroyInstance(m_pMultiLineEditor);
+ m_pMultiLineEditor = 0;
+ m_pInputEditor->show();
+ m_pWindow->childrenTreeChanged(0);
+ m_pInputEditor->setFocus();
+ m_pMultiEditorButton->setOn(false);
+ } else {
+ if(!bOn)return;
+ m_pMultiLineEditor = KviScriptEditor::createInstance(this);
+ QString szText = __tr2qs("<Ctrl+Return>; submits, <Alt+Backspace>; hides this editor");
+ // compatibility entry to avoid breaking translation just before a release... :)
+ szText.replace("Alt+Backspace","Ctrl+Backspace");
+ m_pMultiLineEditor->setFindText(szText);
+ m_pMultiLineEditor->setFindLineeditReadOnly(true);
+ m_pInputEditor->hide();
+ m_pMultiLineEditor->show();
+ m_pWindow->childrenTreeChanged(m_pMultiLineEditor);
+ m_pMultiLineEditor->setFocus();
+ m_pMultiEditorButton->setOn(true);
+ }
+}
+
+void KviInput::iconButtonClicked()
+{
+ if(!g_pTextIconWindow)g_pTextIconWindow = new KviTextIconWindow();
+ QPoint pnt = m_pIconButton->mapToGlobal(QPoint(m_pIconButton->width(),0));
+ g_pTextIconWindow->move(pnt.x()-g_pTextIconWindow->width(),pnt.y() - g_pTextIconWindow->height());
+ g_pTextIconWindow->popup(this,true);
+}
+
+void KviInput::historyButtonClicked()
+{
+ if(!g_pHistoryWindow)g_pHistoryWindow = new KviHistoryWindow();
+
+ QPoint pnt = mapToGlobal(QPoint(0,0));
+
+ g_pHistoryWindow->setGeometry(pnt.x(),pnt.y() - KVI_HISTORY_WIN_HEIGHT,width(),KVI_HISTORY_WIN_HEIGHT);
+ g_pHistoryWindow->popup(this);
+}
+
+#define BUTTON_WIDTH 20
+
+/*void KviInput::resizeEvent(QResizeEvent *e)
+{
+ //m_pButtonContainer
+ m_pInputEditor->setGeometry(0,0,m_pButtonContainer->isVisible() ? width() - (BUTTON_WIDTH * 4)-10 : width() - 10,height());
+ if(m_pMultiLineEditor)m_pMultiLineEditor->setGeometry(0,0,m_pButtonContainer->isVisible() ? width() - (BUTTON_WIDTH * 4)-10 : width() - 10,height());
+ if(m_pButtonContainer->isVisible()) m_pButtonContainer->setGeometry(width() - (BUTTON_WIDTH * 4)-10,0,BUTTON_WIDTH*4,height());
+
+ m_pHideToolsButton->setGeometry(width() - 10,0,10,height());
+
+ QWidget::resizeEvent(e);
+}*/
+
+void KviInput::setFocus()
+{
+ // redirect setFocus() to the right children
+ if(m_pMultiLineEditor)m_pMultiLineEditor->setFocus();
+ else m_pInputEditor->setFocus();
+}
+
+void KviInput::focusInEvent(QFocusEvent * e)
+{
+ // if we get a focus in event , redirect the focus to the children
+ if(m_pMultiLineEditor)m_pMultiLineEditor->setFocus();
+ else m_pInputEditor->setFocus();
+}
+
+
+int KviInput::heightHint() const
+{
+ return m_pMultiLineEditor ? 120 : m_pInputEditor->heightHint();
+}
+
+void KviInput::setText(const QString &text)
+{
+ // FIXME: Latin1 -> QString ?
+ if(m_pMultiLineEditor)m_pMultiLineEditor->setText(text);
+ else m_pInputEditor->setText(text);
+}
+
+void KviInput::insertChar(char c)
+{
+ m_pInputEditor->insertChar(c);
+}
+
+void KviInput::insertText(const QString& text)
+{
+ m_pInputEditor->insertText(text);
+}
+
+void KviInput::applyOptions()
+{
+ if(g_pLastFontMetrics) delete g_pLastFontMetrics;
+ g_pLastFontMetrics = 0;
+
+ if(KVI_OPTION_BOOL(KviOption_boolDisableInputHistory))//G&N mar 2005
+ {
+ QIconSet is1;
+ is1.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUITSPLIT)),QIconSet::Small);
+ m_pHistoryButton->setIconSet(is1);
+ KviTalToolTip::add(m_pHistoryButton,__tr2qs("Input History Disabled"));
+ m_pHistoryButton->disconnect(SIGNAL(clicked()));
+ }
+
+ if(!KVI_OPTION_BOOL(KviOption_boolDisableInputHistory))
+ {
+ QIconSet is1;
+ is1.setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),QIconSet::Small);
+ m_pHistoryButton->setIconSet(is1);
+ KviTalToolTip::add(m_pHistoryButton,__tr2qs("Show History<br>&lt;Ctrl+PageUp&gt;"));
+ connect(m_pHistoryButton,SIGNAL(clicked()),this,SLOT(historyButtonClicked()));
+ }
+
+ m_pInputEditor->applyOptions();
+}
+
+void KviInput::setFocusProxy(QWidget *)
+{
+ /* do nothing */
+}
+
+//const QString & KviInput::text()
+QString KviInput::text()
+{
+ QString szText;
+ if(m_pMultiLineEditor)
+ m_pMultiLineEditor->getText(szText);
+ else
+ szText=m_pInputEditor->text();
+ return szText;
+}
+
+#include "kvi_input.moc"
diff --git a/src/kvirc/ui/kvi_input.h b/src/kvirc/ui/kvi_input.h
new file mode 100644
index 0000000..56ec507
--- /dev/null
+++ b/src/kvirc/ui/kvi_input.h
@@ -0,0 +1,262 @@
+#ifndef _KVI_INPUT_H_
+#define _KVI_INPUT_H_
+
+//=============================================================================
+//
+// File : kvi_input.h
+// Creation date : Sun Jan 3 1999 23:04:10 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2007 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+
+#include <qwidget.h>
+#include "kvi_tal_hbox.h"
+#include <qpixmap.h>
+#include "kvi_pointerlist.h"
+
+#include "kvi_string.h"
+
+//#include <qdialog.h>
+#include <qtoolbutton.h>
+
+class KviUserListView;
+class KviWindow;
+class KviInput;
+class KviTalHBox;
+class QFontMetrics;
+
+// Default maximum buffer size.
+#define KVI_INPUT_MAX_BUFFER_SIZE 400
+// Border , better do not touch this
+#define KVI_INPUT_BORDER 1
+#define KVI_INPUT_MARGIN 2
+// Cursor blink time...just don't set it to a value less than 100 if
+// you don't want to be lagged by your cursors :)
+#define KVI_INPUT_BLINK_TIME 800
+// Drag scroll speed...(smaller values = faster)
+#define KVI_INPUT_DRAG_TIMEOUT 80
+// Maximum entries in the history buffer
+#define KVI_INPUT_MAX_HISTORY_ENTRIES 100
+
+class KVIRC_API KviInputHistory
+{
+public:
+ KviInputHistory();
+ ~KviInputHistory();
+protected:
+ KviPointerList<QString> * m_pStringList;
+public:
+ void add(QString * s);
+ KviPointerList<QString> * list(){ return m_pStringList; };
+ void save(const char * filename);
+ void load(const char * filename);
+};
+
+#ifdef COMPILE_USE_QT4
+ #define QIMEvent QInputMethodEvent
+#endif
+
+class KVIRC_API KviInputEditor : public QFrame
+{
+ // friend class KviUserParser;
+ //Q_PROPERTY( int KviProperty_FocusOwner READ heightHint )
+ Q_PROPERTY( int TransparencyCapable READ heightHint )
+
+ Q_OBJECT
+public:
+ KviInputEditor(QWidget * par,KviWindow *wnd,KviUserListView * view = 0);
+ ~KviInputEditor();
+protected:
+
+ QString m_szTextBuffer;
+ int m_iCursorPosition;
+ int m_iFirstVisibleChar;
+ int m_iSelectionBegin;
+ int m_iSelectionEnd;
+ int m_iMaxBufferSize;
+ bool m_bSpSlowFlag; // <-- what is this ?
+
+ // members for supporting input methods
+ QString m_szIMText;
+ int m_iIMStart;
+ int m_iIMLength;
+ int m_iIMSelectionBegin;
+ int m_iIMSelectionLength;
+ bool m_bIMComposing;
+
+ unsigned char m_iCurFore;
+ unsigned char m_iCurBack;
+ bool m_bCurBold;
+ bool m_bCurUnderline;
+
+ int m_iBlockLen;
+ int m_iBlockWidth;
+ bool m_bControlBlock;
+
+ bool m_bCursorOn;
+
+ int m_iCursorTimer;
+ int m_iDragTimer;
+
+ int m_iLastCursorXPosition;
+ int m_iSelectionAnchorChar;
+
+ // History stuff
+ KviPointerList<QString> * m_pHistory;
+ int m_iCurHistoryIdx;
+
+ KviStr m_szSaveTextBuffer;
+
+ // Nick completion
+ KviUserListView * m_pUserListView;
+ QString m_szLastCompletedNick;
+ QString m_szLastCompletionBuffer;
+ int m_iLastCompletionCursorPosition;
+ int m_iLastCompletionCursorXPosition;
+ int m_iLastCompletionFirstVisibleChar;
+ bool m_bLastCompletionFinished;
+
+ bool m_bUpdatesEnabled;
+ KviStr m_szAltKeyCode;
+ KviWindow * m_pKviWindow;
+ QWidget * m_pInputParent;
+ KviTalPopupMenu * m_pIconMenu;
+ bool m_bReadOnly;
+public:
+ int heightHint() const;
+ virtual QSize sizeHint() const;
+ void setText(const QString text);
+ QString text() { return m_szTextBuffer; };
+ void insertChar(QChar c);
+ void insertText(const QString &text);
+ void applyOptions();
+ void setMaxBufferSize(int size) { m_iMaxBufferSize = size; };
+ void setReadOnly(bool bReadOnly) {m_bReadOnly=bReadOnly; };
+ bool readOnly() {return m_bReadOnly; };
+private:
+ void replaceWordBeforeCursor(const QString &word,const QString &replacement,bool bRepaint = true);
+ int replaceSegment(int start, int length, const QString &string);
+ void getWordBeforeCursor(QString &buffer,bool * bIsFirstWordInLine);
+ void runUpToTheFirstVisibleChar();
+ void extractNextBlock(int idx,QFontMetrics & fm,int curXPos,int maxXPos);
+ void drawTextBlock(QPainter *pa,QFontMetrics & fm,int curXPos,int textBaseline,int idx,int len,bool bSelected=FALSE);
+ QChar getSubstituteChar(unsigned short control_code);
+ void moveRightFirstVisibleCharToShowCursor();
+ void repaintWithCursorOn();
+ void selectOneChar(int pos);
+ int charIndexFromXPosition(int xPos);
+ int xPositionFromCharIndex(QFontMetrics& fm,int chIdx,bool bContentsCoords=FALSE);
+ int xPositionFromCharIndex(int chIdx,bool bContentsCoords=FALSE);
+ void killDragTimer();
+ void handleDragSelection();
+ void end();
+ void home();
+ bool hasSelection();
+ void moveCursorTo(int idx,bool bRepaint = true);
+ void returnPressed(bool bRepaint = true);
+ void completion(bool bShift);
+ void standardNickCompletion(bool bAddMask,QString &word,bool bFirstWordInLine);
+ void recalcFontMetrics(QFontMetrics * pFm);
+ void internalCursorRight(bool bShift);
+ void internalCursorLeft(bool bShift);
+public slots:
+ void iconPopupActivated(int id);
+ void copyToSelection(bool bDonNotCopyToClipboard=true);
+ void copyToClipboard();
+ void removeSelected();
+ void cut();
+ void pasteClipboardWithConfirmation();
+ void pasteSelectionWithConfirmation();
+ void pasteSlow();
+ void stopPasteSlow();
+ void pasteFile();
+ void selectAll();
+ void clear();
+signals:
+ void escapePressed();
+ void enterPressed();
+protected:
+ virtual void drawContents(QPainter *);
+ //virtual void resizeEvent(QResizeEvent *);
+ virtual void timerEvent(QTimerEvent *e);
+ virtual void focusInEvent(QFocusEvent *);
+ virtual void focusOutEvent(QFocusEvent *);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void keyReleaseEvent(QKeyEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void dragEnterEvent(QDragEnterEvent *e);
+ virtual void dropEvent(QDropEvent *e);
+ virtual void imStartEvent(QIMEvent *e);
+ virtual void imComposeEvent(QIMEvent *e);
+ virtual void imEndEvent(QIMEvent *e);
+#ifdef COMPILE_USE_QT4
+ virtual void paintEvent(QPaintEvent *e);
+#endif
+};
+
+class KviScriptEditor;
+
+class KVIRC_API KviInput : public QWidget
+{
+ Q_OBJECT
+public:
+ KviInput(KviWindow *par,KviUserListView * view = 0);
+ ~KviInput();
+public:
+ KviWindow * m_pWindow;
+ KviInputEditor * m_pInputEditor;
+ KviScriptEditor * m_pMultiLineEditor;
+ KviTalHBox * m_pButtonContainer;
+ QToolButton * m_pMultiEditorButton;
+ QToolButton * m_pHistoryButton;
+ QToolButton * m_pIconButton;
+ QToolButton * m_pCommandlineModeButton;
+ QToolButton * m_pHideToolsButton;
+protected:
+// virtual void resizeEvent(QResizeEvent * e);
+ virtual void focusInEvent(QFocusEvent * e);
+ virtual void setFocusProxy(QWidget * w);
+ virtual void keyPressEvent(QKeyEvent * e);
+public slots:
+ void multilineEditorButtonToggled(bool bOn);
+ void historyButtonClicked();
+ void iconButtonClicked();
+ void inputEditorEnterPressed();
+ void toggleToolButtons();
+public:
+ virtual void setFocus();
+ void multiLinePaste(const QString &text);
+ bool isUserFriendly() { return m_pCommandlineModeButton->isOn(); };
+ void setUserFriendly(bool bSet) { m_pCommandlineModeButton->setOn(bSet); };
+ int heightHint() const;
+ void setText(const QString &text);
+ void insertChar(char c);
+ void insertText(const QString & text);
+ void applyOptions();
+ bool isButtonsHidden();
+ void setButtonsHidden(bool bHidden);
+ //const QString & text();
+ QString text();
+};
+
+#endif //_KVI_INPUT_H_
diff --git a/src/kvirc/ui/kvi_ipeditor.cpp b/src/kvirc/ui/kvi_ipeditor.cpp
new file mode 100644
index 0000000..13291c2
--- /dev/null
+++ b/src/kvirc/ui/kvi_ipeditor.cpp
@@ -0,0 +1,453 @@
+//
+// File : kvi_ipeditor.cpp
+// Creation date : Wed Jun 12 2000 14:16:49 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVIRC__
+#include "kvi_ipeditor.h"
+#include "kvi_qcstring.h"
+
+#include <qapplication.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qframe.h>
+#include <ctype.h>
+#include <qevent.h>
+
+
+// FIXME: #warning "THIS COULD GO INTO libkvioptions ?"
+
+KviIpEditor::KviIpEditor(QWidget * parent,AddressType addrType,const QString &ipAddr,const char *name)
+:QFrame(parent,name)
+{
+
+ for(int i=0;i<7;i++)
+ {
+ m_pEdit[i] = 0;
+ m_pLabel[i] = 0;
+ }
+ m_pEdit[7] = 0;
+ setFrameStyle(QFrame::Sunken|QFrame::StyledPanel);
+
+#ifdef COMPILE_USE_QT4
+ setBackgroundRole(QPalette::Base);
+#else
+ setBackgroundMode(QWidget::PaletteBase);
+#endif
+
+ setAddressType(addrType);
+
+ setAddress(ipAddr);
+}
+
+KviIpEditor::~KviIpEditor()
+{
+
+}
+
+void KviIpEditor::setEnabled(bool bEnabled)
+{
+ QFrame::setEnabled(bEnabled);
+ for(int i=0;i<8;i++)
+ {
+ if(m_pEdit[i])m_pEdit[i]->setEnabled(bEnabled);
+ if(i<7)if(m_pLabel[i])
+ {
+ // Is this the right way ?
+#ifdef COMPILE_USE_QT4
+ m_pLabel[i]->setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background);
+#else
+ m_pLabel[i]->setBackgroundMode(isEnabled() ? QWidget::PaletteBase : QWidget::PaletteBackground);
+#endif
+ m_pLabel[i]->setEnabled(bEnabled);
+ }
+ }
+#ifdef COMPILE_USE_QT4
+ setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background);
+#else
+ setBackgroundMode(isEnabled() ? QWidget::PaletteBase : QWidget::PaletteBackground);
+#endif
+}
+
+void KviIpEditor::setAddressType(AddressType addrType)
+{
+ if((addrType != IpV4) && (addrType != IpV6))m_addrType = IpV4;
+ else m_addrType = addrType;
+ recreateChildren();
+}
+
+KviIpEditor::AddressType KviIpEditor::addressType() const
+{
+ return m_addrType;
+}
+
+bool KviIpEditor::hasEmptyFields() const
+{
+ bool bHasEF = false;
+ for(int i=0;i<8;i++)
+ {
+ if(m_pEdit[i])
+ {
+ if(m_pEdit[i]->text().isEmpty())bHasEF = true;
+ }
+ }
+ return bHasEF;
+}
+
+void KviIpEditor::clear()
+{
+ if(!m_pEdit[0])return;
+ int maxW = (m_addrType == IpV4) ? 4 : 8;
+ for(int i=0;i< maxW ;i++)
+ {
+ m_pEdit[i]->setText("");
+ }
+}
+
+bool KviIpEditor::setAddress(const QString &ipAddr)
+{
+ // FIXME We could check if the addres
+ // is valid before effectively setting the fields
+ clear();
+
+ KviQCString ip = ipAddr.ascii(); // ip addresses are digits & latin letters abcdef (IpV6)
+
+ ip = ip.stripWhiteSpace();
+ const char * c = ip.data();
+
+ if(!c)return false; // huh ?....(should never happen at this point)
+
+ if(m_addrType == IpV4)
+ {
+ for(int i=0;i<4;i++)
+ {
+ const char *anchor = c;
+ while(isdigit(*c))c++;
+ if(c == anchor)return false; // Invalid empty field
+ KviQCString str(anchor,(c - anchor) + 1);
+ bool bOk;
+ int num = str.toInt(&bOk);
+ if(!bOk)return false; // should never happen , but just to be sure
+ if((num < 0) || (num > 255))return false; // Invalid field
+ m_pEdit[i]->setText(str.data());
+ if(i < 3){
+ if(*c == '.')c++;
+ else return false; // missing separator
+ }
+ }
+ } else {
+ for(int i=0;i<8;i++)
+ {
+ const char *anchor = c;
+ while(isdigit(*c) || ((tolower(*c) >= 'a') && (tolower(*c) <= 'f')) || ((tolower(*c) >= 'A') && (tolower(*c) <= 'F')))c++;
+ KviQCString str(anchor,(c - anchor) + 1);
+ if(str.length() > 4)return false; // Too long
+ m_pEdit[i]->setText(str.data());
+ if(i < 7){
+ if(*c == ':')c++;
+ else return false; // missing separator
+ }
+ }
+ }
+ if(*c)return false; // trailing garbage (we could avoid this)
+ return true;
+}
+
+QString KviIpEditor::address() const
+{
+ QString ret;
+
+ if(m_addrType == IpV6)
+ {
+ for(int i=0;i<8;i++)
+ {
+ ret.append(m_pEdit[i]->text());
+ if(i < 7)ret.append(":");
+ }
+ } else {
+ for(int i=0;i<4;i++)
+ {
+ QString tmp = m_pEdit[i]->text();
+ bool bOk;
+ int num = tmp.toInt(&bOk);
+ if(!bOk)num = 0;
+ tmp.setNum(num);
+ ret.append(tmp);
+ if(i < 3)ret.append(".");
+ }
+ }
+ return ret;
+}
+
+void KviIpEditor::recreateChildren()
+{
+ // A bit slow , but compact
+ bool bIpV4 = (m_addrType == IpV4);
+ int max = bIpV4 ? 4 : 8;
+ QFontMetrics fm(font());
+ //int minWidth = fm.width(bIpV4 ? "000" : "AAAA") + 4;
+ for(int i=0;i<max;i++)
+ {
+ if(!m_pEdit[i]){
+ m_pEdit[i] = new QLineEdit(this);
+ m_pEdit[i]->installEventFilter(this);
+ m_pEdit[i]->setFrame(false);
+ m_pEdit[i]->setAlignment(Qt::AlignCenter);
+ }
+ //m_pEdit[i]->setMinimumWidth(minWidth);
+ m_pEdit[i]->setMaxLength(bIpV4 ? 3 : 4);
+ m_pEdit[i]->show();
+ if(i < (max - 1))
+ {
+ if(!m_pLabel[i])m_pLabel[i] = new QLabel(this);
+ m_pLabel[i]->setText(bIpV4 ? "." : ":");
+ m_pLabel[i]->show();
+ // Is this the right way ? setBackgroundMode seems to not work well
+#ifdef COMPILE_USE_QT4
+ m_pLabel[i]->setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background);
+#else
+ m_pLabel[i]->setBackgroundMode(isEnabled() ? QWidget::PaletteBase : QWidget::PaletteBackground);
+#endif
+ }
+ }
+ // Kill the unused widgets , if any
+ if(bIpV4)
+ {
+ for(int i=4;i<8;i++)
+ {
+ if(m_pEdit[i])
+ {
+ delete m_pEdit[i];
+ m_pEdit[i] = 0;
+ }
+ if(m_pLabel[i - 1])
+ {
+ delete m_pLabel[i - 1];
+ m_pLabel[i - 1] = 0;
+ }
+ }
+ }
+ //setMinimumWidth(4 + (max * minWidth) + ((max - 1) * m_pLabel[0]->sizeHint().width()));
+ setMinimumHeight(m_pLabel[0]->sizeHint().height() + 4);
+ resizeEvent(0);
+}
+
+bool KviIpEditor::eventFilter(QObject * o,QEvent *e)
+{
+ if(o->inherits("QLineEdit"))
+ {
+ if(e->type() == QEvent::KeyPress)
+ {
+ QString s;
+ // find the editor
+ int edIdx = -1;
+ for(int i=0;i<8;i++)
+ {
+ if(m_pEdit[i] == o)
+ {
+ edIdx = i;
+ break;
+ }
+ }
+ if(edIdx == -1)return QFrame::eventFilter(o,e); // user added QLineEdit child ?
+ int edMax = (m_addrType == IpV4) ? 3 : 7;
+ int cursorPos = ((QLineEdit *)o)->cursorPosition();
+ switch(((QKeyEvent *)e)->key())
+ {
+ case Qt::Key_Right:
+ s = ((QLineEdit *)o)->text();
+ if(((unsigned int)cursorPos) == s.length())
+ {
+ if(edIdx < edMax)
+ {
+ m_pEdit[++edIdx]->setCursorPosition(0);
+ m_pEdit[edIdx]->setFocus();
+ return true;
+ }
+ }
+ break;
+ case Qt::Key_Left:
+ case Qt::Key_Backspace:
+ if(cursorPos == 0)
+ {
+ if(edIdx > 0)
+ {
+ s = m_pEdit[--edIdx]->text();
+ m_pEdit[edIdx]->setCursorPosition(s.length());
+ m_pEdit[edIdx]->setFocus();
+ return true;
+ }
+ }
+ return QFrame::eventFilter(o,e);
+ break;
+ case Qt::Key_End:
+ case Qt::Key_Home:
+ case Qt::Key_Delete:
+ case Qt::Key_Tab:
+ return QFrame::eventFilter(o,e);
+ break;
+ default:
+ // a normal key (this part substitutes a QValidator)
+ const char c = tolower(((QKeyEvent *)e)->ascii());
+ if(m_addrType == IpV4)
+ {
+ if((c >= '0') && (c <= '9'))
+ {
+#if QT_VERSION >= 300
+ if(m_pEdit[edIdx]->hasSelectedText())m_pEdit[edIdx]->cut();
+#else
+ if(m_pEdit[edIdx]->hasMarkedText())m_pEdit[edIdx]->cut();
+#endif
+ cursorPos = m_pEdit[edIdx]->cursorPosition();
+ s = m_pEdit[edIdx]->text();
+ s.insert(cursorPos,c);
+ bool bOk = false;
+ int num = s.toInt(&bOk);
+ if(!bOk)return true; //should never happen , but just to be sure
+ if((num < 0) || (num > 255))return true; //invalid field
+ m_pEdit[edIdx]->setText(s);
+ if(num > 25)
+ {
+ // The focus goes to the next editor
+ if(edIdx < edMax)
+ {
+ m_pEdit[++edIdx]->setFocus();
+ m_pEdit[edIdx]->selectAll();
+ //m_pEdit[edIdx]->setCursorPosition(0);
+ return true;
+ }
+ }
+#if QT_VERSION >= 300
+ m_pEdit[edIdx]->cursorForward(false);
+#else
+ m_pEdit[edIdx]->cursorRight(false);
+#endif
+ } else {
+ if((c == '.') && (edIdx < edMax))
+ {
+#if QT_VERSION >= 300
+ if(!m_pEdit[edIdx]->hasSelectedText())
+#else
+ if(!m_pEdit[edIdx]->hasMarkedText())
+#endif
+ {
+ m_pEdit[++edIdx]->setFocus();
+ m_pEdit[edIdx]->selectAll();
+ }
+ }
+ }
+ } else {
+ if( ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) )
+ {
+#if QT_VERSION >= 300
+ if(m_pEdit[edIdx]->hasSelectedText())m_pEdit[edIdx]->cut();
+#else
+ if(m_pEdit[edIdx]->hasMarkedText())m_pEdit[edIdx]->cut();
+#endif
+ cursorPos = m_pEdit[edIdx]->cursorPosition();
+ s = m_pEdit[edIdx]->text();
+
+ if(s.length() == 4)
+ {
+ if((cursorPos == 4) && (edIdx < edMax))
+ {
+ // the char goes in the next editor
+ s = c;
+ m_pEdit[++edIdx]->setText(s);
+ m_pEdit[edIdx]->end(false);
+ m_pEdit[edIdx]->setFocus();
+ } // else either no space or invalid place in the string
+ } else {
+ // ok .. can insert
+ s.insert(cursorPos,c);
+ m_pEdit[edIdx]->setText(s);
+ if((s.length() == 4) && (edIdx < edMax))
+ {
+ // the focus now goes to the next editor
+ m_pEdit[++edIdx]->setFocus();
+ m_pEdit[edIdx]->selectAll();
+ //m_pEdit[edIdx]->setCursorPosition(0);
+ } else {
+#if QT_VERSION >= 300
+ m_pEdit[edIdx]->cursorForward(false);
+#else
+ m_pEdit[edIdx]->cursorRight(false);
+#endif
+ }
+ }
+ } else {
+ if((c == ':') && (edIdx < edMax))
+ {
+#if QT_VERSION >= 300
+ if(!m_pEdit[edIdx]->hasSelectedText())
+#else
+ if(!m_pEdit[edIdx]->hasMarkedText())
+#endif
+ {
+ m_pEdit[++edIdx]->setFocus();
+ m_pEdit[edIdx]->selectAll();
+ }
+ }
+ }
+ }
+ return true;
+ break;
+ }
+ }
+ }
+ return QFrame::eventFilter(o,e);
+}
+
+void KviIpEditor::resizeEvent(QResizeEvent *e)
+{
+ if(m_pEdit[0])
+ {
+ int maxW = (m_addrType == IpV4) ? 4 : 8;
+ int labHint = m_pLabel[0]->sizeHint().width();
+ int hghHint = height() - 4;
+ int ediWdth = ((width() - 4) - ((maxW - 1) * labHint)) / maxW;
+ int curX = 2;
+ for(int i=0;i<maxW;i++)
+ {
+ if(i > 0)
+ {
+ m_pLabel[i - 1]->setGeometry(curX,2,labHint,hghHint);
+ curX += labHint;
+ }
+ m_pEdit[i]->setGeometry(curX,2,ediWdth,hghHint);
+ curX += ediWdth;
+ }
+ }
+ if(e)QFrame::resizeEvent(e);
+}
+
+QSize KviIpEditor::sizeHint()
+{
+ if(m_pEdit[0])
+ {
+ int labHint = m_pLabel[0]->sizeHint().width();
+ int hghHint = m_pEdit[0]->sizeHint().height();
+ int ediHint = m_pEdit[0]->sizeHint().width();
+ if(m_addrType == IpV4)return QSize((labHint * 3) + (ediHint * 4) + 4,hghHint + 4);
+ else return QSize((labHint * 7) + (ediHint * 8) + 4,hghHint + 4);
+ } else return QFrame::sizeHint();
+}
+
+
+#include "kvi_ipeditor.moc"
diff --git a/src/kvirc/ui/kvi_ipeditor.h b/src/kvirc/ui/kvi_ipeditor.h
new file mode 100644
index 0000000..04574e6
--- /dev/null
+++ b/src/kvirc/ui/kvi_ipeditor.h
@@ -0,0 +1,62 @@
+#ifndef _KVI_IPEDITOR_H_
+#define _KVI_IPEDITOR_H_
+
+//
+// File : kvi_ipeditor.h
+// Creation date : Wed Jun 12 2000 14:16:02 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+
+#include <qwidget.h>
+#include <qstring.h>
+#include <qframe.h>
+
+class QLineEdit;
+class QLabel;
+
+class KVIRC_API KviIpEditor : public QFrame
+{
+ Q_OBJECT
+public:
+ enum AddressType { IpV4 , IpV6 };
+ KviIpEditor(QWidget * parent,AddressType = IpV4,const QString &ipAddr = QString::null,const char *name = 0);
+ ~KviIpEditor();
+private:
+ QLabel * m_pLabel[7];
+ QLineEdit * m_pEdit[8];
+ AddressType m_addrType;
+public:
+ bool setAddress(const QString &ipAddr);
+ QString address() const;
+ void setAddressType(AddressType addrType);
+ AddressType addressType() const;
+ bool hasEmptyFields() const;
+ void clear();
+ virtual void setEnabled(bool bEnabled);
+protected:
+ virtual bool eventFilter(QObject * o,QEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual QSize sizeHint();
+private:
+ void recreateChildren();
+};
+
+#endif //_KVI_IPEDITOR_H_
diff --git a/src/kvirc/ui/kvi_irctoolbar.cpp b/src/kvirc/ui/kvi_irctoolbar.cpp
new file mode 100644
index 0000000..a7e45f3
--- /dev/null
+++ b/src/kvirc/ui/kvi_irctoolbar.cpp
@@ -0,0 +1,441 @@
+//=============================================================================
+//
+// File : kvi_irctoolbar.cpp
+// Creation date : Thu Oct 29 2000 14:13:13 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#include "kvi_irctoolbar.h"
+#include "kvi_console.h"
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_frame.h"
+#include "kvi_app.h"
+#include "kvi_dynamictooltip.h"
+#include "kvi_ircurl.h"
+#include "kvi_internalcmd.h"
+#include "kvi_pointerlist.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_irccontext.h"
+#include "kvi_lagmeter.h"
+
+#include <qstyle.h>
+#include <qpainter.h>
+#include "kvi_tal_popupmenu.h"
+#include <qlayout.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qevent.h>
+#endif
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+#endif
+
+static QPixmap * g_pIccMemBuffer = 0;
+static KviPointerList<KviToolBarGraphicalApplet> * g_pToolBarGraphicalAppletList = 0;
+
+KviToolBarGraphicalApplet::KviToolBarGraphicalApplet(QWidget * par,const char * name)
+: QToolButton(par,name)
+{
+ if(!g_pToolBarGraphicalAppletList)
+ {
+ g_pToolBarGraphicalAppletList = new KviPointerList<KviToolBarGraphicalApplet>();
+ g_pToolBarGraphicalAppletList->setAutoDelete(false);
+ g_pIccMemBuffer = new QPixmap(1,1);
+ }
+
+ g_pToolBarGraphicalAppletList->append(this);
+#ifdef COMPILE_USE_QT4
+ setAutoFillBackground(false);
+#else
+ setBackgroundMode(QWidget::NoBackground);
+#endif
+
+ setMouseTracking(true);
+ m_bResizeMode = false;
+
+ m_sizeHint = QSize(180,32);
+ m_bSizeLoaded = false;
+}
+
+unsigned int KviToolBarGraphicalApplet::loadAppletWidth()
+{
+ if(KVI_OPTION_UINT(KviOption_uintIrcContextAppletWidth) < 32)
+ KVI_OPTION_UINT(KviOption_uintIrcContextAppletWidth) = 32;
+ return KVI_OPTION_UINT(KviOption_uintIrcContextAppletWidth);
+}
+
+void KviToolBarGraphicalApplet::saveAppletWidth(unsigned int uWidth)
+{
+ KVI_OPTION_UINT(KviOption_uintIrcContextAppletWidth) = uWidth;
+}
+
+void KviToolBarGraphicalApplet::setupSizeHint()
+{
+ m_sizeHint = QSize(loadAppletWidth(),22);
+ m_bSizeLoaded = true;
+}
+
+QSize KviToolBarGraphicalApplet::sizeHint() const
+{
+ // forget constness :(
+ KviToolBarGraphicalApplet * that = (KviToolBarGraphicalApplet *)this;
+ if(!m_bSizeLoaded)that->setupSizeHint();
+ return m_sizeHint;
+}
+
+/*
+toolbar.define(default)
+{
+ applet(thisandthat);
+ applet(thisandthat);
+ applet(thisandthat);
+ applet(thisandthat);
+}
+*/
+
+
+void KviToolBarGraphicalApplet::mouseMoveEvent(QMouseEvent * e)
+{
+ if(e->state() & Qt::LeftButton)
+ {
+ if(m_bResizeMode)
+ {
+ int w = e->pos().x();
+ if(w < 32)w = 32;
+ if(w > 480)w = 480;
+ m_sizeHint = QSize(w,22);
+ resize(w,height());
+ g_pApp->postEvent(parentWidget(),new QEvent(QEvent::LayoutHint));
+ }
+ } else {
+ if(e->pos().x() > width() - 4)
+ setCursor(Qt::sizeHorCursor);
+ else
+ setCursor(Qt::arrowCursor);
+ }
+}
+
+void KviToolBarGraphicalApplet::mousePressEvent(QMouseEvent * e)
+{
+ if(e->button() & Qt::LeftButton)
+ {
+ m_bResizeMode = (e->pos().x() > (width() - 4));
+ }
+}
+
+void KviToolBarGraphicalApplet::mouseReleaseEvent(QMouseEvent * e)
+{
+ m_bResizeMode = false;
+}
+
+
+KviToolBarGraphicalApplet::~KviToolBarGraphicalApplet()
+{
+ saveAppletWidth(m_sizeHint.width());
+ g_pToolBarGraphicalAppletList->removeRef(this);
+ if(g_pToolBarGraphicalAppletList->isEmpty())
+ {
+ delete g_pToolBarGraphicalAppletList;
+ g_pToolBarGraphicalAppletList = 0;
+ delete g_pIccMemBuffer;
+ g_pIccMemBuffer = 0;
+ } else {
+ // resize the mem buffer to match the maximum width / height of the applets
+ resizeMemBuffer();
+ }
+}
+
+void KviToolBarGraphicalApplet::resizeMemBuffer()
+{
+ int uMaxW = 0;
+ int uMaxH = 0;
+ for(KviToolBarGraphicalApplet * a = g_pToolBarGraphicalAppletList->first();a;a = g_pToolBarGraphicalAppletList->next())
+ {
+ if(uMaxW < a->width())uMaxW = a->width();
+ if(uMaxH < a->height())uMaxH = a->height();
+ }
+ g_pIccMemBuffer->resize(uMaxW,uMaxH);
+}
+
+void KviToolBarGraphicalApplet::paintEvent(QPaintEvent *e)
+{
+ if(!isVisible())return;
+
+ QPainter pa(g_pIccMemBuffer);
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = mapToGlobal(QPoint(0,0));
+ pa.drawTiledPixmap(e->rect().left(),e->rect().top(),e->rect().width(),e->rect().height(),*g_pShadedChildGlobalDesktopBackground,pnt.x(),pnt.y());
+ } else {
+#endif
+ if(KVI_OPTION_PIXMAP(KviOption_pixmapIrcToolBarAppletBackground).pixmap())
+ {
+ QPoint pnt = mapToGlobal(QPoint(0,0));
+ pa.drawTiledPixmap(e->rect().left(),e->rect().top(),e->rect().width(),e->rect().height(),*(KVI_OPTION_PIXMAP(KviOption_pixmapIrcToolBarAppletBackground).pixmap()),pnt.x(),pnt.y());
+ } else {
+ pa.fillRect(e->rect().left(),e->rect().top(),e->rect().width(),e->rect().height(),KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletBackground));
+ }
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+
+ drawContents(&pa);
+
+ //Need to draw the sunken rect around the view now...
+ pa.setPen(colorGroup().dark());
+ pa.drawLine(0,0,width(),0);
+ pa.drawLine(0,0,0,width());
+ pa.setPen(colorGroup().light());
+ pa.drawLine(1,height() - 1,width() - 1,height() - 1);
+ pa.drawLine(width() - 1,1,width() - 1,height());
+
+#ifdef COMPILE_USE_QT4
+ QPainter qt4SucksBecauseItNeedsAnAdditionalQPainter(this);
+ qt4SucksBecauseItNeedsAnAdditionalQPainter.drawPixmap(e->rect().left(),e->rect().top(),e->rect().width(),e->rect().height(),*g_pIccMemBuffer,e->rect().left(),e->rect().top(),e->rect().width(),e->rect().height());
+#else
+ bitBlt(this,e->rect().left(),e->rect().top(),g_pIccMemBuffer,e->rect().left(),e->rect().top(),e->rect().width(),e->rect().height(),Qt::CopyROP);
+#endif
+}
+
+void KviToolBarGraphicalApplet::drawContents(QPainter *)
+{
+ // nothing here
+}
+
+void KviToolBarGraphicalApplet::resizeEvent(QResizeEvent *e)
+{
+ unsigned int uBufferW = g_pIccMemBuffer->width();
+ unsigned int uBufferH = g_pIccMemBuffer->height();
+ unsigned int uW = width();
+ unsigned int uH = height();
+
+ if((uBufferW != uW) || (uBufferH != uH))
+ {
+ if((uBufferW < uW) && (uBufferH < uH))g_pIccMemBuffer->resize(uW,uH);
+ else resizeMemBuffer();
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// KviIrcContextDisplay
+//
+// Main applet of all irc contexts
+// Displays the server connection status, server name
+// nickname, user mode and the graphical indication of the context
+//
+//////////////////////////////////////////////////////////////////////////////
+
+KviIrcContextDisplay::KviIrcContextDisplay(QWidget * par,const char * name)
+: KviToolBarGraphicalApplet(par,name)
+{
+ KviDynamicToolTip * tip = new KviDynamicToolTip(this);
+ connect(tip,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &)));
+}
+
+
+KviIrcContextDisplay::~KviIrcContextDisplay()
+{
+}
+
+void KviIrcContextDisplay::tipRequest(KviDynamicToolTip * tip,const QPoint &)
+{
+ QString txt;
+
+ KviConsole * c = g_pActiveWindow->console();
+
+ static QString b = "<b>";
+ static QString nb = "</b>";
+ static QString br = "<br>";
+
+ if(c)
+ {
+ KviIrcConnection * ic = c->connection();
+
+ txt = b;
+
+ if(!ic)
+ {
+ txt += __tr2qs("No connection");
+ txt += nb;
+ txt += br;
+ } else {
+ KviStr nickAndMode = ic->userInfo()->nickName();
+ if(!(ic->userInfo()->userMode().isEmpty()))nickAndMode.append(KviStr::Format," (+%s)",ic->userInfo()->userMode().utf8().data());
+
+ txt += ic->currentServerName();
+ txt += nb;
+ txt += br;
+ txt += nickAndMode.ptr();
+ txt += br;
+ }
+
+ QString szNum;
+ szNum.setNum(c->ircContextId());
+
+ QString szIrcContext = QChar('(');
+ szIrcContext += __tr2qs("IRC Context");
+ szIrcContext += QChar(' ');
+ szIrcContext += szNum;
+ szIrcContext += QChar(')');
+ txt += szIrcContext;
+
+ if(ic && ic->lagMeter() && (KVI_OPTION_BOOL(KviOption_boolShowLagOnContextDisplay)))
+ {
+ txt += br;
+ int lll;
+ if((lll = ic->lagMeter()->lag()) > 0)
+ {
+ int llls = lll / 1000;
+ int llld = (lll % 1000) / 100;
+ int lllc = (lll % 100) / 10;
+ KviQString::appendFormatted(txt,__tr2qs("Lag: %d.%d%d"),llls,llld,lllc);
+ } else {
+ txt += __tr2qs("Lag: ?.??");
+ }
+ }
+ } else {
+ txt = b;
+ txt += __tr2qs("No IRC context");
+ txt += nb;
+ }
+
+ tip->tip(rect(),txt);
+}
+
+
+/*
+QSize KviIrcContextDisplay::sizeHint() const
+{
+ return QSize(160,22);
+}
+*/
+
+#define KVI_APPLETIRCCONTEXTINDICATORWIDTH 12
+
+void KviIrcContextDisplay::drawContents(QPainter * p)
+{
+ // The context indicator
+ KviWindow * wnd = g_pActiveWindow;
+ KviConsole * c = wnd ? wnd->console() : 0;
+
+ if(c)
+ {
+ QString serv,nick;
+ QString tmp;
+ if(!c->connection())
+ {
+ serv = __tr2qs("Not connected");
+ } else {
+ if(c->isConnected())
+ {
+ KviIrcConnection * ic = c->connection();
+ nick = ic->currentNickName();
+ if(!ic->userInfo()->userMode().isEmpty())
+ {
+ static QString spp(" (+");
+ nick += spp;
+ nick += ic->userInfo()->userMode();
+ if(ic->userInfo()->isAway())
+ {
+ nick += QChar(' ');
+ nick += __tr2qs("away");
+ }
+ nick += QChar(')');
+ } else {
+ if(ic->userInfo()->isAway())
+ {
+ static QString ugly(" (");
+ nick += ugly;
+ nick += __tr2qs("away");
+ nick += QChar(')');
+ }
+ }
+ serv = ic->currentServerName();
+ if(ic->lagMeter() && (KVI_OPTION_BOOL(KviOption_boolShowLagOnContextDisplay)))
+ {
+ nick += " ";
+ int lll;
+ if((lll = ic->lagMeter()->lag()) > 0)
+ {
+ int llls = lll / 1000;
+ int llld = (lll % 1000) / 100;
+ int lllc = (lll % 100) / 10;
+ KviQString::appendFormatted(nick,__tr2qs("Lag: %d.%d%d"),llls,llld,lllc);
+ } else {
+ nick += __tr2qs("Lag: ?.??");
+ }
+ }
+ } else {
+ serv = __tr2qs("In progress...");
+ }
+ }
+
+ p->setPen(KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundHighContrastActive1));
+
+ p->setClipRect(KVI_APPLETIRCCONTEXTINDICATORWIDTH + 2,2,width() - (KVI_APPLETIRCCONTEXTINDICATORWIDTH + 4),height() - 4);
+
+ if(height() < 30)
+ {
+ static QString xxx(" [");
+ serv += xxx;
+ serv += nick;
+ serv += QChar(']');
+ p->drawText(KVI_APPLETIRCCONTEXTINDICATORWIDTH + 4,16,serv,serv.length());
+ } else {
+ p->drawText(KVI_APPLETIRCCONTEXTINDICATORWIDTH + 4,16,serv,serv.length());
+ p->drawText(KVI_APPLETIRCCONTEXTINDICATORWIDTH + 4,30,nick,nick.length());
+ }
+
+ p->setClipping(false);
+
+ QColor base = colorGroup().background();
+ QColor cntx = KVI_OPTION_ICCOLOR(c->ircContextId() % KVI_NUM_ICCOLOR_OPTIONS);
+ base.setRgb((base.red() + cntx.red()) >> 1,(base.green() + cntx.green()) >> 1,
+ (base.blue() + cntx.blue()) >> 1);
+
+ p->fillRect(2,2, KVI_APPLETIRCCONTEXTINDICATORWIDTH - 2,height() - 4,base);
+ }
+
+ p->setPen(KVI_OPTION_COLOR(KviOption_colorIrcToolBarAppletForegroundMidContrast));
+ p->drawLine(1,1,width() - 1,1);
+ p->drawLine(1,1,1,height() - 1);
+ p->drawLine(2,height() - 2,width() - 1,height() - 2);
+ p->drawLine(width() - 2,1,width() - 2,height());
+ p->drawLine(KVI_APPLETIRCCONTEXTINDICATORWIDTH,2,KVI_APPLETIRCCONTEXTINDICATORWIDTH,height() - 2);
+
+}
+
+
+#ifdef Bool
+ #undef Bool
+#endif
+
+#include "kvi_irctoolbar.moc"
diff --git a/src/kvirc/ui/kvi_irctoolbar.h b/src/kvirc/ui/kvi_irctoolbar.h
new file mode 100644
index 0000000..a903065
--- /dev/null
+++ b/src/kvirc/ui/kvi_irctoolbar.h
@@ -0,0 +1,95 @@
+#ifndef _KVI_IRCTOOLBAR_H_
+#define _KVI_IRCTOOLBAR_H_
+
+//
+// File : kvi_irctoolbar.h
+// Creation date : Thu Oct 29 2000 14:09:11 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+
+#include "kvi_string.h"
+#include "kvi_toolbar.h"
+#include "kvi_console.h"
+
+#include "kvi_pointerlist.h"
+#include <qwidget.h>
+#include <qtoolbutton.h>
+#include "kvi_tal_widgetstack.h"
+#include <qlabel.h>
+
+class KviTalPopupMenu;
+
+
+//
+// Basic graphical applet
+//
+// Thinks about the "common" background (handles transparency stuff & co.)
+// Can be a child of any AppletContainer
+//
+
+class KVIRC_API KviToolBarGraphicalApplet : public QToolButton
+{
+ Q_OBJECT
+public:
+ KviToolBarGraphicalApplet(QWidget * par,const char * name = 0);
+ ~KviToolBarGraphicalApplet();
+private:
+ bool m_bResizeMode;
+ bool m_bSizeLoaded;
+ QSize m_sizeHint;
+private:
+ void resizeMemBuffer();
+protected:
+ void setupSizeHint();
+
+ virtual unsigned int loadAppletWidth();
+ virtual void saveAppletWidth(unsigned int uWidth);
+ virtual QSize sizeHint() const;
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void drawContents(QPainter * p);
+ virtual void resizeEvent(QResizeEvent *e);
+};
+
+
+class KviDynamicToolTip;
+
+class KVIRC_API KviIrcContextDisplay : public KviToolBarGraphicalApplet
+{
+ Q_OBJECT
+public:
+ KviIrcContextDisplay(QWidget * par,const char * name = 0);
+ ~KviIrcContextDisplay();
+protected:
+ virtual void drawContents(QPainter * p);
+protected slots:
+ void tipRequest(KviDynamicToolTip * tip,const QPoint &);
+};
+
+
+
+
+
+
+#endif //_KVI_IRCTOOLBAR_H_
diff --git a/src/kvirc/ui/kvi_ircview.cpp b/src/kvirc/ui/kvi_ircview.cpp
new file mode 100644
index 0000000..e09edee
--- /dev/null
+++ b/src/kvirc/ui/kvi_ircview.cpp
@@ -0,0 +1,5161 @@
+//=============================================================================
+//
+// File : kvi_ircview.cpp
+// Creation date : Tue Jul 6 1999 14:45:20 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+// Damn complex class ...but it works :)
+// #include <brain.h>
+//
+// #define HOPE_THAT_IT_WILL_NEVER_NEED_TO_BE_MODIFIED :)
+
+// 07 May 1999 ,
+// Already forgot how this damn thing works ,
+// and spent 1 hour over a stupid bug.
+// I had to recreate the whole thing in my mind......ooooouh...
+// How did I wrote it ?
+// Just take a look to paintEvent() or to calculateLineWraps()...
+// Anyway...I've solved the bug.
+
+// 23 Nov 1999 ,
+// Well , not so bad...I seem to still remember how it works
+// So just for fun , complicated the things a little bit more.
+// Added precaclucaltion of the text blocks and word wrapping
+// and a fast scrolling mode (3 lines at once) for consecutive
+// appendText() calls.
+// Now the code becomes really not understandable...:)
+
+// 29 Jun 2000 21:02 ,
+// Here we go again... I have to adjust this stuff for 3.0.0
+// Will I make this thingie work ?
+// 01 Jul 2000 04:20 (AM!) ,
+// Yes....I got it to work just now
+// and YES , complicated the things yet more.
+// This time made some paint event code completely unreadable
+// by placing two monster macros...
+// I hope that you have a smart compiler (such as gcc is).
+
+// 09 Dec 2000
+// This is my C-asm-optimisation-hack playground
+// Expect Bad Programming(tm) , Ugly Code(tm) , Unreadable Macros (tm)
+// and massive usage of the Evil(tm) goto.
+
+// 25 Sep 2001
+// This stuff is going to be ported to Windoze
+// A conditionally compiled code will use only Qt calls...let's see :)
+//
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Here we go... a huge set of includes
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "kvi_ircview.h"
+#include "kvi_ircviewtools.h"
+#include "kvi_ircviewprivate.h"
+#include "kvi_styled_controls.h"
+#include "kvi_debug.h"
+#include "kvi_app.h"
+#include "kvi_settings.h"
+#include "kvi_options.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_defaults.h"
+#include "kvi_window.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+#include "kvi_malloc.h"
+#include "kvi_memmove.h"
+#include "kvi_iconmanager.h"
+#include "kvi_out.h"
+#include "kvi_parameterlist.h"
+#include "kvi_console.h"
+#include "kvi_ircuserdb.h"
+#include "kvi_channel.h"
+#include "kvi_topicw.h"
+#include "kvi_query.h"
+#include "kvi_filedialog.h"
+#include "kvi_msgbox.h"
+#include "kvi_texticonmanager.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectiontarget.h"
+#include "kvi_mdimanager.h"
+#include "kvi_userinput.h"
+#include "kvi_kvs_eventtriggers.h"
+#include "kvi_doublebuffer.h"
+#include "kvi_ircurl.h"
+#include "kvi_draganddrop.h"
+#include "kvi_qcstring.h"
+// FIXME: #warning "There should be an option to preserve control codes in copied text (clipboard) (mIrc = CTRL+Copy->with colors)"
+
+#include <qbitmap.h>
+#include <qpainter.h>
+#include <qregexp.h>
+#include <qfile.h>
+#include <qtoolbutton.h>
+#include <qfontmetrics.h> // needed
+#include <qapplication.h>
+#include "kvi_tal_popupmenu.h"
+#include <qmessagebox.h>
+#include <qtextcodec.h>
+#include <qdatetime.h>
+#include <qevent.h>
+
+//#include <qcolor.h> // needed
+
+// FIXME: #warning "There are problems with the selection and wrapped lines: you can select something on the first line and get the second highlighted"
+// FIXME: #warning "This hack is temporary...later remove it"
+
+#if QT_VERSION >= 300
+ #ifndef QT_CLEAN_NAMESPACE
+ #define QT_CLEAN_NAMESPACE
+ #include <qcursor.h>
+ #undef QT_CLEAN_NAMESPACE
+ #else
+ #include <qcursor.h>
+ #endif
+#else
+ #include <qcursor.h>
+#endif
+
+#include <qclipboard.h>
+#include <qdatetime.h>
+#include <qmessagebox.h>
+#include <qscrollbar.h>
+#include <qfontdialog.h>
+
+#include <time.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <q3mimefactory.h>
+ #define QMimeSourceFactory Q3MimeSourceFactory
+#endif
+
+
+#ifdef COMPILE_ON_WINDOWS
+ #pragma warning(disable: 4102)
+#endif
+
+#ifdef __STRICT_ANSI__
+ #ifdef COMPILE_USE_DYNAMIC_LABELS
+ // incompatible with -ansi
+ #undef COMPILE_USE_DYNAMIC_LABELS
+ #endif
+#endif
+
+#ifdef COMPILE_ZLIB_SUPPORT
+ #include <zlib.h>
+#endif
+
+#define KVI_DEF_BACK 200
+
+// FIXME: #warning "The scrollbar should NOT have a fixed size : the KDE styles can configure the size (sizeHint() ?)"
+
+//
+// FIXME: PgUp and PgDn scrolls a fixed number of lines!
+// Make it view height dependant
+//
+// FIXME: This widget is quite slow on a 300 MHz processor
+//
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Globals
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Stuff declared in kvi_app.cpp and managed by KviApp class
+
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Internal constants
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// Maximum size of the internal buffer for each window
+// This is the default value
+//#define KVI_IRCVIEW_MAX_LINES 1024
+// Borders...just do not set it to 0
+#define KVI_IRCVIEW_HORIZONTAL_BORDER 4
+#define KVI_IRCVIEW_VERTICAL_BORDER 4
+// A little bit more than the scroll-bar...
+// Qt+X have strange interactions that I can not understand when I try to move the splitter
+// to the maximum on the left , Maybe the cache pixmap size becomes negative ? (I don't think so)
+// Anyway , when the scroll bar position becomes negative (or the IrcView has smaller width than
+// the scroll bar) X aborts with a funny
+// X Error: BadDrawable (invalid Pixmap or Window parameter) 9
+// Major opcode: 55
+// Program received signal SIGABRT, Aborted.
+// Do not change unless you're sure that it will not happen :)
+#define KVI_IRCVIEW_MINIMUM_WIDTH 22
+//16+4+(2*4) * Do not change
+#define KVI_IRCVIEW_PIXMAP_AND_SEPARATOR 20
+#define KVI_IRCVIEW_PIXMAP_SEPARATOR_AND_DOUBLEBORDER_WIDTH 28
+#define KVI_IRCVIEW_SELECT_REPAINT_INTERVAL 100
+#define KVI_IRCVIEW_SIZEHINT_WIDTH 150
+#define KVI_IRCVIEW_SIZEHINT_HEIGHT 150
+
+#define KVI_IRCVIEW_BLOCK_SELECTION_TOTAL 0
+#define KVI_IRCVIEW_BLOCK_SELECTION_LEFT 1
+#define KVI_IRCVIEW_BLOCK_SELECTION_RIGHT 2
+#define KVI_IRCVIEW_BLOCK_SELECTION_CENTRAL 3
+#define KVI_IRCVIEW_BLOCK_SELECTION_ICON 4
+
+#define KVI_IRCVIEW_PIXMAP_SIZE 16
+
+#define KVI_IRCVIEW_ESCAPE_TAG_URLLINK 'u'
+#define KVI_IRCVIEW_ESCAPE_TAG_NICKLINK 'n'
+#define KVI_IRCVIEW_ESCAPE_TAG_SERVERLINK 's'
+#define KVI_IRCVIEW_ESCAPE_TAG_HOSTLINK 'h'
+#define KVI_IRCVIEW_ESCAPE_TAG_GENERICESCAPE '['
+
+// FIXME: Get rid of this!!!!!!!!!
+#define WSTRINGCONFIG_SAFE_TO_MEMCPY_QCHAR
+
+#define _WSTRING_WMEMCPY(_dst,_src,_len) kvi_fastmoveodd((void *)(_dst),(const void *)(_src),sizeof(kvi_wchar_t) * (_len))
+
+void kvi_appendWCharToQStringWithLength(QString * qstrptr,const kvi_wchar_t * ptr,kvi_wslen_t len)
+{
+ kvi_wslen_t oldLen = qstrptr->length();
+ qstrptr->setLength(oldLen + len);
+ #ifdef WSTRINGCONFIG_SAFE_TO_MEMCPY_QCHAR
+ _WSTRING_WMEMCPY(qstrptr->unicode() + oldLen,ptr,len);
+ #else // !WSTRINGCONFIG_SAFE_TO_MEMCPY_QCHAR
+ QChar * c = (qstrptr->unicode() + oldLen);
+ while(*ptr)
+ {
+ c->unicode() = *ptr;
+ ptr++;
+ c++;
+ }
+ #endif // !WSTRINGCONFIG_SAFE_TO_MEMCPY_QCHAR
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Info about escape syntax
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// escape commands:
+//
+// <cr>!<escape_command><cr><visible parameters<cr>
+//
+// <escape_command> ::= u <--- url link
+// <escape_command> ::= n <--- nick link
+// <escape_command> ::= s <--- server link
+// <escape_command> ::= h <--- host link
+// <escape_command> ::= [... <--- generic escape "rbt" | "mbt" | "dbl" | "txt"
+//
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The IrcView : construct and destroy
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviIrcView::KviIrcView(QWidget *parent,KviFrame *pFrm,KviWindow *pWnd)
+: QWidget(parent,"irc_view")
+{
+ // Ok...here we go
+ // initialize the initializable
+
+#ifdef COMPILE_USE_QT4
+ setAttribute(Qt::WA_NoSystemBackground); // This disables automatic qt double buffering
+ setAttribute(Qt::WA_OpaquePaintEvent);
+ //setAttribute(Qt::WA_PaintOnScreen); // disable qt backing store (that would force us to trigger repaint() instead of the 10 times faster paintEvent(0))
+#endif
+
+ m_iFlushTimer = 0;
+ m_pToolsPopup = 0;
+ m_pFirstLine = 0;
+ m_pCurLine = 0;
+ m_pLastLine = 0;
+ m_pCursorLine = 0;
+ m_uLineMarkLineIndex = KVI_IRCVIEW_INVALID_LINE_MARK_INDEX;
+ m_bHaveUnreadedHighlightedMessages = false;
+ m_bHaveUnreadedMessages = false;
+ m_iNumLines = 0;
+ m_iMaxLines = KVI_OPTION_UINT(KviOption_uintIrcViewMaxBufferSize);
+
+ m_uNextLineIndex = 0;
+
+ if(m_iMaxLines < 32)
+ {
+ m_iMaxLines = 32;
+ KVI_OPTION_UINT(KviOption_uintIrcViewMaxBufferSize) = 32;
+ }
+
+ m_bMouseIsDown = false;
+
+ //m_bShowImages = KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages);
+
+ m_iSelectTimer = 0;
+ m_iMouseTimer = 0;
+ //m_iTipTimer = 0;
+ //m_bTimestamp = KVI_OPTION_BOOL(KviOption_boolIrcViewTimestamp);
+
+ m_bAcceptDrops = false;
+ m_pPrivateBackgroundPixmap = 0;
+ m_bSkipScrollBarRepaint = false;
+ m_pLogFile = 0;
+ m_pKviWindow = pWnd;
+ m_pFrm = pFrm;
+
+ m_iUnprocessedPaintEventRequests = 0;
+ m_bPostedPaintEventPending = false;
+
+ m_pLastLinkUnderMouse = 0;
+ m_iLastLinkRectTop = -1;
+ m_iLastLinkRectHeight = -1;
+
+ m_pMasterView = 0;
+
+ m_pToolWidget = 0;
+
+ m_pWrappedBlockSelectionInfo = new KviIrcViewWrappedBlockSelectionInfo;
+
+
+ m_pMessagesStoppedWhileSelecting = new KviPointerList<KviIrcViewLine>;
+ m_pMessagesStoppedWhileSelecting->setAutoDelete(false);
+
+ // say qt to avoid erasing on repaint
+#ifdef COMPILE_USE_QT4
+ setAutoFillBackground(false);
+#else
+ setBackgroundMode(NoBackground);
+#endif
+
+ m_pFm = 0; // will be updated in the first paint event
+
+ m_pToolTip = new KviIrcViewToolTip(this);
+
+ // Create the scroll bar
+#ifdef COMPILE_USE_QT4
+ m_pScrollBar = new QScrollBar(0,0,1,10,0,Qt::Vertical,this,"irc_view_scrollbar");
+#else
+ m_pScrollBar = new QScrollBar(0,0,1,10,0,QScrollBar::Vertical,this,"irc_view_scrollbar");
+#endif
+ m_pScrollBar->setTracking(true);
+ m_pScrollBar->show();
+
+ m_pScrollBar->setFocusProxy(this);
+
+
+ m_pToolsButton = new KviStyledToolButton(this,"btntools");
+#ifdef COMPILE_USE_QT4
+ QIcon is1(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_POPUPMENU)));
+ m_pToolsButton->setAutoRaise(true);
+#else
+ QIconSet is1(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_POPUPMENU)),QIconSet::Small);
+#endif
+ m_pToolsButton->setIconSet(is1);
+
+ KviTalToolTip::add(m_pToolsButton,__tr2qs("Search tools"));
+ m_pToolsButton->setFocusProxy(this);
+
+ connect(m_pToolsButton,SIGNAL(clicked()),this,SLOT(showToolsPopup()));
+ m_pToolsButton->show();
+
+ connect(m_pScrollBar,SIGNAL(valueChanged(int)),this,SLOT(scrollBarPositionChanged(int)));
+ m_iLastScrollBarValue = 0;
+
+ // set the minimum width
+ setMinimumWidth(KVI_IRCVIEW_MINIMUM_WIDTH);
+ // and catch all mouse events
+ setMouseTracking(true);
+ // let's go!
+ applyOptions();
+
+ if(KVI_OPTION_UINT(KviOption_uintAutoFlushLogs)) //m_iFlushTimer
+ {
+ m_iFlushTimer = startTimer(KVI_OPTION_UINT(KviOption_uintAutoFlushLogs)*60*1000);
+ }
+
+// if(pWnd->input()) setFocusProxy(pWnd->input());
+
+}
+
+static inline void delete_text_line(KviIrcViewLine * l)
+{
+ for(unsigned int i=0;i<l->uChunkCount;i++)
+ {
+ if((l->pChunks[i].type == KVI_TEXT_ESCAPE) || (l->pChunks[i].type == KVI_TEXT_ICON))
+ {
+ if( (l->pChunks[i].type == KVI_TEXT_ICON) && (l->pChunks[i].szPayload!=l->pChunks[i].szSmileId) )
+ kvi_free(l->pChunks[i].szSmileId);
+ kvi_free(l->pChunks[i].szPayload);
+ }
+ }
+ kvi_free(l->pChunks); //free attributes data
+ if(l->iBlockCount)kvi_free(l->pBlocks);
+ delete l;
+}
+
+KviIrcView::~KviIrcView()
+{
+ // kill any pending timer
+ if(m_iFlushTimer) killTimer(m_iFlushTimer);
+ if(m_iSelectTimer)killTimer(m_iSelectTimer);
+ if(m_iMouseTimer)killTimer(m_iMouseTimer);
+ // and close the log file (flush!)
+ stopLogging();
+ if(m_pToolWidget)delete m_pToolWidget;
+ // don't forget the bacgkround pixmap!
+ if(m_pPrivateBackgroundPixmap)delete m_pPrivateBackgroundPixmap;
+ // and to remove all the text lines
+ emptyBuffer(false);
+ // the pending ones too!
+ while(KviIrcViewLine * l = m_pMessagesStoppedWhileSelecting->first())
+ {
+ m_pMessagesStoppedWhileSelecting->removeFirst();
+ delete_text_line(l);
+ }
+ delete m_pMessagesStoppedWhileSelecting;
+ if(m_pFm)delete m_pFm;
+ delete m_pToolTip;
+ delete m_pWrappedBlockSelectionInfo;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The IrcView : options
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void KviIrcView::setFont(const QFont &f)
+{
+ if(m_pFm)
+ {
+ // force an update to the font variables
+ delete m_pFm;
+ m_pFm = 0;
+ }
+ KviIrcViewLine * l = m_pFirstLine;
+ while(l)
+ {
+ l->iMaxLineWidth = -1;
+ l = l->pNext;
+ }
+ QWidget::setFont(f);
+ update();
+}
+
+void KviIrcView::applyOptions()
+{
+ flushLog();
+ setFont(KVI_OPTION_FONT(KviOption_fontIrcView));
+ if(m_iFlushTimer) killTimer(m_iFlushTimer);
+ if(KVI_OPTION_UINT(KviOption_uintAutoFlushLogs))
+ {
+ m_iFlushTimer = startTimer(KVI_OPTION_UINT(KviOption_uintAutoFlushLogs)*60*1000);
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The IrcView : DnD //2005.Resurection by Grifisx & Noldor
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void KviIrcView::enableDnd(bool bEnable)
+{
+ setAcceptDrops(bEnable);
+ m_bAcceptDrops = bEnable;
+}
+
+void KviIrcView::dragEnterEvent(QDragEnterEvent *e)
+{
+ if(!m_bAcceptDrops)return;
+ e->accept(KviUriDrag::canDecode(e));
+ emit dndEntered();
+}
+
+void KviIrcView::dropEvent(QDropEvent *e)
+{
+ if(!m_bAcceptDrops)return;
+ QStringList list;
+ if(KviUriDrag::decodeLocalFiles(e,list))
+ {
+ if(!list.isEmpty())
+ {
+ QStringList::ConstIterator it = list.begin(); //kewl ! :)
+ for( ; it != list.end(); ++it )
+ {
+ QString tmp = *it; //wow :)
+ #ifndef COMPILE_ON_WINDOWS
+ if(tmp[0] != '/')tmp.prepend("/"); //HACK HACK HACK for Qt bug (?!?)
+ #endif
+ emit fileDropped(tmp);
+ }
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The IrcView : Logging
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void KviIrcView::stopLogging()
+{
+ if(m_pLogFile)
+ {
+ QString szLogEnd;
+ szLogEnd.sprintf(__tr2qs("### Log session terminated at %s ###"),QDateTime::currentDateTime().toString().utf8().data());
+
+ add2Log(szLogEnd);
+ m_pLogFile->close();
+#ifdef COMPILE_ZLIB_SUPPORT
+ if(KVI_OPTION_BOOL(KviOption_boolGzipLogs))
+ {
+ if(m_pLogFile->open(IO_ReadOnly))
+ {
+ QByteArray bytes;
+ bytes=m_pLogFile->readAll();
+ m_pLogFile->close();
+ QFileInfo fi(*m_pLogFile);
+ QString szFname=fi.dirPath(true)+QString("/")+fi.baseName(true);
+ gzFile file=gzopen(QTextCodec::codecForLocale()->fromUnicode(szFname).data(),"ab9");
+ if(file)
+ {
+ gzwrite(file,bytes.data(),bytes.size());
+ gzclose(file);
+ m_pLogFile->remove();
+ } else {
+ debug("Cannot open compressed stream");
+ }
+ }
+ }
+#endif
+ delete m_pLogFile;
+ m_pLogFile = 0;
+ }
+}
+
+void KviIrcView::getLogFileName(KviStr &buffer)
+{
+ if(m_pLogFile)buffer.append(m_pLogFile->name());
+}
+
+void KviIrcView::getLogFileName(QString &buffer)
+{
+ if(m_pLogFile) buffer=m_pLogFile->name();
+}
+
+void KviIrcView::getTextBuffer(QString &buffer)
+{
+ // FIXME: #warning "This does not merge the KviChannel::m_pMessageView buffer!"
+ buffer = "";
+ if(!m_pLastLine)return;
+ for(KviIrcViewLine *l=m_pFirstLine;l;l=l->pNext)
+ {
+ buffer.append(l->szText);
+ buffer.append("\n");
+ }
+}
+
+void KviIrcView::flushLog()
+{
+ if(m_pLogFile) {
+#ifdef COMPILE_ZLIB_SUPPORT
+ if(KVI_OPTION_BOOL(KviOption_boolGzipLogs))
+ {
+ m_pLogFile->close();
+ if(m_pLogFile->open(IO_ReadOnly))
+ {
+ QByteArray bytes;
+ bytes=m_pLogFile->readAll();
+ m_pLogFile->close();
+ QFileInfo fi(*m_pLogFile);
+ QString szFname=fi.dirPath(true)+QString("/")+fi.baseName(true);
+ gzFile file=gzopen(QTextCodec::codecForLocale()->fromUnicode(szFname).data(),"ab9");
+ if(file)
+ {
+ gzwrite(file,bytes.data(),bytes.size());
+ gzclose(file);
+ m_pLogFile->remove();
+ } else {
+ debug("Cannot open compressed stream");
+ }
+ }
+ m_pLogFile->open(IO_Append|IO_WriteOnly);
+ } else
+#endif
+ m_pLogFile->flush();
+ }
+ else if(m_pMasterView)m_pMasterView->flushLog();
+}
+
+const QString & KviIrcView::lastMessageText()
+{
+ KviIrcViewLine * pCur=m_pLastLine;
+ while(pCur)
+ {
+ switch(pCur->iMsgType)
+ {
+ case KVI_OUT_CHANPRIVMSG:
+ case KVI_OUT_CHANPRIVMSGCRYPTED:
+ case KVI_OUT_CHANNELNOTICE:
+ case KVI_OUT_CHANNELNOTICECRYPTED:
+ case KVI_OUT_ACTION:
+ case KVI_OUT_OWNPRIVMSG:
+ case KVI_OUT_OWNPRIVMSGCRYPTED:
+ case KVI_OUT_HIGHLIGHT:
+ return pCur->szText;
+ }
+ pCur=pCur->pPrev;
+ }
+ return KviQString::empty;
+}
+
+const QString & KviIrcView::lastLineOfText()
+{
+ if(!m_pLastLine)return KviQString::empty;
+ return m_pLastLine->szText;
+}
+
+//void KviIrcView::toggleLogging()
+//{
+// if(isLogging())stopLogging();
+// else {
+//#warning "FIX THIS COMMENTED STUFF"
+//
+// KviStr tmp;
+// m_pKviWindow->getDefaultLogName(tmp);
+// startLogging(tmp.ptr());
+//
+// }
+//}
+
+void KviIrcView::setMasterView(KviIrcView * v)
+{
+ if(m_pMasterView)disconnect(this,SLOT(masterDead()));
+ m_pMasterView = v;
+ if(m_pMasterView)connect(m_pMasterView,SIGNAL(destroyed()),this,SLOT(masterDead()));
+}
+
+void KviIrcView::masterDead()
+{
+ m_pMasterView = 0;
+}
+
+bool KviIrcView::startLogging(const QString& fname,bool bPrependCurBuffer)
+{
+ stopLogging();
+ QString szFname(fname);
+
+ if(fname.isEmpty())
+ {
+ if(!m_pKviWindow)return false;
+ m_pKviWindow->getDefaultLogFileName(szFname);
+ }
+
+#ifdef COMPILE_ZLIB_SUPPORT
+ if(KVI_OPTION_BOOL(KviOption_boolGzipLogs))
+ szFname+=".tmp";
+#endif
+
+ m_pLogFile = new QFile(szFname);
+
+ if(m_pLogFile->exists())
+ {
+ if(!m_pLogFile->open(IO_Append|IO_WriteOnly))
+ {
+ delete m_pLogFile;
+ m_pLogFile = 0;
+ return false;
+ }
+ } else {
+ if(!m_pLogFile->open(IO_WriteOnly))
+ {
+ delete m_pLogFile;
+ m_pLogFile = 0;
+ return false;
+ }
+ }
+
+ QString szLogStart;
+ szLogStart.sprintf(__tr2qs("### Log session started at %s ###"),QDateTime::currentDateTime().toString().utf8().data());
+ add2Log(szLogStart);
+ if(bPrependCurBuffer)
+ {
+ add2Log(__tr2qs("### Existing data buffer:"));
+ QString buffer;
+ getTextBuffer(buffer);
+ add2Log(buffer);
+ add2Log(__tr2qs("### End of existing data buffer."));
+ m_pLogFile->flush();
+ }
+
+ return true;
+}
+
+void KviIrcView::add2Log(const QString &szBuffer,int iMsgType)
+{
+ QString szToWrite=QString("%1 %2\n").arg(iMsgType).arg(szBuffer);
+ KviQCString szTmp = KviQString::toUtf8(szToWrite);
+ if(m_pLogFile->writeBlock(szTmp.data(),szTmp.length())==-1) debug("WARNING : Can not write to the log file.");
+}
+
+//=============================================================================
+//
+// Some slots
+//
+
+//void KviIrcView::saveBufferToFile()
+//{
+// // Yeah....this is powerful! :)
+//// KviStr cmd = "/DIALOG (savefile,Choose a file name,$deflogfile($window).savebuf,$window) "
+//// "if(\"$dialogresult\" != \"\")window $dialogmagic savebuffer $dialogresult";
+//// m_pFrm->m_pUserParser->parseUserCommand(cmd,m_pKviWindow);
+//}
+/*
+void KviIrcView::toggleTimestamp()
+{
+ setTimestamp(!timestamp());
+}
+
+void KviIrcView::toggleImages()
+{
+ setShowImages(!imagesVisible());
+}*/
+
+void KviIrcView::clearBuffer()
+{
+ emptyBuffer(true);
+}
+
+bool KviIrcView::saveBuffer(const char *filename)
+{
+ QFile f(QString::fromUtf8(filename));
+ if(!f.open(IO_WriteOnly|IO_Truncate))return false;
+ QString tmp;
+ getTextBuffer(tmp);
+ KviQCString tmpx = KviQString::toUtf8(tmp);
+ f.writeBlock(tmpx.data(),tmpx.length());
+ f.close();
+ return true;
+}
+
+void KviIrcView::prevLine(){ m_pScrollBar->subtractLine(); }
+void KviIrcView::nextLine(){ m_pScrollBar->addLine(); }
+void KviIrcView::prevPage(){ m_pScrollBar->subtractPage(); }
+void KviIrcView::nextPage(){ m_pScrollBar->addPage(); }
+
+void KviIrcView::setPrivateBackgroundPixmap(const QPixmap &pixmap,bool bRepaint)
+{
+ if(m_pPrivateBackgroundPixmap)
+ {
+ delete m_pPrivateBackgroundPixmap;
+ m_pPrivateBackgroundPixmap=0;
+ }
+ if(!pixmap.isNull())m_pPrivateBackgroundPixmap = new QPixmap(pixmap);
+
+ if(bRepaint)
+ update();
+}
+
+void KviIrcView::emptyBuffer(bool bRepaint)
+{
+ while(m_pLastLine != 0)removeHeadLine();
+ if(bRepaint)
+ update();
+}
+
+void KviIrcView::clearLineMark(bool bRepaint)
+{
+ m_uLineMarkLineIndex = KVI_IRCVIEW_INVALID_LINE_MARK_INDEX;
+ clearUnreaded();
+ if(bRepaint)
+ update();
+}
+
+void KviIrcView::checkLogDate()
+{
+ QDate::currentDate();
+}
+
+void KviIrcView::clearUnreaded()
+{
+ m_bHaveUnreadedHighlightedMessages = false;
+ m_bHaveUnreadedMessages = false;
+
+ if(m_pFrm)
+ if(m_pFrm->dockExtension())
+ m_pFrm->dockExtension()->refresh();
+}
+
+void KviIrcView::setMaxBufferSize(int maxBufSize,bool bRepaint)
+{
+ if(maxBufSize < 32)maxBufSize = 32;
+ m_iMaxLines = maxBufSize;
+ while(m_iNumLines > m_iMaxLines)removeHeadLine();
+ m_pScrollBar->setRange(0,m_iNumLines);
+ if(bRepaint)
+ update();
+}
+
+/*
+void KviIrcView::setShowImages(bool bShow,bool bRepaint)
+{
+ if(m_bShowImages!=bShow)
+ {
+ m_bShowImages=bShow;
+ if(bRepaint)paintEvent(0);
+ }
+}
+*/
+/*
+void KviIrcView::setTimestamp(bool bTimestamp)
+{
+ m_bTimestamp = bTimestamp;
+
+
+// STATS FOR A BUFFER FULL OF HIGHLY COLORED STRINGS , HIGHLY WRAPPED
+//
+// Lines = 1024 (322425 bytes - 314 KB) (avg 314 bytes per line) , well :)
+// string bytes = 87745 (85 KB)
+// attributes = 3576 (42912 bytes - 41 KB)
+// blocks = 12226 (146712 bytes - 143 KB)
+//
+// unsigned long int nAlloc = 0;
+// unsigned long int nLines = 0;
+// unsigned long int nStringBytes = 0;
+// unsigned long int nAttrBytes = 0;
+// unsigned long int nBlockBytes = 0;
+// unsigned long int nBlocks = 0;
+// unsigned long int nAttributes = 0;
+// KviIrcViewLine * l=m_pFirstLine;
+// while(l){
+// nLines++;
+// nAlloc += sizeof(KviIrcViewLine);
+// nStringBytes += l->data_len + 1;
+// nAlloc += l->data_len + 1;
+// nAlloc += (l->uChunkCount * sizeof(KviIrcViewLineChunk));
+// nAttrBytes +=(l->uChunkCount * sizeof(KviIrcViewLineChunk));
+// nAlloc += (l->iBlockCount * sizeof(KviIrcViewLineChunk));
+// nBlockBytes += (l->iBlockCount * sizeof(KviIrcViewLineChunk));
+// nBlocks += (l->iBlockCount);
+// nAttributes += (l->uChunkCount);
+// l = l->pNext;
+// }
+// debug("\n\nLines = %u (%u bytes - %u KB) (avg %u bytes per line)",nLines,nAlloc,nAlloc / 1024,nLines ? (nAlloc / nLines) : 0);
+// debug("string bytes = %u (%u KB)",nStringBytes,nStringBytes / 1024);
+// debug("attributes = %u (%u bytes - %u KB)",nAttributes,nAttrBytes,nAttrBytes / 1024);
+// debug("blocks = %u (%u bytes - %u KB)\n",nBlocks,nBlockBytes,nBlockBytes / 1024);
+
+}
+*/
+void KviIrcView::scrollBarPositionChanged(int newValue)
+{
+ if(!m_pCurLine)return;
+ int diff = 0;
+ if(newValue > m_iLastScrollBarValue)
+ {
+ while(newValue > m_iLastScrollBarValue)
+ {
+ if(m_pCurLine->pNext)
+ {
+ m_pCurLine=m_pCurLine->pNext;
+ diff++;
+ }
+ m_iLastScrollBarValue++;
+ }
+ } else {
+ while(newValue < m_iLastScrollBarValue)
+ {
+ if(m_pCurLine->pPrev)m_pCurLine=m_pCurLine->pPrev;
+ m_iLastScrollBarValue--;
+ }
+ }
+ if(!m_bSkipScrollBarRepaint)
+ repaint();
+ //update();
+// if(!m_bSkipScrollBarRepaint)postUpdateEvent();
+}
+
+bool KviIrcView::event(QEvent *e)
+{
+ if(e->type() == QEvent::User)
+ {
+ __range_valid(m_bPostedPaintEventPending);
+ if(m_iUnprocessedPaintEventRequests)
+ repaint();
+ // else we just had a pointEvent that did the job
+ m_bPostedPaintEventPending = false;
+ return true;
+ }
+ return QWidget::event(e);
+}
+
+void KviIrcView::wheelEvent(QWheelEvent *e)
+{
+#ifdef COMPILE_USE_QT4
+ static bool bHere = false;
+ if(bHere)return;
+ bHere = true; // Qt4 tends to jump into infinite recursion here
+#endif
+ g_pApp->sendEvent(m_pScrollBar,e);
+#ifdef COMPILE_USE_QT4
+ bHere = false;
+#endif
+}
+
+
+void KviIrcView::postUpdateEvent()
+{
+ // This will post a QEvent with a full repaint request
+ if(!m_bPostedPaintEventPending)
+ {
+ m_bPostedPaintEventPending = true;
+ QEvent *e = new QEvent(QEvent::User);
+ g_pApp->postEvent(this,e); // queue a repaint
+ }
+
+ m_iUnprocessedPaintEventRequests++; // paintEvent() will set it to 0
+
+ if(m_iUnprocessedPaintEventRequests == 3)
+ {
+ // Three unprocessed paint events...do it now
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(! ((KVI_OPTION_PIXMAP(KviOption_pixmapIrcViewBackground).pixmap()) || m_pPrivateBackgroundPixmap || g_pShadedChildGlobalDesktopBackground))
+ fastScroll(3);
+#else
+ if(! ((KVI_OPTION_PIXMAP(KviOption_pixmapIrcViewBackground).pixmap()) || m_pPrivateBackgroundPixmap))
+ fastScroll(3);
+#endif
+ else
+ repaint();
+ }
+}
+
+void KviIrcView::appendLine(KviIrcViewLine *ptr,bool bRepaint)
+{
+ //This one appends a KviIrcViewLine to
+ //the buffer list (at the end)
+ if(m_bMouseIsDown)
+ {
+ // Do not move the view!
+ // So we append the text line to a temp queue
+ // and then we'll add it when the mouse button is released
+ m_pMessagesStoppedWhileSelecting->append(ptr);
+ return;
+ }
+
+ // First log the line and assign the index
+ // Don't use add2log here!...we must go as fast as possible, so we avoid some push and pop calls, and also a couple of branches
+ if(m_pLogFile && KVI_OPTION_BOOL(KviOption_boolStripControlCodesInLogs))
+ {
+ // a slave view has no log files!
+ if(KVI_OPTION_MSGTYPE(ptr->iMsgType).logEnabled())
+ {
+ add2Log(ptr->szText,ptr->iMsgType);
+ // If we fail...this has been already reported!
+ }
+ // mmh.. when this overflows... we have problems (find doesn't work anymore :()
+ // but it overflows at 2^32 lines... 2^32 = 4.294.967.296 lines
+ // to spit it out in a year you'd need to print 1360 lines per second... that's insane :D
+ // a really fast but reasonable rate of printed lines might be 10 per second
+ // thus 429.496.730 seconds would be needed to make this var overflow
+ // that means more or less 13 years of text spitting at full rate :D
+ // I think that we can safely assume that this will NOT overflow ... your cpu (or you)
+ // will get mad before. Well.. it is not that dangerous after all...
+ ptr->uIndex = m_uNextLineIndex;
+ m_uNextLineIndex++;
+ } else {
+ // no log: we could have master view!
+ if(m_pMasterView)
+ {
+ if(m_pMasterView->m_pLogFile && KVI_OPTION_BOOL(KviOption_boolStripControlCodesInLogs))
+ {
+ if(KVI_OPTION_MSGTYPE(ptr->iMsgType).logEnabled())
+ {
+ m_pMasterView->add2Log(ptr->szText,ptr->iMsgType);
+ }
+ }
+ ptr->uIndex = m_pMasterView->m_uNextLineIndex;
+ m_pMasterView->m_uNextLineIndex++;
+ } else {
+ ptr->uIndex = m_uNextLineIndex;
+ m_uNextLineIndex++;
+ }
+ }
+
+ if(m_pLastLine)
+ {
+ // There is at least one line in the view
+ m_pLastLine->pNext=ptr;
+ ptr->pPrev =m_pLastLine;
+ ptr->pNext =0;
+ m_iNumLines++;
+
+ if(m_iNumLines > m_iMaxLines)
+ {
+ // Too many lines in the view...remove one
+ removeHeadLine();
+ if(m_pCurLine==m_pLastLine)
+ {
+ m_pCurLine=ptr;
+ if(bRepaint)
+ postUpdateEvent();
+ } else {
+ // the cur line remains the same
+ // the scroll bar must move up one place to be in sync
+ m_bSkipScrollBarRepaint = true;
+ if(m_pScrollBar->value() > 0)
+ {
+ m_iLastScrollBarValue--;
+ __range_valid(m_iLastScrollBarValue >= 0);
+ m_pScrollBar->subtractLine();
+ } // else will stay in sync
+ m_bSkipScrollBarRepaint = false;
+ }
+ } else {
+ // Just append
+ m_pScrollBar->setRange(0,m_iNumLines);
+ if(m_pCurLine==m_pLastLine)
+ {
+ m_bSkipScrollBarRepaint = true;
+ m_pScrollBar->addLine();
+ m_bSkipScrollBarRepaint = false;
+ if(bRepaint)
+ postUpdateEvent();
+ }
+ }
+ m_pLastLine=ptr;
+ } else {
+ //First line
+ m_pLastLine = ptr;
+ m_pFirstLine = ptr;
+ m_pCurLine = ptr;
+ ptr->pPrev = 0;
+ ptr->pNext = 0;
+ m_iNumLines = 1;
+ m_pScrollBar->setRange(0,1);
+ m_pScrollBar->addLine();
+ if(bRepaint)
+ postUpdateEvent();
+ }
+}
+
+//============== removeHeadLine ===============//
+
+void KviIrcView::removeHeadLine(bool bRepaint)
+{
+ //Removes the first line of the text buffer
+ if(!m_pLastLine)return;
+ if(m_pFirstLine == m_pCursorLine)m_pCursorLine = 0;
+
+ if(m_pFirstLine->pNext)
+ {
+ KviIrcViewLine *aux_ptr=m_pFirstLine->pNext; //get the next line
+ aux_ptr->pPrev=0; //becomes the first
+ if(m_pFirstLine==m_pCurLine)m_pCurLine=aux_ptr; //move the cur line if necessary
+ delete_text_line(m_pFirstLine); //delete the struct
+ m_pFirstLine=aux_ptr; //set the last
+ m_iNumLines--; //and decrement the count
+ } else { //unique line
+ m_pCurLine = 0;
+ delete_text_line(m_pFirstLine);
+ m_pFirstLine = 0;
+ m_iNumLines = 0;
+ m_pLastLine = 0;
+ }
+ if(bRepaint)
+ repaint();
+}
+
+void KviIrcView::splitMessagesTo(KviIrcView *v)
+{
+ v->emptyBuffer(false);
+
+ KviIrcViewLine * l = m_pFirstLine;
+ KviIrcViewLine * tmp;
+ while(l)
+ switch(l->iMsgType)
+ {
+ case KVI_OUT_CHANPRIVMSG:
+ case KVI_OUT_CHANPRIVMSGCRYPTED:
+ case KVI_OUT_CHANNELNOTICE:
+ case KVI_OUT_CHANNELNOTICECRYPTED:
+ case KVI_OUT_ACTION:
+ case KVI_OUT_OWNPRIVMSG:
+ case KVI_OUT_OWNPRIVMSGCRYPTED:
+ case KVI_OUT_HIGHLIGHT:
+ {
+ m_iNumLines--;
+ v->m_iNumLines++;
+
+ if(l->pNext)l->pNext->pPrev = l->pPrev;
+ if(l->pPrev)l->pPrev->pNext = l->pNext;
+ if(l == m_pFirstLine)m_pFirstLine = l->pNext;
+ if(l == m_pLastLine)m_pLastLine = l->pPrev;
+ if(v->m_pLastLine)
+ {
+ v->m_pLastLine->pNext = l;
+ l->pPrev = v->m_pLastLine;
+ v->m_pLastLine = l;
+ } else {
+ v->m_pFirstLine = l;
+ l->pPrev = 0;
+ v->m_pLastLine = l;
+ }
+ tmp = l->pNext;
+ l->pNext = 0;
+ l = tmp;
+ }
+ break;
+ default:
+ l = l->pNext;
+ break;
+ }
+ v->m_pCurLine = v->m_pLastLine;
+ m_pCurLine = m_pLastLine;
+
+ v->m_pCursorLine = 0;
+ m_pCursorLine = 0;
+
+ m_iLastScrollBarValue = m_iNumLines;
+ m_pScrollBar->setRange(0,m_iNumLines);
+ m_pScrollBar->setValue(m_iNumLines);
+
+ repaint();
+
+ v->m_iLastScrollBarValue = v->m_iNumLines;
+ v->m_pScrollBar->setRange(0,v->m_iNumLines);
+ v->m_pScrollBar->setValue(v->m_iNumLines);
+ v->repaint();
+
+}
+
+void KviIrcView::appendMessagesFrom(KviIrcView *v)
+{
+ if(!m_pLastLine)
+ {
+ m_pFirstLine = v->m_pFirstLine;
+ } else {
+ m_pLastLine->pNext = v->m_pFirstLine;
+ v->m_pFirstLine->pPrev = m_pLastLine;
+ }
+ m_pLastLine = v->m_pLastLine;
+ m_pCurLine = m_pLastLine;
+ m_pCursorLine = 0;
+ v->m_pFirstLine = 0;
+ v->m_pLastLine = 0;
+ v->m_pCurLine = 0;
+ v->m_pCursorLine = 0;
+ m_iNumLines += v->m_iNumLines;
+ v->m_iNumLines = 0;
+// v->m_pScrollBar->setRange(0,0);
+// v->m_pScrollBar->setValue(0);
+ m_iLastScrollBarValue = m_iNumLines;
+ m_pScrollBar->setRange(0,m_iNumLines);
+ m_pScrollBar->setValue(m_iNumLines);
+
+ repaint();
+}
+
+void KviIrcView::joinMessagesFrom(KviIrcView *v)
+{
+ KviIrcViewLine * l1 = m_pFirstLine;
+ KviIrcViewLine * l2 = v->m_pFirstLine;
+ KviIrcViewLine * tmp;
+
+ while(l2)
+ {
+ if(l1)
+ {
+ if(l2->uIndex < l1->uIndex)
+ {
+ // the external message is older than the current internal one
+ l2->pPrev = l1->pPrev;
+ if(l1->pPrev)l1->pPrev->pNext = l2;
+ else m_pFirstLine = l2;
+ l1->pPrev = l2;
+ tmp = l2->pNext;
+ l2->pNext = l1;
+ l2 = tmp;
+ } else {
+ // the external message is younger than the current internal one
+ l1 = l1->pNext;
+ }
+ } else {
+ // There is no current internal message (ran over the end)
+ // merge at the end then
+ if(m_pFirstLine)
+ {
+ m_pLastLine->pNext = l2;
+ l2->pPrev = m_pLastLine;
+ } else {
+ m_pFirstLine = l2;
+ l2->pPrev = 0;
+ }
+ tmp = l2->pNext;
+ l2->pNext = 0;
+ m_pLastLine = l2;
+ l2 = tmp;
+ }
+ }
+
+ m_pCurLine = m_pLastLine;
+ m_pCursorLine = 0;
+ v->m_pFirstLine = 0;
+ v->m_pLastLine = 0;
+ v->m_pCurLine = 0;
+ v->m_pCursorLine = 0;
+ m_iNumLines += v->m_iNumLines;
+ v->m_iNumLines = 0;
+// v->m_pScrollBar->setRange(0,0);
+// v->m_pScrollBar->setValue(0);
+
+ m_iLastScrollBarValue = m_iNumLines;
+ m_pScrollBar->setRange(0,m_iNumLines);
+ m_pScrollBar->setValue(m_iNumLines);
+
+ repaint();
+}
+
+void KviIrcView::appendText(int iMsgType,const kvi_wchar_t *data_ptr,int iFlags)
+{
+ //appends a text string to the buffer list
+ //splits the lines
+ __range_valid(data_ptr);
+ m_pLastLinkUnderMouse = 0;
+
+ while(*data_ptr)
+ { //Have more data
+ KviIrcViewLine *line_ptr=new KviIrcViewLine; //create a line struct
+ line_ptr->iMsgType=iMsgType;
+ line_ptr->iMaxLineWidth=-1;
+ line_ptr->iBlockCount=0;
+
+ if(!KVI_OPTION_BOOL(KviOption_boolStripControlCodesInLogs))
+ {
+ QString szBuffer;
+ kvi_appendWCharToQStringWithLength(&szBuffer,data_ptr,kvi_wstrlen(data_ptr));
+ szBuffer.prepend(QDateTime::currentDateTime().toString("[h:mm:ss] "));
+ if(m_pLogFile && KVI_OPTION_MSGTYPE(iMsgType).logEnabled())
+ {
+ add2Log(szBuffer,iMsgType);
+ } else if(m_pMasterView) {
+ if(m_pMasterView->m_pLogFile && KVI_OPTION_MSGTYPE(iMsgType).logEnabled())
+ {
+ m_pMasterView->add2Log(szBuffer,iMsgType);
+ }
+ }
+ }
+
+ data_ptr=getTextLine(iMsgType,data_ptr,line_ptr,!(iFlags & NoTimestamp));
+ appendLine(line_ptr,!(iFlags & NoRepaint));
+ if(iFlags & SetLineMark)
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolTrackLastReadTextViewLine))
+ {
+ m_uLineMarkLineIndex = line_ptr->uIndex;
+ iFlags &= ~SetLineMark;
+ }
+ m_bHaveUnreadedHighlightedMessages = m_bHaveUnreadedHighlightedMessages || iMsgType == KVI_OUT_HIGHLIGHT;
+ m_bHaveUnreadedMessages = m_bHaveUnreadedMessages ||
+ iMsgType == KVI_OUT_CHANPRIVMSG ||
+ iMsgType == KVI_OUT_CHANPRIVMSGCRYPTED ||
+ iMsgType == KVI_OUT_CHANNELNOTICE ||
+ iMsgType == KVI_OUT_CHANNELNOTICECRYPTED ||
+ iMsgType == KVI_OUT_ACTION ||
+ iMsgType == KVI_OUT_OWNPRIVMSGCRYPTED ||
+ iMsgType == KVI_OUT_HIGHLIGHT;
+ }
+ }
+}
+
+
+void KviIrcView::getLinkEscapeCommand(QString &buffer,const QString &szPayload,const QString &escape_label)
+{
+ if(szPayload.isEmpty())return;
+
+ int idx = szPayload.find(escape_label);
+ if(idx == -1)return;
+ idx += escape_label.length();
+
+ int idx2 = szPayload.find("[!",idx);
+ int len = idx2 == -1 ? szPayload.length() - idx : idx2 - idx;
+
+ buffer = szPayload.mid(idx,len);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The IrcView : Get text line
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+static kvi_wchar_t case_xtx_XX[256] =
+{
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
+};
+
+static kvi_wchar_t case_ltu_00[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0130, 0x004A, 0x212A, 0x004C, 0x004D, 0x004E, 0x004F,
+ 0x0050, 0x0051, 0x0052, 0x017F, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x212B, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0000, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x0178
+};
+
+
+static kvi_wchar_t case_ltu_01[256] =
+{
+ 0x0000, 0x0100, 0x0000, 0x0102, 0x0000, 0x0104, 0x0000, 0x0106, 0x0000, 0x0108, 0x0000, 0x010A, 0x0000, 0x010C, 0x0000, 0x010E,
+ 0x0000, 0x0110, 0x0000, 0x0112, 0x0000, 0x0114, 0x0000, 0x0116, 0x0000, 0x0118, 0x0000, 0x011A, 0x0000, 0x011C, 0x0000, 0x011E,
+ 0x0000, 0x0120, 0x0000, 0x0122, 0x0000, 0x0124, 0x0000, 0x0126, 0x0000, 0x0128, 0x0000, 0x012A, 0x0000, 0x012C, 0x0000, 0x012E,
+ 0x0000, 0x0049, 0x0000, 0x0132, 0x0000, 0x0134, 0x0000, 0x0136, 0x0000, 0x0000, 0x0139, 0x0000, 0x013B, 0x0000, 0x013D, 0x0000,
+ 0x013F, 0x0000, 0x0141, 0x0000, 0x0143, 0x0000, 0x0145, 0x0000, 0x0147, 0x0000, 0x0000, 0x014A, 0x0000, 0x014C, 0x0000, 0x014E,
+ 0x0000, 0x0150, 0x0000, 0x0152, 0x0000, 0x0154, 0x0000, 0x0156, 0x0000, 0x0158, 0x0000, 0x015A, 0x0000, 0x015C, 0x0000, 0x015E,
+ 0x0000, 0x0160, 0x0000, 0x0162, 0x0000, 0x0164, 0x0000, 0x0166, 0x0000, 0x0168, 0x0000, 0x016A, 0x0000, 0x016C, 0x0000, 0x016E,
+ 0x0000, 0x0170, 0x0000, 0x0172, 0x0000, 0x0174, 0x0000, 0x0176, 0x0000, 0x0000, 0x0179, 0x0000, 0x017B, 0x0000, 0x017D, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0182, 0x0000, 0x0184, 0x0000, 0x0000, 0x0187, 0x0000, 0x0000, 0x0000, 0x018B, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0191, 0x0000, 0x0000, 0x01F6, 0x0000, 0x0000, 0x0000, 0x0198, 0x0000, 0x0000, 0x0000, 0x0000, 0x0220, 0x0000,
+ 0x0000, 0x01A0, 0x0000, 0x01A2, 0x0000, 0x01A4, 0x0000, 0x0000, 0x01A7, 0x0000, 0x0000, 0x0000, 0x0000, 0x01AC, 0x0000, 0x0000,
+ 0x01AF, 0x0000, 0x0000, 0x0000, 0x01B3, 0x0000, 0x01B5, 0x0000, 0x0000, 0x01B8, 0x0000, 0x0000, 0x0000, 0x01BC, 0x0000, 0x01F7,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01C5, 0x0000, 0x0000, 0x01C8, 0x0000, 0x0000, 0x01CB, 0x0000, 0x01CD, 0x0000,
+ 0x01CF, 0x0000, 0x01D1, 0x0000, 0x01D3, 0x0000, 0x01D5, 0x0000, 0x01D7, 0x0000, 0x01D9, 0x0000, 0x01DB, 0x018E, 0x0000, 0x01DE,
+ 0x0000, 0x01E0, 0x0000, 0x01E2, 0x0000, 0x01E4, 0x0000, 0x01E6, 0x0000, 0x01E8, 0x0000, 0x01EA, 0x0000, 0x01EC, 0x0000, 0x01EE,
+ 0x0000, 0x0000, 0x0000, 0x01F2, 0x0000, 0x01F4, 0x0000, 0x0000, 0x0000, 0x01F8, 0x0000, 0x01FA, 0x0000, 0x01FC, 0x0000, 0x01FE
+};
+
+
+static kvi_wchar_t case_ltu_02[256] =
+{
+ 0x0000, 0x0200, 0x0000, 0x0202, 0x0000, 0x0204, 0x0000, 0x0206, 0x0000, 0x0208, 0x0000, 0x020A, 0x0000, 0x020C, 0x0000, 0x020E,
+ 0x0000, 0x0210, 0x0000, 0x0212, 0x0000, 0x0214, 0x0000, 0x0216, 0x0000, 0x0218, 0x0000, 0x021A, 0x0000, 0x021C, 0x0000, 0x021E,
+ 0x0000, 0x0000, 0x0000, 0x0222, 0x0000, 0x0224, 0x0000, 0x0226, 0x0000, 0x0228, 0x0000, 0x022A, 0x0000, 0x022C, 0x0000, 0x022E,
+ 0x0000, 0x0230, 0x0000, 0x0232, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0181, 0x0186, 0x0000, 0x0189, 0x018A, 0x0000, 0x018F, 0x0000, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0193, 0x0000, 0x0000, 0x0194, 0x0000, 0x0000, 0x0000, 0x0000, 0x0197, 0x0196, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x019C,
+ 0x0000, 0x0000, 0x019D, 0x0000, 0x0000, 0x019F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x01A6, 0x0000, 0x0000, 0x01A9, 0x0000, 0x0000, 0x0000, 0x0000, 0x01AE, 0x0000, 0x01B1, 0x01B2, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x01B7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_ltu_03[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0386, 0x0388, 0x0389, 0x038A,
+ 0x0000, 0x0391, 0x03D0, 0x0393, 0x0394, 0x03F5, 0x0396, 0x0397, 0x03F4, 0x1FBE, 0x03F0, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03D6, 0x03F1, 0x0000, 0x03F2, 0x03A4, 0x03A5, 0x03D5, 0x03A7, 0x03A8, 0x2126, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03D8, 0x0000, 0x03DA, 0x0000, 0x03DC, 0x0000, 0x03DE,
+ 0x0000, 0x03E0, 0x0000, 0x03E2, 0x0000, 0x03E4, 0x0000, 0x03E6, 0x0000, 0x03E8, 0x0000, 0x03EA, 0x0000, 0x03EC, 0x0000, 0x03EE,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_ltu_04[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x040D, 0x040E, 0x040F,
+ 0x0000, 0x0460, 0x0000, 0x0462, 0x0000, 0x0464, 0x0000, 0x0466, 0x0000, 0x0468, 0x0000, 0x046A, 0x0000, 0x046C, 0x0000, 0x046E,
+ 0x0000, 0x0470, 0x0000, 0x0472, 0x0000, 0x0474, 0x0000, 0x0476, 0x0000, 0x0478, 0x0000, 0x047A, 0x0000, 0x047C, 0x0000, 0x047E,
+ 0x0000, 0x0480, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x048A, 0x0000, 0x048C, 0x0000, 0x048E,
+ 0x0000, 0x0490, 0x0000, 0x0492, 0x0000, 0x0494, 0x0000, 0x0496, 0x0000, 0x0498, 0x0000, 0x049A, 0x0000, 0x049C, 0x0000, 0x049E,
+ 0x0000, 0x04A0, 0x0000, 0x04A2, 0x0000, 0x04A4, 0x0000, 0x04A6, 0x0000, 0x04A8, 0x0000, 0x04AA, 0x0000, 0x04AC, 0x0000, 0x04AE,
+ 0x0000, 0x04B0, 0x0000, 0x04B2, 0x0000, 0x04B4, 0x0000, 0x04B6, 0x0000, 0x04B8, 0x0000, 0x04BA, 0x0000, 0x04BC, 0x0000, 0x04BE,
+ 0x0000, 0x0000, 0x04C1, 0x0000, 0x04C3, 0x0000, 0x04C5, 0x0000, 0x04C7, 0x0000, 0x04C9, 0x0000, 0x04CB, 0x0000, 0x04CD, 0x0000,
+ 0x0000, 0x04D0, 0x0000, 0x04D2, 0x0000, 0x04D4, 0x0000, 0x04D6, 0x0000, 0x04D8, 0x0000, 0x04DA, 0x0000, 0x04DC, 0x0000, 0x04DE,
+ 0x0000, 0x04E0, 0x0000, 0x04E2, 0x0000, 0x04E4, 0x0000, 0x04E6, 0x0000, 0x04E8, 0x0000, 0x04EA, 0x0000, 0x04EC, 0x0000, 0x04EE,
+ 0x0000, 0x04F0, 0x0000, 0x04F2, 0x0000, 0x04F4, 0x0000, 0x0000, 0x0000, 0x04F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_ltu_05[256] =
+{
+ 0x0000, 0x0500, 0x0000, 0x0502, 0x0000, 0x0504, 0x0000, 0x0506, 0x0000, 0x0508, 0x0000, 0x050A, 0x0000, 0x050C, 0x0000, 0x050E,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0531, 0x0532, 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, 0x0538, 0x0539, 0x053A, 0x053B, 0x053C, 0x053D, 0x053E, 0x053F,
+ 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, 0x0545, 0x0546, 0x0547, 0x0548, 0x0549, 0x054A, 0x054B, 0x054C, 0x054D, 0x054E, 0x054F,
+ 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_ltu_1E[256] =
+{
+ 0x0000, 0x1E00, 0x0000, 0x1E02, 0x0000, 0x1E04, 0x0000, 0x1E06, 0x0000, 0x1E08, 0x0000, 0x1E0A, 0x0000, 0x1E0C, 0x0000, 0x1E0E,
+ 0x0000, 0x1E10, 0x0000, 0x1E12, 0x0000, 0x1E14, 0x0000, 0x1E16, 0x0000, 0x1E18, 0x0000, 0x1E1A, 0x0000, 0x1E1C, 0x0000, 0x1E1E,
+ 0x0000, 0x1E20, 0x0000, 0x1E22, 0x0000, 0x1E24, 0x0000, 0x1E26, 0x0000, 0x1E28, 0x0000, 0x1E2A, 0x0000, 0x1E2C, 0x0000, 0x1E2E,
+ 0x0000, 0x1E30, 0x0000, 0x1E32, 0x0000, 0x1E34, 0x0000, 0x1E36, 0x0000, 0x1E38, 0x0000, 0x1E3A, 0x0000, 0x1E3C, 0x0000, 0x1E3E,
+ 0x0000, 0x1E40, 0x0000, 0x1E42, 0x0000, 0x1E44, 0x0000, 0x1E46, 0x0000, 0x1E48, 0x0000, 0x1E4A, 0x0000, 0x1E4C, 0x0000, 0x1E4E,
+ 0x0000, 0x1E50, 0x0000, 0x1E52, 0x0000, 0x1E54, 0x0000, 0x1E56, 0x0000, 0x1E58, 0x0000, 0x1E5A, 0x0000, 0x1E5C, 0x0000, 0x1E5E,
+ 0x0000, 0x1E9B, 0x0000, 0x1E62, 0x0000, 0x1E64, 0x0000, 0x1E66, 0x0000, 0x1E68, 0x0000, 0x1E6A, 0x0000, 0x1E6C, 0x0000, 0x1E6E,
+ 0x0000, 0x1E70, 0x0000, 0x1E72, 0x0000, 0x1E74, 0x0000, 0x1E76, 0x0000, 0x1E78, 0x0000, 0x1E7A, 0x0000, 0x1E7C, 0x0000, 0x1E7E,
+ 0x0000, 0x1E80, 0x0000, 0x1E82, 0x0000, 0x1E84, 0x0000, 0x1E86, 0x0000, 0x1E88, 0x0000, 0x1E8A, 0x0000, 0x1E8C, 0x0000, 0x1E8E,
+ 0x0000, 0x1E90, 0x0000, 0x1E92, 0x0000, 0x1E94, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x1EA0, 0x0000, 0x1EA2, 0x0000, 0x1EA4, 0x0000, 0x1EA6, 0x0000, 0x1EA8, 0x0000, 0x1EAA, 0x0000, 0x1EAC, 0x0000, 0x1EAE,
+ 0x0000, 0x1EB0, 0x0000, 0x1EB2, 0x0000, 0x1EB4, 0x0000, 0x1EB6, 0x0000, 0x1EB8, 0x0000, 0x1EBA, 0x0000, 0x1EBC, 0x0000, 0x1EBE,
+ 0x0000, 0x1EC0, 0x0000, 0x1EC2, 0x0000, 0x1EC4, 0x0000, 0x1EC6, 0x0000, 0x1EC8, 0x0000, 0x1ECA, 0x0000, 0x1ECC, 0x0000, 0x1ECE,
+ 0x0000, 0x1ED0, 0x0000, 0x1ED2, 0x0000, 0x1ED4, 0x0000, 0x1ED6, 0x0000, 0x1ED8, 0x0000, 0x1EDA, 0x0000, 0x1EDC, 0x0000, 0x1EDE,
+ 0x0000, 0x1EE0, 0x0000, 0x1EE2, 0x0000, 0x1EE4, 0x0000, 0x1EE6, 0x0000, 0x1EE8, 0x0000, 0x1EEA, 0x0000, 0x1EEC, 0x0000, 0x1EEE,
+ 0x0000, 0x1EF0, 0x0000, 0x1EF2, 0x0000, 0x1EF4, 0x0000, 0x1EF6, 0x0000, 0x1EF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_ltu_1F[256] =
+{
+ 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB, 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000,
+ 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1FB8, 0x1FB9, 0x0000, 0x1FBC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x1FCC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1FD8, 0x1FD9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1FE8, 0x1FE9, 0x0000, 0x0000, 0x0000, 0x1FEC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x1FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_ltu_21[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_ltu_24[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x24B6, 0x24B7, 0x24B8, 0x24B9, 0x24BA, 0x24BB, 0x24BC, 0x24BD, 0x24BE, 0x24BF, 0x24C0, 0x24C1, 0x24C2, 0x24C3, 0x24C4, 0x24C5,
+ 0x24C6, 0x24C7, 0x24C8, 0x24C9, 0x24CA, 0x24CB, 0x24CC, 0x24CD, 0x24CE, 0x24CF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_ltu_FF[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F,
+ 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+kvi_wchar_t * kvirc_case_map_ltu[256] =
+{
+ case_ltu_00, case_ltu_01, case_ltu_02, case_ltu_03, case_ltu_04, case_ltu_05, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_ltu_1E, case_ltu_1F,
+ case_xtx_XX, case_ltu_21, case_xtx_XX, case_xtx_XX, case_ltu_24, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_ltu_FF
+};
+
+
+static kvi_wchar_t case_utl_00[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0131, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03BC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0000, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_01[256] =
+{
+ 0x0101, 0x0000, 0x0103, 0x0000, 0x0105, 0x0000, 0x0107, 0x0000, 0x0109, 0x0000, 0x010B, 0x0000, 0x010D, 0x0000, 0x010F, 0x0000,
+ 0x0111, 0x0000, 0x0113, 0x0000, 0x0115, 0x0000, 0x0117, 0x0000, 0x0119, 0x0000, 0x011B, 0x0000, 0x011D, 0x0000, 0x011F, 0x0000,
+ 0x0121, 0x0000, 0x0123, 0x0000, 0x0125, 0x0000, 0x0127, 0x0000, 0x0129, 0x0000, 0x012B, 0x0000, 0x012D, 0x0000, 0x012F, 0x0000,
+ 0x0069, 0x0000, 0x0133, 0x0000, 0x0135, 0x0000, 0x0137, 0x0000, 0x0000, 0x013A, 0x0000, 0x013C, 0x0000, 0x013E, 0x0000, 0x0140,
+ 0x0000, 0x0142, 0x0000, 0x0144, 0x0000, 0x0146, 0x0000, 0x0148, 0x0000, 0x0000, 0x014B, 0x0000, 0x014D, 0x0000, 0x014F, 0x0000,
+ 0x0151, 0x0000, 0x0153, 0x0000, 0x0155, 0x0000, 0x0157, 0x0000, 0x0159, 0x0000, 0x015B, 0x0000, 0x015D, 0x0000, 0x015F, 0x0000,
+ 0x0161, 0x0000, 0x0163, 0x0000, 0x0165, 0x0000, 0x0167, 0x0000, 0x0169, 0x0000, 0x016B, 0x0000, 0x016D, 0x0000, 0x016F, 0x0000,
+ 0x0171, 0x0000, 0x0173, 0x0000, 0x0175, 0x0000, 0x0177, 0x0000, 0x00FF, 0x017A, 0x0000, 0x017C, 0x0000, 0x017E, 0x0000, 0x0073,
+ 0x0000, 0x0253, 0x0183, 0x0000, 0x0185, 0x0000, 0x0254, 0x0188, 0x0000, 0x0256, 0x0257, 0x018C, 0x0000, 0x0000, 0x01DD, 0x0259,
+ 0x025B, 0x0192, 0x0000, 0x0260, 0x0263, 0x0000, 0x0269, 0x0268, 0x0199, 0x0000, 0x0000, 0x0000, 0x026F, 0x0272, 0x0000, 0x0275,
+ 0x01A1, 0x0000, 0x01A3, 0x0000, 0x01A5, 0x0000, 0x0280, 0x01A8, 0x0000, 0x0283, 0x0000, 0x0000, 0x01AD, 0x0000, 0x0288, 0x01B0,
+ 0x0000, 0x028A, 0x028B, 0x01B4, 0x0000, 0x01B6, 0x0000, 0x0292, 0x01B9, 0x0000, 0x0000, 0x0000, 0x01BD, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x01C6, 0x01C6, 0x0000, 0x01C9, 0x01C9, 0x0000, 0x01CC, 0x01CC, 0x0000, 0x01CE, 0x0000, 0x01D0,
+ 0x0000, 0x01D2, 0x0000, 0x01D4, 0x0000, 0x01D6, 0x0000, 0x01D8, 0x0000, 0x01DA, 0x0000, 0x01DC, 0x0000, 0x0000, 0x01DF, 0x0000,
+ 0x01E1, 0x0000, 0x01E3, 0x0000, 0x01E5, 0x0000, 0x01E7, 0x0000, 0x01E9, 0x0000, 0x01EB, 0x0000, 0x01ED, 0x0000, 0x01EF, 0x0000,
+ 0x0000, 0x01F3, 0x01F3, 0x0000, 0x01F5, 0x0000, 0x0195, 0x01BF, 0x01F9, 0x0000, 0x01FB, 0x0000, 0x01FD, 0x0000, 0x01FF, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_02[256] =
+{
+ 0x0201, 0x0000, 0x0203, 0x0000, 0x0205, 0x0000, 0x0207, 0x0000, 0x0209, 0x0000, 0x020B, 0x0000, 0x020D, 0x0000, 0x020F, 0x0000,
+ 0x0211, 0x0000, 0x0213, 0x0000, 0x0215, 0x0000, 0x0217, 0x0000, 0x0219, 0x0000, 0x021B, 0x0000, 0x021D, 0x0000, 0x021F, 0x0000,
+ 0x019E, 0x0000, 0x0223, 0x0000, 0x0225, 0x0000, 0x0227, 0x0000, 0x0229, 0x0000, 0x022B, 0x0000, 0x022D, 0x0000, 0x022F, 0x0000,
+ 0x0231, 0x0000, 0x0233, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_03[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03B9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03AC, 0x0000, 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE,
+ 0x0000, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x03C3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x03B2, 0x03B8, 0x0000, 0x0000, 0x0000, 0x03C6, 0x03C0, 0x0000, 0x03D9, 0x0000, 0x03DB, 0x0000, 0x03DD, 0x0000, 0x03DF, 0x0000,
+ 0x03E1, 0x0000, 0x03E3, 0x0000, 0x03E5, 0x0000, 0x03E7, 0x0000, 0x03E9, 0x0000, 0x03EB, 0x0000, 0x03ED, 0x0000, 0x03EF, 0x0000,
+ 0x03BA, 0x03C1, 0x03C3, 0x0000, 0x03B8, 0x03B5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_04[256] =
+{
+ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0461, 0x0000, 0x0463, 0x0000, 0x0465, 0x0000, 0x0467, 0x0000, 0x0469, 0x0000, 0x046B, 0x0000, 0x046D, 0x0000, 0x046F, 0x0000,
+ 0x0471, 0x0000, 0x0473, 0x0000, 0x0475, 0x0000, 0x0477, 0x0000, 0x0479, 0x0000, 0x047B, 0x0000, 0x047D, 0x0000, 0x047F, 0x0000,
+ 0x0481, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x048B, 0x0000, 0x048D, 0x0000, 0x048F, 0x0000,
+ 0x0491, 0x0000, 0x0493, 0x0000, 0x0495, 0x0000, 0x0497, 0x0000, 0x0499, 0x0000, 0x049B, 0x0000, 0x049D, 0x0000, 0x049F, 0x0000,
+ 0x04A1, 0x0000, 0x04A3, 0x0000, 0x04A5, 0x0000, 0x04A7, 0x0000, 0x04A9, 0x0000, 0x04AB, 0x0000, 0x04AD, 0x0000, 0x04AF, 0x0000,
+ 0x04B1, 0x0000, 0x04B3, 0x0000, 0x04B5, 0x0000, 0x04B7, 0x0000, 0x04B9, 0x0000, 0x04BB, 0x0000, 0x04BD, 0x0000, 0x04BF, 0x0000,
+ 0x0000, 0x04C2, 0x0000, 0x04C4, 0x0000, 0x04C6, 0x0000, 0x04C8, 0x0000, 0x04CA, 0x0000, 0x04CC, 0x0000, 0x04CE, 0x0000, 0x0000,
+ 0x04D1, 0x0000, 0x04D3, 0x0000, 0x04D5, 0x0000, 0x04D7, 0x0000, 0x04D9, 0x0000, 0x04DB, 0x0000, 0x04DD, 0x0000, 0x04DF, 0x0000,
+ 0x04E1, 0x0000, 0x04E3, 0x0000, 0x04E5, 0x0000, 0x04E7, 0x0000, 0x04E9, 0x0000, 0x04EB, 0x0000, 0x04ED, 0x0000, 0x04EF, 0x0000,
+ 0x04F1, 0x0000, 0x04F3, 0x0000, 0x04F5, 0x0000, 0x0000, 0x0000, 0x04F9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_05[256] =
+{
+ 0x0501, 0x0000, 0x0503, 0x0000, 0x0505, 0x0000, 0x0507, 0x0000, 0x0509, 0x0000, 0x050B, 0x0000, 0x050D, 0x0000, 0x050F, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
+ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
+ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_1E[256] =
+{
+ 0x1E01, 0x0000, 0x1E03, 0x0000, 0x1E05, 0x0000, 0x1E07, 0x0000, 0x1E09, 0x0000, 0x1E0B, 0x0000, 0x1E0D, 0x0000, 0x1E0F, 0x0000,
+ 0x1E11, 0x0000, 0x1E13, 0x0000, 0x1E15, 0x0000, 0x1E17, 0x0000, 0x1E19, 0x0000, 0x1E1B, 0x0000, 0x1E1D, 0x0000, 0x1E1F, 0x0000,
+ 0x1E21, 0x0000, 0x1E23, 0x0000, 0x1E25, 0x0000, 0x1E27, 0x0000, 0x1E29, 0x0000, 0x1E2B, 0x0000, 0x1E2D, 0x0000, 0x1E2F, 0x0000,
+ 0x1E31, 0x0000, 0x1E33, 0x0000, 0x1E35, 0x0000, 0x1E37, 0x0000, 0x1E39, 0x0000, 0x1E3B, 0x0000, 0x1E3D, 0x0000, 0x1E3F, 0x0000,
+ 0x1E41, 0x0000, 0x1E43, 0x0000, 0x1E45, 0x0000, 0x1E47, 0x0000, 0x1E49, 0x0000, 0x1E4B, 0x0000, 0x1E4D, 0x0000, 0x1E4F, 0x0000,
+ 0x1E51, 0x0000, 0x1E53, 0x0000, 0x1E55, 0x0000, 0x1E57, 0x0000, 0x1E59, 0x0000, 0x1E5B, 0x0000, 0x1E5D, 0x0000, 0x1E5F, 0x0000,
+ 0x1E61, 0x0000, 0x1E63, 0x0000, 0x1E65, 0x0000, 0x1E67, 0x0000, 0x1E69, 0x0000, 0x1E6B, 0x0000, 0x1E6D, 0x0000, 0x1E6F, 0x0000,
+ 0x1E71, 0x0000, 0x1E73, 0x0000, 0x1E75, 0x0000, 0x1E77, 0x0000, 0x1E79, 0x0000, 0x1E7B, 0x0000, 0x1E7D, 0x0000, 0x1E7F, 0x0000,
+ 0x1E81, 0x0000, 0x1E83, 0x0000, 0x1E85, 0x0000, 0x1E87, 0x0000, 0x1E89, 0x0000, 0x1E8B, 0x0000, 0x1E8D, 0x0000, 0x1E8F, 0x0000,
+ 0x1E91, 0x0000, 0x1E93, 0x0000, 0x1E95, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E61, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1EA1, 0x0000, 0x1EA3, 0x0000, 0x1EA5, 0x0000, 0x1EA7, 0x0000, 0x1EA9, 0x0000, 0x1EAB, 0x0000, 0x1EAD, 0x0000, 0x1EAF, 0x0000,
+ 0x1EB1, 0x0000, 0x1EB3, 0x0000, 0x1EB5, 0x0000, 0x1EB7, 0x0000, 0x1EB9, 0x0000, 0x1EBB, 0x0000, 0x1EBD, 0x0000, 0x1EBF, 0x0000,
+ 0x1EC1, 0x0000, 0x1EC3, 0x0000, 0x1EC5, 0x0000, 0x1EC7, 0x0000, 0x1EC9, 0x0000, 0x1ECB, 0x0000, 0x1ECD, 0x0000, 0x1ECF, 0x0000,
+ 0x1ED1, 0x0000, 0x1ED3, 0x0000, 0x1ED5, 0x0000, 0x1ED7, 0x0000, 0x1ED9, 0x0000, 0x1EDB, 0x0000, 0x1EDD, 0x0000, 0x1EDF, 0x0000,
+ 0x1EE1, 0x0000, 0x1EE3, 0x0000, 0x1EE5, 0x0000, 0x1EE7, 0x0000, 0x1EE9, 0x0000, 0x1EEB, 0x0000, 0x1EED, 0x0000, 0x1EEF, 0x0000,
+ 0x1EF1, 0x0000, 0x1EF3, 0x0000, 0x1EF5, 0x0000, 0x1EF7, 0x0000, 0x1EF9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_1F[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x0000, 0x03B9, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_21[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03C9, 0x0000, 0x0000, 0x0000, 0x006B, 0x00E5, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_24[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x24D0, 0x24D1, 0x24D2, 0x24D3, 0x24D4, 0x24D5, 0x24D6, 0x24D7, 0x24D8, 0x24D9,
+ 0x24DA, 0x24DB, 0x24DC, 0x24DD, 0x24DE, 0x24DF, 0x24E0, 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, 0x24E7, 0x24E8, 0x24E9,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+static kvi_wchar_t case_utl_FF[256] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
+ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+
+kvi_wchar_t * kvirc_case_map_utl[256] =
+{
+ case_utl_00, case_utl_01, case_utl_02, case_utl_03, case_utl_04, case_utl_05, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_utl_1E, case_utl_1F,
+ case_xtx_XX, case_utl_21, case_xtx_XX, case_xtx_XX, case_utl_24, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX,
+ case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_xtx_XX, case_utl_FF
+};
+
+
+// Case mapping tables are 13824 bytes long
+
+
+
+kvi_wchar_t kvi_wtolower(kvi_wchar_t c)
+{
+ kvi_wchar_t l = kvirc_case_map_utl[c >> 8][c & 0xff];
+ return l ? l : c;
+}
+
+bool kvi_hstrEqualCIN(const kvi_wchar_t *str1,const char *str2,int len)
+{
+ while(len-- && *str1)if(kvi_wtolower(*str1++) != (kvi_wchar_t)tolower(*str2++))return false;
+ return (len < 0);
+}
+
+
+const kvi_wchar_t * KviIrcView::getTextLine(int iMsgType,
+ const kvi_wchar_t * data_ptr,
+ KviIrcViewLine *line_ptr,
+ bool bEnableTimeStamp)
+{
+ const kvi_wchar_t* pUnEscapeAt = 0;
+ // Splits the text data in lines (separated by '\n')
+
+ // NOTE: This function may be NOT reentrant
+ // ... no function in this file is supposed to be thread safe anyway
+
+ int iTextIdx = 0; //we're at the beginning in the buffer
+ int iCurChunk = 0;
+ int blockLen;
+
+ register const kvi_wchar_t *p= data_ptr;
+
+ //Alloc the first attribute
+ line_ptr->uChunkCount = 1;
+ line_ptr->pChunks = (KviIrcViewLineChunk *)kvi_malloc(sizeof(KviIrcViewLineChunk));
+ //And fill it up
+ line_ptr->pChunks[0].type = KVI_TEXT_COLOR;
+ line_ptr->pChunks[0].iTextStart = 0;
+ line_ptr->pChunks[0].colors.back = KVI_OPTION_MSGTYPE(iMsgType).back();
+ line_ptr->pChunks[0].colors.fore = KVI_OPTION_MSGTYPE(iMsgType).fore();
+ line_ptr->pChunks[0].customFore=QColor();
+
+ if(bEnableTimeStamp && KVI_OPTION_BOOL(KviOption_boolIrcViewTimestamp))
+ {
+ QString szTimestamp;
+ szTimestamp=QDateTime::currentDateTime (
+ KVI_OPTION_BOOL(KviOption_boolIrcViewTimestampUTC) ? Qt::UTC : Qt::LocalTime ).toString(
+ KVI_OPTION_STRING(KviOption_stringIrcViewTimestampFormat) );
+ szTimestamp.append(' ');
+ int iTimeStampLength=szTimestamp.length();
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseSpecialColorForTimestamp))
+ {
+ // we need three chunks: the first one uses the default colors
+ // for the message type, the second one the special colors
+ // of the timestamp and the third one goes back to the defaults
+ line_ptr->pChunks[0].iTextLen = 0;
+
+ line_ptr->uChunkCount=3;
+ line_ptr->pChunks=(KviIrcViewLineChunk *)kvi_realloc((void *)line_ptr->pChunks,3 * sizeof(KviIrcViewLineChunk));
+
+ line_ptr->pChunks[1].type = KVI_TEXT_COLOR;
+ line_ptr->pChunks[1].iTextStart = 0;
+ line_ptr->pChunks[1].iTextLen = iTimeStampLength-1;
+ line_ptr->pChunks[1].colors.back = KVI_OPTION_UINT(KviOption_uintTimeStampBackground);
+ line_ptr->pChunks[1].colors.fore = KVI_OPTION_UINT(KviOption_uintTimeStampForeground);
+
+ line_ptr->pChunks[2].type = KVI_TEXT_COLOR;
+ line_ptr->pChunks[2].iTextStart = iTimeStampLength-1;
+ line_ptr->pChunks[2].iTextLen = 1;
+ line_ptr->pChunks[2].colors.back = KVI_OPTION_MSGTYPE(iMsgType).back();
+ line_ptr->pChunks[2].colors.fore = KVI_OPTION_MSGTYPE(iMsgType).fore();
+ line_ptr->pChunks[2].customFore=QColor();
+ iCurChunk+=2;
+ } else {
+ // only one chunk
+ line_ptr->pChunks[0].iTextLen = iTimeStampLength;
+ }
+
+ // We need the timestamp string to be added
+ // alloc the necessary space
+ line_ptr->szText.setLength(iTimeStampLength);
+
+ iTextIdx = iTimeStampLength; // the rest of the string will begin 11 chars later
+
+ // throw away const: we WANT to set the chars :D
+ register QChar * data_ptr_aux = (QChar *)line_ptr->szText.unicode();
+ register QChar * stamp_ptr_aux = (QChar *)szTimestamp.unicode();
+
+ for(int i=0;i<iTimeStampLength;i++)
+ *data_ptr_aux++ = *stamp_ptr_aux++;
+ } else {
+ // Timestamp not needed... but we don't want null strings floating around
+ line_ptr->szText = "";
+ line_ptr->pChunks[0].iTextLen = 0;
+ }
+
+ //
+ // Ok... a couple of macros that occur really frequently
+ // in the following code...
+ // these could work well as functions too...but the macros are a lot faster :)
+ //
+
+#define APPEND_LAST_TEXT_BLOCK(__data_ptr,__data_len) \
+ blockLen = (__data_len); \
+ line_ptr->pChunks[iCurChunk].iTextLen += blockLen; \
+ kvi_appendWCharToQStringWithLength(&(line_ptr->szText),__data_ptr,__data_len); \
+ iTextIdx+=blockLen;
+
+#define APPEND_LAST_TEXT_BLOCK_HIDDEN_FROM_NOW(__data_ptr,__data_len) \
+ blockLen = (__data_len); \
+ kvi_appendWCharToQStringWithLength(&(line_ptr->szText),__data_ptr,__data_len); \
+ iTextIdx+=blockLen;
+
+
+#define APPEND_ZERO_LENGTH_BLOCK(__data_ptr) /* does nothing */
+
+#define NEW_LINE_CHUNK(_chunk_type) \
+ line_ptr->uChunkCount++; \
+ line_ptr->pChunks=(KviIrcViewLineChunk *)kvi_realloc((void *)line_ptr->pChunks, \
+ line_ptr->uChunkCount * sizeof(KviIrcViewLineChunk)); \
+ iCurChunk++; \
+ line_ptr->pChunks[iCurChunk].type = _chunk_type; \
+ line_ptr->pChunks[iCurChunk].iTextStart = iTextIdx; \
+ line_ptr->pChunks[iCurChunk].iTextLen = 0; \
+ line_ptr->pChunks[iCurChunk].customFore=iCurChunk ? line_ptr->pChunks[iCurChunk-1].customFore : QColor();
+
+ // EOF Macros
+
+ int partLen;
+
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+
+ // Herezy :)
+
+ // This is not only usage of the *Evil Goto(tm)*
+ // This is also a *rather unclear* use of the *Really Evil Goto(tm)*
+ // char_to_check_jump_table is a table of dynamic label addresses...
+ // we use it to jump to the proper check
+ // loop_begin is a dynamic label, and we use it to
+ // return to the appropriate loop
+ // This is again BAD PROGRAMMING(TM) :).... but it is faster than
+ // the version with no dynamic gotos, and really faster
+ // that any version without gotos that comed into my mind...
+ //
+ // This code will prolly work only with GCC...(and even needs a "smart" one)
+
+ // Again did two versions... the first was:
+ //
+ // if(void * jmp_address = char_to_check_jump_table[*((unsigned char *)p)])goto *jmp_address;
+ // 18a3: 8b 55 f0 movl 0xfffffff0(%ebp),%edx
+ // 18a6: 31 c0 xorl %eax,%eax
+ // 18a8: 8a 02 movb (%edx),%al
+ // 18aa: 8b 04 85 20 00 00 00 movl 0x20(,%eax,4),%eax
+ // 18b1: 85 c0 testl %eax,%eax
+ // 18b3: 74 02 je 18b7 <KviIrcView::getTextLine(int, char const *, KviIrcViewLine *)+0x1f3>
+ // 18b5: ff e0 jmp *%eax
+ //
+ // I even had a nicer version:
+ //
+ // goto *(char_to_check_jump_table[*((unsigned char *)p)]);
+ // 18a3: 8b 55 f0 movl 0xfffffff0(%ebp),%edx
+ // 18a6: 31 c0 xorl %eax,%eax
+ // 18a8: 8a 02 movb (%edx),%al
+ // 18aa: ff 24 85 20 00 00 00 jmp *0x20(,%eax,4)
+ //
+ // but sth tells me that "jmp *0x20(,%eax,4)" takes a loooooot of clock ticks...
+ // ...we have less instructions , but the code takes longer to execute (7-8% longer)
+ // it might be also due to pipeline tricks, jump "next instruction precalculation" stuff...
+
+ // So we end up using the fist version here
+
+ void * loop_begin;
+
+ static void * char_to_check_jump_table[256]=
+ {
+ &&found_end_of_buffer ,0 ,&&found_mirc_escape ,&&found_color_escape ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,&&found_end_of_line ,0 ,
+ 0 ,&&found_command_escape ,0 ,&&found_mirc_escape ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,&&found_mirc_escape ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,&&found_icon_escape ,0 ,&&found_mirc_escape , // 000-031
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 032-047
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,&&check_emoticon_char ,&&check_emoticon_char ,
+ 0 ,&&check_emoticon_char ,0 ,0 , // 048-063 // 61='=' , 59=';' , 58=':'
+ 0 ,0 ,0 ,0 ,
+ 0 ,&&check_e2k_url ,&&check_file_or_ftp_url,0 ,
+ &&check_http_url ,&&check_irc_url ,0 ,0 ,
+ 0 ,&&check_mailto_url ,0 ,0 , // 064-079 // 070==F 072==H 073==I 077==M
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,&&check_www_url ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 080-095 // 087==W
+ 0 ,0 ,0 ,0 ,
+ 0 ,&&check_e2k_url ,&&check_file_or_ftp_url,0 ,
+ &&check_http_url ,&&check_irc_url ,0 ,0 ,
+ 0 ,&&check_mailto_url ,0 ,0 , // 096-111 // 101=e 102=f 104=h 105=i 109==m
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,&&check_www_url ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 112-127 // 119==w
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 128-133
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 134-159
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 160-175
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 176-191
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 192-207
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 208-223
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 , // 224-239
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 ,
+ 0 ,0 ,0 ,0 // 240-255
+ };
+
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewUrlHighlighting))
+ {
+ loop_begin = &&highlighting_check_loop; // get the address of the return label
+ // forewer loop
+highlighting_check_loop:
+ // yet more optimized
+ if(*((unsigned short *)p) < 0xff)
+ if(void * jmp_address = char_to_check_jump_table[*((unsigned short *)p)])goto *jmp_address;
+ // goto *(char_to_check_jump_table[*((unsigned char *)p)]); <--- replace 0 with &nothing_found
+//nothing_found:
+ p++;
+ goto highlighting_check_loop;
+ // newer here
+ } else {
+ loop_begin = &&escape_check_loop; // get the address of the return label
+ // forever loop
+escape_check_loop:
+ while(*((unsigned short *)p) > 31)p++;
+ goto check_escape_switch; // returns to escape_check_loop or returns from the function at all
+ // newer here
+ }
+ // newer here
+
+
+#else // !COMPILE_USE_DYNAMIC_LABELS
+
+ // No way to have a jump table, nor a dynamic return jump
+ // Anyway...we can have sth similar to a jump table...
+ // Note: this could be substituted by a compiler generated jump table
+ // for a switch command... but this is STILL faster
+
+ static char char_to_check_table[256]=
+ {
+ 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, // 000-015
+ 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, // 016-031
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 032-047
+ 0,0,0,0,0,0,0,0, 0,0,7,7,0,7,0,0, // 048-063
+ 0,0,0,0,0,8,3,0, 2,5,0,0,0,6,0,0, // 064-079 // 070==F 072==H 073==I 077==M
+ 0,0,0,0,0,0,0,4, 0,0,0,0,0,0,0,0, // 080-095 // 087==W
+ 0,0,0,0,0,8,3,0, 2,5,0,0,0,6,0,0, // 096-111 // 102==f 104==h 105==i 109==m
+ 0,0,0,0,0,0,0,4, 0,0,0,0,0,0,0,0, // 112-127 // 119==w
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 128-133
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 134-159
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 160-175
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 176-191
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 192-207
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 208-223
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, // 224-239
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 // 240-255
+ };
+
+check_char_loop:
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewUrlHighlighting))
+ {
+ for(;;)
+ {
+ if(*((unsigned short *)p) < 0xff)
+ if(unsigned int chk = char_to_check_table[*((unsigned short *)p)])
+ {
+ switch(chk)
+ {
+ case 1: goto check_escape_switch; break; // returns to check_char_loop or returns from the function at all
+ case 2: goto check_http_url; break; // returns to check_char_loop
+ case 3: goto check_file_or_ftp_url; break; // returns to check_char_loop
+ case 4: goto check_www_url; break; // returns to check_char_loop
+ case 5: goto check_irc_url; break; // returns to check_char_loop
+ case 6: goto check_mailto_url; break; // returns to check_char_loop
+ case 7: goto check_emoticon_char; break; // returns to check_char_loop
+ case 8: goto check_e2k_url; break;
+ }
+ }
+ p++;
+ }
+ } else {
+ while(((unsigned short)*p) > 31)p++;
+ goto check_escape_switch; // returns to check_char_loop
+ }
+
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+check_escape_switch:
+ switch(*p)
+ {
+ case '\0':
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+found_end_of_buffer:
+#endif //COMPILE_USE_DYNAMIC_LABELS
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr)
+ return p;
+ break;
+ case '\n':
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+found_end_of_line:
+#endif //COMPILE_USE_DYNAMIC_LABELS
+ // Found the end of a line
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr)
+ // terminate the string
+ // move the current pointer to the next character...
+ // if it is '\0' we will simply stop
+ p++;
+ return p;
+ break;
+ case '\r':
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+found_command_escape:
+#endif //COMPILE_USE_DYNAMIC_LABELS
+ if (p==pUnEscapeAt) {
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr);
+ NEW_LINE_CHUNK(KVI_TEXT_UNESCAPE);
+ pUnEscapeAt = 0;
+ p++;
+ data_ptr=p;
+ break;
+ }
+ // Command escape sequence
+ // \r!<escape_cmd>\r<visible parameters string>\r
+ p++;
+ if(*p == '!')
+ {
+ const kvi_wchar_t * next_cr = p;
+ // lookup the next carriage return
+ while(*next_cr && (*next_cr != '\r'))next_cr++;
+ if(*next_cr)
+ {
+ const kvi_wchar_t * term_cr = next_cr;
+ term_cr++;
+ while(*term_cr && (*term_cr != '\r'))term_cr++;
+ if(*term_cr)
+ {
+ // ok....the format is right:
+ // \r! ... \r ... \r
+ // ^p ^next_cr ^term_cr
+ p--;
+ // \r! ... \r ... \r
+ // ^p ^next_cr ^term_cr
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr)
+ NEW_LINE_CHUNK(KVI_TEXT_ESCAPE)
+
+ p+=2; //point after \r!
+
+ blockLen = (next_cr - p);
+ line_ptr->pChunks[iCurChunk].szPayload = (kvi_wchar_t *)kvi_malloc(((next_cr - p) + 1) * sizeof(kvi_wchar_t));
+ kvi_fastmoveodd((void *)(line_ptr->pChunks[iCurChunk].szPayload),p,blockLen * sizeof(kvi_wchar_t));
+
+ line_ptr->pChunks[iCurChunk].szPayload[blockLen] = 0;
+
+ ++next_cr; //point after the middle \r
+
+ pUnEscapeAt = term_cr;
+
+ bool bColorSetted=false;
+ if((line_ptr->pChunks[iCurChunk].szPayload[0]=='n') && KVI_OPTION_BOOL(KviOption_boolUseUserListColorsAsNickColors) && (!KVI_OPTION_BOOL(KviOption_boolColorNicks)))
+ {
+ if(m_pKviWindow->type()==KVI_WINDOW_TYPE_CHANNEL && m_pKviWindow)
+ {
+ if(line_ptr->pChunks[iCurChunk].szPayload[1]=='c' && ((KviChannel*)m_pKviWindow)->userListView())
+ {
+ KviUserListEntry *e = ((KviChannel*)m_pKviWindow)->userListView()->findEntry(QString((QChar*)next_cr,term_cr-next_cr));
+ if(e)
+ {
+ line_ptr->pChunks[iCurChunk].colors.fore = KVI_COLOR_CUSTOM; e->color(line_ptr->pChunks[iCurChunk].customFore);
+ bColorSetted=true;
+ }
+ }
+ }
+ else if(m_pKviWindow->type()==KVI_WINDOW_TYPE_QUERY && m_pKviWindow && line_ptr->pChunks[iCurChunk].szPayload[1]=='c')
+ {
+ QString m_szNick = QString((QChar*)next_cr,term_cr-next_cr);
+ if(m_szNick==m_pKviWindow->connection()->currentNickName()) {
+ line_ptr->pChunks[iCurChunk].colors.fore = KVI_COLOR_OWN;
+ bColorSetted=true;
+ }
+ }
+ }
+ if(!bColorSetted)
+ {
+ line_ptr->pChunks[iCurChunk].colors.fore=KVI_NOCHANGE;
+ }
+
+ /*APPEND_LAST_TEXT_BLOCK(next_cr,term_cr - next_cr)
+ NEW_LINE_CHUNK(KVI_TEXT_UNESCAPE)*/
+
+ p=next_cr;
+ data_ptr=p;
+ }
+ }
+ }
+ break;
+ case KVI_TEXT_COLOR:
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+found_color_escape:
+#endif //COMPILE_USE_DYNAMIC_LABELS
+ //Color control code...need a new attribute struct
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr)
+ NEW_LINE_CHUNK(*p)
+ p++;
+ p=getColorBytesW(p,&(line_ptr->pChunks[iCurChunk].colors.fore),
+ &(line_ptr->pChunks[iCurChunk].colors.back));
+ data_ptr=p;
+ break;
+ case KVI_TEXT_ICON:
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+found_icon_escape:
+#endif //COMPILE_USE_DYNAMIC_LABELS
+ p++;
+ if(*p > 32)
+ {
+ // Icon control word... need a new attribute struct
+ const kvi_wchar_t * beginPtr = p - 1;
+ const kvi_wchar_t * icon_name = p;
+ while(*p > 32)p++;
+ int datalen = p - icon_name;
+ kvi_wchar_t save = *p;
+ // throw away constness!
+ *((kvi_wchar_t *)p) = 0;
+ // FIXME: this has to be changed! : lookupTextIcon must use wide characters!
+ QString tmpQ;
+ tmpQ.setUnicodeCodes(icon_name,datalen);
+ KviTextIcon * icon = g_pTextIconManager->lookupTextIcon(tmpQ);
+ // throw away constness!
+ *((kvi_wchar_t *)p) = save;
+ //if(*p == KVI_TEXT_ICON)p++; // ending delimiter
+ if(icon)
+ {
+ APPEND_LAST_TEXT_BLOCK(data_ptr,beginPtr - data_ptr)
+ NEW_LINE_CHUNK(KVI_TEXT_ICON)
+ line_ptr->pChunks[iCurChunk].szPayload = (kvi_wchar_t *)kvi_malloc((datalen + 1) * sizeof(kvi_wchar_t));
+ kvi_fastmoveodd((void *)(line_ptr->pChunks[iCurChunk].szPayload),icon_name,datalen * sizeof(kvi_wchar_t));
+ line_ptr->pChunks[iCurChunk].szPayload[datalen] = 0;
+ line_ptr->pChunks[iCurChunk].szSmileId=line_ptr->pChunks[iCurChunk].szPayload;
+
+ APPEND_LAST_TEXT_BLOCK_HIDDEN_FROM_NOW(icon_name,datalen)
+
+ data_ptr = p;
+ NEW_LINE_CHUNK(KVI_TEXT_UNICON)
+ }
+ }
+ break;
+ case KVI_TEXT_BOLD:
+ case KVI_TEXT_UNDERLINE:
+ case KVI_TEXT_REVERSE:
+ case KVI_TEXT_RESET:
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+found_mirc_escape:
+#endif //COMPILE_USE_DYNAMIC_LABELS
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr)
+ NEW_LINE_CHUNK(*p)
+ data_ptr=++p;
+ break;
+ default:
+ p++;
+ break;
+ }
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+check_http_url:
+ p++;
+ if((*p == 't') || (*p == 'T'))
+ {
+ p--;
+ if(kvi_hstrEqualCIN(p,"http://",7))
+ {
+ partLen = 7;
+ goto got_url;
+ }
+ if(kvi_hstrEqualCIN(p,"https://",8))
+ {
+ partLen = 8;
+ goto got_url;
+ }
+ p++;
+ }
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+
+check_file_or_ftp_url:
+ p++;
+ if((*p == 'i') || (*p == 'I'))
+ {
+ p--;
+ if(kvi_hstrEqualCIN(p,"file://",7))
+ {
+ partLen = 7;
+ goto got_url;
+ }
+ p++;
+ } else if((*p == 't') || (*p == 'T'))
+ {
+ p--;
+ if(kvi_hstrEqualCIN(p,"ftp://",6))
+ {
+ partLen = 6;
+ goto got_url;
+ }
+ if(kvi_hstrEqualCIN(p,"ftp.",4))
+ {
+ partLen = 4;
+ goto got_url;
+ }
+ p++;
+ }
+
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+check_e2k_url:
+ p++;
+ if((*p == 'd') || (*p == 'D'))
+ {
+ p--;
+ if(kvi_hstrEqualCIN(p,"ed2k://",7))
+ {
+ partLen = 7;
+ goto got_url;
+ }
+ p++;
+ }
+
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+check_www_url:
+ p++;
+ if((*p == 'w') || (*p == 'W'))
+ {
+ p--;
+ if(kvi_hstrEqualCIN(p,"www.",4))
+ {
+ partLen = 4;
+ goto got_url;
+ }
+ p++;
+ }
+
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+check_irc_url:
+ p++;
+ if((*p == 'r') || (*p == 'R'))
+ {
+ p--;
+ if(kvi_hstrEqualCIN(p,"irc://",6))
+ {
+ partLen = 6;
+ goto got_url;
+ }
+ if(kvi_hstrEqualCIN(p,"irc6://",7))
+ {
+ partLen = 7;
+ goto got_url;
+ }
+ if(kvi_hstrEqualCIN(p,"ircs://",7))
+ {
+ partLen = 7;
+ goto got_url;
+ }
+ if(kvi_hstrEqualCIN(p,"ircs6://",8))
+ {
+ partLen = 8;
+ goto got_url;
+ }
+ p++;
+ }
+
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+check_mailto_url:
+ p++;
+ if((*p == 'a') || (*p == 'A'))
+ {
+ p--;
+ if(kvi_hstrEqualCIN(p,"mailto:",7))
+ {
+ partLen = 7;
+ goto got_url;
+ }
+ p++;
+ }
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+
+
+got_url:
+ //Url highlighting block
+ if(*(p + partLen) < 47)
+ {
+ p+=partLen;
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr)
+ } else {
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr)
+ NEW_LINE_CHUNK(KVI_TEXT_ESCAPE)
+// FIXME: #warning "Option for the URL escape...double click and right button!!!"
+// int urlLen = KVI_OPTION_STRING(KviOption_stringUrlLinkCommand).len() + 1;
+ line_ptr->pChunks[iCurChunk].szPayload = (kvi_wchar_t *)kvi_malloc(2 * sizeof(kvi_wchar_t));
+ line_ptr->pChunks[iCurChunk].szPayload[0] = 'u';
+ line_ptr->pChunks[iCurChunk].szPayload[1] = 0x0;
+ line_ptr->pChunks[iCurChunk].colors.fore = KVI_OPTION_MSGTYPE(KVI_OUT_URL).fore();
+ //and run until the presumed end of the url
+ data_ptr=p;
+ p+=partLen;
+ // Question : What characters are NOT allowed in an URL ?
+ // I assume [] () {} 'and chars below 33 (space too , and negative chars too! (for signed char systems))
+ // [] and () are used in ed2k links often
+
+ // These characters are "{", "}", "|", "\", "^", "~", "[", "]", and "`". (RFC1738)
+ while((*p > 32) && (*p != '[') && (*p != '|') && (*p != '{') && (*p != '>') &&
+ (*p != ']') && (*p != '}') && (*p != '<') && (*p != '"'))p++;
+
+ if(m_pKviWindow)
+ {
+ QString tmp;
+ tmp.setUnicodeCodes(data_ptr,p-data_ptr);
+ KVS_TRIGGER_EVENT_1(KviEvent_OnUrl,m_pKviWindow,tmp);
+ }
+
+ APPEND_LAST_TEXT_BLOCK(data_ptr,p - data_ptr)
+ NEW_LINE_CHUNK(KVI_TEXT_UNESCAPE)
+
+ }
+ data_ptr=p;
+
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+ //FIXME #warning: Add more emoticons, and more intelligent code to detect when they're not really emoticons
+
+check_emoticon_char:
+ // What about this ?
+
+ const kvi_wchar_t * begin = p;
+ p++;
+ if(KVI_OPTION_BOOL(KviOption_boolDrawEmoticons))
+ switch(iMsgType)
+ {
+ case KVI_OUT_CHANPRIVMSG:
+ case KVI_OUT_ACTION:
+ case KVI_OUT_OWNPRIVMSG:
+ case KVI_OUT_QUERYPRIVMSG:
+ case KVI_OUT_QUERYPRIVMSGCRYPTED:
+ case KVI_OUT_QUERYNOTICE:
+ case KVI_OUT_QUERYNOTICECRYPTED:
+ case KVI_OUT_CHANPRIVMSGCRYPTED:
+ case KVI_OUT_CHANNELNOTICE:
+ case KVI_OUT_CHANNELNOTICECRYPTED:
+ case KVI_OUT_OWNPRIVMSGCRYPTED:
+ case KVI_OUT_HIGHLIGHT:
+ case KVI_OUT_DCCCHATMSG:
+ {
+ // Pragma: 31.05.2002 : I had to kill the 8 prefix
+ // It happens really too often to have an 8 followed by a parenthesis
+ // that is not an emoticon
+
+ // *begin can be one of ':' , ';' , '='
+ if(*p == '-')p++; // FIXME: we could handle also 'o' as a nose ??? (extreme: also '+' ?)
+ // FIXME: use a "jump-like-check-table" here ? .... it would be surely faster
+ // FIXME: handle also '[',']','\\','p','@','#','<','>','|' ???
+ switch(*p)
+ {
+ case ')':
+ case '(':
+ case '/':
+ case 'D':
+ case 'P':
+ case 'S':
+ case 'O':
+ case '*':
+ case '|':
+ case 176: // '°' -> alt 176 : teardrop
+ {
+ const kvi_wchar_t * item = p;
+ const kvi_wchar_t * item2 = 0;
+ p++;
+ while(*p == *item)p++;
+ int count = (p - item) - 1;
+ if(*item == 176)
+ {
+ if(*p == ')')
+ {
+ item2 = p;
+ p++;
+ }
+ }
+ if(!*p || (*p == ' '))
+ {
+ // ok! this is an emoticon (sequence) !
+ // We lookup simplified versions of the emoticons...
+
+ // FIXME: this sould become UNICODE!!!
+ QString lookupstring;
+ kvi_wchar_t ng[3];
+ ng[0] = *begin;
+ ng[1] = *item;
+ if(item2)ng[2] = *item2;
+ lookupstring.setUnicodeCodes(ng,item2 ? 3 : 2);
+
+ KviTextIcon * icon = g_pTextIconManager->lookupTextIcon(lookupstring);
+ // do we have that emoticon-icon association ?
+ if(icon)
+ {
+ // we got an icon for this emoticon
+ // the tooltip will carry the original emoticon source text
+ APPEND_LAST_TEXT_BLOCK(data_ptr,begin - data_ptr)
+ NEW_LINE_CHUNK(KVI_TEXT_ICON)
+
+ int emolen = p - begin;
+ int reallen=item2 ? 3 : 2;
+
+ line_ptr->pChunks[iCurChunk].szPayload = (kvi_wchar_t *)kvi_malloc((emolen + 1) * sizeof(kvi_wchar_t));
+ kvi_fastmoveodd(line_ptr->pChunks[iCurChunk].szPayload,begin,emolen * sizeof(kvi_wchar_t));
+ line_ptr->pChunks[iCurChunk].szPayload[emolen] = 0;
+
+ line_ptr->pChunks[iCurChunk].szSmileId = (kvi_wchar_t *)kvi_malloc((reallen + 1) * sizeof(kvi_wchar_t));
+ kvi_fastmoveodd(line_ptr->pChunks[iCurChunk].szSmileId,ng,reallen * sizeof(kvi_wchar_t));
+ line_ptr->pChunks[iCurChunk].szSmileId[reallen] = 0;
+
+ APPEND_LAST_TEXT_BLOCK_HIDDEN_FROM_NOW(begin,emolen)
+ data_ptr = p;
+ // let's also handle thingies like :DDDD
+ item++;
+ while(count > 0)
+ {
+ NEW_LINE_CHUNK(KVI_TEXT_ICON)
+ line_ptr->pChunks[iCurChunk].szPayload = (kvi_wchar_t *)kvi_malloc((emolen + 1) * sizeof(kvi_wchar_t));
+ kvi_fastmoveodd(line_ptr->pChunks[iCurChunk].szPayload,begin,emolen * sizeof(kvi_wchar_t));
+ line_ptr->pChunks[iCurChunk].szPayload[emolen] = 0;
+
+ line_ptr->pChunks[iCurChunk].szSmileId = (kvi_wchar_t *)kvi_malloc((reallen + 1) * sizeof(kvi_wchar_t));
+ kvi_fastmoveodd(line_ptr->pChunks[iCurChunk].szSmileId,ng,reallen * sizeof(kvi_wchar_t));
+ line_ptr->pChunks[iCurChunk].szSmileId[reallen] = 0;
+
+ APPEND_ZERO_LENGTH_BLOCK(data_ptr)
+ count--;
+ }
+ NEW_LINE_CHUNK(KVI_TEXT_UNICON)
+ } // we don't even need to skip back... the text eventually parsed is ok to be in a single block for sure
+ } // we don't even need to skip back... the text eventually parsed is ok to be in a single block for sure
+ } // we don't even need to skip back... the text eventually parsed is ok to be in a single block for sure
+ break;
+ } // switch(*p)
+ } break;
+
+ }
+
+
+#ifdef COMPILE_USE_DYNAMIC_LABELS
+ goto *loop_begin;
+#else // !COMPILE_USE_DYNAMIC_LABELS
+ goto check_char_loop;
+#endif // !COMPILE_USE_DYNAMIC_LABELS
+
+ // never here
+ return p;
+
+}
+
+void KviIrcView::fastScroll(int lines)
+{
+ m_iUnprocessedPaintEventRequests = 0;
+
+ if(!isVisible())return;
+
+ if(!m_pFm)
+ {
+ // We must get the metrics from a real paint event :/
+ // must do a full repaint to get them...
+ repaint();
+ return;
+ }
+
+ // Ok...the current line is the last one here
+ // It is the only one that needs to be repainted
+ int widgetWidth = width()-m_pScrollBar->width();
+ if(widgetWidth < KVI_IRCVIEW_PIXMAP_SEPARATOR_AND_DOUBLEBORDER_WIDTH+10)return; //can't show stuff here
+ int widgetHeight = height();
+ int maxLineWidth = widgetWidth;
+ int defLeftCoord=KVI_IRCVIEW_HORIZONTAL_BORDER;
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages))
+ {
+ maxLineWidth -= KVI_IRCVIEW_PIXMAP_SEPARATOR_AND_DOUBLEBORDER_WIDTH;
+ defLeftCoord+=KVI_IRCVIEW_PIXMAP_AND_SEPARATOR;
+ }
+
+
+ int heightToPaint = 1;
+ KviIrcViewLine * l = m_pCurLine;
+ while(lines > 0)
+ {
+ if(l)
+ {
+ if(maxLineWidth != l->iMaxLineWidth)calculateLineWraps(l,maxLineWidth);
+ heightToPaint += l->uLineWraps * m_iFontLineSpacing;
+ heightToPaint += (m_iFontLineSpacing + m_iFontDescent);
+ lines--;
+ l = l->pPrev;
+ } else lines = 0;
+ }
+
+#ifdef COMPILE_USE_QT4
+ scroll(0,-(heightToPaint-1),QRect(1,1,widgetWidth-2,widgetHeight-2));
+#else
+ bitBlt(this,1,1,this,1,heightToPaint,widgetWidth -2,widgetHeight - (heightToPaint + KVI_IRCVIEW_VERTICAL_BORDER));
+
+ QRect r(0,widgetHeight - (heightToPaint + KVI_IRCVIEW_VERTICAL_BORDER),
+ widgetWidth,heightToPaint + KVI_IRCVIEW_VERTICAL_BORDER);
+
+ QPaintEvent * e = new QPaintEvent(r);
+ paintEvent(e);
+ delete e;
+#endif
+
+ if(m_iLastLinkRectHeight > -1)
+ {
+ // need to kill the last highlighted link
+ m_iLastLinkRectTop -= heightToPaint;
+ if(m_iLastLinkRectTop < 0)
+ {
+ m_iLastLinkRectHeight += m_iLastLinkRectTop;
+ m_iLastLinkRectTop = 0;
+ }
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The IrcView : THE paint event
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void KviIrcView::paintEvent(QPaintEvent *p)
+{
+ //
+ // THIS FUNCTION IS A MONSTER
+ //
+
+ int scrollbarWidth = m_pScrollBar->width();
+ int widgetWidth = width() - scrollbarWidth;
+ if(!isVisible() || (widgetWidth < 20))
+ {
+ m_iUnprocessedPaintEventRequests = 0; // assume a full repaint when this widget is shown...
+ return; //can't show stuff here
+ }
+
+ // if the mdiManager is in SDI mode
+ // and this window is attacched but is not the toplevel one
+ // then it is hidden completely behind the other windows
+ // and we can avoid to paint it :)
+ if(g_pFrame->mdiManager()->isInSDIMode() &&
+ (m_pKviWindow->mdiParent() != g_pFrame->mdiManager()->topChild()) &&
+ (m_pKviWindow->mdiParent()))
+ {
+ m_iUnprocessedPaintEventRequests = 0; // assume a full repaint when this widget is shown...
+ return; // totally hidden behind other windows
+ }
+
+ int widgetHeight = height();
+
+ static QRect r; // static: avoid calling constructor and destructor every time...
+
+ if(p)
+ {
+ r=p->rect(); // app triggered , or self triggered from fastScroll (in that case m_iUnprocessedPaintEventRequests is set to 0 there)
+ if(r == rect())
+ m_iUnprocessedPaintEventRequests = 0; // only full repaints reset
+ } else {
+ // A self triggered event
+ m_iUnprocessedPaintEventRequests = 0; // only full repaints reset
+ r = rect();
+ }
+
+ int rectLeft = r.x();
+ int rectTop = r.y();
+ int rectHeight = r.height();
+ int rectBottom = rectTop + rectHeight;
+ int rectWidth = r.width();
+ if(rectWidth > widgetWidth)rectWidth = widgetWidth;
+
+#ifdef COMPILE_USE_QT4
+ QPainter pa(this); // we use qt4 double buffering
+#else
+ KviDoubleBuffer doublebuffer(width(),height());
+ QPixmap * pDoubleBufferPixmap = doublebuffer.pixmap();
+
+ QPainter pa(pDoubleBufferPixmap);
+#endif
+ SET_ANTI_ALIASING(pa);
+
+ pa.setFont(font());
+ if(!m_pFm)
+ {
+ // note that QFontMetrics(pa.font()) may be not the same as QFontMetrics(font())
+ // because the painter might effectively use an approximation of the QFont specified
+ // by font().
+ recalcFontVariables(QFontMetrics(pa.font()),pa.fontInfo());
+ }
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = mapToGlobal(QPoint(rectLeft,rectTop));
+ pa.drawTiledPixmap(rectLeft,rectTop,rectWidth,rectHeight,*g_pShadedChildGlobalDesktopBackground,pnt.x(),pnt.y());
+ } else {
+#endif
+ QPixmap * pix = m_pPrivateBackgroundPixmap;
+
+ if(!pix)
+ pix = KVI_OPTION_PIXMAP(KviOption_pixmapIrcViewBackground).pixmap();
+
+ pa.fillRect(rectLeft,rectTop,rectWidth,rectHeight,KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));
+ if(pix)
+ KviPixmapUtils::drawPixmapWithPainter(&pa,pix,KVI_OPTION_UINT(KviOption_uintIrcViewPixmapAlign),r,widgetWidth,widgetHeight);
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+
+ //Have lines visible
+ int curBottomCoord = widgetHeight - KVI_IRCVIEW_VERTICAL_BORDER;
+ int maxLineWidth = widgetWidth;
+ int defLeftCoord = KVI_IRCVIEW_HORIZONTAL_BORDER;
+ int lineWrapsHeight;
+
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages))
+ {
+ maxLineWidth -= KVI_IRCVIEW_PIXMAP_SEPARATOR_AND_DOUBLEBORDER_WIDTH;
+ defLeftCoord += KVI_IRCVIEW_PIXMAP_AND_SEPARATOR;
+ }
+
+ KviIrcViewLine *pCurTextLine = m_pCurLine;
+
+ if(m_bMouseIsDown)
+ {
+ m_szLastSelectionLine = "";
+ m_szLastSelection = "";
+ }
+
+ //Make sure that we have enough space to paint something...
+ if(maxLineWidth < m_iMinimumPaintWidth)pCurTextLine=0;
+
+ bool bLineMarkPainted = !KVI_OPTION_BOOL(KviOption_boolTrackLastReadTextViewLine);
+
+
+ //And loop thru lines until we not run over the upper bound of the view
+ while((curBottomCoord >= KVI_IRCVIEW_VERTICAL_BORDER) && pCurTextLine)
+ {
+ //Paint pCurTextLine
+ if(maxLineWidth != pCurTextLine->iMaxLineWidth)
+ {
+ // Width of the widget or the font has been changed
+ // from the last time that this line was painted
+ calculateLineWraps(pCurTextLine,maxLineWidth);
+ }
+
+ // the evil multiplication
+ // in an i486 it can get up to 42 clock cycles
+ lineWrapsHeight = (pCurTextLine->uLineWraps) * m_iFontLineSpacing;
+ curBottomCoord -= lineWrapsHeight;
+
+ if((curBottomCoord - m_iFontLineSpacing) > rectBottom)
+ {
+ // not in update rect... skip
+ curBottomCoord -= (m_iFontLineSpacing + m_iFontDescent);
+ pCurTextLine = pCurTextLine->pPrev;
+ continue;
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages))
+ {
+ //Paint the pixmap first
+ //Calculate the position of the image
+ //imageYPos = curBottomCoord - (pixmapHeight(16) + ((m_iFontLineSpacing - 16)/2) );
+ int imageYPos = curBottomCoord - m_iRelativePixmapY;
+ //Set the mask if needed
+ int iPixId = KVI_OPTION_MSGTYPE(pCurTextLine->iMsgType).pixId();
+ if(iPixId > 0)
+ pa.drawPixmap(KVI_IRCVIEW_HORIZONTAL_BORDER,imageYPos,*(g_pIconManager->getSmallIcon(iPixId)));
+ }
+
+ if(m_pToolWidget)
+ {
+ if(!m_pToolWidget->messageEnabled(pCurTextLine->iMsgType))
+ {
+ // not in update rect... skip
+ curBottomCoord -= (m_iFontLineSpacing + m_iFontDescent);
+ pCurTextLine = pCurTextLine->pPrev;
+ continue;
+ }
+ }
+
+ // Initialize for drawing this line of text
+ // The first block is always an attribute block
+ char defaultBack = pCurTextLine->pBlocks->pChunk->colors.back;
+ char defaultFore = pCurTextLine->pBlocks->pChunk->colors.fore;
+ bool curBold = false;
+ bool curUnderline = false;
+ char foreBeforeEscape= KVI_BLACK;
+ bool curLink = false;
+ bool bacWasTransp = false;
+ char curFore = defaultFore;
+ char curBack = defaultBack;
+ int curLeftCoord = defLeftCoord;
+ curBottomCoord -= m_iFontDescent; //rise up the text...
+
+ //
+ // Single text line loop (paint all text blocks)
+ // (May correspond to more physical lines on the display if the text is wrapped)
+ //
+
+ for(int i=0;i < pCurTextLine->iBlockCount;i++)
+ {
+ register KviIrcViewWrappedBlock * block = &(pCurTextLine->pBlocks[i]);
+
+ // Play with the attributes
+ if(block->pChunk)
+ {
+ //normal block
+ switch(block->pChunk->type)
+ {
+ case KVI_TEXT_COLOR:
+ if(block->pChunk->colors.fore != KVI_NOCHANGE)
+ {
+ curFore = block->pChunk->colors.fore;
+ if(block->pChunk->colors.back != KVI_NOCHANGE)
+ curBack = block->pChunk->colors.back;
+ } else {
+ // only a CTRL+K... reset
+ curFore = defaultFore;
+ curBack = defaultBack;
+ }
+ // Begin Edit by GMC-jimmy: Added
+ // When KVIrc encounters a CTRL+K code without any trailing numbers, we then use KVIrc's default color value
+ // defined by the user in the Options dialog.
+ // This is to allow KVIrc to handle mIRC color codes in a similar fashion to most other modern irc clients.
+ // See also kvi_input.cpp
+
+ // Pragma: optimized: moved the code above (avoided duplicate if())
+ // Pragma(05.03.2003): fixed again: reset ONLY if CTRL+K without numbers
+ // otherwise leave the background unchanged
+
+ //if(block->pChunk->colors.fore == KVI_NOCHANGE)
+ // curFore = defaultFore;
+ //if(block->pChunk->colors.back == KVI_NOCHANGE)
+ // curBack = defaultBack;
+ // End Edit
+ break;
+ case KVI_TEXT_ESCAPE:
+ foreBeforeEscape = curFore;
+ if(block->pChunk->colors.fore != KVI_NOCHANGE)
+ curFore = block->pChunk->colors.fore;
+ if(m_pLastLinkUnderMouse == block)curLink = true;
+ break;
+ case KVI_TEXT_UNESCAPE:
+ curLink = false;
+ curFore = foreBeforeEscape;
+ break;
+ case KVI_TEXT_BOLD:
+ curBold = !curBold;
+ break;
+ case KVI_TEXT_UNDERLINE:
+ curUnderline = !curUnderline;
+ break;
+ case KVI_TEXT_RESET:
+ curBold = false;
+ curUnderline = false;
+ curFore = defaultFore;
+ curBack = defaultBack;
+ break;
+ case KVI_TEXT_REVERSE: //Huh ?
+ char aux = curBack;
+ if(bacWasTransp == true)
+ {
+ curBack = KVI_TRANSPARENT;
+ } else {
+ curBack = curFore;
+ }
+ if(aux == KVI_TRANSPARENT)
+ {
+ curFore = (char)KVI_DEF_BACK;
+ } else {
+ curFore = aux;
+ }
+ bacWasTransp = (aux == KVI_TRANSPARENT);
+/* if(curBack != KVI_TRANSPARENT)
+ {
+ char aux =curFore;
+ curFore = curBack;
+ curBack = aux;
+ } else {
+ curBack = curFore;
+ switch(curBack)
+ {
+ case KVI_WHITE:
+ case KVI_ORANGE:
+ case KVI_YELLOW:
+ case KVI_LIGHTGREEN:
+ case KVI_BLUEMARINE:
+ case KVI_LIGHTBLUE:
+ case KVI_LIGHTVIOLET:
+ case KVI_LIGHTGRAY:
+ curFore=KVI_BLACK;
+ break;
+ default: //transparent too
+ curFore=KVI_LIGHTGREEN;
+ break;
+ }
+ }
+*/
+ break;
+ //case KVI_TEXT_ICON:
+ //case KVI_TEXT_UNICON:
+ // does nothing
+ //debug("Have a block with ICON/UNICON attr");
+ //break;
+ }
+
+ } else {
+ // no attributes , it is a line wrap
+ curLeftCoord = defLeftCoord;
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewWrapMargin))curLeftCoord+=m_iWrapMargin;
+ curBottomCoord += m_iFontLineSpacing;
+ }
+
+//
+// Here we run really out of bounds :)))))
+// A couple of macros that could work well as functions...
+// but since there are really many params to be passed
+// and push & pop calls take clock cycles
+// my paranoic mind decided to go for the macro way.
+// This is NOT good programming
+//
+
+#define SET_PEN(_color,_custom)\
+ if( ((unsigned char)_color) < 16 )\
+ {\
+ pa.setPen(KVI_OPTION_MIRCCOLOR((unsigned char)_color));\
+ } else {\
+ switch((unsigned char)_color)\
+ {\
+ case KVI_COLOR_EXT_USER_OP:\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorUserListViewOpForeground));\
+ break;\
+ case KVI_COLOR_EXT_USER_HALFOP:\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorUserListViewHalfOpForeground));\
+ break;\
+ case KVI_COLOR_EXT_USER_ADMIN:\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorUserListViewChanAdminForeground));\
+ break;\
+ case KVI_COLOR_EXT_USER_OWNER:\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorUserListViewChanOwnerForeground));\
+ break;\
+ case KVI_COLOR_EXT_USER_VOICE:\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorUserListViewVoiceForeground));\
+ break;\
+ case KVI_COLOR_EXT_USER_USEROP:\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorUserListViewUserOpForeground));\
+ break;\
+ case KVI_COLOR_EXT_USER_NORMAL:\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorUserListViewNormalForeground));\
+ break;\
+ case KVI_DEF_BACK :\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorIrcViewBackground));\
+ break;\
+ case KVI_COLOR_CUSTOM :\
+ pa.setPen(_custom);\
+ break;\
+ case KVI_COLOR_OWN :\
+ pa.setPen(KVI_OPTION_COLOR(KviOption_colorUserListViewOwnForeground));\
+ break;\
+ }\
+ }
+
+#define DRAW_SELECTED_TEXT(_text_str,_text_idx,_text_len,_text_width) \
+ SET_PEN(KVI_OPTION_MSGTYPE(KVI_OUT_SELECT).fore(),block->pChunk ? block->pChunk->customFore : QColor()); \
+ { \
+ int theWdth = _text_width; \
+ if(theWdth < 0) \
+ theWdth=width()-(curLeftCoord+KVI_IRCVIEW_HORIZONTAL_BORDER+scrollbarWidth); \
+ pa.fillRect(curLeftCoord,curBottomCoord - m_iFontLineSpacing + m_iFontDescent,theWdth,m_iFontLineSpacing,KVI_OPTION_MIRCCOLOR(KVI_OPTION_MSGTYPE(KVI_OUT_SELECT).back())); \
+ } \
+ pa.drawText(curLeftCoord,curBottomCoord,_text_str,_text_idx,_text_len); \
+ m_szLastSelectionLine.append(_text_str.mid(_text_idx,_text_len)); \
+ curLeftCoord += _text_width;
+
+#define DRAW_NORMAL_TEXT(_text_str,_text_idx,_text_len,_text_width) \
+ SET_PEN(curFore,block->pChunk ? block->pChunk->customFore : QColor()); \
+ if(curBack != KVI_TRANSPARENT){ \
+ int theWdth = _text_width; \
+ if(theWdth < 0) \
+ theWdth=width()-(curLeftCoord+KVI_IRCVIEW_HORIZONTAL_BORDER+scrollbarWidth); \
+ pa.fillRect(curLeftCoord,curBottomCoord - m_iFontLineSpacing + m_iFontDescent,theWdth,m_iFontLineSpacing,KVI_OPTION_MIRCCOLOR((unsigned char)curBack)); \
+ } \
+ pa.drawText(curLeftCoord,curBottomCoord,_text_str,_text_idx,_text_len); \
+ if(curBold)pa.drawText(curLeftCoord+1,curBottomCoord,_text_str,_text_idx,_text_len); \
+ if(curUnderline){ \
+ int theWdth = _text_width; \
+ if(theWdth < 0) \
+ theWdth=width()-(curLeftCoord+KVI_IRCVIEW_HORIZONTAL_BORDER+scrollbarWidth); \
+ pa.drawLine(curLeftCoord,curBottomCoord+2,curLeftCoord+theWdth,curBottomCoord+2); \
+ } \
+ curLeftCoord += _text_width;
+
+
+// EOF macro declarations
+
+ if(m_bMouseIsDown)
+ {
+ //Check if the block or a part of it is selected
+ if(checkSelectionBlock(pCurTextLine,curLeftCoord,curBottomCoord,i))
+ {
+ //Selected in some way
+ //__range_valid(g_pOptions->m_cViewOutSeleFore != KVI_TRANSPARENT);
+ //__range_valid(g_pOptions->m_cViewOutSeleBack != KVI_TRANSPARENT);
+
+ if(m_bShiftPressed && i && block->pChunk &&
+ ((m_pWrappedBlockSelectionInfo->selection_type == KVI_IRCVIEW_BLOCK_SELECTION_TOTAL) ||
+ (m_pWrappedBlockSelectionInfo->selection_type == KVI_IRCVIEW_BLOCK_SELECTION_LEFT))
+ )
+ {
+ switch(block->pChunk->type)
+ {
+ case KVI_TEXT_BOLD:
+ case KVI_TEXT_UNDERLINE:
+ case KVI_TEXT_REVERSE:
+ case KVI_TEXT_RESET:
+ m_szLastSelectionLine.append(QChar(block->pChunk->type));
+ break;
+ case KVI_TEXT_COLOR:
+ m_szLastSelectionLine.append(QChar(block->pChunk->type));
+ if((block->pChunk->colors.fore != KVI_NOCHANGE) && (block->pChunk->colors.fore != KVI_TRANSPARENT))
+ {
+ if(curFore > 9)m_szLastSelectionLine.append(QChar('1'));
+ m_szLastSelectionLine.append(QChar((curFore%10)+'0'));
+ }
+ if((block->pChunk->colors.back != KVI_NOCHANGE) && (block->pChunk->colors.back != KVI_TRANSPARENT) )
+ {
+ m_szLastSelectionLine.append(QChar(','));
+ if(curBack > 9)m_szLastSelectionLine.append(QChar('1'));
+ m_szLastSelectionLine.append(QChar((curBack%10)+'0'));
+ }
+ break;
+ }
+ }
+
+ switch(m_pWrappedBlockSelectionInfo->selection_type)
+ {
+ case KVI_IRCVIEW_BLOCK_SELECTION_TOTAL:
+ DRAW_SELECTED_TEXT(pCurTextLine->szText,block->block_start,
+ block->block_len,block->block_width)
+ break;
+ case KVI_IRCVIEW_BLOCK_SELECTION_LEFT:
+ DRAW_SELECTED_TEXT(pCurTextLine->szText,block->block_start,
+ m_pWrappedBlockSelectionInfo->part_1_length,
+ m_pWrappedBlockSelectionInfo->part_1_width)
+ DRAW_NORMAL_TEXT(pCurTextLine->szText,block->block_start+m_pWrappedBlockSelectionInfo->part_1_length,
+ m_pWrappedBlockSelectionInfo->part_2_length,
+ m_pWrappedBlockSelectionInfo->part_2_width)
+ break;
+ case KVI_IRCVIEW_BLOCK_SELECTION_RIGHT:
+ DRAW_NORMAL_TEXT(pCurTextLine->szText,block->block_start,
+ m_pWrappedBlockSelectionInfo->part_1_length,
+ m_pWrappedBlockSelectionInfo->part_1_width)
+ DRAW_SELECTED_TEXT(pCurTextLine->szText,block->block_start+m_pWrappedBlockSelectionInfo->part_1_length,
+ m_pWrappedBlockSelectionInfo->part_2_length,
+ m_pWrappedBlockSelectionInfo->part_2_width)
+ break;
+ case KVI_IRCVIEW_BLOCK_SELECTION_CENTRAL:
+ DRAW_NORMAL_TEXT(pCurTextLine->szText,block->block_start,
+ m_pWrappedBlockSelectionInfo->part_1_length,
+ m_pWrappedBlockSelectionInfo->part_1_width)
+ DRAW_SELECTED_TEXT(pCurTextLine->szText,block->block_start+m_pWrappedBlockSelectionInfo->part_1_length,
+ m_pWrappedBlockSelectionInfo->part_2_length,
+ m_pWrappedBlockSelectionInfo->part_2_width)
+ DRAW_NORMAL_TEXT(pCurTextLine->szText,block->block_start+m_pWrappedBlockSelectionInfo->part_1_length+m_pWrappedBlockSelectionInfo->part_2_length,
+ m_pWrappedBlockSelectionInfo->part_3_length,
+ m_pWrappedBlockSelectionInfo->part_3_width)
+ break;
+ case KVI_IRCVIEW_BLOCK_SELECTION_ICON:
+ {
+ int theWdth = block->block_width;
+ if(theWdth < 0)theWdth=width()-(curLeftCoord+KVI_IRCVIEW_HORIZONTAL_BORDER+scrollbarWidth);
+ pa.fillRect(curLeftCoord,curBottomCoord - m_iFontLineSpacing + m_iFontDescent,theWdth,m_iFontLineSpacing,KVI_OPTION_MIRCCOLOR(KVI_OPTION_MSGTYPE(KVI_OUT_SELECT).back()));
+ kvi_wslen_t the_len = kvi_wstrlen(block->pChunk->szPayload);
+ m_szLastSelectionLine.append(QChar(block->pChunk->type));
+ QString tmp;
+ tmp.setUnicodeCodes(block->pChunk->szPayload,the_len);
+ m_szLastSelectionLine.append(tmp);
+ goto no_selection_paint;
+ }
+ break;
+ }
+ } else {
+ if(block->pChunk && block->pChunk->type == KVI_TEXT_ICON)goto no_selection_paint;
+ int wdth = block->block_width;
+ if(wdth == 0)
+ {
+ // Last block before a word wrap , or a zero characters attribute block ?
+ if(i < (pCurTextLine->iBlockCount - 1))
+ {
+ // There is another block...
+ // Check if it is a wrap...
+ if(pCurTextLine->pBlocks[i+1].pChunk == 0)wdth = widgetWidth-(curLeftCoord+KVI_IRCVIEW_HORIZONTAL_BORDER);
+ // else simply a zero characters block
+ }
+ // else simply a zero characters block
+ }
+ DRAW_NORMAL_TEXT(pCurTextLine->szText,block->block_start,block->block_len,wdth)
+ }
+ } else {
+ //No selection ...go fast!
+no_selection_paint:
+ if(block->pChunk && block->pChunk->type == KVI_TEXT_ICON)
+ {
+ int wdth = block->block_width;
+ if(wdth < 0)wdth = widgetWidth - (curLeftCoord + KVI_IRCVIEW_HORIZONTAL_BORDER);
+ int imageYPos = curBottomCoord - m_iRelativePixmapY;
+ //Set the mask if needed
+ if(curBack != KVI_TRANSPARENT && curBack < 16)
+ {
+ pa.fillRect(curLeftCoord,curBottomCoord - m_iFontLineSpacing + m_iFontDescent,wdth,m_iFontLineSpacing,KVI_OPTION_MIRCCOLOR((unsigned char)curBack));
+ }
+ QString tmpQ;
+ tmpQ.setUnicodeCodes(block->pChunk->szSmileId,kvi_wstrlen(block->pChunk->szSmileId));
+ QPixmap * daIcon =0;
+ KviTextIcon* pIcon = g_pTextIconManager->lookupTextIcon(tmpQ);
+ if(pIcon)
+ {
+ daIcon = pIcon->pixmap();
+ }
+ if(!daIcon)
+ {
+ // this should never happen since we do a check
+ // when building the text icon block , but.. better safe than sorry:
+ // so... we lost some icons ? wrong associations ?
+ // recover it by displaying the "question mark" icon
+ daIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_HELP); // must be there, eventually null pixmap :D
+ }
+ int moredown = 1; //used to center imager vertically (pixels which the image is moved more down)
+ moredown += ((m_iFontLineSpacing - daIcon->height()) / 2);
+ pa.drawPixmap(curLeftCoord + m_iIconSideSpacing,imageYPos + moredown,*(daIcon));
+
+ //debug("SHifting by %d",block->block_width);
+ curLeftCoord += block->block_width;
+ } else {
+
+ int wdth = block->block_width;
+ if(wdth < 0)wdth = widgetWidth - (curLeftCoord + KVI_IRCVIEW_HORIZONTAL_BORDER);
+
+ // FIXME: We could avoid this XSetForeground if the curFore was not changed....
+
+ SET_PEN(curFore,block->pChunk ? block->pChunk->customFore : QColor());
+
+ if(curBack != KVI_TRANSPARENT && curBack < 16 )
+ {
+ pa.fillRect(curLeftCoord,curBottomCoord - m_iFontLineSpacing + m_iFontDescent,wdth,m_iFontLineSpacing,KVI_OPTION_MIRCCOLOR((unsigned char)curBack));
+ }
+
+ if(curLink)
+ {
+ SET_PEN(KVI_OPTION_MSGTYPE(KVI_OUT_LINK).fore(),block->pChunk ? block->pChunk->customFore : QColor());
+ pa.drawText(curLeftCoord,curBottomCoord,pCurTextLine->szText,block->block_start,block->block_len);
+ pa.drawText(curLeftCoord+1,curBottomCoord,pCurTextLine->szText,block->block_start,block->block_len);
+ pa.drawLine(curLeftCoord,curBottomCoord+2,curLeftCoord+wdth,curBottomCoord+2);
+ } else if(curBold) {
+ //Draw doubled font (simulate bold)
+ pa.drawText(curLeftCoord,curBottomCoord,pCurTextLine->szText,block->block_start,block->block_len);
+ pa.drawText(curLeftCoord + 1,curBottomCoord,pCurTextLine->szText,block->block_start,block->block_len);
+ } else {
+ pa.drawText(curLeftCoord,curBottomCoord,pCurTextLine->szText,block->block_start,block->block_len);
+ }
+
+ if(curUnderline)
+ {
+ //Draw a line under the text block....
+ pa.drawLine(curLeftCoord,curBottomCoord+2,curLeftCoord+wdth,curBottomCoord+2);
+ }
+ curLeftCoord += block->block_width;
+ }
+ }
+ }
+
+ if(pCurTextLine == m_pCursorLine)
+ {
+ // paint the cursor line
+ int iH = lineWrapsHeight + m_iFontLineSpacing;
+#ifdef COMPILE_USE_QT4
+ pa.setCompositionMode(QPainter::CompositionMode_SourceOut);
+#else
+ pa.setRasterOp(NotROP);
+#endif
+ pa.fillRect(0,curBottomCoord - iH,widgetWidth,iH + (m_iFontDescent << 1),Qt::black);
+#ifdef COMPILE_USE_QT4
+ pa.setCompositionMode(QPainter::CompositionMode_SourceOver);
+#else
+ pa.setRasterOp(CopyROP);
+#endif
+ }
+
+ if(m_bMouseIsDown)
+ {
+ if(!m_szLastSelectionLine.isEmpty())
+ {
+ if(!m_szLastSelection.isEmpty())m_szLastSelection.prepend("\n");
+ m_szLastSelection.prepend(m_szLastSelectionLine);
+ m_szLastSelectionLine = "";
+ }
+ }
+
+ curBottomCoord -= (lineWrapsHeight + m_iFontLineSpacing);
+
+ if(pCurTextLine->uIndex == m_uLineMarkLineIndex)
+ {
+ if((curBottomCoord >= KVI_IRCVIEW_VERTICAL_BORDER) && !bLineMarkPainted)
+ {
+ // visible!
+ bLineMarkPainted = true;
+ //pa.setRasterOp(NotROP);
+#ifdef COMPILE_USE_QT4
+ pa.setPen(QPen(KVI_OPTION_COLOR(KviOption_colorIrcViewMarkLine),1,Qt::DotLine));
+#else
+ pa.setPen(QPen(KVI_OPTION_COLOR(KviOption_colorIrcViewMarkLine),1,QPen::DotLine));
+#endif
+ pa.drawLine(0,curBottomCoord,widgetWidth,curBottomCoord);
+ //pa.setRasterOp(CopyROP);
+ } // else was partially visible only
+ }
+
+ pCurTextLine = pCurTextLine->pPrev;
+ }
+
+ if(!bLineMarkPainted && pCurTextLine && (rectTop <= (KVI_IRCVIEW_VERTICAL_BORDER + 5)))
+ {
+ // the line mark hasn't been painted yet
+ // need to find out if the mark is above the display
+ // the mark might be somewhere before the current text line
+ // find the first line that can't be painted in the view at all
+ while((curBottomCoord >= KVI_IRCVIEW_VERTICAL_BORDER) && pCurTextLine)
+ {
+ // the line wraps for the visible lines MUST have been already calculated
+ // for this view width
+ lineWrapsHeight = (pCurTextLine->uLineWraps) * m_iFontLineSpacing;
+ curBottomCoord -= lineWrapsHeight + m_iFontLineSpacing + m_iFontDescent;
+ pCurTextLine = pCurTextLine->pPrev;
+ }
+
+ if(pCurTextLine)
+ {
+ // this is the first NOT visible
+ // so pCurTextLine->pNext is the last visible one
+ if(pCurTextLine->pNext)
+ {
+ if(pCurTextLine->pNext->uIndex >= m_uLineMarkLineIndex)
+ bLineMarkPainted = true; // yes, its somewhere before or on this line
+ } else {
+ // no next line ? hm... compare to the not visible one.. but this should never happen
+ if(pCurTextLine->uIndex >= m_uLineMarkLineIndex)
+ bLineMarkPainted = true; // yes, its somewhere before or on this line
+ }
+ if(bLineMarkPainted)
+ {
+ // need to mark it!
+ //pa.setRasterOp(NotROP);
+ //pa.setPen(Qt::black);
+#ifdef COMPILE_USE_QT4
+ pa.setPen(QPen(KVI_OPTION_COLOR(KviOption_colorIrcViewMarkLine),1,Qt::DotLine));
+#else
+ pa.setPen(QPen(KVI_OPTION_COLOR(KviOption_colorIrcViewMarkLine),1,QPen::DotLine));
+#endif
+ int x = widgetWidth - 8;
+ int y = KVI_IRCVIEW_VERTICAL_BORDER;
+ pa.drawLine(x,y,x,y);
+ y++; pa.drawLine(x-1,y,x+1,y);
+ y++; pa.drawLine(x-2,y,x+2,y);
+ y++; pa.drawLine(x-3,y,x+3,y);
+ y++; pa.drawLine(x-4,y,x+4,y);
+ //pa.setRasterOp(CopyROP);
+ }
+ }
+ }
+
+ //Need to draw the sunken rect around the view now...
+ pa.setPen(colorGroup().dark());
+ pa.drawLine(0,0,widgetWidth,0);
+ pa.drawLine(0,0,0,widgetHeight);
+ pa.setPen(colorGroup().light());
+ widgetWidth--;
+ pa.drawLine(1,widgetHeight-1,widgetWidth,widgetHeight-1);
+ pa.drawLine(widgetWidth,1,widgetWidth,widgetHeight);
+
+ // COPY TO THE DISPLAY
+#ifndef COMPILE_USE_QT4
+ bitBlt(this,rectLeft,rectTop,pDoubleBufferPixmap,rectLeft,rectTop,rectWidth,rectHeight,Qt::CopyROP);
+#endif
+// else we use the Qt4 native double buffering
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The IrcView : calculate line wraps
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define IRCVIEW_WCHARWIDTH(__c) (((__c).unicode() < 0xff) ? m_iFontCharacterWidth[(__c).unicode()] : m_pFm->width(__c))
+
+void KviIrcView::calculateLineWraps(KviIrcViewLine *ptr,int maxWidth)
+{
+ //
+ // Another monster
+ //
+
+ if(maxWidth<=0) return;
+
+ if(ptr->iBlockCount != 0)kvi_free(ptr->pBlocks); // free any previous wrap blocks
+ ptr->pBlocks = (KviIrcViewWrappedBlock *)kvi_malloc(sizeof(KviIrcViewWrappedBlock)); // alloc one block
+ ptr->iMaxLineWidth = maxWidth; // calculus for this width
+ ptr->iBlockCount = 0; // it will be ++
+ ptr->uLineWraps = 0; // no line wraps yet
+
+ unsigned int curAttrBlock = 0; // Current attribute block
+ int curLineWidth = 0;
+
+ // init the first block
+ ptr->pBlocks->block_start = 0;
+ ptr->pBlocks->block_len = 0;
+ ptr->pBlocks->block_width = 0;
+ ptr->pBlocks->pChunk = &(ptr->pChunks[0]); // always an attribute block
+
+ int maxBlockLen = ptr->pChunks->iTextLen; // ptr->pChunks[0].iTextLen
+
+ const QChar * unicode = ptr->szText.unicode();
+
+ for(;;)
+ {
+ //Calculate the block_width
+ register const QChar * p = unicode + ptr->pBlocks[ptr->iBlockCount].block_start;
+ int curBlockLen = 0;
+ int curBlockWidth = 0;
+
+ if(ptr->pChunks[curAttrBlock].type == KVI_TEXT_ICON)
+ {
+ curBlockWidth = m_iIconWidth;
+ } else {
+ while(curBlockLen < maxBlockLen)
+ {
+ // FIXME: this is ugly :/
+ curBlockWidth += IRCVIEW_WCHARWIDTH(*p);
+ curBlockLen++;
+ p++;
+ }
+ }
+ //Check the length
+ curLineWidth += curBlockWidth;
+
+ if(curLineWidth < maxWidth)
+ {
+ //debug("Block of %d pix and len %d with type %d",ptr->pBlocks[ptr->iBlockCount].block_width,ptr->pBlocks[ptr->iBlockCount].block_len,ptr->pChunks[curAttrBlock].type);
+ //Ok....proceed to next block
+ ptr->pBlocks[ptr->iBlockCount].block_len = curBlockLen;
+ ptr->pBlocks[ptr->iBlockCount].block_width = curBlockWidth;
+ curAttrBlock++;
+ ptr->iBlockCount++;
+ //Process the next block of data in the next loop or return if have no more blocks
+ if(curAttrBlock < ptr->uChunkCount)
+ {
+ ptr->pBlocks = (KviIrcViewWrappedBlock *)kvi_realloc(ptr->pBlocks,(ptr->iBlockCount + 1) * sizeof(KviIrcViewWrappedBlock));
+ ptr->pBlocks[ptr->iBlockCount].block_start = ptr->pChunks[curAttrBlock].iTextStart;
+ ptr->pBlocks[ptr->iBlockCount].block_len = 0;
+ ptr->pBlocks[ptr->iBlockCount].block_width = 0;
+ ptr->pBlocks[ptr->iBlockCount].pChunk = &(ptr->pChunks[curAttrBlock]);
+ maxBlockLen = ptr->pBlocks[ptr->iBlockCount].pChunk->iTextLen;
+ } else return;
+ } else {
+ //Need word wrap
+ //First go back to an admissible width
+ while((curLineWidth >= maxWidth) && curBlockLen)
+ {
+ p--;
+ curBlockLen--;
+ curLineWidth-=IRCVIEW_WCHARWIDTH(*p);
+ }
+ //Now look for a space
+ while((*p != ' ') && curBlockLen)
+ {
+ p--;
+ curBlockLen--;
+ curLineWidth-=IRCVIEW_WCHARWIDTH(*p);
+ }
+
+ //If we ran up to the beginning of the block....
+ if(curBlockLen == 0)
+ {
+ if(ptr->pChunks[curAttrBlock].type == KVI_TEXT_ICON)
+ {
+ // This is an icon block: needs to be wrapped differently:
+ // The wrap block goes BEFORE the icon itself
+ ptr->pBlocks[ptr->iBlockCount].pChunk = 0;
+ ptr->pBlocks[ptr->iBlockCount].block_width = 0;
+ ptr->iBlockCount++;
+ ptr->pBlocks = (KviIrcViewWrappedBlock *)kvi_realloc(ptr->pBlocks,(ptr->iBlockCount + 1) * sizeof(KviIrcViewWrappedBlock));
+ ptr->pBlocks[ptr->iBlockCount].block_start = p - unicode;
+ ptr->pBlocks[ptr->iBlockCount].block_len = 0;
+ ptr->pBlocks[ptr->iBlockCount].block_width = 0;
+ ptr->pBlocks[ptr->iBlockCount].pChunk = &(ptr->pChunks[curAttrBlock]);
+ goto wrap_line;
+ }
+ //Don't like it....forced wrap here...
+ //Go ahead up to the biggest possible string
+ if(maxBlockLen > 0)
+ {
+ do
+ {
+ curBlockLen++;
+ p++;
+ curLineWidth+=IRCVIEW_WCHARWIDTH(*p);
+ } while((curLineWidth < maxWidth) && (curBlockLen < maxBlockLen));
+ //Now overrunned , go back 1 char
+ p--;
+ curBlockLen--;
+ }
+ //K...wrap
+ } else {
+ //found a space...
+ //include it in the first block
+ p++;
+ curBlockLen++;
+ }
+
+ ptr->pBlocks[ptr->iBlockCount].block_len = curBlockLen;
+ ptr->pBlocks[ptr->iBlockCount].block_width = -1; // word wrap --> negative block_width
+ maxBlockLen-=curBlockLen;
+ ptr->iBlockCount++;
+ ptr->pBlocks = (KviIrcViewWrappedBlock *)kvi_realloc(ptr->pBlocks,(ptr->iBlockCount + 1) * sizeof(KviIrcViewWrappedBlock));
+ ptr->pBlocks[ptr->iBlockCount].block_start = p - unicode;
+ ptr->pBlocks[ptr->iBlockCount].block_len = 0;
+ ptr->pBlocks[ptr->iBlockCount].block_width = 0;
+ ptr->pBlocks[ptr->iBlockCount].pChunk = 0;
+wrap_line:
+ curLineWidth = 0;
+ ptr->uLineWraps++;
+ if(ptr->uLineWraps == 1)
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewWrapMargin))maxWidth-=m_iWrapMargin;
+ if(maxWidth<=0) return;
+ }
+ }
+ }
+
+ ptr->iBlockCount++;
+}
+
+//================= calculateSelectionBounds ==================//
+
+void KviIrcView::calculateSelectionBounds()
+{
+ if(m_mousePressPos.y() < m_mouseCurrentPos.y())
+ {
+ m_iSelectionTop = m_mousePressPos.y();
+ m_iSelectionBottom = m_mouseCurrentPos.y();
+ m_iSelectionBegin = m_mousePressPos.x();
+ m_iSelectionEnd = m_mouseCurrentPos.x();
+ } else {
+ m_iSelectionTop = m_mouseCurrentPos.y();
+ m_iSelectionBottom = m_mousePressPos.y();
+ m_iSelectionBegin = m_mouseCurrentPos.x();
+ m_iSelectionEnd = m_mousePressPos.x();
+ }
+
+ if(m_iSelectionBegin < m_iSelectionEnd)
+ {
+ m_iSelectionLeft = m_iSelectionBegin;
+ m_iSelectionRight = m_iSelectionEnd;
+ } else {
+ m_iSelectionLeft = m_iSelectionEnd;
+ m_iSelectionRight = m_iSelectionBegin;
+ }
+}
+
+
+//=============== checkSelectionBlock ===============//
+
+bool KviIrcView::checkSelectionBlock(KviIrcViewLine * line,int left,int bottom,int bufIndex)
+{
+ //
+ // Yahoo!!!!
+ //
+ const QChar * unicode = line->szText.unicode();
+ register const QChar * p = unicode + line->pBlocks[bufIndex].block_start;
+
+ int top = bottom-m_iFontLineSpacing;
+ int right = ((line->pBlocks[bufIndex].block_width >= 0) ? \
+ left+line->pBlocks[bufIndex].block_width : width()-(KVI_IRCVIEW_HORIZONTAL_BORDER + m_pScrollBar->width()));
+ if(bottom < m_iSelectionTop)return false; //The selection starts under this line
+ if(top > m_iSelectionBottom)return false; //The selection ends over this line
+ if((top >= m_iSelectionTop)&&(bottom < m_iSelectionBottom))
+ {
+ //Whole line selected
+ if(line->pBlocks[bufIndex].pChunk && line->pBlocks[bufIndex].pChunk->type == KVI_TEXT_ICON)
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_ICON;
+ else
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_TOTAL;
+ return true;
+ }
+ if((top < m_iSelectionTop) && (bottom >= m_iSelectionBottom))
+ {
+ //Selection begins and ends in this line
+ if(right < m_iSelectionLeft)return false;
+ if(left > m_iSelectionRight)return false;
+ if(line->pBlocks[bufIndex].pChunk && line->pBlocks[bufIndex].pChunk->type == KVI_TEXT_ICON)
+ {
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_ICON;
+ return true;
+ }
+ if((right <= m_iSelectionRight) && (left > m_iSelectionLeft))
+ {
+ //Whole line selected
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_TOTAL;
+ return true;
+ }
+ if((right > m_iSelectionRight) && (left <= m_iSelectionLeft))
+ {
+ //Selection ends and begins in THIS BLOCK!
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_CENTRAL;
+ m_pWrappedBlockSelectionInfo->part_1_length = 0;
+ m_pWrappedBlockSelectionInfo->part_1_width = 0;
+ while((left <= m_iSelectionLeft) && (m_pWrappedBlockSelectionInfo->part_1_length < line->pBlocks[bufIndex].block_len)){
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left += www;
+ m_pWrappedBlockSelectionInfo->part_1_width += www;
+ p++;
+ m_pWrappedBlockSelectionInfo->part_1_length++;
+ }
+ //Need to include the first character
+ if(m_pWrappedBlockSelectionInfo->part_1_length > 0)
+ {
+ m_pWrappedBlockSelectionInfo->part_1_length--;
+ p--;
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left -= www;
+ m_pWrappedBlockSelectionInfo->part_1_width -= www;
+ }
+ int maxLenNow = line->pBlocks[bufIndex].block_len-m_pWrappedBlockSelectionInfo->part_1_length;
+ int maxWidthNow = line->pBlocks[bufIndex].block_width-m_pWrappedBlockSelectionInfo->part_1_width;
+ m_pWrappedBlockSelectionInfo->part_2_length = 0;
+ m_pWrappedBlockSelectionInfo->part_2_width = 0;
+ while((left < m_iSelectionRight) && (m_pWrappedBlockSelectionInfo->part_2_length < maxLenNow))
+ {
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left += www;
+ m_pWrappedBlockSelectionInfo->part_2_width += www;
+ p++;
+ m_pWrappedBlockSelectionInfo->part_2_length++;
+ }
+ m_pWrappedBlockSelectionInfo->part_3_length = maxLenNow-m_pWrappedBlockSelectionInfo->part_2_length;
+ m_pWrappedBlockSelectionInfo->part_3_width = maxWidthNow-m_pWrappedBlockSelectionInfo->part_2_width;
+ return true;
+ }
+ if(right > m_iSelectionRight)
+ {
+ //Selection ends in THIS BLOCK!
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_LEFT;
+ m_pWrappedBlockSelectionInfo->part_1_length = 0;
+ m_pWrappedBlockSelectionInfo->part_1_width = 0;
+ while((left < m_iSelectionRight) && (m_pWrappedBlockSelectionInfo->part_1_length < line->pBlocks[bufIndex].block_len))
+ {
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left += www;
+ m_pWrappedBlockSelectionInfo->part_1_width += www;
+ p++;
+ m_pWrappedBlockSelectionInfo->part_1_length++;
+ }
+ m_pWrappedBlockSelectionInfo->part_2_length = line->pBlocks[bufIndex].block_len-m_pWrappedBlockSelectionInfo->part_1_length;
+ m_pWrappedBlockSelectionInfo->part_2_width = line->pBlocks[bufIndex].block_width-m_pWrappedBlockSelectionInfo->part_1_width;
+ //debug("%d",m_pWrappedBlockSelectionInfo->part_2_width);
+ return true;
+ }
+ //Selection begins in THIS BLOCK!
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_RIGHT;
+ m_pWrappedBlockSelectionInfo->part_1_length = 0;
+ m_pWrappedBlockSelectionInfo->part_1_width = 0;
+ while((left <= m_iSelectionLeft) && (m_pWrappedBlockSelectionInfo->part_1_length < line->pBlocks[bufIndex].block_len))
+ {
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left += www;
+ m_pWrappedBlockSelectionInfo->part_1_width += www;
+ p++;
+ m_pWrappedBlockSelectionInfo->part_1_length++;
+ }
+ //Need to include the first character
+ if(m_pWrappedBlockSelectionInfo->part_1_length > 0)
+ {
+ m_pWrappedBlockSelectionInfo->part_1_length--;
+ p--;
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left -= www;
+ m_pWrappedBlockSelectionInfo->part_1_width -= www;
+ }
+ m_pWrappedBlockSelectionInfo->part_2_length = line->pBlocks[bufIndex].block_len-m_pWrappedBlockSelectionInfo->part_1_length;
+ m_pWrappedBlockSelectionInfo->part_2_width = line->pBlocks[bufIndex].block_width-m_pWrappedBlockSelectionInfo->part_1_width;
+ return true;
+ }
+
+ if(top < m_iSelectionTop)
+ {
+ //Selection starts in this line
+ if(right < m_iSelectionBegin)return false;
+ if(line->pBlocks[bufIndex].pChunk && line->pBlocks[bufIndex].pChunk->type == KVI_TEXT_ICON)
+ {
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_ICON;
+ return true;
+ }
+ if(left > m_iSelectionBegin)
+ {
+ //Whole block selected
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_TOTAL;
+ return true;
+ }
+ //Selection begins in THIS BLOCK!
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_RIGHT;
+ m_pWrappedBlockSelectionInfo->part_1_length = 0;
+ m_pWrappedBlockSelectionInfo->part_1_width = 0;
+ while((left <= m_iSelectionBegin) && (m_pWrappedBlockSelectionInfo->part_1_length < line->pBlocks[bufIndex].block_len))
+ {
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left += www;
+ m_pWrappedBlockSelectionInfo->part_1_width += www;
+ p++;
+ m_pWrappedBlockSelectionInfo->part_1_length++;
+ }
+ //Need to include the first character
+ if(m_pWrappedBlockSelectionInfo->part_1_length > 0)
+ {
+ m_pWrappedBlockSelectionInfo->part_1_length--;
+ p--;
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left -= www;
+ m_pWrappedBlockSelectionInfo->part_1_width -= www;
+ }
+ m_pWrappedBlockSelectionInfo->part_2_length = line->pBlocks[bufIndex].block_len-m_pWrappedBlockSelectionInfo->part_1_length;
+ m_pWrappedBlockSelectionInfo->part_2_width = line->pBlocks[bufIndex].block_width-m_pWrappedBlockSelectionInfo->part_1_width;
+ return true;
+ }
+ //Selection ends in this line
+ if(left > m_iSelectionEnd)return false;
+ if(line->pBlocks[bufIndex].pChunk && line->pBlocks[bufIndex].pChunk->type == KVI_TEXT_ICON)
+ {
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_ICON;
+ return true;
+ }
+ if(right < m_iSelectionEnd)
+ {
+ //Whole block selected
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_TOTAL;
+ return true;
+ }
+ //Selection ends in THIS BLOCK!
+ m_pWrappedBlockSelectionInfo->selection_type = KVI_IRCVIEW_BLOCK_SELECTION_LEFT;
+ m_pWrappedBlockSelectionInfo->part_1_length = 0;
+ m_pWrappedBlockSelectionInfo->part_1_width = 0;
+ while((left < m_iSelectionEnd) && (m_pWrappedBlockSelectionInfo->part_1_length < line->pBlocks[bufIndex].block_len))
+ {
+ int www = IRCVIEW_WCHARWIDTH(*p);
+ left += www;
+ m_pWrappedBlockSelectionInfo->part_1_width += www;
+ p++;
+ m_pWrappedBlockSelectionInfo->part_1_length++;
+ }
+ m_pWrappedBlockSelectionInfo->part_2_length = line->pBlocks[bufIndex].block_len-m_pWrappedBlockSelectionInfo->part_1_length;
+ m_pWrappedBlockSelectionInfo->part_2_width = line->pBlocks[bufIndex].block_width-m_pWrappedBlockSelectionInfo->part_1_width;
+ return true;
+}
+
+//============ recalcFontVariables ==============//
+
+void KviIrcView::recalcFontVariables(const QFontMetrics &fm,const QFontInfo &fi)
+{
+ // FIXME: #warning "OPTIMIZE THIS: GLOBAL VARIABLES"
+ if(m_pFm)delete m_pFm;
+ m_pFm = new QFontMetrics(fm);
+ m_iFontLineSpacing = m_pFm->lineSpacing();
+ if(m_iFontLineSpacing < KVI_IRCVIEW_PIXMAP_SIZE && KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages))
+ {
+ m_iFontLineSpacing = KVI_IRCVIEW_PIXMAP_SIZE;
+ }
+ m_iFontDescent =m_pFm->descent();
+ m_iFontLineWidth =m_pFm->lineWidth();
+ // cache the first 256 characters
+ for(unsigned short i=0;i<256;i++)
+ {
+ m_iFontCharacterWidth[i]=m_pFm->width(QChar(i));
+ }
+ if(m_iFontLineWidth==0)m_iFontLineWidth=1;
+ m_iWrapMargin = m_pFm->width("wwww");
+ //for(int i=0;i<256;i++)m_iFontCharacterWidth[i]=fm.width((char)i);
+ m_iMinimumPaintWidth = (m_pFm->width('w') << 1)+m_iWrapMargin;
+ m_iRelativePixmapY = (m_iFontLineSpacing + KVI_IRCVIEW_PIXMAP_SIZE) >> 1;
+ m_iIconWidth = m_pFm->width("w");
+
+ if(fi.fixedPitch() && (m_iIconWidth > 0))
+ {
+ while(m_iIconWidth < 18)m_iIconWidth += m_iIconWidth;
+ m_iIconSideSpacing = (m_iIconWidth - 16) >> 1;
+ } else {
+ m_iIconWidth = 18;
+ m_iIconSideSpacing = 1;
+ }
+}
+
+//================ resizeEvent ===============//
+
+void KviIrcView::resizeEvent(QResizeEvent *)
+{
+ int iScr = m_pScrollBar->sizeHint().width();
+ int iLeft = width()-iScr;
+ m_pToolsButton->setGeometry(iLeft,0,iScr,iScr);
+ m_pScrollBar->setGeometry(iLeft,iScr,iScr,height() - iScr);
+
+ if(m_pToolWidget)
+ {
+ if( ((m_pToolWidget->x() + m_pToolWidget->width()) > (iLeft - 1)) ||
+ ((m_pToolWidget->y() + m_pToolWidget->height()) > (height() - 1)))
+ {
+ m_pToolWidget->move(10,10);
+ }
+ }
+}
+
+QSize KviIrcView::sizeHint() const
+{
+ QSize ret(KVI_IRCVIEW_SIZEHINT_WIDTH,KVI_IRCVIEW_SIZEHINT_HEIGHT);
+ return ret;
+}
+
+void KviIrcView::showToolsPopup()
+{
+ if(!m_pToolsPopup)
+ m_pToolsPopup = new KviTalPopupMenu(this);
+
+ m_pToolsPopup->clear();
+
+ if(m_pToolWidget)
+ m_pToolsPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)),__tr2qs("Hide Find Window"),this,SLOT(toggleToolWidget()));
+ else
+ m_pToolsPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)),__tr2qs("Show Find Window"),this,SLOT(toggleToolWidget()));
+ m_pToolsPopup->insertSeparator();
+ m_pToolsPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PLUS)),__tr2qs("Zoom In"),this,SLOT(increaseFontSize()));
+ m_pToolsPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINUS)),__tr2qs("Zoom Out"),this,SLOT(decreaseFontSize()));
+ m_pToolsPopup->insertItem(__tr2qs("Choose Temporary Font..."),this,SLOT(chooseFont()));
+ m_pToolsPopup->insertItem(__tr2qs("Choose Temporary Background..."),this,SLOT(chooseBackground()));
+ int id = m_pToolsPopup->insertItem(__tr2qs("Reset Temporary Background"),this,SLOT(resetBackground()));
+ m_pToolsPopup->setItemEnabled(id,m_pPrivateBackgroundPixmap != 0);
+ m_pToolsPopup->insertSeparator();
+ m_pToolsPopup->insertItem(__tr2qs("Clear Buffer"),this,SLOT(clearBuffer()));
+
+ QSize s = m_pToolsPopup->sizeHint();
+
+ m_pToolsPopup->popup(m_pToolsButton->mapToGlobal(QPoint(m_pToolsButton->width() - s.width(),m_pToolsButton->height())));
+}
+
+void KviIrcView::increaseFontSize()
+{
+ QFont f = font();
+ f.setPointSize(f.pointSize() + 1);
+ setFont(f);
+}
+
+void KviIrcView::decreaseFontSize()
+{
+ QFont f = font();
+ int p = f.pointSize();
+ if(p > 2)p--;
+ f.setPointSize(p);
+ setFont(f);
+}
+
+void KviIrcView::chooseFont()
+{
+ bool bOk;
+ QFont f = QFontDialog::getFont(&bOk,font(),this);
+ if(!bOk)return;
+ setFont(f);
+}
+
+void KviIrcView::chooseBackground()
+{
+ QString f;
+ if(!KviFileDialog::askForOpenFileName(f,__tr2qs("Choose the background image...")))return;
+ if(f.isEmpty())return;
+ QPixmap p(f);
+ if(p.isNull())
+ {
+ QMessageBox::information(this,__tr2qs("Invalid image"),__tr2qs("Failed to load the selected image"),__tr2qs("Ok"));
+ return;
+ }
+ setPrivateBackgroundPixmap(p);
+}
+
+void KviIrcView::resetBackground()
+{
+ setPrivateBackgroundPixmap(0);
+}
+
+void KviIrcView::toggleToolWidget()
+{
+ if(m_pToolWidget)
+ {
+ delete m_pToolWidget;
+ m_pToolWidget = 0;
+ m_pCursorLine = 0;
+ repaint();
+
+ } else {
+ m_pToolWidget = new KviIrcViewToolWidget(this);
+ int w = m_pToolWidget->sizeHint().width();
+ m_pToolWidget->move(width() - (w + 40),10);
+ m_pToolWidget->show();
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// The IrcView : find
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void KviIrcView::setCursorLine(KviIrcViewLine * l)
+{
+ m_pCursorLine = l;
+ if(m_pCursorLine == m_pCurLine)
+ {
+
+ repaint();
+
+ return;
+ }
+ int sc = m_pScrollBar->value();
+ l = m_pCurLine;
+ if(m_pCursorLine->uIndex > m_pCurLine->uIndex)
+ {
+ // The cursor line is below the current line
+ while(l && (l != m_pCursorLine))
+ {
+ l = l->pNext;
+ sc++;
+ }
+ if(!l)return;
+ if(sc != m_pScrollBar->value())
+ {
+ m_pCurLine = m_pCursorLine;
+ m_iLastScrollBarValue = sc;
+ m_pScrollBar->setValue(sc);
+ } else {
+ repaint();
+ }
+ } else {
+ // The cursor line is over the current line
+ // Here we're in trouble :D
+ int curBottomCoord = height() - KVI_IRCVIEW_VERTICAL_BORDER;
+ int maxLineWidth = width();
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages))maxLineWidth -= KVI_IRCVIEW_PIXMAP_SEPARATOR_AND_DOUBLEBORDER_WIDTH;
+ //Make sure that we have enough space to paint something...
+ if(maxLineWidth < m_iMinimumPaintWidth)return; // ugh
+ //And loop thru lines until we not run over the upper bound of the view
+ KviIrcViewLine * curLine = m_pCurLine;
+ while(l)
+ {
+ if(maxLineWidth != l->iMaxLineWidth)calculateLineWraps(l,maxLineWidth);
+ curBottomCoord -= (l->uLineWraps + 1) * m_iFontLineSpacing;
+ while(curLine && (curBottomCoord < KVI_IRCVIEW_VERTICAL_BORDER))
+ {
+ if(curLine->iMaxLineWidth != maxLineWidth)calculateLineWraps(curLine,maxLineWidth);
+ curBottomCoord += ((curLine->uLineWraps + 1) * m_iFontLineSpacing) + m_iFontDescent;
+ curLine = curLine->pPrev;
+ sc--;
+ }
+ if(l == m_pCursorLine)break;
+ curBottomCoord -= m_iFontDescent;
+ l = l->pPrev;
+ }
+ if(!curLine)return;
+ if(sc != m_pScrollBar->value())
+ {
+ m_pCurLine = curLine;
+ m_iLastScrollBarValue = sc;
+ m_pScrollBar->setValue(sc);
+ } else {
+ repaint();
+ }
+ }
+}
+
+void KviIrcView::findNext(const QString& szText,bool bCaseS,bool bRegExp,bool bExtended)
+{
+ KviIrcViewLine * l = m_pCursorLine;
+ if(!l)l = m_pCurLine;
+ if(l)
+ {
+ l = l->pNext;
+ if(!l)l = m_pFirstLine;
+ KviIrcViewLine * start = l;
+
+ int idx = -1;
+
+ do{
+ if(m_pToolWidget)
+ {
+ if(!(m_pToolWidget->messageEnabled(l->iMsgType)))goto do_pNext;
+ }
+
+ if(bRegExp)
+ {
+ QRegExp re(szText,bCaseS,!bExtended);
+#if QT_VERSION >= 300
+ idx = re.search(l->szText,0);
+#else
+ idx = re.find(l->szText,0);
+#endif
+ } else {
+ QString tmp = l->szText;
+ idx = tmp.find(szText,0,bCaseS);
+ }
+
+ if(idx != -1)
+ {
+ setCursorLine(l);
+ if(m_pToolWidget)
+ {
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("Pos %d"),idx);
+ m_pToolWidget->setFindResult(tmp);
+ }
+ return;
+ }
+
+do_pNext:
+
+ l = l->pNext;
+ if(!l)l = m_pFirstLine;
+
+ } while(l != start);
+ }
+ m_pCursorLine = 0;
+ repaint();
+ if(m_pToolWidget)m_pToolWidget->setFindResult(__tr2qs("Not found"));
+}
+
+
+void KviIrcView::findPrev(const QString& szText,bool bCaseS,bool bRegExp,bool bExtended)
+{
+ KviIrcViewLine * l = m_pCursorLine;
+ if(!l)l = m_pCurLine;
+ if(l)
+ {
+ l = l->pPrev;
+ if(!l)l = m_pLastLine;
+ KviIrcViewLine * start = l;
+
+ int idx = -1;
+
+ do{
+
+ if(m_pToolWidget)
+ {
+ if(!(m_pToolWidget->messageEnabled(l->iMsgType)))goto do_pPrev;
+ }
+
+ if(bRegExp)
+ {
+ QRegExp re(szText,bCaseS,!bExtended);
+#if QT_VERSION >= 300
+ idx = re.search(l->szText,0);
+#else
+ idx = re.find(l->szText,0);
+#endif
+ } else {
+ QString tmp = l->szText;
+ idx = tmp.find(szText,0,bCaseS);;
+ }
+
+ if(idx != -1)
+ {
+ setCursorLine(l);
+ if(m_pToolWidget)
+ {
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("Pos %d"),idx);
+ m_pToolWidget->setFindResult(tmp);
+ }
+ return;
+ }
+
+do_pPrev:
+
+ l = l->pPrev;
+ if(!l)l = m_pLastLine;
+
+ } while(l != start);
+ }
+ m_pCursorLine = 0;
+
+ repaint();
+ if(m_pToolWidget)m_pToolWidget->setFindResult(__tr2qs("Not found"));
+}
+
+/*
+void KviIrcView::findClosestPositionInText(int xCursorPos,int yCursorPos,KviIrcViewPositionInText &pos)
+{
+ pos.pLine = getVisibleLineAt(xCursorPos,uCursorPos);
+}
+*/
+
+
+KviIrcViewLine * KviIrcView::getVisibleLineAt(int xPos,int yPos)
+{
+ KviIrcViewLine * l = m_pCurLine;
+ int iTop = height() + m_iFontDescent - KVI_IRCVIEW_VERTICAL_BORDER;
+
+ while(iTop > yPos)
+ {
+ if(l)
+ {
+ iTop -= ((l->uLineWraps + 1) * m_iFontLineSpacing) + m_iFontDescent;
+ if(iTop <= yPos)return l;
+ l = l->pPrev;
+ } else return 0;
+ }
+ return 0;
+}
+
+KviIrcViewWrappedBlock * KviIrcView::getLinkUnderMouse(int xPos,int yPos,QRect * pRect,QString * linkCmd,QString * linkText)
+{
+ KviIrcViewLine * l = m_pCurLine;
+ int iTop = height() + m_iFontDescent - KVI_IRCVIEW_VERTICAL_BORDER;
+
+ while(iTop > yPos)
+ {
+ if(!l)return 0;
+
+ iTop -= ((l->uLineWraps + 1) * m_iFontLineSpacing) + m_iFontDescent;
+
+ if(iTop > yPos)
+ {
+ // still below the mouse
+ l = l->pPrev;
+ continue;
+ }
+
+ // got the right KviIrcViewLine
+ int iLeft = KVI_IRCVIEW_HORIZONTAL_BORDER;
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages))iLeft += KVI_IRCVIEW_PIXMAP_AND_SEPARATOR;
+ int firstRowTop = iTop;
+ int i = 0;
+
+ for(;;)
+ {
+ if(yPos <= iTop + m_iFontLineSpacing)
+ {
+ // exactly this row of this line
+ if(iTop != firstRowTop)
+ if(KVI_OPTION_BOOL(KviOption_boolIrcViewWrapMargin))iLeft+=m_iWrapMargin;
+ if(xPos < iLeft)return 0;
+ int iBlockWidth = 0;
+ int iLastEscapeBlock = -1;
+ int iLastEscapeBlockTop = -1;
+ for(;;)
+ {
+ int iLastLeft = iLeft;
+ if(i >= l->iBlockCount)return 0;
+ if(l->pBlocks[i].pChunk)
+ if(l->pBlocks[i].pChunk->type == KVI_TEXT_ESCAPE)
+ {
+ iLastEscapeBlock=i;
+ iLastEscapeBlockTop=iTop;
+ }
+ if(l->pBlocks[i].pChunk)
+ if(l->pBlocks[i].pChunk->type == KVI_TEXT_UNESCAPE) iLastEscapeBlock=-1;
+ if(l->pBlocks[i].block_width > 0)
+ {
+ iBlockWidth = l->pBlocks[i].block_width;
+ iLeft += iBlockWidth;
+ } else {
+ if(i < (l->iBlockCount - 1))
+ {
+ // There is another block...
+ // Check if it is a wrap...
+ if(l->pBlocks[i+1].pChunk == 0)
+ {
+ iBlockWidth = width() - iLastLeft;
+ iLeft = width();
+ }
+ // else simply a zero characters block
+ }
+ }
+ if(xPos < iLeft)
+ {
+ // Got it!
+ // link ?
+ bool bHadWordWraps = false;
+ while(l->pBlocks[i].pChunk == 0)
+ {
+ // word wrap ?
+ if(i >= 0)
+ {
+ i--;
+ bHadWordWraps = true;
+ } else return 0; // all word wraps ?!!!
+ }
+ if(iLastEscapeBlock != -1)
+ {
+ int iLeftBorder=iLeft;
+ int k;
+ for(k = i ; k>=iLastEscapeBlock ; k--)
+ iLeftBorder-=l->pBlocks[k].block_width;
+ int iRightBorder=0;
+ unsigned int uLineWraps = 0;
+ for(k = iLastEscapeBlock;; k++)
+ {
+ if(l->pBlocks[k].pChunk)
+ if(l->pBlocks[k].pChunk->type != KVI_TEXT_UNESCAPE)
+ iRightBorder+=l->pBlocks[k].block_width;
+ else
+ break;
+ else
+ {
+ uLineWraps++;
+ bHadWordWraps=1;
+ }
+ }
+ if(pRect)
+ {
+ *pRect = QRect(iLeftBorder,
+ bHadWordWraps ? iLastEscapeBlockTop : iTop,
+ iRightBorder,
+ ((uLineWraps + 1) * m_iFontLineSpacing) + m_iFontDescent);
+ }
+ if(linkCmd)
+ {
+ linkCmd->setUnicodeCodes(l->pBlocks[iLastEscapeBlock].pChunk->szPayload,kvi_wstrlen(l->pBlocks[iLastEscapeBlock].pChunk->szPayload));
+ linkCmd->stripWhiteSpace();
+ if((*linkCmd)=="nc") (*linkCmd)="n";
+ }
+ if(linkText)
+ {
+ QString szLink;
+ int iEndOfLInk = iLastEscapeBlock;
+ while(1)
+ {
+ if(l->pBlocks[iEndOfLInk].pChunk)
+ if(l->pBlocks[iEndOfLInk].pChunk->type != KVI_TEXT_UNESCAPE)
+ {
+ switch(l->pBlocks[iEndOfLInk].pChunk->type)
+ {
+ case KVI_TEXT_BOLD:
+ case KVI_TEXT_UNDERLINE:
+ case KVI_TEXT_REVERSE:
+ case KVI_TEXT_RESET:
+ szLink.append(QChar(l->pBlocks[iEndOfLInk].pChunk->type));
+ break;
+ case KVI_TEXT_COLOR:
+ szLink.append(QChar(KVI_TEXT_COLOR));
+ if(l->pBlocks[iEndOfLInk].pChunk->colors.fore != KVI_NOCHANGE)
+ {
+ szLink.append(QString("%1").arg((int)(l->pBlocks[iEndOfLInk].pChunk->colors.fore)));
+ }
+ if(l->pBlocks[iEndOfLInk].pChunk->colors.back != KVI_NOCHANGE)
+ {
+ szLink.append(QChar(','));
+ szLink.append(QString("%1").arg((int)(l->pBlocks[iEndOfLInk].pChunk->colors.back)));
+ }
+ break;
+ }
+ szLink.append(l->szText.mid(l->pBlocks[iEndOfLInk].block_start,l->pBlocks[iEndOfLInk].block_len));
+ } else
+ break;
+ iEndOfLInk++;
+
+ }
+ *linkText=szLink;
+ // grab the rest of the link visible string
+ // Continue while we do not find a non word wrap block block
+ for(int bufIndex = (i + 1);bufIndex < l->iBlockCount;bufIndex++)
+ {
+ if(l->pBlocks[bufIndex].pChunk ) break; //finished : not a word wrap
+ else {
+ linkText->append(l->szText.mid(l->pBlocks[bufIndex].block_start,l->pBlocks[bufIndex].block_len));
+ }
+ }
+ }
+ return &(l->pBlocks[iLastEscapeBlock]);
+ }
+ if(l->pBlocks[i].pChunk->type == KVI_TEXT_ICON)
+ {
+ if(pRect)
+ {
+ *pRect = QRect(iLastLeft,
+ bHadWordWraps ? firstRowTop : iTop,
+ iBlockWidth,
+ ((l->uLineWraps + 1) * m_iFontLineSpacing) + m_iFontDescent);
+ }
+ if(linkCmd)
+ {
+ *linkCmd = "[!txt]";
+ QString tmp;
+ tmp.setUnicodeCodes(l->pBlocks[i].pChunk->szPayload,kvi_wstrlen(l->pBlocks[i].pChunk->szPayload));
+ linkCmd->append(tmp);
+ linkCmd->stripWhiteSpace();
+ }
+ if(linkText)
+ {
+ *linkText = "";
+ }
+ return &(l->pBlocks[i]);
+ }
+ return 0;
+ }
+ i++;
+ }
+ } else {
+ // run until a word wrap block
+ i++; //at least one block!
+ while(i < l->iBlockCount)
+ {
+ // still ok to run right
+ if(l->pBlocks[i].pChunk == 0)
+ {
+// i++;
+ break;
+ } else i++;
+ }
+ if(i >= l->iBlockCount)return 0;
+ iTop += m_iFontLineSpacing;
+ }
+ }
+ }
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Mouse handling routines
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+ @doc: escape_sequences
+ @title:
+ Escape sequences and clickable links
+ @type:
+ generic
+ @body:
+ The KVIrc view widgets support clickable links.[br]
+ The links can be created using special escape sequences in the text
+ passed to the [cmd]echo[/cmd] command.[br]
+ KVIrc uses some escape sequences in the text "echoed" internally.[br]
+ The simplest way to explain it is to use an example:[br]
+ [example]
+ [cmd]echo[/cmd] This is a [fnc]$cr[/fnc]![!dbl][cmd]echo[/cmd] You have clicked it![fnc]$cr[/fnc]\clickable link$cr !
+ [/example]
+ The example above will show the following text line: "This is a clickable link".
+ If you move the mouse over the words "clickable link", you will see the text highlighted.[br]
+ Once you double-click one of that words, the command "[cmd]echo[/cmd] You have clicked it!" will be executed.[br]
+ The format looks complex ?... it is not...just read on.[br]
+
+ <cr>!<link_type><cr><visible text><cr>
+ <cr>!<escape_command><cr><visible text><cr>
+
+ [big]Escape format[/big]
+ The whole escape sequence format is the following:[br]
+ [b]<cr>!<escape_command><cr><visible text><cr>[/b][br]
+ <cr> is the carriage return character. You can obtain it by using the [fnc]]$cr[/fnc] function.[br]
+ <visible text> is the text that will appear as "link" when you move the mouse over it.[br]
+ <escape_command> is the description of the actions to be taken when the user interacts with the link.[br]
+ <escape_command> has the two following syntactic forms:[br]
+ [b]<escape_command> ::= <user_defined_commands>[/b][br]
+ [b]<escape_command> ::= <builtin_link_description>[/b]
+
+ [big]User defined links[/big][br]
+ The user defined links allow you to perform arbitrary commands when the user interacts with the link.[br]
+ The commands are specified in the <escape_command> part by using the following syntax:[br]
+ <escape_command> ::= <user_defined_commands>[br]
+ <user_defined_commands> ::= <command_rule> [<user_defined_commands>][br]
+ <command_rule> ::= <action_tag><command>[br]
+ <action_tag> ::= "[!" <action> "]"[br]
+ <action> ::= "rbt" | "mbt" | "dbl" | "txt"[br]
+ <command> ::= any kvirc command (see notes below)[br]
+
+ [big]Builtin links[/big][br]
+ The builtin links have builtin actions performed when the user interact with the link.[br]
+ These links are used internally in KVIrc , but you can use them too.[br]
+ The <escape_command> is a single letter this time: it defines the type of the link.[br]
+ Currently KVIrc uses six types of builtin links : 'n' for nickname links, 'u' for url links,
+ 'c' for channel links, 'h' for hostname links, 'm' for mask links and 's' for server links.[br]
+ Theoretically you can also use your own link types: just use any other letter or digit (you can't use ']' and <cr>),
+ but probably you will prefer a completely user defined link in that case anyway.[br]
+ Once the user interacts with the link , kvirc executes the predefined events:[br]
+ On right-click the event OnBuiltinLinkRightClicked is triggered: the first parameter is the link type,
+ the second parameter is the <visible text> (as a single parameter!!!)[br]
+ On middle-click the event OnBuiltinLinkMiddleClicked is triggered: the parameters are similar to the previous one.[br]
+ In the same way you have OnBuiltinLinkDoubleClicked.[br]
+
+ [big]A shortcut[/big]
+ You may have a look at the [fnc]$fmtlink[/fnc] function: it does automatically some of the job explained
+ in this document.[br]
+
+*/
+
+// FIXME: #warning "Finish the doc above!! Maybe some examples ?!"
+
+
+void KviIrcView::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ QString cmd;
+ QString linkCmd;
+ QString linkText;
+
+ if(m_iMouseTimer)
+ {
+ killTimer(m_iMouseTimer);
+ m_iMouseTimer=0;
+ delete m_pLastEvent;
+ m_pLastEvent = 0;
+ }
+
+ getLinkUnderMouse(e->pos().x(),e->pos().y(),0,&linkCmd,&linkText);
+
+ if(linkCmd.isEmpty())
+ {
+ KVS_TRIGGER_EVENT_0(KviEvent_OnTextViewDoubleClicked,m_pKviWindow);
+ return;
+ }
+
+ QString szCmd(linkCmd);
+ szCmd.remove(0,1);
+
+ KviKvsVariantList * pParams = new KviKvsVariantList();
+ if(!szCmd.isEmpty()) pParams->append(szCmd);
+ else pParams->append(linkText);
+ pParams->append(linkText);
+ pParams->append(szCmd);
+
+
+ switch(linkCmd[0].unicode())
+ {
+ case 'n':
+ {
+ bool bTrigger = false;
+ switch(m_pKviWindow->type())
+ {
+ case KVI_WINDOW_TYPE_CHANNEL:
+ if(((KviChannel *)m_pKviWindow)->isOn(linkText))
+ {
+ KVS_TRIGGER_EVENT(KviEvent_OnChannelNickDefaultActionRequest,m_pKviWindow,pParams);
+ } else bTrigger = true;
+ break;
+ case KVI_WINDOW_TYPE_QUERY:
+ if(KviQString::equalCI(((KviQuery *)m_pKviWindow)->windowName(),linkText))
+ {
+ KVS_TRIGGER_EVENT(KviEvent_OnQueryNickDefaultActionRequest,m_pKviWindow,pParams);
+ } else bTrigger = true;
+ break;
+ default:
+ bTrigger = true;
+ break;
+ }
+ if(bTrigger)
+ {
+ if(console())
+ {
+ KVS_TRIGGER_EVENT(KviEvent_OnNickLinkDefaultActionRequest,m_pKviWindow,pParams);
+ }
+ }
+ }
+ break;
+ case 'm':
+ if((linkCmd.length() > 2) && (m_pKviWindow->type() == KVI_WINDOW_TYPE_CHANNEL))
+ {
+ if(((KviChannel *)m_pKviWindow)->isMeOp())
+ {
+ QChar plmn = linkCmd[1];
+ if((plmn.unicode() == '+') || (plmn.unicode() == '-'))
+ {
+ QString target(m_pKviWindow->windowName());
+ target.replace("\\","\\\\");
+ target.replace("\"","\\\"");
+ target.replace(";","\\;");
+ target.replace("$","\\$");
+ target.replace("%","\\%");
+ QChar flag = linkCmd[2];
+ switch(flag.unicode())
+ {
+ case 'o':
+ case 'v':
+ // We can do nothing here...
+ break;
+
+ case 'b':
+ case 'I':
+ case 'e':
+ case 'k':
+ KviQString::sprintf(cmd,"mode %Q %c%c $0",&target,plmn.latin1(),flag.latin1());
+ break;
+ default:
+ KviQString::sprintf(cmd,"mode %Q %c%c",&target,plmn.latin1(),flag.latin1());
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case 'h':
+ m_pKviWindow->output(KVI_OUT_HOSTLOOKUP,__tr2qs("Looking up host %Q..."),&linkText);
+ cmd = "host -a $0";
+ break;
+ case 'u':
+ {
+ QString urlText;
+ if(!szCmd.isEmpty()) urlText=szCmd;
+ else urlText=linkText;
+ if(
+ !KviQString::cmpCIN(urlText,"irc://",6) ||
+ !KviQString::cmpCIN(urlText,"irc6://",7) ||
+ !KviQString::cmpCIN(urlText,"ircs://",7) ||
+ !KviQString::cmpCIN(urlText,"ircs6://",8)
+ )
+ {
+ KviIrcUrl::run(urlText,KviIrcUrl::TryCurrentContext | KviIrcUrl::DoNotPartChans, console());
+ } else {
+ cmd = "openurl $0";
+ }
+ }
+ break;
+ case 'c':
+ {
+ if(console() && console()->connection())
+ {
+ QString szChan=linkText;
+ if(szCmd.length()>0) szChan=szCmd;
+ if(KviChannel * c = console()->connection()->findChannel(szChan))
+ {
+ // FIXME: #warning "Is this ok ?"
+ c->raise();
+ c->setFocus();
+ } else {
+ cmd = QString("join %1").arg(szChan);
+ }
+ }
+ }
+ break;
+ case 's':
+ cmd = "motd $0";
+ break;
+ default:
+ {
+ getLinkEscapeCommand(cmd,linkCmd,"[!dbl]");
+ if(cmd.isEmpty())
+ {
+ KVS_TRIGGER_EVENT_0(KviEvent_OnTextViewDoubleClicked,m_pKviWindow);
+ }
+ }
+ break;
+ }
+ if(!cmd.isEmpty())
+ {
+ KviKvsScript::run(cmd,m_pKviWindow,pParams);
+ }
+ delete pParams;
+}
+
+void KviIrcView::mousePressEvent(QMouseEvent *e)
+{
+ if(m_pKviWindow->input()) m_pKviWindow->input()->setFocus();
+
+ if(e->button() & Qt::LeftButton)
+ {
+ // This is the beginning of a selection...
+ // We just set the mouse to be "down" and
+ // await mouseMove events...
+
+ if(m_pToolWidget)
+ {
+ m_pCursorLine = getVisibleLineAt(e->pos().x(),e->pos().y());
+ repaint();
+ }
+
+ m_mousePressPos = e->pos();
+ m_mouseCurrentPos = e->pos();
+
+ m_bMouseIsDown = true;
+
+ m_bShiftPressed = (e->state() & Qt::ShiftButton);
+
+ calculateSelectionBounds();
+ }
+
+ if(e->button() & Qt::LeftButton)
+ {
+ if(m_iMouseTimer)
+ {
+ killTimer(m_iMouseTimer);
+ m_iMouseTimer=0;
+ delete m_pLastEvent;
+ m_pLastEvent = 0;
+ } else {
+ m_iMouseTimer = startTimer(QApplication::doubleClickInterval());
+ m_pLastEvent = new QMouseEvent(*e);
+ }
+ } else {
+ mouseRealPressEvent(e);
+ }
+}
+
+void KviIrcView::mouseRealPressEvent(QMouseEvent *e)
+{
+ QString linkCmd;
+ QString linkText;
+ getLinkUnderMouse(e->pos().x(),e->pos().y(),0,&linkCmd,&linkText);
+
+ QString szCmd(linkCmd);
+ szCmd.remove(0,1);
+
+ KviKvsVariantList * pParams = new KviKvsVariantList();
+ if(!szCmd.isEmpty()) pParams->append(szCmd);
+ else pParams->append(linkText);
+ pParams->append(linkText);
+ pParams->append(szCmd);
+
+
+ if(!(e->state() & Qt::ControlButton))//(e->button() & Qt::RightButton) && (
+ {
+ if(!linkCmd.isEmpty())
+ {
+ switch(linkCmd[0].unicode())
+ {
+ case 'n':
+ {
+ bool bTrigger = false;
+ switch(m_pKviWindow->type())
+ {
+ case KVI_WINDOW_TYPE_CHANNEL:
+ if(((KviChannel *)m_pKviWindow)->isOn(linkText))
+ {
+ if(e->button() & Qt::RightButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnChannelNickPopupRequest,m_pKviWindow,pParams);
+ if(e->button() & Qt::LeftButton) {
+ KVS_TRIGGER_EVENT(KviEvent_OnChannelNickLinkClick,m_pKviWindow,pParams);
+ if(m_pKviWindow)
+ {
+ if(m_pKviWindow->inherits("KviChannel")) {
+ KviChannel *c = (KviChannel*)m_pKviWindow;
+ QString nick;
+ if(pParams->firstAsString(nick))
+ c->userListView()->select(nick);
+ }
+ }
+ }
+ } else bTrigger = true;
+ break;
+ case KVI_WINDOW_TYPE_QUERY:
+ if(KviQString::equalCI(((KviQuery *)m_pKviWindow)->windowName(),linkText))
+ {
+ if(e->button() & Qt::RightButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnQueryNickPopupRequest,m_pKviWindow,pParams);
+ if(e->button() & Qt::LeftButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnQueryNickLinkClick,m_pKviWindow,pParams);
+ } else bTrigger = true;
+ break;
+ default:
+ bTrigger = true;
+ break;
+ }
+ if(bTrigger)
+ {
+ if(console())
+ {
+ if(e->button() & Qt::RightButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnNickLinkPopupRequest,m_pKviWindow,pParams);
+ if(e->button() & Qt::LeftButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnConsoleNickLinkClick,m_pKviWindow,pParams);
+ } else emit rightClicked();
+ }
+ }
+ break;
+ case 'h':
+ if(e->button() & Qt::RightButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnHostLinkPopupRequest,m_pKviWindow,pParams);
+ if(e->button() & Qt::LeftButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnHostLinkClick,m_pKviWindow,pParams);
+ break;
+ case 'u':
+ if(e->button() & Qt::RightButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnUrlLinkPopupRequest,m_pKviWindow,pParams);
+ if(e->button() & Qt::LeftButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnUrlLinkClick,m_pKviWindow,pParams);
+ break;
+ case 'c':
+ if(e->button() & Qt::RightButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnChannelLinkPopupRequest,m_pKviWindow,pParams);
+ if(e->button() & Qt::LeftButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnChannelLinkClick,m_pKviWindow,pParams);
+ break;
+ case 's':
+ if(e->button() & Qt::RightButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnServerLinkPopupRequest,m_pKviWindow,pParams);
+ if(e->button() & Qt::LeftButton)
+ KVS_TRIGGER_EVENT(KviEvent_OnServerLinkClick,m_pKviWindow,pParams);
+ break;
+ default:
+ {
+ if(e->button() & Qt::RightButton)
+ {
+ QString tmp;
+ getLinkEscapeCommand(tmp,linkCmd,"[!rbt]");
+ if(!tmp.isEmpty())
+ {
+ KviKvsScript::run(tmp,m_pKviWindow,pParams);
+ } else emit rightClicked();
+ }
+ }
+ break;
+ }
+ } else if(e->button() & Qt::RightButton) emit rightClicked();
+
+ } else if((e->button() & Qt::MidButton) || ((e->button() & Qt::RightButton) && (e->state() & Qt::ControlButton)))
+ {
+ QString tmp;
+ getLinkEscapeCommand(tmp,linkCmd,QString("[!mbt]"));
+ if(!tmp.isEmpty())
+ {
+ KviKvsScript::run(tmp,m_pKviWindow,pParams);
+ } else {
+ KVS_TRIGGER_EVENT_0(KviEvent_OnWindowPopupRequest,m_pKviWindow);
+ }
+ }
+ delete pParams;
+}
+
+//================ mouseReleaseEvent ===============//
+
+void KviIrcView::mouseReleaseEvent(QMouseEvent *)
+{
+ if(m_iSelectTimer)
+ {
+ killTimer(m_iSelectTimer);
+ m_iSelectTimer = 0;
+ QClipboard * c = QApplication::clipboard();
+ if(c)
+ {
+ // copy to both!
+ c->setText(m_szLastSelection,QClipboard::Clipboard);
+ if(c->supportsSelection())
+ c->setText(m_szLastSelection,QClipboard::Selection);
+ }
+ }
+
+ if(m_bMouseIsDown)
+ {
+ m_bMouseIsDown = false;
+ m_bShiftPressed = false;
+ // Insert the lines blocked while selecting
+ while(KviIrcViewLine * l = m_pMessagesStoppedWhileSelecting->first())
+ {
+ m_pMessagesStoppedWhileSelecting->removeFirst();
+ appendLine(l,false);
+ }
+ repaint();
+ }
+}
+
+// FIXME: #warning "The tooltip timeout should be small, because the view scrolls!"
+
+void KviIrcView::mouseMoveEvent(QMouseEvent *e)
+{
+// debug("Pos : %d,%d",e->pos().x(),e->pos().y());
+ if(m_bMouseIsDown && (e->state() & Qt::LeftButton)) // m_bMouseIsDown MUST BE true...(otherwise the mouse entered the window with the button pressed ?)
+ {
+
+ if(m_iSelectTimer == 0)m_iSelectTimer = startTimer(KVI_IRCVIEW_SELECT_REPAINT_INTERVAL);
+
+ /*if(m_iMouseTimer)
+ {
+ killTimer(m_iMouseTimer);
+ m_iMouseTimer=0;
+ mouseRealPressEvent(m_pLastEvent);
+ delete m_pLastEvent;
+ m_pLastEvent=0;
+ }*/
+ } else {
+ if(m_iSelectTimer)
+ {
+ killTimer(m_iSelectTimer);
+ m_iSelectTimer = 0;
+ }
+
+ int yPos = e->pos().y();
+ int rectTop;
+ int rectHeight;
+ QRect rctLink;
+ KviIrcViewWrappedBlock * newLinkUnderMouse = getLinkUnderMouse(e->pos().x(),yPos,&rctLink);
+
+ rectTop = rctLink.y();
+ rectHeight = rctLink.height();
+
+ if(newLinkUnderMouse != m_pLastLinkUnderMouse)
+ {
+ //abortTip();
+ //m_iTipTimer = startTimer(KVI_OPTION_UINT(KviOption_uintIrcViewToolTipTimeoutInMsec));
+ m_pLastLinkUnderMouse = newLinkUnderMouse;
+ if(m_pLastLinkUnderMouse)
+ {
+ setCursor(Qt::PointingHandCursor);
+ if(rectTop < 0)rectTop = 0;
+ if((rectTop + rectHeight) > height())rectHeight = height() - rectTop;
+
+ if(m_iLastLinkRectHeight > -1)
+ {
+ // prev link
+ int top = (rectTop < m_iLastLinkRectTop) ? rectTop : m_iLastLinkRectTop;
+ int lastBottom = m_iLastLinkRectTop + m_iLastLinkRectHeight;
+ int thisBottom = rectTop + rectHeight;
+ QRect r(0,top,width(),((lastBottom > thisBottom) ? lastBottom : thisBottom) - top);
+ repaint(r);
+ } else {
+ // no prev link
+ QRect r(0,rectTop,width(),rectHeight);
+ repaint(r);
+ }
+ m_iLastLinkRectTop = rectTop;
+ m_iLastLinkRectHeight = rectHeight;
+ } else {
+ setCursor(Qt::ArrowCursor);
+ if(m_iLastLinkRectHeight > -1)
+ {
+ // There was a previous bottom rect
+ QRect r(0,m_iLastLinkRectTop,width(),m_iLastLinkRectHeight);
+ repaint(r);
+ m_iLastLinkRectTop = -1;
+ m_iLastLinkRectHeight = -1;
+ }
+ }
+
+ }
+ }
+}
+
+KviConsole * KviIrcView::console()
+{
+ return m_pKviWindow->console();
+}
+
+void KviIrcView::doLinkToolTip(const QRect &rct,QString &linkCmd,QString &linkText)
+{
+ if(linkCmd.isEmpty())return;
+
+ QString szCmd(linkCmd);
+ szCmd.remove(0,1);
+
+ QString tip;
+
+ switch(linkCmd[0].unicode())
+ {
+ case 'u': // url link
+ {
+ tip = "<table width=\"100%\">" \
+ "<tr><td valign=\"center\"><img src=\"url_icon\"> <u><font color=\"blue\"><nowrap>";
+ if(linkText.length() > 50)
+ {
+ tip += linkText.left(47);
+ tip += "...";
+ } else {
+ tip += linkText;
+ }
+ tip+="</nowrap></font></u></td></tr><tr><td>";
+ QMimeSourceFactory::defaultFactory()->setPixmap("url_icon",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_URL)));
+ tip += __tr2qs("Double-click to open this link");
+ tip += "</td></tr></table>";
+ }
+ break;
+ case 'h': // host link
+ {
+ tip = "<table width=\"100%\">" \
+ "<tr><td valign=\"center\"><img src=\"host_icon\"> <u><font color=\"blue\"><nowrap>";
+ if(linkText.length() > 50)
+ {
+ tip += linkText.left(47);
+ tip += "...";
+ } else {
+ tip += linkText;
+ }
+ tip+="</nowrap></font></u></td></tr><tr><td>";
+ QMimeSourceFactory::defaultFactory()->setPixmap("host_icon",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)));
+
+ if(linkText.find('*') != -1)
+ {
+ if(linkText.length() > 1)tip += __tr2qs("Unable to look it up hostname: Hostname appears to be masked");
+ else tip += __tr2qs("Unable to look it up hostname: Unknown host");
+ } else {
+ tip += __tr2qs("Double-click to look up this hostname<br>Right-click to view other options");
+ }
+ tip += "</td></tr></table>";
+ }
+ break;
+ case 's': // server link
+ {
+ // FIXME: #warning "Spit out some server info...hub ?...registered ?"
+
+ tip = "<table width=\"100%\">" \
+ "<tr><td valign=\"center\"><img src=\"server_icon\"> <u><font color=\"blue\"><nowrap>";
+ QMimeSourceFactory::defaultFactory()->setPixmap("server_icon",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_IRC)));
+ if(linkText.length() > 50)
+ {
+ tip += linkText.left(47);
+ tip += "...";
+ } else {
+ tip += linkText;
+ }
+ tip+="</nowrap></font></u></td></tr><tr><td>";
+
+ if(linkText.find('*') != -1)
+ {
+ if(linkText.length() > 1)tip += __tr2qs("Server appears to be a network hub<br>");
+ else tip += __tr2qs("Unknown server<br>"); // might happen...
+ }
+
+ tip.append(__tr2qs("Double-click to read the MOTD<br>Right-click to view other options"));
+ tip += "</td></tr></table>";
+ }
+ break;
+ case 'm': // mode link
+ {
+ if((linkCmd.length() > 2) && (m_pKviWindow->type() == KVI_WINDOW_TYPE_CHANNEL))
+ {
+ if(((KviChannel *)m_pKviWindow)->isMeOp())
+ {
+ QChar plmn = linkCmd[1];
+ if((plmn.unicode() == '+') || (plmn.unicode() == '-'))
+ {
+ tip = __tr2qs("Double-click to set<br>");
+ QChar flag = linkCmd[2];
+ switch(flag.unicode())
+ {
+ case 'o':
+ case 'v':
+ // We can do nothing here...
+ tip = "";
+ break;
+ case 'b':
+ case 'I':
+ case 'e':
+ case 'k':
+ KviQString::appendFormatted(tip,QString("<b>mode %Q %c%c %Q</b>"),&(m_pKviWindow->windowName()),plmn.latin1(),flag.latin1(),&linkText);
+ break;
+ default:
+ KviQString::appendFormatted(tip,QString("<b>mode %Q %c%c</b>"),&(m_pKviWindow->windowName()),plmn.latin1(),flag.latin1());
+ break;
+ }
+ }
+ } else {
+ // I'm not op...no way
+ tip = __tr2qs("You're not an operator: You may not change channel modes");
+ }
+ }
+ }
+ break;
+ case 'n': // nick link
+ {
+ if(console())
+ {
+ if(console()->connection())
+ {
+ KviIrcUserEntry * e = console()->connection()->userDataBase()->find(linkText);
+ if(e)
+ {
+ QString buffer;
+ console()->getUserTipText(linkText,e,buffer);
+ tip = buffer;
+ } else KviQString::sprintf(tip,__tr2qs("Nothing known about %Q"),&linkText);
+ } else KviQString::sprintf(tip,__tr2qs("Nothing known about %Q (no connection)"),&linkText);
+ }
+ }
+ break;
+ case 'c': // channel link
+ {
+ if(console() && console()->connection())
+ {
+ QString szChan = linkText;
+ QString buf;
+ tip = "<img src=\"chan_icon\"> ";
+ QMimeSourceFactory::defaultFactory()->setPixmap("chan_icon",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)));
+
+ if(szCmd.length()>0) szChan=szCmd;
+ KviChannel * c = console()->connection()->findChannel(szChan);
+ QString szUrl;
+ if(c)
+ {
+ QString chanMode;
+ c->getChannelModeString(chanMode);
+ QString topic = KviMircCntrl::stripControlBytes(c->topicWidget()->topic());
+ topic.replace("<","&lt;");
+ topic.replace(">","&gt;");
+ KviIrcUrl::join(szUrl,console()->connection()->target()->server());
+ szUrl.append(szChan);
+ KviQString::sprintf(buf,__tr2qs("<b>%Q</b> (<u><font color=\"blue\"><nowrap>"
+ "%Q</nowrap></font></u>): <br><nowrap>+%Q (%u users)<hr>%Q</nowrap>"),&szChan,&szUrl,&chanMode,
+ c->count(),&topic);
+ } else {
+ KviIrcUrl::join(szUrl,console()->connection()->target()->server());
+ szUrl.append(szChan);
+ KviQString::sprintf(buf,__tr2qs("<b>%Q</b> (<u><font color=\"blue\"><nowrap>"
+ "%Q</nowrap></font></u>)<hr>Double-click to join %Q<br>Right click to view other options"),&szChan,&szUrl,&szChan);
+ }
+
+ tip += buf;
+ }
+ }
+ break;
+ default:
+ {
+ QString dbl,rbt,txt,mbt;
+ getLinkEscapeCommand(dbl,linkCmd,"[!dbl]");
+ getLinkEscapeCommand(rbt,linkCmd,"[!rbt]");
+ getLinkEscapeCommand(txt,linkCmd,"[!txt]");
+ getLinkEscapeCommand(mbt,linkCmd,"[!mbt]");
+
+ if(!txt.isEmpty())tip = txt;
+ if(tip.isEmpty() && (!dbl.isEmpty()))
+ {
+ if(!tip.isEmpty())tip.append("<hr>");
+ KviQString::appendFormatted(tip,__tr2qs("<b>Double-click:</b><br>%Q"),&dbl);
+ }
+ if(tip.isEmpty() && (!mbt.isEmpty()))
+ {
+ if(!tip.isEmpty())tip.append("<hr>");
+ KviQString::appendFormatted(tip,__tr2qs("<b>Middle-click:</b><br>%Q"),&mbt);
+ }
+ if(tip.isEmpty() && (!rbt.isEmpty()))
+ {
+ if(!tip.isEmpty())tip.append("<hr>");
+ KviQString::appendFormatted(tip,__tr2qs("<b>Right-click:</b><br>%Q"),&rbt);
+ }
+ }
+ break;
+ }
+
+ if(tip.isEmpty())return;
+
+ m_pToolTip->doTip(rct,tip);
+}
+void KviIrcView::leaveEvent ( QEvent * )
+{
+ if(m_pLastLinkUnderMouse)
+ {
+ m_pLastLinkUnderMouse=0;
+ update();
+ }
+}
+void KviIrcView::timerEvent(QTimerEvent *e)
+{
+ m_mouseCurrentPos = mapFromGlobal(QCursor::pos());
+
+ if(e->timerId() == m_iSelectTimer)
+ {
+ calculateSelectionBounds();
+ repaint();
+ }
+ if(e->timerId() == m_iMouseTimer)
+ {
+ killTimer(m_iMouseTimer);
+ m_iMouseTimer=0;
+ mouseRealPressEvent(m_pLastEvent);
+ delete m_pLastEvent;
+ m_pLastEvent=0;
+ }
+ if(e->timerId() == m_iFlushTimer)
+ {
+ flushLog();
+ }
+}
+
+void KviIrcView::keyPressEvent(QKeyEvent *e)
+{
+ switch(e->key())
+ {
+ case Qt::Key_PageUp:
+ prevPage();
+ e->accept();
+ break;
+ case Qt::Key_PageDown:
+ nextPage();
+ e->accept();
+ break;
+ default:
+ e->ignore();
+ }
+}
+
+void KviIrcView::maybeTip(const QPoint &pnt)
+{
+ QString linkCmd;
+ QString linkText;
+
+ QRect rctLink;
+
+ KviIrcViewWrappedBlock * linkUnderMouse = getLinkUnderMouse(pnt.x(),pnt.y(),&rctLink,&linkCmd,&linkText);
+
+ if((linkUnderMouse == m_pLastLinkUnderMouse) && linkUnderMouse)doLinkToolTip(rctLink,linkCmd,linkText);
+ else m_pLastLinkUnderMouse = 0; //
+}
+
+#include "kvi_ircview.moc"
diff --git a/src/kvirc/ui/kvi_ircview.h b/src/kvirc/ui/kvi_ircview.h
new file mode 100644
index 0000000..62ee3e7
--- /dev/null
+++ b/src/kvirc/ui/kvi_ircview.h
@@ -0,0 +1,252 @@
+#ifndef _KVI_IRCVIEW_H_
+#define _KVI_IRCVIEW_H_
+//=========================================================================================================
+//
+// File : kvi_ircview.h
+// Creation date : Fri Mar 19 1999 05:39:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================================================================
+
+#include "kvi_settings.h"
+#include "kvi_string.h"
+#include "kvi_pointerlist.h"
+
+#include <qwidget.h>
+#include <qpixmap.h> // needed
+
+class QScrollBar;
+class QLineEdit;
+class QFile;
+class QToolButton;
+class QFontMetrics;
+class KviTalPopupMenu;
+
+class KviWindow;
+class KviFrame;
+class KviConsole;
+class KviIrcViewToolWidget;
+class KviIrcViewToolTip;
+
+typedef struct _KviIrcViewLineChunk KviIrcViewLineChunk;
+typedef struct _KviIrcViewWrappedBlock KviIrcViewWrappedBlock;
+typedef struct _KviIrcViewLine KviIrcViewLine;
+typedef struct _KviIrcViewWrappedBlockSelectionInfoTag KviIrcViewWrappedBlockSelectionInfo;
+
+#define KVI_IRCVIEW_INVALID_LINE_MARK_INDEX 0xffffffff
+
+class KVIRC_API KviIrcView : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(int TransparencyCapable READ dummyRead)
+ // we cannot #ifdef due to a bug in moc
+ Q_PROPERTY(bool usePaintOnScreen READ getPaintOnScreen WRITE setPaintOnScreen)
+public:
+ friend class KviIrcViewToolTip;
+ friend class KviIrcViewToolWidget;
+public:
+ KviIrcView(QWidget *parent,KviFrame *pFrm,KviWindow *pWnd);
+ ~KviIrcView();
+public:
+ int dummyRead() const { return 0; };
+#ifdef COMPILE_USE_QT4
+ bool getPaintOnScreen() const { return testAttribute(Qt::WA_PaintOnScreen);};
+ void setPaintOnScreen(bool bFlag){setAttribute(Qt::WA_PaintOnScreen,bFlag);} ;
+#else
+ // hack to fix moc bug on win qt4
+ bool getPaintOnScreen() const { return 0;};
+ void setPaintOnScreen(bool bFlag){} ;
+#endif
+private:
+// QDate m_lastLogDay;
+ int m_iFlushTimer;
+ KviIrcViewLine * m_pFirstLine;
+ KviIrcViewLine * m_pCurLine; // Bottom line in the view
+ KviIrcViewLine * m_pLastLine;
+ KviIrcViewLine * m_pCursorLine;
+ unsigned int m_uLineMarkLineIndex;
+
+ // Highliting of links
+ KviIrcViewWrappedBlock * m_pLastLinkUnderMouse;
+ int m_iLastLinkRectTop;
+ int m_iLastLinkRectHeight;
+
+ int m_iNumLines;
+ int m_iMaxLines;
+
+ unsigned int m_uNextLineIndex;
+
+ QPixmap * m_pPrivateBackgroundPixmap;
+ QScrollBar * m_pScrollBar;
+ QToolButton * m_pToolsButton;
+ KviTalPopupMenu * m_pToolsPopup;
+
+ KviIrcViewToolWidget * m_pToolWidget;
+
+ int m_iLastScrollBarValue;
+
+ // Font related stuff (needs precalculation!)
+ int m_iFontLineSpacing;
+ int m_iFontLineWidth;
+ int m_iFontDescent;
+ int m_iFontCharacterWidth[256]; //1024 bytes fixed
+
+ int m_iWrapMargin;
+ int m_iMinimumPaintWidth;
+ int m_iRelativePixmapY;
+ int m_iIconWidth;
+ int m_iIconSideSpacing;
+
+ QPoint m_mousePressPos;
+ QPoint m_mouseCurrentPos;
+
+ // Selection
+ int m_iSelectionBegin;
+ int m_iSelectionTop;
+ int m_iSelectionEnd;
+ int m_iSelectionBottom;
+ int m_iSelectionLeft;
+ int m_iSelectionRight;
+
+ bool m_bMouseIsDown;
+ bool m_bShiftPressed;
+
+ bool m_bSkipScrollBarRepaint;
+ int m_iSelectTimer;
+ int m_iMouseTimer;
+ //int m_iTipTimer;
+ QString m_szLastSelection;
+ QString m_szLastSelectionLine;
+ KviWindow * m_pKviWindow;
+ KviIrcViewWrappedBlockSelectionInfo * m_pWrappedBlockSelectionInfo;
+ QFile * m_pLogFile;
+ KviFrame * m_pFrm;
+ bool m_bAcceptDrops;
+ int m_iUnprocessedPaintEventRequests;
+ bool m_bPostedPaintEventPending;
+ KviPointerList<KviIrcViewLine> * m_pMessagesStoppedWhileSelecting;
+ KviIrcView * m_pMasterView;
+ QFontMetrics * m_pFm; // assume this valid only inside a paint event (may be 0 in other circumstances)
+
+ QMouseEvent * m_pLastEvent;
+
+ KviIrcViewToolTip * m_pToolTip;
+ bool m_bHaveUnreadedHighlightedMessages;
+ bool m_bHaveUnreadedMessages;
+public:
+ void checkLogDate();
+ void clearUnreaded();
+ void applyOptions();
+ void enableDnd(bool bEnable);
+ bool haveUnreadedMessages() { return m_bHaveUnreadedMessages; };
+ bool haveUnreadedHighlightedMessages() { return m_bHaveUnreadedHighlightedMessages; };
+ enum AppendTextFlags { NoRepaint = 1, NoTimestamp = 2, SetLineMark = 4 };
+ void appendText(int msg_type,const kvi_wchar_t *data_ptr,int iFlags = 0);
+ void clearLineMark(bool bRepaint=false);
+ bool hasLineMark(){ return m_uLineMarkLineIndex != KVI_IRCVIEW_INVALID_LINE_MARK_INDEX; };
+ void removeHeadLine(bool bRepaint=false);
+ void emptyBuffer(bool bRepaint=true);
+ void getTextBuffer(QString &buffer);
+ void setMaxBufferSize(int maxBufSize,bool bRepaint=true);
+ int maxBufferSize(){ return m_iMaxLines; }; //Never used ?
+ bool saveBuffer(const char *filename);
+ void findNext(const QString& szText,bool bCaseS = false,bool bRegExp = false,bool bExtended = false);
+ void findPrev(const QString& szText,bool bCaseS = false,bool bRegExp = false,bool bExtended = false);
+ KviWindow * parentKviWindow(){ return m_pKviWindow; };
+ KviConsole * console();
+ // A null pixmap passed here unsets the private backgrdound.
+ void setPrivateBackgroundPixmap(const QPixmap &pixmap,bool bRepaint=true);
+ bool hasPrivateBackgroundPixmap(){ return (m_pPrivateBackgroundPixmap != 0); };
+
+ //==============================================================================================
+ // Logging
+ // Stops previous logging session too...
+ bool startLogging(const QString& fname = QString::null,bool bPrependCurBuffer = false);
+ void stopLogging();
+ bool isLogging(){ return (m_pLogFile != 0); };
+ void getLogFileName(KviStr &buffer);
+ void getLogFileName(QString &buffer);
+ //void add2Log(const char *buffer,int buf_len=-1);
+ void add2Log(const QString &szBuffer,int iMsgType=0);
+
+ //==============================================================================================
+ // Channel view splitting
+ void setMasterView(KviIrcView * v);
+ void splitMessagesTo(KviIrcView * v);
+ void joinMessagesFrom(KviIrcView * v);
+ void appendMessagesFrom(KviIrcView * v);
+
+ void prevLine();
+ void nextLine();
+ void nextPage();
+ void prevPage();
+ virtual QSize sizeHint() const;
+ const QString & lastLineOfText();
+ const QString & lastMessageText();
+ virtual void setFont(const QFont &f);
+public slots:
+ void flushLog();
+ void showToolsPopup();
+ void clearBuffer();
+ void toggleToolWidget();
+ void increaseFontSize();
+ void decreaseFontSize();
+ void chooseFont();
+ void chooseBackground();
+ void resetBackground();
+signals:
+ void rightClicked();
+ void dndEntered();
+ void fileDropped(const char *);
+private:
+ void setCursorLine(KviIrcViewLine * l);
+ KviIrcViewLine * getVisibleLineAt(int xPos,int yPos);
+ void getLinkEscapeCommand(QString &buffer,const QString &escape_cmd,const QString &escape_label);
+ void appendLine(KviIrcViewLine *ptr,bool bRepaint);
+ void postUpdateEvent();
+ void fastScroll(int lines = 1);
+ const kvi_wchar_t * getTextLine(int msg_type,const kvi_wchar_t * data_ptr,KviIrcViewLine *line_ptr,bool bEnableTimeStamp = true);
+ void calculateLineWraps(KviIrcViewLine *ptr,int maxWidth);
+ void recalcFontVariables(const QFontMetrics &fm,const QFontInfo &fi);
+ bool checkSelectionBlock(KviIrcViewLine * line,int left,int bottom,int bufIndex);
+ void calculateSelectionBounds();
+ KviIrcViewWrappedBlock * getLinkUnderMouse(int xPos,int yPos,QRect * pRect = 0,QString * linkCmd = 0,QString * linkText = 0);
+ void doLinkToolTip(const QRect &rct,QString &linkCmd,QString &linkText);
+protected:
+ virtual void paintEvent(QPaintEvent *);
+ virtual void resizeEvent(QResizeEvent *);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseRealPressEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void timerEvent(QTimerEvent *e);
+ virtual void dragEnterEvent(QDragEnterEvent *e);
+ virtual void dropEvent(QDropEvent *e);
+ virtual bool event(QEvent *e);
+ virtual void wheelEvent(QWheelEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+ void maybeTip(const QPoint &pnt);
+ virtual void leaveEvent ( QEvent * );
+protected slots:
+ virtual void scrollBarPositionChanged(int newValue);
+ void masterDead();
+};
+
+#endif //_KVI_IRCVIEW_H_
diff --git a/src/kvirc/ui/kvi_ircviewprivate.h b/src/kvirc/ui/kvi_ircviewprivate.h
new file mode 100644
index 0000000..0a2dea2
--- /dev/null
+++ b/src/kvirc/ui/kvi_ircviewprivate.h
@@ -0,0 +1,164 @@
+#ifndef _KVI_IRCVIEWPRIVATE_H_
+#define _KVI_IRCVIEWPRIVATE_H_
+//=========================================================================================================
+//
+// File : kvi_ircviewprivate.h
+// Creation date : Sat Oct 9 2004 16:29:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================================================================
+
+#include "kvi_settings.h"
+#include <qstring.h>
+
+//=========================================================================================================
+// Internal data structures
+//=========================================================================================================
+
+// Force the structs to be packed...
+#ifdef COMPILE_ON_WINDOWS
+ #pragma pack(push,old_packing,1)
+ #define _KVI_PACKED
+#else //!COMPILE_ON_WIDNOWS
+ // this works only on gcc
+ #ifdef __GNUC__
+ #define _KVI_PACKED __attribute__((__packed__))
+ #else
+ #define _KVI_PACKED
+ #endif
+#endif //!COMPILE_ON_WINDOWS
+
+//
+// The LineChunk structure contains informations about
+// an attribute change, an icon or a link
+//
+// type can be one of:
+//
+// KVI_TEXT_ICON:
+// the uIconId member is the icon to be shown
+// szPayload contains the text that triggered this icon was triggered by
+// KVI_TEXT_UNICON:
+// the text block after an icon
+// KVI_TEXT_ESCAPE:
+// szPayload contains the encoded escape command
+// colors.fore contains the new text color
+// KVI_TEXT_UNESCAPE:
+// the text block after an escape
+// KVI_TEXT_COLOR:
+// the colors.back and colors.fore members indicate the color change
+// KVI_TEXT_BOLD:
+// toggles the bold flag
+// KVI_TEXT_UNDERLINE:
+// toggles the underline flag
+// KVI_TEXT_REVERSE:
+// inverts the current fore and back colors
+// KVI_TEXT_RESET:
+// resets the color, bold and underline flags
+//
+
+typedef struct _KviIrcViewLineChunk
+{
+ unsigned char type; // chunk type
+ int iTextStart; // index in the szText string of the beginning of the block
+ int iTextLen; // length in chars of the block (excluding the terminator)
+ kvi_wchar_t * szPayload; // KVI_TEXT_ESCAPE attribute command buffer and KVI_TEXT_ICON icon name (non zeroed for other attributes!!!)
+ kvi_wchar_t * szSmileId;
+ struct {
+ unsigned char back; // optional background color for KVI_TEXT_COLOR attribute
+ unsigned char fore; // optional foreground color for KVI_TEXT_COLOR attribute (used also for KVI_TEXT_ESCAPE!!!)
+ } _KVI_PACKED colors; // anonymous
+// QColor customBack;
+ QColor customFore;
+} /*_KVI_PACKED*/ KviIrcViewLineChunk;
+
+//
+// The wrapped paintable data block
+//
+
+typedef struct _KviIrcViewWrappedBlock
+{
+ KviIrcViewLineChunk * pChunk; // pointer to real line chunk or 0 for word wraps
+ int block_start; // this is generally different than pAttribute->block_idx!
+ int block_len; // length if the block in characters
+ int block_width; // width of the block in pixels
+} _KVI_PACKED KviIrcViewWrappedBlock;
+
+
+typedef struct _KviIrcViewLine
+{
+ // this is a text line in the IrcView's memory
+ unsigned int uIndex; // index of the text line (needed for find and splitting)
+ QString szText; // data string without color codes nor escapes...
+ int iMsgType; // type of the line (defines icon and colors)
+
+ // At line instert time the szData text is splitted in parts which
+ // signal attribute changes (or icons)
+ unsigned int uChunkCount; // number of allocated chunks
+ KviIrcViewLineChunk * pChunks; // pointer to the allocated structures
+
+ // At paint time the data is re-splitted in drawable chunks which
+ // are either real data chunks or line wraps.
+ // The algorightm that does this is lazy and computes it
+ // only once for a given widget width (iMaxLineWidth)
+ unsigned int uLineWraps; // number of line wraps (lines - 1)
+ int iMaxLineWidth; // width that the blocks were calculated for (lazy calculation)
+ int iBlockCount; // number of allocated paintable blocks
+ KviIrcViewWrappedBlock * pBlocks; // pointer to the re-splitted paintable blocks
+
+ // next and previous line
+ struct _KviIrcViewLine * pPrev;
+ struct _KviIrcViewLine * pNext;
+} KviIrcViewLine;
+
+typedef struct _KviIrcViewWrappedBlockSelectionInfoTag
+{
+ int selection_type;
+ /*struct {
+ int length;
+ int width;
+ } part[3];*/
+ int part_1_length;
+ int part_1_width;
+ int part_2_length;
+ int part_2_width;
+ int part_3_length;
+ int part_3_width;
+} KviIrcViewWrappedBlockSelectionInfo;
+
+#ifdef COMPILE_ON_WINDOWS
+ #pragma pack(pop,old_packing)
+#else //!COMPILE_ON_WINDOWS
+ #undef _KVI_PACKED
+#endif //!COMPILE_ON_WINDOWS
+
+//=========================================================================================================
+// Screen layout
+//=========================================================================================================
+
+//FIRST LINE (prev_line = 0) <---m_pFirstLine
+//LINE
+//--------------------SCREEN--
+//LINE
+//LINE
+//LINE
+//LINE <-------------------------m_pCurLine
+//--------------------SCREEN--
+//LAST LINE (next_line = 0) <----m_pLastLine
+
+#endif //!_KVI_IRCVIEWPRIVATE_H_
diff --git a/src/kvirc/ui/kvi_ircviewtools.cpp b/src/kvirc/ui/kvi_ircviewtools.cpp
new file mode 100644
index 0000000..ea47310
--- /dev/null
+++ b/src/kvirc/ui/kvi_ircviewtools.cpp
@@ -0,0 +1,348 @@
+//=============================================================================
+//
+// File : kvi_ircviewtools.cpp
+// Creation date : Sat Oct 9 2004 16:03:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_ircviewtools.h"
+#include "kvi_ircview.h"
+#include "kvi_styled_controls.h"
+#include "kvi_iconmanager.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_malloc.h"
+#include "kvi_msgbox.h"
+#include "kvi_filedialog.h"
+#include "kvi_app.h"
+#include "kvi_memmove.h"
+
+#include <qtoolbutton.h>
+#include <qtabwidget.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#ifdef COMPILE_USE_QT4
+ #include <q3header.h>
+#else
+ #include <qheader.h>
+#endif
+#include <qlineedit.h>
+#include <qcursor.h>
+#include "kvi_accel.h"
+#include <qevent.h>
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tool widget implementation
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviIrcMessageCheckListItem::KviIrcMessageCheckListItem(KviTalListView * par,KviIrcViewToolWidget * w,int id)
+: KviTalCheckListItem(par,QString::null,KviTalCheckListItem::CheckBox)
+{
+ m_iId = id;
+ m_pToolWidget = 0;
+ setPixmap(0,*(g_pIconManager->getSmallIcon(KVI_OPTION_MSGTYPE(id).pixId())));
+ setOn(true);
+ m_pToolWidget = w;
+}
+
+KviIrcMessageCheckListItem::~KviIrcMessageCheckListItem()
+{
+}
+
+void KviIrcMessageCheckListItem::stateChange(bool bOn)
+{
+ KviTalCheckListItem::stateChange(bOn);
+ if(!m_pToolWidget)return;
+ m_pToolWidget->forceRepaint();
+}
+
+
+
+KviIrcViewToolWidget::KviIrcViewToolWidget(KviIrcView * par)
+: QFrame(par)
+{
+ m_pIrcView = par;
+ setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+
+ QGridLayout * gl = new QGridLayout(this,2,2,4,2);
+
+ QLabel * l = new QLabel(__tr2qs("<b><font color=\"#EAEAEA\" size=\"-1\">Find Text</font></b>"),this);
+ l->setMaximumHeight(14);
+ l->setBackgroundColor(Qt::black);
+ gl->addWidget(l,0,0);
+
+ QToolButton *tb = new QToolButton(Qt::DownArrow,this,"down_arrow");
+ tb->setFixedSize(14,14);
+ tb->setAutoRepeat(false);
+ connect(tb,SIGNAL(clicked()),m_pIrcView,SLOT(toggleToolWidget()));
+ gl->addWidget(tb,0,1);
+
+
+ QTabWidget * tw = new QTabWidget(this);
+
+
+
+ // Find tab
+ QWidget * w = new QWidget(tw);
+
+ QGridLayout * g = new QGridLayout(w,6,2,2,1);
+
+ m_pStringToFind = new QLineEdit(w);
+ g->addMultiCellWidget(m_pStringToFind,0,0,0,2);
+ connect(m_pStringToFind,SIGNAL(returnPressed()),this,SLOT(findNext()));
+
+ m_pRegExp = new KviStyledCheckBox(__tr2qs("&Regular expression"),w);
+ g->addMultiCellWidget(m_pRegExp,1,1,0,2);
+
+ m_pExtendedRegExp = new KviStyledCheckBox(__tr2qs("E&xtended regexp."),w);
+ g->addMultiCellWidget(m_pExtendedRegExp,2,2,0,2);
+ m_pExtendedRegExp->setEnabled(false);
+ connect(m_pRegExp,SIGNAL(toggled(bool)),m_pExtendedRegExp,SLOT(setEnabled(bool)));
+
+ m_pCaseSensitive = new KviStyledCheckBox(__tr2qs("C&ase sensitive"),w);
+ g->addMultiCellWidget(m_pCaseSensitive,3,3,0,2);
+
+ QPushButton * pb = new QPushButton(__tr2qs("Find &Prev."),w);
+ connect(pb,SIGNAL(clicked()),this,SLOT(findPrev()));
+ g->addWidget(pb,4,0);
+
+ pb = new QPushButton(__tr2qs("&Find Next"),w);
+ pb->setDefault(true);
+ connect(pb,SIGNAL(clicked()),this,SLOT(findNext()));
+ g->addMultiCellWidget(pb,4,4,1,2);
+
+ m_pFindResult = new QLabel(w);
+ m_pFindResult->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ g->addMultiCellWidget(m_pFindResult,5,5,0,2);
+
+ //g->setResizeMode(QGridLayout::Fixed);
+
+ tw->addTab(w,__tr2qs("Find"));
+
+ // Filter tab
+ QWidget * w1 = new QWidget(tw);
+
+ g = new QGridLayout(w1,5,2,2,1);
+
+ m_pFilterView = new KviTalListView(w1);
+ m_pFilterView->addColumn(__tr2qs("Type"));
+ m_pFilterView->header()->hide();
+ m_pFilterView->setMinimumSize(QSize(10,10));
+
+ g->addMultiCellWidget(m_pFilterView,0,4,0,0);
+
+
+ m_pFilterItems = (KviIrcMessageCheckListItem **)kvi_malloc(KVI_NUM_MSGTYPE_OPTIONS * sizeof(KviIrcMessageCheckListItem *));
+
+ for(int i=0;i<KVI_NUM_MSGTYPE_OPTIONS;i++)
+ {
+ m_pFilterItems[i] = new KviIrcMessageCheckListItem(m_pFilterView,this,i);
+ }
+
+ pb = new QPushButton(__tr2qs("Set &All"),w1);
+ connect(pb,SIGNAL(clicked()),this,SLOT(filterEnableAll()));
+ g->addWidget(pb,0,1);
+
+ pb = new QPushButton(__tr2qs("Set &None"),w1);
+ connect(pb,SIGNAL(clicked()),this,SLOT(filterEnableNone()));
+ g->addWidget(pb,1,1);
+
+ pb = new QPushButton(__tr2qs("&Load From..."),w1);
+ connect(pb,SIGNAL(clicked()),this,SLOT(filterLoad()));
+ g->addWidget(pb,2,1);
+
+ pb = new QPushButton(__tr2qs("&Save As..."),w1);
+ connect(pb,SIGNAL(clicked()),this,SLOT(filterSave()));
+ g->addWidget(pb,3,1);
+
+ tw->addTab(w1,__tr2qs("Filter"));
+
+ gl->addMultiCellWidget(tw,1,1,0,1);
+
+ gl->setResizeMode(QGridLayout::Fixed);
+ m_pStringToFind->setFocus();
+ tw->showPage(w);
+ KviAccel *a = new KviAccel( this );
+ a->connectItem( a->insertItem(Qt::Key_Escape), this,SLOT(close()) );
+}
+
+KviIrcViewToolWidget::~KviIrcViewToolWidget()
+{
+ kvi_free((void *)m_pFilterItems);
+}
+
+void KviIrcViewToolWidget::filterEnableAll()
+{
+ for(int i=0;i<KVI_NUM_MSGTYPE_OPTIONS;i++)
+ {
+ m_pFilterItems[i]->setToolWidget(0);
+ m_pFilterItems[i]->setOn(true);
+ m_pFilterItems[i]->setToolWidget(this);
+ }
+ forceRepaint();
+}
+
+void KviIrcViewToolWidget::filterEnableNone()
+{
+ for(int i=0;i<KVI_NUM_MSGTYPE_OPTIONS;i++)
+ {
+ m_pFilterItems[i]->setToolWidget(0);
+ m_pFilterItems[i]->setOn(false);
+ m_pFilterItems[i]->setToolWidget(this);
+ }
+ forceRepaint();
+}
+
+void KviIrcViewToolWidget::hideEvent ( QHideEvent * ){
+ m_pIrcView->toggleToolWidget();
+}
+
+void KviIrcViewToolWidget::closeEvent ( QCloseEvent * e ){
+ m_pIrcView->toggleToolWidget();
+}
+
+void KviIrcViewToolWidget::filterLoad()
+{
+ QString szFile;
+ QString szInit;
+ g_pApp->getLocalKvircDirectory(szInit,KviApp::Filters);
+
+ if(KviFileDialog::askForOpenFileName(szFile,__tr2qs("Select a Filter File"),szInit))
+ {
+ QFile f(szFile);
+ if(f.open(IO_ReadOnly))
+ {
+ char buffer[KVI_NUM_MSGTYPE_OPTIONS];
+ kvi_memset(buffer,0,KVI_NUM_MSGTYPE_OPTIONS);
+ f.readBlock(buffer,KVI_NUM_MSGTYPE_OPTIONS);
+ f.close();
+ for(int i=0;i<KVI_NUM_MSGTYPE_OPTIONS;i++)
+ {
+ m_pFilterItems[i]->setToolWidget(0);
+ m_pFilterItems[i]->setOn(buffer[i]);
+ m_pFilterItems[i]->setToolWidget(this);
+ }
+ forceRepaint();
+ } else {
+ KviMessageBox::warning(__tr2qs("Can't open the filter file %s for reading."),&szFile);
+ }
+ }
+}
+
+void KviIrcViewToolWidget::filterSave()
+{
+ QString szFile;
+ QString szInit;
+ g_pApp->getLocalKvircDirectory(szInit,KviApp::Filters,"filter.kvf");
+ if(KviFileDialog::askForSaveFileName(szFile,__tr2qs("Select a Name for the Filter File"),szInit,0,false,true))
+ {
+ QFile f(szFile);
+ if(f.open(IO_WriteOnly))
+ {
+ char buffer[KVI_NUM_MSGTYPE_OPTIONS];
+ for(int i=0;i<KVI_NUM_MSGTYPE_OPTIONS;i++)
+ {
+ buffer[i] = messageEnabled(i) ? 1 : 0;
+ }
+ if(f.writeBlock(buffer,KVI_NUM_MSGTYPE_OPTIONS) < KVI_NUM_MSGTYPE_OPTIONS)
+ KviMessageBox::warning(__tr2qs("Failed to write the filter file %Q (IO Error)"),&szFile);
+ f.close();
+ } else KviMessageBox::warning(__tr2qs("Can't open the filter file %Q for writing"),&szFile);
+ }
+}
+
+void KviIrcViewToolWidget::forceRepaint()
+{
+ #if defined(COMPILE_USE_QT4) && defined(COMPILE_ON_WINDOWS)
+ m_pIrcView->repaint();
+ #else
+ m_pIrcView->paintEvent(0);
+ #endif
+
+}
+
+void KviIrcViewToolWidget::setFindResult(const QString & text)
+{
+ m_pFindResult->setText(text);
+}
+
+void KviIrcViewToolWidget::findPrev()
+{
+ bool bRegExp = m_pRegExp->isChecked();
+ m_pIrcView->findPrev(m_pStringToFind->text(),m_pCaseSensitive->isChecked(),bRegExp,bRegExp && m_pExtendedRegExp->isChecked());
+}
+
+void KviIrcViewToolWidget::findNext()
+{
+ bool bRegExp = m_pRegExp->isChecked();
+ m_pIrcView->findNext(m_pStringToFind->text(),m_pCaseSensitive->isChecked(),bRegExp,bRegExp && m_pExtendedRegExp->isChecked());
+}
+
+
+void KviIrcViewToolWidget::mousePressEvent(QMouseEvent *e)
+{
+ m_pressPoint = e->pos();
+}
+
+void KviIrcViewToolWidget::mouseMoveEvent(QMouseEvent *)
+{
+ QPoint p=m_pIrcView->mapFromGlobal(QCursor::pos());
+ p-=m_pressPoint;
+ if(p.x() < 1)p.setX(1);
+ else {
+ int www = (m_pIrcView->width() - (m_pIrcView->m_pScrollBar->width() + 1));
+ if((p.x() + width()) > www)p.setX(www - width());
+ }
+ if(p.y() < 1)p.setY(1);
+ else {
+ int hhh = (m_pIrcView->height() - 1);
+ if((p.y() + height()) > hhh)p.setY(hhh - height());
+ }
+ move(p);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Link tip label implementation
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviIrcViewToolTip::KviIrcViewToolTip(KviIrcView * pView)
+: KviTalToolTip(pView)
+{
+ m_pView = pView;
+}
+
+KviIrcViewToolTip::~KviIrcViewToolTip()
+{
+}
+
+void KviIrcViewToolTip::maybeTip(const QPoint &pnt)
+{
+ m_pView->maybeTip(pnt);
+}
+
diff --git a/src/kvirc/ui/kvi_ircviewtools.h b/src/kvirc/ui/kvi_ircviewtools.h
new file mode 100644
index 0000000..248c180
--- /dev/null
+++ b/src/kvirc/ui/kvi_ircviewtools.h
@@ -0,0 +1,119 @@
+#ifndef _KVI_IRCVIEWTOOLS_H_
+#define _KVI_IRCVIEWTOOLS_H_
+//=========================================================================================================
+//
+// File : kvi_ircviewtools.h
+// Creation date : Sat Oct 9 2004 16:03:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================================================================
+
+#include "kvi_settings.h"
+
+#include "kvi_tal_tooltip.h"
+#include <qframe.h>
+#include "kvi_tal_listview.h"
+#include <qstring.h>
+
+class QLabel;
+//class KviStyledCheckBox;
+#include "kvi_styled_controls.h"
+class QLineEdit;
+
+class KviIrcView;
+
+class KviIrcViewToolTip : public KviTalToolTip
+{
+public:
+ KviIrcViewToolTip(KviIrcView * pView);
+ virtual ~KviIrcViewToolTip();
+protected:
+ KviIrcView * m_pView;
+protected:
+ virtual void maybeTip(const QPoint &pnt);
+public:
+ void doTip(const QRect &rct,const QString &str){ tip(rct,str); };
+};
+
+//=========================================================================================================
+// Item for the filter list view
+//=========================================================================================================
+
+class KviIrcViewToolWidget;
+
+class KviIrcMessageCheckListItem : public KviTalCheckListItem
+{
+public:
+ KviIrcMessageCheckListItem(KviTalListView * par,KviIrcViewToolWidget * w,int id);
+ ~KviIrcMessageCheckListItem();
+private:
+ int m_iId;
+ KviIrcViewToolWidget * m_pToolWidget;
+public:
+ void setToolWidget(KviIrcViewToolWidget * w){ m_pToolWidget = w; };
+ virtual void stateChange(bool bOn);
+};
+
+//=========================================================================================================
+// Search tools widget
+//=========================================================================================================
+
+class KviIrcView;
+
+class KviIrcViewToolWidget : public QFrame
+{
+ friend class KviIrcView;
+ Q_OBJECT
+protected:
+ KviIrcViewToolWidget(KviIrcView * par);
+ ~KviIrcViewToolWidget();
+protected:
+ KviIrcView * m_pIrcView;
+ QLineEdit * m_pStringToFind;
+ QPoint m_pressPoint;
+
+ KviStyledCheckBox * m_pCaseSensitive;
+ KviStyledCheckBox * m_pRegExp;
+ KviStyledCheckBox * m_pExtendedRegExp;
+
+ QLabel * m_pFindResult;
+
+ KviTalListView * m_pFilterView;
+
+ KviIrcMessageCheckListItem ** m_pFilterItems;
+
+public:
+ void setFindResult(const QString & text);
+ inline bool messageEnabled(int msg_type){ return m_pFilterItems[msg_type]->isOn(); }
+ void forceRepaint();
+protected slots:
+ void findPrev();
+ void findNext();
+ void filterEnableAll();
+ void filterEnableNone();
+ void filterSave();
+ void filterLoad();
+protected:
+ virtual void hideEvent( QHideEvent * );
+ virtual void closeEvent( QCloseEvent * e );
+ virtual void mouseMoveEvent(QMouseEvent *);
+ virtual void mousePressEvent(QMouseEvent *);
+};
+
+#endif //!_KVI_IRCVIEWTOOLS_H_
diff --git a/src/kvirc/ui/kvi_listview.cpp b/src/kvirc/ui/kvi_listview.cpp
new file mode 100644
index 0000000..e9c4b23
--- /dev/null
+++ b/src/kvirc/ui/kvi_listview.cpp
@@ -0,0 +1,212 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// File : kvi_listview.cpp
+// Creation date : 19 Jan 2006 GMT by Alexey Uzhva
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2006 Alexey Uzhva
+// Copyright (C) 2006 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define __KVIRC__
+
+#include "kvi_listview.h"
+
+#include <qpainter.h>
+#include <qpixmap.h>
+
+#include "kvi_doublebuffer.h"
+
+KviListView::KviListView( QWidget * parent, const char * name)
+:KviTalListView(parent)
+{
+ m_pBackgroundOverlayPixmap=0;
+ m_iBackgroundOverlayAlignment=Qt::AlignAuto;
+}
+
+KviListView::~KviListView()
+{
+ if(m_pBackgroundOverlayPixmap)
+ delete m_pBackgroundOverlayPixmap;
+}
+
+void KviListView::setBackgroundOverlayPixmap(QPixmap * pix,int iAlignmentFlags)
+{
+ setStaticBackground(TRUE);
+#ifdef COMPILE_USE_QT4
+ viewport()->setAutoFillBackground(false);
+#else
+ viewport()->setBackgroundMode(QWidget::NoBackground);
+#endif
+ m_pBackgroundOverlayPixmap=new QPixmap(*pix);
+ m_iBackgroundOverlayAlignment= Qt::AlignRight | Qt::AlignBottom;
+ repaintContents();
+}
+
+
+
+void KviListView::drawContentsOffset(QPainter * p,int ox,int oy,int cx,int cy,int cw,int ch)
+{
+ if(!m_pBackgroundOverlayPixmap)
+ {
+ KviTalListView::drawContentsOffset(p,ox,oy,cx,cy,cw,ch);
+ return;
+ }
+
+ if(cw <= 0)return; // this does happen
+ if(ch <= 0)return; // this does happen
+
+ KviDoubleBuffer pix(viewport()->width(),viewport()->height());
+
+ QPixmap * pMemPixmap = pix.pixmap();
+
+ QPainter pa(pMemPixmap);
+
+ int xx = cx - ox;
+ int yy = cy - oy;
+
+ pa.fillRect(QRect(xx,yy,cw,ch),viewport()->backgroundColor());
+
+ //KviTalListView::paintEmptyArea(&pa,);
+
+ // compute the pixmap position
+ int x,y;
+ if(m_iBackgroundOverlayAlignment == Qt::AlignAuto)
+ x=y=0;
+ else {
+ if(m_iBackgroundOverlayAlignment & Qt::AlignLeft)
+ x=0;
+ else if ( m_iBackgroundOverlayAlignment & Qt::AlignRight )
+ x=viewport()->width() - m_pBackgroundOverlayPixmap->width();
+ else if( m_iBackgroundOverlayAlignment & Qt::AlignHCenter )
+ x=(viewport()->width() - m_pBackgroundOverlayPixmap->width())/2;
+ else
+ x=0;
+
+ if( m_iBackgroundOverlayAlignment & Qt::AlignTop )
+ y=0;
+ else if ( m_iBackgroundOverlayAlignment & Qt::AlignBottom )
+ y=viewport()->height() - m_pBackgroundOverlayPixmap->height();
+ else if ( m_iBackgroundOverlayAlignment & Qt::AlignVCenter )
+ y=(viewport()->height() - m_pBackgroundOverlayPixmap->height())/2;
+ else
+ y=0;
+ }
+
+ pa.drawPixmap(xx,yy,*m_pBackgroundOverlayPixmap,xx-x,yy-y,cw,ch);
+
+ // Qt's auto double buffering is buggy and can't be disabled... too bad :/
+ //
+ // The Qt source for the listview painting is also totally unreadable
+ // (maybe that's why they have thrown this cool widget away in Qt4: unmantainable)
+ //
+ // Anyway, I've noticed that when double buffering is choosen (and
+ // Qt seems to have a really complex logic to choose when to enable it
+ // and when not) then the painter passed to paintCell() of the
+ // list view items is NOT this painter. It's the internal painter
+ // of the QSharedDoubleBuffer private Qt class. It's screwed
+ // because of the multiple coordinate translations. With this
+ // widget we screw it even more just because our paintEmptyArea()
+ // does nothing and we do double buffering ourselves.
+
+ KviTalListView::drawContentsOffset(&pa,ox,oy,cx,cy,cw,ch);
+
+ p->drawPixmap(xx,yy,*pMemPixmap,xx,yy,cw,ch);
+
+ //p->drawPixmap(cx-ox,cy-oy,*pMemPixmap,0,0,cw,ch);
+ //KviTalListView::drawContentsOffset(p,ox,oy,cx,cy,cw,ch);
+}
+
+
+void KviListView::paintEmptyArea(QPainter * p,const QRect & rect)
+{
+ if(!m_pBackgroundOverlayPixmap)
+ {
+ KviTalListView::paintEmptyArea(p,rect);
+ return;
+ }
+
+ // otherwise just do nothing (we're filling the background in drawContentsOffset)
+
+ /*
+ KviDoubleBuffer pix(rect.right()+1,rect.bottom()+1);
+
+ QPixmap * pMemPixmap = pix.pixmap();
+
+ QPainter pa(pMemPixmap);
+
+ pa.fillRect(rect,viewport()->backgroundColor());
+
+ KviTalListView::paintEmptyArea(&pa,rect);
+
+ QPoint realTopLeft = p->xForm(rect.topLeft());
+
+ // compute the pixmap position
+ int x,y;
+ if(m_iBackgroundOverlayAlignment == Qt::AlignAuto)
+ x=y=0;
+ else {
+ if(m_iBackgroundOverlayAlignment & Qt::AlignLeft)
+ x=0;
+ else if ( m_iBackgroundOverlayAlignment & Qt::AlignRight )
+ x=viewport()->width() - m_pBackgroundOverlayPixmap->width();
+ else if( m_iBackgroundOverlayAlignment & Qt::AlignHCenter )
+ x=(viewport()->width() - m_pBackgroundOverlayPixmap->width())/2;
+ else
+ x=0;
+
+ if( m_iBackgroundOverlayAlignment & Qt::AlignTop )
+ y=0;
+ else if ( m_iBackgroundOverlayAlignment & Qt::AlignBottom )
+ y=viewport()->height() - m_pBackgroundOverlayPixmap->height();
+ else if ( m_iBackgroundOverlayAlignment & Qt::AlignVCenter )
+ y=(viewport()->height() - m_pBackgroundOverlayPixmap->height())/2;
+ else
+ y=0;
+ }
+
+ pa.drawPixmap(rect.x(),rect.y(),*m_pBackgroundOverlayPixmap,realTopLeft.x()-x,realTopLeft.y()-y,rect.width(),rect.height());
+
+ p->drawPixmap(rect.x(),rect.y(),*pMemPixmap,rect.x(),rect.y(),rect.width(),rect.height());
+ */
+}
+
+void KviListView::resizeEvent(QResizeEvent * e)
+{
+ KviTalListView::resizeEvent(e);
+ if(m_pBackgroundOverlayPixmap)
+ repaintContents(); // force a full repaint (otherwise qt does not honor static background here)
+}
+
+#ifdef COMPILE_ON_WINDOWS
+
+void KviListView::focusInEvent(QFocusEvent * e)
+{
+ KviTalListView::focusInEvent(e);
+ if(m_pBackgroundOverlayPixmap)
+ repaintContents();
+}
+
+void KviListView::focusOutEvent(QFocusEvent * e)
+{
+ KviTalListView::focusOutEvent(e);
+ if(m_pBackgroundOverlayPixmap)
+ repaintContents();
+}
+
+#endif
diff --git a/src/kvirc/ui/kvi_listview.h b/src/kvirc/ui/kvi_listview.h
new file mode 100644
index 0000000..8d39529
--- /dev/null
+++ b/src/kvirc/ui/kvi_listview.h
@@ -0,0 +1,58 @@
+#ifndef _KVI_LISTVIEW_H_
+#define _KVI_LISTVIEW_H_
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// File : kvi_listview.h
+// Creation date : 19 Jan 2006 GMT by Alexey Uzhva
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2006 Alexey Uzhva
+// Copyright (C) 2006 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "kvi_heapobject.h"
+
+#include "kvi_tal_listview.h"
+
+class QPainter;
+
+class KVIRC_API KviListView : public KviTalListView
+{
+ Q_OBJECT
+public:
+ KviListView( QWidget * parent = 0, const char * name = 0);
+ ~KviListView();
+protected:
+ QPixmap * m_pBackgroundOverlayPixmap;
+ int m_iBackgroundOverlayAlignment;
+public:
+ virtual void setBackgroundOverlayPixmap(QPixmap* pix,int iAlignmentFlags = Qt::AlignAuto);
+public:
+ void publicUpdateContents(){ updateContents(); }; // <-- unscrewContents(); :D
+protected:
+ virtual void paintEmptyArea(QPainter * p, const QRect & rect );
+ virtual void drawContentsOffset(QPainter * p,int ox,int oy,int cx,int cy,int cw,int ch);
+ virtual void resizeEvent(QResizeEvent * e);
+#ifdef COMPILE_ON_WINDOWS
+ virtual void focusInEvent(QFocusEvent * e);
+ virtual void focusOutEvent(QFocusEvent * e);
+#endif
+};
+
+#endif //!_KVI_LISTVIEW_H_
diff --git a/src/kvirc/ui/kvi_maskeditor.cpp b/src/kvirc/ui/kvi_maskeditor.cpp
new file mode 100644
index 0000000..744df1c
--- /dev/null
+++ b/src/kvirc/ui/kvi_maskeditor.cpp
@@ -0,0 +1,350 @@
+//=============================================================================
+//
+// File : kvi_maskeditor.cpp
+// Creation date : Tue Aug 30 2000 12:24:59 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#include "kvi_maskeditor.h"
+#include "kvi_locale.h"
+#include "kvi_iconmanager.h"
+#include "kvi_qstring.h"
+#include "kvi_channel.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_toolwindows_container.h"
+#include "kvi_channel.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qvalidator.h>
+
+KviMaskItem::KviMaskItem(KviTalListView* parent,KviMaskEntry* entry)
+:KviTalListViewItem(parent), m_Mask(*entry)
+{
+ QDateTime date;
+ date.setTime_t(mask()->uSetAt);
+ setText(0,mask()->szMask);
+ setText(1,mask()->szSetBy);
+ setText(2,date.toString());
+}
+
+KviMaskItem::~KviMaskItem()
+{
+}
+#ifdef COMPILE_USE_QT4
+int KviMaskItem::compare ( KviTalListViewItem * i, int col, bool ascending ) const
+#else
+int KviMaskItem::compare ( QListViewItem * i, int col, bool ascending ) const
+#endif
+{
+ if(col==2)
+ {
+ if( ((KviMaskItem*)i)->mask()->uSetAt > m_Mask.uSetAt ) return -1;
+ if( ((KviMaskItem*)i)->mask()->uSetAt == m_Mask.uSetAt ) return 0;
+ if( ((KviMaskItem*)i)->mask()->uSetAt < m_Mask.uSetAt ) return 1;
+ }
+ return KviTalListViewItem::compare(i,col,ascending);
+}
+
+KviMaskInputDialog::KviMaskInputDialog(const QString &szMask,KviMaskEditor* pEditor,KviChannel * pChannel)
+:QDialog(pEditor)
+{
+ m_pChannel=pChannel;
+ m_pEditor=pEditor;
+ setModal(1);
+ m_szOldMask=szMask;
+
+ setCaption(__tr2qs("Mask editor - KVirc"));
+
+ QGridLayout * g = new QGridLayout(this,2,3,5,5);
+
+ QLabel * tl = new QLabel(__tr2qs("New mask must match an *!*@* expression"),this);
+ g->addMultiCellWidget(tl,0,0,0,3);
+
+ m_pEdit=new QLineEdit(szMask,this);
+ g->addMultiCellWidget(m_pEdit,1,1,0,3);
+
+ m_pOkButton= new QPushButton(__tr2qs("Ok"),this);
+ connect(m_pOkButton,SIGNAL(clicked()), this, SLOT(accept()));
+ g->addWidget(m_pOkButton,2,1);
+ m_pOkButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+
+ m_pChancelButton= new QPushButton(__tr2qs("Cancel"),this);
+ connect(m_pChancelButton,SIGNAL(clicked()), this, SLOT(reject()));
+ g->addWidget(m_pChancelButton,2,2);
+ m_pChancelButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+
+ QRegExp rx( "*!*@*", false,true );
+ QValidator* validator = new QRegExpValidator( rx, this );
+
+ m_pEdit->setValidator( validator );
+}
+
+KviMaskInputDialog::~KviMaskInputDialog()
+{
+}
+
+void KviMaskInputDialog::accept()
+{
+ if(m_szOldMask.isEmpty())
+ {
+ m_pChannel->connection()->sendFmtData("MODE %s +%c %s",
+ m_pChannel->connection()->encodeText(m_pChannel->name()).data(),
+ m_pEditor->flag(),
+ m_pChannel->connection()->encodeText(m_pEdit->text()).data()
+ );
+ } else {
+ m_pChannel->connection()->sendFmtData("MODE %s -%c+%c %s %s",
+ m_pChannel->connection()->encodeText(m_pChannel->name()).data(),
+ m_pEditor->flag(),
+ m_pEditor->flag(),
+ m_pChannel->connection()->encodeText(m_szOldMask).data(),
+ m_pChannel->connection()->encodeText(m_pEdit->text()).data()
+ );
+ }
+ QDialog::accept();
+}
+
+KviMaskEditor::KviMaskEditor(QWidget * par,KviWindowToolPageButton* button,KviPointerList<KviMaskEntry> * maskList,char flag,const char * nam)
+: KviWindowToolWidget(par,button)
+{
+ bool isEnabled=1;
+
+ QObject * w = parent();
+ while(w)
+ {
+ if(w->inherits("KviChannel"))
+ {
+ KviChannel *chan = ((KviChannel *)w);
+ if(!( chan->isMeHalfOp() || chan->isMeOp() || chan->isMeChanOwner() || chan->isMeChanAdmin() || chan->connection()->userInfo()->hasUserMode('o') || chan->connection()->userInfo()->hasUserMode('O') ) ) isEnabled=0;
+ break;
+ }
+ w = w->parent();
+ }
+
+#ifdef COMPILE_USE_QT4
+ setFocusPolicy(Qt::ClickFocus);
+#else
+ setFocusPolicy(QWidget::ClickFocus);
+#endif
+
+ QGridLayout *g = new QGridLayout(this,4,2,2,2);
+
+ m_cFlag = flag;
+
+ QString txt;
+ switch(flag)
+ {
+ case 'b':
+ txt = __tr2qs("Active Bans");
+ m_iIconId = KVI_SMALLICON_BAN;
+ break;
+ case 'I':
+ txt = __tr2qs("Active Invite Exceptions");
+ m_iIconId = KVI_SMALLICON_INVITEEXCEPT;
+ break;
+ case 'e':
+ txt = __tr2qs("Active Ban Exceptions");
+ m_iIconId = KVI_SMALLICON_BANEXCEPT;
+ break;
+ default:
+ txt = "?";
+ m_iIconId = KVI_SMALLICON_UNHANDLED;
+ break;
+ }
+
+ QLabel * l = new QLabel("",this);
+ l->setPixmap(*(g_pIconManager->getSmallIcon(m_iIconId)));
+ g->addWidget(l,0,0);
+
+ l = new QLabel(txt,this);
+ g->addWidget(l,0,1);
+
+ KviTalHBox * hb = new KviTalHBox(this);
+ g->addMultiCellWidget(hb,1,1,0,1);
+
+ new QLabel(__tr2qs("Filter:"),hb);
+ m_pSearch = new QLineEdit(hb);
+ connect(m_pSearch,SIGNAL(textChanged ( const QString & ) ),this,SLOT(searchTextChanged ( const QString & )));
+
+ l = new QLabel(__tr2qs("Use doubleclick to edit item"),this);
+ g->addWidget(l,1,1);
+ g->addMultiCellWidget(l,2,2,0,1);
+
+ m_pMaskBox = new KviTalListView(this);
+#ifdef COMPILE_USE_QT4
+ m_pMaskBox->setFocusPolicy(Qt::ClickFocus);
+#else
+ m_pMaskBox->setFocusPolicy(QWidget::ClickFocus);
+#endif
+ m_pMaskBox->setFocusProxy(this);
+ m_pMaskBox->setFrameStyle(QFrame::StyledPanel|QFrame::Sunken);
+ m_pMaskBox->addColumn(__tr2qs("Mask"));
+ m_pMaskBox->addColumn(__tr2qs("Set by"));
+ m_pMaskBox->addColumn(__tr2qs("Set at"));
+ m_pMaskBox->setMultiSelection(true);
+ m_pMaskBox->setAllColumnsShowFocus(true);
+ m_pMaskBox->setShowSortIndicator(true);
+ m_pMaskBox->setSorting(2,false);
+ connect(m_pMaskBox,SIGNAL(doubleClicked ( KviTalListViewItem * )),this,SLOT(listViewDoubleClicked( KviTalListViewItem * )));
+ g->addMultiCellWidget(m_pMaskBox,3,3,0,1);
+
+ m_pRemoveMask = new QPushButton(__tr2qs("Re&move"),this);
+ m_pRemoveMask->setEnabled(isEnabled);
+#ifdef COMPILE_USE_QT4
+ m_pRemoveMask->setFocusPolicy(Qt::ClickFocus);
+#else
+ m_pRemoveMask->setFocusPolicy(QWidget::ClickFocus);
+#endif
+ m_pRemoveMask->setFocusProxy(this);
+ g->addWidget(m_pRemoveMask,4,1);
+ connect(m_pRemoveMask,SIGNAL(clicked()),this,SLOT(removeClicked()));
+ m_pRemoveMask->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DELETEITEM)));
+
+ m_pAddButton = new QPushButton(__tr2qs("Add"),this);
+ m_pAddButton->setEnabled(isEnabled);
+#ifdef COMPILE_USE_QT4
+ m_pAddButton->setFocusPolicy(Qt::ClickFocus);
+#else
+ m_pAddButton->setFocusPolicy(QWidget::ClickFocus);
+#endif
+ m_pAddButton->setFocusProxy(this);
+ g->addWidget(m_pAddButton,4,0);
+ connect(m_pAddButton,SIGNAL(clicked()),this,SLOT(addClicked()));
+ m_pAddButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NEWITEM)));
+
+ g->setColStretch(3,1);
+
+ for(KviMaskEntry * e = maskList->first();e;e = maskList->next()) addMask(e);
+ registerSelf();
+}
+
+KviMaskEditor::~KviMaskEditor()
+{
+
+}
+
+void KviMaskEditor::searchTextChanged ( const QString & text)
+{
+ KviTalListViewItem *pItem=m_pMaskBox->firstChild();
+ KviMaskItem *pMaskItem;
+ bool bEmpty = text.isEmpty();
+ while(pItem)
+ {
+ pMaskItem = (KviMaskItem *)pItem;
+ if(bEmpty)
+ {
+ pMaskItem->setVisible(true);
+ } else {
+ if(pMaskItem->mask()->szMask.contains(text))
+ pMaskItem->setVisible(true);
+ else
+ pMaskItem->setVisible(false);
+ }
+ pItem=pItem->nextSibling();
+ }
+}
+
+void KviMaskEditor::removeClicked()
+{
+ KviPointerList<KviMaskEntry> * l = new KviPointerList<KviMaskEntry>;
+ l->setAutoDelete(true);
+ KviMaskItem * it = (KviMaskItem *)(m_pMaskBox->firstChild());
+ while(it)
+ {
+ if(it->isSelected())
+ {
+ KviMaskEntry * e = new KviMaskEntry;
+ e->szMask = it->mask()->szMask;
+ e->szSetBy = it->mask()->szSetBy;
+ e->uSetAt = it->mask()->uSetAt;
+ l->append(e);
+ }
+ it = (KviMaskItem *)(it->nextSibling());
+ }
+ if(l->count() > 0)emit removeMasks(this,l);
+ delete l;
+}
+
+void KviMaskEditor::addClicked()
+{
+ QObject * w = parent();
+ while(w)
+ {
+ if(w->inherits("KviChannel"))
+ {
+ KviChannel *chan = ((KviChannel *)w);
+ if(chan->isMeHalfOp() || chan->isMeOp() || chan->isMeChanAdmin() || chan->isMeChanOwner() || chan->connection()->userInfo()->hasUserMode('o') || chan->connection()->userInfo()->hasUserMode('O'))
+ {
+ KviMaskInputDialog* pDialog=new KviMaskInputDialog("",this,chan);
+ pDialog->show();
+ }
+ break;
+ }
+ w = w->parent();
+ }
+}
+
+void KviMaskEditor::addMask(KviMaskEntry *e)
+{
+// debug("%s %s %i",__FILE__,__FUNCTION__,__LINE__);
+ KviMaskItem *it;
+ it = new KviMaskItem(m_pMaskBox,e);
+ it->setPixmap(0,*(g_pIconManager->getSmallIcon(m_iIconId)));
+}
+
+void KviMaskEditor::removeMask(KviMaskEntry *e)
+{
+ KviMaskItem * it =(KviMaskItem *)(m_pMaskBox->firstChild());
+ while(it)
+ {
+ if(KviQString::equalCI(it->mask()->szMask,e->szMask))
+ {
+ delete it;
+ return;
+ }
+ it = (KviMaskItem *)(it->nextSibling());
+ }
+}
+
+void KviMaskEditor::listViewDoubleClicked( KviTalListViewItem * pItem)
+{
+ if(pItem)
+ {
+ QObject * w = parent();
+ while(w)
+ {
+ if(w->inherits("KviChannel"))
+ {
+ KviChannel *chan = ((KviChannel *)w);
+ if(chan->isMeHalfOp() || chan->isMeOp() || chan->isMeChanAdmin() || chan->isMeChanOwner() || chan->connection()->userInfo()->hasUserMode('o') || chan->connection()->userInfo()->hasUserMode('O'))
+ {
+ KviMaskInputDialog* pDialog=new KviMaskInputDialog(pItem->text(0),this,chan);
+ pDialog->show();
+ }
+ break;
+ }
+ w = w->parent();
+ }
+ }
+}
+
+#include "kvi_maskeditor.moc"
diff --git a/src/kvirc/ui/kvi_maskeditor.h b/src/kvirc/ui/kvi_maskeditor.h
new file mode 100644
index 0000000..de28137
--- /dev/null
+++ b/src/kvirc/ui/kvi_maskeditor.h
@@ -0,0 +1,108 @@
+#ifndef _KVI_MASKEDITOR_H_
+#define _KVI_MASKEDITOR_H_
+
+//
+// File : kvi_maskeditor.h
+// Creation date : Tue Aug 30 2000 12:20:10 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+#include <qdialog.h>
+#include <qlineedit.h>
+#include <qwidget.h>
+#include "kvi_tal_listview.h"
+#include <qpushbutton.h>
+#include "kvi_pointerlist.h"
+
+#include "kvi_string.h"
+#include "kvi_toolwindows_container.h"
+
+class KviMaskEditor;
+class KviChannel;
+
+typedef struct _KviMaskEntry
+{
+ QString szMask;
+ QString szSetBy;
+ unsigned int uSetAt;
+} KviMaskEntry;
+
+class KviMaskItem: public KviTalListViewItem
+{
+public:
+ KviMaskItem(KviTalListView* parent,KviMaskEntry* entry);
+ ~KviMaskItem();
+
+ KviMaskEntry* mask() { return &m_Mask; };
+#ifdef COMPILE_USE_QT4
+ virtual int compare ( KviTalListViewItem * i, int col, bool ascending ) const;
+#else
+ virtual int compare ( QListViewItem * i, int col, bool ascending ) const;
+#endif
+protected:
+ KviMaskEntry m_Mask;
+
+};
+
+class KviMaskInputDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviMaskInputDialog(const QString &szMask,KviMaskEditor* pEditor,KviChannel * pChannel);
+ ~KviMaskInputDialog();
+protected:
+ QLineEdit * m_pEdit;
+ QPushButton * m_pOkButton;
+ QPushButton * m_pChancelButton;
+ QString m_szOldMask;
+ KviChannel * m_pChannel;
+ KviMaskEditor * m_pEditor;
+protected slots:
+ virtual void accept();
+};
+
+class KVIRC_API KviMaskEditor : public KviWindowToolWidget
+{
+ Q_OBJECT
+public:
+ KviMaskEditor(QWidget * par,KviWindowToolPageButton* button,KviPointerList<KviMaskEntry> * maskList,
+ char flag,const char * nam);
+ ~KviMaskEditor();
+protected:
+ KviTalListView * m_pMaskBox;
+ QPushButton * m_pRemoveMask;
+ QPushButton * m_pAddButton;
+ QLineEdit * m_pSearch;
+ char m_cFlag;
+ int m_iIconId;
+public:
+ char flag(){ return m_cFlag; };
+ void addMask(KviMaskEntry *e);
+ void removeMask(KviMaskEntry *e);
+protected slots:
+ void removeClicked();
+ void addClicked();
+ void listViewDoubleClicked( KviTalListViewItem * );
+ void searchTextChanged ( const QString & );
+signals:
+ void removeMasks(KviMaskEditor *,KviPointerList<KviMaskEntry> *);
+};
+
+#endif //_KVI_MASKEDITOR_H_
diff --git a/src/kvirc/ui/kvi_mdicaption.cpp b/src/kvirc/ui/kvi_mdicaption.cpp
new file mode 100644
index 0000000..ba4aea4
--- /dev/null
+++ b/src/kvirc/ui/kvi_mdicaption.cpp
@@ -0,0 +1,285 @@
+//=================================================================================================
+//
+// File : kvi_mdicaption.cpp
+// Creation date : Tue Sep 2 2003 02:35:45 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2003 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=================================================================================================
+
+#define __KVIRC__
+
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+#include "kvi_mdichild.h"
+#include "kvi_mdimanager.h"
+#include "kvi_string.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_settings.h"
+#include "kvi_iconmanager.h"
+#include "kvi_window.h"
+#include "kvi_mdicaption.h"
+
+#include <qcursor.h>
+#include <qnamespace.h>
+#include <qapplication.h>
+#include <qfontmetrics.h>
+#include "kvi_pointerlist.h"
+#include <qpixmap.h>
+#include <qstyle.h>
+#include <qpainter.h>
+#include "kvi_tal_popupmenu.h"
+#ifdef COMPILE_USE_QT4
+ #include <q3simplerichtext.h>
+ #define QSimpleRichText Q3SimpleRichText
+ #include <qstyleoption.h>
+#else
+ #include <qsimplerichtext.h>
+#endif
+#include <qdrawutil.h>
+#include <qevent.h>
+
+KviMdiCaptionButton::KviMdiCaptionButton(const QPixmap &pix,QWidget * parent,const char * name)
+: QToolButton(parent,name)
+{
+ setPixmap(pix);
+ //setAutoRaise(true);
+ setMinimumSize(18,18);
+}
+
+KviMdiCaptionButton::~KviMdiCaptionButton()
+{
+}
+
+
+#ifdef COMPILE_USE_QT4
+void KviMdiCaptionButton::paintEvent(QPaintEvent *e)
+{
+ QPainter painter(this);
+ drawButton(&painter);
+}
+#endif
+
+void KviMdiCaptionButton::drawButton(QPainter *p)
+{
+#ifdef COMPILE_USE_QT4
+ QBrush b(parentWidget()->palette().window());
+#else
+ QBrush b(parentWidget()->colorGroup().background());
+#endif
+
+ if(isDown())
+ qDrawShadePanel(p,0,0,width(),height(),colorGroup(),true,1,&b);
+ else
+ p->fillRect(0,0,width(),height(),b);
+
+#ifdef COMPILE_USE_QT4
+ int x = (width() - 16) / 2;
+ int y = (width() - 16) / 2;
+ p->drawPixmap(x,y,16,16,icon().pixmap(16,16),0,0,16,16);
+#else
+ drawButtonLabel(p);
+#endif
+}
+
+
+
+
+
+
+
+KviMdiCaption::KviMdiCaption(KviMdiChild * parent,const char * name)
+: QWidget(parent,name)
+{
+ m_pMaximizeButton = new KviMdiCaptionButton(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MAXIMIZE)),this,"maximize_button");
+ connect(m_pMaximizeButton,SIGNAL(clicked()),parent,SLOT(maximize()));
+ m_pMinimizeButton = new KviMdiCaptionButton(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINIMIZE)),this,"minimize_button");
+ connect(m_pMinimizeButton,SIGNAL(clicked()),parent,SLOT(minimize()));
+ m_pCloseButton = new KviMdiCaptionButton(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)),this,"close_button");
+ connect(m_pCloseButton,SIGNAL(clicked()),parent,SLOT(closeRequest()));
+ m_pSystemButton = new KviMdiCaptionButton(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DEFAULTICON)),this,"icon_button");
+ connect(m_pSystemButton,SIGNAL(clicked()),parent,SLOT(systemPopupSlot()));
+
+ m_lastMousePos = QPoint(-1,-1);
+ m_bMouseGrabbed = true;
+ m_bActive = false;
+ calcLineSpacing();
+#ifdef COMPILE_USE_QT4
+ setAutoFillBackground(false);
+#endif
+}
+
+KviMdiCaption::~KviMdiCaption()
+{
+}
+
+void KviMdiCaption::reloadImages()
+{
+ m_pMaximizeButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MAXIMIZE)));
+ m_pMinimizeButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINIMIZE)));
+ m_pCloseButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)));
+}
+
+void KviMdiCaption::calcLineSpacing()
+{
+ QFontMetrics fm(font());
+ m_iLineSpacing = fm.lineSpacing() + 3;
+ if(m_iLineSpacing < 20)m_iLineSpacing = 20;
+}
+
+int KviMdiCaption::heightHint()
+{
+ return m_iLineSpacing;
+}
+
+void KviMdiCaption::setActive(bool bActive)
+{
+ m_bActive = bActive;
+
+ QPalette pal(Qt::white,m_bActive ? KVI_OPTION_COLOR(KviOption_colorMdiCaptionActive) : KVI_OPTION_COLOR(KviOption_colorMdiCaptionInactive));
+ setPalette(pal);
+ //update();
+ m_pSystemButton->update();
+ m_pCloseButton->update();
+ m_pMinimizeButton->update();
+ m_pMaximizeButton->update();
+}
+
+void KviMdiCaption::fontChange(const QFont &old)
+{
+ calcLineSpacing();
+ QWidget::fontChange(old);
+ ((KviMdiChild *)parent())->resizeEvent(0);
+}
+
+void KviMdiCaption::mousePressEvent(QMouseEvent *e)
+{
+ m_bMouseGrabbed = true;
+ m_lastMousePos = QCursor::pos();
+#ifdef COMPILE_USE_QT4
+ setCursor(Qt::SizeAllCursor);
+#else
+ setCursor(QCursor::sizeAllCursor);
+#endif
+ ((KviMdiChild *)parent())->activate(true);
+}
+
+void KviMdiCaption::mouseMoveEvent(QMouseEvent *)
+{
+ if(m_bMouseGrabbed)
+ {
+ QPoint p = QCursor::pos();
+ int dx = m_lastMousePos.x() - p.x();
+ int dy = m_lastMousePos.y() - p.y();
+ KviMdiChild * c = (KviMdiChild *)parent();
+
+ int nx = c->manager()->childX(c) - dx;
+ int ny = c->manager()->childY(c) - dy;
+
+ if((nx < 0) || (ny < 0))
+ {
+ int cx = p.x();
+ int cy = p.y();
+ if(nx < 0)
+ {
+ cx -= nx;
+ nx = 0;
+ }
+ if(ny < 0)
+ {
+ cy -= ny;
+ ny = 0;
+ }
+
+ QCursor::setPos(cx,cy);
+ m_lastMousePos = QPoint(cx,cy);
+ } else {
+ m_lastMousePos = p;
+ }
+
+ c->manager()->moveChild(c,nx,ny);
+ c->manager()->childMoved(c);
+ }
+}
+
+void KviMdiCaption::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ ((KviMdiChild *)parent())->maximize();
+}
+
+void KviMdiCaption::paintEvent(QPaintEvent * e)
+{
+ QRect r = e->rect();
+ QPainter p(this);
+ p.fillRect(r,m_bActive ? KVI_OPTION_COLOR(KviOption_colorMdiCaptionActive) : KVI_OPTION_COLOR(KviOption_colorMdiCaptionInactive));
+ QSimpleRichText rt(m_bActive ? ((KviMdiChild *)parent())->xmlActiveCaption() : ((KviMdiChild *)parent())->xmlInactiveCaption(),font());
+ rt.draw(&p,height() + 2,-1,rect(),colorGroup());
+}
+
+void KviMdiCaption::mouseReleaseEvent(QMouseEvent *)
+{
+ m_bMouseGrabbed = false;
+#ifdef COMPILE_USE_QT4
+ setCursor(Qt::arrowCursor);
+#else
+ setCursor(QCursor::arrowCursor);
+#endif
+// releaseMouse();
+}
+
+void KviMdiCaption::setFocusProxy(QWidget * w)
+{
+ QWidget::setFocusProxy(w);
+ m_pSystemButton->setFocusProxy(w);
+ m_pMinimizeButton->setFocusProxy(w);
+ m_pMaximizeButton->setFocusProxy(w);
+ m_pCloseButton->setFocusProxy(w);
+}
+
+void KviMdiCaption::resizeEvent(QResizeEvent * e)
+{
+ int s = height() - 2;
+ m_pSystemButton->setGeometry(1,1,s,s);
+ m_pCloseButton->setGeometry(width() - (s + 1),
+ 1,s,s);
+ m_pMaximizeButton->setGeometry(width() - ((s << 1) + 2),
+ 1,s,s);
+ m_pMinimizeButton->setGeometry(width() - ((s * 3) + 3),
+ 1,s,s);
+}
+
+
+
+KviMenuBarToolButton::KviMenuBarToolButton(QWidget * par,const QPixmap &img, const char * name)
+: KviStyledToolButton(par)
+{
+ setProperty("name","name");
+ setIconSet(img);
+ setAutoRaise(true);
+}
+
+KviMenuBarToolButton::~KviMenuBarToolButton()
+{
+}
+
+QSize KviMenuBarToolButton::sizeHint() const
+{
+ return QSize(20,20);
+}
+
diff --git a/src/kvirc/ui/kvi_mdicaption.h b/src/kvirc/ui/kvi_mdicaption.h
new file mode 100644
index 0000000..6bec405
--- /dev/null
+++ b/src/kvirc/ui/kvi_mdicaption.h
@@ -0,0 +1,101 @@
+#ifndef _KVI_MDICAPTION_H_
+#define _KVI_MDICAPTION_H_
+//=================================================================================================
+//
+// File : kvi_mdicaption.h
+// Creation date : Tue Sep 2 2003 02:35:45 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2003 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=================================================================================================
+
+#include "kvi_settings.h"
+
+#include <qtoolbutton.h>
+#include <qlabel.h>
+#include "kvi_styled_controls.h"
+
+class KviMdiManager;
+class KviMdiChild;
+
+
+class KVIRC_API KviMdiCaptionButton : public QToolButton
+{
+ Q_OBJECT
+public:
+ KviMdiCaptionButton(const QPixmap &pix,QWidget * parent,const char * name);
+ ~KviMdiCaptionButton();
+protected:
+ virtual void drawButton(QPainter * p);
+#ifdef COMPILE_USE_QT4
+ virtual void paintEvent(QPaintEvent *e);
+#endif
+};
+
+
+class KviMenuBarToolButton : public KviStyledToolButton
+{
+ Q_OBJECT
+public:
+ KviMenuBarToolButton(QWidget * par,const QPixmap &img, const char * name);
+ ~KviMenuBarToolButton();
+public:
+ virtual QSize sizeHint() const;
+};
+
+
+class KVIRC_API KviMdiCaption : public QWidget
+{
+ friend class KviMdiChild;
+ Q_OBJECT
+public:
+ KviMdiCaption(KviMdiChild * parent,const char * name);
+ ~KviMdiCaption();
+protected:
+ QPoint m_lastMousePos;
+ bool m_bMouseGrabbed;
+ int m_iLineSpacing;
+ bool m_bActive;
+ KviMdiCaptionButton * m_pSystemButton;
+ KviMdiCaptionButton * m_pMinimizeButton;
+ KviMdiCaptionButton * m_pMaximizeButton;
+ KviMdiCaptionButton * m_pCloseButton;
+ QPixmap m_pixSystemIcon;
+public:
+ int heightHint();
+ void setActive(bool bActive);
+ bool active(){ return m_bActive; };
+ void setSystemIcon(const QPixmap &pix){ m_pSystemButton->setPixmap(pix); m_pixSystemIcon = pix; };
+ const QPixmap * systemIcon(){ return &m_pixSystemIcon; };
+ void enableClose(bool bEnable){ m_pCloseButton->setEnabled(bEnable); };
+ bool closeEnabled(){ return m_pCloseButton->isEnabled(); };
+ virtual void setFocusProxy(QWidget * w);
+protected:
+ void calcLineSpacing();
+ virtual void fontChange(const QFont &old);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+ virtual void paintEvent(QPaintEvent * e);
+ virtual void resizeEvent(QResizeEvent * e);
+ void reloadImages();
+};
+
+
+#endif //_KVI_MDICAPTION_H_
diff --git a/src/kvirc/ui/kvi_mdichild.cpp b/src/kvirc/ui/kvi_mdichild.cpp
new file mode 100644
index 0000000..9b92c56
--- /dev/null
+++ b/src/kvirc/ui/kvi_mdichild.cpp
@@ -0,0 +1,576 @@
+//=============================================================================
+//
+// File : kvi_mdichild.cpp
+// Creation date : Wed Jun 21 2000 17:35:45 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2007 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+#define __KVIRC__
+
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+#include "kvi_mdichild.h"
+#include "kvi_mdimanager.h"
+#include "kvi_string.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_settings.h"
+#include "kvi_iconmanager.h"
+#include "kvi_window.h"
+#include "kvi_mdicaption.h"
+
+#include <qcursor.h>
+#include <qnamespace.h>
+#include <qapplication.h>
+#include <qfontmetrics.h>
+#include "kvi_pointerlist.h"
+#include <qpixmap.h>
+#include <qstyle.h>
+#include <qpainter.h>
+#include "kvi_tal_popupmenu.h"
+#ifndef COMPILE_USE_QT4
+ #include <qobjectlist.h>
+#endif
+#include <qevent.h>
+
+#ifdef Q_OS_MACX
+#include "kvi_app.h" //Needed for g_pApp
+#ifdef COMPILE_USE_QT4
+ #include <QDesktopWidget>
+#endif
+#endif
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+#endif
+
+
+#define KVI_MDI_NORESIZE 0
+#define KVI_MDI_RESIZE_TOP 1
+#define KVI_MDI_RESIZE_LEFT 2
+#define KVI_MDI_RESIZE_RIGHT 4
+#define KVI_MDI_RESIZE_BOTTOM 8
+#define KVI_MDI_RESIZE_TOPLEFT (1|2)
+#define KVI_MDI_RESIZE_TOPRIGHT (1|4)
+#define KVI_MDI_RESIZE_BOTTOMLEFT (8|2)
+#define KVI_MDI_RESIZE_BOTTOMRIGHT (8|4)
+
+
+KviMdiChild::KviMdiChild(KviMdiManager * par,const char * name)
+: QFrame(par->viewport(),name ? name : "mdi_child")
+{
+ setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+ setFrameShape(NoFrame);
+ m_pManager = par;
+
+ m_pCaption = new KviMdiCaption(this,"mdi_caption");
+
+ m_bResizeMode = false;
+ m_iResizeCorner = KVI_MDI_NORESIZE;
+ m_iLastCursorCorner = KVI_MDI_NORESIZE;
+
+ m_pClient = 0;
+ m_state = Normal;
+ m_restoredGeometry = QRect(10,10,100,100);
+
+ setMouseTracking(true);
+ setMinimumSize(KVI_MDICHILD_MIN_WIDTH,KVI_MDICHILD_MIN_HEIGHT);
+
+#ifdef COMPILE_USE_QT4
+ setAutoFillBackground(true);
+#endif
+
+}
+
+KviMdiChild::~KviMdiChild()
+{
+ if(m_pClient)delete m_pClient;
+}
+
+void KviMdiChild::reloadImages()
+{
+ m_pCaption->reloadImages();
+}
+
+QRect KviMdiChild::restoredGeometry()
+{
+ if(m_state == Maximized)return m_restoredGeometry;
+ else return QRect(x(),y(),width(),height());
+// else return geometry();
+
+}
+
+#ifdef COMPILE_USE_QT4
+void KviMdiChild::setBackgroundRole(QPalette::ColorRole)
+{
+ // hack
+ QFrame::setBackgroundRole(QPalette::Window);
+}
+#else
+void KviMdiChild::setBackgroundMode(QWidget::BackgroundMode)
+{
+ // hack
+ QFrame::setBackgroundMode(QWidget::PaletteBackground);
+}
+#endif
+
+void KviMdiChild::setIcon(const QPixmap &pix)
+{
+ m_pCaption->setSystemIcon(pix);
+
+ if((m_state == Maximized) && (m_pManager->topChild() == this))
+ {
+ m_pManager->updateSDIMode();
+ }
+}
+
+const QPixmap * KviMdiChild::icon()
+{
+ return m_pCaption->systemIcon();
+}
+
+void KviMdiChild::enableClose(bool bEnable)
+{
+ m_pCaption->enableClose(bEnable);
+ if((m_state == Maximized) && (m_pManager->topChild() == this))
+ {
+ m_pManager->updateSDIMode();
+ }
+
+}
+
+bool KviMdiChild::closeEnabled()
+{
+ return m_pCaption->closeEnabled();
+}
+
+void KviMdiChild::setCaption(const QString & plain,const QString & xmlActive,const QString & xmlInactive)
+{
+ m_szPlainCaption = plain;
+ m_szXmlActiveCaption = xmlActive;
+ m_szXmlInactiveCaption = xmlInactive;
+ //m_pCaptionLabel->setActive(m_pCaptionLabel->active());
+ m_pCaption->update();
+}
+
+void KviMdiChild::maximize()
+{
+ if(m_state == Minimized)restore(); // restore first
+ if(m_state == Normal)m_restoredGeometry = geometry();
+ m_state = Maximized;
+ manager()->maximizeChild(this);
+}
+
+void KviMdiChild::restore()
+{
+ if(m_restoredGeometry.x() < 0)m_restoredGeometry.setX(0);
+ if(m_restoredGeometry.y() < 0)m_restoredGeometry.setY(0);
+ // ensure coherency
+ if(m_restoredGeometry.width() < 5)m_restoredGeometry.setWidth(5);
+ if(m_restoredGeometry.height() < 5)m_restoredGeometry.setHeight(5);
+
+ /*
+ if((m_restoredGeometry.x() + m_restoredGeometry.width()) > m_pManager->width())
+ m_restoredGeometry.setWidth(m_pManager->width() - m_restoredGeometry.x());
+ if((m_restoredGeometry.y() + m_restoredGeometry.height()) > m_pManager->height())
+ m_restoredGeometry.setHeight(m_pManager->height() - m_restoredGeometry.y());
+ */
+
+ switch(m_state)
+ {
+ case Maximized:
+ m_pManager->moveChild(this,m_restoredGeometry.x(),m_restoredGeometry.y());
+ resize(m_restoredGeometry.width(),m_restoredGeometry.height());
+ m_state = Normal;
+ m_pManager->childRestored(this,true);
+ break;
+ case Minimized:
+ m_pManager->moveChild(this,m_restoredGeometry.x(),m_restoredGeometry.y());
+ resize(m_restoredGeometry.width(),m_restoredGeometry.height());
+ show();
+ m_state = Normal;
+ m_pManager->childRestored(this,false);
+ break;
+ case Normal:
+ m_state = Normal;
+ if(!isVisible())show();
+ return;
+ break;
+ }
+}
+
+void KviMdiChild::minimize()
+{
+ switch(m_state)
+ {
+ case Maximized:
+ hide();
+ m_state = Minimized;
+ m_pManager->childMinimized(this,true);
+ break;
+ case Normal:
+ m_restoredGeometry = geometry();
+ hide();
+ m_state = Minimized;
+ m_pManager->childMinimized(this,false);
+ break;
+ case Minimized:
+ m_state = Minimized;
+ if(isVisible())hide();
+ return;
+ break;
+ }
+}
+
+void KviMdiChild::closeRequest()
+{
+ if(closeEnabled())if(m_pClient)m_pClient->close();
+}
+/*
+void KviMdiChild::systemPopupAboutToShow()
+{
+ m_pSystemPopup->clear();
+ if(m_state != Maximized)m_pSystemPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MAXIMIZE)),__tr("&Maximize"),this,SLOT(maximize()));
+ if(m_state != Minimized)m_pSystemPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINIMIZE)),__tr("M&inimize"),this,SLOT(minimize()));
+ if(m_state != Normal)m_pSystemPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RESTORE)),__tr("&Restore"),this,SLOT(restore()));
+ if(closeEnabled())
+ {
+ m_pSystemPopup->insertSeparator();
+ m_pSystemPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)),__tr("&Close"),this,SLOT(closeRequest()));
+ }
+}
+*/
+void KviMdiChild::moveEvent(QMoveEvent *e)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(m_pClient && g_pShadedChildGlobalDesktopBackground)
+ {
+ if(m_pClient->inherits("KviWindow")) // actually this is always the case
+ {
+ ((KviWindow *)m_pClient)->updateBackgrounds();
+ }
+ }
+#endif
+ QFrame::moveEvent(e);
+}
+
+void KviMdiChild::systemPopupSlot()
+{
+ if(sender()->inherits("QToolButton"))
+ {
+ emit systemPopupRequest(((QToolButton *)sender())->mapToGlobal(QPoint(0,((QToolButton *)sender())->height())));
+ } else {
+ emit systemPopupRequest(m_pCaption->mapToGlobal(QPoint(5,5)));
+ }
+}
+
+void KviMdiChild::resizeEvent(QResizeEvent *e)
+{
+ int s = m_pCaption->heightHint();
+ m_pCaption->setGeometry(KVI_MDICHILD_BORDER,KVI_MDICHILD_BORDER,
+ width() - (KVI_MDICHILD_BORDER << 1),s);
+
+ if(m_pClient)
+ {
+ int yPos = KVI_MDICHILD_BORDER + s + KVI_MDICHILD_SPACING;
+ m_pClient->setGeometry(KVI_MDICHILD_BORDER,yPos,
+ width() - (KVI_MDICHILD_BORDER << 1),height() - (yPos + KVI_MDICHILD_BORDER));
+ }
+ QFrame::resizeEvent(e);
+}
+
+void KviMdiChild::mousePressEvent(QMouseEvent *e)
+{
+ if(m_state == Maximized)return;
+ m_iResizeCorner=getResizeCorner(e->pos().x(),e->pos().y());
+ if(m_iResizeCorner != KVI_MDI_NORESIZE)
+ {
+ grabMouse(getResizeCursor(m_iResizeCorner));
+ m_bResizeMode = true;
+ }
+}
+
+void KviMdiChild::mouseReleaseEvent(QMouseEvent *)
+{
+ m_iResizeCorner=KVI_MDI_NORESIZE;
+ m_iLastCursorCorner=KVI_MDI_NORESIZE;
+
+ if(m_bResizeMode)
+ {
+ m_bResizeMode = false;
+ releaseMouse();
+ }
+
+ //if(QApplication::overrideCursor())QApplication::restoreOverrideCursor();
+}
+
+QCursor KviMdiChild::getResizeCursor(int resizeCorner)
+{
+ switch (resizeCorner)
+ {
+ case KVI_MDI_RESIZE_LEFT:
+ case KVI_MDI_RESIZE_RIGHT:
+ return Qt::sizeHorCursor;
+ break;
+ case KVI_MDI_RESIZE_TOP:
+ case KVI_MDI_RESIZE_BOTTOM:
+ return Qt::sizeVerCursor;
+ break;
+ case KVI_MDI_RESIZE_TOPLEFT:
+ case KVI_MDI_RESIZE_BOTTOMRIGHT:
+ return Qt::sizeFDiagCursor;
+ break;
+ case KVI_MDI_RESIZE_BOTTOMLEFT:
+ case KVI_MDI_RESIZE_TOPRIGHT:
+ return Qt::sizeBDiagCursor;
+ break;
+ default:
+ return Qt::arrowCursor;
+ break;
+ }
+}
+
+void KviMdiChild::mouseMoveEvent(QMouseEvent *e)
+{
+ if(e->state() & Qt::LeftButton)
+ {
+ if(m_iResizeCorner && (m_state != Maximized))resizeWindowOpaque(m_iResizeCorner);
+ } else {
+ setResizeCursor(getResizeCorner(e->pos().x(), e->pos().y()));
+ }
+}
+
+void KviMdiChild::setResizeCursor(int resizeCorner)
+{
+ if(resizeCorner == m_iLastCursorCorner)
+ return; //Don't do it twice
+ m_iLastCursorCorner = resizeCorner;
+ if(resizeCorner == KVI_MDI_NORESIZE)
+ {
+ setCursor(getResizeCursor(resizeCorner));
+ //if(QApplication::overrideCursor())QApplication::restoreOverrideCursor();
+ } else {
+ if(m_state != Maximized)
+ {
+ setCursor(getResizeCursor(resizeCorner));
+ //QApplication::setOverrideCursor(getResizeCursor(resizeCorner),true);
+ }
+ }
+}
+
+void KviMdiChild::leaveEvent(QEvent *)
+{
+ if(!m_bResizeMode)
+ {
+ m_iResizeCorner=KVI_MDI_NORESIZE;
+ m_iLastCursorCorner=KVI_MDI_NORESIZE;
+ //if(QApplication::overrideCursor())QApplication::restoreOverrideCursor();
+ } else {
+ if(m_iResizeCorner != KVI_MDI_NORESIZE)resizeWindowOpaque(m_iResizeCorner);
+ }
+}
+
+void KviMdiChild::calculateResizeRect(int resizeCorner,QPoint mousePos,QRect &resizeRect,int minWidth,int minHeight)
+{
+ switch(resizeCorner)
+ {
+ case KVI_MDI_RESIZE_LEFT:
+ resizeRect.setLeft(mousePos.x() - 1);
+ if(resizeRect.width() < minWidth)resizeRect.setLeft(resizeRect.right() - minWidth);
+ if(resizeRect.x() < 0)resizeRect.setX(0);
+ break;
+ case KVI_MDI_RESIZE_RIGHT:
+ resizeRect.setRight(mousePos.x() + 1);
+ if(resizeRect.width() < minWidth)resizeRect.setRight(resizeRect.left() + minWidth);
+ break;
+ case KVI_MDI_RESIZE_TOP:
+ resizeRect.setTop(mousePos.y() - 1);
+ if(resizeRect.height() < minHeight)resizeRect.setTop(resizeRect.bottom() - minHeight);
+ if(resizeRect.y() < 0)resizeRect.setY(0);
+ break;
+ case KVI_MDI_RESIZE_BOTTOM:
+ resizeRect.setBottom(mousePos.y() + 1);
+ if(resizeRect.height() < minHeight)resizeRect.setBottom(resizeRect.top() + minHeight);
+ break;
+ case KVI_MDI_RESIZE_BOTTOMRIGHT:
+ resizeRect.setBottom(mousePos.y() + 1);
+ if(resizeRect.height() < minHeight)resizeRect.setBottom(resizeRect.top() + minHeight);
+ resizeRect.setRight(mousePos.x() + 1);
+ if(resizeRect.width() < minWidth)resizeRect.setRight(resizeRect.left() + minWidth);
+ break;
+ case KVI_MDI_RESIZE_TOPRIGHT:
+ resizeRect.setTop(mousePos.y() - 1);
+ if(resizeRect.height() < minHeight)resizeRect.setTop(resizeRect.bottom() - minHeight);
+ if(resizeRect.y() < 0)resizeRect.setY(0);
+ resizeRect.setRight(mousePos.x() + 1);
+ if(resizeRect.width() < minWidth)resizeRect.setRight(resizeRect.left() + minWidth);
+ break;
+ case KVI_MDI_RESIZE_BOTTOMLEFT:
+ resizeRect.setBottom(mousePos.y() + 1);
+ if(resizeRect.height() < minHeight)resizeRect.setBottom(resizeRect.top() + minHeight);
+ resizeRect.setLeft(mousePos.x() - 1);
+ if(resizeRect.width() < minWidth)resizeRect.setLeft(resizeRect.right() - minWidth);
+ if(resizeRect.x() < 0)resizeRect.setX(0);
+ break;
+ case KVI_MDI_RESIZE_TOPLEFT:
+ resizeRect.setTop(mousePos.y() - 1);
+ if(resizeRect.height() < minHeight)resizeRect.setTop(resizeRect.bottom() - minHeight);
+ if(resizeRect.y() < 0)resizeRect.setY(0);
+ resizeRect.setLeft(mousePos.x() - 1);
+ if(resizeRect.width() < minWidth)resizeRect.setLeft(resizeRect.right() - minWidth);
+ if(resizeRect.x() < 0)resizeRect.setX(0);
+ break;
+ }
+}
+
+void KviMdiChild::calculateMinimumSize(int &minWidth,int &minHeight)
+{
+ if(m_pClient){
+ minWidth = m_pClient->minimumSize().width() + (KVI_MDICHILD_BORDER << 1);
+ minHeight = m_pClient->minimumSize().height()+ (KVI_MDICHILD_BORDER << 1)+
+ m_pCaption->heightHint() + KVI_MDICHILD_SPACING;
+ }
+ if(minWidth<KVI_MDICHILD_MIN_WIDTH)minWidth=KVI_MDICHILD_MIN_WIDTH;
+ if(minHeight<KVI_MDICHILD_MIN_HEIGHT)minHeight=KVI_MDICHILD_MIN_HEIGHT;
+}
+
+void KviMdiChild::resizeWindowOpaque(int resizeCorner)
+{
+ int minWidth=0;
+ int minHeight=0;
+ QRect resizeRect(m_pManager->childX(this),m_pManager->childY(this),width(),height());
+ calculateMinimumSize(minWidth,minHeight);
+ QPoint mousePos = m_pManager->viewportToContents(m_pManager->viewport()->mapFromGlobal(QCursor::pos()));
+ calculateResizeRect(resizeCorner,mousePos,resizeRect,minWidth,minHeight);
+ m_pManager->moveChild(this,resizeRect.x(),resizeRect.y());
+ resize(resizeRect.width(),resizeRect.height());
+ m_pManager->childMoved(this);
+
+ if(m_state == Maximized)
+ {
+ m_state=Normal;
+ m_pManager->childRestored(this,true);
+ }
+
+}
+
+int KviMdiChild::getResizeCorner(int ax,int ay)
+{
+ int ret = KVI_MDI_NORESIZE;
+ if((ax>0)&&(ax<(KVI_MDICHILD_BORDER+2))) ret |= KVI_MDI_RESIZE_LEFT;
+ if((ax<width())&&(ax>(width()-(KVI_MDICHILD_BORDER+2)))) ret |= KVI_MDI_RESIZE_RIGHT;
+ if((ay>0)&&(ay<(KVI_MDICHILD_BORDER+2))) ret |= KVI_MDI_RESIZE_TOP;
+ if((ay<(height()))&&(ay>(height()-(KVI_MDICHILD_BORDER+2)))) ret |= KVI_MDI_RESIZE_BOTTOM;
+ return ret;
+}
+
+void KviMdiChild::setClient(QWidget *w)
+{
+ __range_valid(m_pClient==0);
+ __range_valid(w!=0);
+
+ m_pClient = w;
+ //resize to match the client
+ int clientYPos=m_pCaption->heightHint()+KVI_MDICHILD_SPACING+KVI_MDICHILD_BORDER;
+ resize(w->width()+(KVI_MDICHILD_BORDER << 1),w->height()+KVI_MDICHILD_BORDER+clientYPos);
+
+ //Reparent if needed
+ if(w->parent()!=this){
+ //reparent to this widget , no flags , point , show it
+ QPoint pnt2(KVI_MDICHILD_BORDER,clientYPos);
+ w->reparent(this,pnt2,true);
+ } else w->move(KVI_MDICHILD_BORDER,clientYPos);
+
+ setFocusProxy(w);
+ m_pCaption->setFocusProxy(w);
+
+/*
+ m_pMinimizeButton->setFocusProxy(w);
+ m_pMaximizeButton->setFocusProxy(w);
+ m_pCloseButton->setFocusProxy(w);
+ m_pIconButton->setFocusProxy(w);
+*/
+ //linkChildren(w);
+
+ if(m_pClient->minimumSize().width() > KVI_MDICHILD_MIN_WIDTH &&
+ m_pClient->minimumSize().height() > KVI_MDICHILD_MIN_HEIGHT){
+ setMinimumWidth(m_pClient->minimumSize().width() + (KVI_MDICHILD_BORDER << 1));
+ setMinimumHeight(m_pClient->minimumSize().height()+ (KVI_MDICHILD_BORDER << 1) +
+ m_pCaption->heightHint() + KVI_MDICHILD_SPACING);
+ }
+
+ KviStr tmp(KviStr::Format,"mdi_child_%s",w->name());
+ setName(tmp.ptr());
+}
+
+void KviMdiChild::unsetClient()
+{
+ __range_valid(m_pClient!=0);
+ if(!m_pClient)return;
+ //reparent to desktop widget , no flags , point , show it
+ //unlinkChildren(m_pClient);
+ setFocusProxy(0); //remove the focus proxy...
+ //Kewl...the reparent function has a small prob now..
+ //the new toplelvel widgets gets not reenabled for dnd
+#ifndef Q_OS_MACX
+ m_pClient->reparent(0,m_pClient->mapToGlobal(QPoint(0,0)),true);
+#else
+ QRect r = g_pApp->desktop()->availableGeometry(m_pClient);
+ r.moveBy(0, 22);
+ m_pClient->reparent(0,r.topLeft(),true);
+#endif
+ m_pClient=0;
+ setName("mdi_child");
+}
+
+
+
+void KviMdiChild::activate(bool bSetFocus)
+{
+ if(!m_pCaption->active())m_pCaption->setActive(true);
+ if(m_pManager->topChild() != this)
+ m_pManager->setTopChild(this,bSetFocus);
+ else if(bSetFocus)setFocus();
+}
+
+void KviMdiChild::focusInEvent(QFocusEvent *)
+{
+ // We gained focus by click , tab or from the caption label
+ // Bring this child to top
+ m_pCaption->setActive(true);
+ m_pManager->setTopChild(this,false); //Do not focus by now...
+ /*The client is our focusProxy ! it should be focused by Qt !*/
+#ifdef _KVI_DEBUG_CLASS_NAME_
+ __range_valid(focusProxy() == m_pClient);
+#endif
+}
+
+QSize KviMdiChild::sizeHint()
+{
+ if(m_pClient)
+ {
+ QSize s = m_pClient->sizeHint();
+ QSize ret(s.width() + (KVI_MDICHILD_BORDER << 1),
+ s.height() + (KVI_MDICHILD_BORDER << 1) + KVI_MDICHILD_SPACING + m_pCaption->heightHint());
+ return ret;
+ }
+ return QFrame::sizeHint();
+}
+
+
diff --git a/src/kvirc/ui/kvi_mdichild.h b/src/kvirc/ui/kvi_mdichild.h
new file mode 100644
index 0000000..7915a3b
--- /dev/null
+++ b/src/kvirc/ui/kvi_mdichild.h
@@ -0,0 +1,122 @@
+#ifndef _KVI_MDICHILD_H_
+#define _KVI_MDICHILD_H_
+//=================================================================================================
+//
+// File : kvi_mdichild.h
+// Creation date : Wed Jun 21 2000 17:35:04 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=================================================================================================
+
+#include "kvi_settings.h"
+#include "kvi_string.h"
+
+#include <qframe.h>
+#include <qtoolbutton.h>
+#include <qlabel.h>
+
+
+class KviMdiManager;
+class KviMdiChild;
+class KviMdiCaption;
+
+class QCursor;
+
+
+
+class KVIRC_API KviMdiChild : public QFrame
+{
+ friend class KviMdiManager;
+ friend class KviMdiCaption;
+ Q_OBJECT
+public:
+ KviMdiChild(KviMdiManager* par,const char * name = 0);
+ ~KviMdiChild();
+public:
+ enum MdiChildState { Maximized , Minimized , Normal };
+protected:
+ KviMdiManager * m_pManager;
+ KviMdiCaption * m_pCaption;
+private:
+ int m_iResizeCorner;
+ int m_iLastCursorCorner;
+ bool m_bResizeMode;
+ QWidget * m_pClient;
+ MdiChildState m_state;
+ QRect m_restoredGeometry;
+
+ QString m_szXmlActiveCaption;
+ QString m_szXmlInactiveCaption;
+ QString m_szPlainCaption;
+public:
+ QRect restoredGeometry();
+ void setRestoredGeometry(const QRect &r){ m_restoredGeometry = r; };
+ void setClient(QWidget * w);
+ QWidget * client(){ return m_pClient; };
+ void unsetClient();
+ KviMdiCaption * captionLabel(){ return m_pCaption; };
+ MdiChildState state(){ return m_state; };
+ const QString & plainCaption(){ return m_szPlainCaption; };
+ const QString & xmlActiveCaption(){ return m_szXmlActiveCaption; };
+ const QString & xmlInactiveCaption(){ return m_szXmlInactiveCaption; };
+ void setCaption(const QString & plain,const QString & xmlActive,const QString & xmlInactive);
+ virtual QSize sizeHint();
+ void setIcon(const QPixmap &pix);
+ const QPixmap * icon();
+ void enableClose(bool bEnable);
+ bool closeEnabled();
+ KviMdiManager * manager(){ return m_pManager; };
+ void activate(bool bSetFocus);
+ void reloadImages();
+public slots:
+ void maximize();
+ void minimize();
+ void restore();
+ void systemPopupSlot();
+ void closeRequest();
+signals:
+ void systemPopupRequest(const QPoint & pnt);
+protected:
+#ifdef COMPILE_USE_QT4
+ virtual void setBackgroundRole(QPalette::ColorRole);
+#else
+ virtual void setBackgroundMode(QWidget::BackgroundMode bgmd);
+#endif
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+ virtual void leaveEvent(QEvent *e);
+ virtual void focusInEvent(QFocusEvent *);
+ virtual void moveEvent(QMoveEvent *e);
+// bool eventFilter(QObject *o,QEvent *e);
+ void emitSystemPopupRequest(const QPoint & pnt){ emit systemPopupRequest(pnt); };
+private:
+// void linkChildren(QWidget *w);
+// void unlinkChildren(QWidget *w);
+ QCursor getResizeCursor(int resizeCorner);
+ void resizeWindowOpaque(int resizeCorner);
+ int getResizeCorner(int ax,int ay);
+ void calculateMinimumSize(int &minWidth,int &minHeight);
+ void setResizeCursor(int resizeCorner);
+ void calculateResizeRect(int resizeCorner,QPoint mousePos,QRect &resizeRect,int minWidth,int minHeight);
+};
+
+
+#endif //_KVI_MDICHILD_H_
diff --git a/src/kvirc/ui/kvi_mdimanager.cpp b/src/kvirc/ui/kvi_mdimanager.cpp
new file mode 100644
index 0000000..feddca1
--- /dev/null
+++ b/src/kvirc/ui/kvi_mdimanager.cpp
@@ -0,0 +1,1126 @@
+//=============================================================================
+//
+// File : kvi_mdimanager.cpp
+// Creation date : Wed Jun 21 2000 17:28:04 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2003 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_debug.h"
+#include "kvi_settings.h"
+#include "kvi_mdimanager.h"
+#include "kvi_mdichild.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_iconmanager.h"
+#include "kvi_frame.h"
+#include "kvi_menubar.h"
+#include "kvi_mdicaption.h"
+#include "kvi_app.h"
+
+#include "kvi_tal_popupmenu.h"
+#include <qmenubar.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <math.h>
+#include <qcursor.h>
+#include <qdrawutil.h>
+#include <qevent.h>
+
+#ifdef COMPILE_USE_QT4
+ #include "kvi_tal_hbox.h"
+#endif
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ #include <qpixmap.h>
+ extern QPixmap * g_pShadedParentGlobalDesktopBackground;
+#endif
+
+
+
+
+KviMdiManager::KviMdiManager(QWidget * parent,KviFrame * pFrm,const char * name)
+: KviTalScrollView(parent)
+{
+ setFrameShape(NoFrame);
+ m_pZ = new KviPointerList<KviMdiChild>;
+ m_pZ->setAutoDelete(true);
+
+ m_pFrm = pFrm;
+
+ m_iSdiIconItemId = 0;
+ m_iSdiCloseItemId = 0;
+ m_iSdiRestoreItemId = 0;
+ m_iSdiMinimizeItemId = 0;
+ m_pSdiIconButton = 0;
+ m_pSdiCloseButton = 0;
+ m_pSdiRestoreButton = 0;
+ m_pSdiMinimizeButton = 0;
+#ifdef COMPILE_USE_QT4
+ m_pSdiControls = 0;
+#endif
+
+ m_pWindowPopup = new KviTalPopupMenu(this);
+ connect(m_pWindowPopup,SIGNAL(activated(int)),this,SLOT(menuActivated(int)));
+ connect(m_pWindowPopup,SIGNAL(aboutToShow()),this,SLOT(fillWindowPopup()));
+ m_pTileMethodPopup = new KviTalPopupMenu(this);
+ connect(m_pTileMethodPopup,SIGNAL(activated(int)),this,SLOT(tileMethodMenuActivated(int)));
+
+#ifdef COMPILE_USE_QT4
+ viewport()->setAutoFillBackground(false);
+#else
+ viewport()->setBackgroundMode(QWidget::NoBackground);
+#endif
+ setStaticBackground(true);
+ resizeContents(width(),height());
+
+#ifdef COMPILE_USE_QT4
+ setFocusPolicy(Qt::NoFocus);
+ viewport()->setFocusPolicy(Qt::NoFocus);
+#else
+ setFocusPolicy(QWidget::NoFocus);
+ viewport()->setFocusPolicy(QWidget::NoFocus);
+#endif
+
+ connect(g_pApp,SIGNAL(reloadImages()),this,SLOT(reloadImages()));
+}
+
+KviMdiManager::~KviMdiManager()
+{
+ delete m_pZ;
+}
+
+void KviMdiManager::reloadImages()
+{
+ for(KviMdiChild * c = m_pZ->first();c;c = m_pZ->next())
+ {
+ c->reloadImages();
+ }
+}
+
+bool KviMdiManager::focusNextPrevChild(bool bNext)
+{
+ //bug("FFFFFF");
+ // this is a QScrollView bug... it doesn't pass this
+ // event to the toplevel window
+ return m_pFrm->focusNextPrevChild(bNext);
+}
+
+void KviMdiManager::drawContents(QPainter *p,int x,int y,int w,int h)
+{
+ //debug("MY DRAW CONTENTS (%d,%d,%d,%d)",x,y,w,h);
+ QRect r(x,y,w,h);
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedParentGlobalDesktopBackground)
+ {
+ QPoint pnt = viewport()->mapToGlobal(contentsToViewport(r.topLeft()));
+ p->drawTiledPixmap(r,*(g_pShadedParentGlobalDesktopBackground),pnt);
+ return;
+ }
+#endif
+
+ if(KVI_OPTION_PIXMAP(KviOption_pixmapMdiBackground).pixmap())
+ {
+ p->drawTiledPixmap(r,*(KVI_OPTION_PIXMAP(KviOption_pixmapMdiBackground).pixmap()));
+ } else {
+ p->fillRect(r,KVI_OPTION_COLOR(KviOption_colorMdiBackground));
+ }
+}
+
+void KviMdiManager::manageChild(KviMdiChild * lpC,bool bCascade,QRect *setGeom)
+{
+ __range_valid(lpC);
+
+ m_pZ->insert(0,lpC); //hidden -> last in the Z order
+
+ if(bCascade)
+ {
+ QPoint p = getCascadePoint(m_pZ->count()-1);
+ addChild(lpC,p.x(),p.y());
+ } else {
+ // FIXME: is this right ?
+ QPoint p = lpC->pos();
+ if(p.x() < 0)p.setX(0);
+ if(p.y() < 0)p.setY(0);
+ addChild(lpC,p.x(),p.y());
+
+ if(setGeom)
+ {
+ if(setGeom->left() < 0)setGeom->setLeft(0);
+ if(setGeom->top() < 0)setGeom->setTop(0);
+ moveChild(lpC,setGeom->x(),setGeom->y());
+ lpC->setGeometry(*setGeom);
+ }
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile();
+}
+
+void KviMdiManager::showAndActivate(KviMdiChild * lpC)
+{
+ lpC->show();
+ setTopChild(lpC,true);
+ if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile();
+}
+
+void KviMdiManager::setTopChild(KviMdiChild *lpC,bool bSetFocus)
+{
+ __range_valid(lpC);
+ // The following check fails safely at startup....
+ // __range_valid(lpC->isVisible() || lpC->testWState(WState_ForceHide));
+
+ KviMdiChild * pOldTop = m_pZ->last();
+ if(pOldTop != lpC)
+ {
+ m_pZ->setAutoDelete(false);
+
+ if(!m_pZ->removeRef(lpC))
+ {
+ m_pZ->setAutoDelete(true);
+ return; // no such child ?
+ }
+
+ // disable the labels of all the other children
+ //for(KviMdiChild *pC=m_pZ->first();pC;pC=m_pZ->next())
+ //{
+ // pC->captionLabel()->setActive(false);
+ //}
+ KviMdiChild * pMaximizedChild = pOldTop;
+ if(pOldTop)
+ {
+ pOldTop->captionLabel()->setActive(false);
+ if(pOldTop->m_state != KviMdiChild::Maximized)pMaximizedChild=0;
+ }
+
+ m_pZ->setAutoDelete(true);
+ m_pZ->append(lpC);
+
+ if(pMaximizedChild)lpC->maximize(); //do not animate the change
+ lpC->raise();
+ if(pMaximizedChild)pMaximizedChild->restore();
+ }
+
+ if(bSetFocus)
+ {
+ if(!lpC->hasFocus())
+ {
+ lpC->setFocus();
+ /*
+ if(topLevelWidget()->isActiveWindow())
+ {
+
+ }
+ */
+ }
+ }
+}
+
+void KviMdiManager::focusInEvent(QFocusEvent *)
+{
+ focusTopChild();
+}
+
+void KviMdiManager::destroyChild(KviMdiChild *lpC,bool bFocusTopChild)
+{
+ bool bWasMaximized = lpC->state() == KviMdiChild::Maximized;
+ disconnect(lpC);
+ lpC->blockSignals(true);
+#ifdef _KVI_DEBUG_CHECK_RANGE_
+ //Report invalid results in a debug session
+ __range_valid(m_pZ->removeRef(lpC));
+#else
+ m_pZ->removeRef(lpC);
+#endif
+ if(bWasMaximized)
+ {
+ KviMdiChild * c=topChild();
+ if(c)
+ {
+ if(c->state() != KviMdiChild::Minimized)c->maximize();
+ else {
+ // minimized top child...the last one
+ leaveSDIMode();
+ }
+ } else {
+ // SDI state change
+ leaveSDIMode();
+ }
+ }
+ if(bFocusTopChild)focusTopChild();
+
+ if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile();
+ updateContentsSize();
+}
+
+KviMdiChild * KviMdiManager::highestChildExcluding(KviMdiChild * pChild)
+{
+ KviMdiChild * c = m_pZ->last();
+ while(c && (c == pChild))c = m_pZ->prev();
+ return c;
+}
+
+QPoint KviMdiManager::getCascadePoint(int indexOfWindow)
+{
+ QPoint pnt(0,0);
+ if(indexOfWindow==0)return pnt;
+ KviMdiChild *lpC=m_pZ->first();
+ int step=(lpC ? (lpC->captionLabel()->heightHint()+KVI_MDICHILD_BORDER) : 20);
+ int availableHeight=viewport()->height()-(lpC ? lpC->minimumSize().height() : KVI_MDICHILD_MIN_HEIGHT);
+ int availableWidth=viewport()->width()-(lpC ? lpC->minimumSize().width() : KVI_MDICHILD_MIN_WIDTH);
+ int ax=0;
+ int ay=0;
+ for(int i=0;i<indexOfWindow;i++)
+ {
+ ax+=step;
+ ay+=step;
+ if(ax>availableWidth)ax=0;
+ if(ay>availableHeight)ay=0;
+ }
+ pnt.setX(ax);
+ pnt.setY(ay);
+ return pnt;
+}
+
+void KviMdiManager::mousePressEvent(QMouseEvent *e)
+{
+ //Popup the window menu
+ if(e->button() & Qt::RightButton)m_pWindowPopup->popup(mapToGlobal(e->pos()));
+}
+
+void KviMdiManager::childMoved(KviMdiChild *)
+{
+ updateContentsSize();
+}
+
+void KviMdiManager::maximizeChild(KviMdiChild * lpC)
+{
+ // the children must be moved once by the means of QScrollView::moveChild()
+ // so the QScrollView internal structures get updated with the negative
+ // position of the widget, otherwise, when restoring with moveChild()
+ // it will refuse to move it back to the original position
+ resizeContents(visibleWidth(),visibleHeight());
+ updateScrollBars();
+ g_pApp->sendPostedEvents();
+ if(g_pApp->closingDown())return;
+
+ moveChild(lpC,-KVI_MDICHILD_HIDDEN_EDGE,
+ -(KVI_MDICHILD_HIDDEN_EDGE + KVI_MDICHILD_SPACING + lpC->m_pCaption->heightHint()));
+
+ lpC->setGeometry(
+ -KVI_MDICHILD_HIDDEN_EDGE,
+ -(KVI_MDICHILD_HIDDEN_EDGE + KVI_MDICHILD_SPACING + lpC->m_pCaption->heightHint()),
+ viewport()->width() + (KVI_MDICHILD_HIDDEN_EDGE * 2), //KVI_MDICHILD_DOUBLE_HIDDEN_EDGE,
+ viewport()->height() + (KVI_MDICHILD_HIDDEN_EDGE * 2) + lpC->m_pCaption->heightHint() + KVI_MDICHILD_SPACING);
+
+ if(isInSDIMode())updateSDIMode();
+ else {
+ enterSDIMode(lpC);
+ // make sure that the child is focused
+ lpC->setFocus();
+ }
+
+ // fixme: we could hide all the other children now!
+}
+
+
+
+void KviMdiManager::resizeEvent(QResizeEvent *e)
+{
+ //If we have a maximized children at the top , adjust its size
+ KviTalScrollView::resizeEvent(e);
+ KviMdiChild *lpC=m_pZ->last();
+ if(lpC)
+ {
+ if(lpC->state()==KviMdiChild::Maximized)
+ {
+ // SDI mode
+ lpC->resize(viewport()->width() + (KVI_MDICHILD_HIDDEN_EDGE * 2),
+ viewport()->height() + lpC->m_pCaption->heightHint() + (KVI_MDICHILD_HIDDEN_EDGE * 2) + KVI_MDICHILD_SPACING);
+ return;
+ } else {
+ if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile();
+ }
+ }
+ updateContentsSize();
+}
+
+
+/*
+void KviMdiManager::childMaximized(KviMdiChild * lpC)
+{
+ if(lpC == m_pZ->last())
+ {
+ enterSDIMode(lpC);
+ }
+ updateContentsSize();
+}
+*/
+
+void KviMdiManager::childMinimized(KviMdiChild * lpC,bool bWasMaximized)
+{
+ __range_valid(lpC);
+ if(m_pZ->findRef(lpC) == -1)return;
+ if(m_pZ->count() > 1)
+ {
+ m_pZ->setAutoDelete(false);
+#ifdef _KVI_DEBUG_CHECK_RANGE_
+ //Report invalid results in a debug session
+ __range_valid(m_pZ->removeRef(lpC));
+#else
+ m_pZ->removeRef(lpC);
+#endif
+ m_pZ->setAutoDelete(true);
+ m_pZ->insert(0,lpC);
+ if(bWasMaximized)
+ {
+ // Need to maximize the top child
+ lpC = m_pZ->last();
+ if(!lpC)return; //??
+ if(lpC->state()==KviMdiChild::Minimized)
+ {
+ if(bWasMaximized)leaveSDIMode();
+ return;
+ }
+ lpC->maximize(); //do nrot animate the change
+ } else {
+ if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile();
+ }
+ focusTopChild();
+ } else {
+ // Unique window minimized...it won't loose the focus...!!
+ setFocus(); //Remove focus from the child
+ if(bWasMaximized)leaveSDIMode();
+ }
+ updateContentsSize();
+}
+
+void KviMdiManager::childRestored(KviMdiChild * lpC,bool bWasMaximized)
+{
+ if(bWasMaximized)
+ {
+ if(lpC != m_pZ->last())return; // do nothing in this case
+ leaveSDIMode();
+ updateContentsSize();
+ }
+ if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile();
+}
+
+void KviMdiManager::focusTopChild()
+{
+ KviMdiChild *lpC=m_pZ->last();
+ if(!lpC)return;
+ if(!lpC->isVisible())return;
+ // if(lpC->state()==KviMdiChild::Minimized)return;
+ // debug("Focusing top child %s",lpC->name());
+ //disable the labels of all the other children
+ for(KviMdiChild *pC=m_pZ->first();pC;pC=m_pZ->next())
+ {
+ if(pC != lpC)
+ pC->captionLabel()->setActive(false);
+ }
+ lpC->raise();
+ if(!lpC->hasFocus())lpC->setFocus();
+}
+
+void KviMdiManager::minimizeActiveChild()
+{
+ KviMdiChild * lpC = m_pZ->last();
+ if(!lpC)return;
+ if(lpC->state() != KviMdiChild::Minimized)lpC->minimize();
+}
+
+void KviMdiManager::restoreActiveChild()
+{
+ KviMdiChild * lpC = m_pZ->last();
+ if(!lpC)return;
+ if(lpC->state() == KviMdiChild::Maximized)lpC->restore();
+}
+
+void KviMdiManager::closeActiveChild()
+{
+ KviMdiChild * lpC = m_pZ->last();
+ if(!lpC)return;
+ lpC->closeRequest();
+}
+
+void KviMdiManager::updateContentsSize()
+{
+ KviMdiChild * c = m_pZ->last();
+ if(c)
+ {
+ if(c->state() == KviMdiChild::Maximized)
+ {
+ return;
+ }
+ }
+
+ int fw = frameWidth() * 2;
+ int mx = width() - fw;
+ int my = height() - fw;
+
+ for(c = m_pZ->first();c;c = m_pZ->next())
+ {
+ if(c->isVisible())
+ {
+ int x = childX(c) + c->width();
+ if(x > mx)mx = x;
+ int y = childY(c) + c->height();
+ if(y > my)my = y;
+ }
+ }
+
+ resizeContents(mx,my);
+}
+
+
+void KviMdiManager::updateSDIMode()
+{
+
+ KviMdiChild * lpC = m_pZ->last();
+
+ if(m_pSdiCloseButton)
+ m_pSdiCloseButton->setEnabled(lpC ? lpC->closeEnabled() : false);
+
+// This would result in an addictional main menu bar entry on MacOSX which would trigger a popup menu and not
+// a submenu. Due to the optical reasons it is removed here.
+// The same popup is triggered by right clicking on the window name in the channel window list.
+#ifndef Q_OS_MACX
+ KviMenuBar * b = m_pFrm->mainMenuBar();
+
+ const QPixmap * pix = lpC ? lpC->icon() : 0;
+ if(!pix)pix = g_pIconManager->getSmallIcon(KVI_SMALLICON_NONE);
+ else if(pix->isNull())pix = g_pIconManager->getSmallIcon(KVI_SMALLICON_NONE);
+
+ if(!m_pSdiIconButton)
+ {
+ m_pSdiIconButton = new KviMenuBarToolButton(b,*pix,"nonne");
+ connect(m_pSdiIconButton,SIGNAL(clicked()),this,SLOT(activeChildSystemPopup()));
+#ifdef COMPILE_USE_QT4
+ // This is an obscure, undocumented and internal function in QT4 QMenuBar
+ // I won't be surprised if this disappears....
+ b->setCornerWidget(m_pSdiIconButton,Qt::TopLeftCorner);
+ m_pSdiIconButton->show();
+#else
+ m_iSdiIconItemId = b->insertItem(m_pSdiIconButton,-1,0);
+#endif
+ connect(m_pSdiIconButton,SIGNAL(destroyed()),this,SLOT(sdiIconButtonDestroyed()));
+ } else {
+ m_pSdiIconButton->setPixmap(*pix);
+ }
+#endif //Q_OS_MACX
+}
+
+void KviMdiManager::activeChildSystemPopup()
+{
+ KviMdiChild * lpC = m_pZ->last();
+ if(!lpC)return;
+ QPoint pnt;
+ if(m_pSdiIconButton)
+ {
+ pnt = m_pSdiIconButton->mapToGlobal(QPoint(0,m_pSdiIconButton->height()));
+ } else {
+ pnt = QCursor::pos();
+ }
+ lpC->emitSystemPopupRequest(pnt);
+}
+
+bool KviMdiManager::isInSDIMode()
+{
+ return (m_pSdiCloseButton != 0);
+}
+
+
+void KviMdiManager::enterSDIMode(KviMdiChild *lpC)
+{
+ if(!m_pSdiCloseButton)
+ {
+ KviMenuBar * b = m_pFrm->mainMenuBar();
+
+ QWidget * pButtonParent;
+
+#ifdef COMPILE_USE_QT4
+ m_pSdiControls = new KviTalHBox(b);
+ m_pSdiControls->setMargin(0);
+ m_pSdiControls->setSpacing(2);
+ m_pSdiControls->setAutoFillBackground(false);
+ pButtonParent = m_pSdiControls;
+#else
+ pButtonParent = b;
+#endif
+ m_pSdiMinimizeButton = new KviMenuBarToolButton(pButtonParent,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINIMIZE)),"btnminimize");
+ connect(m_pSdiMinimizeButton,SIGNAL(clicked()),this,SLOT(minimizeActiveChild()));
+#ifndef COMPILE_USE_QT4
+ m_iSdiMinimizeItemId = b->insertItem(m_pSdiMinimizeButton,-1,b->count());
+#endif
+ connect(m_pSdiMinimizeButton,SIGNAL(destroyed()),this,SLOT(sdiMinimizeButtonDestroyed()));
+
+ m_pSdiRestoreButton = new KviMenuBarToolButton(pButtonParent,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RESTORE)),"btnrestore");
+ connect(m_pSdiRestoreButton,SIGNAL(clicked()),this,SLOT(restoreActiveChild()));
+#ifndef COMPILE_USE_QT4
+ m_iSdiRestoreItemId = b->insertItem(m_pSdiRestoreButton,-1,b->count());
+#endif
+ connect(m_pSdiRestoreButton,SIGNAL(destroyed()),this,SLOT(sdiRestoreButtonDestroyed()));
+
+ m_pSdiCloseButton = new KviMenuBarToolButton(pButtonParent,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)),"btnclose");
+ connect(m_pSdiCloseButton,SIGNAL(clicked()),this,SLOT(closeActiveChild()));
+#ifndef COMPILE_USE_QT4
+ m_iSdiCloseItemId = b->insertItem(m_pSdiCloseButton,-1,b->count());
+#endif
+ connect(m_pSdiCloseButton,SIGNAL(destroyed()),this,SLOT(sdiCloseButtonDestroyed()));
+
+#ifdef COMPILE_USE_QT4
+ // This is an obscure, undocumented and internal function in QT4 QMenuBar
+ // I won't be surprised if this disappears....
+ b->setCornerWidget(m_pSdiControls,Qt::TopRightCorner);
+ // The show below SHOULD force a re-layout of the menubar..
+ // but it doesn't work when the KviFrame is still hidden (at startup)
+ // We handle this BUG in showEvent()
+ m_pSdiControls->show();
+#else
+ m_pSdiRestoreButton->show();
+ m_pSdiMinimizeButton->show();
+ m_pSdiCloseButton->show();
+#endif
+ emit enteredSdiMode();
+
+ setVScrollBarMode(KviTalScrollView::AlwaysOff);
+ setHScrollBarMode(KviTalScrollView::AlwaysOff);
+ }
+
+ updateSDIMode();
+}
+void KviMdiManager::relayoutMenuButtons()
+{
+#ifdef COMPILE_USE_QT4
+ // force a re-layout of the menubar in Qt4 (see the note in enterSDIMode())
+ // by resetting the corner widget
+ if(m_pSdiControls)
+ {
+ m_pFrm->mainMenuBar()->setCornerWidget(0,Qt::TopRightCorner);
+ m_pFrm->mainMenuBar()->setCornerWidget(m_pSdiControls,Qt::TopRightCorner);
+ }
+ // also force an activation of the top MdiChild since it probably didn't get it yet
+ KviMdiChild * c = topChild();
+ if(c)
+ c->activate(false);
+#endif
+}
+
+
+void KviMdiManager::sdiIconButtonDestroyed()
+{
+ m_iSdiIconItemId = 0;
+ m_pSdiIconButton = 0;
+}
+
+void KviMdiManager::sdiMinimizeButtonDestroyed()
+{
+ m_iSdiMinimizeItemId = 0;
+ m_pSdiMinimizeButton = 0;
+}
+
+void KviMdiManager::sdiRestoreButtonDestroyed()
+{
+ m_iSdiRestoreItemId = 0;
+ m_pSdiRestoreButton = 0;
+}
+
+void KviMdiManager::sdiCloseButtonDestroyed()
+{
+ m_iSdiCloseItemId = 0;
+ m_pSdiCloseButton = 0;
+}
+
+void KviMdiManager::leaveSDIMode()
+{
+ __range_valid(m_pSdiCloseButton);
+
+#ifdef COMPILE_USE_QT4
+ if(m_pSdiControls)
+ {
+ delete m_pSdiControls;
+ m_pSdiControls = 0;
+ }
+ if(m_pSdiIconButton)
+ {
+ m_pSdiIconButton->hide(); // this will force a QMenuBar relayout
+ delete m_pSdiIconButton;
+ m_pSdiIconButton = 0;
+ }
+#else
+ if(m_iSdiIconItemId != 0)m_pFrm->mainMenuBar()->removeItem(m_iSdiIconItemId);
+ if(m_iSdiCloseItemId != 0)m_pFrm->mainMenuBar()->removeItem(m_iSdiCloseItemId);
+ if(m_iSdiRestoreItemId != 0)m_pFrm->mainMenuBar()->removeItem(m_iSdiRestoreItemId);
+ if(m_iSdiMinimizeItemId != 0)m_pFrm->mainMenuBar()->removeItem(m_iSdiMinimizeItemId);
+#endif
+
+ setVScrollBarMode(KviTalScrollView::Auto);
+ setHScrollBarMode(KviTalScrollView::Auto);
+
+ emit leftSdiMode();
+}
+
+#define KVI_TILE_METHOD_ANODINE 0
+#define KVI_TILE_METHOD_PRAGMA4HOR 1
+#define KVI_TILE_METHOD_PRAGMA4VER 2
+#define KVI_TILE_METHOD_PRAGMA6HOR 3
+#define KVI_TILE_METHOD_PRAGMA6VER 4
+#define KVI_TILE_METHOD_PRAGMA9HOR 5
+#define KVI_TILE_METHOD_PRAGMA9VER 6
+
+#define KVI_NUM_TILE_METHODS 7
+
+void KviMdiManager::fillWindowPopup()
+{
+ m_pWindowPopup->clear();
+
+ m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CASCADEWINDOWS)),(__tr2qs("&Cascade Windows")),this,SLOT(cascadeWindows()));
+ m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CASCADEWINDOWS)),(__tr2qs("Cascade &Maximized")),this,SLOT(cascadeMaximized()));
+
+ m_pWindowPopup->insertSeparator();
+ m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("&Tile Windows")),this,SLOT(tile()));
+
+ m_pTileMethodPopup->clear();
+ int id = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_AUTOTILEWINDOWS)),(__tr2qs("&Auto Tile")),this,SLOT(toggleAutoTile()));
+ m_pTileMethodPopup->setItemChecked(id,KVI_OPTION_BOOL(KviOption_boolAutoTileWindows));
+ m_pTileMethodPopup->setItemParameter(id,-1);
+ m_pTileMethodPopup->insertSeparator();
+ int ids[KVI_NUM_TILE_METHODS];
+ ids[KVI_TILE_METHOD_ANODINE] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Anodine's Full Grid")));
+ m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_ANODINE],KVI_TILE_METHOD_ANODINE);
+ ids[KVI_TILE_METHOD_PRAGMA4HOR] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Horizontal 4-Grid")));
+ m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA4HOR],KVI_TILE_METHOD_PRAGMA4HOR);
+ ids[KVI_TILE_METHOD_PRAGMA4VER] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Vertical 4-Grid")));
+ m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA4VER],KVI_TILE_METHOD_PRAGMA4VER);
+ ids[KVI_TILE_METHOD_PRAGMA6HOR] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Horizontal 6-Grid")));
+ m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA6HOR],KVI_TILE_METHOD_PRAGMA6HOR);
+ ids[KVI_TILE_METHOD_PRAGMA6VER] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Vertical 6-Grid")));
+ m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA6VER],KVI_TILE_METHOD_PRAGMA6VER);
+ ids[KVI_TILE_METHOD_PRAGMA9HOR] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Horizontal 9-Grid")));
+ m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA9HOR],KVI_TILE_METHOD_PRAGMA9HOR);
+ ids[KVI_TILE_METHOD_PRAGMA9VER] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Vertical 9-Grid")));
+ m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA9VER],KVI_TILE_METHOD_PRAGMA9VER);
+
+ if(KVI_OPTION_UINT(KviOption_uintTileMethod) >= KVI_NUM_TILE_METHODS)KVI_OPTION_UINT(KviOption_uintTileMethod) = KVI_TILE_METHOD_PRAGMA9HOR;
+ m_pTileMethodPopup->setItemChecked(ids[KVI_OPTION_UINT(KviOption_uintTileMethod)],true);
+
+ m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Tile Met&hod")),m_pTileMethodPopup);
+
+ m_pWindowPopup->insertSeparator();
+ m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MAXVERTICAL)),(__tr2qs("Expand &Vertically")),this,SLOT(expandVertical()));
+ m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MAXHORIZONTAL)),(__tr2qs("Expand &Horizontally")),this,SLOT(expandHorizontal()));
+
+ m_pWindowPopup->insertSeparator();
+ m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINIMIZE)),(__tr2qs("Mi&nimize All")),this,SLOT(minimizeAll()));
+// m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RESTORE)),(__tr2qs("&Restore all")),this,SLOT(restoreAll()));
+//
+ m_pWindowPopup->insertSeparator();
+ int i=100;
+ QString szItem;
+ QString szCaption;
+ for(KviMdiChild *lpC=m_pZ->first();lpC;lpC=m_pZ->next())
+ {
+ szItem.setNum(((uint)i)-99);
+ szItem+=". ";
+
+ szCaption = lpC->plainCaption();
+ if(szCaption.length() > 30)
+ {
+ QString trail = szCaption.right(12);
+ szCaption.truncate(12);
+ szCaption+="...";
+ szCaption+=trail;
+ }
+
+ if(lpC->state()==KviMdiChild::Minimized)
+ {
+ szItem+="(";
+ szItem+=szCaption;
+ szItem+=")";
+ } else szItem+=szCaption;
+ const QPixmap * pix = lpC->icon();
+ if(pix && !(pix->isNull()))m_pWindowPopup->insertItem(*pix,szItem,i);
+ else m_pWindowPopup->insertItem(szItem,i);
+ m_pWindowPopup->setItemChecked(i,((uint)i)==(m_pZ->count()+99));
+ i++;
+ }
+}
+
+void KviMdiManager::menuActivated(int id)
+{
+ if(id<100)return;
+ id-=100;
+ __range_valid(((uint)id) < m_pZ->count());
+ KviMdiChild *lpC=m_pZ->at(id);
+ if(!lpC)return;
+ if(lpC->state()==KviMdiChild::Minimized)lpC->restore();
+ setTopChild(lpC,true);
+}
+
+void KviMdiManager::ensureNoMaximized()
+{
+ KviMdiChild * lpC;
+
+ for(lpC=m_pZ->first();lpC;lpC=m_pZ->next())
+ {
+ if(lpC->state()==KviMdiChild::Maximized)lpC->restore();
+ }
+}
+
+void KviMdiManager::tileMethodMenuActivated(int id)
+{
+ int idx = m_pTileMethodPopup->itemParameter(id);
+ if(idx < 0)idx = 0;
+ if(idx >= KVI_NUM_TILE_METHODS)idx = KVI_TILE_METHOD_PRAGMA9VER;
+ KVI_OPTION_UINT(KviOption_uintTileMethod) = idx;
+ if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile();
+}
+
+void KviMdiManager::cascadeWindows()
+{
+ ensureNoMaximized();
+ // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct
+ resizeContents(visibleWidth(),visibleHeight());
+ updateScrollBars();
+ g_pApp->sendPostedEvents();
+ if(g_pApp->closingDown())return;
+
+ int idx=0;
+ KviPointerList<KviMdiChild> list(*m_pZ);
+ list.setAutoDelete(false);
+ while(!list.isEmpty())
+ {
+ KviMdiChild *lpC=list.first();
+ if(lpC->state() != KviMdiChild::Minimized)
+ {
+ QPoint p = getCascadePoint(idx);
+ moveChild(lpC,p.x(),p.y());
+ lpC->resize(lpC->sizeHint());
+ idx++;
+ }
+ list.removeFirst();
+ }
+ focusTopChild();
+ updateContentsSize();
+}
+
+void KviMdiManager::cascadeMaximized()
+{
+ ensureNoMaximized();
+ // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct
+ resizeContents(visibleWidth(),visibleHeight());
+ updateScrollBars();
+ g_pApp->sendPostedEvents();
+ if(g_pApp->closingDown())return;
+
+ int idx=0;
+ KviPointerList<KviMdiChild> list(*m_pZ);
+
+ list.setAutoDelete(false);
+ while(!list.isEmpty())
+ {
+ KviMdiChild *lpC=list.first();
+ if(lpC->state() != KviMdiChild::Minimized)
+ {
+ QPoint pnt(getCascadePoint(idx));
+ moveChild(lpC,pnt.x(),pnt.y());
+ QSize curSize(viewport()->width() - pnt.x(),viewport()->height() - pnt.y());
+ if((lpC->minimumSize().width() > curSize.width()) ||
+ (lpC->minimumSize().height() > curSize.height()))lpC->resize(lpC->minimumSize());
+ else lpC->resize(curSize);
+ idx++;
+ }
+ list.removeFirst();
+ }
+ focusTopChild();
+ updateContentsSize();
+}
+
+void KviMdiManager::expandVertical()
+{
+ ensureNoMaximized();
+ // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct
+ resizeContents(visibleWidth(),visibleHeight());
+ updateScrollBars();
+ g_pApp->sendPostedEvents();
+ if(g_pApp->closingDown())return;
+
+ KviPointerList<KviMdiChild> list(*m_pZ);
+ list.setAutoDelete(false);
+ while(!list.isEmpty())
+ {
+ KviMdiChild *lpC=list.first();
+ if(lpC->state() != KviMdiChild::Minimized)
+ {
+ moveChild(lpC,lpC->x(),0);
+ lpC->resize(lpC->width(),viewport()->height());
+ }
+ list.removeFirst();
+ }
+
+ focusTopChild();
+ updateContentsSize();
+}
+
+void KviMdiManager::expandHorizontal()
+{
+ ensureNoMaximized();
+ // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct
+ resizeContents(visibleWidth(),visibleHeight());
+ updateScrollBars();
+ g_pApp->sendPostedEvents();
+ if(g_pApp->closingDown())return;
+
+ KviPointerList<KviMdiChild> list(*m_pZ);
+ list.setAutoDelete(false);
+ while(!list.isEmpty())
+ {
+ KviMdiChild *lpC=list.first();
+ if(lpC->state() != KviMdiChild::Minimized)
+ {
+ moveChild(lpC,0,lpC->y());
+ lpC->resize(viewport()->width(),lpC->height());
+ }
+ list.removeFirst();
+ }
+ focusTopChild();
+ updateContentsSize();
+}
+
+void KviMdiManager::minimizeAll()
+{
+ KviPointerList<KviMdiChild> list(*m_pZ);
+ list.setAutoDelete(false);
+ m_pFrm->setActiveWindow((KviWindow*)m_pFrm->firstConsole());
+ while(!list.isEmpty())
+ {
+ KviMdiChild *lpC=list.first();
+ if(lpC->state() != KviMdiChild::Minimized)lpC->minimize();
+ list.removeFirst();
+ }
+ focusTopChild();
+ updateContentsSize();
+}
+
+/*
+void KviMdiManager::restoreAll()
+{
+ int idx=0;
+ KviPointerList<KviMdiChild> list(*m_pZ);
+ list.setAutoDelete(false);
+ while(!list.isEmpty())
+ {
+ KviMdiChild *lpC=list.first();
+ if(lpC->state() != KviMdiChild::Normal && (!(lpC->plainCaption()).contains("CONSOLE") ))
+ lpC->restore();
+ list.removeFirst();
+ }
+ focusTopChild();
+ updateContentsSize();
+}
+*/
+
+int KviMdiManager::getVisibleChildCount()
+{
+ int cnt=0;
+ for(KviMdiChild *lpC=m_pZ->first();lpC;lpC=m_pZ->next())
+ {
+ if(lpC->state() != KviMdiChild::Minimized)cnt++;
+ }
+ return cnt;
+}
+
+void KviMdiManager::tile()
+{
+ switch(KVI_OPTION_UINT(KviOption_uintTileMethod))
+ {
+ case KVI_TILE_METHOD_ANODINE: tileAnodine(); break;
+ case KVI_TILE_METHOD_PRAGMA4HOR: tileAllInternal(4,true); break;
+ case KVI_TILE_METHOD_PRAGMA4VER: tileAllInternal(4,false); break;
+ case KVI_TILE_METHOD_PRAGMA6HOR: tileAllInternal(6,true); break;
+ case KVI_TILE_METHOD_PRAGMA6VER: tileAllInternal(6,false); break;
+ case KVI_TILE_METHOD_PRAGMA9HOR: tileAllInternal(9,true); break;
+ case KVI_TILE_METHOD_PRAGMA9VER: tileAllInternal(9,false); break;
+ default:
+ KVI_OPTION_UINT(KviOption_uintTileMethod) = KVI_TILE_METHOD_PRAGMA9HOR;
+ tileAllInternal(9,true);
+ break;
+ }
+}
+
+void KviMdiManager::toggleAutoTile()
+{
+ if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))
+ {
+ KVI_OPTION_BOOL(KviOption_boolAutoTileWindows) = false;
+ } else {
+ KVI_OPTION_BOOL(KviOption_boolAutoTileWindows) = true;
+ tile();
+ }
+}
+
+
+void KviMdiManager::tileAllInternal(int maxWnds,bool bHorizontal)
+{
+ //NUM WINDOWS = 1,2,3,4,5,6,7,8,9
+ static int colstable[9]={ 1,1,1,2,2,2,3,3,3 }; //num columns
+ static int rowstable[9]={ 1,2,3,2,3,3,3,3,3 }; //num rows
+ static int lastwindw[9]={ 1,1,1,1,2,1,3,2,1 }; //last window multiplier
+ static int colrecall[9]={ 0,0,0,3,3,3,6,6,6 }; //adjust self
+ static int rowrecall[9]={ 0,0,0,0,4,4,4,4,4 }; //adjust self
+
+ int * pColstable = bHorizontal ? colstable : rowstable;
+ int * pRowstable = bHorizontal ? rowstable : colstable;
+ int * pColrecall = bHorizontal ? colrecall : rowrecall;
+ int * pRowrecall = bHorizontal ? rowrecall : colrecall;
+
+ ensureNoMaximized();
+ // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct
+ resizeContents(visibleWidth(),visibleHeight());
+ updateScrollBars();
+ g_pApp->sendPostedEvents();
+ if(g_pApp->closingDown())return;
+
+ KviMdiChild *lpTop=topChild();
+ int numVisible=getVisibleChildCount();
+
+ if(numVisible<1)return;
+
+ int numToHandle=((numVisible > maxWnds) ? maxWnds : numVisible);
+ int xQuantum=viewport()->width()/pColstable[numToHandle-1];
+ if(xQuantum < ((lpTop->minimumSize().width() > KVI_MDICHILD_MIN_WIDTH) ? lpTop->minimumSize().width() : KVI_MDICHILD_MIN_WIDTH)){
+ if(pColrecall[numToHandle-1]==0)debug("Tile : Not enouh space");
+ else tileAllInternal(pColrecall[numToHandle-1],bHorizontal);
+ return;
+ }
+ int yQuantum=viewport()->height()/pRowstable[numToHandle-1];
+ if(yQuantum < ((lpTop->minimumSize().height() > KVI_MDICHILD_MIN_HEIGHT) ? lpTop->minimumSize().height() : KVI_MDICHILD_MIN_HEIGHT)){
+ if(pRowrecall[numToHandle-1]==0)debug("Tile : Not enough space");
+ else tileAllInternal(pRowrecall[numToHandle-1],bHorizontal);
+ return;
+ }
+ int curX=0;
+ int curY=0;
+ int curRow=1;
+ int curCol=1;
+ int curWin=1;
+
+ for(KviMdiChild * lpC=m_pZ->first();lpC;lpC=m_pZ->next())
+ {
+ if(lpC->state()!=KviMdiChild::Minimized)
+ {
+ if((curWin%numToHandle)==0)
+ {
+ moveChild(lpC,curX,curY);
+ lpC->resize(xQuantum * lastwindw[numToHandle-1],yQuantum);
+ } else {
+ moveChild(lpC,curX,curY);
+ lpC->resize(xQuantum,yQuantum);
+ }
+ //example : 12 windows : 3 cols 3 rows
+ if(curCol<pColstable[numToHandle-1])
+ { //curCol<3
+ curX+=xQuantum; //add a column in the same row
+ curCol++; //increase current column
+ } else {
+ curX=0; //new row
+ curCol=1; //column 1
+ if(curRow<pRowstable[numToHandle-1])
+ { //curRow<3
+ curY+=yQuantum; //add a row
+ curRow++; //
+ } else {
+ curY=0; //restart from beginning
+ curRow=1; //
+ }
+ }
+ curWin++;
+ }
+ }
+ if(lpTop)lpTop->setFocus();
+ updateContentsSize();
+}
+
+void KviMdiManager::tileAnodine()
+{
+ ensureNoMaximized();
+ // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct
+ resizeContents(visibleWidth(),visibleHeight());
+ updateScrollBars();
+ g_pApp->sendPostedEvents();
+ if(g_pApp->closingDown())return;
+
+ KviMdiChild *lpTop=topChild();
+ int numVisible=getVisibleChildCount(); // count visible windows
+ if(numVisible<1)return;
+ int numCols=int(sqrt((double)numVisible)); // set columns to square root of visible count
+ // create an array to form grid layout
+ int *numRows=new int[numCols];
+ int numCurCol=0;
+ while(numCurCol<numCols)
+ {
+ numRows[numCurCol]=numCols; // create primary grid values
+ numCurCol++;
+ }
+ int numDiff=numVisible-(numCols*numCols); // count extra rows
+ int numCurDiffCol=numCols; // set column limiting for grid updates
+ while(numDiff>0)
+ {
+ numCurDiffCol--;
+ numRows[numCurDiffCol]++; // add extra rows to column grid
+ if(numCurDiffCol<1)numCurDiffCol=numCols; // rotate through the grid
+ numDiff--;
+ }
+ numCurCol=0;
+ int numCurRow=0;
+ int curX=0;
+ int curY=0;
+ // the following code will size everything based on my grid above
+ // there is no limit to the number of windows it will handle
+ // it's great when a kick-ass theory works!!! // Pragma :)
+ int xQuantum=viewport()->width()/numCols;
+ int yQuantum=viewport()->height()/numRows[numCurCol];
+
+ for(KviMdiChild * lpC=m_pZ->first();lpC;lpC=m_pZ->next())
+ {
+ if(lpC->state() != KviMdiChild::Minimized)
+ {
+ moveChild(lpC,curX,curY);
+ lpC->resize(xQuantum,yQuantum);
+ numCurRow++;
+ curY+=yQuantum;
+ if(numCurRow==numRows[numCurCol])
+ {
+ numCurRow=0;
+ numCurCol++;
+ curY=0;
+ curX+=xQuantum;
+ if(numCurCol!=numCols)yQuantum=viewport()->height()/numRows[numCurCol];
+ }
+ }
+ }
+ delete[] numRows;
+ if(lpTop)lpTop->setFocus();
+ updateContentsSize();
+}
+
+
diff --git a/src/kvirc/ui/kvi_mdimanager.h b/src/kvirc/ui/kvi_mdimanager.h
new file mode 100644
index 0000000..17202fa
--- /dev/null
+++ b/src/kvirc/ui/kvi_mdimanager.h
@@ -0,0 +1,144 @@
+#ifndef _KVI_MDIMANAGER_H_
+#define _KVI_MDIMANAGER_H_
+//=============================================================================
+//
+// File : kvi_mdimanager.h
+// Creation date : Wed Jun 21 2000 17:28:04 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+
+#include "kvi_settings.h"
+#include "kvi_pointerlist.h"
+
+#include <qwidget.h>
+#include <qframe.h>
+#include <qpixmap.h>
+#include <qtoolbutton.h>
+
+#include "kvi_tal_scrollview.h"
+
+#define KVI_MDICHILD_BORDER 4
+#define KVI_MDICHILD_SPACING 2
+#define KVI_MDICHILD_MIN_WIDTH 100
+#define KVI_MDICHILD_MIN_HEIGHT 40
+#define KVI_MDICHILD_HIDDEN_EDGE 3
+
+#ifdef COMPILE_ON_WINDOWS
+ #include "kvi_mdichild.h"
+#else
+ class KviMdiChild;
+#endif
+//class KviMdiCaptionButton;
+class KviFrame;
+
+class KviTalPopupMenu;
+class KviTalHBox;
+class KviSdiButtonBox;
+class KviMenuBarToolButton;
+
+class KVIRC_API KviMdiManager : public KviTalScrollView
+{
+ friend class KviMdiChild;
+ friend class KviMdiCaption;
+ Q_OBJECT
+public:
+ KviMdiManager(QWidget * parent,KviFrame * pFrm,const char * name);
+ ~KviMdiManager();
+public:
+ KviMdiChild * topChild(){ return m_pZ->last(); };
+ KviMdiChild * highestChildExcluding(KviMdiChild * pChild);
+ void manageChild(KviMdiChild * lpC,bool bCascade = true,QRect * setGeom = 0);
+ void setTopChild(KviMdiChild *lpC,bool bSetFocus);
+ void showAndActivate(KviMdiChild * lpC);
+ KviTalPopupMenu * windowPopup(){ return m_pWindowPopup; };
+ void focusTopChild();
+ void destroyChild(KviMdiChild *lpC,bool bFocusTopChild = true);
+ int getVisibleChildCount();
+ bool isInSDIMode();
+protected:
+ KviPointerList<KviMdiChild> * m_pZ; // topmost child is the last in the list
+
+ KviMenuBarToolButton * m_pSdiRestoreButton;
+ KviMenuBarToolButton * m_pSdiMinimizeButton;
+ KviMenuBarToolButton * m_pSdiCloseButton;
+ KviMenuBarToolButton * m_pSdiIconButton;
+
+#ifdef COMPILE_USE_QT4
+ KviTalHBox * m_pSdiControls;
+#endif
+ int m_iSdiIconItemId;
+ int m_iSdiRestoreItemId;
+ int m_iSdiMinimizeItemId;
+ int m_iSdiCloseItemId;
+
+ KviTalPopupMenu * m_pWindowPopup;
+ KviTalPopupMenu * m_pTileMethodPopup;
+ KviFrame * m_pFrm;
+protected:
+ void updateContentsSize();
+ //void childMaximized(KviMdiChild *lpC);
+ void childMinimized(KviMdiChild *lpC,bool bWasMaximized);
+ void childRestored(KviMdiChild *lpC,bool bWasMaximized);
+ void childMoved(KviMdiChild * lpC);
+ void maximizeChild(KviMdiChild * lpC);
+ virtual void focusInEvent(QFocusEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void drawContents(QPainter * p,int x,int y,int w,int h);
+ virtual bool focusNextPrevChild(bool pNext);
+public slots:
+ void relayoutMenuButtons();
+ void cascadeWindows();
+ void cascadeMaximized();
+ void expandVertical();
+ void expandHorizontal();
+ void minimizeAll();
+// void restoreAll(); <-- this does nothing
+ void tile();
+ void toggleAutoTile();
+
+ void tileAnodine();
+ void reloadImages();
+protected slots:
+ void minimizeActiveChild();
+ void restoreActiveChild();
+ void closeActiveChild();
+ void activeChildSystemPopup();
+ void menuActivated(int id);
+ void tileMethodMenuActivated(int id);
+ void fillWindowPopup();
+ void sdiMinimizeButtonDestroyed();
+ void sdiRestoreButtonDestroyed();
+ void sdiCloseButtonDestroyed();
+ void sdiIconButtonDestroyed();
+private:
+ void ensureNoMaximized();
+ void tileAllInternal(int maxWnds,bool bHorizontal);
+ QPoint getCascadePoint(int indexOfWindow);
+ void enterSDIMode(KviMdiChild *lpC);
+ void leaveSDIMode();
+ void updateSDIMode();
+signals:
+ void enteredSdiMode();
+ void leftSdiMode();
+};
+
+#endif //_KVI_MDIMANAGER_H_
diff --git a/src/kvirc/ui/kvi_menubar.cpp b/src/kvirc/ui/kvi_menubar.cpp
new file mode 100644
index 0000000..a382f73
--- /dev/null
+++ b/src/kvirc/ui/kvi_menubar.cpp
@@ -0,0 +1,415 @@
+//=============================================================================
+//
+// File : kvi_menubar.cpp
+// Creation date : Wen Jun 21 2000 13:12:11 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2005 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#include "kvi_menubar.h"
+#include "kvi_app.h"
+#include "kvi_locale.h"
+#include "kvi_frame.h"
+#include "kvi_mdimanager.h"
+#include "kvi_iconmanager.h"
+#include "kvi_internalcmd.h"
+#include "kvi_settings.h"
+#include "kvi_ircurl.h"
+#include "kvi_console.h"
+#include "kvi_kvs_popupmenu.h"
+#include "kvi_malloc.h"
+#include "kvi_moduleextension.h"
+#include "kvi_actionmanager.h"
+#include "kvi_coreactionnames.h"
+#include "kvi_kvs_script.h"
+
+#include "kvi_tal_popupmenu.h"
+
+KviMenuBar::KviMenuBar(KviFrame * par,const char * name)
+ : KviTalMenuBar(par,name)
+{
+ m_pFrm = par;
+
+ m_iNumDefaultItems = 0;
+ m_pDefaultItemId = 0;
+
+ KviTalPopupMenu * pop = new KviTalPopupMenu(this,"KVIrc");
+ connect(pop,SIGNAL(aboutToShow()),this,SLOT(setupMainPopup()));
+#ifndef Q_OS_MACX
+ addDefaultItem("&KVIrc",pop);
+#else
+ // Qt/Mac creates already a "KVirc" menu item on its own, and we don't like double entries ;-)
+ addDefaultItem("&IRC",pop);
+#endif //Q_OS_MACX
+ m_pRecentServersPopup = new KviTalPopupMenu(this,"recentservers");
+ connect(m_pRecentServersPopup,SIGNAL(aboutToShow()),this,SLOT(setupRecentServersPopup()));
+ connect(m_pRecentServersPopup,SIGNAL(activated(int)),this,SLOT(newConnectionToServer(int)));
+
+ m_pScriptItemList = 0;
+
+ pop = new KviTalPopupMenu(this,"scripting");
+ connect(pop,SIGNAL(aboutToShow()),this,SLOT(setupScriptingPopup()));
+ addDefaultItem(__tr2qs("Scri&pting"),pop);
+
+ pop = new KviTalPopupMenu(this,"tools");
+ connect(pop,SIGNAL(aboutToShow()),this,SLOT(setupToolsPopup()));
+ connect(pop,SIGNAL(activated(int)),this,SLOT(toolsPopupSelected(int)));
+ addDefaultItem(__tr2qs("&Tools"),pop);
+
+ m_pToolbarsPopup = new KviTalPopupMenu(this,"toolbars");
+ connect(m_pToolbarsPopup,SIGNAL(aboutToShow()),this,SLOT(setupToolbarsPopup()));
+
+ pop = new KviTalPopupMenu(this,"settings");
+ connect(pop,SIGNAL(aboutToShow()),this,SLOT(setupSettingsPopup()));
+ addDefaultItem(__tr2qs("&Settings"),pop);
+
+ addDefaultItem(__tr2qs("&Window"),par->mdiManager()->windowPopup());
+
+ pop = new KviTalPopupMenu(this,"help");
+ connect(pop,SIGNAL(aboutToShow()),this,SLOT(setupHelpPopup()));
+ addDefaultItem(__tr2qs("&Help"),pop);
+}
+
+KviMenuBar::~KviMenuBar()
+{
+ if(m_pScriptItemList)delete m_pScriptItemList;
+ if(m_pDefaultItemId)kvi_free(m_pDefaultItemId);
+}
+
+void KviMenuBar::showEvent(QShowEvent *e)
+{
+#ifdef COMPILE_USE_QT4
+ debug("menubar show");
+ // force a re-layout of the menubar in Qt4 (see the note in enterSDIMode())
+ // by resetting the corner widget
+ m_pFrm->mdiManager()->relayoutMenuButtons();
+#endif
+}
+
+void KviMenuBar::addDefaultItem(const QString &text,KviTalPopupMenu * pop)
+{
+ m_iNumDefaultItems++;
+ m_pDefaultItemId = (int *)kvi_realloc((void *)m_pDefaultItemId,sizeof(int) * m_iNumDefaultItems);
+ m_pDefaultItemId[m_iNumDefaultItems - 1] = insertItem(text,pop);
+}
+
+void KviMenuBar::setupHelpPopup()
+{
+ KviTalPopupMenu * help = (KviTalPopupMenu *)sender();
+ help->clear();
+
+ // FIXME: Convert these to actions!
+ int id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_HELP)),__tr2qs("&Help Browser (Panel)"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_HELP_NEWSTATICWINDOW);
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MDIHELP)),__tr2qs("Help Browser (&Window)"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_HELP_NEWMDIWINDOW);
+ help->insertSeparator();
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_IDEA)),__tr2qs("&Tip of the Day"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_TIP_OPEN);
+ help->insertSeparator();
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)),__tr2qs("About &KVIrc"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_ABOUT_ABOUTKVIRC);
+ help->insertSeparator();
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_HOMEPAGE)),__tr2qs("KVIrc Home&page"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_KVIRC_HOMEPAGE);
+ if(kvi_strEqualCIN(KviLocale::localeName(),"ru",2))
+ {
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_HOMEPAGE)),__tr2qs("KVIrc Russian Home&page"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_KVIRC_HOMEPAGE_RU);
+ }
+ if(kvi_strEqualCIN(KviLocale::localeName(),"fr",2))
+ {
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_HOMEPAGE)),__tr2qs("KVIrc French Home&page"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_KVIRC_HOMEPAGE_FR);
+ }
+ help->insertSeparator();
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MESSAGE)),__tr2qs("Subscribe to the Mailing List"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_OPENURL_KVIRC_MAILINGLIST);
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_BOMB)),__tr2qs("Report a Bug / Propose Improvements"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_OPENURL_KVIRC_BUGTRACK);
+ help->insertSeparator();
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)),__tr2qs("Join KVIrc International Channel on Freenode"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_OPENURL_KVIRC_ON_FREENODE);
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)),__tr2qs("Join KVIrc International Channel on IRCNet"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_OPENURL_KVIRC_ON_IRCNET);
+ if(kvi_strEqualCIN(KviLocale::localeName(),"it",2))
+ {
+ // join #kvirc.net on azzurra
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)),__tr2qs("Join KVIrc Italian Channel on AzzurraNet"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_OPENURL_KVIRC_IT_ON_AZZURRA);
+ }
+ if(kvi_strEqualCIN(KviLocale::localeName(),"fr",2))
+ {
+ // join #kvirc-fr on freenode
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)),__tr2qs("Join KVIrc French Channel on Freenode"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_OPENURL_KVIRC_FR_ON_FREENODE);
+ // join #kvirc on europnet
+ id = help->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)),__tr2qs("Join KVIrc French Channel on EuropNet"),m_pFrm,SLOT(executeInternalCommand(int)));
+ help->setItemParameter(id,KVI_INTERNALCOMMAND_OPENURL_KVIRC_FR_ON_EUROPNET);
+ }
+ // add your localized #kvirc channels here...
+}
+
+void KviMenuBar::setupSettingsPopup()
+{
+ // FIXME: Move everything to actions!
+
+ KviTalPopupMenu * opt = (KviTalPopupMenu *)sender();
+ opt->clear();
+
+ opt->insertItem(__tr2qs("Toolbars"),m_pToolbarsPopup);
+
+ int id = opt->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_STATUSBAR)),__tr2qs("Show StatusBar"),m_pFrm,SLOT(toggleStatusBar()));
+ opt->setItemChecked(id,m_pFrm->mainStatusBar());
+
+
+ opt->insertSeparator();
+ // FIXME: #warning "Toggle these items on the fly ?"
+ ACTION_POPUP_ITEM(KVI_COREACTION_GENERALOPTIONS,opt)
+ ACTION_POPUP_ITEM(KVI_COREACTION_THEMEOPTIONS,opt)
+ ACTION_POPUP_ITEM(KVI_COREACTION_MANAGETHEMES,opt)
+ ACTION_POPUP_ITEM(KVI_COREACTION_MANAGEADDONS,opt)
+ ACTION_POPUP_ITEM(KVI_COREACTION_SERVEROPTIONS,opt)
+ ACTION_POPUP_ITEM(KVI_COREACTION_TOOLBAREDITOR,opt)
+ ACTION_POPUP_ITEM(KVI_COREACTION_EDITREGUSERS,opt)
+
+ opt->insertSeparator();
+ opt->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_FLOPPY)),__tr2qs("&Save Configuration"),g_pApp,SLOT(saveConfiguration()));
+}
+
+void KviMenuBar::setupScriptingPopup()
+{
+ KviTalPopupMenu * script = (KviTalPopupMenu *)sender();
+ script->clear();
+
+ ACTION_POPUP_ITEM(KVI_COREACTION_ACTIONEDITOR,script)
+ ACTION_POPUP_ITEM(KVI_COREACTION_ALIASEDITOR,script)
+ ACTION_POPUP_ITEM(KVI_COREACTION_EVENTEDITOR,script)
+ ACTION_POPUP_ITEM(KVI_COREACTION_POPUPEDITOR,script)
+ ACTION_POPUP_ITEM(KVI_COREACTION_RAWEDITOR,script)
+ script->insertSeparator();
+ ACTION_POPUP_ITEM(KVI_COREACTION_CODETESTER,script)
+ script->insertSeparator();
+ ACTION_POPUP_ITEM(KVI_COREACTION_EXECUTEKVS,script)
+
+ script->insertSeparator();
+ script->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TEXTEXCLAMATIVE)),__tr2qs("Restore &Default Script"),g_pApp,SLOT(restoreDefaultScript()));
+}
+
+void KviMenuBar::setupMainPopup()
+{
+ KviTalPopupMenu * main = (KviTalPopupMenu *)sender();
+ main->clear();
+
+ ACTION_POPUP_ITEM(KVI_COREACTION_NEWIRCCONTEXT,main)
+ if(m_pFrm->activeContext())
+ if(m_pFrm->activeContext()->state()==KviIrcContext::Connected)
+ {
+ int id = main->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs("Disconnect"),m_pFrm,SLOT(executeInternalCommand(int)));
+ main->setItemParameter(id,KVI_INTERNALCOMMAND_QUIT);
+ }
+ main->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_WORLD)),__tr2qs("New &Connection To"),m_pRecentServersPopup);
+
+ main->insertSeparator();
+
+ if(m_pFrm->dockExtension())
+ {
+ int id = main->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DOCKWIDGET)),__tr2qs("Hide &Dock Icon"),m_pFrm,SLOT(executeInternalCommand(int)));
+ main->setItemParameter(id,KVI_INTERNALCOMMAND_DOCKWIDGET_HIDE);
+ } else {
+ int id = main->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DOCKWIDGET)),__tr2qs("Show &Dock Icon"),m_pFrm,SLOT(executeInternalCommand(int)));
+ main->setItemParameter(id,KVI_INTERNALCOMMAND_DOCKWIDGET_SHOW);
+ }
+
+// Qt/Mac creates a Quit item on its own
+#ifndef Q_OS_MACX
+ main->insertSeparator();
+
+ main->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUITAPP)),__tr2qs("&Quit"),g_pApp,SLOT(quit()));
+#endif //Q_OS_MACX
+}
+
+
+void KviMenuBar::setupRecentServersPopup()
+{
+ KviTalPopupMenu * m = (KviTalPopupMenu *)sender();
+ g_pApp->fillRecentServersPopup(m);
+ m->insertSeparator();
+ m->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVER)),__tr2qs("&Other..."));
+}
+
+void KviMenuBar::newConnectionToServer(int id)
+{
+ QString text = m_pRecentServersPopup->text(id);
+ if(!text.isEmpty())
+ {
+ // the gentoo qt 3.3.4-r2 is broken
+ // since it adds random & characters to the popup texts...
+ if(text == __tr2qs("&Other..."))
+ {
+ KviKvsScript::run("options.edit KviServerOptionsWidget",m_pFrm->firstConsole());
+ } else {
+ text.replace(QString("&"),QString(""));
+ KviStr szCommand;
+ if(KviIrcUrl::parse(text.utf8().data(),szCommand,KVI_IRCURL_CONTEXT_NEW))
+ KviKvsScript::run(szCommand.ptr(),m_pFrm->firstConsole());
+ }
+ }
+}
+
+void KviMenuBar::setupToolsPopup()
+{
+ KviTalPopupMenu * m = (KviTalPopupMenu *)sender();
+ if(!m)return;
+
+ m->clear();
+
+ KviModuleExtensionDescriptorList * l = g_pModuleExtensionManager->getExtensionList("tool");
+ if(l)
+ {
+ for(KviModuleExtensionDescriptor * d = l->first();d;d = l->next())
+ {
+ int id;
+ if(d->icon())id = m->insertItem(*(d->icon()),d->visibleName());
+ else id = m->insertItem(d->visibleName());
+ //m->setItemChecked(id,(m_pFrm->moduleExtensionToolBar(d->id())));
+ m->setItemParameter(id,d->id());
+ }
+ }
+ m->insertSeparator();
+ ACTION_POPUP_ITEM(KVI_COREACTION_SOCKETSPY,m)
+ ACTION_POPUP_ITEM(KVI_COREACTION_NETWORKLINKS,m)
+ ACTION_POPUP_ITEM(KVI_COREACTION_CHANNELLIST,m)
+ m->insertSeparator();
+
+ ACTION_POPUP_ITEM(KVI_COREACTION_SCREENSHOT,m)
+
+ // moved the old tools here
+ m->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ICONMANAGER)),__tr2qs("Show &Icon Table"),g_pIconManager,SLOT(showIconWidget()));
+#ifdef COMPILE_KDE_SUPPORT
+ int id;
+ id = m->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TERMINAL)),__tr2qs("Open &Terminal"),m_pFrm,SLOT(executeInternalCommand(int)));
+ m->setItemParameter(id,KVI_INTERNALCOMMAND_TERM_OPEN);
+#endif
+
+
+ KviPointerList<KviAction> list;
+ KviActionManager::instance()->listActionsByCategory("tools",&list);
+ if(!list.isEmpty())
+ {
+ m->insertSeparator();
+ for(KviAction * ac = list.first();ac;ac = list.next())
+ ac->addToPopupMenu(m);
+ }
+}
+
+void KviMenuBar::toolsPopupSelected(int id)
+{
+ KviTalPopupMenu * m = (KviTalPopupMenu *)sender();
+ if(!m)return;
+ int idext = m->itemParameter(id);
+ g_pModuleExtensionManager->allocateExtension("tool",idext,m_pFrm->firstConsole());
+}
+
+
+void KviMenuBar::setupToolbarsPopup()
+{
+ m_pFrm->fillToolBarsPopup(m_pToolbarsPopup);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Script items
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+int KviMenuBar::getDefaultItemRealIndex(int iDefaultIndex)
+{
+ if(iDefaultIndex < 0)iDefaultIndex = 0;
+ if(iDefaultIndex >= m_iNumDefaultItems)
+ return indexOf(m_pDefaultItemId[m_iNumDefaultItems - 1]) + 1;
+ return indexOf(m_pDefaultItemId[iDefaultIndex]);
+}
+
+KviScriptMenuBarItem * KviMenuBar::findMenu(const QString &text)
+{
+ if(!m_pScriptItemList)return 0;
+ for(KviScriptMenuBarItem * i = m_pScriptItemList->first();i;i = m_pScriptItemList->next())
+ {
+ if(KviQString::equalCI(i->szText,text))return i;
+ }
+ return 0;
+}
+
+KviScriptMenuBarItem * KviMenuBar::findMenu(KviKvsPopupMenu * p)
+{
+ if(!m_pScriptItemList)return 0;
+ for(KviScriptMenuBarItem * i = m_pScriptItemList->first();i;i = m_pScriptItemList->next())
+ {
+ if(i->pPopup == p)return i;
+ }
+ return 0;
+}
+
+bool KviMenuBar::removeMenu(const QString &text)
+{
+ KviScriptMenuBarItem * i = findMenu(text);
+ if(i)
+ {
+ disconnect(i->pPopup,SIGNAL(destroyed()),this,SLOT(menuDestroyed()));
+ removeItem(i->id);
+ m_pScriptItemList->removeRef(i);
+ return true;
+ }
+ return false;
+}
+
+void KviMenuBar::menuDestroyed()
+{
+ KviScriptMenuBarItem * i = findMenu(((KviKvsPopupMenu *)sender()));
+ if(i)
+ {
+ removeItem(i->id);
+ m_pScriptItemList->removeRef(i);
+ }
+}
+
+void KviMenuBar::addMenu(const QString &text,KviKvsPopupMenu * p,int index)
+{
+ if(!m_pScriptItemList)
+ {
+ m_pScriptItemList = new KviPointerList<KviScriptMenuBarItem>;
+ m_pScriptItemList->setAutoDelete(true);
+ }/* else {
+ removeMenu(text);
+ }*/
+ KviScriptMenuBarItem * it = new KviScriptMenuBarItem;
+ it->szText = text;
+ it->szPopupName = p->name();
+ it->pPopup = p;
+ it->id = insertItem(text,p,-1,index);
+ connect(p,SIGNAL(destroyed()),this,SLOT(menuDestroyed()));
+ m_pScriptItemList->append(it);
+}
+
+#include "kvi_menubar.moc"
diff --git a/src/kvirc/ui/kvi_menubar.h b/src/kvirc/ui/kvi_menubar.h
new file mode 100644
index 0000000..3095913
--- /dev/null
+++ b/src/kvirc/ui/kvi_menubar.h
@@ -0,0 +1,83 @@
+#ifndef _KVI_MENUBAR_H_
+#define _KVI_MENUBAR_H_
+
+//=============================================================================
+//
+// File : kvi_menubar.h
+// Creation date : Wen Jun 21 2000 13:11:24 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2005 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+#include "kvi_tal_menubar.h"
+#include "kvi_string.h"
+
+#include "kvi_pointerlist.h"
+
+class KviFrame;
+class KviTalPopupMenu;
+class KviKvsPopupMenu;
+
+typedef struct _KviScriptMenuBarItem
+{
+ int id;
+ KviStr szPopupName;
+ KviKvsPopupMenu * pPopup;
+ KviStr szText;
+} KviScriptMenuBarItem;
+
+
+class KVIRC_API KviMenuBar : public KviTalMenuBar
+{
+ Q_OBJECT
+public:
+ KviMenuBar(KviFrame * par,const char * name);
+ ~KviMenuBar();
+protected:
+ KviTalPopupMenu * m_pToolbarsPopup;
+ KviTalPopupMenu * m_pRecentServersPopup;
+ KviFrame * m_pFrm;
+ KviPointerList<KviScriptMenuBarItem> * m_pScriptItemList;
+ int m_iNumDefaultItems;
+ int * m_pDefaultItemId;
+protected:
+ KviScriptMenuBarItem * findMenu(const QString &text);
+ KviScriptMenuBarItem * findMenu(KviKvsPopupMenu * p);
+ void addDefaultItem(const QString &text,KviTalPopupMenu * pop);
+ virtual void showEvent(QShowEvent *e);
+public:
+ int getDefaultItemRealIndex(int iDefaultIndex);
+ void addMenu(const QString &text,KviKvsPopupMenu * p,int index);
+ bool removeMenu(const QString &text);
+protected slots:
+ void menuDestroyed();
+ void setupMainPopup();
+ void setupSettingsPopup();
+ void setupHelpPopup();
+ void setupRecentServersPopup();
+ void setupScriptingPopup();
+ void newConnectionToServer(int id);
+ void setupToolbarsPopup();
+ void setupToolsPopup();
+ void toolsPopupSelected(int id);
+};
+
+#endif //_KVI_MENUBAR_H_
diff --git a/src/kvirc/ui/kvi_modeeditor.cpp b/src/kvirc/ui/kvi_modeeditor.cpp
new file mode 100644
index 0000000..f72d0a2
--- /dev/null
+++ b/src/kvirc/ui/kvi_modeeditor.cpp
@@ -0,0 +1,336 @@
+//
+// File : kvi_modeeditor.cpp
+// Creation date : Sat Apr 14 2001 13:52:11 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVIRC__
+#include "kvi_modeeditor.h"
+#include "kvi_iconmanager.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+#include "kvi_console.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionserverinfo.h"
+#include "kvi_channel.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_styled_controls.h"
+#include "kvi_toolwindows_container.h"
+#include "kvi_tal_scrollview.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+
+
+//////////////////////////////////////////////////////////////////////
+// class KviModeEditor
+//
+//////////////////////////////////////////////////////////////////////
+
+//static char checkable_modes_table[KVI_NUM_CHECKABLE_MODES] = { 'p','s','t','n','m','i'};
+
+// FIXME: This widget should use a KviTalScrollView!
+
+KviModeEditor::KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const char * nam,KviConsole * c,const char * mode,const char * key,const char * limit)
+: KviWindowToolWidget(par,button)
+{
+ m_szMode = mode;
+ m_szKey = key;
+ m_szLimit = limit;
+ bool isEnabled=1;
+
+ QObject * w = parent();
+ while(w)
+ {
+ if(w->inherits("KviChannel"))
+ {
+ KviChannel *chan = ((KviChannel *)w);
+ if(!( chan->isMeHalfOp() || chan->isMeOp() || chan->isMeChanOwner() || chan->isMeChanAdmin() || chan->connection()->userInfo()->hasUserMode('o') || chan->connection()->userInfo()->hasUserMode('O') ) ) isEnabled=0;
+ break;
+ }
+ w = w->parent();
+ }
+
+ QGridLayout *pMasterLayout = new QGridLayout(this,2,1,2,2);
+
+#ifdef COMPILE_USE_QT4
+ setFocusPolicy(Qt::ClickFocus);
+#else
+ setFocusPolicy(QWidget::ClickFocus);
+#endif
+
+ KviTalScrollView *pScrollView = new KviTalScrollView(this);
+#ifdef COMPILE_USE_QT4
+ pScrollView->viewport()->setBackgroundRole(QPalette::Background);
+#else
+ pScrollView->viewport()->setBackgroundMode(QWidget::PaletteBackground);
+#endif
+
+ pMasterLayout->addWidget(pScrollView,0,0);
+
+ pMasterLayout->setRowStretch(1,1);
+ QPushButton * b;
+ if(isEnabled) b = new QPushButton(__tr2qs("&Apply"),this);
+ else b = new QPushButton(__tr2qs("Close"),this);
+
+ pMasterLayout->addWidget(b,1,0);
+ connect(b,SIGNAL(clicked()),this,SLOT(commit()));
+
+ QWidget * pBackground = new QWidget(pScrollView->viewport());
+
+ QGridLayout *g = new QGridLayout(pBackground,20,3,2,2);
+
+ QLabel * l = new QLabel("",pBackground);
+ l->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MODE)));
+ g->addWidget(l,0,0);
+
+ l = new QLabel(__tr2qs("Channel Modes"),pBackground);
+ g->addMultiCellWidget(l,0,0,1,2);
+
+ QFrame * f = new QFrame(pBackground);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ g->addMultiCellWidget(f,1,1,0,2);
+
+ int i = 1;
+ QString tmp;
+
+ m_pCheckBoxes = new KviPointerList<KviStyledCheckBox>;
+ m_pCheckBoxes->setAutoDelete(false);
+
+
+ // first che basic checkable modes pstnmi
+ QString szModes = "pstnmi";
+
+ while(!szModes.isEmpty())
+ {
+ QChar ccc = szModes[0];
+ szModes.remove(0,1);
+
+ KviQString::sprintf(tmp,"%c: %Q",ccc.unicode(),&(c->connection()->serverInfo()->getChannelModeDescription(ccc)));
+ KviStyledCheckBox * cb = new KviStyledCheckBox(tmp,pBackground);
+ cb->setEnabled(isEnabled);
+ m_pCheckBoxes->append(cb);
+ cb->setChecked(m_szMode.contains((char)ccc.unicode()));
+ i++;
+ g->addMultiCellWidget(cb,i,i,0,2);
+ }
+
+ KviQString::sprintf(tmp,"l: %Q",&(c->connection()->serverInfo()->getChannelModeDescription('l')));
+ m_pLimitBox = new KviStyledCheckBox(tmp,pBackground);
+ m_pLimitBox->setEnabled(isEnabled);
+ i++;
+ g->addMultiCellWidget(m_pLimitBox,i,i,0,2);
+ connect(m_pLimitBox,SIGNAL(toggled(bool)),this,SLOT(limitBoxToggled(bool)));
+ m_pLimitEdit = new QLineEdit(pBackground);
+ m_pLimitEdit->setEnabled(isEnabled);
+ i++;
+ g->addMultiCellWidget(m_pLimitEdit,i,i,1,2);
+ if(m_szLimit.hasData())
+ {
+ m_pLimitBox->setChecked(true);
+// m_pLimitEdit->setEnabled(true);
+ m_pLimitEdit->setText(m_szLimit.ptr());
+ } else {
+ m_pLimitEdit->setEnabled(false);
+ }
+
+ KviQString::sprintf(tmp,"k: %Q",&(c->connection()->serverInfo()->getChannelModeDescription('k')));
+ m_pKeyBox = new KviStyledCheckBox(tmp,pBackground);
+ m_pKeyBox->setEnabled(isEnabled);
+ i++;
+ g->addMultiCellWidget(m_pKeyBox,i,i,0,2);
+ connect(m_pKeyBox,SIGNAL(toggled(bool)),this,SLOT(keyBoxToggled(bool)));
+ m_pKeyEdit = new QLineEdit(pBackground);
+ m_pKeyEdit->setEnabled(isEnabled);
+ i++;
+ g->addMultiCellWidget(m_pKeyEdit,i,i,1,2);
+ if(m_szKey.hasData())
+ {
+ m_pKeyBox->setChecked(true);
+// m_pLimitEdit->setEnabled(true);
+ m_pKeyEdit->setText(m_szKey.ptr());
+ } else {
+ m_pKeyEdit->setEnabled(false);
+ }
+
+ if(c->connection())
+ {
+ if(c->connection()->serverInfo())
+ szModes = c->connection()->serverInfo()->supportedChannelModes();
+ }
+
+ int idx = szModes.findRev(',');
+ if(idx != -1)szModes.remove(0,idx+1);
+
+ szModes.replace("p","");
+ szModes.replace("s","");
+ szModes.replace("t","");
+ szModes.replace("n","");
+ szModes.replace("m","");
+ szModes.replace("i","");
+ szModes.replace(",","");
+ szModes.replace("b","");
+ szModes.replace("k","");
+ szModes.replace("l","");
+
+ while(!szModes.isEmpty())
+ {
+ QChar ccc = szModes[0];
+ szModes.remove(0,1);
+
+ KviQString::sprintf(tmp,"%c: %Q",(char)ccc.unicode(),&(c->connection()->serverInfo()->getChannelModeDescription(ccc)));
+ KviStyledCheckBox * cb = new KviStyledCheckBox(tmp,pBackground);
+ cb->setEnabled(isEnabled);
+ m_pCheckBoxes->append(cb);
+ cb->setChecked(m_szMode.contains((char)ccc.unicode()));
+ i++;
+ g->addMultiCellWidget(cb,i,i,0,2);
+ }
+
+ i++;
+
+ g->setRowStretch(i,1);
+ g->setColStretch(2,1);
+
+ pScrollView->addChild(pBackground,0,0);
+ registerSelf();
+}
+
+KviModeEditor::~KviModeEditor()
+{
+ delete m_pCheckBoxes;
+}
+
+void KviModeEditor::limitBoxToggled(bool bChecked)
+{
+ m_pLimitEdit->setEnabled(bChecked);
+}
+
+void KviModeEditor::keyBoxToggled(bool bChecked)
+{
+ m_pKeyEdit->setEnabled(bChecked);
+}
+
+void KviModeEditor::commit()
+{
+ KviStr szPlusModes;
+ KviStr szMinusModes;
+
+ if(m_szKey.hasData())
+ {
+ // had a key before
+ if(m_pKeyBox->isChecked())
+ {
+ // still have it
+ KviStr tmp = m_pKeyEdit->text();
+ tmp.stripWhiteSpace();
+ if(tmp.hasData())
+ {
+ if(!kvi_strEqualCI(tmp.ptr(),m_szKey.ptr()))
+ {
+ // not the same key!
+ // set the new one
+ KviStr mode(KviStr::Format,"-k %s",m_szKey.ptr());
+ emit setMode(mode.ptr());
+ mode.sprintf("+k %s",tmp.ptr());
+ emit setMode(mode.ptr());
+ }
+ }
+ } else {
+ // no key now! reset
+ KviStr mode(KviStr::Format,"-k %s",m_szKey.ptr());
+ emit setMode(mode.ptr());
+ }
+ } else {
+ // there was no key before
+ if(m_pKeyBox->isChecked())
+ {
+ KviStr tmp = m_pKeyEdit->text();
+ tmp.stripWhiteSpace();
+ if(tmp.hasData())
+ {
+ // new key to be set
+ KviStr mode(KviStr::Format,"+k %s",tmp.ptr());
+ emit setMode(mode.ptr());
+ }
+ }
+ }
+
+ if(m_szLimit.hasData())
+ {
+ // had a limit before
+ if(m_pLimitBox->isChecked())
+ {
+ // still have it
+ KviStr tmp = m_pLimitEdit->text();
+ tmp.stripWhiteSpace();
+ if(tmp.hasData() && tmp.isUnsignedNum())
+ {
+ if(!kvi_strEqualCI(tmp.ptr(),m_szLimit.ptr()))
+ {
+ // not the same limit!
+ KviStr mode(KviStr::Format,"+l %s",tmp.ptr());
+ emit setMode(mode.ptr());
+ }
+ }
+ } else {
+ // no limit now! reset
+ szMinusModes.append('l');
+ }
+ } else {
+ // there was no limit before
+ if(m_pLimitBox->isChecked())
+ {
+ KviStr tmp = m_pLimitEdit->text();
+ tmp.stripWhiteSpace();
+ if(tmp.hasData() && tmp.isUnsignedNum())
+ {
+ // new limit to be set
+ KviStr mode(KviStr::Format,"+l %s",tmp.ptr());
+ emit setMode(mode.ptr());
+ }
+ }
+ }
+
+
+ for(KviStyledCheckBox * cb = m_pCheckBoxes->first();cb;cb = m_pCheckBoxes->next())
+ {
+ QString sz = cb->text();
+ sz.replace("&","");
+ if(sz.length() > 0)
+ {
+ QChar ccc = sz[0];
+ if(cb->isChecked())
+ {
+ if(!m_szMode.contains((char)ccc.unicode()))szPlusModes.append((char)ccc.unicode());
+ } else {
+ if(m_szMode.contains((char)ccc.unicode()))szMinusModes.append((char)ccc.unicode());
+ }
+ }
+ }
+
+ KviStr szModes;
+
+ if(szMinusModes.hasData())szModes.sprintf("-%s",szMinusModes.ptr());
+ if(szPlusModes.hasData())szModes.append(KviStr::Format,"+%s",szPlusModes.ptr());
+ if(szModes.hasData())emit setMode(szModes.ptr());
+
+ emit done();
+}
+
+#include "kvi_modeeditor.moc"
diff --git a/src/kvirc/ui/kvi_modeeditor.h b/src/kvirc/ui/kvi_modeeditor.h
new file mode 100644
index 0000000..06512d9
--- /dev/null
+++ b/src/kvirc/ui/kvi_modeeditor.h
@@ -0,0 +1,70 @@
+#ifndef _KVI_MODEEDITOR_H_
+#define _KVI_MODEEDITOR_H_
+
+//
+// File : kvi_modeeditor.h
+// Creation date : Sat Apr 14 2001 13:50:12 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+
+#include <qwidget.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+
+#include "kvi_string.h"
+#include "kvi_pointerlist.h"
+#include "kvi_styled_controls.h"
+#include "kvi_toolwindows_container.h"
+
+class KviConsole;
+
+//////////////////////////////////////////////////////////////////////
+// class KviModeEditor
+//
+//////////////////////////////////////////////////////////////////////
+
+class KVIRC_API KviModeEditor : public KviWindowToolWidget
+{
+ Q_OBJECT
+public:
+ KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const char * nam,KviConsole * c,const char * mode,const char * key,const char * limit);
+ ~KviModeEditor();
+protected: // fields
+ KviStr m_szMode;
+ KviStr m_szKey;
+ KviStr m_szLimit;
+ KviPointerList<KviStyledCheckBox> * m_pCheckBoxes;
+ KviStyledCheckBox * m_pLimitBox;
+ QLineEdit * m_pLimitEdit;
+ KviStyledCheckBox * m_pKeyBox;
+ QLineEdit * m_pKeyEdit;
+signals:
+ void setMode(const char *);
+ void done();
+protected slots:
+ void limitBoxToggled(bool bChecked);
+ void keyBoxToggled(bool bChecked);
+ void commit();
+};
+
+#endif //_KVI_MODEEDITOR_H_
diff --git a/src/kvirc/ui/kvi_modew.cpp b/src/kvirc/ui/kvi_modew.cpp
new file mode 100755
index 0000000..a0cf85e
--- /dev/null
+++ b/src/kvirc/ui/kvi_modew.cpp
@@ -0,0 +1,175 @@
+//============================================================================
+//
+// File : kvi_modew.cpp
+// Creation date : 12.11.2005 23.50 by Uzhva Alexey
+//
+// This file is part of the KVirc irc client distribution
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//============================================================================
+#define __KVIRC__
+
+#include "kvi_themedlabel.h"
+#include "kvi_channel.h"
+#include "kvi_options.h"
+#include "kvi_ircconnectionserverinfo.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_qcstring.h"
+
+#include <qframe.h>
+#include <qlineedit.h>
+#include "kvi_tal_hbox.h"
+#include <qevent.h>
+
+KviModeWidget::KviModeWidget(QWidget * par,KviChannel* chan,const char * name)
+:QFrame(par,name)
+{
+ m_pChannel=chan;
+ m_pLabel=0;
+ m_pLineEdit=0;
+#ifdef COMPILE_USE_QT4
+ setAutoFillBackground(false);
+#else
+ setBackgroundMode(QWidget::NoBackground);
+#endif
+ reset();
+}
+
+KviModeWidget::~KviModeWidget()
+{
+}
+
+void KviModeWidget::reset()
+{
+ if(m_pLineEdit)
+ {
+ delete m_pLineEdit;
+ m_pLineEdit=0;
+ }
+ if(!m_pLabel)
+ m_pLabel=new KviThemedLabel(this,0);
+ refreshModes();
+ m_pLabel->show();
+ connect(m_pLabel,SIGNAL(doubleClicked()),this,SLOT(labelDoubleClick()));
+ QResizeEvent* ev=new QResizeEvent(size(),size());
+ resizeEvent(ev);
+ delete ev;
+ if(m_pChannel->input())
+ m_pChannel->setFocus();
+}
+
+void KviModeWidget::refreshModes()
+{
+ QString szMode=m_pChannel->channelMode();
+ if(!m_pChannel->channelKey().isEmpty())
+ szMode+=QString(" k:%1").arg(m_pChannel->channelKey());
+ if(!m_pChannel->channelLimit().isEmpty())
+ szMode+=QString(" l:%1").arg(m_pChannel->channelLimit().ptr());
+ if(m_pLabel)
+ m_pLabel->setText(szMode);
+}
+
+void KviModeWidget::applyOptions()
+{
+ if(m_pLabel)
+ m_pLabel->applyOptions();
+}
+
+void KviModeWidget::resizeEvent(QResizeEvent *e)
+{
+ if(e)QFrame::resizeEvent(e);
+ if(m_pLabel)
+ {
+ m_pLabel->setGeometry(0,0,width(),height());
+ }
+ if(m_pLineEdit)
+ {
+ m_pLineEdit->setGeometry(0,0,width(),height());
+ }
+}
+
+void KviModeWidget::labelDoubleClick()
+{
+ if(m_pLabel && ( m_pChannel->isMeHalfOp() || m_pChannel->isMeOp() || m_pChannel->isMeChanOwner() || m_pChannel->isMeChanAdmin() || m_pChannel->connection()->userInfo()->hasUserMode('o') || m_pChannel->connection()->userInfo()->hasUserMode('O')) )
+ {
+ delete m_pLabel;
+ m_pLabel=0;
+ m_pLineEdit = new QLineEdit(this,0);
+ m_pLineEdit->setText(m_pChannel->channelMode());
+ m_pLineEdit->show();
+ m_pLineEdit->setFocus();
+ resizeEvent(new QResizeEvent(size(),size()));
+ m_pLineEdit->installEventFilter( this );
+ connect(m_pLineEdit,SIGNAL(textChanged ( const QString & ) ),this,SLOT(editorTextChanged( const QString & )));
+ }
+}
+
+bool KviModeWidget::eventFilter( QObject *obj, QEvent *ev )
+{
+ if( (obj==m_pLineEdit) && ( ev->type() == QEvent::KeyPress ) )
+ {
+ QKeyEvent *keyEvent = (QKeyEvent*)ev;
+ switch(keyEvent->key())
+ {
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ editorReturnPressed();
+ return TRUE;
+ case Qt::Key_Escape:
+ reset();
+ return TRUE;
+ }
+ }
+ return QFrame::eventFilter( obj, ev );
+}
+
+void KviModeWidget::editorReturnPressed()
+{
+ QString szCurModes=m_pChannel->channelMode();
+ QString szNewModes=m_pLineEdit->text();
+ QString szMinusModes;
+ for(int i=0; i<szCurModes.length(); i++)
+ {
+ if(szNewModes.contains(szCurModes[i]))
+ szNewModes.remove(szCurModes[i]);
+ else
+ szMinusModes+=szCurModes[i];
+ }
+ QString mode;
+ if(!szMinusModes.isEmpty()) mode+=QString("-"+szMinusModes);
+ if(!szNewModes.isEmpty()) mode+=QString("+"+szNewModes);
+ if(!mode.isEmpty())
+ {
+ KviQCString chan = m_pChannel->connection()->encodeText(m_pChannel->name());
+ m_pChannel->connection()->sendFmtData("MODE %s %s",chan.data(),mode.utf8().data());
+ }
+ reset();
+}
+
+void KviModeWidget::editorTextChanged( const QString & text)
+{
+ int i = 0;
+ QString szText=text;
+ for(i=0;i<szText.length();i++)
+ {
+ if( !m_pChannel->connection()->serverInfo()->supportedPlainModes().contains(szText[i]) ||
+ szText.find(szText[i])<i )
+ szText.remove(i,1);
+ }
+ m_pLineEdit->setText(szText);
+}
+
+#include "kvi_modew.moc"
diff --git a/src/kvirc/ui/kvi_modew.h b/src/kvirc/ui/kvi_modew.h
new file mode 100755
index 0000000..7efbc96
--- /dev/null
+++ b/src/kvirc/ui/kvi_modew.h
@@ -0,0 +1,57 @@
+#ifndef _KVI_MODEW_H_
+#define _KVI_MODEW_H_
+
+//============================================================================
+//
+// File : kvi_modew.h
+// Creation date : 12.11.2005 23.50 by Uzhva Alexey
+//
+// This file is part of the KVirc irc client distribution
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//============================================================================
+
+#include "kvi_themedlabel.h"
+#include "kvi_channel.h"
+
+#include <qframe.h>
+#include <qlineedit.h>
+#include "kvi_tal_hbox.h"
+
+class KVIRC_API KviModeWidget : public QFrame
+{
+ Q_OBJECT
+
+public:
+ KviModeWidget(QWidget * par,KviChannel* chan,const char * name=0);
+ ~KviModeWidget();
+ void reset();
+ void refreshModes();
+ void applyOptions();
+private:
+ KviChannel * m_pChannel;
+ KviThemedLabel * m_pLabel;
+ QLineEdit * m_pLineEdit;
+protected:
+ void resizeEvent(QResizeEvent *e);
+ bool eventFilter( QObject *obj, QEvent *ev );
+public slots:
+ void labelDoubleClick();
+ void editorReturnPressed();
+ void editorTextChanged( const QString & );
+};
+
+#endif //_KVI_MODEW_H_
diff --git a/src/kvirc/ui/kvi_msgbox.cpp b/src/kvirc/ui/kvi_msgbox.cpp
new file mode 100644
index 0000000..81cea10
--- /dev/null
+++ b/src/kvirc/ui/kvi_msgbox.cpp
@@ -0,0 +1,89 @@
+//
+// File : kvi_msgbox.cpp
+// Creation date : Tue Jun 20 2000 12:49:41 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVIRC__
+#include "kvi_msgbox.h"
+
+// FIXME: #warning "This should go into TAL as layer ...then maybe a wrapper in KviApp!"
+
+#ifdef COMPILE_KDE_SUPPORT
+ #include <kmessagebox.h>
+#else
+ #include <qmessagebox.h>
+#endif //!COMPILE_WITH_KDE
+
+#include "kvi_malloc.h"
+#include "kvi_string.h"
+#include "kvi_locale.h"
+
+// FIXME: #warning "This could go into KviApp"
+
+namespace KviMessageBox
+{
+ void warning(const QString &fmt,...)
+ {
+ kvi_va_list list;
+ kvi_va_start_by_reference(list,fmt);
+ QString s;
+ KviQString::vsprintf(s,fmt,list);
+ kvi_va_end(list);
+#ifdef COMPILE_KDE_SUPPORT
+ KMessageBox::error(0,s,"KVIrc");
+#else
+ QMessageBox::warning(0,"KVIrc",s);
+#endif
+ }
+
+ void information(const QString &fmt,...)
+ {
+ kvi_va_list list;
+ kvi_va_start_by_reference(list,fmt);
+ QString s;
+ KviQString::vsprintf(s,fmt,list);
+ kvi_va_end(list);
+#ifdef COMPILE_KDE_SUPPORT
+ KMessageBox::information(0,s,"KVIrc");
+#else
+ QMessageBox::information(0,"KVIrc",s);
+#endif
+ }
+
+ bool yesNo(const QString &caption,const QString &fmt,...)
+ {
+ kvi_va_list list;
+ kvi_va_start_by_reference(list,fmt);
+ QString s;
+ KviQString::vsprintf(s,fmt,list);
+ kvi_va_end(list);
+ bool bRet;
+#ifdef COMPILE_KDE_SUPPORT
+ bRet = (KMessageBox::questionYesNo(0,s,caption) == KMessageBox::Yes);
+#else
+ bRet = (QMessageBox::information(0,caption,s,
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No | QMessageBox::Escape) == QMessageBox::Yes);
+#endif
+ return bRet;
+ }
+};
+
+
+
diff --git a/src/kvirc/ui/kvi_msgbox.h b/src/kvirc/ui/kvi_msgbox.h
new file mode 100644
index 0000000..71b22a2
--- /dev/null
+++ b/src/kvirc/ui/kvi_msgbox.h
@@ -0,0 +1,53 @@
+#ifndef _KVI_MSGBOX_H_
+#define _KVI_MSGBOX_H_
+
+//
+// File : kvi_msgbox.h
+// Creation date : Sun Jan 17 1999 13:55:41 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+#include "kvi_qstring.h"
+/*
+class KviMessageBox : public KviTalMessageBox
+{
+ enum Result { Yes , No , Ok , Cancel };
+ enum ButtonResult { Button1 , Button2 , Button3 };
+
+ KVIRC_API void warning(const char * fmt,...);
+ KVIRC_API void information(const char * fmt,...);
+
+ KVIRC_API Result yesNo(const char * fmt,...);
+ KVIRC_API Result yesNoCancel(const char * fmt,...);
+
+ KVIRC_API ButtonResult oneButton(const char * btnTxt,const char * fmt,...);
+ KVIRC_API ButtonResult twoButtons(const char * btnTxt1,const char * btnTxt2,const char * fmt,...);
+ KVIRC_API ButtonResult threeButtons(const char * btnTxt1,const char * btnTxt2,const char * btnTxt3,const char * fmt,...);
+};
+*/
+
+namespace KviMessageBox
+{
+ KVIRC_API void warning(const QString &fmt,...);
+ KVIRC_API void information(const QString &fmt,...);
+ KVIRC_API bool yesNo(const QString &caption,const QString &fmt,...);
+};
+
+#endif //!_KVI_MSGBOX_H_
diff --git a/src/kvirc/ui/kvi_optionswidget.cpp b/src/kvirc/ui/kvi_optionswidget.cpp
new file mode 100644
index 0000000..546d4b1
--- /dev/null
+++ b/src/kvirc/ui/kvi_optionswidget.cpp
@@ -0,0 +1,722 @@
+//=============================================================================
+//
+// File : kvi_optionswidget.h
+// Creation date : Mon Jun 10 2000 17:47:33 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2006 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_optionswidget.h"
+
+#define _WANT_OPTION_FLAGS_
+#include "kvi_options.h"
+
+#include "kvi_locale.h"
+
+#include "kvi_app.h"
+
+#include "kvi_tal_tooltip.h"
+
+#define KVI_OPTIONSWIDGET_GRIDLAYOUT_BORDER 4
+#define KVI_OPTIONSWIDGET_GRIDLAYOUT_SPACE 6
+
+QString KviOptionsWidget::m_szBasicTipStart; // empty decl
+QString KviOptionsWidget::m_szBasicTipEnd;
+
+KviOptionsWidget::KviOptionsWidget(QWidget * parent,const char * name,bool bSunken)
+: QFrame(parent,name), KviSelectorInterface()
+{
+ if(m_szBasicTipStart.isEmpty())
+ {
+ m_szBasicTipStart = "<center><font color=\"#a0a0a0\">";
+ m_szBasicTipStart += __tr2qs("This option is also available as");
+ m_szBasicTipStart += "<br><nobr>/option <b> ";
+ m_szBasicTipEnd = "</b></nobr></font></center>";
+
+ }
+ // FIXME: The bSunken value is ignored!
+ //if(bSunken)setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ //setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
+ m_pLayout = 0;
+ m_pTabWidget = 0;
+ m_iResetFlags = 0;
+ m_iSelectors = 0;
+ m_pSelectorInterfaceList = new KviPointerList<KviSelectorInterface>;
+ m_pSelectorInterfaceList->setAutoDelete(false);
+}
+
+KviOptionsWidget::~KviOptionsWidget()
+{
+ delete m_pSelectorInterfaceList;
+}
+
+void KviOptionsWidget::mergeTip(QWidget * w,const QString &tip)
+{
+ static QString begin = "<table width=\"100%\" align=\"center\"><tr><td bgcolor=\"#fefef0\">";
+ static QString mid = "</td></tr><tr><td>";
+ static QString end = "</td></tr></table>";
+#ifdef COMPILE_USE_QT4
+ QString s = w->toolTip();
+#else
+ QString s = KviTalToolTip::textFor(w);
+#endif
+ if(s.isEmpty())KviTalToolTip::add(w,tip);
+ else {
+ QString tmp = begin;
+ tmp += tip;
+ tmp += mid;
+ tmp += s;
+ tmp += end;
+ KviTalToolTip::add(w,tmp);
+ }
+}
+
+void KviOptionsWidget::createLayout(int rows,int cols)
+{
+ if(m_pLayout)delete m_pLayout;
+ m_pLayout = new QGridLayout(this,rows,cols,KVI_OPTIONSWIDGET_GRIDLAYOUT_BORDER,KVI_OPTIONSWIDGET_GRIDLAYOUT_SPACE);
+}
+
+void KviOptionsWidget::createTabbedPage()
+{
+ createLayout(1,1);
+ layout()->setMargin(0);
+ layout()->setSpacing(0);
+ m_pTabWidget = new QTabWidget(this);
+ addWidgetToLayout(m_pTabWidget,0,0,0,0);
+}
+
+void KviOptionsWidget::addOptionsWidget(const QString &szText,const QIconSet &iconSet,KviOptionsWidget * pWidget)
+{
+ if(pWidget->layout())
+ pWidget->layout()->setMargin(10);
+ m_pTabWidget->addTab(pWidget,iconSet,szText);
+ m_pSelectorInterfaceList->append(pWidget);
+}
+
+
+void KviOptionsWidget::addWidgetToLayout(QWidget * w,int x1,int y1,int x2,int y2)
+{
+ if((x1 == x2) && (y1 == y2))layout()->addWidget(w,y1,x1);
+ else layout()->addMultiCellWidget(w,y1,y2,x1,x2);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviDirectorySelector * KviOptionsWidget::addDirectorySelector(int x1,int y1,int x2,int y2,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviDirectorySelector * d = new KviDirectorySelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(d,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviDirectorySelector * KviOptionsWidget::addDirectorySelector(QWidget * pParent,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviDirectorySelector * d = new KviDirectorySelector(pParent,txt,pOption,bEnabled);
+ //addWidgetToLayout(d,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviDirectorySelector * KviOptionsWidget::addDirectorySelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviDirectorySelector * d = addDirectorySelector(x1,y1,x2,y2,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+
+ return d;
+}
+
+KviDirectorySelector * KviOptionsWidget::addDirectorySelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviDirectorySelector * d = addDirectorySelector(pParent,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+
+ return d;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviFileSelector * KviOptionsWidget::addFileSelector(int x1,int y1,int x2,int y2,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviFileSelector * d = new KviFileSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(d,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviFileSelector * KviOptionsWidget::addFileSelector(QWidget * pParent,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviFileSelector * d = new KviFileSelector(pParent,txt,pOption,bEnabled);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviFileSelector * KviOptionsWidget::addFileSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviFileSelector * d = addFileSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+
+ return d;
+}
+
+KviFileSelector * KviOptionsWidget::addFileSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviFileSelector * d = addFileSelector(pParent,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+
+ return d;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviSoundSelector * KviOptionsWidget::addSoundSelector(int x1,int y1,int x2,int y2,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviSoundSelector * d = new KviSoundSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(d,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviSoundSelector * KviOptionsWidget::addSoundSelector(QWidget * pParent,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviSoundSelector * d = new KviSoundSelector(pParent,txt,pOption,bEnabled);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviSoundSelector * KviOptionsWidget::addSoundSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviSoundSelector * d = addSoundSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+
+ return d;
+}
+
+KviSoundSelector * KviOptionsWidget::addSoundSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviSoundSelector * d = addSoundSelector(pParent,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+
+ return d;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviBoolSelector * KviOptionsWidget::addBoolSelector(int x1,int y1,int x2,int y2,const QString & txt,bool *pOption,bool bEnabled)
+{
+ KviBoolSelector * b = new KviBoolSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(b,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(b);
+ return b;
+}
+
+KviBoolSelector * KviOptionsWidget::addBoolSelector(QWidget * pParent,const QString & txt,bool *pOption,bool bEnabled)
+{
+ KviBoolSelector * b = new KviBoolSelector(pParent,txt,pOption,bEnabled);
+ m_pSelectorInterfaceList->append(b);
+ return b;
+}
+
+KviBoolSelector * KviOptionsWidget::addBoolSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_boolOptionsTable[optId].flags & KviOption_resetMask);
+ KviBoolSelector * d = addBoolSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_BOOL(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_boolOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+KviBoolSelector * KviOptionsWidget::addBoolSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_boolOptionsTable[optId].flags & KviOption_resetMask);
+ KviBoolSelector * d = addBoolSelector(pParent,txt,&(KVI_OPTION_BOOL(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_boolOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviPixmapSelector * KviOptionsWidget::addPixmapSelector(int x1,int y1,int x2,int y2,const QString & txt,KviPixmap *pOption,bool bEnabled)
+{
+ KviPixmapSelector * b = new KviPixmapSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(b,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(b);
+ return b;
+}
+
+KviPixmapSelector * KviOptionsWidget::addPixmapSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_pixmapOptionsTable[optId].flags & KviOption_resetMask);
+ KviPixmapSelector * d = addPixmapSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_PIXMAP(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_pixmapOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviUIntSelector * KviOptionsWidget::addUIntSelector(int x1,int y1,int x2,int y2,const QString & txt,
+ unsigned int * pOption,unsigned int uLowBound,
+ unsigned int uHighBound,unsigned int uDefault,bool bEnabled)
+{
+ KviUIntSelector * u = new KviUIntSelector(this,txt,pOption,uLowBound,uHighBound,uDefault,bEnabled,false);
+ addWidgetToLayout(u,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(u);
+ return u;
+}
+
+KviUIntSelector * KviOptionsWidget::addUIntSelector(QWidget * pParent,const QString & txt,
+ unsigned int * pOption,unsigned int uLowBound,
+ unsigned int uHighBound,unsigned int uDefault,bool bEnabled)
+{
+ KviUIntSelector * u = new KviUIntSelector(pParent,txt,pOption,uLowBound,uHighBound,uDefault,bEnabled,false);
+ m_pSelectorInterfaceList->append(u);
+ return u;
+}
+
+KviUIntSelector * KviOptionsWidget::addUIntSelector(int x1,int y1,int x2,int y2,const QString & txt,
+ int optId,unsigned int uLowBound,
+ unsigned int uHighBound,unsigned int uDefault,bool bEnabled)
+{
+ m_iResetFlags |= (g_uintOptionsTable[optId].flags & KviOption_resetMask);
+ KviUIntSelector * d = addUIntSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_UINT(optId)),uLowBound,uHighBound,uDefault,bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_uintOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+KviUIntSelector * KviOptionsWidget::addUIntSelector(QWidget * pParent,const QString & txt,
+ int optId,unsigned int uLowBound,
+ unsigned int uHighBound,unsigned int uDefault,bool bEnabled)
+{
+ m_iResetFlags |= (g_uintOptionsTable[optId].flags & KviOption_resetMask);
+ KviUIntSelector * d = addUIntSelector(pParent,txt,&(KVI_OPTION_UINT(optId)),uLowBound,uHighBound,uDefault,bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_uintOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+KviUIntSelector * KviOptionsWidget::addUShortIntSelector(int x1,int y1,int x2,int y2,const QString & txt,
+ unsigned short int * pOption,unsigned int uLowBound,
+ unsigned int uHighBound,unsigned int uDefault,bool bEnabled)
+{
+ KviUIntSelector * u = new KviUIntSelector(this,txt,(unsigned int *)pOption,uLowBound,uHighBound,uDefault,bEnabled,true);
+ addWidgetToLayout(u,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(u);
+ return u;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviStringSelector * KviOptionsWidget::addStringSelector(int x1,int y1,int x2,int y2,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviStringSelector * d = new KviStringSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(d,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviStringSelector * KviOptionsWidget::addStringSelector(QWidget * pParent,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviStringSelector * d = new KviStringSelector(pParent,txt,pOption,bEnabled);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviStringSelector * KviOptionsWidget::addStringSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviStringSelector * d = addStringSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+KviStringSelector * KviOptionsWidget::addStringSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviStringSelector * d = addStringSelector(pParent,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviPasswordSelector * KviOptionsWidget::addPasswordSelector(int x1,int y1,int x2,int y2,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviPasswordSelector * d = new KviPasswordSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(d,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviPasswordSelector * KviOptionsWidget::addPasswordSelector(QWidget * pParent,const QString & txt,QString *pOption,bool bEnabled)
+{
+ KviPasswordSelector * d = new KviPasswordSelector(pParent,txt,pOption,bEnabled);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviPasswordSelector * KviOptionsWidget::addPasswordSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviPasswordSelector * d = addPasswordSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+KviPasswordSelector * KviOptionsWidget::addPasswordSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringOptionsTable[optId].flags & KviOption_resetMask);
+ KviPasswordSelector * d = addPasswordSelector(pParent,txt,&(KVI_OPTION_STRING(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviStringListSelector * KviOptionsWidget::addStringListSelector(int x1,int y1,int x2,int y2,const QString & txt,QStringList * pOption,bool bEnabled)
+{
+ KviStringListSelector * d = new KviStringListSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(d,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(d);
+ return d;
+}
+
+KviStringListSelector * KviOptionsWidget::addStringListSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_stringlistOptionsTable[optId].flags & KviOption_resetMask);
+ KviStringListSelector * d = addStringListSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_STRINGLIST(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_stringlistOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviColorSelector * KviOptionsWidget::addColorSelector(int x1,int y1,int x2,int y2,const QString & txt,QColor * pOption,bool bEnabled)
+{
+ KviColorSelector * s = new KviColorSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(s,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(s);
+ return s;
+}
+
+KviColorSelector * KviOptionsWidget::addColorSelector(QWidget * pParent,const QString & txt,QColor * pOption,bool bEnabled)
+{
+ KviColorSelector * s = new KviColorSelector(pParent,txt,pOption,bEnabled);
+ m_pSelectorInterfaceList->append(s);
+ return s;
+}
+
+KviColorSelector * KviOptionsWidget::addColorSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_colorOptionsTable[optId].flags & KviOption_resetMask);
+ KviColorSelector * d = addColorSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_COLOR(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_colorOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+KviColorSelector * KviOptionsWidget::addColorSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_colorOptionsTable[optId].flags & KviOption_resetMask);
+ KviColorSelector * d = addColorSelector(pParent,txt,&(KVI_OPTION_COLOR(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_colorOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviMircTextColorSelector * KviOptionsWidget::addMircTextColorSelector(int x1,int y1,int x2,int y2,const QString & txt,unsigned int *uFore,unsigned int *uBack,bool bEnabled)
+{
+ KviMircTextColorSelector * s = new KviMircTextColorSelector(this,txt,uFore,uBack,bEnabled);
+ addWidgetToLayout(s,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(s);
+ return s;
+}
+
+KviMircTextColorSelector * KviOptionsWidget::addMircTextColorSelector(QWidget * pParent,const QString & txt,unsigned int *uFore,unsigned int *uBack,bool bEnabled)
+{
+ KviMircTextColorSelector * s = new KviMircTextColorSelector(pParent,txt,uFore,uBack,bEnabled);
+ m_pSelectorInterfaceList->append(s);
+ return s;
+}
+
+KviMircTextColorSelector * KviOptionsWidget::addMircTextColorSelector(int x1,int y1,int x2,int y2,const QString & txt,int optForeId,int optBackId,bool bEnabled)
+{
+ m_iResetFlags |= (g_uintOptionsTable[optForeId].flags & KviOption_resetMask);
+ m_iResetFlags |= (g_uintOptionsTable[optBackId].flags & KviOption_resetMask);
+ KviMircTextColorSelector * d = addMircTextColorSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_UINT(optForeId)),&(KVI_OPTION_UINT(optBackId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_uintOptionsTable[optForeId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+KviMircTextColorSelector * KviOptionsWidget::addMircTextColorSelector(QWidget * pParent,const QString & txt,int optForeId,int optBackId,bool bEnabled)
+{
+ m_iResetFlags |= (g_uintOptionsTable[optForeId].flags & KviOption_resetMask);
+ m_iResetFlags |= (g_uintOptionsTable[optBackId].flags & KviOption_resetMask);
+ KviMircTextColorSelector * d = addMircTextColorSelector(pParent,txt,&(KVI_OPTION_UINT(optForeId)),&(KVI_OPTION_UINT(optBackId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_uintOptionsTable[optForeId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviFontSelector * KviOptionsWidget::addFontSelector(int x1,int y1,int x2,int y2,const QString & txt,QFont * pOption,bool bEnabled)
+{
+ KviFontSelector * f = new KviFontSelector(this,txt,pOption,bEnabled);
+ addWidgetToLayout(f,x1,y1,x2,y2);
+ m_pSelectorInterfaceList->append(f);
+ return f;
+}
+
+KviFontSelector * KviOptionsWidget::addFontSelector(QWidget * pParent,const QString & txt,QFont * pOption,bool bEnabled)
+{
+ KviFontSelector * f = new KviFontSelector(pParent,txt,pOption,bEnabled);
+ m_pSelectorInterfaceList->append(f);
+ return f;
+}
+
+KviFontSelector * KviOptionsWidget::addFontSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_fontOptionsTable[optId].flags & KviOption_resetMask);
+ KviFontSelector * d = addFontSelector(x1,y1,x2,y2,txt,&(KVI_OPTION_FONT(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_fontOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+KviFontSelector * KviOptionsWidget::addFontSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled)
+{
+ m_iResetFlags |= (g_fontOptionsTable[optId].flags & KviOption_resetMask);
+ KviFontSelector * d = addFontSelector(pParent,txt,&(KVI_OPTION_FONT(optId)),bEnabled);
+ QString tmp = m_szBasicTipStart;
+ tmp += g_fontOptionsTable[optId].name;
+ tmp += m_szBasicTipEnd;
+ KviTalToolTip::add(d,tmp);
+ return d;
+}
+
+//#define DECLARE_COMMIT_FUNCTION(__fnc,__class,__classString)
+// void KviOptionsWidget::__fnc()
+// {
+// QObjectList * l = queryList(__classString);
+// if(!l)return;
+// QObjectListIt it(*l);
+// while(it.current())
+// {
+// ((__class *)it.current())->commit();
+// ++it;
+// }
+// delete l;
+// }
+
+//DECLARE_COMMIT_FUNCTION(commitBoolSelectors,KviBoolSelector,"KviBoolSelector")
+//DECLARE_COMMIT_FUNCTION(commitUIntSelectors,KviUIntSelector,"KviUIntSelector")
+//DECLARE_COMMIT_FUNCTION(commitStringSelectors,KviStringSelector,"KviStringSelector")
+//DECLARE_COMMIT_FUNCTION(commitPixmapSelectors,KviPixmapSelector,"KviPixmapSelector")
+
+void KviOptionsWidget::addRowSpacer(int x1,int y1,int x2,int y2)
+{
+ QWidget * w = new QWidget(this);
+ addWidgetToLayout(w,x1,y1,x2,y2);
+ layout()->setRowStretch(y1,1);
+}
+
+QLabel * KviOptionsWidget::addLabel(int x1,int y1,int x2,int y2,const QString & text,bool bEnabled)
+{
+ QLabel * l = new QLabel(text,this);
+#ifdef COMPILE_USE_QT4
+ l->setWordWrap(true);
+#endif
+ l->setEnabled(bEnabled);
+ addWidgetToLayout(l,x1,y1,x2,y2);
+ return l;
+}
+
+QLabel * KviOptionsWidget::addLabel(QWidget * pParent,const QString & text,bool bEnabled)
+{
+ QLabel * l = new QLabel(text,pParent);
+#ifdef COMPILE_USE_QT4
+ l->setWordWrap(true);
+#endif
+ l->setEnabled(bEnabled);
+ return l;
+}
+
+QLineEdit * KviOptionsWidget::addLineEdit(int x1,int y1,int x2,int y2,bool bEnabled)
+{
+ QLineEdit * l = new QLineEdit(this);
+ l->setEnabled(bEnabled);
+ addWidgetToLayout(l,x1,y1,x2,y2);
+ return l;
+}
+
+QFrame * KviOptionsWidget::addSeparator(int x1,int y1,int x2,int y2)
+{
+ QFrame * f = new QFrame(this);
+ f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ addWidgetToLayout(f,x1,y1,x2,y2);
+ return f;
+}
+
+#ifdef COMPILE_USE_QT4
+KviTalGroupBox * KviOptionsWidget::addGroupBox(int x1,int y1,int x2,int y2,int nStrips,Qt::Orientation o,const QString &txt,bool bEnabled)
+#else
+KviTalGroupBox * KviOptionsWidget::addGroupBox(int x1,int y1,int x2,int y2,int nStrips,KviTalGroupBox::Orientation o,const QString &txt,bool bEnabled)
+#endif
+{
+ KviTalGroupBox * g = new KviTalGroupBox(nStrips,o,txt,this);
+ g->setEnabled(bEnabled);
+ addWidgetToLayout(g,x1,y1,x2,y2);
+ return g;
+}
+
+void KviOptionsWidget::addAdvancedButton(int x1,int y1,int x2,int y2)
+{
+ QWidget * w = topLevelWidget();
+ if(!w)return;
+ if(!w->inherits("KviGeneralOptionsDialog"))return;
+
+ QPushButton * b = new QPushButton(__tr2qs("Advanced..."),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(switchToAdvancedPage()));
+ addWidgetToLayout(b,x1,y1,x2,y2);
+}
+
+
+void KviOptionsWidget::commitSelectors()
+{
+// if(m_iSelectors & KVI_OPTIONSELECTOR_TYPE_BOOL)commitBoolSelectors();
+// if(m_iSelectors & KVI_OPTIONSELECTOR_TYPE_UINT)commitUIntSelectors();
+// if(m_iSelectors & KVI_OPTIONSELECTOR_TYPE_STRING)commitStringSelectors();
+// if(m_iSelectors & KVI_OPTIONSELECTOR_TYPE_PIXMAP)commitPixmapSelectors();
+// m_iSelectors = 0;
+ for(KviSelectorInterface * i = m_pSelectorInterfaceList->first();i;i = m_pSelectorInterfaceList->next())
+ {
+ i->commit();
+ }
+}
+
+void KviOptionsWidget::commitOptionsReset()
+{
+ if(m_iResetFlags)g_pApp->optionResetUpdate(m_iResetFlags);
+ //m_iResetFlags = 0;
+}
+
+void KviOptionsWidget::commit()
+{
+ commitSelectors();
+ commitOptionsReset();
+}
+
+void KviOptionsWidget::switchToAdvancedPage()
+{
+ // FIXME: what happens if we're toplevel ????
+ // (so nobody listens to this signal....)
+
+ emit wantToSwitchToAdvancedPage(this);
+}
+
+#include "kvi_optionswidget.moc"
diff --git a/src/kvirc/ui/kvi_optionswidget.h b/src/kvirc/ui/kvi_optionswidget.h
new file mode 100644
index 0000000..8466093
--- /dev/null
+++ b/src/kvirc/ui/kvi_optionswidget.h
@@ -0,0 +1,163 @@
+#ifndef _KVI_OPTIONSWIDGET_H_
+#define _KVI_OPTIONSWIDGET_H_
+
+//=============================================================================
+//
+// File : kvi_optionswidget.h
+// Creation date : Mon Jun 10 2000 17:47:33 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+#include <qframe.h>
+#include <qlayout.h>
+#include "kvi_pointerlist.h"
+#include <qlineedit.h>
+#include <kvi_tal_groupbox.h>
+#include <qtabwidget.h>
+#include "kvi_tal_groupbox.h"
+#include "kvi_selectors.h"
+
+class KVIRC_API KviOptionsWidget : public QFrame, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviOptionsWidget(QWidget * parent,const char * name = 0,bool bSunken = true);
+ ~KviOptionsWidget();
+private:
+ QGridLayout * m_pLayout;
+ QTabWidget * m_pTabWidget;
+ int m_iResetFlags;
+ int m_iSelectors;
+ KviPointerList<KviSelectorInterface> * m_pSelectorInterfaceList;
+ static QString m_szBasicTipStart;
+ static QString m_szBasicTipEnd;
+public:
+ void mergeResetFlag(int flag){ m_iResetFlags |= flag; };
+ void createLayout(int rows,int columns);
+ QGridLayout * layout(){ return m_pLayout; };
+protected:
+ void commitSelectors();
+ void commitOptionsReset();
+public:
+ void mergeTip(QWidget * w,const QString &tip);
+
+ // tabbed page paradigm
+ void createTabbedPage();
+ void addOptionsWidget(const QString &szText,const QIconSet &iconSet,KviOptionsWidget * pWidget);
+ QTabWidget * tabWidget(){ return m_pTabWidget; };
+
+ // non tabbed page paradigm
+ KviBoolSelector * addBoolSelector(int x1,int y1,int x2,int y2,const QString & txt,bool * pOption,bool bEnabled = true);
+ KviBoolSelector * addBoolSelector(QWidget * pParent,const QString & txt,bool * pOption,bool bEnabled = true);
+ KviBoolSelector * addBoolSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviBoolSelector * addBoolSelector(QWidget * pParnt,const QString & txt,int optId,bool bEnabled = true);
+
+ KviColorSelector * addColorSelector(int x1,int y1,int x2,int y2,const QString & txt,QColor * pOption,bool bEnabled = true);
+ KviColorSelector * addColorSelector(QWidget * pParent,const QString & txt,QColor * pOption,bool bEnabled = true);
+ KviColorSelector * addColorSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviColorSelector * addColorSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled = true);
+
+ KviMircTextColorSelector * addMircTextColorSelector(int x1,int y1,int x2,int y2,const QString & txt,unsigned int *uFore,unsigned int *uBack,bool bEnabled = true);
+ KviMircTextColorSelector * addMircTextColorSelector(QWidget * pParent,const QString & txt,unsigned int *uFore,unsigned int *uBack,bool bEnabled = true);
+ KviMircTextColorSelector * addMircTextColorSelector(int x1,int y1,int x2,int y2,const QString & txt,int optForeId,int optBackId,bool bEnabled = true);
+ KviMircTextColorSelector * addMircTextColorSelector(QWidget * pParent,const QString & txt,int optForeId,int optBackId,bool bEnabled = true);
+
+ KviDirectorySelector * addDirectorySelector(int x1,int y1,int x2,int y2,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviDirectorySelector * addDirectorySelector(QWidget * pParent,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviDirectorySelector * addDirectorySelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviDirectorySelector * addDirectorySelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled = true);
+
+ KviFileSelector * addFileSelector(int x1,int y1,int x2,int y2,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviFileSelector * addFileSelector(QWidget * pParent,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviFileSelector * addFileSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviFileSelector * addFileSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled = true);
+
+ KviSoundSelector * addSoundSelector(int x1,int y1,int x2,int y2,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviSoundSelector * addSoundSelector(QWidget * pParent,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviSoundSelector * addSoundSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviSoundSelector * addSoundSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled = true);
+
+
+ KviFontSelector * addFontSelector(int x1,int y1,int x2,int y2,const QString & txt,QFont * pOption,bool bEnabled = true);
+ KviFontSelector * addFontSelector(QWidget * pParent,const QString & txt,QFont * pOption,bool bEnabled = true);
+ KviFontSelector * addFontSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviFontSelector * addFontSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled = true);
+
+ KviPasswordSelector * addPasswordSelector(int x1,int y1,int x2,int y2,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviPasswordSelector * addPasswordSelector(QWidget * pParent,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviPasswordSelector * addPasswordSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviPasswordSelector * addPasswordSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled = true);
+
+ KviPixmapSelector * addPixmapSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviPixmapSelector * addPixmapSelector(int x1,int y1,int x2,int y2,const QString & txt,KviPixmap * pOption,bool bEnabled = true);
+
+ KviStringListSelector * addStringListSelector(int x1,int y1,int x2,int y2,const QString & txt,QStringList * pOption,bool bEnabled = true);
+ KviStringListSelector * addStringListSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+
+ KviStringSelector * addStringSelector(int x1,int y1,int x2,int y2,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviStringSelector * addStringSelector(QWidget * pParent,const QString & txt,QString * pOption,bool bEnabled = true);
+ KviStringSelector * addStringSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,bool bEnabled = true);
+ KviStringSelector * addStringSelector(QWidget * pParent,const QString & txt,int optId,bool bEnabled = true);
+
+ KviUIntSelector * addUIntSelector(int x1,int y1,int x2,int y2,const QString & txt,unsigned int * pOption,
+ unsigned int uLowBound,unsigned int uHighBound,unsigned int uDefault,bool bEnabled = true);
+ KviUIntSelector * addUIntSelector(QWidget * pParent,const QString & txt,unsigned int * pOption,
+ unsigned int uLowBound,unsigned int uHighBound,unsigned int uDefault,bool bEnabled = true);
+ KviUIntSelector * addUIntSelector(int x1,int y1,int x2,int y2,const QString & txt,int optId,
+ unsigned int uLowBound,unsigned int uHighBound,unsigned int uDefault,bool bEnabled = true);
+ KviUIntSelector * addUIntSelector(QWidget * pParent,const QString & txt,int optId,
+ unsigned int uLowBound,unsigned int uHighBound,unsigned int uDefault,bool bEnabled = true);
+
+
+ KviUIntSelector * addUShortIntSelector(int x1,int y1,int x2,int y2,const QString & txt,unsigned short int * pOption,
+ unsigned int uLowBound,unsigned int uHighBound,unsigned int uDefault,bool bEnabled = true);
+
+ QLabel * addLabel(int x1,int y1,int x2,int y2,const QString & text,bool bEnabled = true);
+ QLabel * addLabel(QWidget * pParent,const QString & text,bool bEnabled = true);
+ QLineEdit * addLineEdit(int x1,int y1,int x2,int y2,bool bEnabled = true);
+#ifdef COMPILE_USE_QT4
+ KviTalGroupBox * addGroupBox(int x1,int y1,int x2,int y2,int nStrips,Qt::Orientation o,const QString &txt,bool bEnabled = true);
+#else
+ KviTalGroupBox * addGroupBox(int x1,int y1,int x2,int y2,int nStrips,KviTalGroupBox::Orientation o,const QString &txt,bool bEnabled = true);
+#endif
+ QFrame * addSeparator(int x1,int y1,int x2,int y2);
+ void addRowSpacer(int x1,int y1,int x2,int y2);
+
+ void addWidgetToLayout(QWidget * w,int x1,int y1,int x2,int y2);
+
+ // this does NOT add the advanced button if this page is not inside a KviGeneralOptionsDialog
+ // this is because nobody listens to the "switchToAdvancedPage" requests....
+ void addAdvancedButton(int x1,int y1,int x2,int y2);
+
+ virtual void commit();
+protected slots:
+ // this is internal to the options dialog (options module)
+ // it attempts to show all the hidden subitems (usually the "Advanced...") page
+ // and switch to the first of them
+ void switchToAdvancedPage();
+signals:
+ // internal signal used for the stuff above
+ void wantToSwitchToAdvancedPage(KviOptionsWidget *);
+};
+
+
+#endif //!_KVI_OPTIONSWIDGET_H_
diff --git a/src/kvirc/ui/kvi_query.cpp b/src/kvirc/ui/kvi_query.cpp
new file mode 100644
index 0000000..c32c33f
--- /dev/null
+++ b/src/kvirc/ui/kvi_query.cpp
@@ -0,0 +1,659 @@
+//=============================================================================
+//
+// File : kvi_query.cpp
+// Creation date : Tue Aug 7 2000 14:23:22 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#include "kvi_query.h"
+#include "kvi_console.h"
+#include "kvi_iconmanager.h"
+#include "kvi_ircview.h"
+#include "kvi_input.h"
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_settings.h"
+#include "kvi_ircsocket.h"
+#include "kvi_out.h"
+#include "kvi_taskbar.h"
+#include "kvi_config.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_settings.h"
+#include "kvi_themedlabel.h"
+#include "kvi_useraction.h"
+#include "kvi_parameterlist.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_sparser.h"
+#include "kvi_ircuserdb.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_toolwindows_container.h"
+#include "kvi_qcstring.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ #include "kvi_crypt.h"
+ #include "kvi_cryptcontroller.h"
+#endif
+
+#include "kvi_kvs_eventtriggers.h"
+
+#include <qpixmap.h>
+#include <qsplitter.h>
+#include "kvi_tal_hbox.h"
+#include <qtoolbutton.h>
+#include "kvi_draganddrop.h"
+#include "kvi_valuelist.h"
+
+KviQuery::KviQuery(KviFrame * lpFrm,KviConsole * lpConsole,const QString &nick)
+: KviWindow(KVI_WINDOW_TYPE_QUERY,lpFrm,nick,lpConsole)
+{
+
+ m_iFlags = 0;
+ connection()->registerQuery(this);
+
+ //m_pTopSplitter = new QSplitter(QSplitter::Horizontal,this,"top_splitter");
+ m_pButtonBox = new KviTalHBox(this);
+ m_pLabel = new KviThemedLabel(m_pButtonBox,"query_label");
+ m_pLabel->setAutoHeight(1);
+ updateLabelText();
+ m_pButtonBox->setStretchFactor(m_pLabel,1);
+
+ // The button box on the right
+ //KviTalHBox * box = new KviTalHBox(m_pTopSplitter,"button_box");
+ if(KVI_OPTION_BOOL(KviOption_boolShowExtendedInfoInQueryLabel))
+ m_pButtonGrid= (QFrame*) new KviTalGrid(2,Qt::Horizontal,m_pButtonBox);
+ else
+ m_pButtonGrid= (QFrame*) new KviTalGrid(4,Qt::Horizontal,m_pButtonBox);
+
+ createTextEncodingButton(m_pButtonGrid);
+
+#ifdef COMPILE_USE_QT4
+ m_pSplitter = new QSplitter(Qt::Horizontal,this,"main_splitter");
+#else
+ m_pSplitter = new QSplitter(QSplitter::Horizontal,this,"main_splitter");
+#endif
+ m_pIrcView = new KviIrcView(m_pSplitter,lpFrm,this);
+ connect(m_pIrcView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked()));
+ //m_pEditorsContainer= new KviToolWindowsContainer(m_pSplitter);
+
+
+ m_pListViewButton = new KviWindowToolPageButton(KVI_SMALLICON_HIDELISTVIEW,KVI_SMALLICON_SHOWLISTVIEW,__tr2qs("Show User List"),buttonContainer(),true,"list_view_button");
+ connect(m_pListViewButton,SIGNAL(clicked()),this,SLOT(toggleListView()));
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ createCryptControllerButton(m_pButtonGrid);
+#endif
+
+ m_pUserListView = new KviUserListView(m_pSplitter,m_pListViewButton,connection()->userDataBase(),this,7,__tr2qs("Query Targets"),"user_list_view");
+
+ m_pInput = new KviInput(this,m_pUserListView);
+
+ if(KVI_OPTION_BOOL(KviOption_boolAutoLogQueries)) m_pIrcView->startLogging();
+ // FIXME: #warning "Maybe tell the user all that we know about the remote end(s)....channels..."
+
+ m_pIrcView->enableDnd(TRUE);
+ connect(m_pIrcView,SIGNAL(fileDropped(const char *)),this,SLOT(slotDndEvents(const char *)));
+
+ updateCaption();
+}
+
+KviQuery::~KviQuery()
+{
+ m_pUserListView->partAll();
+ if(type() == KVI_WINDOW_TYPE_DEADQUERY)
+ context()->unregisterDeadQuery(this);
+ else
+ connection()->unregisterQuery(this);
+}
+
+void KviQuery::updateLabelText()
+{
+ QString szText=getInfoLabelText();
+ if(szText!=m_pLabel->text())
+ {
+ m_pLabel->setText(szText);
+ KviTalToolTip::add(m_pLabel,getInfoLabelTipText());
+ }
+}
+
+QString KviQuery::getInfoLabelTipText()
+{
+ QString txt;
+ KviIrcUserEntry * e = connection()->userDataBase()->find(m_szName);
+ if(e)
+ {
+ QString tmp;
+ QString szMask;
+ if(e->hasUser())
+ szMask+=e->user();
+ else
+ szMask+="*";
+ szMask+="@";
+ if(e->hasHost())
+ szMask+=e->host();
+ else
+ szMask+="*";
+ tmp+="\n";
+ QString szChans;
+ connection()->getCommonChannels(m_szName,szChans,0);
+ if(console()->connection())
+ {
+
+ txt = "<html>" \
+ "<body>" \
+ "<table width=\"100%\">";
+
+ txt += START_TABLE_BOLD_ROW;
+ txt += __tr2qs("Query target:");
+ txt += END_TABLE_BOLD_ROW;
+ txt += "<tr><td>";
+
+ if(e->hasRealName())
+ tmp=__tr2qs("%1 is %2 (%3)").arg(m_szName).arg(szMask).arg(KviMircCntrl::stripControlBytes(e->realName()));
+ else
+ tmp=__tr2qs("%1 is %2").arg(m_szName).arg(szMask);
+
+ tmp.replace('&',"&amp;");
+ tmp.replace('<',"&lt;");
+ tmp.replace('>',"&gt;");
+
+ txt += tmp;
+
+ txt += "</td></tr>";
+
+ if(e->hasServer())
+ {
+ txt+="<tr><td>";
+ if(e->hasHops())
+ txt+=__tr2qs("%1 is using irc server: %2 (%3 hops)").arg(m_szName).arg(e->server()).arg(e->hops());
+ else
+ txt+=__tr2qs("%1 is using irc server: %2").arg(m_szName).arg(e->server());
+ txt+="</td></tr>";
+ }
+
+ if(e->isAway())
+ {
+ txt+="<tr><td>";
+ txt+=__tr2qs("%1 is probably away").arg(m_szName);
+ txt+="</td></tr>";
+ }
+
+ txt+="<tr><td>";
+ tmp=__tr2qs("Common channels with %1: %2").arg(m_szName).arg(szChans);
+
+ tmp.replace('&',"&amp;");
+ tmp.replace('<',"&lt;");
+ tmp.replace('>',"&gt;");
+
+ txt+=tmp;
+ txt +="</td></tr>";
+
+ txt += "</table>" \
+ "</body>" \
+ "<html>";
+ } else {
+ txt=__tr2qs("[Dead Query]");
+ }
+ }
+ return txt;
+}
+
+QString KviQuery::getInfoLabelText()
+{
+ QString tmp;
+ if(KVI_OPTION_BOOL(KviOption_boolShowExtendedInfoInQueryLabel))
+ {
+ KviIrcUserEntry * e = connection()->userDataBase()->find(m_szName);
+ if(e)
+ {
+ QString szMask;
+ if(console()->connection())
+ {
+ if(e->hasUser())
+ szMask+=e->user();
+ else
+ szMask+="*";
+ szMask+="@";
+ if(e->hasHost())
+ szMask+=e->host();
+ else
+ szMask+="*";
+ if(e->hasRealName())
+ tmp=__tr2qs("Query with %1!%2 (%3)").arg(m_szName).arg(szMask).arg(KviMircCntrl::stripControlBytes(e->realName()));
+ else
+ tmp=__tr2qs("Query with %1!%2").arg(m_szName).arg(szMask);
+ if(e->hasServer())
+ tmp+=__tr2qs(", using server %1").arg(e->server());
+ if(e->hasHops())
+ tmp+=__tr2qs(" (%1 hops)").arg(e->hops());
+ if(e->isAway())
+ tmp+=__tr2qs(", probably away");
+ tmp+="\n";
+ QString szChans;
+ connection()->getCommonChannels(m_szName,szChans,0);
+ tmp+=__tr2qs("Common channels: %2").arg(szChans);
+ } else {
+ tmp=__tr2qs("[Dead Query]");
+ }
+ }
+ }
+ return tmp;
+}
+void KviQuery::slotDndEvents(const char *file)
+{
+ KVS_TRIGGER_EVENT_1(KviEvent_OnQueryFileDropped,this,QString(file));
+}
+
+void KviQuery::triggerCreationEvents()
+{
+ if(!KVI_OPTION_STRING(KviOption_stringOnNewQueryOpenedSound).isEmpty()) KviKvsScript::run("snd.play $0",0,new KviKvsVariantList(new KviKvsVariant(KVI_OPTION_STRING(KviOption_stringOnNewQueryOpenedSound))));
+ KVS_TRIGGER_EVENT_0(KviEvent_OnQueryWindowCreated,this);
+}
+
+void KviQuery::getBaseLogFileName(QString &buffer)
+{
+ if(console()->connection())
+ {
+ buffer=windowName();
+ buffer += ".";
+ buffer += console()->currentNetworkName();
+ } else {
+ buffer=windowName();
+ buffer+=".";
+ buffer+=console()->ircContextId();
+ }
+}
+
+void KviQuery::mergeQuery(KviQuery * q)
+{
+ m_pIrcView->appendMessagesFrom(q->m_pIrcView);
+ updateLabelText();
+}
+
+void KviQuery::textViewRightClicked()
+{
+ KVS_TRIGGER_EVENT_0(KviEvent_OnQueryPopupRequest,this);
+}
+
+void KviQuery::saveProperties(KviConfig *cfg)
+{
+ KviWindow::saveProperties(cfg);
+ cfg->writeEntry("Splitter",m_pSplitter->sizes());
+ cfg->writeEntry("UserListViewVisible",m_pUserListView->isVisible());
+}
+
+void KviQuery::loadProperties(KviConfig *cfg)
+{
+ int w = width();
+ KviWindow::loadProperties(cfg);
+ KviValueList<int> def;
+ def.append((w * 80) / 100);
+ def.append((w * 20) / 100);
+ m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def));
+ showListView(cfg->readBoolEntry("UserListViewVisible",false));
+}
+
+void KviQuery::notifyTargetChange(const QString &oldNick,const QString &oldUser,const QString &oldHost,const QString &nick,const QString &user,const QString &host)
+{
+ QString oldN = oldNick.isEmpty() ? QString("*") : oldNick;
+ QString oldU = oldUser.isEmpty() ? QString("*") : oldUser;
+ QString oldH = oldHost.isEmpty() ? QString("*") : oldHost;
+ output(KVI_OUT_QUERYTRACE,
+ __tr2qs("The target of this query has changed from \r!n\r%Q\r [%Q@\r!h\r%Q\r] to \r!n\r%Q\r [%Q@\r!h\r%Q\r]"),
+ &oldN,&oldU,&oldH,&nick,&user,&host);
+ updateLabelText();
+}
+
+
+void KviQuery::userAction(const QString &nick,const QString &user,const QString &host,unsigned int uActionType)
+{
+ int iTemperature = kvi_getUserActionTemperature(uActionType);
+ if(KVI_OPTION_BOOL(KviOption_boolEnableQueryTracing))
+ {
+ QString oldUser,oldHost;
+ if(!m_pUserListView->userActionVerifyMask(nick,user,host,iTemperature,oldUser,oldHost))
+ notifyTargetChange(nick,oldUser,oldHost,nick,user,host);
+ } else {
+ m_pUserListView->userAction(nick,user,host,iTemperature);
+ }
+ updateLabelText();
+}
+
+
+void KviQuery::userAction(const QString &nick,unsigned int uActionType)
+{
+ int iTemperature = kvi_getUserActionTemperature(uActionType);
+ m_pUserListView->userAction(nick,iTemperature);
+ updateLabelText();
+}
+
+void KviQuery::userAction(KviIrcMask *user,unsigned int uActionType)
+{
+ int iTemperature = kvi_getUserActionTemperature(uActionType);
+ if(KVI_OPTION_BOOL(KviOption_boolEnableQueryTracing))
+ {
+ QString oldUser,oldHost;
+ if(!m_pUserListView->userActionVerifyMask(user->nick(),user->user(),user->host(),iTemperature,oldUser,oldHost))
+ notifyTargetChange(user->nick(),oldUser,oldHost,user->nick(),user->user(),user->host());
+ } else {
+ m_pUserListView->userAction(user,iTemperature);
+ }
+ updateLabelText();
+}
+
+
+KviUserListEntry * KviQuery::setTarget(const QString &nick,const QString &user,const QString &host)
+{
+ KviUserListEntry * e = m_pUserListView->join(nick,user,host);
+ if((!e->globalData()->avatar()) && (!user.isEmpty()) && (user != "*"))
+ m_pConsole->checkDefaultAvatar(e->globalData(),nick,user,host);
+
+ setWindowName(nick);
+ updateCaption();
+
+ if(KVI_OPTION_BOOL(KviOption_boolEnableQueryTracing))
+ {
+ QString szChans;
+ int iChans = m_pConsole->connection()->getCommonChannels(nick,szChans);
+ notifyCommonChannels(nick,user,host,iChans,szChans);
+ }
+
+ KVS_TRIGGER_EVENT_3(KviEvent_OnQueryTargetAdded,this,nick,user,host);
+ updateLabelText();
+ return e;
+}
+
+void KviQuery::notifyCommonChannels(const QString &nick,const QString &user,const QString &host,int iChans,const QString &szChans)
+{
+ static QString star("*");
+ if(iChans > 0)
+ {
+ output(KVI_OUT_QUERYTRACE,__tr2qs("Common channels for \r!n\r%Q\r [%Q@\r!h\r%Q\r]: %Q"),
+ &nick,user.isEmpty() ? &star : &user,host.isEmpty() ? &star : &host,&szChans);
+ } else {
+ output(KVI_OUT_QUERYTRACE,__tr2qs("No common channels for \r!n\r%Q\r [%Q@\r!h\r%Q\r]"),
+ &nick,user.isEmpty() ? &star : &user,host.isEmpty() ? &star : &host);
+ }
+ updateLabelText();
+}
+
+
+
+
+/*void KviQuery::updateTargets()
+{
+ QString szName;
+
+ if(targetCount() > 0)
+ {
+ KviPointerHashTableIterator<QString,KviUserListEntry> it(*(m_pUserListView->entryDict()));
+ if(it.current())szName = it.currentKey();
+ }
+
+ if(szName.isEmpty())szName = __tr2qs("[No targets]");
+
+ setWindowName(szName);
+
+ updateCaption();
+}*/
+
+void KviQuery::fillCaptionBuffers()
+{
+ static QString begin("<nobr><font color=\"");
+ static QString boldbegin("\"><b>");
+ static QString endofbold("</b></font> <font color=\"");
+ static QString endoffont("\">");
+ static QString end("</font></nobr>");
+
+ if(!console()->connection())
+ {
+ QString dead = __tr2qs("[Dead query]");
+
+ m_szPlainTextCaption = windowName();
+ m_szPlainTextCaption += " : ";
+ m_szPlainTextCaption += dead;
+
+ m_szHtmlActiveCaption = begin;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += boldbegin;
+ m_szHtmlActiveCaption += windowName();
+ m_szHtmlActiveCaption += endofbold;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name();
+ m_szHtmlActiveCaption += endoffont;
+ m_szHtmlActiveCaption += dead;
+ m_szHtmlActiveCaption += end;
+
+ m_szHtmlInactiveCaption = begin;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += boldbegin;
+ m_szHtmlInactiveCaption += windowName();
+ m_szHtmlInactiveCaption += endofbold;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name();
+ m_szHtmlInactiveCaption += endoffont;
+ m_szHtmlInactiveCaption += dead;
+ m_szHtmlInactiveCaption += end;
+
+ return;
+ }
+
+ QString szNickOnServer = QChar('[');
+ szNickOnServer += connection()->currentNickName();
+ szNickOnServer += __tr2qs(" on ");
+ szNickOnServer += connection()->currentServerName();
+ szNickOnServer += QChar(']');
+
+ m_szPlainTextCaption = windowName();
+ m_szPlainTextCaption += QChar(' ');
+ m_szPlainTextCaption += szNickOnServer;
+
+ m_szHtmlActiveCaption = begin;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += boldbegin;
+ m_szHtmlActiveCaption += windowName();
+ m_szHtmlActiveCaption += endofbold;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name();
+ m_szHtmlActiveCaption += endoffont;
+ m_szHtmlActiveCaption += szNickOnServer;
+ m_szHtmlActiveCaption += end;
+
+ m_szHtmlInactiveCaption = begin;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += boldbegin;
+ m_szHtmlInactiveCaption += windowName();
+ m_szHtmlInactiveCaption += endofbold;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name();
+ m_szHtmlInactiveCaption += endoffont;
+ m_szHtmlInactiveCaption += szNickOnServer;
+ m_szHtmlInactiveCaption += end;
+}
+
+bool KviQuery::nickChange(const QString &oldNick,const QString &newNick)
+{
+ bool bRet = m_pUserListView->nickChange(oldNick,newNick);
+ if(!bRet)return false; // ugh!! ?
+ setWindowName(newNick);
+ updateCaption();
+ updateLabelText();
+ return bRet;
+}
+
+void KviQuery::showListView(bool bShow)
+{
+ if(!bShow)
+ {
+ m_pUserListView->hide();
+ if(m_pListViewButton->isOn())m_pListViewButton->setOn(false);
+ } else {
+ m_pUserListView->show();
+ if(!(m_pListViewButton->isOn()))m_pListViewButton->setOn(true);
+ }
+}
+
+void KviQuery::toggleListView()
+{
+ showListView(!m_pUserListView->isVisible());
+}
+
+void KviQuery::setDeadQuery()
+{
+ m_iFlags |= KVI_QUERY_FLAG_DEAD;
+
+ m_pUserListView->enableUpdates(false);
+ m_pUserListView->partAll();
+ m_pUserListView->enableUpdates(true);
+ m_pUserListView->setUserDataBase(0);
+ connection()->unregisterQuery(this);
+ context()->registerDeadQuery(this);
+ setType(KVI_WINDOW_TYPE_DEADQUERY);
+
+ updateIcon();
+ updateCaption();
+ updateLabelText();
+};
+
+void KviQuery::setAliveQuery()
+{
+ m_iFlags &= ~KVI_QUERY_FLAG_DEAD;
+ m_pUserListView->setUserDataBase(connection()->userDataBase());
+ setType(KVI_WINDOW_TYPE_QUERY);
+ context()->unregisterDeadQuery(this);
+ connection()->registerQuery(this);
+ // Update log file name
+ if(m_pIrcView->isLogging()) m_pIrcView->startLogging();
+ updateIcon();
+ updateCaption();
+ updateLabelText();
+}
+
+void KviQuery::applyOptions()
+{
+ m_pUserListView->applyOptions();
+ updateLabelText();
+ // this applies options for IrcView and Input and forces the window to relayout
+ KviWindow::applyOptions();
+}
+
+QPixmap * KviQuery::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(isDeadQuery() ? KVI_SMALLICON_DEADQUERY : KVI_SMALLICON_QUERY);
+}
+
+void KviQuery::resizeEvent(QResizeEvent *e)
+{
+ int hght = m_pInput->heightHint();
+ int hght2 = m_pButtonBox->sizeHint().height();
+ m_pButtonBox->setGeometry(0,0,width(),hght2);
+ m_pSplitter->setGeometry(0,hght2,width(),height() - (hght + hght2));
+ m_pInput->setGeometry(0,height() - hght,width(),hght);
+}
+
+QSize KviQuery::sizeHint() const
+{
+ QSize ret(m_pSplitter->sizeHint().width(),m_pIrcView->sizeHint().height() + m_pInput->heightHint());
+ return ret;
+}
+
+void KviQuery::ownMessage(const QString &buffer)
+{
+ if(!connection())
+ {
+ outputNoFmt(KVI_OUT_SYSTEMWARNING,__tr2qs("This query has no active targets, no message sent"));
+ return;
+ }
+
+ KviQCString szName = connection()->encodeText(windowName());
+ KviQCString szData = encodeText(buffer);
+
+ const char * d = szData.data();
+ if(!d)return;
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ if(cryptSessionInfo())
+ {
+ if(cryptSessionInfo()->bDoEncrypt)
+ {
+ if(*d != KVI_TEXT_CRYPTESCAPE)
+ {
+ KviStr encrypted;
+ cryptSessionInfo()->pEngine->setMaxEncryptLen(500 - szName.length());
+ switch(cryptSessionInfo()->pEngine->encrypt(d,encrypted))
+ {
+ case KviCryptEngine::Encrypted:
+ if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),encrypted.ptr()))return;
+ m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSGCRYPTED,
+ QString::null,QString::null,QString::null,buffer,KviConsole::NoNotifications);
+ break;
+ case KviCryptEngine::Encoded:
+ {
+ if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),encrypted.ptr()))return;
+ // ugly ,but we must redecode here
+ QString szRedecoded = decodeText(encrypted.ptr());
+ m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,
+ QString::null,QString::null,QString::null,szRedecoded,KviConsole::NoNotifications);
+ }
+ break;
+ default: // also case KviCryptEngine::EncryptError
+ {
+ QString szEngineError = cryptSessionInfo()->pEngine->lastError();
+ output(KVI_OUT_SYSTEMERROR,
+ __tr2qs("The crypto engine was unable to encrypt the current message (%Q): %s, no data sent to the server"),
+ &buffer,&szEngineError);
+ }
+ break;
+ }
+ userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG);
+ return;
+ } else {
+ d++; //eat the escape code
+ QString tmp = buffer.right(buffer.length() - 1);
+ if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),d))return;
+ m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,QString::null,QString::null,QString::null,tmp,KviConsole::NoNotifications);
+ userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG);
+ return;
+ }
+ }
+ }
+#endif
+
+ if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),d))return;
+ m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,QString::null,QString::null,QString::null,buffer,KviConsole::NoNotifications);
+ userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG);
+}
+
+void KviQuery::ownAction(const QString &buffer)
+{
+ if(!connection())
+ {
+ outputNoFmt(KVI_OUT_SYSTEMWARNING,__tr2qs("This query has no active targets, no message sent"));
+ } else {
+ KviQCString szBuffer = encodeText(buffer);
+ if(!szBuffer.data())return;
+ KviQCString sz = connection()->encodeText(windowName());
+ if(sz.isEmpty())return;
+ if(!connection()->sendFmtData("PRIVMSG %s :%cACTION %s%c",
+ sz.data(),0x01,szBuffer.data(),0x01))return;
+ if(KVS_TRIGGER_EVENT_1_HALTED(KviEvent_OnMeAction,this,QString(szBuffer.data())))return;
+ output(KVI_OUT_ACTION,"\r!nc\r%Q\r %Q",&(connection()->currentNickName()),&buffer);
+ m_pUserListView->userAction(connection()->currentNickName(),KVI_USERACTION_ACTION);
+ }
+}
+
+#include "kvi_query.moc"
diff --git a/src/kvirc/ui/kvi_query.h b/src/kvirc/ui/kvi_query.h
new file mode 100644
index 0000000..ba087ac
--- /dev/null
+++ b/src/kvirc/ui/kvi_query.h
@@ -0,0 +1,95 @@
+#ifndef _KVI_QUERY_H_
+#define _KVI_QUERY_H_
+//=============================================================================
+//
+// File : kvi_query.h
+// Creation date : Mon Aug 7 2000 14:19:00 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_window.h"
+#include "kvi_string.h"
+#include "kvi_ircuserdb.h"
+#include "kvi_userlistview.h"
+#include "kvi_themedlabel.h"
+
+#include "kvi_pointerhashtable.h"
+#include "kvi_tal_grid.h"
+
+class KviConsole;
+class KviConfig;
+class QSplitter;
+class KviWindowToolPageButton;
+
+#define KVI_QUERY_FLAG_DEAD 1
+
+class KVIRC_API KviQuery : public KviWindow
+{
+ Q_OBJECT
+public:
+ KviQuery(KviFrame * lpFrm,KviConsole * lpConsole,const QString &nick);
+ ~KviQuery();
+protected:
+ KviUserListView * m_pUserListView;
+ KviWindowToolPageButton * m_pListViewButton;
+ int m_iFlags;
+ KviThemedLabel * m_pLabel;
+ QFrame * m_pButtonGrid;
+protected:
+ virtual QPixmap * myIconPtr();
+ virtual void fillCaptionBuffers();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void loadProperties(KviConfig * cfg);
+ virtual void saveProperties(KviConfig * cfg);
+ virtual void getBaseLogFileName(QString &buffer);
+ virtual void triggerCreationEvents();
+public:
+ void setDeadQuery();
+ void setAliveQuery();
+ bool isDeadQuery(){ return m_iFlags & KVI_QUERY_FLAG_DEAD; };
+ virtual QSize sizeHint() const;
+ virtual const QString & target(){ return windowName(); };
+ virtual void applyOptions();
+ KviUserListEntry * setTarget(const QString &nick,const QString &user,const QString &host);
+ void userAction(KviIrcMask *user,unsigned int uActionType);
+ void userAction(const QString &nick,unsigned int uActionType);
+ void userAction(const QString &nick,const QString &user,const QString &host,unsigned int uActionType);
+ bool nickChange(const QString &oldNick,const QString &newNick);
+ void ownMessage(const QString &buffer);
+ void ownAction(const QString &buffer);
+ int selectedCount(){ return m_pUserListView->selectedCount(); };
+ bool avatarChanged(const QString &nick){ return m_pUserListView->avatarChanged(nick); };
+ void notifyCommonChannels(const QString &nick,const QString &user,const QString &host,int iChans,const QString &szChans);
+ void showListView(bool bShow);
+ void mergeQuery(KviQuery * q);
+ void updateLabelText();
+ QFrame * buttonContainer() { return (QFrame*)m_pButtonGrid; };
+protected:
+ void notifyTargetChange(const QString &oldNick,const QString &oldUser,const QString &oldHost,const QString &nick,const QString &user,const QString &host);
+ QString getInfoLabelText();
+ QString getInfoLabelTipText();
+protected slots:
+ void textViewRightClicked();
+ void toggleListView();
+ void slotDndEvents(const char *);
+};
+
+#endif //_KVI_CHANNEL_H_
diff --git a/src/kvirc/ui/kvi_scriptbutton.cpp b/src/kvirc/ui/kvi_scriptbutton.cpp
new file mode 100644
index 0000000..7b4a8e7
--- /dev/null
+++ b/src/kvirc/ui/kvi_scriptbutton.cpp
@@ -0,0 +1,98 @@
+//
+// File : kvi_scriptbutton.cpp
+// Creation date : Wed Nov 14 15:43:41 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVIRC__
+#include "kvi_scriptbutton.h"
+#include "kvi_irctoolbar.h"
+#include "kvi_window.h"
+#include "kvi_console.h"
+#include "kvi_app.h"
+#include "kvi_parameterlist.h"
+#include "kvi_kvs_variantlist.h"
+#include "kvi_kvs_script.h"
+
+
+KviScriptUserButton::KviScriptUserButton(QWidget * par,const char * name)
+: KviStyledToolButton(par,name)
+{
+ m_pScript = 0;
+// setAutoRaise(true);
+ connect(this,SIGNAL(clicked()),this,SLOT(btnClicked()));
+ setAutoRaise(true);
+}
+
+KviScriptUserButton::~KviScriptUserButton()
+{
+ if(m_pScript)delete m_pScript;
+}
+
+KviWindow * KviScriptUserButton::window()
+{
+ return g_pActiveWindow;
+}
+
+void KviScriptUserButton::setButtonCode(KviKvsScript * pScript)
+{
+ if(m_pScript)delete m_pScript;
+ m_pScript = pScript;
+}
+
+
+void KviScriptUserButton::btnClicked()
+{
+ KviWindow * pWnd = window();
+ if(!pWnd)return; // ops...
+ QPoint pos = mapToGlobal(QPoint(0,height()));
+
+ KviKvsVariantList vList;
+ vList.append((kvs_int_t)pos.x());
+ vList.append((kvs_int_t)pos.y());
+ m_pScript->run(pWnd,&vList,0,KviKvsScript::PreserveParams);
+}
+/*
+
+KviIrcToolBarScriptButton::KviIrcToolBarScriptButton(QToolBar * p,const char * name)
+: KviScriptUserButton(p,name)
+{
+ setAutoRaise(true);
+}
+
+KviIrcToolBarScriptButton::~KviIrcToolBarScriptButton()
+{
+}
+
+KviWindow * KviIrcToolBarScriptButton::window()
+{
+ return g_pActiveWindow;
+}
+*/
+
+KviWindowScriptButton::KviWindowScriptButton(QWidget * p,KviWindow * wnd,const char * name)
+: KviScriptUserButton(p,name)
+{
+ m_pWnd = wnd;
+}
+
+KviWindowScriptButton::~KviWindowScriptButton()
+{
+}
+
+#include "kvi_scriptbutton.moc"
diff --git a/src/kvirc/ui/kvi_scriptbutton.h b/src/kvirc/ui/kvi_scriptbutton.h
new file mode 100644
index 0000000..79740c8
--- /dev/null
+++ b/src/kvirc/ui/kvi_scriptbutton.h
@@ -0,0 +1,79 @@
+#ifndef _KVI_SCRIPTBUTTON_H_
+#define _KVI_SCRIPTBUTTON_H_
+//
+// File : kvi_scriptbutton.h
+// Creation date : Wed Nov 14 15:43:39 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+#include "kvi_string.h"
+#include "kvi_styled_controls.h"
+
+#include <qtoolbutton.h>
+#include <qtoolbar.h>
+
+class KviKvsScript;
+class KviWindow;
+
+class KVIRC_API KviScriptUserButton : public KviStyledToolButton
+{
+ Q_OBJECT
+public:
+ KviScriptUserButton(QWidget * par,const char * name);
+ ~KviScriptUserButton();
+protected:
+ KviKvsScript * m_pScript;
+public:
+ void setButtonCode(KviKvsScript * pScript);
+ virtual void setButtonPixmap(const QPixmap & pix){ setIconSet(pix); };
+ void setButtonText(const char * text){ setTextLabel(text); };
+ virtual KviWindow * window();
+protected slots:
+ void btnClicked();
+};
+
+/*
+class KVIRC_API KviIrcToolBarScriptButton : public KviScriptUserButton
+{
+ Q_OBJECT
+public:
+ KviIrcToolBarScriptButton(QToolBar * p,const char * name);
+ ~KviIrcToolBarScriptButton();
+protected:
+ KviStr m_szCode;
+public:
+ virtual KviWindow * window();
+};
+*/
+
+class KVIRC_API KviWindowScriptButton : public KviScriptUserButton
+{
+ Q_OBJECT
+public:
+ KviWindowScriptButton(QWidget * p,KviWindow * wnd,const char * name);
+ ~KviWindowScriptButton();
+protected:
+ KviWindow * m_pWnd;
+public:
+ virtual void setButtonPixmap(const QPixmap & pix){ setIconSet(pix); setUsesBigPixmap(false); };
+ virtual KviWindow * window(){ return m_pWnd; };
+};
+
+#endif //_KVI_SCRIPTBUTTON_H_
diff --git a/src/kvirc/ui/kvi_scripteditor.cpp b/src/kvirc/ui/kvi_scripteditor.cpp
new file mode 100644
index 0000000..f94000d
--- /dev/null
+++ b/src/kvirc/ui/kvi_scripteditor.cpp
@@ -0,0 +1,139 @@
+//
+// File : kvi_scripteditor.cpp
+// Creation date : Sun Mar 28 1999 16:12:41 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#define __KVIRC__
+
+#define _KVI_SCRIPTEDITOR_CPP_
+
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+
+#include "kvi_scripteditor.h"
+#include "kvi_modulemanager.h"
+
+
+KviScriptEditor::KviScriptEditor(QWidget * par)
+: QWidget(par)
+{
+}
+
+
+KviScriptEditor::~KviScriptEditor()
+{
+}
+
+void KviScriptEditor::setText(const char * txt)
+{
+ setText(KviQCString(txt));
+}
+
+void KviScriptEditor::setText(const KviQCString &txt)
+{
+}
+
+void KviScriptEditor::setText(const QString &txt)
+{
+ setText(KviQCString(txt.utf8()));
+}
+
+void KviScriptEditor::setFindText(const QString &text)
+{
+}
+void KviScriptEditor::setInfoText(const QString &text)
+{
+}
+
+void KviScriptEditor::setFindLineeditReadOnly(bool b)
+{
+}
+
+void KviScriptEditor::getText(KviQCString &txt)
+{
+}
+
+void KviScriptEditor::setCursorPosition(QPoint)
+{
+}
+
+bool KviScriptEditor::isModified()
+{
+ return false;
+}
+
+QPoint KviScriptEditor::getCursor()
+{
+ return QPoint(0,0);
+}
+void KviScriptEditor::getText(QString &txt)
+{
+ KviQCString tmp;
+ getText(tmp);
+ txt = QString::fromUtf8(tmp.data());
+}
+
+KviScriptEditor * KviScriptEditor::getDummyEditor(QWidget * par)
+{
+ return new KviScriptEditor(par);
+}
+
+
+static KviScriptEditor * (*editorModuleCreateScriptEditor)(QWidget *);
+static void (*editorModuleDestroyScriptEditor)(KviScriptEditor *);
+
+
+KviScriptEditor * KviScriptEditor::createInstance(QWidget * par)
+{
+ KviModule * m = g_pModuleManager->getModule("editor");
+ // If the module can't be loaded...return a dummy widget
+// FIXME: #warning "Maybe provide some sort of basic default editable widget ?"
+ if(!m)return KviScriptEditor::getDummyEditor(par); // dummy implementation
+
+
+ editorModuleCreateScriptEditor = (KviScriptEditor * (*)(QWidget *)) m->getSymbol("editor_module_createScriptEditor");
+
+ if(!editorModuleCreateScriptEditor)return KviScriptEditor::getDummyEditor(par);
+
+ return editorModuleCreateScriptEditor(par);
+
+}
+
+void KviScriptEditor::destroyInstance(KviScriptEditor * e)
+{
+ KviModule * m = g_pModuleManager->getModule("editor");
+ if(!m)
+ {
+ delete e;
+ return;
+ }
+
+ editorModuleDestroyScriptEditor = (void (*)(KviScriptEditor *)) m->getSymbol("editor_module_destroyScriptEditor");
+
+ if(!editorModuleDestroyScriptEditor)
+ {
+ delete e;
+ return;
+ }
+
+ editorModuleDestroyScriptEditor(e);
+}
+
+#include "kvi_scripteditor.moc"
diff --git a/src/kvirc/ui/kvi_scripteditor.h b/src/kvirc/ui/kvi_scripteditor.h
new file mode 100644
index 0000000..e9f04c2
--- /dev/null
+++ b/src/kvirc/ui/kvi_scripteditor.h
@@ -0,0 +1,69 @@
+#ifndef _KVI_SCRIPTEDITOR_H_
+#define _KVI_SCRIPTEDITOR_H_
+
+//
+// File : kvi_scripteditor.h
+// Creation date : Sun Mar 28 1999 16:11:48 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+#include <qwidget.h>
+#include <qlineedit.h>
+#include "kvi_qcstring.h"
+
+//
+// This is the basic interface of a script editor widget
+//
+// Actually the REAL script editor is implemented in an
+// external module called "libkvieditor", and it is a really
+// huge class.
+// The constructor of this thing is protected: forget
+// about instantiating it directly
+//
+
+
+class KVIRC_API KviScriptEditor : public QWidget
+{
+ Q_OBJECT
+protected:
+ KviScriptEditor(QWidget * par);
+ ~KviScriptEditor();
+protected:
+ QLineEdit * m_pFindLineedit;
+public:
+ virtual void setText(const char * txt);
+ virtual void setText(const KviQCString &txt);
+ virtual void setText(const QString &txt);
+ virtual void getText(KviQCString &txt);
+ virtual void getText(QString &txt);
+ virtual void setInfoText(const QString &text);
+ virtual void setFindText(const QString &text);
+ virtual void setCursorPosition(QPoint);
+ virtual QPoint getCursor();
+ virtual void setFindLineeditReadOnly(bool b);
+ virtual bool isModified();
+
+ static KviScriptEditor * getDummyEditor(QWidget * par);
+ static KviScriptEditor * createInstance(QWidget * par);
+ static void destroyInstance(KviScriptEditor * e);
+};
+
+
+#endif //!_KVI_SCRIPTEDITOR_H_
diff --git a/src/kvirc/ui/kvi_selectors.cpp b/src/kvirc/ui/kvi_selectors.cpp
new file mode 100644
index 0000000..f8c9af9
--- /dev/null
+++ b/src/kvirc/ui/kvi_selectors.cpp
@@ -0,0 +1,839 @@
+//=============================================================================
+//
+// File : kvi_selectors.cpp
+// Creation date : Mon Nov 13 2000 15:22:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#define _KVI_SELECTORS_CPP_
+
+#include "kvi_selectors.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_filedialog.h"
+#include "kvi_kvs_script.h"
+
+#include <qlabel.h>
+#include <qpainter.h>
+#include <qlayout.h>
+#include <qcolordialog.h>
+#include <qpalette.h>
+#include <qfontdialog.h>
+#include "kvi_tal_popupmenu.h"
+
+KviBoolSelector::KviBoolSelector(QWidget * par,const QString & txt,bool *pOption,bool bEnabled)
+: KviStyledCheckBox(txt,par), KviSelectorInterface()
+{
+ setEnabled(bEnabled);
+ setChecked(*pOption);
+ m_pOption = pOption;
+}
+
+void KviBoolSelector::setNotEnabled(bool bNotEnabled)
+{
+ setEnabled(!bNotEnabled);
+}
+
+void KviBoolSelector::commit()
+{
+ *m_pOption = isChecked();
+}
+
+KviUIntSelector::KviUIntSelector(QWidget * par,const QString & txt,unsigned int *pOption,
+ unsigned int uLowBound,unsigned int uHighBound,unsigned int uDefault,bool bEnabled,bool bShortInt)
+: KviTalHBox(par) , KviSelectorInterface()
+{
+ m_pLabel = new QLabel(txt,this);
+ //m_pLineEdit = new QLineEdit(this);
+ //m_pLineEdit->setMaximumWidth(150);
+ m_pSpinBox = new QSpinBox(this);
+
+ m_bIsShortInt = bShortInt;
+
+ setEnabled(bEnabled);
+
+ m_pOption = pOption;
+
+ m_uLowBound = uLowBound;
+ m_uHighBound = uHighBound;
+ m_uDefault = uDefault;
+
+ m_pSpinBox->setMinValue(m_uLowBound);
+ m_pSpinBox->setMaxValue(m_uHighBound);
+
+ //KviStr tmp(KviStr::Format,"%u",bShortInt ? (unsigned int) *((unsigned short int *)pOption) : *pOption);
+ //m_pLineEdit->setText(tmp.ptr());
+ m_pSpinBox->setValue(bShortInt ? (unsigned int) *((unsigned short int *)pOption) : *pOption);
+
+ setSpacing(4);
+ setStretchFactor(m_pLabel,1);
+}
+
+void KviUIntSelector::setPrefix(const QString & txt)
+{
+ m_pSpinBox->setPrefix(txt);
+}
+
+void KviUIntSelector::setSuffix(const QString & txt)
+{
+ m_pSpinBox->setSuffix(txt);
+}
+
+void KviUIntSelector::commit()
+{
+ KviStr tmp = m_pSpinBox->cleanText();
+ bool bOk;
+ unsigned int val = tmp.toUInt(&bOk);
+ if(!bOk)val = m_uDefault;
+ if(m_uHighBound > m_uLowBound)
+ {
+ if(val < m_uLowBound)val = m_uLowBound;
+ else if(val > m_uHighBound)val = m_uHighBound;
+ }
+
+ if(m_bIsShortInt)*((unsigned short int *)m_pOption) = (unsigned short int)val;
+ else *m_pOption = val;
+}
+
+
+void KviUIntSelector::setEnabled(bool bEnabled)
+{
+ KviTalHBox::setEnabled(bEnabled);
+ m_pLabel->setEnabled(bEnabled);
+ m_pSpinBox->setEnabled(bEnabled);
+}
+
+
+
+KviStringSelector::KviStringSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled)
+: KviTalHBox(par) , KviSelectorInterface()
+{
+ m_pLabel = new QLabel(txt,this);
+ m_pLineEdit = new QLineEdit(this);
+ //m_pLineEdit->setMinimumWidth(200);
+ QString tmp = *pOption;
+ m_pLineEdit->setText(tmp);
+
+ setSpacing(4);
+ setStretchFactor(m_pLineEdit,1);
+
+ m_pOption = pOption;
+
+ setEnabled(bEnabled);
+}
+
+KviStringSelector::~KviStringSelector()
+{
+}
+
+void KviStringSelector::commit()
+{
+ QString tmp = m_pLineEdit->text();
+ *m_pOption = tmp;
+}
+
+void KviStringSelector::setEnabled(bool bEnabled)
+{
+ KviTalHBox::setEnabled(bEnabled);
+ m_pLineEdit->setEnabled(bEnabled);
+ m_pLabel->setEnabled(bEnabled);
+}
+
+void KviStringSelector::setText(const QString& text){
+ m_pLineEdit->setText(text);
+}
+
+KviPasswordSelector::KviPasswordSelector(QWidget * par,const QString & txt,QString *pOption,bool bEnabled)
+: KviStringSelector(par,txt,pOption,bEnabled)
+{
+ m_pLineEdit->setEchoMode(QLineEdit::Password);
+}
+
+
+
+
+KviPixmapPreview::KviPixmapPreview(QWidget * par)
+: KviTalScrollView(par)
+{
+ m_pPixmap = 0;
+ resizeContents(0,0);
+}
+
+
+KviPixmapPreview::~KviPixmapPreview()
+{
+}
+
+void KviPixmapPreview::setPixmap(KviPixmap * pix)
+{
+ m_pPixmap = pix;
+ if(m_pPixmap)
+ {
+ if(m_pPixmap->pixmap())
+ {
+ resizeContents(m_pPixmap->pixmap()->width(),m_pPixmap->pixmap()->height());
+ update();
+ return;
+ }
+ }
+ resizeContents(0,0);
+ update();
+}
+
+void KviPixmapPreview::drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph)
+{
+ if(m_pPixmap)
+ {
+ if(m_pPixmap->pixmap())
+ {
+ p->drawPixmap(clipx,clipy,*(m_pPixmap->pixmap()),clipx,clipy,clipw,cliph);
+ }
+ }
+}
+
+
+KviPixmapSelector::KviPixmapSelector(QWidget * par,const QString & txt,KviPixmap * pOption,bool bEnabled)
+: QWidget(par), KviSelectorInterface()
+{
+ QGridLayout * g = new QGridLayout(this,3,2,4,8);
+ m_pOption = pOption;
+
+ m_localPixmap = *pOption;
+
+ m_pCheckBox = new KviStyledCheckBox(txt,this);
+ m_pCheckBox->setChecked(m_localPixmap.pixmap());
+ connect(m_pCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool)));
+ g->addMultiCellWidget(m_pCheckBox,0,0,0,1);
+
+ m_pPreview = new KviPixmapPreview(this);
+ m_pPreview->setPixmap(&m_localPixmap);
+ g->addMultiCellWidget(m_pPreview,1,1,0,1);
+
+ m_pFileNameLabel = new QLabel(this);
+ m_pFileNameLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ if(m_localPixmap.pixmap())m_pFileNameLabel->setText(m_localPixmap.path());
+ g->addWidget(m_pFileNameLabel,2,0);
+
+ m_pChooseButton = new QPushButton("...",this);
+ g->addWidget(m_pChooseButton,2,1);
+ connect(m_pChooseButton,SIGNAL(clicked()),this,SLOT(choosePixmap()));
+
+ g->setRowStretch(1,1);
+ g->setColStretch(0,1);
+
+ setEnabled(bEnabled);
+}
+
+KviPixmapSelector::~KviPixmapSelector()
+{
+}
+
+
+void KviPixmapSelector::checkBoxToggled(bool bEnabled)
+{
+ setEnabled(isEnabled());
+}
+
+void KviPixmapSelector::commit()
+{
+ if(m_pCheckBox->isChecked())
+ {
+ *m_pOption = m_localPixmap;
+ } else {
+ *m_pOption = KviPixmap(); // null pixmap
+ }
+}
+
+void KviPixmapSelector::choosePixmap()
+{
+// KviStr tmp;
+ QString tmp;
+ if(KviFileDialog::askForOpenFileName(tmp,__tr("Choose an Image File - KVIrc")))
+ {
+ setImagePath(tmp);
+ }
+}
+
+void KviPixmapSelector::setImagePath(const char * path)
+{
+ m_localPixmap.load(path);
+ m_pPreview->setPixmap(&m_localPixmap);
+
+ if(m_localPixmap.isNull())
+ {
+ KviStr tmp2(KviStr::Format,__tr("Unloadable: %s"),path);
+ m_pFileNameLabel->setText(tmp2.ptr());
+ m_pCheckBox->setChecked(false);
+ } else {
+ m_pCheckBox->setChecked(true);
+ m_pFileNameLabel->setText(path);
+ }
+
+ setEnabled(isEnabled());
+}
+
+void KviPixmapSelector::setEnabled(bool bEnabled)
+{
+ QWidget::setEnabled(bEnabled);
+ m_pCheckBox->setEnabled(bEnabled);
+ m_pPreview->setEnabled(bEnabled && m_pCheckBox->isChecked());
+ m_pFileNameLabel->setEnabled(bEnabled && m_pCheckBox->isChecked());
+ m_pChooseButton->setEnabled(bEnabled && m_pCheckBox->isChecked());
+}
+
+
+
+// FIXME: #warning "Option for DIR_MUST_EXISTS...(this widget could be turned into a file selector too)"
+KviFileSelector::KviFileSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled,unsigned int uFlags,const QString &szFilter)
+: KviTalHBox(par), KviSelectorInterface()
+{
+ m_uFlags = uFlags;
+ m_szFilter = szFilter;
+ m_pLabel = new QLabel(txt,this);
+ m_pLineEdit = new QLineEdit(this);
+ //m_pLineEdit->setMinimumWidth(200);
+ m_pLineEdit->setText(*pOption);
+ m_pButton = new QPushButton(__tr2qs("&Browse..."),this);
+ connect(m_pButton,SIGNAL(clicked()),this,SLOT(browseClicked()));
+
+ setSpacing(4);
+ setStretchFactor(m_pLineEdit,1);
+
+ m_pOption = pOption;
+
+ setEnabled(bEnabled);
+}
+
+
+void KviFileSelector::commit()
+{
+ *m_pOption = m_pLineEdit->text();
+}
+
+void KviFileSelector::setEnabled(bool bEnabled)
+{
+ KviTalHBox::setEnabled(bEnabled);
+ m_pLineEdit->setEnabled(bEnabled);
+ m_pLabel->setEnabled(bEnabled);
+ m_pButton->setEnabled(bEnabled);
+}
+
+void KviFileSelector::browseClicked()
+{
+ select();
+}
+
+void KviFileSelector::setSelection(const QString &szSelection)
+{
+ m_pLineEdit->setText(szSelection);
+}
+
+
+void KviFileSelector::select()
+{
+ //KviStr tmp;
+ QString tmp = *m_pOption;
+ if(m_uFlags & ChooseSaveFileName)
+ {
+ if(KviFileDialog::askForSaveFileName(tmp,__tr2qs("Choose a File - KVIrc"),tmp,m_szFilter,true,!(m_uFlags & DontConfirmOverwrite)))
+ {
+ m_pLineEdit->setText(tmp);
+ emit selectionChanged(tmp);
+ }
+ } else {
+ if(KviFileDialog::askForOpenFileName(tmp,__tr2qs("Choose a File - KVIrc"),tmp,m_szFilter,true))
+ {
+ m_pLineEdit->setText(tmp);
+ emit selectionChanged(tmp);
+ }
+ }
+
+}
+
+
+KviDirectorySelector::KviDirectorySelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled)
+: KviFileSelector(par,txt,pOption,bEnabled)
+{
+}
+
+void KviDirectorySelector::select()
+{
+ QString tmp;
+ if(KviFileDialog::askForDirectoryName(tmp,__tr2qs("Choose a Directory - KVIrc"),""))
+ {
+ m_pLineEdit->setText(tmp);
+ }
+
+}
+
+
+
+
+
+
+
+
+KviStringListSelector::KviStringListSelector(QWidget * par,const QString & txt,QStringList * pOption,bool bEnabled)
+: KviTalVBox(par), KviSelectorInterface()
+{
+ m_pLabel = new QLabel(txt,this);
+ m_pListBox = new KviTalListBox(this);
+ m_pLineEdit = new QLineEdit(this);
+ connect(m_pLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(textChanged(const QString &)));
+ connect(m_pLineEdit,SIGNAL(returnPressed()),this,SLOT(addClicked()));
+ KviTalHBox * hBox = new KviTalHBox(this);
+ m_pAddButton = new QPushButton(__tr2qs("A&dd"),hBox);
+ connect(m_pAddButton,SIGNAL(clicked()),this,SLOT(addClicked()));
+ m_pRemoveButton = new QPushButton(__tr2qs("Re&move"),hBox);
+ connect(m_pRemoveButton,SIGNAL(clicked()),this,SLOT(removeClicked()));
+ m_pOption = pOption;
+ m_pListBox->insertStringList(*pOption);
+ m_pListBox->setSelectionMode(KviTalListBox::Extended);
+ connect(m_pListBox,SIGNAL(selectionChanged()),this,SLOT(selectionChanged()));
+ setSpacing(4);
+ setStretchFactor(m_pListBox,1);
+ setEnabled(bEnabled);
+}
+
+KviStringListSelector::~KviStringListSelector()
+{
+}
+
+void KviStringListSelector::selectionChanged()
+{
+ unsigned int uCount = m_pListBox->count();
+ bool bSomeSelected = false;
+ for(unsigned int u=0;u<uCount;u++)
+ {
+ if(m_pListBox->isSelected(u))
+ {
+ bSomeSelected = true;
+ break;
+ }
+ }
+ m_pRemoveButton->setEnabled(isEnabled() && bSomeSelected);
+}
+
+void KviStringListSelector::textChanged(const QString &str)
+{
+ str.stripWhiteSpace();
+ m_pAddButton->setEnabled((str.length() > 0) && isEnabled());
+}
+
+void KviStringListSelector::setEnabled(bool bEnabled)
+{
+ KviTalVBox::setEnabled(bEnabled);
+ m_pLineEdit->setEnabled(bEnabled);
+ m_pLabel->setEnabled(bEnabled);
+ QString txt = m_pLineEdit->text();
+ txt.stripWhiteSpace();
+ m_pAddButton->setEnabled(bEnabled && (txt.length() > 0));
+ unsigned int uCount = m_pListBox->count();
+ bool bSomeSelected = false;
+ for(unsigned int u=0;u<uCount;u++)
+ {
+ if(m_pListBox->isSelected(u))
+ {
+ bSomeSelected = true;
+ break;
+ }
+ }
+ m_pRemoveButton->setEnabled(bEnabled && bSomeSelected);
+ m_pListBox->setEnabled(bEnabled);
+}
+
+void KviStringListSelector::commit()
+{
+ unsigned int uCount = m_pListBox->count();
+ m_pOption->clear();
+ for(unsigned int u=0;u<uCount;u++)
+ {
+ QString str = m_pListBox->text(u);
+ str.stripWhiteSpace();
+ if(str.length() > 0)m_pOption->append(str);
+ }
+}
+
+void KviStringListSelector::addClicked()
+{
+ QString str = m_pLineEdit->text();
+ str.stripWhiteSpace();
+ if(str.length() > 0)m_pListBox->insertItem(str);
+ m_pLineEdit->setText("");
+}
+
+void KviStringListSelector::removeClicked()
+{
+ unsigned int uCount = m_pListBox->count();
+ for(unsigned int u=0;u<uCount;u++)
+ {
+ while(m_pListBox->isSelected(u))m_pListBox->removeItem(u);
+ }
+}
+
+
+KviColorSelector::KviColorSelector(QWidget * par,const QString & txt,QColor * pOption,bool bEnabled)
+: KviTalHBox(par), KviSelectorInterface()
+{
+ m_pLabel = new QLabel(txt,this);
+
+ m_pButton = new QPushButton(" ",this);
+ // m_pButton->setMinimumWidth(150);
+ connect(m_pButton,SIGNAL(clicked()),this,SLOT(changeClicked()));
+
+ setSpacing(4);
+ setStretchFactor(m_pLabel,1);
+
+ setButtonPalette(pOption);
+
+ m_pOption = pOption;
+
+ setEnabled(bEnabled);
+}
+
+void KviColorSelector::setButtonPalette(QColor * pOption)
+{
+ QPalette pal(*pOption,colorGroup().background());
+ m_memColor = *pOption;
+ m_pButton->setPalette(pal);
+
+ QPixmap pix(16,16);
+ pix.fill(*pOption);
+ m_pButton->setIconSet(pix);
+}
+
+void KviColorSelector::forceColor(QColor clr)
+{
+ setButtonPalette(&clr);
+}
+
+void KviColorSelector::changeClicked()
+{
+ QColor tmp = QColorDialog::getColor(m_memColor);
+ if(tmp.isValid())setButtonPalette(&tmp);
+}
+
+void KviColorSelector::commit()
+{
+ *m_pOption = m_memColor;
+}
+
+void KviColorSelector::setEnabled(bool bEnabled)
+{
+ KviTalHBox::setEnabled(bEnabled);
+ m_pLabel->setEnabled(bEnabled);
+ m_pButton->setEnabled(bEnabled);
+}
+
+
+KviFontSelector::KviFontSelector(QWidget * par,const QString & txt,QFont * pOption,bool bEnabled)
+: KviTalHBox(par), KviSelectorInterface()
+{
+ m_pLabel = new QLabel(txt,this);
+
+ m_pButton = new QPushButton("",this);
+ // m_pButton->setMinimumWidth(150);
+ connect(m_pButton,SIGNAL(clicked()),this,SLOT(changeClicked()));
+
+ setSpacing(4);
+ setStretchFactor(m_pLabel,1);
+
+ setButtonFont(pOption);
+
+ m_pOption = pOption;
+
+ setEnabled(bEnabled);
+}
+
+void KviFontSelector::setButtonFont(QFont * pOption)
+{
+ m_pButton->setText(pOption->family());
+ m_pButton->setFont(*pOption);
+}
+
+void KviFontSelector::changeClicked()
+{
+ bool bOk;
+ QFont tmp = QFontDialog::getFont(&bOk,m_pButton->font());
+ if(bOk)setButtonFont(&tmp);
+}
+
+void KviFontSelector::commit()
+{
+ *m_pOption = m_pButton->font();
+}
+
+void KviFontSelector::setEnabled(bool bEnabled)
+{
+ KviTalHBox::setEnabled(bEnabled);
+ m_pLabel->setEnabled(bEnabled);
+ m_pButton->setEnabled(bEnabled);
+}
+
+
+
+
+
+KviMircTextColorSelector::KviMircTextColorSelector(QWidget * par,const QString &txt,unsigned int * uFore,unsigned int * uBack,bool bEnabled)
+: KviTalHBox(par), KviSelectorInterface()
+{
+ m_pLabel = new QLabel(txt,this);
+
+ m_pButton = new QPushButton(__tr2qs("Sample Text"),this);
+ // m_pButton->setMinimumWidth(150);
+ connect(m_pButton,SIGNAL(clicked()),this,SLOT(buttonClicked()));
+
+ setSpacing(4);
+ setStretchFactor(m_pLabel,1);
+
+ m_pUFore = uFore;
+ m_pUBack = uBack;
+
+ m_uBack = *uBack;
+ m_uFore = *uFore;
+
+ setButtonPalette();
+
+ setEnabled(bEnabled);
+
+ m_pContextPopup = new KviTalPopupMenu(this);
+
+ m_pForePopup = new KviTalPopupMenu(this);
+ connect(m_pForePopup,SIGNAL(activated(int)),this,SLOT(foreSelected(int)));
+ int i;
+ for(i=0;i<KVI_MIRCCOLOR_MAX_FOREGROUND;i++)
+ {
+ QPixmap tmp(120,16);
+ tmp.fill(KVI_OPTION_MIRCCOLOR(i));
+#ifdef COMPILE_USE_QT4
+ int id = m_pForePopup->insertItem(tmp,QString("x"));
+#else
+ int id = m_pForePopup->insertItem(tmp);
+#endif
+ m_pForePopup->setItemParameter(id,i);
+ }
+ m_pContextPopup->insertItem(__tr2qs("Foreground"),m_pForePopup);
+
+ m_pBackPopup = new KviTalPopupMenu(this);
+ connect(m_pBackPopup,SIGNAL(activated(int)),this,SLOT(backSelected(int)));
+ i = m_pBackPopup->insertItem(__tr2qs("Transparent"));
+ m_pBackPopup->setItemParameter(i,KVI_TRANSPARENT);
+ for(i=0;i<KVI_MIRCCOLOR_MAX_BACKGROUND;i++)
+ {
+ QPixmap tmp(120,16);
+ tmp.fill(KVI_OPTION_MIRCCOLOR(i));
+#ifdef COMPILE_USE_QT4
+ int id = m_pForePopup->insertItem(tmp,QString("x"));
+#else
+ int id = m_pBackPopup->insertItem(tmp);
+#endif
+ m_pBackPopup->setItemParameter(id,i);
+ }
+ m_pContextPopup->insertItem(__tr2qs("Background"),m_pBackPopup);
+}
+
+KviMircTextColorSelector::~KviMircTextColorSelector()
+{
+}
+
+void KviMircTextColorSelector::commit()
+{
+ *m_pUFore = m_uFore;
+ *m_pUBack = m_uBack;
+}
+
+void KviMircTextColorSelector::setEnabled(bool bEnabled)
+{
+ KviTalHBox::setEnabled(bEnabled);
+ m_pLabel->setEnabled(bEnabled);
+ m_pButton->setEnabled(bEnabled);
+}
+
+void KviMircTextColorSelector::setButtonPalette()
+{
+ QPalette pal;
+
+ if(m_uBack > KVI_MIRCCOLOR_MAX_BACKGROUND)
+ {
+ if(m_uBack != KVI_TRANSPARENT)m_uBack = KVI_TRANSPARENT;
+ pal = palette();
+ } else {
+ pal = QPalette(KVI_OPTION_MIRCCOLOR(m_uBack));
+ }
+
+ if(m_uFore > KVI_MIRCCOLOR_MAX_FOREGROUND)m_uFore = KVI_MIRCCOLOR_MAX_FOREGROUND;
+
+ pal.setColor(QColorGroup::ButtonText,KVI_OPTION_MIRCCOLOR(m_uFore));
+ pal.setColor(QColorGroup::Text,KVI_OPTION_MIRCCOLOR(m_uFore));
+
+ m_pButton->setPalette(pal);
+}
+
+void KviMircTextColorSelector::buttonClicked()
+{
+ QPoint p = m_pButton->mapToGlobal(QPoint(0,m_pButton->height()));
+ m_pContextPopup->popup(p);
+}
+
+void KviMircTextColorSelector::foreSelected(int id)
+{
+ if(m_pForePopup)
+ m_uFore = m_pForePopup->itemParameter(id);
+ setButtonPalette();
+}
+
+void KviMircTextColorSelector::backSelected(int id)
+{
+ if(m_pBackPopup)
+ m_uBack = m_pBackPopup->itemParameter(id);
+ setButtonPalette();
+}
+
+KviSoundSelector::KviSoundSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled)
+:KviFileSelector(par,txt,pOption,bEnabled)
+{
+ m_pPlayButton = new QPushButton(__tr2qs("Play"),this);
+ connect(m_pPlayButton,SIGNAL(clicked()),this,SLOT(playSound()));
+}
+
+KviSoundSelector::~KviSoundSelector()
+{
+}
+
+void KviSoundSelector::playSound()
+{
+ KviKvsScript::run("snd.play $0",0,new KviKvsVariantList(new KviKvsVariant(m_pLineEdit->text())));
+}
+
+void KviSoundSelector::setEnabled(bool bEnabled)
+{
+ KviFileSelector::setEnabled(bEnabled);
+ m_pPlayButton->setEnabled(bEnabled);
+}
+
+KviChanListViewItem::KviChanListViewItem(KviTalListView* pList,QString szChan,QString szPass)
+:KviTalListViewItem(pList,szChan)
+{
+ m_szPass=szPass;
+ QString mask;
+ mask.fill('*',szPass.length());
+ setText(1,mask);
+}
+
+KviCahnnelListSelector::KviCahnnelListSelector(QWidget * par,const QString & txt,QStringList * pOption,bool bEnabled)
+: KviTalVBox(par), KviSelectorInterface()
+{
+ m_pLabel = new QLabel(txt,this);
+ m_pListView = new KviTalListView(this);
+ m_pListView->addColumn(__tr2qs("Channel name"));
+ m_pListView->addColumn(__tr2qs("Channel password"));
+
+ KviTalHBox* pEditsHBox = new KviTalHBox(this);
+
+ m_pChanLineEdit = new QLineEdit(pEditsHBox);
+ connect(m_pChanLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(textChanged(const QString &)));
+ connect(m_pChanLineEdit,SIGNAL(returnPressed()),this,SLOT(addClicked()));
+
+ m_pPassLineEdit = new QLineEdit(pEditsHBox);
+ m_pPassLineEdit->setEchoMode(QLineEdit::Password);
+ connect(m_pPassLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(textChanged(const QString &)));
+ connect(m_pPassLineEdit,SIGNAL(returnPressed()),this,SLOT(addClicked()));
+
+
+ KviTalHBox * hBox = new KviTalHBox(this);
+ m_pAddButton = new QPushButton(__tr2qs("A&dd"),hBox);
+ connect(m_pAddButton,SIGNAL(clicked()),this,SLOT(addClicked()));
+ m_pRemoveButton = new QPushButton(__tr2qs("Re&move"),hBox);
+ connect(m_pRemoveButton,SIGNAL(clicked()),this,SLOT(removeClicked()));
+ m_pOption = pOption;
+
+ for ( QStringList::Iterator it = pOption->begin(); it != pOption->end(); ++it ) {
+ new KviChanListViewItem(m_pListView,(*it).section(':',0,0),(*it).section(':',1));
+ }
+
+ m_pListView->setSelectionMode(KviTalListView::Extended);
+ m_pListView->setAllColumnsShowFocus(TRUE);
+ connect(m_pListView,SIGNAL(selectionChanged()),this,SLOT(selectionChanged()));
+ setSpacing(4);
+ setStretchFactor(m_pListView,1);
+ setEnabled(bEnabled);
+}
+
+KviCahnnelListSelector::~KviCahnnelListSelector()
+{
+}
+
+void KviCahnnelListSelector::commit()
+{
+ m_pOption->clear();
+ register KviChanListViewItem* pItem;
+ KviTalListViewItemIterator it( m_pListView);
+ while ( it.current() ) {
+ pItem = (KviChanListViewItem*)( it.current() );
+ m_pOption->append(pItem->text(0)+":"+pItem->pass());
+ ++it;
+ }
+}
+
+void KviCahnnelListSelector::setEnabled(bool bEnabled)
+{
+ m_pLabel->setEnabled(bEnabled);
+ m_pListView->setEnabled(bEnabled);
+ m_pChanLineEdit->setEnabled(bEnabled);
+ m_pPassLineEdit->setEnabled(bEnabled);
+ m_pAddButton->setEnabled(bEnabled);
+ m_pRemoveButton->setEnabled(bEnabled);
+}
+
+void KviCahnnelListSelector::textChanged(const QString &str)
+{
+ m_pAddButton->setEnabled(!m_pChanLineEdit->text().isEmpty());
+}
+
+void KviCahnnelListSelector::selectionChanged()
+{
+}
+
+void KviCahnnelListSelector::addClicked()
+{
+ if(!m_pChanLineEdit->text().isEmpty())
+ {
+ new KviChanListViewItem(m_pListView,m_pChanLineEdit->text().stripWhiteSpace(),m_pPassLineEdit->text().stripWhiteSpace());
+ m_pChanLineEdit->clear();
+ m_pPassLineEdit->clear();
+ }
+}
+
+void KviCahnnelListSelector::removeClicked()
+{
+ KviPointerList<KviTalListViewItem> lst;
+ KviTalListViewItemIterator it( m_pListView, KviTalListViewItemIterator::Selected );
+ while ( it.current() ) {
+ lst.append((KviTalListViewItem *)it.current() );
+ ++it;
+ }
+ lst.setAutoDelete(TRUE);
+ lst.clear();
+}
+
+#include "kvi_selectors.moc"
diff --git a/src/kvirc/ui/kvi_selectors.h b/src/kvirc/ui/kvi_selectors.h
new file mode 100644
index 0000000..3e62012
--- /dev/null
+++ b/src/kvirc/ui/kvi_selectors.h
@@ -0,0 +1,367 @@
+#ifndef _KVI_SELECTORS_H_
+#define _KVI_SELECTORS_H_
+
+//=============================================================================
+//
+// File : kvi_selectors.h
+// Creation date : Mon Now 13 2000 15:21:10 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+
+#include "kvi_settings.h"
+
+#include <qcheckbox.h>
+#include "kvi_tal_hbox.h"
+#include "kvi_tal_vbox.h"
+#include <qlineedit.h>
+#include <qlabel.h>
+#include "kvi_tal_scrollview.h"
+#include <qpushbutton.h>
+#include <qcolor.h>
+#include <qfont.h>
+#include "kvi_tal_listbox.h"
+#include "kvi_tal_listview.h"
+#include <qspinbox.h>
+#include <qstringlist.h>
+#include <qvalidator.h>
+
+#include "kvi_string.h"
+#include "kvi_pixmap.h"
+#include "kvi_styled_controls.h"
+
+//#ifndef _KVI_SELECTORS_CPP_
+// extern void commitAllSelectors(QWidget * par,const char * classname);
+//#endif
+
+
+//
+// This is the common KviSelectorInterface
+//
+// Note: I'm always learning
+// Today I have discovered that:
+// QObject * o = new KviBoolSelector(...)
+// ((KviSelectorInterface *)o)->commit()
+// Does not work (SIGSEGV when jumping into commit(): bad vtable entry)
+// But the following works fine:
+// KviBoolSelector * b = new KviBoolSelector(...)
+// ((KviSelectorInterface *)b)->commit();
+// Mmmmmh.... the assembler generated by gcc
+// uses two different vtable offsets in the two cases
+// why ?
+//
+
+class KVIRC_API KviSelectorInterface
+{
+public:
+ KviSelectorInterface(){};
+ virtual ~KviSelectorInterface(){};
+public:
+ virtual void commit(){};
+};
+
+class KVIRC_API KviBoolSelector : public KviStyledCheckBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviBoolSelector(QWidget * par,const QString & txt,bool *pOption,bool bEnabled);
+ ~KviBoolSelector(){};
+private:
+ bool * m_pOption;
+public:
+ virtual void commit();
+public slots:
+ void setNotEnabled(bool bNotEnabled);
+};
+
+class KVIRC_API KviStringSelector : public KviTalHBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviStringSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled);
+ ~KviStringSelector();
+protected:
+ QLabel * m_pLabel;
+ QLineEdit * m_pLineEdit;
+ QString * m_pOption;
+public:
+ void setValidator(QValidator * v){ m_pLineEdit->setValidator(v); };
+ void setMinimumLabelWidth(unsigned int uWidth){ m_pLabel->setMinimumWidth(uWidth); };
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+ void setText(const QString& text);
+};
+
+
+class KVIRC_API KviPasswordSelector : public KviStringSelector
+{
+ Q_OBJECT
+public:
+ KviPasswordSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled);
+ ~KviPasswordSelector(){};
+};
+
+class KVIRC_API KviPixmapPreview : public KviTalScrollView
+{
+ Q_OBJECT
+public:
+ KviPixmapPreview(QWidget * par);
+ ~KviPixmapPreview();
+protected:
+ KviPixmap * m_pPixmap;
+public:
+ void setPixmap(KviPixmap * pix);
+protected:
+ virtual void drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph);
+
+};
+
+class KVIRC_API KviPixmapSelector : public QWidget, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviPixmapSelector(QWidget * par,const QString & txt,KviPixmap * pOption,bool bEnabled);
+ ~KviPixmapSelector();
+private:
+ KviStyledCheckBox * m_pCheckBox;
+ QLabel * m_pFileNameLabel;
+ KviPixmapPreview * m_pPreview;
+ QPushButton * m_pChooseButton;
+ KviPixmap * m_pOption;
+ KviPixmap m_localPixmap;
+public:
+ void setImagePath(const char * path);
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+protected slots:
+ void checkBoxToggled(bool bEnabled);
+ void choosePixmap();
+};
+
+class KVIRC_API KviUIntSelector : public KviTalHBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviUIntSelector(QWidget * par,const QString & txt,unsigned int *pOption,
+ unsigned int uLowBound,unsigned int uHighBound,unsigned int uDefault,bool bEnabled,bool bShortInt = false);
+ ~KviUIntSelector(){};
+private:
+ QLabel * m_pLabel;
+ QSpinBox * m_pSpinBox;
+ unsigned int * m_pOption;
+ unsigned int m_uLowBound;
+ unsigned int m_uHighBound;
+ unsigned int m_uDefault;
+ bool m_bIsShortInt;
+public:
+ virtual void setPrefix(const QString & txt);
+ virtual void setSuffix(const QString & txt);
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+};
+
+
+class KVIRC_API KviFileSelector : public KviTalHBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviFileSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled,unsigned int uFlags = 0,const QString &szFilter = QString::null);
+ ~KviFileSelector(){};
+public:
+ enum Flags {
+ ChooseSaveFileName = 1,
+ DontConfirmOverwrite = 2
+ };
+protected:
+ QLabel * m_pLabel;
+ QLineEdit * m_pLineEdit;
+ QPushButton * m_pButton;
+ QString * m_pOption;
+ unsigned int m_uFlags;
+ QString m_szFilter;
+public:
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+ void setSelection(const QString &szSelection);
+signals:
+ void selectionChanged(const QString &szNewValue);
+private slots:
+ void browseClicked();
+protected:
+ virtual void select();
+};
+
+class KVIRC_API KviDirectorySelector : public KviFileSelector
+{
+ Q_OBJECT
+public:
+ KviDirectorySelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled);
+ ~KviDirectorySelector(){};
+protected:
+ virtual void select();
+};
+
+
+class KVIRC_API KviColorSelector : public KviTalHBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviColorSelector(QWidget * par,const QString & txt,QColor * pOption,bool bEnabled);
+ ~KviColorSelector(){};
+private:
+ QLabel * m_pLabel;
+ QColor * m_pOption;
+ QColor m_memColor;
+ QPushButton * m_pButton;
+public:
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+ QColor getColor(){ return m_memColor; };
+ void forceColor(QColor clr);
+private:
+ void setButtonPalette(QColor * pOption);
+private slots:
+ void changeClicked();
+};
+
+class KVIRC_API KviFontSelector : public KviTalHBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviFontSelector(QWidget * par,const QString & txt,QFont * pOption,bool bEnabled);
+ ~KviFontSelector(){};
+private:
+ QLabel * m_pLabel;
+ QFont * m_pOption;
+ QPushButton * m_pButton;
+public:
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+private:
+ void setButtonFont(QFont * pOption);
+private slots:
+ void changeClicked();
+};
+
+class KVIRC_API KviStringListSelector : public KviTalVBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviStringListSelector(QWidget * par,const QString & txt,QStringList * pOption,bool bEnabled);
+ ~KviStringListSelector();
+private:
+ QLabel * m_pLabel;
+ KviTalListBox * m_pListBox;
+ QLineEdit * m_pLineEdit;
+ QPushButton * m_pAddButton;
+ QPushButton * m_pRemoveButton;
+ QStringList * m_pOption;
+public:
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+private slots:
+ void textChanged(const QString &str);
+ void selectionChanged();
+ void addClicked();
+ void removeClicked();
+};
+
+class KviTalPopupMenu;
+
+class KVIRC_API KviMircTextColorSelector : public KviTalHBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviMircTextColorSelector(QWidget * par,const QString &txt,unsigned int * uFore,unsigned int * uBack,bool bEnabled);
+ ~KviMircTextColorSelector();
+private:
+ QLabel *m_pLabel;
+ QPushButton * m_pButton;
+ unsigned int * m_pUFore;
+ unsigned int * m_pUBack;
+ unsigned int m_uFore;
+ unsigned int m_uBack;
+ KviTalPopupMenu * m_pContextPopup;
+ KviTalPopupMenu * m_pForePopup;
+ KviTalPopupMenu * m_pBackPopup;
+public:
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+protected slots:
+ void buttonClicked();
+ void foreSelected(int);
+ void backSelected(int);
+protected:
+ void setButtonPalette();
+};
+
+
+class KVIRC_API KviSoundSelector : public KviFileSelector
+{
+ Q_OBJECT
+public:
+ KviSoundSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled);
+ ~KviSoundSelector();
+protected:
+ QPushButton *m_pPlayButton;
+private slots:
+ void playSound();
+public:
+ virtual void setEnabled(bool bEnabled);
+};
+
+class KVIRC_API KviChanListViewItem : public KviTalListViewItem
+{
+private:
+ QString m_szPass;
+public:
+ KviChanListViewItem(KviTalListView* pList,QString szChan,QString szPass);
+ ~KviChanListViewItem() {};
+
+ const QString& pass() { return m_szPass; }
+};
+
+class KVIRC_API KviCahnnelListSelector : public KviTalVBox, public KviSelectorInterface
+{
+ Q_OBJECT
+public:
+ KviCahnnelListSelector(QWidget * par,const QString & txt,QStringList * pOption,bool bEnabled);
+ ~KviCahnnelListSelector();
+private:
+ QLabel * m_pLabel;
+ KviTalListView * m_pListView;
+ QLineEdit * m_pChanLineEdit;
+ QLineEdit * m_pPassLineEdit;
+ QPushButton * m_pAddButton;
+ QPushButton * m_pRemoveButton;
+ QStringList * m_pOption;
+public:
+ virtual void commit();
+ virtual void setEnabled(bool bEnabled);
+private slots:
+ void textChanged(const QString &str);
+ void selectionChanged();
+ void addClicked();
+ void removeClicked();
+};
+
+
+
+#endif //!_KVI_SELECTORS_H_
diff --git a/src/kvirc/ui/kvi_splash.cpp b/src/kvirc/ui/kvi_splash.cpp
new file mode 100644
index 0000000..7b6b717
--- /dev/null
+++ b/src/kvirc/ui/kvi_splash.cpp
@@ -0,0 +1,222 @@
+//=============================================================================
+//
+// File : kvi_splash.cpp
+// Creation date : Wed Aug 8 2001 17:46:10 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#include "kvi_string.h"
+#include "kvi_app.h"
+#include "kvi_defaults.h"
+#include "kvi_splash.h"
+#include "kvi_locale.h"
+#include "kvi_fileutils.h"
+#include <qsplashscreen.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qdesktopwidget.h>
+#endif
+
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qlayout.h>
+
+#include <stdio.h>
+
+
+KviSplashScreen::KviSplashScreen()
+: QSplashScreen(QPixmap(1,1),Qt::WStyle_NoBorder | Qt::WType_TopLevel | Qt::WStyle_Customize | Qt::WStyle_StaysOnTop | Qt::WStyle_Splash)
+{
+ QString szPix;
+ QPixmap * pix = 0;
+
+ // check for the current theme splash screen pointer
+ QString szPointerFile;
+ g_pApp->getLocalKvircDirectory(szPointerFile,KviApp::Themes,"current-splash");
+ if(KviFileUtils::fileExists(szPointerFile))
+ {
+ QString szBuf;
+ KviFileUtils::readFile(szPointerFile,szBuf);
+ if(!szBuf.isEmpty())
+ {
+ g_pApp->getLocalKvircDirectory(szPix,KviApp::Themes,szBuf);
+ KviQString::ensureLastCharIs(szPix,KVI_PATH_SEPARATOR_CHAR);
+ szPix.append("kvi_splash.png");
+ pix = new QPixmap(szPix);
+ if(pix->isNull())
+ {
+ // no way..
+ delete pix;
+ pix = 0;
+ } else {
+ // else we might have a themed splash screen
+// g_pApp->getLocalKvircDirectory(szPix,KviApp::Themes,szBuf);
+ KviQString::ensureLastCharIs(szPix,KVI_PATH_SEPARATOR_CHAR);
+ szPix.append("kvi_splash_overlay.png");
+ m_pOverlay = new QPixmap(szPix);
+ if(m_pOverlay->isNull())
+ {
+ // no way..
+ delete pix;
+ pix = 0;
+ delete m_pOverlay;
+ m_pOverlay = 0;
+ }
+ }
+ }
+ }
+
+ if(!pix)
+ {
+ if(g_pApp->findImage(szPix,"kvi_splash.png"))
+ {
+ pix = new QPixmap(szPix);
+ } else {
+ // dummy image
+ pix = new QPixmap(300,200);
+ }
+
+ if(g_pApp->findImage(szPix,"kvi_splash_overlay.png"))
+ {
+ m_pOverlay = new QPixmap(szPix);
+ } else {
+ m_pOverlay = new QPixmap(300,20);
+ }
+ }
+
+ setPixmap(*pix);
+ m_pTimer = new QTimer(this);
+ connect(m_pTimer,SIGNAL(timeout()),this,SLOT(suicide()));
+ delete pix;
+
+#ifdef COMPILE_USE_QT4
+ setWindowOpacity(0);
+ m_bIncreasing=true;
+ m_rTransparency=0;
+ m_pFadeTimer= new QTimer(this);
+ connect(m_pFadeTimer,SIGNAL(timeout()),this,SLOT(fadeTimerShot()));
+ m_pFadeTimer->start(6);
+#endif
+}
+
+// We don't need messages on the splash: they just add work to the translators and nobody can read them anyway :D
+//void KviSplashScreen::message(QString szMessage)
+//{
+ //QSplashScreen::message(szMessage, Qt::AlignRight | Qt::AlignBottom, Qt::white);
+//}
+
+KviSplashScreen::~KviSplashScreen()
+{
+ g_pSplashScreen = 0; // make sure it's true
+ delete m_pTimer;
+ delete m_pOverlay;
+}
+
+
+void KviSplashScreen::showEvent(QShowEvent *e)
+{
+ move((g_pApp->desktop()->width() - width())/2,
+ (g_pApp->desktop()->height() - height())/2);
+ m_creationTime = QTime::currentTime();
+}
+
+void KviSplashScreen::hideEvent(QHideEvent *e)
+{
+ suicide();
+}
+
+void KviSplashScreen::setProgress(int progress)
+{
+#ifdef COMPILE_USE_QT4
+ QPixmap slowQt4Copy = pixmap();
+ QPainter painter(&slowQt4Copy);
+ QSize size = slowQt4Copy.size();
+ int w = (m_pOverlay->width() * progress) / 100;
+ painter.drawPixmap(0,size.height() - m_pOverlay->height(),w,m_pOverlay->height(),*m_pOverlay,0,0,w,m_pOverlay->height());
+ painter.end();
+ setPixmap(slowQt4Copy);
+#else
+ QPainter painter(pixmap());
+ QSize size = pixmap()->size();
+ painter.drawPixmap(0,size.height() - m_pOverlay->height(),*m_pOverlay,0,0,(m_pOverlay->width() * progress) / 100,m_pOverlay->height());
+ painter.end();
+#endif
+ //raise();
+ repaint();
+ g_pApp->processEvents(); //damn...
+}
+
+#define KVI_SPLASH_SCREEN_MINIMUM_TIMEOUT_IN_MSECS 2000
+
+void KviSplashScreen::die()
+{
+#ifdef COMPILE_USE_QT4
+ m_bIncreasing = false;
+ m_pFadeTimer->start(6);
+#else
+ QTime now = QTime::currentTime();
+ int mSecs = m_creationTime.msecsTo(now);
+ int mRemaining = KVI_SPLASH_SCREEN_MINIMUM_TIMEOUT_IN_MSECS - mSecs;
+ if(mRemaining < 0)mRemaining = 0;
+ m_pTimer->start(mRemaining,true);
+#endif
+}
+
+
+void KviSplashScreen::suicide()
+{
+ if(!g_pSplashScreen)return; // already in suicide ?
+ //g_pApp->collectGarbage(this);
+ g_pSplashScreen = 0;
+ deleteLater();
+ //delete this;
+}
+
+
+void KviSplashScreen::fadeTimerShot()
+{
+#ifdef COMPILE_USE_QT4
+ if(m_bIncreasing)
+ {
+ m_rTransparency+=0.05;
+ setWindowOpacity(m_rTransparency);
+ if(m_rTransparency>=1)
+ {
+ m_pFadeTimer->stop();
+ m_bIncreasing=false;
+ }
+
+
+ } else {
+ m_rTransparency-=0.02;
+ setWindowOpacity(m_rTransparency);
+ if(m_rTransparency<=0)
+ {
+ m_pFadeTimer->stop();
+ m_bIncreasing=true;
+ suicide();
+ }
+ }
+#endif
+}
+
+
+#include "kvi_splash.moc"
diff --git a/src/kvirc/ui/kvi_splash.h b/src/kvirc/ui/kvi_splash.h
new file mode 100644
index 0000000..83cfb73
--- /dev/null
+++ b/src/kvirc/ui/kvi_splash.h
@@ -0,0 +1,72 @@
+#ifndef _KVI_SPLASH_H_
+#define _KVI_SPLASH_H_
+//=============================================================================
+//
+// File : kvi_splash.h
+// Creation date : Wed Aug 8 2001 17:45:12 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+
+#include <qframe.h>
+
+#include <qprogressbar.h>
+#include <qlabel.h>
+#include <qtimer.h>
+#include <qdatetime.h>
+#include <qsplashscreen.h>
+#include <qpixmap.h>
+
+class KVIRC_API KviSplashScreen : public QSplashScreen
+{
+ Q_OBJECT
+public:
+ KviSplashScreen();
+ virtual ~KviSplashScreen();
+private:
+ QTimer * m_pTimer;
+ QTime m_creationTime;
+ QPixmap * m_pOverlay;
+#ifdef COMPILE_USE_QT4
+ bool m_bIncreasing;
+ qreal m_rTransparency;
+ QTimer * m_pFadeTimer;
+#endif
+protected:
+ virtual void showEvent(QShowEvent * e);
+ virtual void hideEvent(QHideEvent * e);
+public:
+ void setProgress(int progress);
+ void die();
+ //void message(QString);
+protected slots:
+ void suicide();
+ void fadeTimerShot();
+};
+
+extern KVIRC_API KviSplashScreen * g_pSplashScreen;
+
+#define KVI_SPLASH_SET_PROGRESS(__val) if(g_pSplashScreen)g_pSplashScreen->setProgress(__val);
+//#define KVI_SPLASH_SET_TEXT(__txt) if(g_pSplashScreen){ g_pSplashScreen->message(__txt); debug(__txt.latin1()); }
+
+
+#endif //_KVI_SPLASH_H_
diff --git a/src/kvirc/ui/kvi_statusbar.cpp b/src/kvirc/ui/kvi_statusbar.cpp
new file mode 100644
index 0000000..df20a22
--- /dev/null
+++ b/src/kvirc/ui/kvi_statusbar.cpp
@@ -0,0 +1,643 @@
+//=============================================================================
+//
+// File : kvi_statusbar.cpp
+// Created on Tue 07 Sep 2004 03:56:46 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2004 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_statusbar.h"
+#include "kvi_frame.h"
+
+#include <qlabel.h>
+
+#include "kvi_iconmanager.h"
+#include "kvi_window.h"
+#include "kvi_irccontext.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_config.h"
+#include "kvi_modulemanager.h"
+#include "kvi_statusbarapplet.h"
+#include "kvi_dynamictooltip.h"
+
+#include <qpainter.h>
+#include <qstyle.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qcursor.h>
+#include "kvi_tal_popupmenu.h"
+#include <qpixmap.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <qevent.h>
+#endif
+
+// This class COULD be derived also from KStatusBar but in fact
+// it adds no graphic functionality and it has only useless methods for us.
+// ... for now let's keep it simple :)
+
+
+#include "kvi_time.h"
+#include "kvi_qstring.h"
+
+#include <qfont.h>
+
+/*
+ IDEAS:
+ - Countdown timer
+*/
+
+
+
+
+
+KviStatusBar::KviStatusBar(KviFrame * pFrame)
+: QStatusBar(pFrame)
+{
+
+ setProperty("name","statusbar");
+ m_pFrame = pFrame;
+ // ugh :D
+ setSizeGripEnabled(false);
+
+ m_pContextPopup = 0;
+ m_pAppletsPopup = 0;
+
+ m_pClickedApplet = 0;
+
+ m_pAppletDescriptors = new KviPointerHashTable<QString,KviStatusBarAppletDescriptor>;
+ m_pAppletDescriptors->setAutoDelete(true);
+
+ KviStatusBarClock::selfRegister(this);
+ KviStatusBarAwayIndicator::selfRegister(this);
+ KviStatusBarLagIndicator::selfRegister(this);
+ KviStatusBarConnectionTimer::selfRegister(this);
+ KviStatusBarSeparator::selfRegister(this);
+
+ m_pAppletList = new KviPointerList<KviStatusBarApplet>;
+ m_pAppletList->setAutoDelete(false);
+
+ m_pMessageQueue = new KviPointerList<KviStatusBarMessage>;
+ m_pMessageQueue->setAutoDelete(true);
+
+ m_pMessageTimer = 0;
+
+ m_pMessageLabel = new QLabel("<b>[x]</b> x",this,"msgstatuslabel");
+ m_pMessageLabel->setMargin(1);
+#ifdef COMPILE_USE_QT4
+ m_pMessageLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
+#else
+ m_pMessageLabel->setAlignment(SingleLine | Qt::AlignVCenter | Qt::AlignLeft);
+#endif
+ m_pMessageLabel->setMinimumWidth(350);
+
+ m_iLastMinimumHeight = 0;
+ m_bStopLayoutOnAddRemove = true;
+
+ connect(m_pFrame,SIGNAL(activeContextChanged()),this,SLOT(setPermanentMessage()));
+ connect(m_pFrame,SIGNAL(activeContextStateChanged()),this,SLOT(setPermanentMessage()));
+ connect(m_pFrame,SIGNAL(activeConnectionUserModeChanged()),this,SLOT(setPermanentMessage()));
+ connect(m_pFrame,SIGNAL(activeConnectionNickNameChanged()),this,SLOT(setPermanentMessage()));
+ setPermanentMessage();
+
+ m_bStopLayoutOnAddRemove = false;
+
+ m_pToolTip = new KviDynamicToolTip(this);
+ connect(m_pToolTip,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &)));
+
+ updateLayout();
+}
+
+KviStatusBar::~KviStatusBar()
+{
+ save();
+
+ m_bStopLayoutOnAddRemove = true;
+
+ if(m_pMessageTimer)delete m_pMessageTimer;
+ delete m_pMessageQueue;
+ delete m_pAppletDescriptors;
+ delete m_pAppletList;
+}
+
+void KviStatusBar::load()
+{
+ KviStr szBuf;
+ if(!g_pApp->getReadOnlyConfigPath(szBuf,"statusbar.kvc"))return; // no config file at all
+
+ KviConfig cfg(szBuf.ptr(),KviConfig::Read);
+ cfg.setGroup("Applets");
+
+ int nApplets = cfg.readIntEntry("Count",0);
+ for(int i=0;i<nApplets;i++)
+ {
+ KviStr prefix(KviStr::Format,"Applet%d",i);
+ KviStr tmp(KviStr::Format,"%s_InternalName",prefix.ptr());
+ QString szInternalName = cfg.readEntry(tmp.ptr(),"");
+ if(!szInternalName.isEmpty())
+ {
+ tmp.sprintf("%s_PreloadModule",prefix.ptr());
+ QString szPreloadModule = cfg.readEntry(tmp.ptr(),"");
+ if(!szPreloadModule.isEmpty())
+ g_pModuleManager->getModule(szPreloadModule.utf8().data());
+
+ KviStatusBarApplet * a = createApplet(szInternalName);
+ if (a)
+ a->loadState(prefix.ptr(),&cfg);
+ else
+ debug("warning: failed to create applet %s (preload: %s)!",
+ szInternalName.utf8().data(), szPreloadModule.utf8().data());
+ }
+ }
+}
+
+void KviStatusBar::save()
+{
+ // FIXME: This will preserve the settings of the last saved KviFrame's statusbar only :/
+ KviStr szBuf;
+ g_pApp->getLocalKvircDirectory(szBuf,KviApp::Config,"statusbar.kvc");
+
+ KviConfig cfg(szBuf.ptr(),KviConfig::Write);
+ cfg.setGroup("Applets");
+
+ cfg.writeEntry("Count",m_pAppletList->count());
+
+ int i = 0;
+ for(KviStatusBarApplet * a = m_pAppletList->first();a;a = m_pAppletList->next())
+ {
+ KviStr prefix(KviStr::Format,"Applet%d",i);
+ KviStr tmp(KviStr::Format,"%s_InternalName",prefix.ptr());
+ cfg.writeEntry(tmp.ptr(),a->descriptor()->internalName());
+ a->saveState(prefix.ptr(),&cfg);
+ if(!(a->descriptor()->preloadModule().isEmpty()))
+ {
+ tmp.sprintf("%s_PreloadModule",prefix.ptr());
+ cfg.writeEntry(tmp.ptr(),a->descriptor()->preloadModule());
+ }
+ i++;
+ }
+}
+
+#define VMARGIN 3
+#define HMARGIN 4
+#define SPACING 3
+#define RICHTEXTLABELTRICK 2
+
+void KviStatusBar::layoutChildren()
+{
+ int x = width() - HMARGIN;
+ int h = height() - (VMARGIN * 2);
+ for(KviStatusBarApplet * a = m_pAppletList->last();a;a = m_pAppletList->prev())
+ {
+ int w = a->sizeHint().width();
+ x -= w;
+ a->setGeometry(x,VMARGIN,w,h);
+ x -= SPACING;
+ }
+ // trick to center vertically the rich text label: make it some pixels smaller
+ m_pMessageLabel->setGeometry(HMARGIN,VMARGIN,x - HMARGIN,h - RICHTEXTLABELTRICK);
+}
+
+void KviStatusBar::resizeEvent(QResizeEvent * e)
+{
+ layoutChildren();
+}
+
+bool KviStatusBar::event(QEvent * e)
+{
+ if(e->type() == QEvent::LayoutHint)
+ {
+ updateLayout();
+ return false; // send to parents too!
+ }
+ return QStatusBar::event(e);
+}
+
+void KviStatusBar::recalcMinimumHeight()
+{
+ int s = 18;
+ int h = m_pMessageLabel->sizeHint().height();
+ if(h > s)s = h;
+ for(KviStatusBarApplet * a = m_pAppletList->last();a;a = m_pAppletList->prev())
+ {
+ h = a->sizeHint().height();
+ if(h > s)s = h;
+ }
+ s += (VMARGIN * 2) + RICHTEXTLABELTRICK;
+ if(m_iLastMinimumHeight != s)
+ {
+ m_iLastMinimumHeight = s;
+ setMinimumHeight(s);
+ QLayout * l = layout();
+ if(l)
+ if(l->inherits("QBoxLayout"))
+ ((QBoxLayout *)l)->addStrut(s);
+ // FIXME: do QMainWindow need setUpLayout() here ?
+ }
+}
+
+bool KviStatusBar::appletExists(KviStatusBarApplet * pApplet)
+{
+ return (m_pAppletList->findRef(pApplet) != -1);
+}
+
+KviStatusBarApplet * KviStatusBar::appletAt(const QPoint &pnt,bool bBestMatch)
+{
+ QPoint local = mapFromGlobal(pnt);
+ if(bBestMatch)
+ {
+ for(KviStatusBarApplet * a = m_pAppletList->first();a;a = m_pAppletList->next())
+ {
+ if(local.x() <= (a->x() + a->width()))return a;
+ }
+ return m_pAppletList->last(); // last anyway
+ }
+
+ for(KviStatusBarApplet * a = m_pAppletList->first();a;a = m_pAppletList->next())
+ {
+ if((local.x() >= a->x()) && (local.y() >= a->y()))
+ {
+ if((local.x() <= (a->x() + a->width())) && (local.y() <= (a->y() + a->height())))
+ {
+ return a;
+ }
+ }
+ }
+ return 0;
+}
+
+void KviStatusBar::tipRequest(KviDynamicToolTip *pTip,const QPoint &pnt)
+{
+ KviStatusBarApplet * a = appletAt(mapToGlobal(pnt));
+ QString szTip;
+ QRect r;
+ if(a)
+ {
+ szTip = "<table width=\"100%\"><tr><td bgcolor=\"#303030\" align=\"center\"><font color=\"#ffffff\"><b>" + a->descriptor()->visibleName() + "</b></font></td></tr>";
+
+ QString szTipx = a->tipText(a->mapFromGlobal(mapToGlobal(pnt)));
+ if(!szTipx.isEmpty())
+ {
+ szTip += "<tr><td>";
+ szTip += szTipx;
+ szTip += "</td></tr><tr><td align=\"center\"><hr></td></tr>";
+ }
+
+ szTip += "<tr><td align=\"center\"><font color=\"#808080\" size=\"-1\">";
+ szTip += __tr2qs("<b>Shift+Drag</b> or <b>Ctrl+Drag</b> to move the applet around<br><b>Right click</b> to see the other options");
+ szTip += "</font></td></tr></table>";
+ r = QRect(a->x(),a->y(),a->width(),a->height());
+ } else {
+ szTip = "<center>";
+ szTip += __tr2qs("<b>Right click</b> to add/remove applets");
+ szTip += "</center>";
+ r = QRect(m_pMessageLabel->x(),m_pMessageLabel->y(),m_pMessageLabel->width(),m_pMessageLabel->height());
+ }
+ pTip->tip(r,szTip);
+}
+
+KviTalPopupMenu * KviStatusBar::contextPopup()
+{
+ if(!m_pContextPopup)
+ {
+ m_pContextPopup = new KviTalPopupMenu(this);
+ connect(m_pContextPopup,SIGNAL(aboutToShow()),this,SLOT(contextPopupAboutToShow()));
+ }
+ m_pClickedApplet = appletAt(QCursor::pos());
+ return m_pContextPopup;
+}
+
+void KviStatusBar::contextPopupAboutToShow()
+{
+ if(!m_pContextPopup)return;
+ m_pContextPopup->clear();
+
+
+ if(appletExists(m_pClickedApplet))
+ {
+ QString app = m_pClickedApplet->descriptor()->visibleName();
+
+ QString tmp;
+ KviQString::sprintf(tmp,"<center><b>%Q</b></center>",&app);
+
+#ifndef COMPILE_USE_QT4
+ // FIXME: This is not supported under Qt4.. :(
+ QLabel * l = new QLabel(tmp,m_pContextPopup);
+ l->setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
+ m_pContextPopup->insertItem(l);
+#endif
+
+ m_pClickedApplet->fillContextPopup(m_pContextPopup);
+
+ KviQString::sprintf(tmp,__tr2qs("Remove %Q"),&app);
+ m_pContextPopup->insertSeparator();
+ m_pContextPopup->insertItem(tmp,this,SLOT(removeClickedApplet()));
+ }
+
+ if(!m_pAppletsPopup)
+ {
+ m_pAppletsPopup = new KviTalPopupMenu(this);
+ connect(m_pAppletsPopup,SIGNAL(aboutToShow()),this,SLOT(appletsPopupAboutToShow()));
+ connect(m_pAppletsPopup,SIGNAL(activated(int)),this,SLOT(appletsPopupActivated(int)));
+ }
+
+ m_pContextPopup->insertItem(__tr2qs("Add Applet"),m_pAppletsPopup);
+}
+
+void KviStatusBar::removeClickedApplet()
+{
+ if(!appletExists(m_pClickedApplet))return;
+ delete m_pClickedApplet;
+ m_pClickedApplet = 0;
+}
+
+void KviStatusBar::appletsPopupAboutToShow()
+{
+ if(!m_pAppletsPopup)return;
+ m_pAppletsPopup->clear();
+
+ // FIXME: could we cache the module results in some way ?
+ g_pModuleManager->loadModulesByCaps("statusbarapplet");
+
+ KviPointerHashTableIterator<QString,KviStatusBarAppletDescriptor> it(*m_pAppletDescriptors);
+ while(KviStatusBarAppletDescriptor * d = it.current())
+ {
+ int id;
+ QPixmap * pix = d->icon();
+ if(pix)id = m_pAppletsPopup->insertItem(*pix,d->visibleName());
+ else id = m_pAppletsPopup->insertItem(d->visibleName());
+ m_pAppletsPopup->setItemParameter(id,d->id());
+ ++it;
+ }
+}
+
+KviStatusBarApplet * KviStatusBar::createApplet(const QString &szInternalName)
+{
+ KviStatusBarAppletDescriptor * d = m_pAppletDescriptors->find(szInternalName);
+ if(!d)return 0;
+ return d->create(this);
+}
+
+void KviStatusBar::showLayoutHelp()
+{
+ queueMessage(new KviStatusBarMessage(__tr2qs("Drag the applet while holding the Shift or Ctrl key to move it to the desired position")));
+}
+
+void KviStatusBar::appletsPopupActivated(int id)
+{
+ // FIXME: In fact the applet descriptors in modules could
+ // have been unloaded while the popup was being shown...
+ // For now we just assume that this never happens :D
+
+ if(!m_pAppletsPopup)return;
+ int par = m_pAppletsPopup->itemParameter(id);
+ KviPointerHashTableIterator<QString,KviStatusBarAppletDescriptor> it(*m_pAppletDescriptors);
+ while(KviStatusBarAppletDescriptor * d = it.current())
+ {
+ if(par == d->id())
+ {
+ if(m_pClickedApplet)
+ {
+ int idx = m_pAppletList->findRef(m_pClickedApplet);
+ if(idx != -1)
+ {
+ // try to put the new applet just after the clicked one
+ bool bSave = m_bStopLayoutOnAddRemove;
+ m_bStopLayoutOnAddRemove = true;
+ KviStatusBarApplet * a = d->create(this);
+ m_pAppletList->removeRef(a);
+ m_pAppletList->insert(idx + 1,a);
+ m_bStopLayoutOnAddRemove = bSave;
+ if(!m_bStopLayoutOnAddRemove)updateLayout();
+ showLayoutHelp();
+ return;
+ }
+ }
+ d->create(this);
+ showLayoutHelp();
+ return;
+ }
+ ++it;
+ }
+}
+
+void KviStatusBar::registerAppletDescriptor(KviStatusBarAppletDescriptor * d)
+{
+ m_pAppletDescriptors->replace(d->internalName(),d);
+}
+
+void KviStatusBar::registerApplet(KviStatusBarApplet * a)
+{
+ m_pAppletList->append(a);
+ if(!a->isVisible())a->show();
+ if(!m_bStopLayoutOnAddRemove)updateLayout();
+}
+
+void KviStatusBar::unregisterApplet(KviStatusBarApplet * a)
+{
+ if(!a)return;
+ m_pAppletList->removeRef(a);
+ if(a->isVisible())a->hide();
+ if(!m_bStopLayoutOnAddRemove)updateLayout();
+}
+
+
+void KviStatusBar::paintEvent(QPaintEvent * e)
+{
+ // avoid the ugly rectangle around the widgets painted by QStatusBar
+// QPainter p(this);
+// style().drawPrimitive(QStyle::PE_Panel,&p,rect(),colorGroup(),QStyle::Style_Raised,QStyleOption(1,1));
+ //QStatusBar::paintEvent(e);
+ //qDrawWinPanel(&p,0,0,width(),height(),colorGroup(),false,0);
+}
+
+void KviStatusBar::mousePressEvent(QMouseEvent * e)
+{
+ m_pClickedApplet = 0;
+ if(e->button() & Qt::RightButton)
+ {
+ contextPopup()->popup(QCursor::pos());
+ return;
+ }
+ if((e->button() & Qt::LeftButton) && (e->state() & (Qt::ShiftButton | Qt::ControlButton)))
+ {
+ // move!
+ m_pClickedApplet = appletAt(mapToGlobal(e->pos()));
+ if(!m_pClickedApplet)return;
+ m_pClickedApplet->select();
+#ifdef COMPILE_USE_QT4
+ g_pApp->setOverrideCursor(Qt::SizeAllCursor);
+#else
+ g_pApp->setOverrideCursor(sizeAllCursor);
+#endif
+ }
+}
+
+void KviStatusBar::mouseMoveEvent(QMouseEvent * e)
+{
+ if(!m_pClickedApplet)return;
+ if(!appletExists(m_pClickedApplet))return;
+ QPoint g = mapToGlobal(e->pos());
+ KviStatusBarApplet * a = appletAt(g,true);
+ if(a == m_pClickedApplet)return;
+ // move!
+ if(!a)
+ {
+ a = m_pAppletList->first();
+ if(!a)return; // ops!
+
+ if(e->pos().x() < (a->x() + a->width()))
+ {
+ if(a == m_pClickedApplet)return; // don't move
+ } else {
+ a = m_pAppletList->last();
+ if(!a)return;
+ if(a == m_pClickedApplet)return; // no way to move
+ }
+ }
+
+ m_pAppletList->removeRef(m_pClickedApplet);
+ int idx = m_pAppletList->findRef(a);
+ if(idx == -1)m_pAppletList->append(m_pClickedApplet); // uhg ?
+ else {
+ QPoint p = a->mapFromGlobal(g);
+ if(p.x() > (a->width() / 2))idx++; // just after
+ m_pAppletList->insert(idx,m_pClickedApplet);
+ }
+ layoutChildren();
+}
+
+void KviStatusBar::mouseReleaseEvent(QMouseEvent * e)
+{
+ if(e->button() & Qt::LeftButton)
+ {
+ if(m_pClickedApplet && appletExists(m_pClickedApplet))
+ {
+ m_pClickedApplet->select(false);
+ g_pApp->restoreOverrideCursor();
+ }
+ }
+}
+
+void KviStatusBar::queueMessage(KviStatusBarMessage * pMsg)
+{
+ // FIXME: the priority of the message!!!
+ m_pMessageQueue->append(pMsg);
+ if(!m_pMessageTimer)showFirstMessageInQueue();
+ // else we wait for the message timer to shot
+}
+
+void KviStatusBar::messageTimerFired()
+{
+ if(m_pMessageTimer)m_pMessageTimer->stop();
+
+ if(!m_pMessageQueue->isEmpty())
+ {
+ // the first message in queue is currently visible
+ // kill it
+ m_pMessageQueue->removeFirst();
+ if(!m_pMessageQueue->isEmpty())
+ {
+ // something to show
+ showFirstMessageInQueue();
+ }
+ }
+ // nothing else to show
+ delete m_pMessageTimer;
+ m_pMessageTimer = 0;
+
+ setPermanentMessage();
+}
+
+void KviStatusBar::showFirstMessageInQueue()
+{
+ KviStatusBarMessage * pMsg = m_pMessageQueue->first();
+ if(!pMsg)
+ {
+ if(m_pMessageTimer)
+ {
+ delete m_pMessageTimer;
+ m_pMessageTimer = 0;
+ }
+ return;
+ }
+
+ if(!m_pMessageTimer)
+ {
+ m_pMessageTimer = new QTimer(this);
+ QObject::connect(m_pMessageTimer,SIGNAL(timeout()),this,SLOT(messageTimerFired()));
+ } else {
+ m_pMessageTimer->stop();
+ }
+
+ m_pMessageLabel->setText("<nobr>" + pMsg->text() + "</nobr>");
+ m_pMessageTimer->start(pMsg->timeout());
+}
+
+
+void KviStatusBar::setPermanentMessage()
+{
+ if(m_pMessageTimer)return; // something is being actually shown!
+
+ KviIrcContext * c = m_pFrame->activeContext();
+
+ QString txt = "<nobr>";
+
+ if(c)
+ {
+ switch(c->state())
+ {
+ case KviIrcContext::Connected:
+ txt += "<b>[";
+ txt += c->connection()->currentServerName();
+ txt += "]</b> ";
+ txt += c->connection()->currentNickName();
+ if(!c->connection()->userInfo()->userMode().isEmpty())
+ {
+ txt += " (+";
+ txt += c->connection()->userInfo()->userMode();
+ txt += ")";
+ }
+ break;
+ case KviIrcContext::Connecting:
+ txt += __tr2qs("Connection in progress...");
+ break;
+ case KviIrcContext::LoggingIn:
+ txt += "<b>[";
+ txt += c->connection()->currentServerName();
+ txt += "]</b> ";
+ txt += __tr2qs("Login in progress...");
+ break;
+ default:
+ txt += __tr2qs("Not connected");
+ break;
+ }
+ } else {
+ txt += __tr2qs("No IRC context");
+ }
+
+ txt += "</nobr>";
+
+ m_pMessageLabel->setText(txt);
+}
diff --git a/src/kvirc/ui/kvi_statusbar.h b/src/kvirc/ui/kvi_statusbar.h
new file mode 100644
index 0000000..119c93d
--- /dev/null
+++ b/src/kvirc/ui/kvi_statusbar.h
@@ -0,0 +1,130 @@
+#ifndef _KVI_STATUSBAR_H_
+#define _KVI_STATUSBAR_H_
+//=============================================================================
+//
+// File : kvi_statusbar.h
+// Created on Tue 07 Sep 2004 03:56:46 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2004 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_pointerlist.h"
+#include "kvi_heapobject.h"
+
+#include <qstring.h>
+#include "kvi_pointerhashtable.h"
+#include <qstatusbar.h>
+
+class KviFrame;
+
+class QTimer;
+class QLabel;
+class KviTalPopupMenu;
+
+class KVIRC_API KviStatusBarMessage : public KviHeapObject
+{
+ friend class KviStatusBar;
+protected:
+ QString m_szText;
+ unsigned int m_uTimeout;
+ unsigned int m_uPriority;
+public:
+ KviStatusBarMessage(const QString &szText,unsigned int uTimeout = 8000,unsigned int uPriority = 0)
+ : KviHeapObject(), m_szText(szText), m_uTimeout(uTimeout), m_uPriority(uPriority) {};
+ ~KviStatusBarMessage(){};
+public:
+ const QString & text(){ return m_szText; };
+ unsigned int timeout(){ return m_uTimeout; };
+ unsigned int priority(){ return m_uPriority; };
+};
+
+
+class KviStatusBarApplet;
+class KviStatusBarAppletDescriptor;
+class KviIrcContext;
+class KviDynamicToolTip;
+
+class KVIRC_API KviStatusBar : public QStatusBar
+{
+ friend class KviStatusBarApplet;
+ friend class KviFrame;
+ Q_OBJECT
+public:
+ KviStatusBar(KviFrame * pFrame);
+ ~KviStatusBar();
+protected:
+ KviFrame * m_pFrame;
+ KviPointerList<KviStatusBarMessage> * m_pMessageQueue;
+ QTimer * m_pMessageTimer;
+ QLabel * m_pMessageLabel;
+ KviPointerList<KviStatusBarApplet> * m_pAppletList;
+ KviPointerHashTable<QString,KviStatusBarAppletDescriptor> * m_pAppletDescriptors;
+ KviTalPopupMenu * m_pContextPopup;
+ KviTalPopupMenu * m_pAppletsPopup;
+ KviStatusBarApplet * m_pClickedApplet;
+ int m_iLastMinimumHeight;
+ bool m_bStopLayoutOnAddRemove;
+ KviDynamicToolTip * m_pToolTip;
+public:
+ KviFrame * frame(){ return m_pFrame; };
+protected slots:
+ void messageTimerFired();
+protected:
+ void showFirstMessageInQueue();
+ virtual void paintEvent(QPaintEvent * e);
+ virtual void mousePressEvent(QMouseEvent * e);
+ virtual void mouseMoveEvent(QMouseEvent * e);
+ virtual void mouseReleaseEvent(QMouseEvent * e);
+ virtual void resizeEvent(QResizeEvent * e);
+ virtual bool event(QEvent * e);
+ void registerApplet(KviStatusBarApplet * a);
+ void unregisterApplet(KviStatusBarApplet * a);
+ void recalcMinimumHeight();
+ void layoutChildren();
+ void updateLayout(){ recalcMinimumHeight(); layoutChildren(); };
+ void save();
+ void load();
+ KviStatusBarApplet * createApplet(const QString &szInternalName);
+ void showLayoutHelp();
+public:
+ bool appletExists(KviStatusBarApplet * pApplet);
+ // pnt is global!
+ KviStatusBarApplet * appletAt(const QPoint &pnt,bool bBestMatch = false);
+
+ KviTalPopupMenu * contextPopup();
+ // takes the ownership of pMsg
+ void queueMessage(KviStatusBarMessage * pMsg);
+ // called by KviFrame
+ void activeWindowChanged();
+
+ void registerAppletDescriptor(KviStatusBarAppletDescriptor * d);
+
+ //void addApplet(KviStatusBarApplet * pApplet);
+ //void removeApplet(KviStatusBarApplet * pApplet);
+protected slots:
+ void contextPopupAboutToShow();
+ void appletsPopupAboutToShow();
+ void appletsPopupActivated(int id);
+ void removeClickedApplet();
+ void setPermanentMessage();
+ void tipRequest(KviDynamicToolTip *pTip,const QPoint &pnt);
+};
+
+#endif //!_KVI_STATUSBAR_H_
diff --git a/src/kvirc/ui/kvi_statusbarapplet.cpp b/src/kvirc/ui/kvi_statusbarapplet.cpp
new file mode 100644
index 0000000..8e4ec89
--- /dev/null
+++ b/src/kvirc/ui/kvi_statusbarapplet.cpp
@@ -0,0 +1,563 @@
+//=============================================================================//
+// File : kvi_statusbarapplet.cpp
+// Created on Tue 07 Sep 2004 03:56:46 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2004 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_statusbarapplet.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_window.h"
+#include "kvi_irccontext.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_ircconnectionstatistics.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+#include "kvi_config.h"
+#include "kvi_modulemanager.h"
+#include "kvi_console.h"
+#include "kvi_lagmeter.h"
+#include "kvi_options.h"
+#include "kvi_kvs_script.h"
+
+#include <qpainter.h>
+#include <qstyle.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qcursor.h>
+#include "kvi_tal_popupmenu.h"
+#include <qpixmap.h>
+#ifdef COMPILE_USE_QT4
+ #include <qevent.h>
+#endif
+
+// This class COULD be derived also from KStatusBar but in fact
+// it adds no graphic functionality and it has only useless methods for us.
+// ... for now let's keep it simple :)
+
+
+// FIXME: Applets in modules SHOULD be unregistered automatically on unload!
+
+#include "kvi_time.h"
+#include "kvi_qstring.h"
+
+#include <qfont.h>
+
+/*
+ IDEAS:
+ - Lag meter
+ - Countdown timer
+*/
+
+KviStatusBarAppletDescriptor::KviStatusBarAppletDescriptor(const QString &szVisibleName,const QString &szInternalName,CreateAppletCallback pProc,const QString &szPreloadModule,const QPixmap &pixIcon)
+: KviHeapObject()
+{
+ static int s_iAppletDescriptorUniqueId = 0;
+ m_iId = s_iAppletDescriptorUniqueId;
+ s_iAppletDescriptorUniqueId++;
+ m_szVisibleName = szVisibleName;
+ m_szInternalName = szInternalName;
+ m_szPreloadModule = szPreloadModule;
+ m_pProc = pProc;
+ m_pAppletList = new KviPointerList<KviStatusBarApplet>;
+ m_pAppletList->setAutoDelete(false);
+ if(!pixIcon.isNull())m_pIcon = new QPixmap(pixIcon);
+ else m_pIcon = 0;
+}
+
+KviStatusBarAppletDescriptor::~KviStatusBarAppletDescriptor()
+{
+ while(KviStatusBarApplet * a = m_pAppletList->first())delete a;
+ delete m_pAppletList;
+ if(m_pIcon)delete m_pIcon;
+}
+
+KviStatusBarApplet * KviStatusBarAppletDescriptor::create(KviStatusBar * pBar)
+{
+ return m_pProc(pBar,this);
+}
+
+void KviStatusBarAppletDescriptor::registerApplet(KviStatusBarApplet * a)
+{
+ m_pAppletList->append(a);
+}
+
+void KviStatusBarAppletDescriptor::unregisterApplet(KviStatusBarApplet * a)
+{
+ m_pAppletList->removeRef(a);
+}
+
+
+
+
+
+
+KviStatusBarApplet::KviStatusBarApplet(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor)
+: QLabel(pParent), m_pStatusBar(pParent), m_pDescriptor(pDescriptor)
+{
+ m_pDescriptor->registerApplet(this);
+ m_pStatusBar->registerApplet(this);
+ m_bSelected = false;
+}
+
+KviStatusBarApplet::~KviStatusBarApplet()
+{
+ m_pDescriptor->unregisterApplet(this);
+ m_pStatusBar->unregisterApplet(this);
+}
+
+QString KviStatusBarApplet::tipText(const QPoint &)
+{
+ return QString::null;
+}
+
+void KviStatusBarApplet::paintEvent(QPaintEvent * e)
+{
+ QLabel::paintEvent(e);
+ setFont(KVI_OPTION_FONT(KviOption_fontIrcToolBarApplet));
+ if(m_bSelected)
+ {
+ QPainter p(this);
+#ifdef COMPILE_USE_QT4
+ p.setCompositionMode(QPainter::CompositionMode_SourceOut);
+ p.fillRect(rect(),Qt::black);
+ p.setCompositionMode(QPainter::CompositionMode_SourceOver);
+#else
+ p.setRasterOp(Qt::NotROP);
+ p.fillRect(rect(),Qt::black);
+ p.setRasterOp(Qt::CopyROP);
+#endif
+ }
+}
+
+void KviStatusBarApplet::select(bool bSelect)
+{
+ if(m_bSelected == bSelect)return;
+ m_bSelected = bSelect;
+ update();
+}
+
+
+
+
+KviStatusBarAwayIndicator::KviStatusBarAwayIndicator(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor)
+: KviStatusBarApplet(pParent,pDescriptor)
+{
+ m_bAwayOnAllContexts = false;
+ connect(pParent->frame(),SIGNAL(activeContextChanged()),this,SLOT(updateDisplay()));
+ connect(pParent->frame(),SIGNAL(activeContextStateChanged()),this,SLOT(updateDisplay()));
+ connect(pParent->frame(),SIGNAL(activeConnectionAwayStateChanged()),this,SLOT(updateDisplay()));
+
+ updateDisplay();
+
+ if(!pixmap())
+ setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NOTAWAY)));
+}
+
+KviStatusBarAwayIndicator::~KviStatusBarAwayIndicator()
+{
+}
+
+void KviStatusBarAwayIndicator::updateDisplay()
+{
+ KviIrcContext * c = statusBar()->frame()->activeContext();
+
+ if(c && c->isConnected())
+ {
+ setPixmap(c->connection()->userInfo()->isAway() ?
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_AWAY)) : *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NOTAWAY)));
+ } else {
+ // FIXME: We'd like to appear disabled here... but then we
+ // no longer get mouse events :/
+ setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NOTAWAY)));
+ }
+}
+
+void KviStatusBarAwayIndicator::toggleContext()
+{
+ m_bAwayOnAllContexts = !m_bAwayOnAllContexts;
+}
+
+void KviStatusBarAwayIndicator::fillContextPopup(KviTalPopupMenu *p)
+{
+ int id = p->insertItem(__tr2qs("Apply to all IRC Contexts"),this,SLOT(toggleContext()));
+ p->setItemChecked(id,m_bAwayOnAllContexts);
+}
+
+void KviStatusBarAwayIndicator::loadState(const char * prefix,KviConfig *cfg)
+{
+ KviStr tmp(KviStr::Format,"%s_AwayOnAllContexts",prefix);
+ m_bAwayOnAllContexts = cfg->readBoolEntry(tmp.ptr(),false);
+}
+
+void KviStatusBarAwayIndicator::saveState(const char * prefix,KviConfig *cfg)
+{
+ KviStr tmp(KviStr::Format,"%s_AwayOnAllContexts",prefix);
+ cfg->writeEntry(tmp.ptr(),m_bAwayOnAllContexts);
+}
+
+KviStatusBarApplet * CreateStatusBarAwayIndicator(KviStatusBar * pBar,KviStatusBarAppletDescriptor *pDescriptor)
+{
+ return new KviStatusBarAwayIndicator(pBar,pDescriptor);
+}
+
+void KviStatusBarAwayIndicator::selfRegister(KviStatusBar * pBar)
+{
+ KviStatusBarAppletDescriptor * d = new KviStatusBarAppletDescriptor(
+ __tr2qs("Away Indicator"),"awayindicator",CreateStatusBarAwayIndicator,"",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_AWAY)));
+ pBar->registerAppletDescriptor(d);
+}
+
+// FIXME: Away on all context should know where user is not away/back before toggling status
+void KviStatusBarAwayIndicator::mouseDoubleClickEvent(QMouseEvent * e)
+{
+ if(!(e->button() & Qt::LeftButton))return;
+ KviIrcConnection * c = statusBar()->frame()->activeConnection();
+ if(!c)return;
+ if(c->state() != KviIrcConnection::Connected)return;
+ QString command;
+ if(m_bAwayOnAllContexts)
+ command = "if($away)back -a; else away -a";
+ else
+ command = "if($away)back; else away";
+ KviKvsScript::run(command,c->console());
+}
+
+QString KviStatusBarAwayIndicator::tipText(const QPoint &)
+{
+ KviIrcConnection * c = statusBar()->frame()->activeConnection();
+ QString ret = "<center><b>";
+ if(!c)goto not_connected;
+ if(c->state() != KviIrcConnection::Connected)goto not_connected;
+ if(c->userInfo()->isAway())
+ {
+ QString tmp = KviTimeUtils::formatTimeInterval(kvi_unixTime() - c->userInfo()->awayTime(),KviTimeUtils::NoLeadingEmptyIntervals);
+ ret += __tr2qs("Away since");
+ ret += ' ';
+ ret += tmp;
+ ret += "</b><br>";
+ ret += __tr2qs("Double click to leave away mode");
+ } else {
+ ret += __tr2qs("Not away");
+ ret += "</b><br>";
+ ret += __tr2qs("Double click to enter away mode");
+ }
+ ret += "</center>";
+ return ret;
+
+not_connected:
+ ret += __tr2qs("Not connected");
+ ret += "</b></center>";
+ return ret;
+}
+
+
+KviStatusBarLagIndicator::KviStatusBarLagIndicator(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor)
+: KviStatusBarApplet(pParent,pDescriptor)
+{
+ connect(pParent->frame(),SIGNAL(activeContextChanged()),this,SLOT(updateDisplay()));
+ connect(pParent->frame(),SIGNAL(activeContextStateChanged()),this,SLOT(updateDisplay()));
+ connect(pParent->frame(),SIGNAL(activeConnectionLagChanged()),this,SLOT(updateDisplay()));
+
+ updateDisplay();
+
+ QFont f = font();
+ f.setFixedPitch(true);
+ f.setFamily("fixed");
+ setFont(f);
+
+ updateDisplay();
+}
+
+KviStatusBarLagIndicator::~KviStatusBarLagIndicator()
+{
+}
+
+void KviStatusBarLagIndicator::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if(!(e->button() & Qt::LeftButton))return;
+
+ KviIrcConnection * c = statusBar()->frame()->activeConnection();
+ if(!c)return;
+ if(c->state() != KviIrcConnection::Connected)return;
+ if(!c->lagMeter())
+ {
+ KVI_OPTION_BOOL(KviOption_boolUseLagMeterEngine) = true;
+ g_pApp->restartLagMeters();
+ }
+}
+
+
+QString KviStatusBarLagIndicator::tipText(const QPoint &)
+{
+ KviIrcConnection * c = statusBar()->frame()->activeConnection();
+ QString ret = "<center><b>";
+ if(!c)goto not_connected;
+ if(c->state() != KviIrcConnection::Connected)goto not_connected;
+ if(c->lagMeter())
+ {
+ int lll;
+ if((lll = c->lagMeter()->lag()) > 0)
+ {
+ int llls = lll / 1000;
+ int llld = (lll % 1000) / 100;
+ int lllc = (lll % 100) / 10;
+ KviQString::appendFormatted(ret,__tr2qs("Lag: %d.%d%d"),llls,llld,lllc);
+ ret += "</b><br>";
+ int vss = c->lagMeter()->secondsSinceLastCompleted();
+ int vmm = vss / 60;
+ vss = vss % 60;
+ KviQString::appendFormatted(ret,__tr2qs("Last checked %d mins %d secs ago"),vmm,vss);
+ } else {
+ ret += __tr2qs("Lag measure not available yet");
+ ret += "</b>";
+ }
+ } else {
+ ret += __tr2qs("Lag meter engine disabled");
+ ret += "</b><br>";
+ ret += __tr2qs("Double click to enable it");
+ }
+ ret += "</center>";
+ return ret;
+
+not_connected:
+ ret += __tr2qs("Not connected");
+ ret += "</b></center>";
+ return ret;
+}
+
+void KviStatusBarLagIndicator::updateDisplay()
+{
+ KviIrcContext * c = statusBar()->frame()->activeContext();
+ if(!c)return;
+ if(c->isConnected())
+ {
+ KviIrcConnection * ic = c->connection();
+ if(ic->lagMeter())
+ {
+ int lll;
+ if((lll = ic->lagMeter()->lag()) > 0)
+ {
+ int llls = lll / 1000;
+ int llld = (lll % 1000) / 100;
+ int lllc = (lll % 100) / 10;
+ QString tmp;
+ KviQString::sprintf(tmp,__tr2qs("Lag: %d.%d%d"),llls,llld,lllc);
+ if(lll > 60000)
+ {
+ // one minute lag!
+ // paint it in red
+ tmp.prepend("<nobr><font color=\"#e00000\">");
+ tmp.append("</font></nobr>");
+ }
+ setText(tmp);
+ return;
+ }
+ }
+ }
+ // no lag available
+ setText(__tr2qs("Lag: ?.??"));
+}
+
+KviStatusBarApplet * CreateStatusBarLagIndicator(KviStatusBar * pBar,KviStatusBarAppletDescriptor *pDescriptor)
+{
+ return new KviStatusBarLagIndicator(pBar,pDescriptor);
+}
+
+
+void KviStatusBarLagIndicator::selfRegister(KviStatusBar * pBar)
+{
+ KviStatusBarAppletDescriptor * d = new KviStatusBarAppletDescriptor(
+ __tr2qs("Lag Indicator"),"lagindicator",CreateStatusBarLagIndicator,"",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVERPING)));
+ pBar->registerAppletDescriptor(d);
+}
+
+
+
+KviStatusBarClock::KviStatusBarClock(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor)
+: KviStatusBarApplet(pParent,pDescriptor)
+{
+ m_bUtc = false;
+
+ startTimer(1000);
+
+ QFont f = font();
+ f.setFixedPitch(true);
+ f.setFamily("fixed");
+ setFont(f);
+}
+
+KviStatusBarClock::~KviStatusBarClock()
+{
+}
+
+void KviStatusBarClock::timerEvent(QTimerEvent *)
+{
+ kvi_time_t tt = kvi_unixTime();
+ struct tm * t = m_bUtc ? gmtime(&tt) : localtime(&tt);
+ QString tmp;
+ KviQString::sprintf(tmp,"%d%d:%d%d:%d%d",
+ t->tm_hour / 10,
+ t->tm_hour % 10,
+ t->tm_min / 10,
+ t->tm_min % 10,
+ t->tm_sec / 10,
+ t->tm_sec % 10);
+ setText(tmp);
+}
+
+void KviStatusBarClock::fillContextPopup(KviTalPopupMenu * p)
+{
+ int id = p->insertItem("UTC",this,SLOT(toggleUtc()));
+ p->setItemChecked(id,m_bUtc);
+}
+
+void KviStatusBarClock::toggleUtc()
+{
+ m_bUtc = !m_bUtc;
+ timerEvent(0);
+}
+
+void KviStatusBarClock::loadState(const char * prefix,KviConfig *cfg)
+{
+ KviStr tmp(KviStr::Format,"%s_Utc",prefix);
+ m_bUtc = cfg->readBoolEntry(tmp.ptr(),false);
+}
+
+void KviStatusBarClock::saveState(const char * prefix,KviConfig *cfg)
+{
+ KviStr tmp(KviStr::Format,"%s_Utc",prefix);
+ cfg->writeEntry(tmp.ptr(),m_bUtc);
+}
+
+KviStatusBarApplet * CreateStatusBarClock(KviStatusBar * pBar,KviStatusBarAppletDescriptor *pDescriptor)
+{
+ return new KviStatusBarClock(pBar,pDescriptor);
+}
+
+void KviStatusBarClock::selfRegister(KviStatusBar * pBar)
+{
+ KviStatusBarAppletDescriptor * d = new KviStatusBarAppletDescriptor(
+ __tr2qs("Simple Clock"),"clock",CreateStatusBarClock,"",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)));
+ pBar->registerAppletDescriptor(d);
+}
+
+
+KviStatusBarConnectionTimer::KviStatusBarConnectionTimer(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor)
+: KviStatusBarApplet(pParent,pDescriptor)
+{
+ startTimer(1000);
+ m_bTotal=0;
+}
+
+KviStatusBarConnectionTimer::~KviStatusBarConnectionTimer()
+{
+}
+//g_pApp->topmostConnectedConsole()
+void KviStatusBarConnectionTimer::timerEvent(QTimerEvent * e)
+{
+ if(m_bTotal)
+ {
+ setText(KviTimeUtils::formatTimeInterval(KVI_OPTION_UINT(KviOption_uintTotalConnectionTime)));
+ } else {
+ if(g_pActiveWindow)
+ {
+ KviIrcContext * c = g_pActiveWindow->context();
+ if(c)
+ {
+ if(c->isConnected())
+ {
+ KviIrcConnection * cnn = c->connection();
+ if(cnn)
+ {
+ setText(KviTimeUtils::formatTimeInterval(kvi_unixTime() - cnn->statistics()->connectionStartTime()));
+ return;
+ }
+ }
+ }
+ }
+
+ setText(KviTimeUtils::formatTimeInterval(0,KviTimeUtils::FillWithHypens));
+ }
+ return;
+}
+
+void KviStatusBarConnectionTimer::toggleTotal()
+{
+ m_bTotal = !m_bTotal;
+}
+
+void KviStatusBarConnectionTimer::fillContextPopup(KviTalPopupMenu *p)
+{
+ int id = p->insertItem(__tr2qs("Show total connection time"),this,SLOT(toggleTotal()));
+ p->setItemChecked(id,m_bTotal);
+}
+
+void KviStatusBarConnectionTimer::loadState(const char * prefix,KviConfig *cfg)
+{
+ KviStr tmp(KviStr::Format,"%s_Total",prefix);
+ m_bTotal = cfg->readBoolEntry(tmp.ptr(),false);
+}
+
+void KviStatusBarConnectionTimer::saveState(const char * prefix,KviConfig *cfg)
+{
+ KviStr tmp(KviStr::Format,"%s_Total",prefix);
+ cfg->writeEntry(tmp.ptr(),m_bTotal);
+}
+
+KviStatusBarApplet * CreateStatusBarConnectionTimer(KviStatusBar * pBar,KviStatusBarAppletDescriptor *pDescriptor)
+{
+ return new KviStatusBarConnectionTimer(pBar,pDescriptor);
+}
+
+void KviStatusBarConnectionTimer::selfRegister(KviStatusBar * pBar)
+{
+ KviStatusBarAppletDescriptor * d = new KviStatusBarAppletDescriptor(
+ __tr2qs("Connection Timer"),"connectiontimer",CreateStatusBarConnectionTimer,"",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)));
+ pBar->registerAppletDescriptor(d);
+}
+
+
+
+KviStatusBarSeparator::KviStatusBarSeparator(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor)
+: KviStatusBarApplet(pParent,pDescriptor)
+{
+ setFrameStyle(QFrame::VLine | QFrame::Sunken);
+}
+
+KviStatusBarSeparator::~KviStatusBarSeparator()
+{
+}
+
+KviStatusBarApplet * CreateStatusBarSeparator(KviStatusBar * pBar,KviStatusBarAppletDescriptor *pDescriptor)
+{
+ return new KviStatusBarSeparator(pBar,pDescriptor);
+}
+
+void KviStatusBarSeparator::selfRegister(KviStatusBar * pBar)
+{
+ KviStatusBarAppletDescriptor * d = new KviStatusBarAppletDescriptor(
+ __tr2qs("Separator"),"separator",CreateStatusBarSeparator);
+ pBar->registerAppletDescriptor(d);
+}
+
diff --git a/src/kvirc/ui/kvi_statusbarapplet.h b/src/kvirc/ui/kvi_statusbarapplet.h
new file mode 100644
index 0000000..6302be5
--- /dev/null
+++ b/src/kvirc/ui/kvi_statusbarapplet.h
@@ -0,0 +1,195 @@
+#ifndef _KVI_STATUSBARAPPLET_H_
+#define _KVI_STATUSBARAPPLET_H_
+//=============================================================================
+//
+// File : kvi_statusbarapplet.h
+// Created on Tue 07 Sep 2004 03:56:46 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC client distribution
+// Copyright (C) 2004 Szymon Stefanek <pragma at kvirc dot net>
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_pointerlist.h"
+#include "kvi_heapobject.h"
+#include "kvi_statusbar.h"
+
+#include <qstring.h>
+#include "kvi_pointerhashtable.h"
+#include <qstatusbar.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+
+class QTimer;
+class QLabel;
+class KviTalPopupMenu;
+
+class KviConfig;
+class KviFrame;
+class KviIrcContext;
+class KviIrcConnection;
+class KviStatusBarApplet;
+class KviStatusBarAppletDescriptor;
+
+typedef KviStatusBarApplet * (*CreateAppletCallback)(KviStatusBar *,KviStatusBarAppletDescriptor *);
+
+class KVIRC_API KviStatusBarAppletDescriptor : public KviHeapObject
+{
+ friend class KviStatusBar;
+ friend class KviStatusBarApplet;
+protected:
+ QString m_szVisibleName; // visible name of the applet
+ QString m_szInternalName; // UNIQUE name of the applet
+ QString m_szPreloadModule; // name of the module that must be preloaded for this applet
+ CreateAppletCallback m_pProc; // creation callback
+ QPixmap * m_pIcon;
+ int m_iId;
+ KviPointerList<KviStatusBarApplet> * m_pAppletList;
+public:
+ KviStatusBarAppletDescriptor(const QString &szVisibleName,
+ const QString &szInternalName,
+ CreateAppletCallback pProc,
+ const QString &szPreloadModule = QString::null,
+ const QPixmap &pixIcon = QPixmap());
+ virtual ~KviStatusBarAppletDescriptor();
+public:
+ const QString &visibleName(){ return m_szVisibleName; };
+ const QString &internalName(){ return m_szInternalName; };
+ const QString &preloadModule(){ return m_szPreloadModule; };
+ int id(){ return m_iId; };
+ QPixmap * icon(){ return m_pIcon; };
+protected:
+ KviStatusBarApplet * create(KviStatusBar * pBar);
+ void registerApplet(KviStatusBarApplet * a);
+ void unregisterApplet(KviStatusBarApplet * a);
+};
+
+
+class KVIRC_API KviStatusBarApplet : public QLabel
+{
+ friend class KviStatusBar;
+ Q_OBJECT
+protected:
+ KviStatusBar * m_pStatusBar;
+ KviStatusBarAppletDescriptor * m_pDescriptor;
+ bool m_bSelected;
+public:
+ KviStatusBarApplet(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor);
+ virtual ~KviStatusBarApplet();
+public:
+ KviStatusBar * statusBar(){ return m_pStatusBar; };
+ KviFrame * frame(){ return m_pStatusBar->frame(); };
+ KviStatusBarAppletDescriptor * descriptor(){ return m_pDescriptor; };
+ void select(bool bSelect = true);
+ bool isSelected(){ return m_bSelected; };
+protected:
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void fillContextPopup(KviTalPopupMenu *p){};
+ virtual void loadState(const char * prefix,KviConfig *cfg){};
+ virtual void saveState(const char * prefix,KviConfig *cfg){};
+ virtual QString tipText(const QPoint &);
+};
+
+
+
+class KviStatusBarClock : public KviStatusBarApplet
+{
+ Q_OBJECT
+public:
+ KviStatusBarClock(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor);
+ virtual ~KviStatusBarClock();
+protected:
+ bool m_bUtc;
+public:
+ static void selfRegister(KviStatusBar * pBar);
+protected:
+ virtual void fillContextPopup(KviTalPopupMenu * p);
+ virtual void timerEvent(QTimerEvent * e);
+ virtual void loadState(const char * prefix,KviConfig *cfg);
+ virtual void saveState(const char * prefix,KviConfig *cfg);
+protected slots:
+ void toggleUtc();
+};
+
+class KviStatusBarConnectionTimer : public KviStatusBarApplet
+{
+ Q_OBJECT
+public:
+ KviStatusBarConnectionTimer(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor);
+ virtual ~KviStatusBarConnectionTimer();
+protected:
+ bool m_bTotal;
+protected:
+ virtual void timerEvent(QTimerEvent * e);
+ virtual void fillContextPopup(KviTalPopupMenu *p);
+ virtual void loadState(const char * prefix,KviConfig *cfg);
+ virtual void saveState(const char * prefix,KviConfig *cfg);
+public:
+ static void selfRegister(KviStatusBar * pBar);
+protected slots:
+ void toggleTotal();
+};
+
+class KviStatusBarSeparator : public KviStatusBarApplet
+{
+ Q_OBJECT
+public:
+ KviStatusBarSeparator(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor);
+ virtual ~KviStatusBarSeparator();
+public:
+ static void selfRegister(KviStatusBar * pBar);
+};
+
+class KviStatusBarAwayIndicator : public KviStatusBarApplet
+{
+ Q_OBJECT
+public:
+ KviStatusBarAwayIndicator(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor);
+ virtual ~KviStatusBarAwayIndicator();
+public:
+ static void selfRegister(KviStatusBar * pBar);
+protected:
+ bool m_bAwayOnAllContexts;
+protected:
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual QString tipText(const QPoint &);
+ virtual void fillContextPopup(KviTalPopupMenu *p);
+ virtual void loadState(const char * prefix,KviConfig *cfg);
+ virtual void saveState(const char * prefix,KviConfig *cfg);
+protected slots:
+ void updateDisplay();
+ void toggleContext();
+};
+
+class KviStatusBarLagIndicator : public KviStatusBarApplet
+{
+ Q_OBJECT
+public:
+ KviStatusBarLagIndicator(KviStatusBar * pParent,KviStatusBarAppletDescriptor *pDescriptor);
+ virtual ~KviStatusBarLagIndicator();
+public:
+ static void selfRegister(KviStatusBar * pBar);
+protected:
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual QString tipText(const QPoint &);
+protected slots:
+ void updateDisplay();
+};
+
+
+#endif //!_KVI_STATUSBARAPPLET_H_
diff --git a/src/kvirc/ui/kvi_styled_controls.cpp b/src/kvirc/ui/kvi_styled_controls.cpp
new file mode 100644
index 0000000..8656b69
--- /dev/null
+++ b/src/kvirc/ui/kvi_styled_controls.cpp
@@ -0,0 +1,373 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// File : kvi_styled_controls.cpp
+// Creation date : 19 Jan 2006 GMT by Alexey Uzhva
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2006 Alexey Uzhva
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+#define __KVIRC__
+
+#include "kvi_styled_controls.h"
+
+#ifndef COMPILE_USE_QT4
+
+#include "kvi_iconmanager.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_doublebuffer.h"
+#include "kvi_tal_toolbar.h"
+
+#include <qcheckbox.h>
+#include <qpainter.h>
+#include <qimage.h>
+#include <qevent.h>
+#include <qtimer.h>
+
+
+KviStyledControlInternal::KviStyledControlInternal( KviStyledControl* control)
+:QObject(0,0)
+{
+ m_pControl=control;
+}
+
+KviStyledControlInternal::~KviStyledControlInternal()
+{
+
+}
+
+bool KviStyledControlInternal::eventFilter( QObject *obj, QEvent *ev )
+{
+ if(ev->type()==QEvent::Enter)
+ {
+ m_pControl->enterEvent(ev);
+ } else if(ev->type()==QEvent::Leave) {
+ m_pControl->leaveEvent(ev);
+ }
+ return FALSE;
+}
+
+void KviStyledControlInternal::paintTimerShot ()
+{
+// debug("%s %s %i",__FILE__,__FUNCTION__,__LINE__);
+// debug("%s %i",__FUNCTION__,m_pControl->m_iStepNumber);
+ if(m_pControl->m_bMouseEnter)
+ {
+ m_pControl->m_iStepNumber++;
+ if(m_pControl->m_iStepNumber>=KVI_STYLE_NUM_STEPS)
+ {
+ m_pControl->m_iStepNumber=KVI_STYLE_NUM_STEPS;
+ m_pControl->m_pTimer->stop();
+ }
+ } else {
+ m_pControl->m_iStepNumber--;
+ if(m_pControl->m_iStepNumber<=0)
+ {
+ m_pControl->m_iStepNumber=0;
+ m_pControl->m_pTimer->stop();
+ }
+ }
+ m_pControl->m_pWidget->repaint( false );
+}
+
+KviStyledControl::KviStyledControl(QWidget* w)
+{
+ m_pWidget=w;
+ m_iStepNumber=0;
+ m_bMouseEnter=0;
+ m_pInternal=new KviStyledControlInternal(this);
+ m_pTimer = new QTimer(m_pInternal);
+ m_pWidget->installEventFilter(m_pInternal);
+}
+
+KviStyledControl::~KviStyledControl()
+{
+ delete m_pTimer;
+ delete m_pInternal;
+}
+
+void KviStyledControl::enterEvent ( QEvent * )
+{
+// debug("%s %s %i",__FILE__,__FUNCTION__,__LINE__);
+ if(m_pWidget->isEnabled() && KVI_OPTION_BOOL(KviOption_boolEnableVisualEffects))
+ {
+ if(m_iStepNumber<KVI_STYLE_NUM_STEPS)
+ {
+ if(!m_pTimer->isActive())
+ {
+ m_pTimer->connect( m_pTimer, SIGNAL(timeout()), m_pInternal, SLOT(paintTimerShot()) );
+ m_pTimer->start(KVI_STYLE_TIMER_STEP);
+ }
+ }
+ m_bMouseEnter=1;
+ m_iStepNumber++;
+ m_pWidget->repaint( false );
+ }
+}
+
+void KviStyledControl::leaveEvent ( QEvent * )
+{
+// debug("%s %s %i",__FILE__,__FUNCTION__,__LINE__);
+ if(m_pWidget->isEnabled() && KVI_OPTION_BOOL(KviOption_boolEnableVisualEffects))
+ {
+ if(m_iStepNumber>0)
+ {
+ if(!m_pTimer->isActive())
+ {
+ m_pTimer->connect( m_pTimer, SIGNAL(timeout()), m_pInternal, SLOT(paintTimerShot()) );
+ m_pTimer->start(KVI_STYLE_TIMER_STEP);
+ }
+ }
+ m_bMouseEnter=0;
+ m_iStepNumber--;
+ m_pWidget->repaint( false );
+ }
+}
+
+
+KviStyledCheckBox::KviStyledCheckBox ( QWidget * parent, const char * name )
+: QCheckBox(parent,name), KviStyledControl(this)
+{
+ setWFlags(WNoAutoErase);
+
+}
+
+KviStyledCheckBox::KviStyledCheckBox ( const QString & text, QWidget * parent, const char * name )
+: QCheckBox(text,parent,name), KviStyledControl(this)
+{
+ setWFlags(WNoAutoErase);
+}
+
+KviStyledCheckBox::~KviStyledCheckBox()
+{
+
+}
+
+
+void KviStyledCheckBox::paintEvent ( QPaintEvent * event)
+{
+ //debug("%s %s %i %i %i",__FILE__,__FUNCTION__,__LINE__,m_bMouseEnter,m_iStepNumber);
+ if(KVI_OPTION_BOOL(KviOption_boolEnableVisualEffects))
+ {
+ KviDoubleBuffer doublebuffer(event->rect().width(),event->rect().height());
+ QPixmap * pDoubleBufferPixmap = doublebuffer.pixmap();
+
+ QRect rect=event->rect();
+ pDoubleBufferPixmap->fill(this, rect.topLeft());
+
+ QPainter p(pDoubleBufferPixmap, this);
+ p.translate(-rect.x(), -rect.y());
+
+ QPixmap* pStoredPix = 0;
+
+ if(isChecked())
+ pStoredPix=g_pIconManager->getBigIcon("kvi_checkbox_selected.png");
+ else
+ pStoredPix=g_pIconManager->getBigIcon("kvi_checkbox_unselected.png");
+ //debug("%s %s %i %i %i",__FILE__,__FUNCTION__,__LINE__,m_bMouseEnter,m_iStepNumber);
+ if(pStoredPix)
+ {
+ //debug("%s %s %i %i %i",__FILE__,__FUNCTION__,__LINE__,m_bMouseEnter,m_iStepNumber);
+ QPixmap pix=*pStoredPix;
+ if(m_iStepNumber && isEnabled())
+ {
+ QImage image = pix.convertToImage();
+ for(int x=0; x<image.width(); x++)
+ for(int y=0; y<image.height(); y++)
+ {
+ QRgb rgb=image.pixel(x,y);
+ rgb=qRgba(
+ qRed(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber < 255 ? qRed(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber : 255 ,
+ qGreen(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber < 255 ? qGreen(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber : 255,
+ qBlue(rgb),
+ qAlpha(rgb)
+ );
+ image.setPixel(x,y,rgb);
+ }
+ p.drawImage(0,0,image);
+ } else if( !isEnabled()) {
+ QImage image = pix.convertToImage();
+ for(int x=0; x<image.width(); x++)
+ for(int y=0; y<image.height(); y++)
+ {
+ //- From Black to Gray conversion for disabled mode.
+ QRgb rgb=image.pixel(x,y);
+ rgb=qRgba(
+ qRed(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber == 0 ? 180 : qRed(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber,
+ qGreen(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber == 0 ? 180 : qGreen(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber,
+ qBlue(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber == 0 ? 180 : qBlue(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber,
+ qAlpha(rgb)
+ );
+ image.setPixel(x,y,rgb);
+ }
+ p.drawImage(0,0,image);
+ } else {
+ p.drawPixmap(0,0,pix);
+ }
+ //debug("%s %s %i %i %i",__FILE__,__FUNCTION__,__LINE__,m_bMouseEnter,m_iStepNumber);
+ QString szText=text();
+ szText=szText.remove("&");
+ p.drawText(pix.width()+3,0,width(),height(),0,szText);
+ bitBlt(this, rect.x(), rect.y(), pDoubleBufferPixmap, 0, 0, rect.width(), rect.height());
+ //debug("%s %s %i %i %i",__FILE__,__FUNCTION__,__LINE__,m_bMouseEnter,m_iStepNumber);
+ } else {
+ QCheckBox::paintEvent(event);
+ }
+ } else
+ QCheckBox::paintEvent(event);
+}
+
+KviStyledToolButton::KviStyledToolButton( QWidget * parent, const char * name )
+: QToolButton(parent,name), KviStyledControl(this), bShowSubmenuIndicator(false)
+{
+ setWFlags(WNoAutoErase);
+ resizeEvent(0);
+}
+
+KviStyledToolButton::KviStyledToolButton ( const QIconSet & iconSet, const QString & textLabel, const QString & grouptext, QObject * receiver, const char * slot, KviTalToolBar * parent, const char * name )
+: QToolButton(iconSet,textLabel,grouptext,receiver,slot,parent,name), KviStyledControl(this), bShowSubmenuIndicator(false)
+{
+ setWFlags(WNoAutoErase);
+ resizeEvent(0);
+}
+
+KviStyledToolButton::~KviStyledToolButton()
+{
+
+}
+
+void KviStyledToolButton::setShowSubmenuIndicator(bool bShow)
+{
+ bShowSubmenuIndicator=bShow;
+ resizeEvent(0);
+}
+
+void KviStyledToolButton::paintEvent ( QPaintEvent * event)
+{
+ if(KVI_OPTION_BOOL(KviOption_boolEnableVisualEffects))
+ {
+ QPixmap* pArrowPix = 0;
+ int iWidth=width();
+ int iPixWidth=0;
+ if(bShowSubmenuIndicator)
+ {
+ if(pArrowPix=g_pIconManager->getBigIcon("kvi_toolbutton_menuindicator.png"))
+ iPixWidth=pArrowPix->width();
+ }
+ bool bActive= isOn() || m_bMouseEnter;
+ KviDoubleBuffer doublebuffer(event->rect().width(),event->rect().height());
+ QPixmap * pDoubleBufferPixmap = doublebuffer.pixmap();
+
+ QRect rect=event->rect();
+
+ pDoubleBufferPixmap->fill(
+ bActive ? QColor(206,215,223) :
+ colorGroup().background()
+ );
+
+
+ QPainter p(pDoubleBufferPixmap, this);
+ p.translate(-rect.x(), -rect.y());
+
+ if(bActive)
+ {
+ p.setPen(QColor(185,190,195));
+ p.drawRect(0,0,iWidth,height());
+ }
+
+ QPixmap pix=iconSet().pixmap(
+ usesBigPixmap() ? QIconSet::Large : QIconSet::Small,
+ isEnabled() ? QIconSet::Normal :
+ QIconSet::Disabled,
+ isOn() ? QIconSet::On :
+ QIconSet::Off);
+ QPoint pos((iWidth-iPixWidth-pix.width())/2,(height()-pix.height())/2);
+ if(!pix.isNull())
+ {
+ if(m_iStepNumber && isEnabled())
+ {
+ QImage image = pix.convertToImage();
+ for(int x=0; x<image.width(); x++)
+ for(int y=0; y<image.height(); y++)
+ {
+ QRgb rgb=image.pixel(x,y);
+ rgb=qRgba(
+ qRed(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber < 255 ? qRed(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber : 255 ,
+ qGreen(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber < 255 ? qGreen(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber : 255,
+ qBlue(rgb),
+ qAlpha(rgb)
+ );
+ image.setPixel(x,y,rgb);
+ }
+ p.drawImage(pos,image);
+ } else if( !isEnabled()) {
+ QImage image = pix.convertToImage();
+ for(int x=0; x<image.width(); x++)
+ for(int y=0; y<image.height(); y++)
+ {
+ //- From Black to Gray conversion for disabled mode.
+ QRgb rgb=image.pixel(x,y);
+ rgb=qRgba(
+ qRed(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber == 0 ? 180 : qRed(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber,
+ qGreen(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber == 0 ? 180 : qGreen(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber,
+ qBlue(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber == 0 ? 180 : qBlue(rgb)+KVI_STYLE_COLOR_DIFF/KVI_STYLE_NUM_STEPS*m_iStepNumber,
+ qAlpha(rgb)
+ );
+ image.setPixel(x,y,rgb);
+ }
+ p.drawImage(pos,image);
+ } else {
+ p.drawPixmap(pos,pix);
+ }
+ }
+
+ if(pArrowPix)
+ {
+ pos.setX(pix.width()+4);
+ pos.setY((height()-pArrowPix->height())/2);
+ p.drawPixmap(pos,*pArrowPix);
+ }
+
+ bitBlt(this, rect.x(), rect.y(), pDoubleBufferPixmap, 0, 0, rect.width(), rect.height());
+
+ } else {
+ QToolButton::paintEvent(event);
+ }
+}
+
+void KviStyledToolButton::resizeEvent ( QResizeEvent * e)
+{
+ QPixmap* pStoredPix = 0;
+ if(pStoredPix=g_pIconManager->getBigIcon("kvi_toolbutton_menuindicator.png"))
+ {
+ QPixmap pix=iconSet().pixmap(
+ usesBigPixmap() ? QIconSet::Large : QIconSet::Small,
+ isEnabled() ? QIconSet::Normal :
+ QIconSet::Disabled,
+ isOn() ? QIconSet::On :
+ QIconSet::Off);
+
+ setMinimumWidth(bShowSubmenuIndicator ? pix.width()+8+pStoredPix->width() : pix.width());
+ }
+}
+
+#include "kvi_styled_controls.moc"
+
+#endif
diff --git a/src/kvirc/ui/kvi_styled_controls.h b/src/kvirc/ui/kvi_styled_controls.h
new file mode 100644
index 0000000..8d096fa
--- /dev/null
+++ b/src/kvirc/ui/kvi_styled_controls.h
@@ -0,0 +1,113 @@
+#ifndef _KVI_STYLED_CONTROLS_H_
+#define _KVI_STYLED_CONTROLS_H_
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// File : kvi_styled_controls.h
+// Creation date : 19 Jan 2006 GMT by Alexey Uzhva
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2006 Alexey Uzhva
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "kvi_settings.h"
+
+#ifdef COMPILE_USE_QT4
+ // we use internal Qt4 styles for now
+ #include <qcheckbox.h>
+ #include <qtoolbutton.h>
+
+ #define KviStyledCheckBox QCheckBox
+ #define KviStyledToolButton QToolButton
+#else
+
+#include <qcheckbox.h>
+#include <qtoolbutton.h>
+#include <qevent.h>
+#include <qtimer.h>
+#include "kvi_heapobject.h"
+
+class KviTalToolBar;
+
+#define KVI_STYLE_NUM_STEPS 20
+#define KVI_STYLE_COLOR_DIFF 60
+#define KVI_STYLE_TIMER_STEP 18
+
+class KviStyledControl;
+
+class KVIRC_API KviStyledControlInternal : public QObject
+{
+ Q_OBJECT
+public:
+ KviStyledControlInternal( KviStyledControl* control );
+ ~KviStyledControlInternal();
+public slots:
+ virtual void paintTimerShot();
+protected:
+ bool eventFilter( QObject *obj, QEvent *ev );
+protected:
+ KviStyledControl* m_pControl;
+};
+
+class KVIRC_API KviStyledControl
+{
+ friend class KviStyledControlInternal;
+public:
+ KviStyledControl(QWidget*);
+ ~KviStyledControl();
+protected:
+ virtual void enterEvent ( QEvent * );
+ virtual void leaveEvent ( QEvent * );
+
+ int m_bMouseEnter;
+ int m_iStepNumber;
+ QTimer* m_pTimer;
+ KviStyledControlInternal* m_pInternal;
+ QWidget *m_pWidget;
+};
+
+class KVIRC_API KviStyledCheckBox : public QCheckBox, public KviStyledControl
+{
+ Q_OBJECT
+public:
+ KviStyledCheckBox ( QWidget * parent, const char * name = 0 );
+ KviStyledCheckBox ( const QString & text, QWidget * parent, const char * name = 0 );
+ ~KviStyledCheckBox();
+protected:
+ virtual void paintEvent ( QPaintEvent * );
+};
+
+class KVIRC_API KviStyledToolButton : public QToolButton, public KviStyledControl
+{
+ Q_OBJECT
+private:
+ bool bShowSubmenuIndicator;
+public:
+ KviStyledToolButton ( QWidget * parent, const char * name = 0 );
+ KviStyledToolButton ( const QIconSet & iconSet, const QString & textLabel, const QString & grouptext, QObject * receiver, const char * slot, KviTalToolBar * parent, const char * name = 0 );
+ ~KviStyledToolButton();
+
+ void setShowSubmenuIndicator(bool bShow);
+protected:
+ virtual void paintEvent ( QPaintEvent * );
+ virtual void resizeEvent ( QResizeEvent * ) ;
+};
+
+#endif
+
+#endif
diff --git a/src/kvirc/ui/kvi_taskbar.cpp b/src/kvirc/ui/kvi_taskbar.cpp
new file mode 100644
index 0000000..8e75bfd
--- /dev/null
+++ b/src/kvirc/ui/kvi_taskbar.cpp
@@ -0,0 +1,1509 @@
+//===============================================================================================
+//
+// File : kvi_taskbar.cpp
+// Last major modification : Thu Jan 7 1999 03:59:43 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//===============================================================================================
+
+#define __KVIRC__
+//#define KVI_TASKBARBUTTON_MIN_WIDTH 100
+#define KVI_TASKBARBUTTON_CONTEXTINDICATORHEIGHT 6
+#define KVI_TASKBAR_MIN_WIDTH 120
+
+#define KVI_NUM_STEPS 20
+#define KVI_TIMER_DELAY 18
+
+
+#define _KVI_DEBUG_CHECK_RANGE_
+#include "kvi_debug.h"
+#include "kvi_taskbar.h"
+#include "kvi_frame.h"
+#include "kvi_window.h"
+#include "kvi_string.h"
+#include "kvi_options.h"
+#include "kvi_console.h"
+#include "kvi_locale.h"
+#include "kvi_dynamictooltip.h"
+#include "kvi_settings.h"
+#include "kvi_channel.h"
+#include "kvi_ircconnection.h"
+#include "kvi_doublebuffer.h"
+
+// FIXME: #warning "The tree taskbar min width should be configurable"
+#include <qtimer.h>
+#include <qfontmetrics.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include "kvi_tal_popupmenu.h"
+#include <qcursor.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <q3header.h>
+#else
+ #include <qheader.h>
+#endif
+#include <qevent.h>
+
+#ifdef COMPILE_USE_QT4
+ #include <QPaintEvent>
+#endif
+
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+#endif
+
+extern QPixmap * g_pActivityMeterPixmap;
+
+// FIXME: This should be renamed to "Window List"
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// KviTaskBarBase
+//
+
+KviTaskBarBase::KviTaskBarBase()
+#ifdef COMPILE_USE_QT4
+: QDockWidget(__tr2qs("Taskbar"),g_pFrame)
+#else
+: KviToolBar(__tr2qs("Taskbar"),QT_DOCK_BOTTOM,false,"taskbar")
+#endif
+{
+ // FIXME: this timer should be started only if KVI_OPTION_BOOL(KviOption_boolUseTaskBarActivityMeter)
+#ifdef COMPILE_USE_QT4
+ setObjectName(__tr2qs("taskbar"));
+ setFeatures(QDockWidget::DockWidgetMovable);
+#endif //COMPILE_USE_QT4
+ m_pActivityMeterTimer = new QTimer();
+ connect(m_pActivityMeterTimer,SIGNAL(timeout()),this,SLOT(updateActivityMeter()));
+ m_pActivityMeterTimer->start(5000);
+}
+
+KviTaskBarBase::~KviTaskBarBase()
+{
+ delete m_pActivityMeterTimer;
+}
+
+void KviTaskBarBase::updateActivityMeter()
+{
+}
+
+void KviTaskBarBase::getTextForConsole(QString &szText,KviConsole * pConsole)
+{
+ if(pConsole->isConnected())
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolShowNetworkNameForConsoleTaskBarEntry))
+ {
+ // FIXME: Should never show "Standalone Servers" or "orphan_servers".
+ // It would also be nice to have a number appended to
+ // multiple entries with the same server name...but this costs too much.
+ szText = pConsole->connection()->networkName();
+ if(szText.isEmpty())
+ szText = pConsole->connection()->currentServerName();
+ } else {
+ szText = pConsole->connection()->currentServerName();
+ }
+ } else {
+ szText = pConsole->statusString();
+ }
+}
+
+
+KviTaskBarItem * KviTaskBarBase::item(int number)
+{
+ KviTaskBarItem * it = firstItem();
+ if(!setIterationPointer(it))return 0;
+
+ while(it && (number > 0))
+ {
+ it = nextItem();
+ number--;
+ }
+ return it;
+}
+
+void KviTaskBarBase::switchWindow(bool bNext,bool bInContextOnly)
+{
+ if(!g_pActiveWindow)return;
+
+ KviConsole * cons = g_pActiveWindow->console();
+ KviTaskBarItem * cur = g_pActiveWindow->taskBarItem();
+ KviTaskBarItem * it = cur;
+
+ if(!setIterationPointer(cur))return;
+
+ while(it)
+ {
+ it = bNext ? nextItem() : prevItem();
+ if(!it)it = bNext ? firstItem() : lastItem();
+ if(it)
+ {
+ if(bInContextOnly)
+ {
+ if(it->kviWindow()->console() == cons)
+ {
+ g_pFrame->setActiveWindow(it->kviWindow());
+ return;
+ }
+ } else {
+ g_pFrame->setActiveWindow(it->kviWindow());
+ return;
+ }
+ }
+ if(it == cur)return; // did a complete loop.... no window to switch to
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// KviTaskBarItem
+//
+
+KviTaskBarItem::KviTaskBarItem(KviWindow * wnd)
+{
+ m_pWindow = wnd;
+ m_iHighlightLevel = 0;
+ m_iProgress = -1;
+}
+
+KviTaskBarItem::~KviTaskBarItem()
+{
+ m_pWindow->m_pTaskBarItem = 0;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// KviTaskBarButton
+//
+
+
+KviTaskBarButton::KviTaskBarButton(QWidget * par,KviWindow * wnd,const char * name)
+: QPushButton(par,name) , KviTaskBarItem(wnd)
+{
+ m_bActive = false;
+ m_pTip = new KviDynamicToolTip(this);
+ connect(m_pTip,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &)));
+// setBackgroundMode(QWidget::NoBackground);
+ setToggleButton (true);
+ setFlat ( KVI_OPTION_BOOL(KviOption_boolUseFlatClassicTaskbarButtons) );
+}
+
+KviTaskBarButton::~KviTaskBarButton()
+{
+ delete m_pTip; //not necessary ?
+}
+
+void KviTaskBarButton::tipRequest(KviDynamicToolTip *,const QPoint &pnt)
+{
+ if(KVI_OPTION_BOOL(KviOption_boolShowTaskBarToolTips))
+ {
+ QString szText;
+ m_pWindow->getTaskBarTipText(szText);
+ m_pTip->tip(rect(),szText);
+ }
+}
+
+void KviTaskBarButton::mousePressEvent(QMouseEvent *e)
+{
+ if(e->button() & Qt::LeftButton)
+ {
+ if(e->state() & Qt::ShiftButton)
+ {
+ m_pWindow->delayedClose();
+ } else {
+ if((g_pActiveWindow != m_pWindow) || (m_pWindow->isMinimized()))g_pFrame->setActiveWindow(m_pWindow);
+ else m_pWindow->minimize();
+ }
+ } else m_pWindow->contextPopup();
+}
+
+#if QT_VERSION >= 300
+void KviTaskBarButton::contextMenuEvent(QContextMenuEvent *e)
+{
+ m_pWindow->contextPopup();
+ e->accept();
+}
+#endif
+
+void KviTaskBarButton::setActive(bool bActive)
+{
+ if(bActive)
+ {
+ m_bActive = true;
+ m_iHighlightLevel = 0;
+ } else {
+ if(m_bActive)
+ {
+ // was active... unset the highlighting if it was silently turned on while being active...
+ m_iHighlightLevel = 0;
+ }
+ m_bActive = false;
+ }
+ setOn(bActive);
+ update();
+}
+
+#ifdef COMPILE_USE_QT4
+void KviTaskBarButton::paintEvent(QPaintEvent * e)
+{
+ QPainter p(this);
+ QStyleOption opt;
+ opt.initFrom(this);
+ if(isOn())
+ opt.state = QStyle::State_On | QStyle::State_Active;
+ style()->drawPrimitive(QStyle::PE_PanelButtonTool,&opt,&p,this);
+ drawButtonLabel(&p);
+}
+#endif
+
+void KviTaskBarButton::drawButtonLabel(QPainter * painter)
+{
+ QRect distRect = painter->window();
+ int iHeight = distRect.height();
+ int iWidth = distRect.width();
+
+ QPainter * pPainter;
+#ifdef COMPILE_USE_QT4
+ pPainter = painter;
+#else //!COMPILE_USE_QT4
+ KviDoubleBuffer db(iWidth,iHeight);
+ QPixmap * pMemBuffer = db.pixmap();
+ QPainter p(pMemBuffer);
+ bitBlt(pMemBuffer,0,0,painter->device(),distRect.x(),distRect.y(),iWidth,iHeight);
+ pPainter = &p;
+#endif //!COMPILE_USE_QT4
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIrcContextIndicator))
+ {
+ iHeight -= KVI_TASKBARBUTTON_CONTEXTINDICATORHEIGHT;
+ QColor base = colorGroup().background();
+ if(m_pWindow->console())
+ {
+ QColor cntx = KVI_OPTION_ICCOLOR(m_pWindow->console()->ircContextId() % KVI_NUM_ICCOLOR_OPTIONS);
+ base.setRgb((base.red() + cntx.red()) >> 1,(base.green() + cntx.green()) >> 1,
+ (base.blue() + cntx.blue()) >> 1);
+ pPainter->fillRect(2,iHeight,iWidth - 4,KVI_TASKBARBUTTON_CONTEXTINDICATORHEIGHT - 2,base);
+ } else {
+ pPainter->fillRect(2,iHeight,iWidth - 4,KVI_TASKBARBUTTON_CONTEXTINDICATORHEIGHT - 2,colorGroup().brush(QColorGroup::Background));
+ }
+ }
+
+ int daX = 3;
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIcons))
+ {
+ pPainter->drawPixmap(3,3,*(m_pWindow->myIconPtr()));
+ daX = 20;
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarActivityMeter))
+ {
+ unsigned int uActivityValue;
+ unsigned int uActivityTemperature;
+ if(m_pWindow->activityMeter(&uActivityValue,&uActivityTemperature))
+ {
+ pPainter->drawPixmap(daX,3,*g_pActivityMeterPixmap,uActivityValue * 5,uActivityTemperature * 16,5,16);
+ daX = 27;
+ }
+ }
+
+ QRect cRect(daX,3,iWidth - (20 + daX),iHeight - 6);
+
+ if(m_iProgress >= 0)
+ {
+ // paint the progress bar
+ int wdth = (m_iProgress * cRect.width()) / 100;
+ pPainter->setPen(KVI_OPTION_COLOR(KviOption_colorTaskBarProgressBar));
+ pPainter->drawRect(cRect);
+ pPainter->fillRect(daX,3,wdth,cRect.height(),KVI_OPTION_COLOR(KviOption_colorTaskBarProgressBar));
+ }
+
+ QRect bRect;
+ QString szText;
+
+ bool bMinimized = m_pWindow->isMinimized();
+
+ if(m_bActive)
+ {
+ pPainter->setPen(KVI_OPTION_COLOR(KviOption_colorTaskBarNormalText));
+ } else {
+ int iLevel;
+
+ switch(m_iHighlightLevel)
+ {
+ case 0: iLevel = bMinimized ? KviOption_colorTaskBarMinimizedText : KviOption_colorTaskBarNormalText; break;
+ case 1: iLevel = KviOption_colorTaskBarHighlight1Text; break;
+ case 2: iLevel = KviOption_colorTaskBarHighlight2Text; break;
+ case 3: iLevel = KviOption_colorTaskBarHighlight3Text; break;
+ case 4: iLevel = KviOption_colorTaskBarHighlight4Text; break;
+ default: iLevel = KviOption_colorTaskBarHighlight5Text; break;
+ }
+ pPainter->setPen(KVI_OPTION_COLOR(iLevel));
+ }
+
+ pPainter->setFont(KVI_OPTION_FONT(KviOption_fontTaskbar));
+
+ switch(m_pWindow->type())
+ {
+ case KVI_WINDOW_TYPE_CONSOLE:
+ {
+ QFont f = QFont(KVI_OPTION_FONT(KviOption_fontTaskbar));
+ f.setBold(true);
+ pPainter->setFont(f);
+ KviTaskBarBase::getTextForConsole(szText,(KviConsole *)m_pWindow);
+ }
+ break;
+ case KVI_WINDOW_TYPE_CHANNEL:
+ case KVI_WINDOW_TYPE_DEADCHANNEL:
+ szText = ((KviChannel *)m_pWindow)->nameWithUserFlag();
+ break;
+ case KVI_WINDOW_TYPE_QUERY:
+ case KVI_WINDOW_TYPE_DEADQUERY:
+ szText = m_pWindow->windowName();
+ break;
+ default:
+ szText = m_pWindow->plainTextCaption();
+ break;
+ }
+
+ if(bMinimized)
+ {
+ QString tmp = QChar('(');
+ tmp += szText;
+ tmp += QChar(')');
+ pPainter->drawText(cRect,Qt::AlignLeft | Qt::AlignTop,tmp,-1,&bRect);
+ } else {
+ pPainter->drawText(cRect,Qt::AlignLeft | Qt::AlignTop,szText,-1,&bRect);
+ }
+
+ if(bRect.width() > cRect.width())
+ {
+ pPainter->setClipRect(cRect.right(),cRect.y(),10,cRect.height());
+ QColor base = pPainter->pen().color();
+ QColor bg = colorGroup().color(QColorGroup::Background);
+ base.setRgb((base.red() + bg.red()) / 2,(base.green() + bg.green()) / 2,(base.blue() + bg.blue()) / 2);
+ pPainter->setPen(base);
+ cRect.setWidth(cRect.width() + 10);
+ pPainter->drawText(cRect,Qt::AlignLeft | Qt::AlignTop,szText,-1);
+ pPainter->setClipRect(cRect.right(),cRect.y(),5,cRect.height());
+ base.setRgb((base.red() + bg.red()) / 2,(base.green() + bg.green()) / 2,(base.blue() + bg.blue()) / 2);
+ pPainter->setPen(base);
+ cRect.setWidth(cRect.width() + 10);
+ pPainter->drawText(cRect,Qt::AlignLeft | Qt::AlignTop,szText,-1);
+ }
+#ifndef COMPILE_USE_QT4
+ pPainter->setClipping(FALSE);
+ painter->drawPixmap(0,0,*pMemBuffer,distRect.x(),distRect.y(),iWidth,iHeight);
+#endif
+}
+
+
+void KviTaskBarButton::captionChanged()
+{
+ update();
+}
+
+void KviTaskBarButton::setProgress(int progress)
+{
+ if(progress == m_iProgress)return;
+ m_iProgress = progress;
+ update(); // repaint(false) ?
+}
+
+void KviTaskBarButton::unhighlight()
+{
+ if(m_iHighlightLevel < 1)return;
+ m_iHighlightLevel = 0;
+ if(g_pFrame->dockExtension())g_pFrame->dockExtension()->refresh();
+ update();
+}
+
+void KviTaskBarButton::highlight(int iLevel)
+{
+ if(iLevel <= m_iHighlightLevel)return;
+ if(m_bActive && g_pFrame->isActiveWindow())return;
+ m_iHighlightLevel = iLevel;
+ if(g_pFrame->dockExtension())g_pFrame->dockExtension()->refresh();
+ if(m_bActive)return;
+ update(); // repaint(false) ?
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// KviTaskBarToolTip
+//
+/*
+KviTaskBarToolTip::KviTaskBarToolTip(KviTaskBarButton * b)
+: KviTalToolTip(b,0)
+{
+ m_pTaskBarButton = b;
+}
+
+KviTaskBarToolTip::~KviTaskBarToolTip()
+{
+}
+
+void KviTaskBarToolTip::maybeTip(const QPoint &pnt)
+{
+ tip(m_pTaskBarButton->rect(),m_pTaskBarButton->m_pWindow->plainTextCaption());
+}
+*/
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// KviClasicTaskBar
+//
+
+
+KviClassicTaskBar::KviClassicTaskBar()
+: KviTaskBarBase()
+{
+ m_pButtonList = new KviPointerList<KviTaskBarButton>;
+ m_pButtonList->setAutoDelete(true);
+
+ calcButtonHeight();
+
+ m_pBase = new QWidget(this);
+// m_pBase->setBackgroundMode(NoBackground);
+#ifdef COMPILE_USE_QT4
+ setWidget(m_pBase);
+
+ m_pBase->setMinimumWidth(KVI_TASKBAR_MIN_WIDTH);
+ setMinimumWidth(KVI_TASKBAR_MIN_WIDTH);
+#else //!COMPILE_USE_QT4
+ setStretchableWidget(m_pBase);
+
+ setVerticalStretchable(true);
+ setHorizontalStretchable(true);
+#endif //!COMPILE_USE_QT4
+ //m_pBase->setMinimumWidth(KVI_TASKBAR_MIN_WIDTH);
+ //setMinimumWidth(KVI_TASKBAR_MIN_WIDTH);
+
+ m_pBase->setMinimumHeight(m_iButtonHeight+5);
+ setMinimumHeight(m_iButtonHeight+5);
+
+#ifndef COMPILE_USE_QT4
+ setResizeEnabled( true );
+ connect(this,SIGNAL(orientationChanged(Orientation)),this,SLOT(orientationChangedSlot(Orientation)));
+#endif
+}
+
+KviClassicTaskBar::~KviClassicTaskBar()
+{
+ delete m_pButtonList;
+ m_pButtonList = 0;
+}
+
+void KviClassicTaskBar::orientationChangedSlot(Qt::Orientation o)
+{
+#ifndef COMPILE_USE_QT4
+ if (orientation() == Qt::Horizontal) m_pBase->setMinimumHeight(m_iButtonHeight);
+#endif
+ doLayout();
+}
+
+/*
+void KviClassicTaskBar::fontChange(const QFont &old)
+{
+ calcButtonHeight();
+ doLayout();
+ QToolBar::fontChange(old);
+}
+*/
+
+void KviClassicTaskBar::updateActivityMeter()
+{
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarActivityMeter))
+ {
+ for(KviTaskBarButton * btn = m_pButtonList->first();btn;btn = m_pButtonList->next())
+ btn->update();
+ }
+}
+
+void KviClassicTaskBar::calcButtonHeight()
+{
+ QFontMetrics fm(KVI_OPTION_FONT(KviOption_fontTaskbar));
+ m_iButtonHeight = fm.lineSpacing() + 6;
+ if(m_iButtonHeight < 22)m_iButtonHeight = 22;
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIrcContextIndicator))
+ m_iButtonHeight += KVI_TASKBARBUTTON_CONTEXTINDICATORHEIGHT;
+}
+
+void KviClassicTaskBar::insertButton(KviTaskBarButton * b)
+{
+ int idx = 0;
+// if(KVI_OPTION_BOOL(KviOption_boolSortTaskbarButtons))
+// {
+ // first sort by irc context
+ for(KviTaskBarButton * btn = m_pButtonList->first();btn;btn = m_pButtonList->next())
+ {
+ if(btn->kviWindow()->console() == b->kviWindow()->console())
+ {
+ // same irc context (or none)
+ // sort by type now
+ for(;btn;btn = m_pButtonList->next())
+ {
+ if((btn->kviWindow()->type() > b->kviWindow()->type()) ||
+ (btn->kviWindow()->console() != b->kviWindow()->console()))
+ {
+ // greater type or another irc context
+ m_pButtonList->insert(idx,b);
+ return;
+ } else if(btn->kviWindow()->type() == b->kviWindow()->type())
+ {
+ // same type!
+ // sort by name
+ if(!KVI_OPTION_BOOL(KviOption_boolSortTaskBarItemsByName) || (KviQString::cmpCI(btn->kviWindow()->windowName(),b->kviWindow()->windowName()) > 0))
+ {
+ // got a "higher one"
+ m_pButtonList->insert(idx,b);
+ return;
+ }
+ }
+ idx++;
+ }
+ // ran out of buttons
+ m_pButtonList->append(b);
+ return;
+ } else {
+ if(!(btn->kviWindow()->console()) && b->kviWindow()->console())
+ {
+ // this must be a new console...insert before the contextless windows
+ __range_valid(b->kviWindow()->console() == b->kviWindow());
+ m_pButtonList->insert(idx,b);
+ return;
+ } else idx++; // wrong irc contet...go on searching
+ }
+ }
+// }
+ // no sorting selected , or no match for this irc context
+ m_pButtonList->append(b);
+}
+
+
+KviTaskBarItem * KviClassicTaskBar::addItem(KviWindow * wnd)
+{
+ KviTaskBarButton * b = new KviTaskBarButton(m_pBase,wnd,"");
+ insertButton(b);
+ b->show();
+ doLayout();
+ if(g_pFrame->dockExtension())g_pFrame->dockExtension()->refresh();
+/* if(b->width() < m_pBase->width()) m_pBase->setMinimumWidth(b->width());
+ if(b->height() < m_pBase->height()) m_pBase->setMinimumWidth(b->height());*/
+ return b;
+}
+
+bool KviClassicTaskBar::removeItem(KviTaskBarItem * it)
+{
+ if(it)
+ {
+ m_pButtonList->removeRef((KviTaskBarButton *)it);
+ doLayout();
+ if(g_pFrame->dockExtension())g_pFrame->dockExtension()->refresh();
+ }
+ return true;
+}
+
+void KviClassicTaskBar::setActiveItem(KviTaskBarItem * it)
+{
+ if(it)
+ {
+ for(KviTaskBarButton * b = m_pButtonList->first();b;b = m_pButtonList->next())
+ {
+ b->setActive(((KviTaskBarButton *)it) == b);
+ }
+ if(g_pFrame->dockExtension())g_pFrame->dockExtension()->refresh();
+ }
+}
+
+
+void KviClassicTaskBar::doLayout()
+{
+ if(!m_pButtonList->count())return;
+
+ if(!m_pBase->isVisible())
+ {
+ // handle a windows bug: sometimes this ugly thing happens
+ // this shouldn't hurt on other platforms
+ if(isVisible())m_pBase->show();
+ }
+
+ int baseWidth = m_pBase->width();
+ int btnsInRow = baseWidth / KVI_OPTION_UINT(KviOption_uintTaskBarButtonMinWidth);
+ int totCount = m_pButtonList->count();
+ //int btnsInRow = totCount * totCount * btnWidth * btnWidth / (wdth * wdth);
+ if(btnsInRow < 1)btnsInRow = 1;
+
+ int rows = 0;
+ while(totCount > 0)
+ {
+ rows++;
+ totCount -= btnsInRow;
+ }
+
+#ifdef COMPILE_USE_QT4
+ if(isFloating() || ((g_pFrame->dockWidgetArea(this) != Qt::BottomDockWidgetArea) && (g_pFrame->dockWidgetArea(this) != Qt::TopDockWidgetArea)))
+ {
+ QDockWidget::DockWidgetFeatures f = features();
+ if(f & QDockWidget::DockWidgetVerticalTitleBar)
+ {
+ f &= ~QDockWidget::DockWidgetVerticalTitleBar;
+ setFeatures(f);
+ }
+ } else {
+ QDockWidget::DockWidgetFeatures f = features();
+ if(!(f & QDockWidget::DockWidgetVerticalTitleBar))
+ {
+ f |= QDockWidget::DockWidgetVerticalTitleBar;
+ setFeatures(f);
+ }
+ }
+#endif
+
+#ifdef COMPILE_USE_QT4
+ if ((width() > height()) &&
+#else
+ if ((orientation() == Qt::Horizontal) &&
+#endif
+ (((unsigned int)rows) > m_pBase->height() / m_iButtonHeight ))
+ {
+ rows = m_pBase->height() / m_iButtonHeight;
+ }
+ if(rows==0) rows=1;
+ totCount = m_pButtonList->count();
+ btnsInRow = totCount / rows;
+ if(totCount % rows)btnsInRow++;
+
+ //m_pBase->setMinimumHeight(rows * m_iButtonHeight);
+
+ int theWidth = 0;
+ int theX = 0;
+ int theY = -m_iButtonHeight;
+ int btnIdx = 0;
+ int btnInRow = 1;
+ for(KviTaskBarButton * b = m_pButtonList->first();b;b = m_pButtonList->next())
+ {
+ if((btnIdx % btnsInRow) == 0)
+ {
+ int inRow = ((totCount < btnsInRow ) ? totCount : btnsInRow);
+ theWidth = baseWidth / (inRow ? inRow : 1);
+ theX = 0;
+ theY += m_iButtonHeight;
+ btnInRow = 1;
+ } else {
+ if((btnInRow == btnsInRow) || (totCount == 1))theWidth = baseWidth - theX;
+ }
+
+ if( KVI_OPTION_BOOL(KviOption_boolClassicTaskBarSetMaximumButtonWidth) && (theWidth > KVI_OPTION_UINT(KviOption_uintClassicTaskBarMaximumButtonWidth)) &&
+#ifdef COMPILE_USE_QT4
+ (width() > height())
+#else
+ (orientation() == Qt::Horizontal)
+#endif
+ )
+ theWidth = KVI_OPTION_UINT(KviOption_uintClassicTaskBarMaximumButtonWidth);
+
+ b->setGeometry(theX,theY,theWidth,m_iButtonHeight);
+
+ if(btnInRow != btnsInRow)
+ {
+ theX += theWidth;
+ btnInRow++;
+ }
+ btnIdx++;
+ totCount--;
+ }
+}
+
+void KviClassicTaskBar::applyOptions()
+{
+ for(KviTaskBarButton * b = m_pButtonList->first();b;b = m_pButtonList->next())
+ {
+ b->setFlat(KVI_OPTION_BOOL(KviOption_boolUseFlatClassicTaskbarButtons));
+ }
+ doLayout();
+}
+
+void KviClassicTaskBar::resizeEvent(QResizeEvent *e)
+{
+/*
+#ifdef COMPILE_USE_QT4
+ if(orientation() == Qt::Horizontal)
+ {
+ int iRows = height()/m_iButtonHeight;
+ if(!iRows) iRows=1;
+ debug("%i %i",height(),iRows);
+ resize(width(),iRows*m_iButtonHeight);
+ }
+#endif
+*/
+ KviTaskBarBase::resizeEvent(e);
+ doLayout();
+}
+
+inline KviTaskBarItem * KviClassicTaskBar::firstItem()
+{
+ return m_pButtonList->first();
+}
+
+inline KviTaskBarItem * KviClassicTaskBar::lastItem(void)
+{
+ return m_pButtonList->last();
+}
+
+inline KviTaskBarItem * KviClassicTaskBar::nextItem()
+{
+ return m_pButtonList->next();
+}
+
+inline KviTaskBarItem * KviClassicTaskBar::prevItem(void)
+{
+ return m_pButtonList->prev();
+}
+
+inline bool KviClassicTaskBar::setIterationPointer(KviTaskBarItem * it)
+{
+ return (m_pButtonList->findRef((const KviTaskBarButton *)it) != -1);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// KviTreeTaskBarItem
+//
+
+
+KviTreeTaskBarItem::KviTreeTaskBarItem(KviTalListView * par,KviWindow * wnd)
+: KviTalListViewItem(par) , KviTaskBarItem(wnd)
+{
+ m_iStepNumber=0;
+ m_bIncreasing=0;
+ m_pInternal=new KviTreeTaskBarItemInternal(this);
+ m_pAnimTimer=new QTimer();
+ QObject::connect( m_pAnimTimer, SIGNAL(timeout()), m_pInternal, SLOT(timerShot()));
+ applyOptions();
+}
+
+KviTreeTaskBarItem::KviTreeTaskBarItem(KviTreeTaskBarItem * par,KviWindow * wnd)
+: KviTalListViewItem(par) , KviTaskBarItem(wnd)
+{
+ m_iStepNumber=0;
+ m_bIncreasing=0;
+ m_pInternal=new KviTreeTaskBarItemInternal(this);
+ m_pAnimTimer=new QTimer();
+ QObject::connect( m_pAnimTimer, SIGNAL(timeout()), m_pInternal, SLOT(timerShot()));
+ applyOptions();
+}
+
+int KviTreeTaskBarItem::calculateColor(int col1,int col2)
+{
+ int result=col1+(col2-col1)/KVI_NUM_STEPS*m_iStepNumber;
+ return result<255 ? result :255;
+}
+
+KviTreeTaskBarItem::~KviTreeTaskBarItem()
+{
+ KviTalListView* pView=(KviTalListView *)listView();
+ if(pView)
+ if(((KviTreeTaskBarListView*)(pView))->m_pPrevItem==this) ((KviTreeTaskBarListView*)(listView()))->m_pPrevItem=0;
+ delete m_pAnimTimer;
+ delete m_pInternal;
+}
+
+void KviTreeTaskBarItem::applyOptions()
+{
+ m_iRedDiff=(KVI_OPTION_COLOR(KviOption_colorTreeTaskBarActiveBackground).red()-KVI_OPTION_COLOR(KviOption_colorTreeTaskBarBackground).red())/KVI_NUM_STEPS;
+ m_iGreenDiff=(KVI_OPTION_COLOR(KviOption_colorTreeTaskBarActiveBackground).green()-KVI_OPTION_COLOR(KviOption_colorTreeTaskBarBackground).green())/KVI_NUM_STEPS;
+ m_iBlueDiff=(KVI_OPTION_COLOR(KviOption_colorTreeTaskBarActiveBackground).blue()-KVI_OPTION_COLOR(KviOption_colorTreeTaskBarBackground).blue())/KVI_NUM_STEPS;
+}
+
+void KviTreeTaskBarItem::captionChanged()
+{
+ // FIXME: can we do better ?
+ repaint();
+}
+
+void KviTreeTaskBarItem::unhighlight()
+{
+ if(m_iHighlightLevel < 1)return;
+ m_iHighlightLevel = 0;
+ if(g_pFrame->dockExtension())g_pFrame->dockExtension()->refresh();
+ repaint();
+}
+
+void KviTreeTaskBarItem::highlight(int iLevel)
+{
+ if(iLevel <= m_iHighlightLevel)return;
+ if(isSelected() && g_pFrame->isActiveWindow())return;
+ m_iHighlightLevel = iLevel;
+ if(g_pFrame->dockExtension())g_pFrame->dockExtension()->refresh();
+ if(isSelected())return;
+ repaint(); // repaint(false) ?
+}
+
+void KviTreeTaskBarItem::setProgress(int progress)
+{
+ if(progress == m_iProgress)return;
+ m_iProgress = progress;
+ repaint(); // repaint(false) ?
+}
+
+void KviTreeTaskBarItem::setActive(bool bActive)
+{
+ if(bActive)
+ {
+// m_bHighlighted = false;
+// m_bAltColor = false;
+ m_iHighlightLevel = 0;
+ // was not selected: the listView will repaint it
+ } else {
+ if(isSelected())
+ {
+ // was active... unset the highlighting if it was silently turned on while being active...
+// m_bHighlighted = false;
+// m_bAltColor = false;
+ m_iHighlightLevel = 0;
+ // was selected: the list view will repaint it
+ }
+ }
+}
+
+#ifdef COMPILE_USE_QT4
+void KviTreeTaskBarItem::paintBranches(QPainter *p,const QColorGroup &,int w,int y,int h)
+#else
+void KviTreeTaskBarItem::paintBranches(QPainter *p,const QColorGroup &,int w,int y,int h,GUIStyle s)
+#endif
+{
+ SET_ANTI_ALIASING(*p);
+ ((KviTreeTaskBarListView *)listView())->paintEmptyArea(p,QRect(0,y,w,totalHeight() - height()));
+}
+
+void KviTreeTaskBarItem::paintCell(QPainter *painter,const QColorGroup &cg,int column,int width,int)
+{
+ KviDoubleBuffer db(width,height());
+ QPixmap * pMemBuffer = db.pixmap();
+ QPainter p(pMemBuffer);
+ SET_ANTI_ALIASING(p);
+
+ if(isSelected())
+ {
+ p.fillRect(0,0,width,height(),KVI_OPTION_COLOR(KviOption_colorTreeTaskBarActiveBackground));
+ } else {
+ if(!m_iStepNumber)
+ {
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = listView()->viewport()->mapToGlobal(QPoint(int(painter->worldMatrix().dx()),int(painter->worldMatrix().dy())));
+ p.drawTiledPixmap(0,0,width,height(),*g_pShadedChildGlobalDesktopBackground,pnt.x(),pnt.y());
+ } else {
+#endif
+ p.fillRect(0,0,width,height(),KVI_OPTION_COLOR(KviOption_colorTreeTaskBarBackground));
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+ QPixmap * pix = KVI_OPTION_PIXMAP(KviOption_pixmapTreeTaskBarBackground).pixmap();
+ if(pix)
+ {
+ QPoint pnt = listView()->viewportToContents(QPoint(int(painter->worldMatrix().dx()),int(painter->worldMatrix().dy())));
+ //p.drawTiledPixmap(0,0,width,height(),*pix,pnt.x(),pnt.y());
+// debug("%i %i",pnt.x(),pnt.y());
+ p.translate(-pnt.x(),-pnt.y());
+ KviPixmapUtils::drawPixmapWithPainter(&p,pix,KVI_OPTION_UINT(KviOption_uintTreeTaskBarPixmapAlign),QRect(pnt.x(),pnt.y(),width,height()),listView()->width(),listView()->height());
+ p.translate(pnt.x(),pnt.y());
+ }
+ } else {
+ p.fillRect(0,0,width,height(),
+ QColor(KVI_OPTION_COLOR(KviOption_colorTreeTaskBarBackground).red()+m_iRedDiff*m_iStepNumber,
+ KVI_OPTION_COLOR(KviOption_colorTreeTaskBarBackground).green()+m_iGreenDiff*m_iStepNumber,
+ KVI_OPTION_COLOR(KviOption_colorTreeTaskBarBackground).blue()+m_iBlueDiff*m_iStepNumber
+ )
+ );
+
+ }
+ }
+
+ int h = height();
+ int im = listView()->itemMargin();
+ int yPixmap = (h - 16) >> 1;
+
+ QString szText;
+
+ QRect cRect(im + 3,0,width - (im << 1),height());
+
+ switch(m_pWindow->type())
+ {
+ case KVI_WINDOW_TYPE_CONSOLE:
+ {
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIrcContextIndicator))
+ {
+ QColor base = cg.background();
+ QColor cntx = KVI_OPTION_ICCOLOR(m_pWindow->console()->ircContextId() % KVI_NUM_ICCOLOR_OPTIONS);
+ base.setRgb((base.red() + cntx.red()) >> 1,(base.green() + cntx.green()) >> 1,
+ (base.blue() + cntx.blue()) >> 1);
+ p.fillRect(im + 2,yPixmap + 1,14,15,base);
+ //draw_frame_helper(&p,im + 1,yPixmap,im + 15,yPixmap + 15,base.light(180),base.dark());
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIcons))
+ {
+ p.drawPixmap(im + 20,yPixmap,*(m_pWindow->myIconPtr()));
+ cRect.setLeft(cRect.left() + 37);
+ } else {
+ cRect.setLeft(cRect.left() + 20);
+ }
+ } else {
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIcons))
+ {
+ p.drawPixmap(im,yPixmap,*(m_pWindow->myIconPtr()));
+ cRect.setLeft(cRect.left() + 17);
+ }
+ }
+ QFont f = QFont();
+ f.setBold(true);
+ p.setFont(f);
+ KviTaskBarBase::getTextForConsole(szText,(KviConsole *)m_pWindow);
+ }
+ break;
+ case KVI_WINDOW_TYPE_CHANNEL:
+ case KVI_WINDOW_TYPE_DEADCHANNEL:
+ szText = ((KviChannel *)m_pWindow)->nameWithUserFlag();
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIcons))
+ {
+ p.drawPixmap(im,yPixmap,*(m_pWindow->myIconPtr()));
+ cRect.setLeft(cRect.left() + 17);
+ }
+ break;
+ case KVI_WINDOW_TYPE_QUERY:
+ case KVI_WINDOW_TYPE_DEADQUERY:
+ szText = m_pWindow->windowName();
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIcons))
+ {
+ p.drawPixmap(im,yPixmap,*(m_pWindow->myIconPtr()));
+ cRect.setLeft(cRect.left() + 17);
+ }
+ break;
+ default:
+ szText = m_pWindow->plainTextCaption();
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarIcons))
+ {
+ p.drawPixmap(im,yPixmap,*(m_pWindow->myIconPtr()));
+ cRect.setLeft(cRect.left() + 17);
+ }
+ break;
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarActivityMeter))
+ {
+ unsigned int uActivityValue;
+ unsigned int uActivityTemperature;
+ if(m_pWindow->activityMeter(&uActivityValue,&uActivityTemperature))
+ {
+ p.drawPixmap(cRect.left(),yPixmap,*g_pActivityMeterPixmap,uActivityValue * 5,uActivityTemperature * 16,5,16);
+ cRect.setLeft(cRect.left() + 7);
+ }
+ }
+
+ if(m_iProgress >= 0)
+ {
+ // paint the progress bar
+ int wdth = (m_iProgress * cRect.width()) / 100;
+ p.fillRect(cRect.x(),cRect.y(),wdth,cRect.height(),KVI_OPTION_COLOR(KviOption_colorTreeTaskBarProgress));
+ }
+
+ if(isSelected())
+ {
+ p.setPen(KVI_OPTION_COLOR(KviOption_colorTreeTaskBarActiveForeground));
+ } else {
+ int iLevel;
+ switch(m_iHighlightLevel)
+ {
+ case 0: iLevel = KviOption_colorTreeTaskBarForeground; break;
+ case 1: iLevel = KviOption_colorTreeTaskBarHighlight1Foreground; break;
+ case 2: iLevel = KviOption_colorTreeTaskBarHighlight2Foreground; break;
+ case 3: iLevel = KviOption_colorTreeTaskBarHighlight3Foreground; break;
+ case 4: iLevel = KviOption_colorTreeTaskBarHighlight4Foreground; break;
+ default: iLevel = KviOption_colorTreeTaskBarHighlight5Foreground; break;
+ }
+ p.setPen(
+ QColor(
+ calculateColor(KVI_OPTION_COLOR(iLevel).red(),KVI_OPTION_COLOR(KviOption_colorTreeTaskBarActiveForeground).red()),
+ calculateColor(KVI_OPTION_COLOR(iLevel).green(),KVI_OPTION_COLOR(KviOption_colorTreeTaskBarActiveForeground).green()),
+ calculateColor(KVI_OPTION_COLOR(iLevel).blue(),KVI_OPTION_COLOR(KviOption_colorTreeTaskBarActiveForeground).blue())
+ )
+ );
+ }
+
+ if(m_pWindow->isMinimized())
+ {
+ QString tmp = QChar('(');
+ tmp += szText;
+ tmp += QChar(')');
+ p.drawText(cRect,Qt::AlignLeft | Qt::AlignVCenter,tmp,-1,0);
+ } else {
+ p.drawText(cRect,Qt::AlignLeft | Qt::AlignVCenter,szText,-1,0);
+ }
+
+ painter->drawPixmap(0,0,*pMemBuffer,0,0,width,height());
+ //bitBlt(painter->pixmap(),0,0,pMemBuffer,0,0,width,height(),Qt::CopyROP,false);
+}
+
+QString KviTreeTaskBarItem::key(int,bool) const
+{
+ QString ret = m_pWindow->typeString();
+ ret.append(m_pWindow->windowName());
+ return ret;
+}
+
+void KviTreeTaskBarItem::timerShot()
+{
+ if(m_bIncreasing)
+ m_iStepNumber++;
+ else
+ m_iStepNumber--;
+
+ if((m_iStepNumber>=KVI_NUM_STEPS) && m_bIncreasing)
+ {
+ m_pAnimTimer->stop();
+ m_iStepNumber=KVI_NUM_STEPS; //make shure, that we cannot get out of range
+ } else if((m_iStepNumber<=0) && !m_bIncreasing) {
+ m_pAnimTimer->stop();
+ m_iStepNumber=0; //make shure, that we cannot get out of range
+ }
+ repaint();
+}
+
+void KviTreeTaskBarItem::mouseEnter()
+{
+ if(KVI_OPTION_BOOL(KviOption_boolEnableVisualEffects))
+ {
+ m_bIncreasing=true;
+ if(!m_pAnimTimer->isActive()) m_pAnimTimer->start(KVI_TIMER_DELAY);
+ }
+}
+
+void KviTreeTaskBarItem::mouseLeave()
+{
+ if(KVI_OPTION_BOOL(KviOption_boolEnableVisualEffects))
+ {
+ m_bIncreasing=false;
+ if(!m_pAnimTimer->isActive()) m_pAnimTimer->start(KVI_TIMER_DELAY);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// KviTreeTaskBarListView
+//
+
+
+KviTreeTaskBarListView::KviTreeTaskBarListView(QWidget * par)
+: KviTalListView(par)
+{
+ //setSorting(0);
+ setShowSortIndicator(true);
+ setItemMargin(2);
+ setFrameShape(NoFrame);
+ viewport()->setMouseTracking(TRUE);
+ m_pPrevItem=0;
+ setHScrollBarMode(KviTalListView::AlwaysOff);
+}
+
+KviTreeTaskBarListView::~KviTreeTaskBarListView()
+{
+}
+
+void KviTreeTaskBarListView::contentsMouseMoveEvent ( QMouseEvent * e )
+{
+ if(!e) return;
+ KviTreeTaskBarItem* pCur=(KviTreeTaskBarItem*)(itemAt(contentsToViewport(e->pos())));
+ if(pCur!=m_pPrevItem)
+ {
+ if(m_pPrevItem)m_pPrevItem->mouseLeave();
+ if(pCur) pCur->mouseEnter();
+ setCursor(Qt::PointingHandCursor);
+ m_pPrevItem=pCur;
+ } else if(!pCur) {
+ setCursor(Qt::ArrowCursor);
+ }
+}
+void KviTreeTaskBarListView::leaveEvent(QEvent *)
+{
+ if(m_pPrevItem) m_pPrevItem->mouseLeave();
+ m_pPrevItem=0;
+ setCursor(Qt::ArrowCursor);
+}
+
+
+void KviTreeTaskBarListView::contentsMousePressEvent(QMouseEvent *e)
+{
+ KviTalListViewItem * it = (KviTalListViewItem *)itemAt(contentsToViewport(e->pos()));
+ if(it)
+ {
+ if(e->button() & Qt::LeftButton)emit leftMousePress(it);
+ else if(e->button() & Qt::RightButton)emit rightMousePress(it);
+ } else {
+ if(e->button() & Qt::RightButton)
+ {
+ KviTalPopupMenu* pPopup=new KviTalPopupMenu();
+ pPopup->insertItem(__tr2qs("Sort"),this,SLOT(sort()));
+ pPopup->insertItem(__tr2qs("Reverse Sort"),this,SLOT(reverseSort()));
+ pPopup->popup(QCursor::pos());
+ }
+ }
+}
+
+void KviTreeTaskBarListView::sort()
+{
+ setSorting(0,TRUE);
+}
+
+void KviTreeTaskBarListView::reverseSort()
+{
+ setSorting(0,FALSE);
+}
+
+void KviTreeTaskBarListView::resizeEvent(QResizeEvent *e)
+{
+ KviTalListView::resizeEvent(e);
+ setColumnWidth(0,viewport()->width());
+ resizeContents(viewport()->width(),contentsHeight());
+}
+
+//void KviTreeTaskBarListView::paintEmptyAreaInternal(QPainter * p,const QRect &viewportRect,const QRect &painterRect)
+//{
+//
+//}
+
+void KviTreeTaskBarListView::paintEmptyArea(QPainter * p,const QRect &rct)
+{
+ SET_ANTI_ALIASING(*p);
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = viewport()->mapToGlobal(QPoint(rct.x() + int(p->worldMatrix().dx()),rct.y() + int(p->worldMatrix().dy())));
+ p->drawTiledPixmap(rct.x(),rct.y(),rct.width(),rct.height(),*g_pShadedChildGlobalDesktopBackground,pnt.x(),pnt.y());
+ } else {
+#endif
+ p->fillRect(rct.x(),rct.y(),rct.width(),rct.height(),KVI_OPTION_COLOR(KviOption_colorTreeTaskBarBackground));
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+
+ QPixmap * pix = KVI_OPTION_PIXMAP(KviOption_pixmapTreeTaskBarBackground).pixmap();
+ if(pix)
+ {
+ QPoint pnt = viewportToContents(QPoint(rct.x() + int(p->worldMatrix().dx()),rct.y() + int(p->worldMatrix().dy())));
+ //p->drawTiledPixmap(rct.x(),rct.y(),rct.width(),rct.height(),*pix,pnt.x(),pnt.y());
+ KviPixmapUtils::drawPixmapWithPainter(p,pix,KVI_OPTION_UINT(KviOption_uintTreeTaskBarPixmapAlign),rct,viewport()->width(),viewport()->height(),pnt.x(),pnt.y());
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// KviTreeTaskBar
+//
+
+KviTreeTaskBar::KviTreeTaskBar()
+: KviTaskBarBase()
+{
+ m_pListView = new KviTreeTaskBarListView(this);
+ m_pListView->addColumn(__tr2qs("Window List"),135);
+ m_pListView->setAllColumnsShowFocus(true);
+ m_pListView->setMultiSelection(false);
+
+#ifdef COMPILE_USE_QT4
+ setWidget(m_pListView);
+#else //!COMPILE_USE_QT4
+ setStretchableWidget(m_pListView);
+
+ setVerticalStretchable(true);
+ setHorizontalStretchable(true);
+#endif //!COMPILE_USE_QT4
+
+
+ // FIXME: this code is useless ?
+ if(KVI_OPTION_UINT(KviOption_uintTreeTaskBarMinimumWidth) < 48)
+ KVI_OPTION_UINT(KviOption_uintTreeTaskBarMinimumWidth) = 48;
+ int iMin = m_pListView->minimumSize().width() + 4;
+ if(((unsigned int)iMin) < KVI_OPTION_UINT(KviOption_uintTreeTaskBarMinimumWidth))
+ iMin = KVI_OPTION_UINT(KviOption_uintTreeTaskBarMinimumWidth);
+ setMinimumWidth(iMin);
+
+ // this is surely useful :)
+ m_pListView->setMinimumWidth(4);
+
+ //setMaximumWidth(KVI_OPTION_UINT(KviOption_uintTreeTaskBarMaximumWidth));
+ //m_pListView->setMinimumWidth(KVI_OPTION_UINT(KviOption_uintTreeTaskBarMinimumWidth));
+ //m_pListView->setMaximumWidth(KVI_OPTION_UINT(KviOption_uintTreeTaskBarMaximumWidth));
+#ifdef COMPILE_USE_QT4
+ m_pListView->setFocusPolicy(Qt::NoFocus);
+#else
+ m_pListView->setFocusPolicy(QWidget::NoFocus);
+#endif
+ m_pListView->setStaticBackground(true);
+#ifdef COMPILE_USE_QT4
+ m_pListView->viewport()->setAutoFillBackground(false);
+#else
+ m_pListView->viewport()->setBackgroundMode(QWidget::NoBackground);
+#endif
+ if(!KVI_OPTION_BOOL(KviOption_boolShowTreeTaskbarHeader))
+ {
+ m_pListView->header()->hide();
+ }
+
+ m_pListView->header()->setResizeEnabled(true);
+
+#ifdef COMPILE_USE_QT4
+ setMaximumWidth(600);
+#endif
+
+ m_pListView->viewport()->installEventFilter(this);
+
+#if QT_VERSION >= 300
+#ifndef COMPILE_USE_QT4
+ setResizeEnabled(true);
+#endif
+#endif
+
+ m_pToolTip = new KviDynamicToolTip(m_pListView->viewport(),"tree_taskbar_tooltip");
+ connect(m_pToolTip,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &)));
+}
+
+KviTreeTaskBar::~KviTreeTaskBar()
+{
+}
+
+void KviTreeTaskBar::updatePseudoTransparency()
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ m_pListView->viewport()->update();
+#endif
+}
+
+void KviTreeTaskBar::moveEvent(QMoveEvent *)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ updatePseudoTransparency();
+#endif
+}
+
+void KviTreeTaskBar::tipRequest(KviDynamicToolTip *,const QPoint &pnt)
+{
+ if(KVI_OPTION_BOOL(KviOption_boolShowTaskBarToolTips))
+ {
+ KviTalListViewItem * it = (KviTalListViewItem *)m_pListView->itemAt(pnt);
+ if(it)
+ {
+ QString szText;
+ ((KviTreeTaskBarItem *)it)->m_pWindow->getTaskBarTipText(szText);
+ m_pToolTip->tip(m_pListView->itemRect(it),szText);
+ }
+ }
+}
+
+bool KviTreeTaskBar::eventFilter(QObject * o,QEvent *e)
+{
+ if(o == m_pListView->viewport())
+ {
+ if(e->type() == QEvent::MouseButtonPress)
+ {
+ QMouseEvent * ev = (QMouseEvent *)e;
+ KviTreeTaskBarItem * it = (KviTreeTaskBarItem *)m_pListView->itemAt(ev->pos());
+ if(!it)return false;
+ KviWindow * wnd = it->kviWindow();
+ if(wnd)
+ {
+ if(ev->button() & Qt::LeftButton)
+ {
+ if(ev->state() & Qt::ShiftButton)
+ {
+ wnd->delayedClose();
+ } else {
+ if((g_pActiveWindow != wnd) || (wnd->isMinimized()))g_pFrame->setActiveWindow(wnd);
+ else wnd->minimize();
+ }
+ } else {
+ wnd->contextPopup();
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+
+KviTaskBarItem * KviTreeTaskBar::addItem(KviWindow * wnd)
+{
+ // complex insertion task
+ if(wnd->console())
+ {
+ if(wnd->type() != KVI_WINDOW_TYPE_CONSOLE)
+ {
+ ((KviTreeTaskBarItem *)(wnd->console()->m_pTaskBarItem))->setOpen(true);
+ return new KviTreeTaskBarItem(((KviTreeTaskBarItem *)(wnd->console()->m_pTaskBarItem)),wnd);
+ }
+ }
+
+ // console , or a window that has no irc context
+ return new KviTreeTaskBarItem(m_pListView,wnd);
+}
+
+bool KviTreeTaskBar::removeItem(KviTaskBarItem * it)
+{
+ delete (KviTreeTaskBarItem *)it;
+ return true;
+}
+
+void KviTreeTaskBar::setActiveItem(KviTaskBarItem * it)
+{
+ if(it)
+ {
+ KviTreeTaskBarItem * cur = (KviTreeTaskBarItem *)m_pListView->currentItem();
+ if(cur && (cur != (KviTreeTaskBarItem *)it))
+ {
+ cur->setActive(false);
+ }
+ if(((KviTreeTaskBarItem *)it)->parent())
+ {
+ if(!((KviTreeTaskBarItem *)it)->parent()->isOpen())((KviTreeTaskBarItem *)it)->parent()->setOpen(true);
+ }
+ ((KviTreeTaskBarItem *)it)->setActive(true);
+ m_pListView->setSelected(((KviTreeTaskBarItem *)it),true); // this MUST go after it->setActive()
+ if(g_pFrame->dockExtension())g_pFrame->dockExtension()->refresh();
+ }
+}
+
+void KviTreeTaskBar::updateActivityMeter()
+{
+ if(KVI_OPTION_BOOL(KviOption_boolUseTaskBarActivityMeter))
+ {
+ m_pListView->viewport()->update();
+ }
+}
+
+KviTaskBarItem * KviTreeTaskBar::firstItem()
+{
+ m_pCurrentItem = (KviTreeTaskBarItem *)m_pListView->firstChild();
+ return m_pCurrentItem;
+}
+
+KviTaskBarItem * KviTreeTaskBar::nextItem()
+{
+ if(!m_pCurrentItem)return 0;
+
+ if(m_pCurrentItem->firstChild())
+ {
+ m_pCurrentItem = (KviTreeTaskBarItem *)m_pCurrentItem->firstChild();
+ } else {
+ // this item has no children: try the next sibling
+ if(m_pCurrentItem->nextSibling())
+ {
+ m_pCurrentItem = (KviTreeTaskBarItem *)m_pCurrentItem->nextSibling();
+ } else {
+ if(m_pCurrentItem->parent())
+ {
+ // child with not siblings : try the sibling of the parent
+ m_pCurrentItem = (KviTreeTaskBarItem *)m_pCurrentItem->parent()->nextSibling();
+ } else {
+ m_pCurrentItem = 0; // toplevel with no siblings
+ }
+ }
+ }
+ return m_pCurrentItem;
+}
+
+KviTaskBarItem * KviTreeTaskBar::prevItem()
+{
+ KviTreeTaskBarItem * it;
+
+ if(!m_pCurrentItem)return 0;
+
+ if(m_pCurrentItem->parent())
+ {
+ // a child item
+ it = (KviTreeTaskBarItem *)m_pCurrentItem->parent()->firstChild();
+
+ while(it)
+ {
+ if(((KviTreeTaskBarItem *)it->nextSibling()) == m_pCurrentItem)break;
+ else it = ((KviTreeTaskBarItem *)(it->nextSibling()));
+ }
+ if(!it)
+ {
+ it = (KviTreeTaskBarItem *)m_pCurrentItem->parent();
+ }
+
+ } else {
+ // a toplevel one
+ it = (KviTreeTaskBarItem *)m_pListView->firstChild();
+ while(it)
+ {
+ if(((KviTreeTaskBarItem *)it->nextSibling()) == m_pCurrentItem)break;
+ else it = ((KviTreeTaskBarItem *)(it->nextSibling()));
+ }
+ if(it)
+ {
+ if(it->firstChild())
+ {
+ it = ((KviTreeTaskBarItem *)(it->firstChild()));
+ while(it->nextSibling())it = ((KviTreeTaskBarItem *)(it->nextSibling()));
+ }
+ }
+ }
+
+ m_pCurrentItem = it;
+ return it;
+}
+
+KviTaskBarItem * KviTreeTaskBar::lastItem()
+{
+ // first find last toplevel item
+ m_pCurrentItem = (KviTreeTaskBarItem *)m_pListView->firstChild();
+ for(;;)
+ {
+ if(m_pCurrentItem->nextSibling())
+ {
+ m_pCurrentItem = (KviTreeTaskBarItem *)m_pCurrentItem->nextSibling();
+ } else if(m_pCurrentItem->firstChild())
+ {
+ m_pCurrentItem = (KviTreeTaskBarItem *)m_pCurrentItem->firstChild();
+ } else return m_pCurrentItem;
+ }
+ return 0;
+}
+
+bool KviTreeTaskBar::setIterationPointer(KviTaskBarItem * it)
+{
+ m_pCurrentItem = (KviTreeTaskBarItem *)it;
+ if(!it)return true;
+ if(((KviTalListView *)m_pListView) == ((KviTreeTaskBarItem *)it)->listView())return true;
+ m_pCurrentItem = 0;
+ return false;
+}
+
+void KviTreeTaskBar::applyOptions()
+{
+ m_pListView->update();
+ if(!KVI_OPTION_BOOL(KviOption_boolShowTreeTaskbarHeader))
+ {
+ m_pListView->header()->hide();
+ } else {
+ m_pListView->header()->show();
+ }
+}
+
+#include "kvi_taskbar.moc"
diff --git a/src/kvirc/ui/kvi_taskbar.h b/src/kvirc/ui/kvi_taskbar.h
new file mode 100644
index 0000000..300e0f6
--- /dev/null
+++ b/src/kvirc/ui/kvi_taskbar.h
@@ -0,0 +1,312 @@
+#ifndef _KVI_TASKBAR_H_
+#define _KVI_TASKBAR_H_
+//=============================================================================
+//
+// File : kvi_taskbar.h
+// Creation date : Thu Jan 7 1999 03:56:50 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+#include "kvi_pointerlist.h"
+#include <qframe.h>
+#include "kvi_tal_tooltip.h"
+#include "kvi_tal_listview.h"
+#include <qpushbutton.h>
+
+
+
+class KviWindow;
+class KviFrame;
+class QPixmap;
+class KviDynamicToolTip;
+class KviConsole;
+
+//
+// KviTaskBarItem
+//
+// The base class for the taskBar items
+// this is the only interface to an item visible to external classes
+//
+
+class KVIRC_API KviTaskBarItem
+{
+public:
+ KviTaskBarItem(KviWindow * wnd);
+ virtual ~KviTaskBarItem();
+protected:
+ KviWindow * m_pWindow;
+ int m_iHighlightLevel;
+ int m_iProgress;
+public:
+ KviWindow * kviWindow(){ return m_pWindow; };
+ virtual void captionChanged(){};
+ virtual void highlight(int iLevel = 1){};
+ virtual void setProgress(int progress){};
+ virtual bool active(){ return false; };
+ virtual void unhighlight(){};
+ int progress(){ return m_iProgress; };
+ int highlightLevel(){ return m_iHighlightLevel; };
+};
+
+//
+// KviTaskBarBase
+//
+// The base class for the taskbar implementations
+// This is the basic interface that all the external classes should see
+//
+
+// Please note that Qt3 moc skips the *_SKIP_BEGIN -> *_SKIP_END blocks
+// while the Qt4 moc skips the Q_MOC_RUN ifdef block.. so...
+
+// Qt4 version
+
+// If you get failures (undefined references) in some non-autotools based
+// build system that uses Qt4 then you must add the -DCOMPILE_USE_QT4
+// commandline parameter to moc (at leat) when parsing this file.
+
+// MOC_SKIP_BEGIN
+#ifdef COMPILE_USE_QT4
+
+#include <QDockWidget>
+
+class KVIRC_API KviTaskBarBase : public QDockWidget
+{
+ Q_OBJECT
+#endif //COMPILE_USE_QT4
+// MOC_SKIP_END
+
+// Qt3 version
+#ifndef Q_MOC_RUN
+#ifndef COMPILE_USE_QT4
+
+#include "kvi_toolbar.h"
+
+class KVIRC_API KviTaskBarBase : public KviToolBar
+{
+ Q_OBJECT
+#endif
+#endif
+
+public:
+ KviTaskBarBase();
+ virtual ~KviTaskBarBase();
+protected:
+ KviFrame * m_pFrm;
+ QTimer * m_pActivityMeterTimer;
+public:
+ virtual KviTaskBarItem * addItem(KviWindow *){ return 0; };
+ virtual bool removeItem(KviTaskBarItem *){ return false; };
+ virtual void setActiveItem(KviTaskBarItem *){};
+ virtual KviTaskBarItem * firstItem(){ return 0; };
+ virtual KviTaskBarItem * lastItem(void) { return 0; }
+ virtual KviTaskBarItem * nextItem(){ return 0; };
+ virtual KviTaskBarItem * prevItem(void) { return 0; }
+ virtual KviTaskBarItem * item(int number);
+ virtual bool setIterationPointer(KviTaskBarItem * it){ return false; };
+ virtual void switchWindow(bool bNext,bool bInContextOnly);
+ virtual void updatePseudoTransparency(){};
+ virtual void applyOptions(){};
+ static void getTextForConsole(QString &szText,KviConsole * pConsole);
+protected slots:
+ virtual void updateActivityMeter();
+};
+
+//
+// Implementation details: the following classes should be
+// never used directly (with just the exception of KviFrame
+// that creates the taskbar)
+//
+
+class KviClassicTaskBar;
+
+class KVIRC_API KviTaskBarButton : public QPushButton , KviTaskBarItem
+{
+ friend class KviClassicTaskBar;
+ Q_OBJECT
+public:
+ KviTaskBarButton(QWidget * par,KviWindow * wnd,const char * name);
+ ~KviTaskBarButton();
+protected:
+ bool m_bActive;
+ KviDynamicToolTip * m_pTip;
+protected:
+ virtual void mousePressEvent(QMouseEvent *e);
+#if QT_VERSION >= 300
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+#endif
+ virtual void drawButtonLabel(QPainter *p);
+#ifdef COMPILE_USE_QT4
+ virtual void paintEvent(QPaintEvent * e);
+#endif
+public:
+ virtual bool active(){ return m_bActive; };
+ virtual void highlight(int iLevel = 1);
+ virtual void unhighlight();
+ virtual void setProgress(int progress);
+ virtual void captionChanged();
+protected:
+ void setActive(bool bActive);
+protected slots:
+ void tipRequest(KviDynamicToolTip *tip,const QPoint &pnt);
+};
+
+
+class KVIRC_API KviClassicTaskBar : public KviTaskBarBase
+{
+ Q_OBJECT
+public:
+ KviClassicTaskBar();
+ ~KviClassicTaskBar();
+protected:
+ KviPointerList<KviTaskBarButton> * m_pButtonList;
+ int m_iButtonHeight;
+ QWidget * m_pBase;
+protected:
+ void calcButtonHeight();
+ void doLayout(); // called by KviFrame to adjust a bug on WIndows
+ void insertButton(KviTaskBarButton * b);
+public:
+// virtual void fontChange(const QFont & old);
+ virtual void resizeEvent(QResizeEvent *e);
+public:
+ virtual KviTaskBarItem * addItem(KviWindow *);
+ virtual bool removeItem(KviTaskBarItem *);
+ virtual void setActiveItem(KviTaskBarItem *);
+ virtual KviTaskBarItem * firstItem();
+ virtual KviTaskBarItem * lastItem(void);
+ virtual KviTaskBarItem * nextItem();
+ virtual KviTaskBarItem * prevItem(void);
+ virtual bool setIterationPointer(KviTaskBarItem * it);
+ virtual void updateActivityMeter();
+ virtual void applyOptions();
+protected slots:
+ void orientationChangedSlot(Qt::Orientation o);
+};
+
+class KviTreeTaskBar;
+class KviTreeTaskBarItemInternal;
+
+class KVIRC_API KviTreeTaskBarItem : public KviTalListViewItem , public KviTaskBarItem
+{
+ friend class KviTreeTaskBar;
+ friend class KviTreeTaskBarListView;
+ friend class KviTreeTaskBarItemInternal;
+public:
+ KviTreeTaskBarItem(KviTalListView * par,KviWindow * wnd);
+ KviTreeTaskBarItem(KviTreeTaskBarItem * par,KviWindow * wnd);
+ ~KviTreeTaskBarItem();
+protected:
+ int m_iStepNumber;
+ bool m_bIncreasing;
+ QTimer* m_pAnimTimer;
+ KviTreeTaskBarItemInternal *m_pInternal;
+ int m_iRedDiff;
+ int m_iGreenDiff;
+ int m_iBlueDiff;
+public:
+ virtual QString key(int column,bool) const;
+ virtual void paintCell(QPainter *p,const QColorGroup &cg,int column,int width,int alignment);
+#ifdef COMPILE_USE_QT4
+ virtual void paintBranches(QPainter *p,const QColorGroup &cg,int w,int y,int h);
+#else
+ virtual void paintBranches(QPainter *p,const QColorGroup &cg,int w,int y,int h,GUIStyle s);
+#endif
+ virtual void captionChanged();
+ virtual void highlight(int iLevel = 1);
+ virtual void unhighlight();
+ virtual void setProgress(int progress);
+ virtual bool active(){ return isSelected(); };
+ virtual void applyOptions();
+protected:
+ void setActive(bool bActive);
+ void mouseEnter();
+ void mouseLeave();
+ void timerShot();
+ int calculateColor(int col1,int col2);
+};
+
+class KviTreeTaskBarItemInternal : public QObject
+{
+ Q_OBJECT
+public:
+ KviTreeTaskBarItemInternal(KviTreeTaskBarItem* pItem):m_pItem(pItem) {};
+ ~KviTreeTaskBarItemInternal() {};
+protected:
+ KviTreeTaskBarItem* m_pItem;
+public slots:
+ void timerShot() { m_pItem->timerShot();};
+};
+
+class KVIRC_API KviTreeTaskBarListView : public KviTalListView
+{
+ friend class KviTreeTaskBarItem;
+ Q_OBJECT
+ KviTreeTaskBarItem* m_pPrevItem;
+public:
+ KviTreeTaskBarListView(QWidget * par);
+ ~KviTreeTaskBarListView();
+protected:
+ virtual void contentsMousePressEvent(QMouseEvent *e);
+ virtual void paintEmptyArea(QPainter * p,const QRect &rct);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void contentsMouseMoveEvent ( QMouseEvent * e );
+ virtual void leaveEvent(QEvent *);
+signals:
+ void leftMousePress(KviTalListViewItem * it);
+ void rightMousePress(KviTalListViewItem * it);
+public slots:
+ void sort();
+ void reverseSort();
+};
+
+
+class KVIRC_API KviTreeTaskBar : public KviTaskBarBase
+{
+ Q_OBJECT
+public:
+ KviTreeTaskBar();
+ ~KviTreeTaskBar();
+private:
+ KviTreeTaskBarListView * m_pListView;
+ KviTreeTaskBarItem * m_pCurrentItem;
+ KviDynamicToolTip * m_pToolTip;
+public:
+ virtual KviTaskBarItem * addItem(KviWindow *);
+ virtual bool removeItem(KviTaskBarItem *);
+ virtual void setActiveItem(KviTaskBarItem *);
+ virtual KviTaskBarItem * firstItem();
+ virtual KviTaskBarItem * nextItem(void);
+ virtual KviTaskBarItem * lastItem();
+ virtual KviTaskBarItem * prevItem(void);
+ virtual bool setIterationPointer(KviTaskBarItem * it);
+ virtual void updatePseudoTransparency();
+ virtual bool eventFilter(QObject * o,QEvent *e);
+ virtual void updateActivityMeter();
+ virtual void applyOptions();
+protected:
+ virtual void moveEvent(QMoveEvent *);
+protected slots:
+ void tipRequest(KviDynamicToolTip *tip,const QPoint &pnt);
+};
+
+
+#endif //_KVI_TASKBAR_H_
diff --git a/src/kvirc/ui/kvi_texticonwin.cpp b/src/kvirc/ui/kvi_texticonwin.cpp
new file mode 100644
index 0000000..bd48078
--- /dev/null
+++ b/src/kvirc/ui/kvi_texticonwin.cpp
@@ -0,0 +1,283 @@
+//=============================================================================
+//
+// File : kvi_texticonwin.cpp
+// Creation date : Fri May 17 2002 02:35:20 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_texticonwin.h"
+#include "kvi_texticonmanager.h"
+#include "kvi_app.h"
+#include "kvi_options.h"
+#include "kvi_input.h"
+#include "kvi_topicw.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_iconmanager.h"
+
+#include <qnamespace.h>
+#include <qlineedit.h>
+#include <ctype.h>
+#ifdef COMPILE_USE_QT4
+ #include <qevent.h>
+#endif
+
+KviTextIconWindow::KviTextIconWindow()
+#ifdef COMPILE_USE_QT4
+: KviTalIconView(0,Qt::Popup)
+#else
+: KviTalIconView(0,Qt::WType_Popup)
+#endif
+{
+ m_iTimerId = -1;
+ setGridX ( 40 );
+ setFixedSize(KVI_TEXTICON_WIN_WIDTH,KVI_TEXTICON_WIN_HEIGHT);
+ m_pOwner = 0;
+ fill();
+ connect(g_pTextIconManager,SIGNAL(changed()),this,SLOT(fill()));
+ connect(this,SIGNAL(doubleClicked( KviTalIconViewItem * )),this,SLOT(itemSelected(KviTalIconViewItem *)));
+ connect(this,SIGNAL(returnPressed ( KviTalIconViewItem * ) ),this,SLOT(itemSelected(KviTalIconViewItem *)));
+ m_bAltMode = false;
+ setWordWrapIconText(true);
+}
+
+KviTextIconWindow::~KviTextIconWindow()
+{
+ if(m_iTimerId != -1)
+ {
+ killTimer(m_iTimerId);
+ m_iTimerId = -1;
+ }
+// killTimers();
+// if(m_pOwner)m_pOwner->setFocus();
+}
+
+void KviTextIconWindow::fill()
+{
+ clear();
+ KviPointerHashTable<QString,KviTextIcon> * d = g_pTextIconManager->textIconDict();
+ KviPointerHashTableIterator<QString,KviTextIcon> it(*d);
+ while(KviTextIcon * i = it.current())
+ {
+ QPixmap *pix = i->pixmap();
+ if(pix)insertItem(new KviTalIconViewItem(this,it.currentKey(),*pix));
+ ++it;
+ }
+ sort();
+ setCurrentItem(0);
+}
+
+void KviTextIconWindow::popup(QWidget *owner,bool bAltMode)
+{
+ if(m_pOwner)disconnect(m_pOwner,SIGNAL(destroyed()),this,SLOT(ownerDead()));
+ m_pOwner = owner;
+ m_szTypedSeq = "";
+ m_bAltMode = bAltMode;
+ connect(m_pOwner,SIGNAL(destroyed()),this,SLOT(ownerDead()));
+ show();
+}
+
+bool KviTextIconWindow::findTypedSeq()
+{
+ int cnt = count();
+ int max = 0;
+ KviTalIconViewItem *mit = 0;
+ bool bFullMax = false;
+ KviTalIconViewItem *item;
+ for ( item = (KviTalIconViewItem *)firstItem(); item; item = (KviTalIconViewItem *)item->nextItem() )
+ {
+ QString szIt = item->text();
+ int j;
+ for(j=0;j<((int)(szIt.length()));j++)
+ {
+ if(szIt[j].lower() != m_szTypedSeq[j].lower())break;
+ }
+ if(j < max)
+ {
+ goto got_mit;
+ } else {
+ if(j >= max)
+ {
+ bFullMax = (j == ((int)(szIt.length())));
+ max = j;
+ mit = item;
+ }
+ }
+ }
+got_mit:
+ setCurrentItem(mit);
+ m_szCurFullSeq = mit->text();
+ return bFullMax;
+}
+
+void KviTextIconWindow::keyPressEvent(QKeyEvent *e)
+{
+ switch(e->key())
+ {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Return:
+ KviTalIconView::keyPressEvent(e);
+ return;
+ break;
+ case Qt::Key_Escape:
+ doHide();
+ return;
+ break;
+ case Qt::Key_Backspace:
+ if(!m_szTypedSeq.isEmpty())
+ {
+ m_szTypedSeq.remove(m_szTypedSeq.length() - 1,1);
+ findTypedSeq();
+ } else {
+ doHide();
+ if(m_pOwner)g_pApp->sendEvent(m_pOwner,e);
+ }
+ return;
+ break;
+ case Qt::Key_Space:
+ doHide();
+ if(findTypedSeq())
+ {
+ QString szItem = m_szTypedSeq;
+ szItem.append(' ');
+ if(m_pOwner)
+ {
+ if(m_pOwner->inherits("KviInputEditor"))
+ ((KviInputEditor *)m_pOwner)->insertText(szItem);
+ else if(m_pOwner->inherits("KviInput"))
+ ((KviInput *)m_pOwner)->insertText(szItem);
+ else if(m_pOwner->inherits("QLineEdit"))
+ {
+ QString tmp = ((QLineEdit *)m_pOwner)->text();
+ tmp.insert(((QLineEdit *)m_pOwner)->cursorPosition(),szItem);
+ ((QLineEdit *)m_pOwner)->setText(tmp);
+ ((QLineEdit *)m_pOwner)->setCursorPosition(((QLineEdit *)m_pOwner)->cursorPosition() + szItem.length());
+ }
+ }
+ } else {
+ if(m_pOwner)g_pApp->sendEvent(m_pOwner,e);
+ }
+ return;
+ break;
+ case Qt::Key_Tab:
+ doHide();
+ findTypedSeq();
+ QString szItem = m_szCurFullSeq;
+ szItem.append(' ');
+ if(m_bAltMode)szItem.prepend(KVI_TEXT_ICON);
+ if(m_pOwner->inherits("KviInputEditor"))
+ ((KviInputEditor *)m_pOwner)->insertText(szItem);
+ else if(m_pOwner->inherits("KviInput"))
+ ((KviInput *)m_pOwner)->insertText(szItem);
+ else if(m_pOwner->inherits("QLineEdit"))
+ {
+ QString tmp = ((QLineEdit *)m_pOwner)->text();
+ tmp.insert(((QLineEdit *)m_pOwner)->cursorPosition(),szItem);
+ ((QLineEdit *)m_pOwner)->setText(tmp);
+ ((QLineEdit *)m_pOwner)->setCursorPosition(((QLineEdit *)m_pOwner)->cursorPosition() + szItem.length());
+ }
+ return;
+ break;
+ }
+
+ int as = e->ascii();
+ if((as >= 'a' && as <= 'z') || (as >= 'A' && as <= 'Z') || (as >= '0' && as <= '9')
+ || (as == '?') || (as == '$') || (as == '.') || (as == ',') || (as == '!') || (as =='&'))
+ {
+ m_szTypedSeq.append((char)as);
+ findTypedSeq();
+ } else {
+ if(m_pOwner)g_pApp->sendEvent(m_pOwner,e);
+ }
+}
+
+void KviTextIconWindow::ownerDead()
+{
+ m_pOwner = 0;
+ doHide();
+}
+
+void KviTextIconWindow::show()
+{
+ m_iTimerId = startTimer(50000); //50 sec ...seems enough
+ QWidget::show();
+}
+
+void KviTextIconWindow::timerEvent(QTimerEvent *)
+{
+ doHide();
+}
+
+void KviTextIconWindow::doHide()
+{
+ if(m_iTimerId != -1)
+ {
+ killTimer(m_iTimerId);
+ m_iTimerId = -1;
+ }
+ hide();
+ if(m_pOwner)m_pOwner->setFocus();
+}
+
+void KviTextIconWindow::itemSelected(KviTalIconViewItem * item)
+{
+ if(item)
+ {
+// debug("%i %i %i %s",m_pOwner->inherits("KviInputEditor"),m_pOwner->inherits("KviInput"),m_pOwner->inherits("QLineEdit"),m_pOwner->className());
+ doHide();
+ QString szItem = item->text();
+ szItem.append(' ');
+ if(m_bAltMode)szItem.prepend(KVI_TEXT_ICON);
+ if(m_pOwner->inherits("KviInputEditor"))
+ ((KviInputEditor *)m_pOwner)->insertText(szItem);
+ else if(m_pOwner->inherits("KviInput"))
+ ((KviInput *)m_pOwner)->insertText(szItem);
+ else if(m_pOwner->inherits("QLineEdit"))
+ {
+ QString tmp = ((QLineEdit *)m_pOwner)->text();
+ tmp.insert(((QLineEdit *)m_pOwner)->cursorPosition(),szItem);
+ ((QLineEdit *)m_pOwner)->setText(tmp);
+ ((QLineEdit *)m_pOwner)->setCursorPosition(((QLineEdit *)m_pOwner)->cursorPosition() + szItem.length());
+ }
+ }
+}
+
+void KviTextIconWindow::mousePressEvent(QMouseEvent *e)
+{
+ if(e->pos().x() < 0)goto hideme;
+ if(e->pos().x() > width())goto hideme;
+ if(e->pos().y() < 0)goto hideme;
+ if(e->pos().y() > height())goto hideme;
+
+ KviTalIconView::mousePressEvent(e);
+ return;
+
+hideme:
+ doHide();
+}
+
+
+#include "kvi_texticonwin.moc"
diff --git a/src/kvirc/ui/kvi_texticonwin.h b/src/kvirc/ui/kvi_texticonwin.h
new file mode 100644
index 0000000..76a4a60
--- /dev/null
+++ b/src/kvirc/ui/kvi_texticonwin.h
@@ -0,0 +1,64 @@
+#ifndef _KVI_TEXTICONWIN_H_
+#define _KVI_TEXTICONWIN_H_
+//=============================================================================
+//
+// File : kvi_texticonwin.h
+// Creation date : Fri May 17 2002 02:33:45 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_string.h"
+
+#include "kvi_tal_iconview.h"
+
+
+#define KVI_TEXTICON_WIN_WIDTH 230
+#define KVI_TEXTICON_WIN_HEIGHT 200
+
+class KVIRC_API KviTextIconWindow : public KviTalIconView
+{
+ Q_OBJECT
+public:
+ KviTextIconWindow();
+ ~KviTextIconWindow();
+private:
+ QWidget * m_pOwner;
+ QString m_szTypedSeq;
+ QString m_szCurFullSeq;
+ bool m_bAltMode; // in alt mode the itemSelected() string contains
+ // also the CTRL+I escape code
+ int m_iTimerId;
+public:
+ void popup(QWidget *owner,bool bAltMode = false);
+private:
+ void doHide();
+ virtual void show();
+ bool findTypedSeq(); // returns true if it is a complete word
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void timerEvent(QTimerEvent *);
+public slots:
+ void fill();
+ void ownerDead();
+ void itemSelected(KviTalIconViewItem * item);
+};
+
+#endif //_KVI_TEXTICONWIN_H_
diff --git a/src/kvirc/ui/kvi_themedlabel.cpp b/src/kvirc/ui/kvi_themedlabel.cpp
new file mode 100644
index 0000000..f9cf8e3
--- /dev/null
+++ b/src/kvirc/ui/kvi_themedlabel.cpp
@@ -0,0 +1,154 @@
+//
+// File : kvi_themedlabel.cpp
+// Creation date : Tue Aug 29 2000 21:17:01 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVIRC__
+#include "kvi_themedlabel.h"
+
+#include "kvi_options.h"
+#include "kvi_settings.h"
+#include "kvi_app.h"
+#include "kvi_window.h"
+#include <qpainter.h>
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+#endif
+
+KviThemedLabel::KviThemedLabel(QWidget * par,const char * name)
+: QFrame(par,name)
+{
+ setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ applyOptions();
+ m_bAutoHeight=0;
+}
+
+KviThemedLabel::~KviThemedLabel()
+{
+}
+
+/*QSize KviThemedLabel::sizeHint()
+{
+ QSize size=QFrame::sizeHint();
+ int iHeight=fontMetrics().height()*QStringList::split('\n',m_szText).count()+4;
+ size.setHeight(iHeight);
+ return size;
+}*/
+
+void KviThemedLabel::setText(const char * text)
+{
+ m_szText = QString(text);
+ if(m_bAutoHeight)
+ {
+ int iHeight=fontMetrics().height()*QStringList::split('\n',m_szText).count()+4;
+ setMinimumHeight(iHeight);
+ //g_pApp->postEvent(parent(),new QEvent(QEvent::Resize));
+ }
+ update();
+}
+
+void KviThemedLabel::setText(const QString& text)
+{
+ m_szText = text;
+ if(m_bAutoHeight)
+ {
+ int iHeight=fontMetrics().height()*QStringList::split('\n',m_szText).count()+4;
+ setMinimumHeight(iHeight);
+ //g_pApp->postEvent(parent(),new QEvent(QEvent::Resize));
+ }
+ update();
+}
+
+void KviThemedLabel::applyOptions()
+{
+ setFont(KVI_OPTION_FONT(KviOption_fontLabel));
+ update();
+}
+
+#ifdef COMPILE_USE_QT4
+void KviThemedLabel::paintEvent ( QPaintEvent * event )
+{
+ QFrame::paintEvent(event);
+ QPainter p(this);
+ SET_ANTI_ALIASING(p);
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = mapToGlobal(contentsRect().topLeft());
+ p.drawTiledPixmap(contentsRect(),*g_pShadedChildGlobalDesktopBackground,pnt);
+ } else {
+#endif
+
+ if(KVI_OPTION_PIXMAP(KviOption_pixmapLabelBackground).pixmap())
+ {
+ p.drawTiledPixmap(contentsRect(),*(KVI_OPTION_PIXMAP(KviOption_pixmapLabelBackground).pixmap()));
+ } else {
+ p.fillRect(contentsRect(),KVI_OPTION_COLOR(KviOption_colorLabelBackground));
+ }
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+
+ QRect r = contentsRect();
+ r.setLeft(r.left() + 2); // some margin
+
+ p.setPen(KVI_OPTION_COLOR(KviOption_colorLabelForeground));
+
+ p.drawText(r,Qt::AlignLeft | Qt::AlignVCenter,m_szText);
+}
+#else
+void KviThemedLabel::drawContents(QPainter *p)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = mapToGlobal(contentsRect().topLeft());
+ p->drawTiledPixmap(contentsRect(),*g_pShadedChildGlobalDesktopBackground,pnt);
+ } else {
+#endif
+
+ if(KVI_OPTION_PIXMAP(KviOption_pixmapLabelBackground).pixmap())
+ {
+ p->drawTiledPixmap(contentsRect(),*(KVI_OPTION_PIXMAP(KviOption_pixmapLabelBackground).pixmap()));
+ } else {
+ p->fillRect(contentsRect(),KVI_OPTION_COLOR(KviOption_colorLabelBackground));
+ }
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+
+ QRect r = contentsRect();
+ r.setLeft(r.left() + 2); // some margin
+
+ p->setPen(KVI_OPTION_COLOR(KviOption_colorLabelForeground));
+
+ p->drawText(r,Qt::AlignLeft | Qt::AlignVCenter,m_szText);
+}
+#endif
+
+void KviThemedLabel::mouseDoubleClickEvent(QMouseEvent *)
+{
+ emit doubleClicked();
+}
+
+
+#include "kvi_themedlabel.moc"
diff --git a/src/kvirc/ui/kvi_themedlabel.h b/src/kvirc/ui/kvi_themedlabel.h
new file mode 100644
index 0000000..b63e238
--- /dev/null
+++ b/src/kvirc/ui/kvi_themedlabel.h
@@ -0,0 +1,62 @@
+#ifndef _KVI_THEMEDLABEL_H_
+#define _KVI_THEMEDLABEL_H_
+
+//
+// File : kvi_themedlabel.h
+// Creation date : Tue Aug 29 2000 21:12:12 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#include "kvi_settings.h"
+
+#include <qframe.h>
+
+#include "kvi_string.h"
+
+class KVIRC_API KviThemedLabel : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(int TransparencyCapable READ dummyRead)
+public:
+ KviThemedLabel(QWidget * par,const char * name);
+ ~KviThemedLabel();
+private:
+ QString m_szText;
+ bool m_bAutoHeight;
+protected:
+#ifdef COMPILE_USE_QT4
+ virtual void paintEvent ( QPaintEvent * event );
+#else
+ virtual void drawContents(QPainter *p);
+#endif
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+public:
+ int dummyRead() const { return 0; };
+ void setText(const char * text);
+ void setText(const QString& text);
+ QString text() { return m_szText; };
+ void setAutoHeight(bool value) { m_bAutoHeight=value; };
+ void applyOptions();
+
+// QSize sizeHint();
+signals:
+ void doubleClicked();
+};
+
+#endif //_KVI_THEMEDLABEL_H_
diff --git a/src/kvirc/ui/kvi_toolbar.cpp b/src/kvirc/ui/kvi_toolbar.cpp
new file mode 100644
index 0000000..792f9fc
--- /dev/null
+++ b/src/kvirc/ui/kvi_toolbar.cpp
@@ -0,0 +1,160 @@
+//=============================================================================
+//
+// File : kvi_toolbar.cpp
+// Creation date : Tue Sep 17 02:00:17 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_toolbar.h"
+#include "kvi_frame.h"
+#include "kvi_locale.h"
+#include "kvi_app.h"
+
+#include <qcursor.h>
+#include "kvi_tal_popupmenu.h"
+
+#ifdef COMPILE_USE_QT4
+ #include <qevent.h>
+#endif
+
+static KviTalPopupMenu * g_pToolBarContextPopup = 0;
+static KviTalPopupMenu * g_pToolBarWindowsPopup = 0;
+static KviTalPopupMenu * g_pToolBarIconSizesPopup = 0;
+static KviTalPopupMenu * g_pToolBarPositionsPopup = 0;
+
+
+KviToolBar::KviToolBar(const QString &label,QT_TOOLBARDOCK_TYPE dock,bool bNewLine,const char * nam)
+: KviTalToolBar(label,g_pFrame,dock,bNewLine,nam)
+{
+}
+
+KviToolBar::~KviToolBar()
+{
+ if(g_pToolBarContextPopup)delete g_pToolBarContextPopup;
+ if(g_pToolBarIconSizesPopup)delete g_pToolBarIconSizesPopup;
+ if(g_pToolBarPositionsPopup)delete g_pToolBarPositionsPopup;
+ if(g_pToolBarWindowsPopup)delete g_pToolBarWindowsPopup;
+
+ g_pToolBarContextPopup = 0;
+ g_pToolBarIconSizesPopup = 0;
+ g_pToolBarPositionsPopup = 0;
+ g_pToolBarWindowsPopup = 0;
+}
+
+void KviToolBar::mousePressEvent(QMouseEvent *e)
+{
+ if(!(e->button() & Qt::RightButton))
+ {
+ KviTalToolBar::mousePressEvent(e);
+ return;
+ }
+
+ if(!g_pToolBarContextPopup)g_pToolBarContextPopup = new KviTalPopupMenu();
+ if(!g_pToolBarIconSizesPopup)g_pToolBarIconSizesPopup = new KviTalPopupMenu();
+ if(!g_pToolBarPositionsPopup)g_pToolBarPositionsPopup = new KviTalPopupMenu();
+ if(!g_pToolBarWindowsPopup)g_pToolBarWindowsPopup = new KviTalPopupMenu();
+
+ g_pToolBarContextPopup->clear();
+ g_pToolBarIconSizesPopup->clear();
+ g_pToolBarPositionsPopup->clear();
+ g_pToolBarWindowsPopup->clear();
+
+ g_pFrame->fillToolBarsPopup(g_pToolBarWindowsPopup);
+ g_pToolBarContextPopup->insertItem(__tr2qs("Toolbars"),g_pToolBarWindowsPopup);
+
+ g_pToolBarContextPopup->insertItem(__tr2qs("Orientation"),g_pToolBarPositionsPopup);
+
+ g_pToolBarPositionsPopup->insertItem(__tr2qs("Top"),this,SLOT(moveToTop()));
+ g_pToolBarPositionsPopup->insertItem(__tr2qs("Left"),this,SLOT(moveToLeft()));
+ g_pToolBarPositionsPopup->insertItem(__tr2qs("Right"),this,SLOT(moveToRight()));
+ g_pToolBarPositionsPopup->insertItem(__tr2qs("Bottom"),this,SLOT(moveToBottom()));
+ g_pToolBarPositionsPopup->insertSeparator();
+ g_pToolBarPositionsPopup->insertItem(__tr2qs("Detached"),this,SLOT(moveToTornOff()));
+ g_pToolBarPositionsPopup->insertItem(__tr2qs("Flat"),this,SLOT(moveToMinimized()));
+
+ g_pToolBarContextPopup->insertItem(__tr2qs("Icon Size"),g_pToolBarIconSizesPopup);
+
+ g_pToolBarIconSizesPopup->insertItem(__tr2qs("Small (22x22)"),this,SLOT(setSmallIcons()));
+ g_pToolBarIconSizesPopup->insertItem(__tr2qs("Large (32x32)"),this,SLOT(setBigIcons()));
+
+ g_pToolBarContextPopup->popup(QCursor::pos());
+}
+
+void KviToolBar::moveTo(QT_TOOLBARDOCK_TYPE dock)
+{
+ // FIXME: this should be hidden in Tal
+#ifdef COMPILE_USE_QT4
+ g_pFrame->removeToolBar(this);
+ g_pFrame->addToolBar(dock,this);
+#else //!COMPILE_USE_QT4
+#if QT_VERSION >= 300
+ g_pFrame->moveDockWindow(this,dock);
+#else
+ g_pFrame->moveToolBar(this,dock);
+#endif
+#endif //!COMPILE_USE_QT4
+}
+
+void KviToolBar::moveToTop()
+{
+ moveTo(QT_DOCK_TOP);
+}
+
+void KviToolBar::moveToLeft()
+{
+ moveTo(QT_DOCK_LEFT);
+}
+
+void KviToolBar::moveToRight()
+{
+ moveTo(QT_DOCK_RIGHT);
+}
+
+void KviToolBar::moveToBottom()
+{
+ moveTo(QT_DOCK_BOTTOM);
+}
+
+void KviToolBar::moveToMinimized()
+{
+ moveTo(QT_DOCK_MINIMIZED);
+}
+
+void KviToolBar::moveToTornOff()
+{
+ moveTo(QT_DOCK_TORNOFF);
+}
+
+void KviToolBar::setBigIcons()
+{
+ g_pFrame->setUsesBigPixmaps(true);
+}
+
+void KviToolBar::setSmallIcons()
+{
+ g_pFrame->setUsesBigPixmaps(false);
+}
+
+
+
+
+#include "kvi_toolbar.moc"
diff --git a/src/kvirc/ui/kvi_toolbar.h b/src/kvirc/ui/kvi_toolbar.h
new file mode 100644
index 0000000..a0e0511
--- /dev/null
+++ b/src/kvirc/ui/kvi_toolbar.h
@@ -0,0 +1,52 @@
+#ifndef _KVI_TOOLBAR_H_
+#define _KVI_TOOLBAR_H_
+//=============================================================================
+//
+// File : kvi_toolbar.h
+// Creation date : Tue Sep 17 02:00:16 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_tal_toolbar.h"
+
+class KviFrame;
+
+class KVIRC_API KviToolBar : public KviTalToolBar
+{
+ Q_OBJECT
+public:
+ KviToolBar(const QString &label,QT_TOOLBARDOCK_TYPE dock = QT_DOCK_TOP,bool bNewLine = false,const char * nam = 0);
+ ~KviToolBar();
+protected:
+ virtual void mousePressEvent(QMouseEvent *e);
+ void moveTo(QT_TOOLBARDOCK_TYPE dock);
+public slots:
+ void moveToTop();
+ void moveToLeft();
+ void moveToRight();
+ void moveToBottom();
+ void moveToMinimized();
+ void moveToTornOff();
+ void setBigIcons();
+ void setSmallIcons();
+};
+
+
+#endif //_KVI_TOOLBAR_H_
diff --git a/src/kvirc/ui/kvi_toolwindows_container.cpp b/src/kvirc/ui/kvi_toolwindows_container.cpp
new file mode 100644
index 0000000..270a706
--- /dev/null
+++ b/src/kvirc/ui/kvi_toolwindows_container.cpp
@@ -0,0 +1,140 @@
+#define __KVIRC__
+
+
+#include <qlayout.h>
+#include <qtoolbutton.h>
+#include <qobjectcleanuphandler.h>
+#include <qpushbutton.h>
+#include "kvi_tal_vbox.h"
+#include <qpainter.h>
+#include <qapplication.h>
+
+#include "kvi_toolwindows_container.h"
+#include "kvi_iconmanager.h"
+
+
+KviWindowToolWidget::KviWindowToolWidget(QWidget * parent, KviWindowToolPageButton* button/*, const char * name, WFlags f*/ )
+:QWidget(parent/*,name,f*/)
+{
+// m_pContainer=parent;
+ m_pButton=button;
+ m_bAutoDelete=1;
+ m_bHidden=0;
+ if(m_pButton) m_pButton->setOn(!isHidden());
+// m_ObjectHandler.add(button);
+// setMinimumWidth(0);
+}
+
+KviWindowToolWidget::~KviWindowToolWidget()
+{
+// unregisterSelf();
+// m_ObjectHandler.remove(m_pButton);
+
+}
+
+void KviWindowToolWidget::registerSelf()
+{
+/* m_pContainer->registerWidget(this);
+ if(!m_ObjectHandler.isEmpty())
+ {
+ if(m_pButton)
+ m_pButton->setOn(true);
+ } else {
+ m_pButton=0;
+ }*/
+}
+
+void KviWindowToolWidget::unregisterSelf()
+{
+/* if(!m_bHidden)
+ m_pContainer->unregisterWidget(this);
+ if(!m_ObjectHandler.isEmpty())
+ {
+ if(m_pButton)
+ m_pButton->setOn(false);
+ } else {
+ m_pButton=0;
+ }*/
+}
+
+/*void KviWindowToolWidget::hide()
+{
+ if(m_bAutoDelete==0)
+ {
+ unregisterSelf();
+ m_bHidden=1;
+ }
+ QWidget::hide();
+}*/
+
+/*void KviWindowToolWidget::show()
+{
+ if(m_bHidden)
+ {
+ registerSelf();
+ }
+ QWidget::show();
+ m_bHidden=0;
+}*/
+
+KviWindowToolPageButton::KviWindowToolPageButton ( int pixon,int pixoff, const QString & text, QWidget * parent,bool bOn, const char * name )
+:TOOL_PAGE_PARENT(parent)
+{
+#ifdef COMPILE_USE_QT4
+ setFlat(true);
+ setObjectName("kvi_window_tool_button");
+ setIcon(QIcon(*(g_pIconManager->getSmallIcon(pixon))));
+#else
+ QIconSet is1;
+ is1.setPixmap(*(g_pIconManager->getSmallIcon(pixon)),QIconSet::Small,QIconSet::Normal,QIconSet::On);
+ is1.setPixmap(*(g_pIconManager->getSmallIcon(pixoff)),QIconSet::Small,QIconSet::Normal,QIconSet::Off);
+ setIconSet(is1);
+ setUsesBigPixmap(false);
+#endif
+ setToggleButton(true);
+ setOn(bOn);
+
+// setSizePolicy(QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Ignored));
+}
+
+KviWindowToolPageButton::~KviWindowToolPageButton()
+{
+
+}
+
+/*void KviWindowToolPageButton::drawButton ( QPainter * p)
+{
+ QPixmap pixmap( height(), width() );
+ if(isOn())
+ pixmap.fill(colorGroup().mid());
+ else
+ pixmap.fill(colorGroup().button());
+ QPainter painter( &pixmap );
+
+ QPixmap icon;
+ if(isOn())
+ icon=iconSet()->pixmap(QIconSet::Small,QIconSet::Normal,QIconSet::On);
+ else
+ icon=iconSet()->pixmap(QIconSet::Small,QIconSet::Normal,QIconSet::Off);
+
+ // Draw the frame
+ //painter.setPen( colorGroup().mid() );
+ //if ( m_id != NUM_TABS - 1 ) painter.drawLine( 0, 0, 0, pixmap.height() - 1 );
+ //painter.drawLine( 0, pixmap.height() - 1, pixmap.width() - 1, pixmap.height() - 1 );
+
+ // Draw the text
+ QFont font;
+ QString str = text();
+ str.remove("&");
+ const int textX = pixmap.width() / 2 - QFontMetrics( font ).width( str ) / 2;
+ painter.setPen( colorGroup().buttonText() );
+ const QRect rect( textX + icon.width() / 2 + 2, 0, pixmap.width(), pixmap.height() );
+ painter.drawText( rect, Qt::AlignLeft | Qt::AlignVCenter, str );
+
+ // Draw the icon
+ painter.drawPixmap( textX - icon.width() / 2 - 2, pixmap.height() / 2 - icon.height() / 2, icon );
+
+ // Paint to widget
+ p->rotate( -90 );
+ p->drawPixmap( 1 - pixmap.width(), 0, pixmap );
+}*/
diff --git a/src/kvirc/ui/kvi_toolwindows_container.h b/src/kvirc/ui/kvi_toolwindows_container.h
new file mode 100644
index 0000000..ec131d9
--- /dev/null
+++ b/src/kvirc/ui/kvi_toolwindows_container.h
@@ -0,0 +1,65 @@
+#ifndef _KVI_TOOLWINDOWS_CONTAINER_H_
+#define _KVI_TOOLWINDOWS_CONTAINER_H_
+
+#include "kvi_tal_widgetstack.h"
+#include "kvi_tal_vbox.h"
+
+#include <qtoolbutton.h>
+#include <qobjectcleanuphandler.h>
+#include <qpushbutton.h>
+
+#include "kvi_heapobject.h"
+#include "kvi_styled_controls.h"
+
+class KviWindowToolWidget;
+class KviWindowToolPageButton;
+
+// FIXME: these classes are probably useless now... no ?
+
+// Pragma: KviWindowToolPageButton is actually used in kvi_window.h and others (need to fix the name and move
+// it to its own file.
+
+
+
+class KVIRC_API KviWindowToolWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ KviWindowToolWidget( QWidget * parent,KviWindowToolPageButton* button/*, const char * name = 0, WFlags f = 0 */);
+ ~KviWindowToolWidget();
+
+ void setAutoDelete(bool b) { m_bAutoDelete=b; };
+ bool autoDelete() { return m_bAutoDelete; };
+
+ virtual void registerSelf();
+ virtual void unregisterSelf();
+/*public slots:
+ virtual void hide ();
+ virtual void show ();*/
+protected:
+// KviToolWindowsContainer *m_pContainer;
+ KviWindowToolPageButton *m_pButton;
+ bool m_bAutoDelete;
+ bool m_bHidden;
+// QObjectCleanupHandler m_ObjectHandler;
+
+};
+
+#ifdef COMPILE_USE_QT4
+ #define TOOL_PAGE_PARENT QPushButton
+#else
+ #define TOOL_PAGE_PARENT KviStyledToolButton
+#endif
+
+
+class KVIRC_API KviWindowToolPageButton : public TOOL_PAGE_PARENT
+{
+ Q_OBJECT
+public:
+ KviWindowToolPageButton ( int pixon,int pixoff, const QString & text, QWidget * parent,bool bOn=0,const char * name = 0 );
+ ~KviWindowToolPageButton();
+/*protected:
+ virtual void drawButton ( QPainter * painter);*/
+};
+
+#endif //_KVI_TOOLWINDOWS_CONTAINER_H_
diff --git a/src/kvirc/ui/kvi_topicw.cpp b/src/kvirc/ui/kvi_topicw.cpp
new file mode 100644
index 0000000..bbcf0c5
--- /dev/null
+++ b/src/kvirc/ui/kvi_topicw.cpp
@@ -0,0 +1,834 @@
+//=============================================================================
+//
+// File : kvi_topicw.cpp
+// Creation date : Fri Aug 4 2000 12:09:21 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2005 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+
+#include "kvi_topicw.h"
+#include "kvi_options.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_locale.h"
+#include "kvi_defaults.h"
+#include "kvi_settings.h"
+#include "kvi_iconmanager.h"
+#include "kvi_texticonmanager.h"
+#include "kvi_app.h"
+#include "kvi_colorwin.h"
+#include "kvi_texticonwin.h"
+#include "kvi_window.h"
+#include "kvi_channel.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionserverinfo.h"
+#include "kvi_ircconnectionuserinfo.h"
+#include "kvi_mirccntrl.h"
+
+extern KviTextIconWindow * g_pTextIconWindow;
+extern KviColorWindow * g_pColorWindow;
+static int g_iInputFontCharWidth[256];
+
+#include <qpainter.h>
+#include <qfontmetrics.h>
+#include "kvi_tal_tooltip.h"
+#include <qlineedit.h>
+#include "kvi_tal_listbox.h"
+#include <qregexp.h>
+#include <qclipboard.h>
+#include "kvi_tal_popupmenu.h"
+#include <qevent.h>
+
+// FIXME: #warning "The combo should disappear when it looses focus!...(how to do it ?)"
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+
+#endif
+
+
+extern QStringList * g_pRecentTopicList;
+
+int KviListBoxTopicItem::width ( const KviTalListBox * lb ) const
+{
+ QFontMetrics fm(lb->font());
+ return fm.width(KviMircCntrl::stripControlBytes(text()));
+}
+
+void KviListBoxTopicItem::paint ( QPainter * p )
+{
+ KviTopicWidget::paintColoredText(p,text(),listBox()->colorGroup(),height(listBox()));
+}
+
+
+KviTopicWidget::KviTopicWidget(QWidget * par,const char * name)
+: QFrame(par,name)
+{
+ setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ setFont(KVI_OPTION_FONT(KviOption_fontLabel));
+ m_pHistory = 0;
+ m_pAccept = 0;
+ m_pDiscard = 0;
+ m_pContextPopup = 0;
+ m_iCursorPosition = 0;
+ m_pInput = 0;
+#ifdef COMPILE_USE_QT4
+ setAutoFillBackground(false);
+#else
+ setBackgroundMode(QWidget::NoBackground);
+#endif
+ reset();
+#ifdef COMPILE_USE_QT4
+ m_pCompletionBox=new KviTalListBox(this,Qt::Popup);
+#else
+ m_pCompletionBox=new KviTalListBox(this,Qt::WType_Popup);
+#endif
+ m_pCompletionBox->setFont( font() );
+ m_pCompletionBox->setPalette( palette() );
+// m_pCompletionBox->setVScrollBarMode( KviTalListBox::AlwaysOff );
+// m_pCompletionBox->setHScrollBarMode( KviTalListBox::AlwaysOff );
+ m_pCompletionBox->setFrameStyle( QFrame::Box | QFrame::Plain );
+ m_pCompletionBox->setLineWidth( 1 );
+ connect(m_pCompletionBox,SIGNAL(selected(int)),this,SLOT(complete(int)));
+ m_pCompletionBox->hide();
+}
+
+KviTopicWidget::~KviTopicWidget()
+{
+ delete m_pCompletionBox;
+}
+
+void KviTopicWidget::popDownListBox()
+{
+ m_pCompletionBox->removeEventFilter( this );
+ m_pCompletionBox->hide();
+}
+
+void KviTopicWidget::reset()
+{
+ KviTalToolTip::remove(this);
+ m_szTopic = __tr2qs("Unknown");
+ KviTalToolTip::add(this,__tr2qs("No topic message has been received from the server yet"));
+ m_szSetAt = "";
+ m_szSetBy = "";
+ update();
+}
+
+void KviTopicWidget::applyOptions()
+{
+// setFont(KVI_OPTION_FONT(KviOption_fontLabel));
+// if(m_pComboBox)m_pComboBox->setFont(KVI_OPTION_FONT(KviOption_fontLabel));
+ resizeEvent(0);
+}
+
+#define KVI_LABEL_DEF_BACK 100
+#define KVI_LABEL_DEF_FORE 101
+
+QString convertToHtml(const QString &text)
+{
+ QString result;
+ bool curBold = false;
+ bool curUnderline = false;
+ unsigned char curFore = KVI_LABEL_DEF_FORE; //default fore
+ unsigned char curBack = KVI_LABEL_DEF_BACK; //default back
+
+ unsigned int idx = 0;
+
+ while(idx < text.length())
+ {
+ unsigned short c = text[(int)idx].unicode();
+
+ unsigned int start = idx;
+
+ while(
+ (c != KVI_TEXT_COLOR) &&
+ (c != KVI_TEXT_BOLD) &&
+ (c != KVI_TEXT_UNDERLINE) &&
+ (c != KVI_TEXT_REVERSE) &&
+ (c != KVI_TEXT_RESET) &&
+ (c != KVI_TEXT_ICON)
+ )
+ {
+ idx++;
+ if(idx >= text.length())break;
+ else c = text[(int)idx].unicode();
+ }
+
+ int len = idx - start;
+
+ if(len > 0)
+ {
+ bool bOpened = FALSE;
+ QString szText = text.mid(start,len);
+
+ if(curBold) result.append("<b>");
+ if(curUnderline) result.append("<u>");
+
+ if(curFore != KVI_LABEL_DEF_FORE)
+ {
+ result.append("<font color=\"");
+ result.append(KVI_OPTION_MIRCCOLOR(curFore).name());
+ result.append('"');
+ bOpened = TRUE;
+ }
+
+/* if(curBack != KVI_LABEL_DEF_BACK)
+ {
+ if(!bOpened)
+ result.append("<font bgcolor=");
+ else
+ result.append(" bgcolor=");
+ result.append(KVI_OPTION_MIRCCOLOR(curBack).name());
+ }*/
+
+ if(bOpened) result.append(">");
+
+ result.append(text.mid(start,len));
+
+ if( (curFore != KVI_LABEL_DEF_FORE) /*|| (curBack != KVI_LABEL_DEF_BACK)*/ )
+ result.append("</font>");
+
+ if(curUnderline) result.append("</u>");
+ if(curBold) result.append("</b>");
+
+ }
+
+ switch(c)
+ {
+ case KVI_TEXT_BOLD: curBold = !curBold; ++idx; break;
+ case KVI_TEXT_UNDERLINE: curUnderline = !curUnderline; ++idx; break;
+ case KVI_TEXT_REVERSE:
+ {
+ char auxBack = curBack;
+ curBack = curFore;
+ curFore = auxBack;
+ }
+ ++idx;
+ break;
+ case KVI_TEXT_RESET:
+ curFore = KVI_LABEL_DEF_FORE;
+ curBack = KVI_LABEL_DEF_BACK;
+ curBold = false;
+ curUnderline = false;
+ ++idx;
+ break;
+ case KVI_TEXT_COLOR:
+ {
+ ++idx;
+ unsigned char fore;
+ unsigned char back;
+ idx = getUnicodeColorBytes(text,idx,&fore,&back);
+ if(fore != KVI_NOCHANGE)
+ {
+ curFore = fore;
+ if(back != KVI_NOCHANGE)curBack = back;
+ } else {
+ // only a CTRL+K
+ curBack = KVI_LABEL_DEF_BACK;
+ curFore = KVI_LABEL_DEF_FORE;
+ }
+ }
+ break;
+ case KVI_TEXT_ICON:
+ {
+ ++idx;
+
+ unsigned int icoStart = idx;
+ while((idx < text.length()) && (text[(int)idx].unicode() > 32))idx++;
+
+ KviStr lookupString = text.mid(icoStart,idx - icoStart);
+
+ KviTextIcon * icon = g_pTextIconManager->lookupTextIcon(lookupString.ptr());
+ if(icon)
+ {
+ //TODO: icons
+/* QPixmap * pigzmap = icon->pixmap();
+ p->drawPixmap(curX,(baseline + 2) - pigzmap->height(),*(pigzmap));
+ curX += pigzmap->width();*/
+ } else {
+ idx = icoStart;
+ }
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+void KviTopicWidget::paintColoredText(QPainter *p, QString text,const QColorGroup& cg,int height, int width)
+{
+ QFontMetrics fm(p->font());
+
+ if(height<0) height=p->window().height();
+ if(width<0) width=p->window().width();
+
+ bool curBold = false;
+ bool curUnderline = false;
+ unsigned char curFore = KVI_LABEL_DEF_FORE; //default fore
+ unsigned char curBack = KVI_LABEL_DEF_BACK; //default back
+ int baseline = ((height + fm.ascent() - fm.descent() + 1) >> 1);
+
+ int curX = p->window().x() + 2; //2 is the margin
+
+ unsigned int idx = 0;
+
+ while((idx < text.length()) && (curX < width))
+ {
+ unsigned short c = text[(int)idx].unicode();
+
+ unsigned int start = idx;
+
+ while((idx < text.length()) &&
+ (c != KVI_TEXT_COLOR) &&
+ (c != KVI_TEXT_BOLD) &&
+ (c != KVI_TEXT_UNDERLINE) &&
+ (c != KVI_TEXT_REVERSE) &&
+ (c != KVI_TEXT_RESET) &&
+ (c != KVI_TEXT_ICON)
+ )
+ {
+ idx++;
+ c = text[(int)idx].unicode();
+ }
+
+ int len = idx - start;
+ int wdth;
+
+ if(len > 0)
+ {
+ QString szText = text.mid(start,len);
+
+ wdth = fm.width(szText);
+
+ if(curFore == KVI_LABEL_DEF_FORE)
+ {
+ p->setPen(cg.text());
+ } else {
+ if(curFore > 16)p->setPen(cg.background());
+ else p->setPen(KVI_OPTION_MIRCCOLOR(curFore));
+ }
+
+ if(curBack != KVI_LABEL_DEF_BACK)
+ {
+ if(curBack > 16)
+ {
+ p->fillRect(curX,p->window().y() + 2,wdth,height - 4,
+ cg.text());
+ } else {
+ p->fillRect(curX,p->window().y() + 2,wdth,height - 4,
+ KVI_OPTION_MIRCCOLOR(curBack));
+ }
+ }
+
+ p->drawText(curX,baseline,szText,0,len);
+
+ if(curBold)p->drawText(curX+1,baseline,szText,0,len);
+ if(curUnderline)
+ {
+ p->drawLine(curX,baseline + 1,curX+wdth,baseline + 1);
+ }
+ } else {
+ wdth = 0;
+ }
+
+
+ curX += wdth;
+
+ switch(c)
+ {
+ case KVI_TEXT_BOLD: curBold = !curBold; ++idx; break;
+ case KVI_TEXT_UNDERLINE: curUnderline = !curUnderline; ++idx; break;
+ case KVI_TEXT_REVERSE:
+ {
+ char auxBack = curBack;
+ curBack = curFore;
+ curFore = auxBack;
+ }
+ ++idx;
+ break;
+ case KVI_TEXT_RESET:
+ curFore = KVI_LABEL_DEF_FORE;
+ curBack = KVI_LABEL_DEF_BACK;
+ curBold = false;
+ curUnderline = false;
+ ++idx;
+ break;
+ case KVI_TEXT_COLOR:
+ {
+ ++idx;
+ unsigned char fore;
+ unsigned char back;
+ idx = getUnicodeColorBytes(text,idx,&fore,&back);
+ if(fore != KVI_NOCHANGE)
+ {
+ curFore = fore;
+ if(back != KVI_NOCHANGE)curBack = back;
+ } else {
+ // only a CTRL+K
+ curBack = KVI_LABEL_DEF_BACK;
+ curFore = KVI_LABEL_DEF_FORE;
+ }
+ }
+ break;
+ case KVI_TEXT_ICON:
+ {
+ ++idx;
+
+ unsigned int icoStart = idx;
+ while((idx < text.length()) && (text[(int)idx].unicode() > 32))idx++;
+
+ KviStr lookupString = text.mid(icoStart,idx - icoStart);
+
+ KviTextIcon * icon = g_pTextIconManager->lookupTextIcon(lookupString.ptr());
+ if(icon)
+ {
+ QPixmap * pigzmap = icon->pixmap();
+ p->drawPixmap(curX,(baseline + 2) - pigzmap->height(),*(pigzmap));
+ curX += pigzmap->width();
+ } else {
+ idx = icoStart;
+ }
+ }
+ break;
+ }
+ }
+}
+
+#ifdef COMPILE_USE_QT4
+void KviTopicWidget::paintEvent(QPaintEvent * e)
+{
+ QPainter pa(this);
+ drawFrame(&pa);
+ drawContents(&pa);
+}
+#endif
+
+void KviTopicWidget::drawContents(QPainter *p)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = mapToGlobal(contentsRect().topLeft());
+ p->drawTiledPixmap(contentsRect(),*g_pShadedChildGlobalDesktopBackground,pnt);
+ } else {
+#endif
+ if(KVI_OPTION_PIXMAP(KviOption_pixmapLabelBackground).pixmap())
+ {
+ p->drawTiledPixmap(contentsRect(),*(KVI_OPTION_PIXMAP(KviOption_pixmapLabelBackground).pixmap()));
+ } else {
+ p->fillRect(contentsRect(),KVI_OPTION_COLOR(KviOption_colorLabelBackground));
+ }
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+ QColorGroup colorGroup;
+ //colorGroup()
+ colorGroup.setColor(QColorGroup::Text,KVI_OPTION_COLOR(KviOption_colorLabelForeground));
+ colorGroup.setColor(QColorGroup::Background,KVI_OPTION_COLOR(KviOption_colorLabelBackground));
+ paintColoredText(p,m_szTopic,colorGroup);
+}
+
+void KviTopicWidget::setTopic(const QString & topic)
+{
+ m_szTopic = topic;
+ bool bFound = false;
+ for(QStringList::Iterator it=g_pRecentTopicList->begin();it != g_pRecentTopicList->end(); ++it)
+ {
+ if(*it == m_szTopic)
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound && (!m_szTopic.isEmpty()))
+ {
+ if(g_pRecentTopicList->count() >= KVI_RECENT_TOPIC_ENTRIES)
+ {
+ g_pRecentTopicList->remove(g_pRecentTopicList->begin());
+ }
+ g_pRecentTopicList->append(m_szTopic);
+ }
+ updateToolTip();
+ update();
+}
+
+void KviTopicWidget::setTopicSetBy(const QString & setBy)
+{
+ m_szSetBy = setBy;
+ updateToolTip();
+}
+
+void KviTopicWidget::setTopicSetAt(const QString & setAt)
+{
+ m_szSetAt = setAt;
+ updateToolTip();
+}
+
+void KviTopicWidget::updateToolTip()
+{
+ KviTalToolTip::remove(this);
+
+ QString txt = "<html>" \
+ "<body>" \
+ "<table width=\"100%\">";
+
+ if(!m_szTopic.isEmpty())
+ {
+ txt += START_TABLE_BOLD_ROW;
+ txt += __tr2qs("Channel topic:");
+ txt += END_TABLE_BOLD_ROW;
+
+ txt += "<tr><td><center>";
+
+ QString tmp = m_szTopic;
+
+ tmp.replace('&',"&amp;");
+ tmp.replace('<',"&lt;");
+ tmp.replace('>',"&gt;");
+ tmp = convertToHtml(tmp);
+
+ txt += tmp;
+ txt += "</center></td></tr>";
+
+ if(!m_szSetBy.isEmpty())
+ {
+ txt += "<tr><td bgcolor=\"#D0D0D0\">";
+ txt += __tr2qs("Set by") + " <b>" + m_szSetBy + "</b>";
+ txt += "</td></tr>";
+
+ if(!m_szSetAt.isEmpty())
+ {
+ txt += "<tr><td bgcolor=\"#D0D0D0\">";
+ txt += __tr2qs("Set on") + " <b>" + m_szSetAt + "</b>";
+ txt += "</td></tr>";
+ }
+ }
+
+ txt += "<tr><td>";
+ txt += __tr2qs("Double-click to edit...");
+ txt += "</td></tr>";
+
+ } else {
+ txt += "<tr><td>";
+ txt += __tr2qs("No topic is set");
+ txt += "</td></tr>";
+ txt += "<tr><td>";
+ txt += __tr2qs("Double-click to set...");
+ txt += "</td></tr>";
+ }
+
+ txt += "</table>" \
+ "</body>" \
+ "<html>";
+
+ KviTalToolTip::add(this,txt);
+}
+
+QSize KviTopicWidget::sizeHint() const
+{
+ QFontMetrics fm(font());
+ int hght = fm.lineSpacing() + (frameWidth() << 1) + 4;
+ int baseline = ((hght + fm.ascent() - fm.descent() + 1) >> 1);
+ if(baseline < 16)hght += (16 - baseline);
+ return QSize(width(),hght);
+}
+
+void KviTopicWidget::mouseDoubleClickEvent(QMouseEvent *)
+{
+ int maxlen=-1;
+ QObject * w = parent();
+ QString szModes;
+ bool bCanEdit = TRUE;
+ while(w)
+ {
+ if(w->inherits("KviChannel"))
+ {
+ KviChannel *chan = ((KviChannel *)w);
+ maxlen=chan->connection()->serverInfo()->maxTopicLen();
+ chan->getChannelModeString(szModes);
+ if(szModes.contains('t') && !( chan->isMeHalfOp() || chan->isMeOp() || chan->isMeChanOwner() || chan->isMeChanAdmin() || chan->connection()->userInfo()->hasUserMode('o') || chan->connection()->userInfo()->hasUserMode('O')) ) {
+ bCanEdit=false;
+ }
+ break;
+ }
+ w = w->parent();
+ }
+ if(m_pInput == 0)
+ {
+ m_pInput=new KviInputEditor(this,0);
+ m_pInput->setReadOnly(!bCanEdit);
+ m_pInput->setMaxBufferSize(maxlen);
+ m_pInput->setGeometry(0,0,width() - (height() << 2)+height(),height());
+ m_pInput->setText(m_szTopic);
+ connect(m_pInput,SIGNAL(enterPressed()),this,SLOT(acceptClicked()));
+ connect(m_pInput,SIGNAL(escapePressed()),this,SLOT(discardClicked()));
+ m_pInput->installEventFilter(this);
+
+ m_pHistory = new QPushButton(this);
+ m_pHistory->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)));
+ m_pHistory->setGeometry(width() - (height() << 2)+height(),0,height(),height());
+ KviTalToolTip::add(m_pHistory,__tr2qs("History"));
+ m_pHistory->show();
+ connect(m_pHistory,SIGNAL(clicked()),this,SLOT(historyClicked()));
+
+ m_pAccept = new QPushButton(this);
+ m_pAccept->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ m_pAccept->setGeometry(width() - (height() << 1),0,height(),height());
+ m_pAccept->setEnabled(bCanEdit);
+ m_pAccept->show();
+ KviTalToolTip::add(m_pAccept,__tr2qs("Commit Changes"));
+ connect(m_pAccept,SIGNAL(clicked()),this,SLOT(acceptClicked()));
+
+ m_pDiscard = new QPushButton(this);
+ m_pDiscard->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ m_pDiscard->setGeometry(width() - height(),0,height(),height());
+ KviTalToolTip::add(m_pDiscard,__tr2qs("Discard Changes"));
+ m_pDiscard->show();
+ connect(m_pDiscard,SIGNAL(clicked()),this,SLOT(discardClicked()));
+
+ m_pInput->show();
+ m_pInput->setFocus();
+ }
+}
+
+void KviTopicWidget::mousePressEvent(QMouseEvent * e)
+{
+
+ if(!(e->button() & Qt::RightButton))return;
+ if(!m_pContextPopup)
+ {
+ m_pContextPopup = new KviTalPopupMenu(this);
+ connect(m_pContextPopup,SIGNAL(aboutToShow()),this,SLOT(contextPopupAboutToShow()));
+ }
+ m_pContextPopup->popup(mapToGlobal(e->pos()));
+}
+
+void KviTopicWidget::contextPopupAboutToShow()
+{
+ if(!m_pContextPopup)return; // hm ?
+ m_pContextPopup->clear();
+ m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_COPY)),__tr2qs("Copy to clipboard"),this,SLOT(copy()));
+}
+
+void KviTopicWidget::copy()
+{
+ QClipboard * c = QApplication::clipboard();
+ if(!c)return;
+ if(c->supportsSelection())c->setText(m_szTopic,QClipboard::Selection);
+ c->setText(m_szTopic,QClipboard::Clipboard);
+}
+
+bool KviTopicWidget::eventFilter(QObject *object,QEvent *e)
+{
+ if ( !e )
+ return TRUE;
+ if(object==m_pCompletionBox)
+ {
+ switch( e->type() ) {
+ case QEvent::MouseButtonPress:
+ if ( m_pCompletionBox->rect().contains( ((QMouseEvent*)e)->pos() ) ) {
+ complete(m_pCompletionBox->index(m_pCompletionBox->itemAt(((QMouseEvent*)e)->pos())));
+ return TRUE;
+ }
+ break;
+ case QEvent::MouseButtonRelease:
+ if ( m_pCompletionBox->rect().contains( ((QMouseEvent*)e)->pos() ) ) {
+ QMouseEvent tmp( QEvent::MouseButtonDblClick,
+ ((QMouseEvent*)e)->pos(), ((QMouseEvent*)e)->button(), ((QMouseEvent*)e)->state() ) ;
+ // will hide popup
+ QApplication::sendEvent( object, &tmp );
+ return TRUE;
+ } else {
+ if ( m_pCompletionBox->isVisible() )
+ popDownListBox();
+ }
+ break;
+ case QEvent::KeyPress:
+ switch( ((QKeyEvent *)e)->key() ) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ if ( !(((QKeyEvent *)e)->state() & Qt::AltButton) )
+ break;
+ case Qt::Key_F4:
+ case Qt::Key_Escape:
+ if ( m_pCompletionBox->isVisible() ) {
+ popDownListBox();
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case QEvent::Hide:
+ popDownListBox();
+ break;
+ default:
+ break;
+ }
+ }
+ return QFrame::eventFilter(object,e);
+}
+
+bool KviTopicWidget::handleKeyPressEvent(QKeyEvent * e)
+{
+ return 1;
+}
+
+void KviTopicWidget::keyPressEvent(QKeyEvent * e)
+{
+ if(handleKeyPressEvent(e))
+ {
+ e->accept();
+ return;
+ }
+}
+
+void KviTopicWidget::resizeEvent(QResizeEvent *e)
+{
+ if(e)QFrame::resizeEvent(e);
+ if(m_pInput)
+ {
+ m_pInput->setGeometry(0,0,width() - (height() << 2)+height(),height());
+ m_pHistory->setGeometry(width() - (height() << 2)+height(),0,height(),height());
+ m_pAccept->setGeometry(width() - (height() << 1),0,height(),height());
+ m_pDiscard->setGeometry(width() - height(),0,height(),height());
+ }
+}
+
+void KviTopicWidget::deactivate()
+{
+ popDownListBox();
+ if(m_pInput)
+ {
+ delete m_pInput;
+ m_pInput = 0;
+ delete m_pHistory;
+ m_pHistory = 0;
+ delete m_pAccept;
+ m_pAccept = 0;
+ delete m_pDiscard;
+ m_pDiscard = 0;
+ }
+
+ // try to find a KviWindow parent and give it the focus
+
+ QObject * w = parent();
+ while(w)
+ {
+ if(w->inherits("KviWindow"))
+ {
+ ((KviWindow *)w)->setFocus();
+ return;
+ }
+ w = w->parent();
+ }
+
+ // no KviWindow on the path
+ w = parent();
+ if(w)
+ {
+ if(w->inherits("QWidget"))
+ ((QWidget *)w)->setFocus();
+ }
+}
+
+void KviTopicWidget::discardClicked()
+{
+ deactivate();
+}
+
+void KviTopicWidget::historyClicked()
+{
+ if(g_pRecentTopicList)
+ {
+ m_pCompletionBox->installEventFilter( this );
+ m_pCompletionBox->clear();
+ for ( QStringList::Iterator it = g_pRecentTopicList->begin(); it != g_pRecentTopicList->end(); ++it ) {
+ KviListBoxTopicItem* item=new KviListBoxTopicItem(m_pCompletionBox,*it);
+ }
+ m_pCompletionBox->resize(m_pInput->width(),6*m_pCompletionBox->fontMetrics().height()+20);
+ QPoint point=m_pInput->mapToGlobal(QPoint(0,0));
+ point+=QPoint(0,m_pInput->height());
+ m_pCompletionBox->move(point);
+ m_pCompletionBox->show();
+ }
+}
+
+void KviTopicWidget::acceptClicked()
+{
+ if(!m_pInput->readOnly())
+ {
+ QString tmp = m_pInput->text();
+ if(tmp != m_szTopic)emit topicSelected(tmp);
+ }
+ deactivate();
+}
+
+void KviTopicWidget::insertChar(QChar c)
+{
+ insertText(QString(c));
+}
+
+void KviTopicWidget::insertText(const QString &c)
+{
+ if(m_pInput)
+ m_pInput->insertText(c);
+}
+
+int KviTopicWidget::xCursorPostionCalculation(int xInd)
+{
+ return 0;
+}
+void KviTopicWidget::complete(int pos)
+{
+ m_pInput->setText(m_pCompletionBox->text(pos));
+ popDownListBox();
+}
+
+QChar KviTopicWidget::getSubstituteChar(unsigned short control_code)
+{
+ switch(control_code)
+ {
+ case KVI_TEXT_COLOR:
+ return QChar('K');
+ break;
+ case KVI_TEXT_BOLD:
+ return QChar('B');
+ break;
+ case KVI_TEXT_RESET:
+ return QChar('O');
+ break;
+ case KVI_TEXT_REVERSE:
+ return QChar('R');
+ break;
+ case KVI_TEXT_UNDERLINE:
+ return QChar('U');
+ break;
+ case KVI_TEXT_ICON:
+ return QChar('I');
+ break;
+ default:
+ return QChar(control_code);
+ break;
+ }
+}
+
+#include "kvi_topicw.moc"
diff --git a/src/kvirc/ui/kvi_topicw.h b/src/kvirc/ui/kvi_topicw.h
new file mode 100644
index 0000000..b13088d
--- /dev/null
+++ b/src/kvirc/ui/kvi_topicw.h
@@ -0,0 +1,120 @@
+#ifndef _KVI_TOPICW_H_
+#define _KVI_TOPICW_H_
+
+//============================================================================
+//
+// File : kvi_topicw.h
+// Creation date : Fri Aug 4 2000 12:03:12 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//============================================================================
+
+#include "kvi_settings.h"
+
+#include <qframe.h>
+#include <qpushbutton.h>
+#include "kvi_tal_listbox.h"
+
+#include "kvi_string.h"
+#include "kvi_app.h"
+#include "kvi_input.h"
+
+class QComboBox;
+class KviChannel;
+class KviTalPopupMenu;
+class KviIrcConnection;
+class KviTalListBox;
+
+class KVIRC_API KviListBoxTopicItem : public KviTalListBoxText
+{
+public:
+ KviListBoxTopicItem( KviTalListBox * listbox = 0 , const QString & text = QString::null):KviTalListBoxText(listbox,text) { ; };
+ virtual int width ( const KviTalListBox * lb ) const;
+protected:
+ virtual void paint ( QPainter * p );
+
+};
+
+class KVIRC_API KviTopicWidget : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(int TransparencyCapable READ dummyRead)
+ friend class KviChannel;
+
+public:
+ KviTopicWidget(QWidget * par,const char * name);
+ ~KviTopicWidget();
+
+private:
+ QString m_szTopic;
+ QString m_szSetBy;
+ QString m_szSetAt;
+ QPushButton * m_pAccept;
+ QPushButton * m_pDiscard;
+ QPushButton * m_pHistory;
+ KviTalPopupMenu * m_pContextPopup;
+ QChar getSubstituteChar(unsigned short control_code);
+ int xCursorPostionCalculation(int xInd);
+ KviInputEditor* m_pInput;
+ KviTalListBox* m_pCompletionBox;
+protected:
+ int m_iCursorPosition;
+ virtual void drawContents(QPainter *p);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+#ifdef COMPILE_USE_QT4
+ virtual void paintEvent(QPaintEvent * e);
+#endif
+ void updateToolTip();
+ void deactivate();
+ void iconButtonClicked();
+ virtual bool eventFilter(QObject *o,QEvent *e);
+ bool handleKeyPressEvent(QKeyEvent * e);
+public:
+ void insertChar(QChar c);
+ void insertText(const QString &s);
+ int dummyRead() const { return 0; };
+ void reset();
+
+ void setTopic(const QString & szTopic);
+ void setTopicSetBy(const QString & setBy);
+ void setTopicSetAt(const QString & setAt);
+
+ const QString & topic(){ return m_szTopic; };
+ const QString & topicSetBy(){ return m_szSetBy; };
+ const QString & topicSetAt(){ return m_szSetAt; };
+ virtual QSize sizeHint() const;
+ void applyOptions();
+
+ static void paintColoredText(QPainter *p, QString text,const QColorGroup& cg, int h=-1, int w=-1);
+protected slots:
+ void acceptClicked();
+ void discardClicked();
+ void historyClicked();
+ void contextPopupAboutToShow();
+ void copy();
+ void complete(int);
+ void popDownListBox();
+signals:
+ void topicSelected(const QString &szTopic);
+};
+
+#endif //_KVI_TOPICW_H_
diff --git a/src/kvirc/ui/kvi_userlistview.cpp b/src/kvirc/ui/kvi_userlistview.cpp
new file mode 100644
index 0000000..20f75f0
--- /dev/null
+++ b/src/kvirc/ui/kvi_userlistview.cpp
@@ -0,0 +1,1972 @@
+//=============================================================================
+//
+// File : kvi_userlistview.cpp
+// Creation date : Tue Aug 1 2000 21:05:22 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#define _KVI_USERLISTVIEW_CPP_
+
+#include "kvi_debug.h"
+#include "kvi_userlistview.h"
+#include "kvi_settings.h"
+#include "kvi_locale.h"
+#include "kvi_options.h"
+#include "kvi_defaults.h"
+#include "kvi_iconmanager.h"
+#include "kvi_regusersdb.h"
+#include "kvi_parameterlist.h"
+#include "kvi_window.h"
+#include "kvi_console.h"
+#include "kvi_app.h"
+#include "kvi_useraction.h"
+#include "kvi_qstring.h"
+#include "kvi_frame.h"
+#include "kvi_mdimanager.h"
+#include "kvi_kvs_eventtriggers.h"
+#include "kvi_toolwindows_container.h"
+#include "kvi_doublebuffer.h"
+#include "kvi_stringconversion.h"
+#include "kvi_ircconnection.h"
+#include "kvi_ircconnectionserverinfo.h"
+
+#include <qlabel.h>
+#include <qscrollbar.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qfontmetrics.h>
+#include <qdatetime.h>
+#include <qmime.h>
+#include "kvi_styled_controls.h"
+#include <qevent.h>
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ extern QPixmap * g_pShadedChildGlobalDesktopBackground;
+#endif
+
+
+// kvi_app.cpp (loaded and destroyed by KviIconManager)
+extern QPixmap * g_pUserChanStatePixmap;
+
+// Yet another really complex widget :)
+
+#define KVI_USERLIST_BORDER_WIDTH 2
+
+// FIXME: #warning "Button to show/hide avatars"
+// FIXME: #warning "We want to be able to navigate the list with the keyboard!"
+
+KviUserListToolTip::KviUserListToolTip(KviUserListView * v,KviUserListViewArea * a)
+: KviTalToolTip(a)
+{
+ m_pListView = v;
+}
+
+KviUserListToolTip::~KviUserListToolTip()
+{
+}
+
+void KviUserListToolTip::maybeTip(const QPoint &pnt)
+{
+ m_pListView->maybeTip(this,pnt);
+}
+
+
+
+
+KviUserListEntry::KviUserListEntry(KviUserListView * parent,const QString &nick,
+ KviIrcUserEntry * e,short int iFlags,bool bJoinTimeUnknown)
+{
+ m_pListView = parent;
+ m_szNick = nick;
+ m_pGlobalData = e;
+ m_iFlags = iFlags;
+ m_lastActionTime = (kvi_time_t)0;
+ m_joinTime = bJoinTimeUnknown ? (kvi_time_t)0 : kvi_unixTime();
+ m_iTemperature = bJoinTimeUnknown ? 0 : KVI_USERACTION_JOIN;
+
+ m_bSelected = false;
+
+ recalcSize();
+}
+
+KviUserListEntry::~KviUserListEntry()
+{
+}
+
+bool KviUserListEntry::color(QColor& color)
+{
+ //
+ // FIXME: Unused ?
+ //
+ KviRegisteredUser* pRegisteredUser=m_pListView->m_pKviWindow->connection()->userDataBase()->registeredUser(m_szNick);
+ if(pRegisteredUser)
+ {
+ if(m_pListView->m_pKviWindow->connection()->userDataBase()->haveCustomColor(m_szNick))
+ {
+ color=*(m_pListView->m_pKviWindow->connection()->userDataBase()->customColor(m_szNick));
+ return true;
+ }
+ }
+ if(KVI_OPTION_BOOL(KviOption_boolUseDifferentColorForOwnNick) && m_pListView->m_pKviWindow->connection())
+ {
+ if(m_szNick==m_pListView->m_pKviWindow->connection()->currentNickName())
+ {
+ color = KVI_OPTION_COLOR(KviOption_colorUserListViewOwnForeground);
+ return true;
+ }
+ }
+ if(m_iFlags == 0)
+ {
+ color=KVI_OPTION_COLOR(KviOption_colorUserListViewNormalForeground);
+ return true;
+ } else {
+ color = KVI_OPTION_COLOR((m_iFlags & KVI_USERFLAG_CHANOWNER) ? \
+ KviOption_colorUserListViewChanOwnerForeground : ((m_iFlags & KVI_USERFLAG_CHANADMIN) ? \
+ KviOption_colorUserListViewChanAdminForeground : ((m_iFlags & KVI_USERFLAG_OP) ? \
+ KviOption_colorUserListViewOpForeground : ((m_iFlags & KVI_USERFLAG_HALFOP) ? \
+ KviOption_colorUserListViewHalfOpForeground : ((m_iFlags & KVI_USERFLAG_VOICE) ? \
+ KviOption_colorUserListViewVoiceForeground : KviOption_colorUserListViewUserOpForeground)))));
+ return true;
+ }
+ return true;
+}
+
+void KviUserListEntry::recalcSize()
+{
+ KviAvatar * av = m_pGlobalData->avatar();
+ m_iHeight = m_pListView->m_iFontHeight;
+ if(KVI_OPTION_BOOL(KviOption_boolShowUserChannelIcons) && (m_iHeight < 20))m_iHeight = 20;
+
+ if(!KVI_OPTION_BOOL(KviOption_boolDisableAvatars))//G&N 2005
+ {
+ if(av)
+ {
+ if( KVI_OPTION_BOOL(KviOption_boolScaleAvatars) &&
+ (
+ !KVI_OPTION_BOOL(KviOption_boolDoNotStretchAvatars) ||
+ (av->pixmap()->width() > KVI_OPTION_UINT(KviOption_uintAvatarScaleWidth)) ||
+ (av->pixmap()->height() > KVI_OPTION_UINT(KviOption_uintAvatarScaleHeight))
+ )
+ )
+ {
+ QPixmap * pix = av->scaledPixmap(KVI_OPTION_UINT(KviOption_uintAvatarScaleWidth), KVI_OPTION_UINT(KviOption_uintAvatarScaleHeight));
+
+ m_iHeight += pix->height();
+ }
+ else
+ {
+ m_iHeight += av->pixmap()->height();
+ }
+ }
+ }
+ m_iHeight += 3;
+}
+
+///////////////////////////////////////////////
+
+
+
+KviUserListView::KviUserListView(QWidget * parent,KviWindowToolPageButton* button,KviIrcUserDataBase * db,KviWindow * pWnd,int dictSize,const QString & label_text,const char * name)
+: KviWindowToolWidget(parent,button)
+{
+ setAutoDelete(0);
+ m_pKviWindow = pWnd;
+ m_pEntryDict = new KviPointerHashTable<QString,KviUserListEntry>(dictSize,false);
+ m_pEntryDict->setAutoDelete(true);
+
+ m_pUsersLabel = new QLabel(this,"userslabel");
+ KviTalToolTip::add(m_pUsersLabel,label_text);
+
+ m_pViewArea = new KviUserListViewArea(this);
+ m_pToolTip = new KviUserListToolTip(this,m_pViewArea);
+ m_pTopItem = 0;
+ m_pHeadItem = 0;
+ m_pTailItem = 0;
+ m_iOpCount = 0;
+ m_iHalfOpCount = 0;
+ m_iVoiceCount = 0;
+ m_iChanAdminCount = 0;
+ m_iChanOwnerCount = 0;
+ m_iUserOpCount = 0;
+ m_pIrcUserDataBase = db;
+ m_iTotalHeight = 0;
+ m_ibEntries = 0;
+ m_ieEntries = 0;
+ m_iIEntries = 0;
+ m_iSelectedCount = 0;
+// setBackgroundMode(QWidget::NoBackground);
+ applyOptions();
+ registerSelf();
+}
+
+KviUserListView::~KviUserListView()
+{
+ removeAllEntries();
+ delete m_pEntryDict;
+ delete m_pToolTip;
+}
+
+void KviUserListView::emitRightClick()
+{
+ int ev = -1;
+ switch(m_pKviWindow->type())
+ {
+ case KVI_WINDOW_TYPE_CHANNEL: ev = KviEvent_OnChannelNickPopupRequest; break;
+ case KVI_WINDOW_TYPE_QUERY: ev = KviEvent_OnQueryNickPopupRequest; break;
+ case KVI_WINDOW_TYPE_CONSOLE: ev = KviEvent_OnNotifyListPopupRequest; break;
+ default: ev = KviEvent_OnNickLinkPopupRequest; break; // this should actually never happen
+ }
+ if(ev > -1)
+ {
+ if(KviKvsEventManager::instance()->hasAppHandlers(ev))
+ {
+ QString nicks;
+ appendSelectedNicknames(nicks);
+ KviKvsVariantList vList;
+ vList.append(nicks);
+ KviKvsEventManager::instance()->trigger(ev,m_pKviWindow,&vList);
+ } else {
+ g_pApp->checkSuggestRestoreDefaultScript();
+ }
+ }
+}
+
+void KviUserListView::emitDoubleClick()
+{
+ int ev = -1;
+ switch(m_pKviWindow->type())
+ {
+ case KVI_WINDOW_TYPE_CHANNEL: ev = KviEvent_OnChannelNickDefaultActionRequest; break;
+ case KVI_WINDOW_TYPE_QUERY: ev = KviEvent_OnQueryNickDefaultActionRequest; break;
+ case KVI_WINDOW_TYPE_CONSOLE: ev = KviEvent_OnNotifyListDefaultActionRequest; break;
+ default: ev = KviEvent_OnNickLinkDefaultActionRequest; break; // this should actually never happen
+ }
+ if(ev > -1)
+ {
+ if(KviKvsEventManager::instance()->hasAppHandlers(ev))
+ {
+ QString nicks;
+ appendSelectedNicknames(nicks);
+ KviKvsVariantList vList;
+ vList.append(nicks);
+ KviKvsEventManager::instance()->trigger(ev,m_pKviWindow,&vList);
+ } else {
+ g_pApp->checkSuggestRestoreDefaultScript();
+ }
+ }
+}
+
+void KviUserListView::updateScrollBarRange()
+{
+ int max = m_iTotalHeight - (m_pViewArea->height() - (KVI_USERLIST_BORDER_WIDTH * 2));
+ m_pViewArea->m_pScrollBar->setRange(0,max > 0 ? max : 0);
+}
+
+void KviUserListView::applyOptions()
+{
+/* if(!KVI_OPTION_BOOL(KviOption_boolDisableUserListLabel)){
+ m_pUsersLabel->hide();
+ m_pViewArea->setGeometry(0,0,width(),height());
+ }
+ if(KVI_OPTION_BOOL(KviOption_boolDisableUserListLabel)){
+ m_pUsersLabel->show();
+ updateUsersLabel();
+ }*/
+ setFont(KVI_OPTION_FONT(KviOption_fontUserListView));
+ QFontMetrics fm(KVI_OPTION_FONT(KviOption_fontUserListView));
+ m_iFontHeight = fm.lineSpacing();
+ KviUserListEntry * e = m_pHeadItem;
+ m_iTotalHeight = 0;
+ while(e)
+ {
+ e->recalcSize();
+ m_iTotalHeight += e->m_iHeight;
+ e = e->m_pNext;
+ }
+ updateScrollBarRange();
+ m_pUsersLabel->setFont(KVI_OPTION_FONT(KviOption_fontUserListView));
+ setMinimumWidth(100);
+ resizeEvent(0); // this will call update() too
+ repaint();
+}
+void KviUserListView::updateArea()
+{
+ bool bEnable = m_pViewArea->isUpdatesEnabled();
+ if(!bEnable) m_pViewArea->setUpdatesEnabled(true);
+ triggerUpdate();
+ if(!bEnable) m_pViewArea->setUpdatesEnabled(false);
+}
+
+void KviUserListView::enableUpdates(bool bEnable)
+{
+ m_pViewArea->setUpdatesEnabled(bEnable);
+ if(bEnable)triggerUpdate();
+}
+
+void KviUserListView::setMaskEntries(char type, int num)
+{
+ switch (type)
+ {
+ case 'b':
+ m_ibEntries = num;
+ break;
+ case 'e':
+ m_ieEntries = num;
+ break;
+ case 'I':
+ m_iIEntries = num;
+ break;
+ }
+ updateUsersLabel();
+}
+
+void KviUserListView::completeNickBashLike(const QString &begin,KviPointerList<QString> *l,bool bAppendMask)
+{
+ KviUserListEntry * entry = m_pHeadItem;
+
+ while(entry)
+ {
+ if(KviQString::equalCIN(begin,entry->m_szNick,begin.length()))
+ {
+ if(bAppendMask)
+ {
+ QString * s = new QString();
+ KviQString::sprintf(*s,"%Q!%Q@%Q",&(entry->m_szNick),&(entry->m_pGlobalData->user()),&(entry->m_pGlobalData->host()));
+ l->append(s);
+ } else
+ l->append(new QString(entry->m_szNick));
+ }
+ entry = entry->m_pNext;
+ }
+}
+
+bool KviUserListView::completeNickStandard(const QString &begin,const QString &skipAfter,QString &buffer,bool bAppendMask)
+{
+ KviUserListEntry * entry = m_pHeadItem;
+
+ if(!skipAfter.isEmpty())
+ {
+ while(entry)
+ {
+ if(KviQString::equalCI(skipAfter,entry->m_szNick))
+ {
+ entry = entry->m_pNext;
+ break;
+ }
+ entry = entry->m_pNext;
+ }
+ }
+
+ // FIXME: completion should skip my own nick or place it as last entry in the chain (?)
+
+ // if(KviConsole * c = m_pKviWindow->console())
+ // {
+ // if(kvi_strEqualCI(entry->m_szNick.ptr(),c->currentNickName())
+ // }
+
+ // Ok...now the real completion
+ while(entry)
+ {
+ if(entry->m_szNick.length() >= begin.length())
+ {
+ int result = KviQString::cmpCIN(begin,entry->m_szNick,begin.length());
+ if(result == 0)
+ {
+ // This is ok.
+ buffer = entry->m_szNick;
+ if(bAppendMask)
+ {
+ buffer += entry->m_pGlobalData->user();
+ buffer += entry->m_pGlobalData->host();
+ }
+ return true;
+ } else if(result < 0)
+ {
+ // No match...begin is lower than the current entry
+ if(entry->m_iFlags == 0)return false;
+ else {
+ int flags = entry->m_iFlags;
+ // skip the current flag
+ while(entry)
+ {
+ if(entry->m_iFlags != flags)break;
+ entry = entry->m_pNext;
+ }
+ continue;
+ }
+ }
+ }
+ entry = entry->m_pNext;
+ }
+
+ return false;
+}
+
+
+void KviUserListView::insertUserEntry(const QString &nick,KviUserListEntry * e)
+{
+ // Complex insertion task :)
+
+ m_pEntryDict->insert(nick,e);
+ m_iTotalHeight += e->m_iHeight;
+
+ bool bGotTopItem = false;
+
+ int flag = 0;
+ if(e->m_iFlags != 0)
+ {
+ if(e->m_iFlags & KVI_USERFLAG_USEROP)
+ {
+ flag = KVI_USERFLAG_USEROP;
+ m_iUserOpCount++;
+ }
+ if(e->m_iFlags & KVI_USERFLAG_VOICE)
+ {
+ flag = KVI_USERFLAG_VOICE;
+ m_iVoiceCount++;
+ }
+ if(e->m_iFlags & KVI_USERFLAG_HALFOP)
+ {
+ flag = KVI_USERFLAG_HALFOP;
+ m_iHalfOpCount++;
+ }
+ if(e->m_iFlags & KVI_USERFLAG_OP)
+ {
+ flag = KVI_USERFLAG_OP;
+ m_iOpCount++;
+ }
+ if(e->m_iFlags & KVI_USERFLAG_CHANADMIN)
+ {
+ flag = KVI_USERFLAG_CHANADMIN;
+ m_iChanAdminCount++;
+ }
+ if(e->m_iFlags & KVI_USERFLAG_CHANOWNER)
+ {
+ flag = KVI_USERFLAG_CHANOWNER;
+ m_iChanOwnerCount++;
+ }
+ }
+
+
+ if(m_pHeadItem)
+ {
+ KviUserListEntry * entry = m_pHeadItem;
+
+ if(!(e->m_iFlags & KVI_USERFLAG_CHANOWNER))
+ {
+ // the new user is not a channel owner...
+ // skip the channel owners
+ while(entry && (entry->m_iFlags & KVI_USERFLAG_CHANOWNER))
+ {
+ if(entry == m_pTopItem)bGotTopItem = true;
+ entry = entry->m_pNext;
+ }
+
+ if(!(e->m_iFlags & KVI_USERFLAG_CHANADMIN))
+ {
+ // the new user is not a channel admin...
+ // skip chan admins
+ while(entry && (entry->m_iFlags & KVI_USERFLAG_CHANADMIN))
+ {
+ if(entry == m_pTopItem)bGotTopItem = true;
+ entry = entry->m_pNext;
+ }
+
+ // is operator ?
+ if(!(e->m_iFlags & KVI_USERFLAG_OP))
+ {
+ // the new user is not an op...
+ // skip ops
+ while(entry && (entry->m_iFlags & KVI_USERFLAG_OP))
+ {
+ if(entry == m_pTopItem)bGotTopItem = true;
+ entry = entry->m_pNext;
+ }
+
+ // is half oped ?
+ if(!(e->m_iFlags & KVI_USERFLAG_HALFOP))
+ {
+ // nope , skip halfops
+ while(entry && (entry->m_iFlags & KVI_USERFLAG_HALFOP))
+ {
+ if(entry == m_pTopItem)bGotTopItem = true;
+ entry = entry->m_pNext;
+ }
+
+ // is voiced ?
+ if(!(e->m_iFlags & KVI_USERFLAG_VOICE))
+ {
+ // nope , not voiced so skip voiced users
+ while(entry && (entry->m_iFlags & KVI_USERFLAG_VOICE))
+ {
+ if(entry == m_pTopItem)bGotTopItem = true;
+ entry = entry->m_pNext;
+ }
+
+ // is userop'd?
+ if(!(e->m_iFlags & KVI_USERFLAG_USEROP))
+ {
+ // nope , skip userops
+ while(entry && (entry->m_iFlags & KVI_USERFLAG_USEROP))
+ {
+ if(entry == m_pTopItem)bGotTopItem = true;
+ entry = entry->m_pNext;
+ }
+ } // else is userop, ops, halfops, and voiced are skipped
+ } // else it is voiced , ops and halfops are skipped
+ } // else it is halfop , ops are skipped
+ } // else it is op , chan admins are skipped
+ } // else it is chan admin , chan owners are skipped
+ } // else it is chan owner, so nothing to skip: the chan owners are first in the list
+
+ // now strcmp within the current user-flag group...
+ while(entry && (KviQString::cmpCI(entry->m_szNick,e->m_szNick) < 0) &&
+ ((entry->m_iFlags & flag) || (flag == 0)))
+ {
+ if(entry == m_pTopItem)bGotTopItem = true;
+ entry = entry->m_pNext;
+ }
+ if(entry)
+ {
+ // inserting
+ e->m_pNext = entry;
+ e->m_pPrev = entry->m_pPrev;
+ if(e->m_pPrev == 0)m_pHeadItem = e;
+ else e->m_pPrev->m_pNext = e;
+ entry->m_pPrev = e;
+ // need to adjust the item offsets now...
+ // ok... if we're inserting something after
+ // the top item, we move everything down
+ // otherwise we only update the scrollbar values
+ if(!bGotTopItem)
+ {
+ // Inserting BEFORE the top item
+ if((e == m_pHeadItem) && (m_pTopItem == e->m_pNext) && (m_pViewArea->m_iTopItemOffset == 0))
+ {
+ // special case...the top item is the head one
+ // and it has zero offset...change the top item too
+ m_pTopItem = e;
+ triggerUpdate();
+ } else {
+ // invisible insertion
+ m_pViewArea->m_bIgnoreScrollBar = true;
+ m_pViewArea->m_iLastScrollBarVal += e->m_iHeight;
+ updateScrollBarRange();
+ m_pViewArea->m_pScrollBar->setValue(m_pViewArea->m_iLastScrollBarVal);
+ m_pViewArea->m_bIgnoreScrollBar = false;
+ updateUsersLabel();
+ }
+ } else {
+ triggerUpdate();
+ }
+ } else {
+ // appending to the end (may be visible)
+ m_pTailItem->m_pNext = e;
+ e->m_pNext = 0;
+ e->m_pPrev = m_pTailItem;
+ m_pTailItem = e;
+ triggerUpdate();
+ }
+ } else {
+ // There were no items (is rather visible)
+ m_pHeadItem = e;
+ m_pTailItem = e;
+ m_pTopItem = e;
+ e->m_pNext = 0;
+ e->m_pPrev = 0;
+ triggerUpdate();
+ }
+ if(e->m_bSelected)
+ {
+ m_iSelectedCount++;
+ if(m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pKviWindow,true);
+ }
+}
+
+KviUserListEntry * KviUserListView::join(const QString &nick,const QString &user,
+ const QString &host,int iFlags)
+{
+ // Ok..an user joins the channel
+ KviUserListEntry * it = m_pEntryDict->find(nick);
+ if(it == 0)
+ {
+ // add an entry to the global dict
+ KviIrcUserEntry * pGlobalData = m_pIrcUserDataBase->insertUser(nick,user,host);
+ // calculate the flags and update the counters
+ it = new KviUserListEntry(this,nick,pGlobalData,iFlags,(user == QString::null));
+ insertUserEntry(nick,it);
+ } else {
+// if(!host.isEmpty()) - it can be UHNAMES with host or NAMEX(X) w/o it
+// {
+ // Ok...the user was already on...
+ // Probably this is a NAMES(X) reply , and the user IS_ME
+ // (already joined after the JOIN message)
+ if(iFlags != it->m_iFlags)
+ {
+//// FIXME: #warning "Maybe say to the channel that we're oped : and the op is guessed from the names reply"
+ if((iFlags & KVI_USERFLAG_CHANOWNER) != (it->m_iFlags & KVI_USERFLAG_CHANOWNER))setChanOwner(nick,iFlags & KVI_USERFLAG_CHANOWNER);
+ if((iFlags & KVI_USERFLAG_CHANADMIN) != (it->m_iFlags & KVI_USERFLAG_CHANADMIN))setChanAdmin(nick,iFlags & KVI_USERFLAG_CHANADMIN);
+ if((iFlags & KVI_USERFLAG_OP) != (it->m_iFlags & KVI_USERFLAG_OP))op(nick,iFlags & KVI_USERFLAG_OP);
+ if((iFlags & KVI_USERFLAG_HALFOP) != (it->m_iFlags & KVI_USERFLAG_HALFOP))halfop(nick,iFlags & KVI_USERFLAG_HALFOP);
+ if((iFlags & KVI_USERFLAG_VOICE) != (it->m_iFlags & KVI_USERFLAG_VOICE))voice(nick,iFlags & KVI_USERFLAG_VOICE);
+ if((iFlags & KVI_USERFLAG_USEROP) != (it->m_iFlags & KVI_USERFLAG_USEROP))userop(nick,iFlags & KVI_USERFLAG_USEROP);
+ }
+// }
+ }
+ return it;
+}
+
+void KviUserListView::triggerUpdate()
+{
+ // This stuff is useful on joins only
+ if(m_pViewArea->isUpdatesEnabled())
+ {
+ //m_pViewArea->m_pScrollBar->setRange(0,m_iTotalHeight);
+ updateScrollBarRange();
+ m_pViewArea->update();
+ updateUsersLabel();
+ }
+}
+
+bool KviUserListView::avatarChanged(const QString &nick)
+{
+ KviUserListEntry * it = m_pEntryDict->find(nick);
+ if(it)
+ {
+ int oldH = it->m_iHeight;
+ m_iTotalHeight -= it->m_iHeight;
+ it->recalcSize();
+ m_iTotalHeight += it->m_iHeight;
+ // if this was "over" the top item , we must adjust the scrollbar value
+ // otherwise scroll everything down
+ KviUserListEntry * e = m_pHeadItem;
+ bool bGotTopItem = false;
+ while(e != it)
+ {
+ if(e == m_pTopItem)
+ {
+ bGotTopItem = true;
+ e = it;
+ } else e = e->m_pNext;
+ }
+ if(!bGotTopItem && (m_pTopItem != it))
+ {
+ // we're "over" the top item , so over the
+ // upper side of the view...adjust the scroll bar value
+ int hDiff = it->m_iHeight - oldH;
+ m_pViewArea->m_iLastScrollBarVal += hDiff;
+ m_pViewArea->m_bIgnoreScrollBar = true;
+// m_pViewArea->m_pScrollBar->setRange(0,m_iTotalHeight);
+ updateScrollBarRange();
+ m_pViewArea->m_pScrollBar->setValue(m_pViewArea->m_iLastScrollBarVal);
+ m_pViewArea->m_bIgnoreScrollBar = false;
+ } else {
+ // the item may be visible!
+ // the scroll bar should take care of the case
+ // in that the current value runs out of the allowed
+ // range.... it should set the value to a good one
+ // and emit the signal
+ updateScrollBarRange();
+// m_pViewArea->m_pScrollBar->setRange(0,m_iTotalHeight);
+ m_pViewArea->update();
+ }
+ return true;
+ }
+ return false;
+}
+
+
+bool KviUserListView::userActionVerifyMask(const QString &nick,const QString &user,const QString &host,int actionTemperature,QString &oldUser,QString &oldHost)
+{
+ // This is called when an user "acts" in some visible way
+ // on the channel, so we can keep track of his channeel
+ // idle time.
+ // This particular function version of userAction
+ // will return false if there was a user or hostname
+ // change (unless they were not known at all)
+ // This will also update the username and hostname
+ // if needed.
+ KviUserListEntry * it = m_pEntryDict->find(QString(nick));
+ if(it)
+ {
+ it->m_lastActionTime = kvi_unixTime();
+ bool bChanged = false;
+ if(!(host.isEmpty() || (KviQString::equalCS(host,"*"))))
+ {
+ if(!KviQString::equalCI(it->m_pGlobalData->host(),host))
+ {
+ if(!(it->m_pGlobalData->host().isEmpty() || KviQString::equalCS(it->m_pGlobalData->host(),"*")))
+ {
+ oldHost = it->m_pGlobalData->host();
+ bChanged = true;
+ }
+ it->m_pGlobalData->setHost(host);
+ }
+ }
+ if(!(user.isEmpty() || (KviQString::equalCS(user,"*"))))
+ {
+ if(!KviQString::equalCI(it->m_pGlobalData->user(),user))
+ {
+ if(!(it->m_pGlobalData->user().isEmpty() || KviQString::equalCS(it->m_pGlobalData->user(),"*")))
+ {
+ oldUser = it->m_pGlobalData->user();
+ bChanged = true;
+ }
+ it->m_pGlobalData->setUser(user);
+ }
+ }
+ it->m_iTemperature += actionTemperature;
+ // Don't allow it to grow too much
+ if(it->m_iTemperature > 300)it->m_iTemperature = 300;
+ else if(it->m_iTemperature < -300)it->m_iTemperature = -300;
+ if(itemVisible(it))triggerUpdate();
+ return !bChanged;
+ }
+ return true; // no such nick so no change
+}
+
+
+void KviUserListView::userAction(const QString &nick,const QString &user,const QString &host,int actionTemperature)
+{
+ // This is called when an user "acts" in some visible way
+ // on the channel, so we can keep track of his channeel
+ // idle time. This will also update the username and hostname
+ // if needed.
+ KviUserListEntry * it = m_pEntryDict->find(QString(nick));
+ if(it)
+ {
+ it->m_lastActionTime = kvi_unixTime();
+ if(!(host.isEmpty() || (KviQString::equalCS(host,"*"))))
+ it->m_pGlobalData->setHost(host);
+ if(!(user.isEmpty() || (KviQString::equalCS(user,"*"))))
+ it->m_pGlobalData->setUser(user);
+ it->m_iTemperature += actionTemperature;
+ // Don't allow it to grow too much
+ if(it->m_iTemperature > 300)it->m_iTemperature = 300;
+ else if(it->m_iTemperature < -300)it->m_iTemperature = -300;
+ if(itemVisible(it))triggerUpdate();
+ }
+}
+
+
+void KviUserListView::userAction(KviIrcMask *user,int actionTemperature)
+{
+ // This is called when an user "acts" in some visible way
+ // on the channel, so we can keep track of his channeel
+ // idle time. This will also update the username and hostname
+ // if needed.
+ KviUserListEntry * it = m_pEntryDict->find(QString(user->nick()));
+ if(it)
+ {
+ it->m_lastActionTime = kvi_unixTime();
+ if(user->hasUser())it->m_pGlobalData->setUser(user->user());
+ if(user->hasHost())it->m_pGlobalData->setHost(user->host());
+ it->m_iTemperature += actionTemperature;
+ // Don't allow it to grow too much
+ if(it->m_iTemperature > 300)it->m_iTemperature = 300;
+ else if(it->m_iTemperature < -300)it->m_iTemperature = -300;
+ if(itemVisible(it))triggerUpdate();
+ }
+}
+
+void KviUserListView::userAction(const QString &nick,int actionTemperature)
+{
+ // This is called when an user "acts" in some visible way
+ // on the channel, so we can keep track of his channeel
+ // idle time. This will also update the username and hostname
+ // if needed.
+ KviUserListEntry * it = m_pEntryDict->find(nick);
+ if(it)
+ {
+ it->m_lastActionTime = kvi_unixTime();
+ it->m_iTemperature += actionTemperature;
+ if(it->m_iTemperature > 300)it->m_iTemperature = 300;
+ else if(it->m_iTemperature < -300)it->m_iTemperature = -300;
+ if(itemVisible(it))triggerUpdate();
+ }
+}
+
+kvi_time_t KviUserListView::getUserJoinTime(const QString &szNick)
+{
+ KviUserListEntry * e = m_pEntryDict->find(szNick);
+ if(!e)return (kvi_time_t)0;
+ return e->m_joinTime;
+}
+
+kvi_time_t KviUserListView::getUserLastActionTime(const QString &szNick)
+{
+ KviUserListEntry * e = m_pEntryDict->find(szNick);
+ if(!e)return (kvi_time_t)0;
+ return e->m_lastActionTime;
+}
+
+
+int KviUserListView::getUserModeLevel(const QString &szNick)
+{
+ KviUserListEntry * e = m_pEntryDict->find(szNick);
+ if(!e)return 0;
+ if(e->m_iFlags & KVI_USERFLAG_MODEMASK)
+ {
+ if(e->m_iFlags & KVI_USERFLAG_CHANOWNER)return 60;
+ if(e->m_iFlags & KVI_USERFLAG_CHANADMIN)return 50;
+ if(e->m_iFlags & KVI_USERFLAG_OP)return 40;
+ if(e->m_iFlags & KVI_USERFLAG_HALFOP)return 30;
+ if(e->m_iFlags & KVI_USERFLAG_VOICE)return 20;
+ if(e->m_iFlags & KVI_USERFLAG_USEROP)return 10;
+ }
+ return 0;
+}
+
+char KviUserListView::getUserFlag(KviUserListEntry * e)
+{
+ if(!e)return 0;
+ return (char)m_pKviWindow->connection()->serverInfo()->modePrefixChar(e->m_iFlags).unicode();
+}
+
+void KviUserListView::prependUserFlag(const QString &nick,QString &buffer)
+{
+ char uFlag = getUserFlag(nick);
+ if(uFlag)buffer.prepend(uFlag);
+}
+
+int KviUserListView::flags(const QString &nick)
+{
+ KviUserListEntry * it = m_pEntryDict->find(nick);
+ return it ? it->m_iFlags : 0;
+}
+
+#define SET_FLAG_FUNC(__funcname,__flag) \
+ bool KviUserListView::__funcname(const QString &nick,bool bYes) \
+ { \
+ KviUserListEntry * it = m_pEntryDict->find(nick); \
+ if(!it)return false; \
+ m_pEntryDict->setAutoDelete(false); \
+ partInternal(nick,false); \
+ m_pEntryDict->setAutoDelete(true); \
+ if(bYes) \
+ { \
+ if(!(it->m_iFlags & __flag))it->m_iFlags |= __flag; \
+ } else { \
+ if(it->m_iFlags & __flag)it->m_iFlags &= ~__flag; \
+ } \
+ updateScrollBarRange(); \
+ insertUserEntry(nick,it); \
+ m_pViewArea->update(); \
+ return true; \
+ }
+
+SET_FLAG_FUNC(setChanOwner,KVI_USERFLAG_CHANOWNER)
+SET_FLAG_FUNC(setChanAdmin,KVI_USERFLAG_CHANADMIN)
+SET_FLAG_FUNC(op,KVI_USERFLAG_OP)
+SET_FLAG_FUNC(halfop,KVI_USERFLAG_HALFOP)
+SET_FLAG_FUNC(userop,KVI_USERFLAG_USEROP)
+SET_FLAG_FUNC(voice,KVI_USERFLAG_VOICE)
+
+#define GET_FLAG_FUNC(__funcname,__flag) \
+ bool KviUserListView::__funcname(const QString &nick,bool bAtLeast) \
+ { \
+ KviUserListEntry * it = m_pEntryDict->find(nick); \
+ return it ? (bAtLeast ? (it->m_iFlags >= __flag) : (it->m_iFlags & __flag)) : false; \
+ }
+
+GET_FLAG_FUNC(isChanOwner,KVI_USERFLAG_CHANOWNER)
+GET_FLAG_FUNC(isChanAdmin,KVI_USERFLAG_CHANADMIN)
+GET_FLAG_FUNC(isOp,KVI_USERFLAG_OP)
+GET_FLAG_FUNC(isVoice,KVI_USERFLAG_VOICE)
+GET_FLAG_FUNC(isHalfOp,KVI_USERFLAG_HALFOP)
+GET_FLAG_FUNC(isUserOp,KVI_USERFLAG_USEROP)
+
+
+QString * KviUserListView::firstSelectedNickname()
+{
+ m_pIterator = m_pHeadItem;
+ while(m_pIterator)
+ {
+ if(m_pIterator->m_bSelected)
+ {
+ QString * s = &(m_pIterator->m_szNick);
+ m_pIterator = m_pIterator->m_pNext;
+ return s;
+ }
+ m_pIterator = m_pIterator->m_pNext;
+ }
+ return 0;
+}
+
+QString * KviUserListView::nextSelectedNickname()
+{
+ while(m_pIterator)
+ {
+ if(m_pIterator->m_bSelected)
+ {
+ QString * s = &(m_pIterator->m_szNick);
+ m_pIterator = m_pIterator->m_pNext;
+ return s;
+ }
+ m_pIterator = m_pIterator->m_pNext;
+ }
+ return 0;
+}
+
+void KviUserListView::appendSelectedNicknames(QString &buffer)
+{
+ KviUserListEntry * aux = m_pHeadItem;
+ bool bFirst = true;
+ while(aux)
+ {
+ if(aux->m_bSelected)
+ {
+ if(!bFirst)buffer.append(',');
+ else bFirst = false;
+ buffer.append(aux->m_szNick);
+ }
+ aux = aux->m_pNext;
+ }
+}
+
+void KviUserListView::select(const QString& nick){
+ KviPointerHashTableIterator<QString,KviUserListEntry> it(*m_pEntryDict);
+ while(it.current())
+ {
+ ((KviUserListEntry *)it.current())->m_bSelected = false;
+ ++it;
+ }
+
+ KviUserListEntry * entry = m_pEntryDict->find(nick);
+ if(entry)
+ {
+ entry->m_bSelected = true;
+ m_iSelectedCount = 1;
+ } else {
+ m_iSelectedCount = 0;
+ }
+ g_pFrame->childWindowSelectionStateChange(m_pKviWindow,true);
+ m_pViewArea->update();
+}
+
+bool KviUserListView::partInternal(const QString &nick,bool bRemove)
+{
+ KviUserListEntry * it = m_pEntryDict->find(nick);
+ if(it)
+ {
+ // so, first of all..check if this item is over, or below the top item
+ KviUserListEntry * e = m_pHeadItem;
+ bool bGotTopItem = false;
+ while(e != it)
+ {
+ if(e == m_pTopItem)
+ {
+ bGotTopItem = true;
+ e = it;
+ } else e = e->m_pNext;
+ }
+ if(bRemove)m_pIrcUserDataBase->removeUser(nick,it->m_pGlobalData);
+
+ // now just remove it
+ if(it->m_iFlags & KVI_USERFLAG_OP)m_iOpCount--;
+ if(it->m_iFlags & KVI_USERFLAG_VOICE)m_iVoiceCount--;
+ if(it->m_iFlags & KVI_USERFLAG_HALFOP)m_iHalfOpCount--;
+ if(it->m_iFlags & KVI_USERFLAG_CHANADMIN)m_iChanAdminCount--;
+ if(it->m_iFlags & KVI_USERFLAG_CHANOWNER)m_iChanOwnerCount--;
+ if(it->m_iFlags & KVI_USERFLAG_USEROP)m_iUserOpCount--;
+ if(it->m_bSelected)
+ {
+ m_iSelectedCount--;
+ if(m_iSelectedCount == 0)g_pFrame->childWindowSelectionStateChange(m_pKviWindow,false);
+ }
+ if(it->m_pPrev)it->m_pPrev->m_pNext = it->m_pNext;
+ if(it->m_pNext)it->m_pNext->m_pPrev = it->m_pPrev;
+ if(m_pTopItem == it)
+ {
+ bGotTopItem = true; //!!! the previous while() does not handle it!
+ m_pTopItem = it->m_pNext;
+ if(m_pTopItem == 0)m_pTopItem = it->m_pPrev;
+ }
+ if(it == m_pHeadItem)m_pHeadItem = it->m_pNext;
+ if(it == m_pTailItem)m_pTailItem = it->m_pPrev;
+ m_iTotalHeight -= it->m_iHeight;
+
+ int iHeight = it->m_iHeight;
+
+ m_pEntryDict->remove(nick);
+
+ if(bGotTopItem)
+ {
+ // removing after (or exactly) the top item, may be visible
+ if(bRemove)triggerUpdate();
+ } else {
+ // removing over (before) the top item...not visible
+ m_pViewArea->m_bIgnoreScrollBar = true;
+ m_pViewArea->m_iLastScrollBarVal -= iHeight;
+ m_pViewArea->m_pScrollBar->setValue(m_pViewArea->m_iLastScrollBarVal);
+// m_pViewArea->m_pScrollBar->setRange(0,m_iTotalHeight);
+ updateScrollBarRange();
+ m_pViewArea->m_bIgnoreScrollBar = false;
+ if(bRemove)updateUsersLabel();
+ }
+
+ return true;
+ }
+ return false;
+}
+
+bool KviUserListView::nickChange(const QString &oldNick,const QString &newNick)
+{
+ KviUserListEntry * it = m_pEntryDict->find(oldNick);
+ if(it)
+ {
+ QString user = it->m_pGlobalData->user();
+ QString host = it->m_pGlobalData->host();
+ int iFlags = it->m_iFlags;
+ kvi_time_t joint = it->m_joinTime;
+ bool bSelect = it->m_bSelected;
+ KviAvatar * av = it->m_pGlobalData->forgetAvatar();
+ KviIrcUserEntry::Gender gender = it->m_pGlobalData->gender();
+ bool bBot = it->m_pGlobalData->isBot();
+ part(oldNick);
+ __range_invalid(m_pEntryDict->find(oldNick));
+ it = join(newNick,user,host,iFlags);
+ it->m_pGlobalData->setGender(gender);
+ it->m_pGlobalData->setBot(bBot);
+ it->m_joinTime = joint;
+ it->m_lastActionTime = kvi_unixTime();
+ it->m_bSelected = bSelect;
+ it->m_iTemperature += KVI_USERACTION_NICK;
+ if(av)
+ {
+ it->m_pGlobalData->setAvatar(av);
+ avatarChanged(newNick);
+ }
+ return true;
+ }
+ return false;
+}
+
+
+void KviUserListView::updateUsersLabel()
+{
+ if(!KVI_OPTION_BOOL(KviOption_boolDisableUserListLabel))//G&N 2005
+ {
+ KviStr tmp;
+ tmp.sprintf("<nobr><b>[%u]</b>",m_pEntryDict->count());
+ if(m_iChanOwnerCount)tmp.append(KviStr::Format," q:%d",m_iChanOwnerCount);
+ if(m_iChanAdminCount)tmp.append(KviStr::Format," a:%d",m_iChanAdminCount);
+ if(m_iOpCount)tmp.append(KviStr::Format," o:%d",m_iOpCount);
+ if(m_iHalfOpCount)tmp.append(KviStr::Format," h:%d",m_iHalfOpCount);
+ if(m_iVoiceCount)tmp.append(KviStr::Format," v:%d",m_iVoiceCount);
+ if(m_iUserOpCount)tmp.append(KviStr::Format," u:%d",m_iUserOpCount);
+ if(m_ibEntries)tmp.append(KviStr::Format," b:%d",m_ibEntries);
+ if(m_ieEntries)tmp.append(KviStr::Format," e:%d",m_ieEntries);
+ if(m_iIEntries)tmp.append(KviStr::Format," I:%d",m_iIEntries);
+ tmp.append("</nobr>");
+ m_pUsersLabel->setText(tmp.ptr());
+ }
+}
+
+// FIXME: this could be done really better
+void KviUserListView::partAllButOne(const QString &whoNot)
+{
+ QStringList ll;
+ KviPointerHashTableIterator<QString,KviUserListEntry> it(*m_pEntryDict);
+ while(it.current())
+ {
+ if(!KviQString::equalCI(whoNot,it.currentKey()))
+ ll.append(it.currentKey());
+ ++it;
+ }
+ for(QStringList::Iterator it2 = ll.begin();it2 != ll.end();it2++)
+ {
+ part(*it2);
+ }
+}
+
+void KviUserListView::removeAllEntries()
+{
+ KviPointerHashTableIterator<QString,KviUserListEntry> it(*m_pEntryDict);
+ while(it.current())
+ {
+ m_pIrcUserDataBase->removeUser(it.currentKey(),
+ ((KviUserListEntry *)it.current())->m_pGlobalData);
+ ++it;
+ }
+ m_pEntryDict->clear();
+ m_pHeadItem = 0;
+ m_pTopItem = 0;
+ m_iVoiceCount = 0;
+ m_iHalfOpCount = 0;
+ m_iChanAdminCount = 0;
+ m_iChanOwnerCount = 0;
+ m_iOpCount = 0;
+ m_iUserOpCount = 0;
+ if(m_iSelectedCount != 0)
+ {
+ m_iSelectedCount = 0;
+ g_pFrame->childWindowSelectionStateChange(m_pKviWindow,false);
+ }
+ m_pViewArea->m_iTopItemOffset = 0;
+ m_pViewArea->m_iLastScrollBarVal = 0;
+ m_pViewArea->m_bIgnoreScrollBar = true;
+ m_pViewArea->m_pScrollBar->setValue(0);
+ m_iTotalHeight = 0;
+ updateScrollBarRange();
+ m_pViewArea->m_bIgnoreScrollBar = false; // gfgf
+}
+
+void KviUserListView::partAll()
+{
+ removeAllEntries();
+ triggerUpdate();
+}
+
+void KviUserListView::resizeEvent(QResizeEvent *)
+{
+ int hght;
+ if(!KVI_OPTION_BOOL(KviOption_boolDisableUserListLabel))//G&N 2005
+ {
+ hght = m_pUsersLabel->sizeHint().height();
+ if(hght < 16)hght = 16; // at least
+ m_pUsersLabel->setGeometry(0,0,width(),hght);
+ }
+ else
+ {
+ hght =0;
+ }
+
+ m_pViewArea->setGeometry(0,hght,width(),height() - hght);
+
+ updateScrollBarRange();
+}
+
+bool KviUserListView::itemVisible(KviUserListEntry * e)
+{
+ KviUserListEntry * le = m_pTopItem;
+ int curTop = KVI_USERLIST_BORDER_WIDTH - m_pViewArea->m_iTopItemOffset;
+ int hght = height();
+ while(le && (curTop < hght))
+ {
+ if(le == e)return true;
+ curTop += le->m_iHeight;
+ le = le->m_pNext;
+ }
+ return false;
+}
+
+KviUserListEntry * KviUserListView::itemAt(const QPoint &pnt,QRect * rct)
+{
+ if(!m_pTopItem)return 0;
+ if(pnt.y() < 0)return 0;
+ int curTop = KVI_USERLIST_BORDER_WIDTH - m_pViewArea->m_iTopItemOffset;
+ KviUserListEntry * e = m_pTopItem;
+ int curBottom = 0;
+ while(e && (curTop <= m_pViewArea->height()))
+ {
+ curBottom = curTop + e->m_iHeight;
+ if((pnt.y() >= curTop) && (pnt.y() < curBottom))
+ {
+ if(rct)
+ {
+ rct->setX(0);
+ rct->setY(curTop);
+ rct->setWidth(m_pViewArea->width());
+ rct->setHeight(e->m_iHeight);
+ }
+ return e;
+ }
+ curTop = curBottom;
+ e = e->m_pNext;
+ }
+ return 0;
+}
+
+
+
+void KviUserListView::userStats(KviUserListViewUserStats * s)
+{
+ s->uTotal = m_pEntryDict->count();
+ s->uHot = 0;
+ s->uHotOp = 0;
+ s->uActive = 0;
+ s->uActiveOp = 0;
+ s->uChanAdmin = 0;
+ s->uChanOwner = 0;
+ s->iAvgTemperature = 0;
+ s->uOp = 0;
+ s->uVoiced = 0;
+ s->uHalfOp = 0;
+ s->uUserOp = 0;
+
+ KviUserListEntry * e = m_pHeadItem;
+
+ kvi_time_t curTime = kvi_unixTime();
+
+ while(e)
+ {
+ if(e->m_lastActionTime)
+ {
+ unsigned int uTimeDiff = (((unsigned int)(curTime - e->m_lastActionTime)) >> 6);
+ if(uTimeDiff < 10)
+ {
+ s->uActive++; // the user was alive in the last ~16 mins
+ if(e->m_iFlags & (KVI_USERFLAG_OP | KVI_USERFLAG_CHANADMIN | KVI_USERFLAG_CHANOWNER))
+ {
+ s->uActiveOp++;
+ if(e->m_iTemperature > 0)
+ {
+ s->uHot++;
+ s->uHotOp++;
+ }
+ } else {
+ if(e->m_iTemperature > 0)s->uHot++;
+ }
+ s->iAvgTemperature += e->m_iTemperature;
+ }
+ }
+ if(e->m_iFlags & KVI_USERFLAG_CHANOWNER)s->uChanOwner++;
+ else {
+ if(e->m_iFlags & KVI_USERFLAG_CHANADMIN)s->uChanAdmin++;
+ else {
+ if(e->m_iFlags & KVI_USERFLAG_OP)s->uOp++;
+ else {
+ if(e->m_iFlags & KVI_USERFLAG_HALFOP)s->uHalfOp++;
+ else {
+ if(e->m_iFlags & KVI_USERFLAG_VOICE)s->uVoiced++;
+ else {
+ if(e->m_iFlags & KVI_USERFLAG_USEROP)s->uUserOp++;
+ }
+ }
+ }
+ }
+ }
+ e = e->m_pNext;
+ }
+
+ if(s->uActive > 0)s->iAvgTemperature /= ((int)s->uActive);
+}
+
+
+void KviUserListView::maybeTip(KviUserListToolTip * tip,const QPoint &pnt)
+{
+ if(!KVI_OPTION_BOOL(KviOption_boolShowUserListViewToolTips))return;
+ QRect itRect;
+ KviUserListEntry * it = (KviUserListEntry *)itemAt(pnt,&itRect);
+ if(it)
+ {
+ if(m_pKviWindow->console())
+ {
+ QString buffer;
+ m_pKviWindow->console()->getUserTipText(it->m_szNick,it->m_pGlobalData,buffer);
+
+ buffer += "<table width=\"100%\">";
+
+ if(it->m_joinTime != 0)
+ {
+ QDateTime dt;
+ dt.setTime_t(it->m_joinTime);
+ buffer += "<tr><td bgcolor=\"#F0F0F0\"><nobr>";
+ buffer += __tr2qs("Joined on <b>%1</b>").arg(dt.toString());
+ buffer += "</nobr></td></tr>";
+ }
+
+ if(it->m_lastActionTime != 0)
+ {
+ int secs = kvi_unixTime() - it->m_lastActionTime;
+ int mins = secs / 60;
+ secs = secs % 60;
+ int hors = mins / 60;
+ mins = mins % 60;
+ buffer += "<tr><td bgcolor=\"#F0F0F0\"><nobr>";
+ buffer += __tr2qs("Quiet for <b>%1h %2m %3s</b>").arg(hors).arg(mins).arg(secs);
+ buffer += "</nobr></td></tr>";
+ }
+ buffer += "</table>";
+
+ tip->doTip(itRect,buffer);
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////
+
+KviUserListViewArea::KviUserListViewArea(KviUserListView * par)
+: QWidget(par)
+{
+ m_pListView = par;
+#ifdef COMPILE_USE_QT4
+ setAutoFillBackground(false);
+#else
+ setBackgroundMode(QWidget::NoBackground);
+#endif
+#ifdef COMPILE_USE_QT4
+ m_pScrollBar = new QScrollBar(Qt::Vertical,this,"scrollbar");
+#else
+ m_pScrollBar = new QScrollBar(QScrollBar::Vertical,this,"scrollbar");
+#endif
+ m_pScrollBar->setRange(0,0);
+ m_pScrollBar->setValue(0);
+ connect(m_pScrollBar,SIGNAL(valueChanged(int)),this,SLOT(scrollBarMoved(int)));
+ m_pScrollBar->setPageStep(height());
+ m_pScrollBar->setLineStep(m_pListView->m_iFontHeight);
+ m_iLastScrollBarVal = 0;
+ m_iTopItemOffset = 0;
+ m_bIgnoreScrollBar = false;
+ m_pLastEntryUnderMouse = 0;
+}
+
+KviUserListViewArea::~KviUserListViewArea()
+{
+}
+
+void KviUserListViewArea::scrollBarMoved(int newVal)
+{
+ if(m_bIgnoreScrollBar)return;
+ int diff = newVal - m_iLastScrollBarVal;
+ if(m_pListView->m_pTopItem)
+ {
+ while(diff > 0)
+ {
+ int nextH = (m_pListView->m_pTopItem->m_iHeight - m_iTopItemOffset);
+ if(diff >= nextH)
+ {
+ // the diff is greater than the top item visible part
+ diff -= nextH;
+ if(m_pListView->m_pTopItem->m_pNext)
+ {
+ // There is a next item (offset to 0)
+ m_pListView->m_pTopItem = m_pListView->m_pTopItem->m_pNext;
+ m_iTopItemOffset = 0;
+ } else {
+ // No next item (rather a bug) (offset to the top item size)
+ m_iTopItemOffset = m_pListView->m_pTopItem->m_iHeight;
+ diff = 0;
+ }
+ } else {
+ // just offset the top item
+ m_iTopItemOffset += diff;
+ diff = 0;
+ }
+ }
+ while(diff < 0)
+ {
+ if((-diff) <= m_iTopItemOffset)
+ {
+ // just move the top item
+ m_iTopItemOffset += diff;
+ diff = 0;
+ } else {
+ diff += m_iTopItemOffset;
+ if(m_pListView->m_pTopItem->m_pPrev)
+ {
+ // There is a prev item (offset to 0)
+ m_pListView->m_pTopItem = m_pListView->m_pTopItem->m_pPrev;
+ m_iTopItemOffset = m_pListView->m_pTopItem->m_iHeight;
+ } else {
+ // No prev item (rather a bug) (offset to the top item size)
+ m_iTopItemOffset = 0;
+ diff = 0;
+ }
+ }
+ }
+ }
+ m_iLastScrollBarVal = newVal;
+ update();
+
+}
+
+void KviUserListViewArea::paintEvent(QPaintEvent *ev)
+{
+ // update the scroll bar
+
+ if(!isVisible())return;
+
+ // if the mdiManager is in SDI mode
+ // and this window is attacched but is not the toplevel one
+ // then it is hidden completely behind the other windows
+ // and we can avoid to paint it :)
+ if(g_pFrame->mdiManager()->isInSDIMode() &&
+ (m_pListView->window()->mdiParent() != g_pFrame->mdiManager()->topChild()) &&
+ (m_pListView->window()->mdiParent()))
+ {
+ return; // totally hidden behind other windows
+ }
+
+ int wdth = width() - m_pScrollBar->width();
+
+ QRect r = ev->rect();
+ if(r.right() > wdth)r.setRight(wdth);
+
+ //debug("PAINT EVENT %d,%d,%d,%d",r.left(),r.top(),r.width(),r.height());
+
+ KviDoubleBuffer db(width(),height());
+ QPixmap * pMemBuffer = db.pixmap();
+
+ QPainter p(pMemBuffer);
+ SET_ANTI_ALIASING(p);
+ p.setFont(KVI_OPTION_FONT(KviOption_fontUserListView));
+
+#ifdef COMPILE_USE_QT4
+ QFontMetrics fm(p.fontMetrics());
+#endif
+
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ if(g_pShadedChildGlobalDesktopBackground)
+ {
+ QPoint pnt = mapToGlobal(QPoint(r.left(),r.top()));
+ p.drawTiledPixmap(r.left(),r.top(),r.width(),r.height(),*g_pShadedChildGlobalDesktopBackground,pnt.x(),pnt.y());
+ } else {
+#endif
+ QPixmap *pix = KVI_OPTION_PIXMAP(KviOption_pixmapUserListViewBackground).pixmap();
+ p.fillRect(r.left(),r.top(),r.width(),r.height(),KVI_OPTION_COLOR(KviOption_colorUserListViewBackground));
+ if(pix)
+ KviPixmapUtils::drawPixmapWithPainter(&p,pix,KVI_OPTION_UINT(KviOption_uintUserListPixmapAlign),r,width(),height());
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ }
+#endif
+
+ KviUserListEntry * e = m_pListView->m_pTopItem;
+
+ int theY = KVI_USERLIST_BORDER_WIDTH - m_iTopItemOffset;
+
+ kvi_time_t curTime = kvi_unixTime();
+
+ bool bShowIcons = KVI_OPTION_BOOL(KviOption_boolShowUserChannelIcons);
+ bool bShowState = KVI_OPTION_BOOL(KviOption_boolShowUserChannelState);
+ bool bShowGender = KVI_OPTION_BOOL(KviOption_boolDrawGenderIcons);
+
+ while(e && theY <= r.bottom())
+ {
+ int bottom = theY + e->m_iHeight;
+ // theY is our top line
+ // theX is our left corner
+ // bottom is our bottom line
+ // wdth is the width of the whole widget
+
+ if(bottom >= r.top())
+ {
+ QColor * pClrFore = 0;
+ bool bColorAllocated=0; // FIXME: bool is true or false
+ if(e->m_bSelected)
+ {
+ p.fillRect(0,theY,wdth,e->m_iHeight,KVI_OPTION_COLOR(KviOption_colorUserListViewSelectionBackground));
+ pClrFore = &(KVI_OPTION_COLOR(KviOption_colorUserListViewSelectionForeground));
+ } else if(KVI_OPTION_BOOL(KviOption_boolUseDifferentColorForOwnNick) && m_pListView->m_pKviWindow->connection())
+ {
+ if(e->m_szNick==m_pListView->m_pKviWindow->connection()->currentNickName())
+ pClrFore = &(KVI_OPTION_COLOR(KviOption_colorUserListViewOwnForeground));
+ }
+
+ if(!pClrFore){
+ // FIXME:
+ //
+ // this is slow... VERY slow when one has a lot of registered users.
+ // (this is NOT a simple lookup in the user db... it is a mask match)
+ // if we REALLY need to use custom colors for regged users then
+ // they should be updated ONCE and stored (cached) in the KviUserListEntry structure
+ //
+ if(m_pListView->m_pKviWindow->connection()->userDataBase()->haveCustomColor(e->m_szNick))
+ {
+ pClrFore = m_pListView->m_pKviWindow->connection()->userDataBase()->customColor(e->m_szNick);
+ }
+ if(!pClrFore)
+ {
+ if(e->m_iFlags == 0)
+ {
+ pClrFore = &(KVI_OPTION_COLOR(KviOption_colorUserListViewNormalForeground));
+ } else {
+ pClrFore = &(KVI_OPTION_COLOR((e->m_iFlags & KVI_USERFLAG_CHANOWNER) ? \
+ KviOption_colorUserListViewChanOwnerForeground : ((e->m_iFlags & KVI_USERFLAG_CHANADMIN) ? \
+ KviOption_colorUserListViewChanAdminForeground : ((e->m_iFlags & KVI_USERFLAG_OP) ? \
+ KviOption_colorUserListViewOpForeground : ((e->m_iFlags & KVI_USERFLAG_HALFOP) ? \
+ KviOption_colorUserListViewHalfOpForeground : ((e->m_iFlags & KVI_USERFLAG_VOICE) ? \
+ KviOption_colorUserListViewVoiceForeground : KviOption_colorUserListViewUserOpForeground))))));
+ }
+ }
+ }
+
+ int theX = KVI_USERLIST_BORDER_WIDTH + 1;
+
+ int iAvatarAndTextX = theX;
+
+ if(bShowGender)iAvatarAndTextX += 11;
+ if(bShowIcons)iAvatarAndTextX += 18;
+ if(bShowState)iAvatarAndTextX += 11;
+
+ if(KVI_OPTION_BOOL(KviOption_boolUserListViewDrawGrid))
+ {
+ // the grid
+ switch(KVI_OPTION_UINT(KviOption_uintUserListViewGridType))
+ {
+ case KVI_USERLISTVIEW_GRIDTYPE_PLAINGRID:
+ case KVI_USERLISTVIEW_GRIDTYPE_DOTGRID:
+ p.setPen(QPen(KVI_OPTION_COLOR(KviOption_colorUserListViewGrid),0,
+#ifdef COMPILE_USE_QT4
+ (KVI_OPTION_UINT(KviOption_uintUserListViewGridType) == KVI_USERLISTVIEW_GRIDTYPE_DOTGRID) ? Qt::DotLine : Qt::SolidLine));
+#else
+ (KVI_OPTION_UINT(KviOption_uintUserListViewGridType) == KVI_USERLISTVIEW_GRIDTYPE_DOTGRID) ? QPen::DotLine : QPen::SolidLine));
+#endif
+ p.drawLine(0,bottom - 1,wdth,bottom - 1);
+ if(bShowState || bShowIcons)
+ p.drawLine(iAvatarAndTextX,bottom - 1,iAvatarAndTextX,theY);
+ break;
+ default: // KVI_USERLISTVIEW_GRIDTYPE_3DGRID and KVI_USERLISTVIEW_GRIDTYPE_3DBUTTONS
+ if(!e->m_bSelected)
+ {
+ p.setPen(QPen(KVI_OPTION_COLOR(KviOption_colorUserListViewGrid),0 /*,QPen::DotLine*/));
+ if((bShowState || bShowIcons) && (KVI_OPTION_UINT(KviOption_uintUserListViewGridType) == KVI_USERLISTVIEW_GRIDTYPE_3DGRID))
+ p.drawLine(iAvatarAndTextX,bottom - 1,iAvatarAndTextX,theY);
+ p.setPen(colorGroup().shadow());
+ p.drawLine(0,bottom - 1,wdth,bottom - 1);
+ p.setPen(colorGroup().light());
+ p.drawLine(0,theY,wdth,theY);
+ theY--;
+ }
+ theY++;
+ break;
+ }
+ iAvatarAndTextX += 3;
+ } else {
+ iAvatarAndTextX += 1;
+ }
+
+ if(e->globalData()->isAway())
+ {
+ QRgb rgb2 = pClrFore->rgb();
+ QRgb rgb1 = KVI_OPTION_COLOR(KviOption_colorUserListViewAwayForeground).rgb();
+ p.setPen(QColor(((qRed(rgb1)*2) + qRed(rgb2)) / 3,((qGreen(rgb1)*2) + qGreen(rgb2)) / 3,((qBlue(rgb1)*2) + qBlue(rgb2)) / 3));
+ } else {
+ p.setPen(*pClrFore);
+ }
+ theY+=2;
+
+ if(!KVI_OPTION_BOOL(KviOption_boolDisableAvatars))//G&N 2005
+ {
+ KviAvatar * av = e->m_pGlobalData->avatar();
+ if(av && KVI_OPTION_UINT(KviOption_uintAvatarScaleWidth) && KVI_OPTION_UINT(KviOption_uintAvatarScaleHeight))
+ {
+ QPixmap * pix;
+ if( KVI_OPTION_BOOL(KviOption_boolScaleAvatars) &&
+ (
+ !KVI_OPTION_BOOL(KviOption_boolDoNotStretchAvatars) ||
+ (av->pixmap()->width() > KVI_OPTION_UINT(KviOption_uintAvatarScaleWidth)) ||
+ (av->pixmap()->height() > KVI_OPTION_UINT(KviOption_uintAvatarScaleHeight))
+ )
+ )
+ pix=av->scaledPixmap(KVI_OPTION_UINT(KviOption_uintAvatarScaleWidth),KVI_OPTION_UINT(KviOption_uintAvatarScaleHeight));
+ else
+ pix=av->pixmap();
+ p.drawPixmap(iAvatarAndTextX,theY,*pix);
+ theY += pix->height() + 1;
+ }
+ }
+
+ if(bShowGender)
+ {
+ if(e->globalData()->gender()!=KviIrcUserEntry::Unknown)
+ {
+ QPixmap * ico = g_pIconManager->getBigIcon((e->globalData()->gender()==KviIrcUserEntry::Male) ? "kvi_icon_male.png" : "kvi_icon_female.png");
+ p.drawPixmap(theX,theY+(m_pListView->m_iFontHeight-11)/2,*ico);
+ }
+ if(e->globalData()->isBot())
+ {
+ QPixmap * ico = g_pIconManager->getBigIcon("kvi_icon_bot.png");
+ p.drawPixmap(theX,theY+(m_pListView->m_iFontHeight-11)/2,*ico);
+ }
+ theX +=11;
+ }
+
+ if(bShowState)
+ {
+ if(e->m_lastActionTime)
+ {
+ // the g_pUserChanStatePixmap is 36 x 80 pixels
+ // divided into 6 rows of 5 pixmaps
+ // row 0 is hot , row 5 is cold
+ // left is most active , right is least active
+ // e->m_iTemperature is a signed short , negative values are cold
+ // e->m_lastActionTime is the time of the last action (eventually 0 , if not known)
+ // 6 bit right shift is an aprox division for 64 : really aprox minutes
+ unsigned int uTimeDiff = (((unsigned int)(curTime - e->m_lastActionTime)) >> 6);
+ if(uTimeDiff < 16)
+ {
+ //p.drawRect(theX,theY + 2,10,e->m_iHeight - 4);
+ static int xOffTable[16] =
+ {
+ 0 , 8 , 16 , 16 ,
+ 24 , 24 , 24 , 24 ,
+ 32 , 32 , 32 , 32 ,
+ 32 , 32 , 32 , 32
+ };
+ // the temperature now
+ // temp > 100 is hot (offset y = 0)
+ // temp < -100 is cold (offset y = 80)
+ // temp > 30 is half-hot (offset y = 16)
+ // temp < -30 is half-cold (offset y = 64)
+ // temp > 0 is a-bit-hot (offset y = 32)
+ // temp < 0 is a-bit-cold (offset y = 48)
+
+ if(e->m_iTemperature > KVI_MID_TEMPERATURE)
+ {
+ if(e->m_iTemperature > KVI_HALF_HOT_TEMPERATURE)
+ {
+ if(e->m_iTemperature > KVI_HOT_TEMPERATURE)
+ {
+ // hot
+ p.drawPixmap(theX,theY,*g_pUserChanStatePixmap,xOffTable[uTimeDiff],0,8,16);
+ } else {
+ // half-hot
+ p.drawPixmap(theX,theY,*g_pUserChanStatePixmap,xOffTable[uTimeDiff],16,8,16);
+ }
+ } else {
+ // bit-hot
+ p.drawPixmap(theX,theY,*g_pUserChanStatePixmap,xOffTable[uTimeDiff],32,8,16);
+ }
+ } else {
+ if(e->m_iTemperature < KVI_HALF_COLD_TEMPERATURE)
+ {
+ if(e->m_iTemperature < KVI_COLD_TEMPERATURE)
+ {
+ // cold
+ p.drawPixmap(theX,theY,*g_pUserChanStatePixmap,xOffTable[uTimeDiff],80,8,16);
+ } else {
+ // half-cold
+ p.drawPixmap(theX,theY,*g_pUserChanStatePixmap,xOffTable[uTimeDiff],64,8,16);
+ }
+ } else {
+ // bit-cold
+ p.drawPixmap(theX,theY,*g_pUserChanStatePixmap,xOffTable[uTimeDiff],48,8,16);
+ }
+ }
+ }
+ }
+ theX += 11;
+ }
+
+ if(bShowIcons)
+ {
+ //p.drawRect(theX,theY + 2,18,e->m_iHeight - 4);
+ if(e->m_iFlags != 0)
+ {
+ QPixmap * ico = g_pIconManager->getSmallIcon( \
+ e->globalData()->isAway() ? \
+ ( \
+ (e->m_iFlags & KVI_USERFLAG_CHANOWNER) ? \
+ KVI_SMALLICON_CHANOWNERAWAY : ((e->m_iFlags & KVI_USERFLAG_CHANADMIN) ? \
+ KVI_SMALLICON_CHANADMINAWAY : ((e->m_iFlags & KVI_USERFLAG_OP) ? \
+ KVI_SMALLICON_OPAWAY : ((e->m_iFlags & KVI_USERFLAG_HALFOP) ? \
+ KVI_SMALLICON_HALFOPAWAY : ((e->m_iFlags & KVI_USERFLAG_VOICE) ? \
+ KVI_SMALLICON_VOICEAWAY : KVI_SMALLICON_USEROPAWAY))))
+ ) \
+ : \
+ ( \
+ (e->m_iFlags & KVI_USERFLAG_CHANOWNER) ? \
+ KVI_SMALLICON_CHANOWNER : ((e->m_iFlags & KVI_USERFLAG_CHANADMIN) ? \
+ KVI_SMALLICON_CHANADMIN : ((e->m_iFlags & KVI_USERFLAG_OP) ? \
+ KVI_SMALLICON_OP : ((e->m_iFlags & KVI_USERFLAG_HALFOP) ? \
+ KVI_SMALLICON_HALFOP : ((e->m_iFlags & KVI_USERFLAG_VOICE) ? \
+ KVI_SMALLICON_VOICE : KVI_SMALLICON_USEROP)))) \
+ ) \
+ );
+#ifdef COMPILE_USE_QT4
+ p.drawPixmap(theX,theY+(fm.lineSpacing()-16/*size of small icon*/)/2,*ico);
+#else
+ p.drawPixmap(theX,theY+(m_pListView->m_iFontHeight-16/*size of small icon*/)/2,*ico);
+#endif
+ }
+ theX +=18;
+#ifdef COMPILE_USE_QT4
+ p.drawText(iAvatarAndTextX,theY,wdth - theX,fm.lineSpacing(),Qt::AlignLeft|Qt::AlignVCenter,e->m_szNick);
+#else
+ p.drawText(iAvatarAndTextX,theY,wdth - theX,m_pListView->m_iFontHeight,Qt::AlignLeft|Qt::AlignVCenter,e->m_szNick);
+#endif
+ } else {
+
+ char flag = m_pListView->getUserFlag(e);
+ if(flag)
+ {
+ QString ttt = QChar(flag);
+ ttt += e->m_szNick;
+#ifdef COMPILE_USE_QT4
+ p.drawText(iAvatarAndTextX,theY,wdth - theX,fm.lineSpacing(),Qt::AlignLeft|Qt::AlignVCenter,ttt);
+#else
+ p.drawText(iAvatarAndTextX,theY,wdth - theX,m_pListView->m_iFontHeight,Qt::AlignLeft|Qt::AlignVCenter,ttt);
+#endif
+ } else {
+#ifdef COMPILE_USE_QT4
+ p.drawText(iAvatarAndTextX,theY,wdth - theX,fm.lineSpacing(),Qt::AlignLeft|Qt::AlignVCenter,e->m_szNick);
+#else
+ p.drawText(iAvatarAndTextX,theY,wdth - theX,m_pListView->m_iFontHeight,Qt::AlignLeft|Qt::AlignVCenter,e->m_szNick);
+#endif
+ }
+ }
+ if(bColorAllocated) delete pClrFore;
+ }
+
+ theY = bottom;
+ e = e->m_pNext;
+ }
+
+ //we really do not need any self-draw borders.
+ //if we will need it, we will draw a better one with system style
+
+ //p.setPen(colorGroup().dark());
+ //p.drawLine(0,0,wdth,0);
+ //p.drawLine(0,0,0,height());
+ //p.setPen(colorGroup().light());
+ //p.drawLine(1,height()-1,wdth,height()-1);
+ //p.drawLine(wdth - 1,1,wdth - 1,height());
+
+#ifdef COMPILE_USE_QT4
+ QPainter qt4SuxBecauseOfThisAdditionalPainter(this);
+ qt4SuxBecauseOfThisAdditionalPainter.drawPixmap(r.left(),r.top(),r.width(),r.height(),*pMemBuffer,r.left(),r.top(),r.width(),r.height());
+#else
+ bitBlt(this,r.left(),r.top(),pMemBuffer,r.left(),r.top(),r.width(),r.height(),Qt::CopyROP,false);
+#endif
+}
+
+void KviUserListViewArea::resizeEvent(QResizeEvent *)
+{
+ int iScr = m_pScrollBar->sizeHint().width();
+ m_pScrollBar->setGeometry(width() - iScr,0,iScr,height());
+ m_pScrollBar->setPageStep(height());
+ m_pScrollBar->setLineStep(m_pListView->m_iFontHeight - 1);
+}
+
+void KviUserListViewArea::mousePressEvent(QMouseEvent *e)
+{
+ setFocus();
+ if(e->button() & Qt::LeftButton)
+ {
+ KviUserListEntry * entry = m_pListView->itemAt(e->pos());
+ if(entry)
+ {
+ if(e->state() & Qt::ShiftButton)
+ {
+ // Multiselect mode
+ if(!entry->m_bSelected)m_pListView->m_iSelectedCount++;
+ entry->m_bSelected = true;
+ if(m_pListView->m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ update();
+ } else if(e->state() & Qt::ControlButton)
+ {
+ // Invert mode
+ if(!entry->m_bSelected)m_pListView->m_iSelectedCount++;
+ else m_pListView->m_iSelectedCount--;
+ entry->m_bSelected = ! entry->m_bSelected;
+ if(m_pListView->m_iSelectedCount == 0)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,false);
+ else if(m_pListView->m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ update();
+ } else {
+ // Single select mode
+ bool bThereWasSelection = false;
+ if(m_pListView->m_iSelectedCount > 0)
+ {
+ KviUserListEntry * aux = m_pListView->m_pHeadItem;
+ while(aux)
+ {
+ aux->m_bSelected = false;
+ aux = aux->m_pNext;
+ }
+ bThereWasSelection = true;
+ }
+ entry->m_bSelected = true;
+ m_pListView->m_iSelectedCount = 1;
+ if(!bThereWasSelection)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ update();
+ }
+ }
+ m_pLastEntryUnderMouse = entry;
+ } else if(e->button() & Qt::RightButton)
+ {
+ KviUserListEntry * entry = m_pListView->itemAt(e->pos());
+ if(entry)
+ {
+ if(!entry->m_bSelected){
+ entry->m_bSelected = true;
+ m_pListView->m_iSelectedCount=1;
+ KviPointerHashTableIterator<QString,KviUserListEntry> it(*(m_pListView->m_pEntryDict));
+ while(it.current())
+ {
+ if(it.current()!=entry)
+ ((KviUserListEntry *)it.current())->m_bSelected = false;
+ ++it;
+ }
+ }
+ if(m_pListView->m_iSelectedCount == 1)
+ g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ update();
+ }
+ m_pListView->emitRightClick();
+ }
+}
+void KviUserListViewArea::keyPressEvent( QKeyEvent * e )
+{
+ if(e->key()==Qt::Key_Escape)
+ {
+ if(m_pListView->m_pKviWindow->input())
+ ((QWidget*)(m_pListView->m_pKviWindow->input()))->setFocus();
+ } else {
+ QString szKey=e->text();
+ if(!szKey.isEmpty())
+ {
+ KviUserListEntry * nick=0;
+ KviUserListEntry * aux = m_pListView->m_pHeadItem;
+ while(aux)
+ {
+ //debug("%s %s %i %s %i",__FILE__,__FUNCTION__,__LINE__,aux->nick().utf8().data(),aux->nick().find(szKey,0,0));
+ if(aux->nick().find(szKey,0,0)==0)
+ {
+ nick=aux;
+ break;
+ }
+ aux = aux->m_pNext;
+ }
+ if(nick)
+ {
+ bool bThereWasSelection = false;
+ if(m_pListView->m_iSelectedCount > 0)
+ {
+ aux = m_pListView->m_pHeadItem;
+ while(aux)
+ {
+ aux->m_bSelected = false;
+ aux = aux->m_pNext;
+ }
+ bThereWasSelection = true;
+ }
+ nick->m_bSelected = true;
+ m_pListView->m_iSelectedCount = 1;
+ if(!bThereWasSelection)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ update();
+ }
+ }
+ }
+}
+
+void KviUserListViewArea::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ m_pListView->emitDoubleClick();
+}
+
+void KviUserListViewArea::mouseMoveEvent(QMouseEvent *e)
+{
+ if(e->state() & Qt::LeftButton)
+ {
+ KviUserListEntry * entry = m_pListView->itemAt(e->pos());
+ if(entry && (entry != m_pLastEntryUnderMouse))
+ {
+ if(e->state() & Qt::ControlButton)
+ {
+ if(entry->m_bSelected)m_pListView->m_iSelectedCount--;
+ else m_pListView->m_iSelectedCount++;
+ entry->m_bSelected = ! entry->m_bSelected;
+ if(m_pListView->m_iSelectedCount == 0)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,false);
+ else if(m_pListView->m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ } else {
+ if(!entry->m_bSelected)m_pListView->m_iSelectedCount++;
+ entry->m_bSelected = true;
+ if(m_pListView->m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ }
+ update();
+ m_pLastEntryUnderMouse = entry;
+ } else {
+ // out of the widget ?
+ if(entry == m_pLastEntryUnderMouse)return;
+ if(e->pos().y() < KVI_USERLIST_BORDER_WIDTH)
+ {
+ KviUserListEntry * top = m_pListView->m_pTopItem;
+ if(top)
+ {
+ m_pScrollBar->setValue(m_pScrollBar->value() - top->m_iHeight);
+ if(m_pListView->m_pTopItem != top)
+ {
+ if(e->state() & Qt::ControlButton)
+ {
+ if(m_pListView->m_pTopItem->m_bSelected)m_pListView->m_iSelectedCount--;
+ else m_pListView->m_iSelectedCount++;
+ m_pListView->m_pTopItem->m_bSelected = ! m_pListView->m_pTopItem->m_bSelected;
+ if(m_pListView->m_iSelectedCount == 0)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,false);
+ else if(m_pListView->m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ } else {
+ if(!m_pListView->m_pTopItem->m_bSelected)m_pListView->m_iSelectedCount++;
+ m_pListView->m_pTopItem->m_bSelected = true;
+ if(m_pListView->m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ }
+ update();
+ }
+ }
+ m_pLastEntryUnderMouse = top;
+ } else if(e->pos().y() > (height() - KVI_USERLIST_BORDER_WIDTH))
+ {
+ KviUserListEntry * bottom = m_pListView->m_pTopItem;
+ if(bottom)
+ {
+ int theY = KVI_USERLIST_BORDER_WIDTH - m_iTopItemOffset;
+ while(bottom && (theY < height()))
+ {
+ theY+= bottom->m_iHeight;
+ bottom = bottom->m_pNext;
+ }
+ if(!bottom)bottom = m_pListView->m_pTailItem;
+ if(bottom)
+ {
+ m_pScrollBar->setValue(m_pScrollBar->value() + bottom->m_iHeight);
+ if(bottom != m_pLastEntryUnderMouse)
+ {
+ if(e->state() & Qt::ControlButton)
+ {
+ if(bottom->m_bSelected)m_pListView->m_iSelectedCount--;
+ else m_pListView->m_iSelectedCount++;
+ bottom->m_bSelected = ! bottom->m_bSelected;
+ if(m_pListView->m_iSelectedCount == 0)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,false);
+ else if(m_pListView->m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ } else {
+ if(!bottom->m_bSelected)m_pListView->m_iSelectedCount++;
+ bottom->m_bSelected = true;
+ if(m_pListView->m_iSelectedCount == 1)g_pFrame->childWindowSelectionStateChange(m_pListView->m_pKviWindow,true);
+ }
+ update();
+ }
+ }
+ }
+ m_pLastEntryUnderMouse = bottom;
+ } else m_pLastEntryUnderMouse = 0;
+ }
+ }
+}
+
+void KviUserListViewArea::mouseReleaseEvent(QMouseEvent *)
+{
+ m_pLastEntryUnderMouse = 0;
+}
+
+void KviUserListViewArea::wheelEvent(QWheelEvent *e)
+{
+#ifdef COMPILE_USE_QT4
+ static bool bHere = false; // Qt4(<= 4.2.2) has a nasty bug that makes the re-sent wheelEvent to cause infinite recursion
+ if(bHere)return;
+ bHere = true;
+#endif
+ g_pApp->sendEvent(m_pScrollBar,e);
+#ifdef COMPILE_USE_QT4
+ bHere = false;
+#endif
+}
+
+#include "kvi_userlistview.moc"
diff --git a/src/kvirc/ui/kvi_userlistview.h b/src/kvirc/ui/kvi_userlistview.h
new file mode 100644
index 0000000..f540593
--- /dev/null
+++ b/src/kvirc/ui/kvi_userlistview.h
@@ -0,0 +1,259 @@
+#ifndef _KVI_USERLISTVIEW_H_
+#define _KVI_USERLISTVIEW_H_
+
+//=============================================================================
+//
+// File : kvi_userlistview.h
+// Creation date : Tue Aug 1 2000 21:03:41 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+
+#include "kvi_string.h"
+#include "kvi_ircuserdb.h"
+#include "kvi_ircmask.h"
+#include "kvi_time.h"
+
+#include <time.h>
+#include "kvi_tal_tooltip.h"
+#include <qwidget.h>
+#include "kvi_pointerlist.h"
+#include "kvi_pointerhashtable.h"
+#include "kvi_toolwindows_container.h"
+
+class QLabel;
+class QScrollBar;
+
+class KviUserListView;
+class KviUserListViewArea;
+class KviConsole;
+class KviWindow;
+
+#define KVI_USERLISTVIEW_GRIDTYPE_3DGRID 0
+#define KVI_USERLISTVIEW_GRIDTYPE_3DBUTTONS 1
+#define KVI_USERLISTVIEW_GRIDTYPE_PLAINGRID 2
+#define KVI_USERLISTVIEW_GRIDTYPE_DOTGRID 3
+
+#define KVI_USERLISTVIEW_GRIDTYPE_MAXIMUM 3
+#define KVI_USERLISTVIEW_GRIDTYPE_DEFAULT 0
+
+class KVIRC_API KviUserListToolTip : public KviTalToolTip
+{
+public:
+ KviUserListToolTip(KviUserListView *v,KviUserListViewArea * a);
+ virtual ~KviUserListToolTip();
+private:
+ KviUserListView * m_pListView;
+public:
+ virtual void maybeTip(const QPoint &pnt);
+ void doTip(const QRect &rct,const QString &str){ tip(rct,str); };
+};
+
+
+
+class KVIRC_API KviUserListEntry
+{
+ friend class KviUserListView;
+ friend class KviUserListViewArea;
+public:
+ KviUserListEntry(KviUserListView * parent,const QString &nick,KviIrcUserEntry * e,short int iFlags,bool bJoinTimeUnknown = true);
+ ~KviUserListEntry();
+protected:
+ KviUserListView * m_pListView;
+ QString m_szNick;
+ KviIrcUserEntry * m_pGlobalData;
+ short int m_iFlags;
+ short int m_iTemperature; // user temperature : 0 = neutral
+ kvi_time_t m_lastActionTime;
+ kvi_time_t m_joinTime;
+
+ int m_iHeight;
+ bool m_bSelected;
+ KviUserListEntry * m_pNext;
+ KviUserListEntry * m_pPrev;
+public:
+ short int flags() const { return m_iFlags; };
+ KviIrcUserEntry * globalData(){ return m_pGlobalData; };
+ const QString &nick() const { return m_szNick; };
+ KviUserListEntry * next(){ return m_pNext; };
+ bool color(QColor& color);
+protected:
+ void recalcSize();
+};
+
+
+typedef struct _KviUserListViewUserStats
+{
+ unsigned int uTotal; // total users on the channel
+ unsigned int uActive; // active users in the last 10 mins
+ unsigned int uActiveOp; // active operators in the last 10 minutes
+ unsigned int uHot; // hot active users
+ unsigned int uHotOp; // hot operators
+ unsigned int uOp; // total operators
+ unsigned int uHalfOp; // total halfops
+ unsigned int uVoiced; // total voiced users
+ unsigned int uChanAdmin; // total channel administrators
+ unsigned int uChanOwner; // total channel owners
+ unsigned int uUserOp; // total userops (uops)
+ int iAvgTemperature; // average user temperature
+} KviUserListViewUserStats;
+
+
+class KVIRC_API KviUserListView : public KviWindowToolWidget
+{
+ friend class KviUserListEntry;
+ friend class KviUserListViewArea;
+ friend class KviUserListToolTip;
+ friend class KviConsole;
+ friend class KviChannel;
+ friend class KviQuery;
+ Q_OBJECT
+public:
+ KviUserListView(QWidget * parent,KviWindowToolPageButton* button,KviIrcUserDataBase * db,KviWindow * pWnd,int dictSize = 5,const QString &label_text = QString::null,const char * name = 0);
+ ~KviUserListView();
+protected:
+ KviPointerHashTable<QString,KviUserListEntry> * m_pEntryDict;
+ KviUserListEntry * m_pTopItem;
+ KviUserListEntry * m_pHeadItem;
+ KviUserListEntry * m_pTailItem;
+ KviUserListEntry * m_pIterator;
+ QLabel * m_pUsersLabel;
+ KviUserListViewArea * m_pViewArea;
+ KviIrcUserDataBase * m_pIrcUserDataBase;
+ int m_iSelectedCount;
+ int m_iOpCount;
+ int m_iVoiceCount;
+ int m_iHalfOpCount;
+ int m_iChanAdminCount;
+ int m_iChanOwnerCount;
+ int m_iUserOpCount;
+ int m_iTotalHeight;
+ int m_iFontHeight;
+ KviUserListToolTip * m_pToolTip;
+ int m_ibEntries;
+ int m_ieEntries;
+ int m_iIEntries;
+ KviWindow * m_pKviWindow;
+protected:
+ void maybeTip(KviUserListToolTip * tip,const QPoint &pnt);
+ void triggerUpdate();
+ void updateUsersLabel();
+ void insertUserEntry(const QString &nick,KviUserListEntry * e);
+ void removeAllEntries();
+ virtual void resizeEvent(QResizeEvent *);
+ bool partInternal(const QString &nick,bool bRemove = true);
+ void setUserDataBase(KviIrcUserDataBase * db){ m_pIrcUserDataBase = db; };
+ void updateScrollBarRange();
+public:
+ void updateArea();
+ void select(const QString&);
+ void applyOptions();
+ KviPointerHashTable<QString,KviUserListEntry> * entryDict(){ return m_pEntryDict; };
+ KviUserListEntry * firstItem(){ return m_pHeadItem; };
+ KviUserListEntry * itemAt(const QPoint &pnt,QRect * rct = 0);
+ bool itemVisible(KviUserListEntry * e);
+ KviWindow * window(){ return m_pKviWindow; };
+
+ unsigned int count(){ return m_pEntryDict->count(); };
+ int selectedCount(){ return m_iSelectedCount; };
+ int opCount(){ return m_iOpCount; };
+ int voiceCount(){ return m_iVoiceCount; };
+ int chanOwnerCount(){ return m_iChanOwnerCount; };
+ int chanAdminCount(){ return m_iChanAdminCount; };
+ int halfOpCount(){ return m_iHalfOpCount; };
+ int userOpCount(){ return m_iUserOpCount; };
+
+ KviUserListEntry * findEntry(const QString &nick){ return nick.isEmpty() ? 0 : m_pEntryDict->find(nick); };
+ void appendSelectedNicknames(QString &buffer);
+ QString * firstSelectedNickname();
+ QString * nextSelectedNickname();
+ void partAll();
+ void partAllButOne(const QString &whoNot);
+ void userStats(KviUserListViewUserStats * s);
+ int getUserModeLevel(const QString &nick);
+ kvi_time_t getUserJoinTime(const QString &nick);
+ kvi_time_t getUserLastActionTime(const QString &nick);
+ char getUserFlag(KviUserListEntry * e);
+ char getUserFlag(const QString &nick){ return getUserFlag(m_pEntryDict->find(nick)); };
+ bool part(const QString &nick){ return partInternal(nick,true); };
+ bool op(const QString &nick,bool bOp);
+ void prependUserFlag(const QString &nick,QString &buffer);
+ int flags(const QString &nick);
+ bool isOp(const QString &nick,bool bAtLeast = false);
+ bool isVoice(const QString &nick,bool bAtLeast = false);
+ bool isHalfOp(const QString &nick,bool bAtLeast = false);
+ bool isChanAdmin(const QString &nick,bool bAtLeast = false);
+ bool isChanOwner(const QString &nick,bool bAtLeast = false);
+ bool isUserOp(const QString &nick,bool bAtLeast = false);
+ bool voice(const QString &nick,bool bVoice);
+ bool setChanAdmin(const QString &nick,bool bChanAdmin);
+ bool setChanOwner(const QString &nick,bool bChanOwner);
+ bool halfop(const QString &nick,bool bHalfOp);
+ bool userop(const QString &nick,bool bUserOp);
+ void userAction(KviIrcMask *user,int actionTemperature);
+ bool userActionVerifyMask(const QString &nick,const QString &user,const QString &host,int actionTemperature,QString &oldUser,QString &oldHost);
+ void userAction(const QString &nick,const QString &user,const QString &host,int actionTemperature);
+ void userAction(const QString &nick,int actionTemperature);
+ bool nickChange(const QString &oldNick,const QString &newNick);
+ //KviUserListEntry * join(const char *nick,const char * user,const char * host,bool bOp,bool bVoice,bool bHalfOp);
+ KviUserListEntry * join(const QString &nick,const QString &user = QString::null,const QString &host = QString::null,int iFlags = 0);
+ bool avatarChanged(const QString &nick);
+ void enableUpdates(bool bEnable);
+ void setMaskEntries(char type, int num);
+ void emitRightClick();
+ void emitDoubleClick();
+ bool completeNickStandard(const QString &begin,const QString &skipAfter,QString &buffer,bool bAppendMask);
+ void completeNickBashLike(const QString &begin,KviPointerList<QString> * l,bool bAppendMask);
+};
+
+class KVIRC_API KviUserListViewArea : public QWidget
+{
+ friend class KviUserListView;
+
+ Q_OBJECT
+ Q_PROPERTY(int TransparencyCapable READ dummyRead)
+public:
+ KviUserListViewArea(KviUserListView * par);
+ ~KviUserListViewArea();
+public:
+ int dummyRead() const { return 0; };
+protected:
+ KviUserListView * m_pListView;
+ KviUserListEntry * m_pLastEntryUnderMouse;
+ QScrollBar * m_pScrollBar;
+ int m_iLastScrollBarVal;
+ int m_iTopItemOffset;
+ bool m_bIgnoreScrollBar;
+protected:
+ virtual void paintEvent(QPaintEvent *);
+ virtual void resizeEvent(QResizeEvent *);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void wheelEvent(QWheelEvent *e);
+ virtual void keyPressEvent( QKeyEvent * e );
+protected slots:
+ void scrollBarMoved(int newVal);
+};
+
+
+#endif //!_KVI_USERLISTVIEW_H_
diff --git a/src/kvirc/ui/kvi_window.cpp b/src/kvirc/ui/kvi_window.cpp
new file mode 100644
index 0000000..2cf6408
--- /dev/null
+++ b/src/kvirc/ui/kvi_window.cpp
@@ -0,0 +1,1518 @@
+//=============================================================================
+//
+// File : kvi_window.cpp
+// Creation date : Tue Jul 6 1999 14:52:11 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2007 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#define __KVIRC__
+#define KVI_WINDOW_MIN_WIDTH 100
+#define KVI_WINDOW_MIN_HEIGHT 100
+
+#define _KVI_WINDOW_CPP_
+
+#define _KVI_DEBUG_CHECK_RANGE_
+
+#include "kvi_debug.h"
+#include "kvi_app.h"
+#include "kvi_window.h"
+#include "kvi_frame.h"
+#include "kvi_taskbar.h"
+#include "kvi_iconmanager.h"
+#include "kvi_mdichild.h"
+#include "kvi_locale.h"
+#include "kvi_ircview.h"
+#include "kvi_out.h"
+#include "kvi_malloc.h"
+#include "kvi_input.h"
+#include "kvi_fileutils.h"
+#include "kvi_options.h"
+#include "kvi_config.h"
+#include "kvi_irccontext.h"
+#include "kvi_console.h"
+#include "kvi_ircconnectionserverinfo.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_toolwindows_container.h"
+#include "kvi_styled_controls.h"
+#include "kvi_kvs_script.h"
+
+#include <qpixmap.h>
+#include "kvi_tal_popupmenu.h"
+#include <qcursor.h>
+#include <qtimer.h>
+#include <qsplitter.h>
+#include <qmetaobject.h>
+#include <qdatetime.h>
+#include <qtextcodec.h>
+#include <qevent.h>
+
+// it looks they can't decide :D
+#ifdef COMPILE_USE_QT4
+ #include <QPushButton>
+ #include <qdesktopwidget.h>
+#else
+ #include <qobjectlist.h>
+#endif
+
+
+#include <qvariant.h>
+#include <qtoolbutton.h>
+#include "kvi_tal_tooltip.h"
+#include <qmessagebox.h>
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ #include "kvi_crypt.h"
+ #include "kvi_cryptcontroller.h"
+#endif
+
+#ifdef COMPILE_KDE_SUPPORT
+ #include <kwin.h>
+ #include <kdeversion.h>
+#endif
+
+#ifdef COMPILE_ON_WINDOWS
+ #include <windows.h>
+#endif
+
+KVIRC_API KviWindow * g_pActiveWindow = 0;
+
+static KviTalPopupMenu * g_pMdiWindowSystemMainPopup = 0;
+static KviTalPopupMenu * g_pMdiWindowSystemTextEncodingPopup = 0;
+static KviTalPopupMenu * g_pMdiWindowSystemTextEncodingPopupStandard = 0;
+static KviTalPopupMenu * g_pMdiWindowSystemTextEncodingPopupSmart = 0;
+static KviTalPopupMenu * g_pMdiWindowSystemTextEncodingPopupSmartUtf8 = 0;
+
+unsigned long int g_uUniqueWindowId = 1;
+
+// FIXME: #warning "Mouse wheel support"
+KviWindow::KviWindow(int type,KviFrame * lpFrm,const QString &name,KviConsole * lpConsole)
+ : QWidget(0)
+{
+ m_uId = g_uUniqueWindowId;
+ g_uUniqueWindowId++;
+
+
+ // FIXME: REMOVE THIS
+ setName(name);
+ // END FIXME
+ m_szName = name;
+
+ g_pApp->registerWindow(this);
+
+ m_iType = type;
+ m_pFocusHandler = 0;
+
+ m_pFrm = lpFrm; // FIXME: Should disappear!
+ m_pIrcView = 0;
+ m_pInput = 0;
+ m_pSplitter = 0;
+ m_pButtonBox = 0;
+ m_pConsole = lpConsole;
+ m_pContext = lpConsole ? lpConsole->context() : 0;
+ m_pLastFocusedChild = 0;
+ m_pTextCodec = 0; // will be set by loadProperties
+ m_pTextEncodingButton = 0;
+ m_pHideToolsButton = 0;
+// m_pEditorsContainer = 0;
+
+#ifdef COMPILE_CRYPT_SUPPORT
+
+ m_pCryptControllerButton = 0;
+ m_pCryptController = 0;
+ m_pCryptSessionInfo = 0;
+#endif
+
+ m_pAccel = 0;
+
+ m_pTaskBarItem = 0;
+
+ setMinimumSize(KVI_WINDOW_MIN_WIDTH,KVI_WINDOW_MIN_HEIGHT);
+#ifdef COMPILE_USE_QT4
+ //setAutoFillBackground(false);
+ setFocusPolicy(Qt::StrongFocus);
+#else
+ setBackgroundMode(NoBackground);
+ setFocusPolicy(StrongFocus);
+#endif
+
+ connect(g_pApp,SIGNAL(reloadImages()),this,SLOT(reloadImages()));
+}
+
+KviWindow::~KviWindow()
+{
+ //g_pFrame->childWindowDestroyed(this);
+ destroyTaskBarItem();
+ g_pApp->unregisterWindow(this);
+ if(g_pApp->windowCount() == 0)
+ {
+ // this is the last window!
+ if(g_pMdiWindowSystemMainPopup)
+ delete g_pMdiWindowSystemMainPopup;
+ if(g_pMdiWindowSystemTextEncodingPopup)
+ delete g_pMdiWindowSystemTextEncodingPopup;
+ if(g_pMdiWindowSystemTextEncodingPopupStandard)
+ delete g_pMdiWindowSystemTextEncodingPopupStandard;
+ if(g_pMdiWindowSystemTextEncodingPopupSmart)
+ delete g_pMdiWindowSystemTextEncodingPopupSmart;
+ if(g_pMdiWindowSystemTextEncodingPopupSmartUtf8)
+ delete g_pMdiWindowSystemTextEncodingPopupSmartUtf8;
+ }
+#ifdef COMPILE_CRYPT_SUPPORT
+ if(m_pCryptSessionInfo)
+ KviCryptController::destroyCryptSessionInfo(&m_pCryptSessionInfo);
+#endif
+}
+
+void KviWindow::setWindowName(const QString &szName)
+{
+ m_szName = szName;
+ emit windowNameChanged();
+}
+
+void KviWindow::toggleButtonContainer()
+{
+ QFrame *pContainer=buttonContainer();
+ if(pContainer)
+ {
+ pContainer->setHidden(!pContainer->isHidden());
+ }
+}
+
+void KviWindow::setName(const char * name)
+{
+ m_szName = name;
+ QWidget::setName(name);
+}
+
+KviIrcConnection * KviWindow::connection()
+{
+ return m_pContext ? m_pContext->connection() : 0;
+}
+
+void KviWindow::reloadImages()
+{
+ updateIcon();
+}
+
+bool KviWindow::hasAttention()
+{
+ if(((QApplication *)g_pApp)->activeWindow() == 0)return false; // no application window has the focus atm
+
+ if(mdiParent())
+ {
+ if(frame()->isActiveWindow())return true;
+ // This frame is not the active window but the
+ // active window still belongs to KVIrc.
+ // When the active window is derived from QDialog
+ // then it is probably a KVIrc's option dialog
+ // or something similar.
+ // In this case we assume that the user has the
+ // KVIrc window just below and can see it.
+
+ // Handle the special case of the dialogs then
+ QWidget * w = ((QApplication *)g_pApp)->activeWindow();
+ if(w->inherits("QDialog"))
+ {
+ // but make sure that the frame is visible at all!
+ if(!frame()->isVisible())return false;
+ return true;
+ }
+ // any other class is so unfrequent that we ignore it
+ } else {
+ // when the window is undocked, instead
+ // it is likely to be covered by KVIrc or other windows...
+ if(isActiveWindow())return true;
+ }
+ return false;
+}
+
+void KviWindow::demandAttention()
+{
+ if(mdiParent())
+ {
+ if(frame()->isActiveWindow())return;
+#ifdef COMPILE_ON_WINDOWS
+ FLASHWINFO fwi;
+ fwi.cbSize = sizeof(fwi);
+ fwi.hwnd = (HWND)(frame()->winId());
+ fwi.dwFlags = FLASHW_TRAY | FLASHW_TIMERNOFG;
+ fwi.uCount = 20;
+ fwi.dwTimeout = 500;
+ FlashWindowEx(&fwi);
+#else
+ #ifdef COMPILE_KDE_SUPPORT
+ #if (KDE_VERSION_MAJOR >= 3) && (KDE_VERSION_MINOR >= 2)
+ KWin::demandAttention(frame()->winId(),true);
+ #endif
+ #endif
+#endif
+ } else {
+ if(isActiveWindow())return;
+#ifdef COMPILE_ON_WINDOWS
+ FLASHWINFO fwi;
+ fwi.cbSize = sizeof(fwi);
+ fwi.hwnd = (HWND)winId();
+ fwi.dwFlags = FLASHW_TRAY | FLASHW_TIMERNOFG;
+ fwi.uCount = 20;
+ fwi.dwTimeout = 500;
+ FlashWindowEx(&fwi);
+#else
+ #ifdef COMPILE_KDE_SUPPORT
+ #if (KDE_VERSION_MAJOR >= 3) && (KDE_VERSION_MINOR >= 2)
+ KWin::demandAttention(winId(),true);
+ #endif
+ #endif
+#endif
+ }
+}
+
+bool KviWindow::focusNextPrevChild(bool next)
+{
+ QWidget * w = focusWidget();
+ if(w)
+ {
+#ifdef COMPILE_USE_QT4
+ if(w->focusPolicy() == Qt::StrongFocus)return false;
+#else
+ if(w->focusPolicy() == QWidget::StrongFocus)return false;
+#endif
+ //QVariant v = w->property("KviProperty_FocusOwner");
+ //if(v.isValid())return false; // Do NOT change the focus widget!
+
+ if(w->parent())
+ {
+#ifdef COMPILE_USE_QT4
+ if(w->parent()->metaObject()->indexOfProperty("KviProperty_ChildFocusOwner") == -1)
+#else
+ if(w->parent()->metaObject()->findProperty("KviProperty_ChildFocusOwner") == -1)
+#endif
+ return false; // Do NOT change the focus widget!
+ }
+ }
+
+ return QWidget::focusNextPrevChild(next);
+}
+
+void KviWindow::forceTextCodec(QTextCodec * c)
+{
+ if(!c)return;
+ m_pTextCodec = c;
+ QTextCodec * dc = defaultTextCodec();
+ if(dc != c)
+ m_szTextEncoding = c->name();
+ else
+ m_szTextEncoding = ""; // this is the default anyway
+}
+
+bool KviWindow::setTextEncoding(const QString &szTextEncoding)
+{
+ if(!szTextEncoding.isEmpty())
+ {
+ m_pTextCodec = KviLocale::codecForName(szTextEncoding.latin1());
+ if(m_pTextCodec)
+ {
+ m_szTextEncoding = szTextEncoding;
+ return true;
+ }
+ // this is an error because we specified an encoding
+ // and we couldn't find a codec for this
+ } // else it is empty : this means : guess from locale
+ // either empty or not found...
+ m_pTextCodec = 0;
+ m_szTextEncoding = ""; // empty: we're using the default
+ return false;
+}
+
+QTextCodec * KviWindow::defaultTextCodec()
+{
+ // if we have a connection try to inherit from there...
+ if(connection())
+ {
+ QTextCodec * c = connection()->textCodec();
+ if(c)return c;
+ }
+ return KviApp::defaultTextCodec();
+}
+
+KviQCString KviWindow::encodeText(const QString &szText)
+{
+ if(!m_pTextCodec)return defaultTextCodec()->fromUnicode(szText);
+ return m_pTextCodec->fromUnicode(szText);
+}
+
+QString KviWindow::decodeText(const char * szText)
+{
+ if(!m_pTextCodec)return defaultTextCodec()->toUnicode(szText);
+ return m_pTextCodec->toUnicode(szText);
+}
+
+bool KviWindow::activityMeter(unsigned int *,unsigned int *)
+{
+ return false;
+}
+
+
+const char * KviWindow::m_typeTable[KVI_WINDOW_NUM_TYPES + 1]=
+{
+ "console",
+ "channel",
+ "query",
+ "help",
+ "terminal",
+ "editor",
+ "dccchat",
+ "dccsend",
+ "socketspy",
+ "links",
+ "tool",
+ "gnutella",
+ "dirbrowser",
+ "dcccanvas",
+ "dccvoice",
+ "list",
+ "offer",
+ "logview",
+ "deadchannel",
+ "deadquery",
+ "scripteditor",
+ "scriptobject",
+ "userwindow",
+ "debug",
+ // <------ NEW TYPES GO HERE!
+ "unknown"
+};
+
+const char * KviWindow::typeString()
+{
+ if(m_iType < KVI_WINDOW_NUM_TYPES)
+ {
+ return m_typeTable[m_iType];
+ }
+ return m_typeTable[KVI_WINDOW_NUM_TYPES];
+}
+
+void KviWindow::setType(int iType)
+{
+ m_iType = iType;
+}
+
+
+void KviWindow::createTaskBarItem()
+{
+ if(m_pTaskBarItem)return;
+ m_pTaskBarItem = g_pFrame->m_pTaskBar->addItem(this);
+}
+
+void KviWindow::destroyTaskBarItem()
+{
+ if(!m_pTaskBarItem)return;
+ g_pFrame->m_pTaskBar->removeItem(m_pTaskBarItem);
+ // m_pTaskBarItem = 0; // actually the taskBarItem destructor sets it
+}
+
+BUTTON_CLASS * KviWindow::createToolButton(QWidget * par,const char * nam,int pixon,int pixoff,const QString & tooltip,bool bOn)
+{
+#ifdef COMPILE_USE_QT4
+ BUTTON_CLASS * b = new BUTTON_CLASS(par);
+ b->setObjectName(nam);
+ b->setFlat(true);
+ b->setIcon(QIcon(*(g_pIconManager->getSmallIcon(pixon))));
+#else
+ BUTTON_CLASS * b = new BUTTON_CLASS(par,nam);
+ b->setToggleButton(true);
+ b->setUsesBigPixmap(false);
+ QIconSet is1;
+ is1.setPixmap(*(g_pIconManager->getSmallIcon(pixon)),QIconSet::Small,QIconSet::Normal,QIconSet::On);
+ is1.setPixmap(*(g_pIconManager->getSmallIcon(pixoff)),QIconSet::Small,QIconSet::Normal,QIconSet::Off);
+ b->setIconSet(is1);
+#endif
+
+
+ KviTalToolTip::add
+ (b,tooltip);
+ b->setOn(bOn);
+ return b;
+}
+
+// This is always defined...
+void KviWindow::createCryptControllerButton(QWidget * par)
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ m_pCryptControllerButton = new KviWindowToolPageButton(KVI_SMALLICON_UNLOCKEDOFF,KVI_SMALLICON_UNLOCKED,__tr2qs("Crypting"),buttonContainer(),false,"crypt_controller_button");
+ connect(m_pCryptControllerButton,SIGNAL(clicked()),this,SLOT(toggleCryptController()));
+#endif // COMPILE_CRYPT_SUPPORT
+}
+
+void KviWindow::createTextEncodingButton(QWidget * par)
+{
+ if(m_pTextEncodingButton)delete m_pTextEncodingButton;
+ m_pTextEncodingButton = createToolButton(par,"text_encoding_button",KVI_SMALLICON_TEXTENCODING,KVI_SMALLICON_TEXTENCODING,__tr2qs("Private Text Encoding"),false);
+ connect(m_pTextEncodingButton,SIGNAL(clicked()),this,SLOT(textEncodingButtonClicked()));
+}
+
+void KviWindow::textEncodingButtonClicked()
+{
+ createSystemTextEncodingPopup();
+ g_pMdiWindowSystemTextEncodingPopup->popup(m_pTextEncodingButton->mapToGlobal(QPoint(0,m_pTextEncodingButton->height())));
+ m_pTextEncodingButton->setOn(false);
+}
+
+const QString & KviWindow::lastLineOfText()
+{
+ if(m_pIrcView)
+ return m_pIrcView->lastLineOfText();
+ return KviQString::empty;
+}
+
+const QString & KviWindow::lastMessageText()
+{
+ if(m_pIrcView)
+ return m_pIrcView->lastMessageText();
+ return KviQString::empty;
+}
+
+// The following three have to be here even if the crypt support is disabled...moc does not support conditional compilations
+void KviWindow::toggleCryptController()
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ if(!m_pCryptControllerButton->isOn())
+ {
+ if(m_pCryptController)
+ {
+ delete m_pCryptController;
+ m_pCryptController = 0;
+ if(!m_pCryptControllerButton)
+ return;
+ if(m_pCryptControllerButton->isOn())
+ m_pCryptControllerButton->setOn(false);
+ }
+ } else {
+ if(m_pSplitter && m_pInput)
+ {
+ m_pCryptController = new KviCryptController(m_pSplitter,m_pCryptControllerButton,"crypt_controller",this,m_pCryptSessionInfo);
+ connect(m_pCryptController,SIGNAL(done()),this,SLOT(cryptControllerFinished()));
+ //setFocusHandlerNoClass(m_pInput,m_pCryptController,"QLineEdit"); //link it!
+ m_pCryptController->show();
+ if(!m_pCryptControllerButton)
+ return;
+ if(!(m_pCryptControllerButton->isOn()))
+ m_pCryptControllerButton->setOn(true);
+ }
+ }
+#endif // COMPILE_CRYPT_SUPPORT
+}
+
+#ifdef COMPILE_CRYPT_SUPPORT
+void KviWindow::setCryptSessionInfo(KviCryptSessionInfo * inf)
+{
+ if(m_pCryptSessionInfo)
+ KviCryptController::destroyCryptSessionInfo(&m_pCryptSessionInfo);
+ m_pCryptSessionInfo = inf;
+ if(m_pCryptSessionInfo)
+ {
+ connect(m_pCryptSessionInfo->pEngine,SIGNAL(destroyed()),this,SLOT(cryptSessionInfoDestroyed()));
+ }
+ if(m_pCryptControllerButton)
+ {
+#if QT_VERSION >= 300
+ QIconSet is;
+ is.setPixmap(*(g_pIconManager->getSmallIcon(m_pCryptSessionInfo ? KVI_SMALLICON_LOCKEDOFF : KVI_SMALLICON_UNLOCKEDOFF)),QIconSet::Small,QIconSet::Normal,QIconSet::Off);
+ is.setPixmap(*(g_pIconManager->getSmallIcon(m_pCryptSessionInfo ? KVI_SMALLICON_LOCKED : KVI_SMALLICON_UNLOCKED)),QIconSet::Small,QIconSet::Normal,QIconSet::On);
+ m_pCryptControllerButton->setIconSet(is);
+#else
+
+ m_pCryptControllerButton->setOnIconSet(
+ *(g_pIconManager->getSmallIcon(m_pCryptSessionInfo ? KVI_SMALLICON_LOCKEDOFF : KVI_SMALLICON_UNLOCKEDOFF)));
+ m_pCryptControllerButton->setOffIconSet(
+ *(g_pIconManager->getSmallIcon(m_pCryptSessionInfo ? KVI_SMALLICON_LOCKED : KVI_SMALLICON_UNLOCKED)));
+#endif
+
+ if(m_pCryptControllerButton->isOn())
+ m_pCryptControllerButton->setOn(false);
+ }
+}
+#endif // COMPILE_CRYPT_SUPPORT
+
+void KviWindow::cryptControllerFinished()
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ KviCryptSessionInfo * inf = m_pCryptController->getNewSessionInfo();
+ setCryptSessionInfo(inf);
+ delete m_pCryptController;
+ m_pCryptController = 0;
+#endif
+}
+
+void KviWindow::cryptSessionInfoDestroyed()
+{
+#ifdef COMPILE_CRYPT_SUPPORT
+ output(KVI_OUT_SYSTEMERROR,__tr2qs("Ops...I've accidentally lost the crypting engine..."));
+ m_pCryptSessionInfo->pEngine = 0;
+ delete m_pCryptSessionInfo;
+ m_pCryptSessionInfo = 0;
+#endif
+}
+
+
+
+void KviWindow::setProgress(int progress)
+{
+ m_pTaskBarItem->setProgress(progress);
+}
+
+void KviWindow::listWindowTypes()
+{
+ outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("List of window types available in this release of KVIrc:"));
+ for(int i=0;i< KVI_WINDOW_NUM_TYPES;i++)
+ outputNoFmt(KVI_OUT_SYSTEMMESSAGE,m_typeTable[i]);
+}
+
+void KviWindow::getConfigGroupName(QString &buf)
+{
+ buf = typeString();
+}
+
+
+void KviWindow::getDefaultLogFileName(QString &buffer)
+{
+ // FIXME: #warning "Make it configurable ?"
+ QString date;
+ QDate dt(QDate::currentDate());
+ date=dt.toString("yyyy.MM.dd");
+ QString base;
+ getBaseLogFileName(base);
+ kvi_encodeFileName(base);
+ base.replace("%%2e","%2e");
+ base=base.lower();
+ QString tmp;
+ if(KVI_OPTION_BOOL(KviOption_boolGzipLogs))
+ KviQString::sprintf(tmp,"%s_%s_%s.log.gz",typeString(),base.utf8().data(),date.utf8().data());
+ else
+ KviQString::sprintf(tmp,"%s_%s_%s.log",typeString(),base.utf8().data(),date.utf8().data());
+ g_pApp->getLocalKvircDirectory(buffer,KviApp::Log,tmp);
+}
+
+/*void KviWindow::getBaseLogFileName(KviStr &buffer)
+{
+ buffer = m_szName;
+}*/
+
+void KviWindow::getBaseLogFileName(QString &buffer)
+{
+ buffer = m_szName;
+}
+
+
+void KviWindow::saveProperties(KviConfig *cfg)
+{
+ // store only the non-default text encoding.
+ QString szCodec = m_szTextEncoding;
+ QTextCodec * c = defaultTextCodec();
+ if(c && m_pTextCodec)
+ {
+#ifdef COMPILE_USE_QT4
+ if(KviQString::equalCI(szCodec,c->name().data()))szCodec = KviQString::empty; // store "default"
+#else
+ if(KviQString::equalCI(szCodec,c->name()))szCodec = KviQString::empty; // store "default"
+#endif
+ }
+ QString szKey = "TextEncoding_";
+ szKey += m_szName;
+ cfg->writeEntry(szKey,szCodec);
+ if(m_pInput) {
+ cfg->writeEntry("inputToolButtonsHidden",m_pInput->isButtonsHidden());
+ cfg->writeEntry("commandLineIsUserFriendly",m_pInput->isUserFriendly());
+ }
+
+ //
+
+ /*if(m_pIrcView && m_iType==KVI_WINDOW_TYPE_CHANNEL)
+ if(m_pIrcView->isLogging())
+ cfg->writeEntry("LoggingEnabled",m_pIrcView->isLogging());*/
+}
+
+void KviWindow::loadProperties(KviConfig *cfg)
+{
+ QString szKey = "TextEncoding_";
+ szKey += m_szName;
+ setTextEncoding(cfg->readQStringEntry(szKey,KviQString::empty).utf8().data());
+ if(m_pInput) {
+ m_pInput->setButtonsHidden(cfg->readBoolEntry("inputToolButtonsHidden",KVI_OPTION_BOOL(KviOption_boolHideInputToolButtons)));
+ m_pInput->setUserFriendly(cfg->readBoolEntry("commandLineIsUserFriendly",KVI_OPTION_BOOL(KviOption_boolCommandlineInUserFriendlyModeByDefault)));
+ }
+/* if(m_pIrcView && m_iType==KVI_WINDOW_TYPE_CHANNEL)
+ {
+ bool bEnableLogs=cfg->readBoolEntry("LoggingEnabled",0);
+ if(!m_pIrcView->isLogging() && bEnableLogs)
+ {
+ QString szTmp;
+ getBaseLogFileName(szTmp);
+ m_pIrcView->startLogging();
+ }
+ }*/
+}
+
+QPixmap * KviWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_DEFAULTICON);
+}
+
+void KviWindow::getTaskBarTipText(QString &buffer)
+{
+ buffer = m_szPlainTextCaption;
+}
+
+void KviWindow::setFixedCaption(const QString &szCaption)
+{
+ m_szPlainTextCaption = szCaption;
+}
+
+void KviWindow::fillCaptionBuffers()
+{
+ QString szCaption = m_szPlainTextCaption;
+ if(szCaption.isEmpty())
+ szCaption = m_szName;
+
+ fillSingleColorCaptionBuffers(szCaption);
+}
+
+void KviWindow::fillSingleColorCaptionBuffers(const QString &szName)
+{
+ static QString p1("<nobr><font color=\"");
+ static QString p2("\"><b>");
+ static QString p3("</b></font></nobr>");
+
+ m_szPlainTextCaption = szName;
+
+ m_szHtmlActiveCaption = p1;
+ m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name();
+ m_szHtmlActiveCaption += p2;
+ m_szHtmlActiveCaption += szName;
+ m_szHtmlActiveCaption += p3;
+
+ m_szHtmlInactiveCaption = p1;
+ m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name();
+ m_szHtmlInactiveCaption += p2;
+ m_szHtmlInactiveCaption += szName;
+ m_szHtmlInactiveCaption += p3;
+}
+
+void KviWindow::updateCaption()
+{
+ fillCaptionBuffers();
+ if(mdiParent())
+ mdiParent()->setCaption(plainTextCaption(),htmlActiveCaption(),htmlInactiveCaption());
+ else
+ setCaption(plainTextCaption());
+ if(m_pTaskBarItem)m_pTaskBarItem->captionChanged();
+ if(mdiParent() && isMaximized() && (g_pActiveWindow == this))
+ g_pFrame->updateCaption();
+}
+
+void KviWindow::createSystemTextEncodingPopup()
+{
+ if(!g_pMdiWindowSystemTextEncodingPopup)
+ g_pMdiWindowSystemTextEncodingPopup = new KviTalPopupMenu();
+ else
+ {
+ g_pMdiWindowSystemTextEncodingPopup->clear();
+ }
+
+ if(!g_pMdiWindowSystemTextEncodingPopupStandard)
+ g_pMdiWindowSystemTextEncodingPopupStandard = new KviTalPopupMenu();
+ else
+ {
+ g_pMdiWindowSystemTextEncodingPopupStandard->clear();
+ disconnect(g_pMdiWindowSystemTextEncodingPopupStandard,SIGNAL(activated(int)),0,0);
+ }
+
+ if(!g_pMdiWindowSystemTextEncodingPopupSmart)
+ g_pMdiWindowSystemTextEncodingPopupSmart = new KviTalPopupMenu();
+ else
+ {
+ g_pMdiWindowSystemTextEncodingPopupSmart->clear();
+ disconnect(g_pMdiWindowSystemTextEncodingPopupSmart,SIGNAL(activated(int)),0,0);
+ }
+
+ if(!g_pMdiWindowSystemTextEncodingPopupSmartUtf8)
+ g_pMdiWindowSystemTextEncodingPopupSmartUtf8 = new KviTalPopupMenu();
+ else
+ {
+ g_pMdiWindowSystemTextEncodingPopupSmartUtf8->clear();
+ disconnect(g_pMdiWindowSystemTextEncodingPopupSmartUtf8,SIGNAL(activated(int)),0,0);
+ }
+
+ QTextCodec * c = defaultTextCodec();
+ QString tmp = __tr2qs("Use Default Encoding");
+ if(c)
+ {
+ tmp += " (";
+ tmp += c->name();
+ tmp += ")";
+ }
+
+ int id = g_pMdiWindowSystemTextEncodingPopup->insertItem(tmp,this,SLOT(systemTextEncodingPopupDefault()));
+ if(m_szTextEncoding.isEmpty())g_pMdiWindowSystemTextEncodingPopup->setItemChecked(id,true);
+ g_pMdiWindowSystemTextEncodingPopup->insertSeparator();
+
+ g_pMdiWindowSystemTextEncodingPopup->insertItem(__tr2qs("Standard"),g_pMdiWindowSystemTextEncodingPopupStandard);
+ g_pMdiWindowSystemTextEncodingPopup->insertItem(__tr2qs("Smart (Send Local)"),g_pMdiWindowSystemTextEncodingPopupSmart);
+ g_pMdiWindowSystemTextEncodingPopup->insertItem(__tr2qs("Smart (Send UTF-8)"),g_pMdiWindowSystemTextEncodingPopupSmartUtf8);
+
+ int i = 0;
+ KviLocale::EncodingDescription * d = KviLocale::encodingDescription(i);
+ while(d->szName)
+ {
+ KviQString::sprintf(tmp,"%s (%s)",d->szName,d->szDescription);
+ KviTalPopupMenu * ppp = d->bSmart ? (d->bSendUtf8 ? g_pMdiWindowSystemTextEncodingPopupSmartUtf8 : g_pMdiWindowSystemTextEncodingPopupSmart) : g_pMdiWindowSystemTextEncodingPopupStandard;
+ id = ppp->insertItem(tmp);
+ if(KviQString::equalCI(m_szTextEncoding,d->szName))
+ ppp->setItemChecked(id,true);
+ i = i + 1;
+ d = KviLocale::encodingDescription(i);
+ }
+
+ connect(g_pMdiWindowSystemTextEncodingPopupSmart,SIGNAL(activated(int)),this,SLOT(systemTextEncodingPopupSmartActivated(int)));
+ connect(g_pMdiWindowSystemTextEncodingPopupSmartUtf8,SIGNAL(activated(int)),this,SLOT(systemTextEncodingPopupSmartUtf8Activated(int)));
+ connect(g_pMdiWindowSystemTextEncodingPopupStandard,SIGNAL(activated(int)),this,SLOT(systemTextEncodingPopupStandardActivated(int)));
+}
+
+
+void KviWindow::systemPopupRequest(const QPoint &pnt)
+{
+ if(!g_pMdiWindowSystemMainPopup)
+ g_pMdiWindowSystemMainPopup = new KviTalPopupMenu();
+ else
+ {
+ g_pMdiWindowSystemMainPopup->clear();
+ g_pMdiWindowSystemMainPopup->disconnect();
+ }
+
+ if(mdiParent())
+ g_pMdiWindowSystemMainPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_UNDOCK)),
+ __tr2qs("&Undock"),this,SLOT(undock()));
+ else
+ g_pMdiWindowSystemMainPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DOCK)),
+ __tr2qs("&Dock"),this,SLOT(dock()));
+
+ g_pMdiWindowSystemMainPopup->insertSeparator();
+
+ int id = g_pMdiWindowSystemMainPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINIMIZE)),
+ __tr2qs("Mi&nimize"),this,SLOT(minimize()));
+ g_pMdiWindowSystemMainPopup->setItemEnabled(id,!isMinimized());
+ id = g_pMdiWindowSystemMainPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MAXIMIZE)),
+ __tr2qs("Ma&ximize"),this,SLOT(maximize()));
+ g_pMdiWindowSystemMainPopup->setItemEnabled(id,!isMaximized());
+ id = g_pMdiWindowSystemMainPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RESTORE)),
+ __tr2qs("&Restore"),this,SLOT(restore()));
+ g_pMdiWindowSystemMainPopup->setItemEnabled(id,isMinimized()||isMaximized());
+
+ g_pMdiWindowSystemMainPopup->insertSeparator();
+
+ g_pMdiWindowSystemMainPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)),
+ __tr2qs("Close"),this,SLOT(close()));
+
+ g_pMdiWindowSystemMainPopup->insertSeparator();
+
+ if(m_pTextEncodingButton)
+ {
+ createSystemTextEncodingPopup();
+ g_pMdiWindowSystemMainPopup->insertItem(__tr2qs("Text &Encoding"),g_pMdiWindowSystemTextEncodingPopup);
+ } // else we don't support setting private encoding anyway
+
+
+ g_pMdiWindowSystemMainPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_XY)),
+ __tr2qs("Sa&ve Window Properties"),this,SLOT(savePropertiesAsDefault()));
+
+ fillContextPopup(g_pMdiWindowSystemMainPopup);
+
+ g_pMdiWindowSystemMainPopup->popup(pnt);
+}
+
+void KviWindow::systemTextEncodingPopupDefault()
+{
+ // default
+ setTextEncoding("");
+}
+
+void KviWindow::systemTextEncodingPopupSmartActivated(int id)
+{
+ if(!g_pMdiWindowSystemTextEncodingPopupSmart)
+ return;
+ QString tmp = g_pMdiWindowSystemTextEncodingPopupSmart->text(id);
+ KviQString::cutFromFirst(tmp," (");
+ setTextEncoding(tmp);
+}
+
+void KviWindow::systemTextEncodingPopupSmartUtf8Activated(int id)
+{
+ if(!g_pMdiWindowSystemTextEncodingPopupSmartUtf8)
+ return;
+ QString tmp = g_pMdiWindowSystemTextEncodingPopupSmartUtf8->text(id);
+ KviQString::cutFromFirst(tmp," (");
+ setTextEncoding(tmp);
+}
+
+void KviWindow::systemTextEncodingPopupStandardActivated(int id)
+{
+ if(!g_pMdiWindowSystemTextEncodingPopupStandard)
+ return;
+ QString tmp = g_pMdiWindowSystemTextEncodingPopupStandard->text(id);
+ KviQString::cutFromFirst(tmp," (");
+ setTextEncoding(tmp);
+}
+
+void KviWindow::savePropertiesAsDefault()
+{
+ QString group;
+ getConfigGroupName(group);
+
+ if(!kvi_strEqualCI(group,typeString()))
+ {
+ // save also the settings for THIS specialized window
+ g_pFrame->saveWindowProperties(this,group);
+ }
+
+ g_pFrame->saveWindowProperties(this,typeString());
+}
+
+void KviWindow::contextPopup()
+{
+ systemPopupRequest(QCursor::pos());
+}
+
+void KviWindow::fillContextPopup(KviTalPopupMenu *)
+{
+ // nothing here
+}
+
+void KviWindow::undock()
+{
+ g_pFrame->undockWindow(this);
+}
+
+void KviWindow::dock()
+{
+ g_pFrame->dockWindow(this);
+}
+
+void KviWindow::delayedAutoRaise()
+{
+ QTimer::singleShot(0,this,SLOT(autoRaise()));
+}
+
+void KviWindow::autoRaise()
+{
+ if(!mdiParent())
+ {
+ raise();
+ setActiveWindow();
+ }
+ if(m_pFocusHandler)
+ m_pFocusHandler->setFocus();
+ else
+ setFocus();
+}
+
+void KviWindow::delayedClose()
+{
+ QTimer::singleShot(0,this,SLOT(close()));
+}
+
+void KviWindow::closeEvent(QCloseEvent *e)
+{
+ e->ignore();
+ g_pFrame->childWindowCloseRequest(this);
+}
+
+void KviWindow::updateIcon()
+{
+ if(parent())
+ {
+ ((KviMdiChild *)parent())->setIcon(*myIconPtr());
+ } else {
+ setIcon(*myIconPtr());
+ }
+}
+
+void KviWindow::youAreDocked()
+{
+ if(m_pAccel)
+ {
+ delete m_pAccel;
+ m_pAccel = 0;
+ }
+ ((KviMdiChild *)parent())->setIcon(*myIconPtr());
+ updateCaption();
+ connect(((KviMdiChild *)parent()),SIGNAL(systemPopupRequest(const QPoint &)),this,SLOT(systemPopupRequest(const QPoint &)));
+}
+
+void KviWindow::youAreUndocked()
+{
+ m_pAccel = g_pFrame->installAccelerators(this);
+ setIcon(*myIconPtr());
+ updateCaption();
+}
+
+#ifdef FocusIn
+// Hack for X.h
+#undef FocusIn
+#endif
+
+void KviWindow::activateSelf()
+{
+ if(mdiParent())
+ mdiParent()->activate(false);
+
+ g_pFrame->childWindowActivated(this);
+ // this is now done by KviFrame in childWindowActivated
+ //g_pFrame->m_pTaskBar->setActiveItem(m_pTaskBarItem);
+}
+
+void KviWindow::setFocus()
+{
+ // don't trigger the whole Qt focus mechanism..
+ // just trigger directly our focusInEvent
+ // so we'll redirect the focus to the m_pFocusHandler
+ focusInEvent(0);
+}
+
+void KviWindow::focusInEvent(QFocusEvent *)
+{
+ if(m_pLastFocusedChild)
+ {
+ if(m_pLastFocusedChild->hasFocus() && m_pLastFocusedChild->isVisible())
+ {
+ // the last focused child still has focus (ehm ???)
+ if(g_pActiveWindow != this)activateSelf();
+ return;
+ }
+ }
+
+ if(!m_pFocusHandler)
+ {
+ // must find one NOW
+ // we probably have no KviInput since it would have been grabbed anyway
+
+ if(m_pIrcView)m_pFocusHandler = m_pIrcView;
+ else {
+#ifdef COMPILE_USE_QT4
+ QList<QObject *> list = children();
+ for(QList<QObject *>::Iterator it = list.begin();it != list.end();++it)
+ {
+ QObject * c = *it;
+ if(c->isWidgetType())
+ {
+ m_pFocusHandler = (QWidget *)c;
+ break;
+ }
+ }
+#else
+ QObjectList *list = (QObjectList *)(children());
+ if(list)
+ {
+ for(QObject * c = list->first();c;c = list->next())
+ {
+ if(c->isWidgetType())
+ {
+ m_pFocusHandler = (QWidget *)c;
+ break;
+ }
+ }
+ }
+#endif
+ }
+ if(m_pFocusHandler)m_pFocusHandler->setFocus();
+ else {
+ // else too bad :/
+ debug("No widget able to handle focus for window %s",name());
+ return;
+ }
+ } else {
+ m_pFocusHandler->setFocus();
+ }
+
+ // Setting the focus to the focus handler usually
+ // triggers our filter for the children's focusInEvent.
+ // This should call activateSelf() and thus
+ // we should be already the active window at this point.
+ // If we're not, then run activateSelf() to fix this.
+ if(g_pActiveWindow != this)activateSelf();
+ //else debug("ACTIVE WINDOW IS ALREADY THIS");
+ updateCaption();
+}
+
+bool KviWindow::eventFilter(QObject *o,QEvent *e)
+{
+ switch(e->type())
+ {
+ case QEvent::FocusIn:
+ m_pLastFocusedChild = (QWidget *)o;
+ if(g_pActiveWindow != this)activateSelf();
+ break;
+ case QEvent::Enter:
+ // this is a handler moved here from KviMdiChild::eventFilter
+ if(QApplication::overrideCursor())
+ QApplication::restoreOverrideCursor();
+ break;
+ case QEvent::MouseButtonPress:
+#ifdef COMPILE_USE_QT4
+ if( (((QWidget *)o)->focusPolicy() == Qt::NoFocus) ||
+ (((QWidget *)o)->focusPolicy() == Qt::TabFocus))
+#else
+ if( (((QWidget *)o)->focusPolicy() == QWidget::NoFocus) ||
+ (((QWidget *)o)->focusPolicy() == QWidget::TabFocus))
+#endif
+ {
+ // this will not focus our window
+ // set the focus to the focus handler
+ if(m_pLastFocusedChild)
+ {
+ if(m_pLastFocusedChild->hasFocus() && m_pLastFocusedChild->isVisible())
+ return false;
+ }
+
+ if(m_pFocusHandler)
+ {
+ m_pFocusHandler->setFocus();
+ } else {
+ setFocus(); // we grab the focus (someone must do it , damn :D)
+ }
+ }
+ break;
+ case QEvent::ChildInserted:
+ if(((QChildEvent *)e)->child()->isWidgetType())
+ childInserted((QWidget *)((QChildEvent *)e)->child());
+ break;
+ case QEvent::ChildRemoved:
+ if(((QChildEvent *)e)->child()->isWidgetType())
+ childRemoved((QWidget *)((QChildEvent *)e)->child());
+ break;
+ default: /* make gcc happy */ break;
+ }
+ return false;
+}
+
+
+void KviWindow::childInserted(QWidget * o)
+{
+ o->removeEventFilter(this); // ensure that we don't filter twice
+ o->installEventFilter(this); // we filter its events
+ connect(o,SIGNAL(destroyed()),this,SLOT(childDestroyed()));
+
+ if(o->inherits("KviInput"))
+ m_pFocusHandler = o;
+ else
+ {
+#ifdef COMPILE_USE_QT4
+ if(!m_pFocusHandler && (o->focusPolicy() == Qt::StrongFocus))
+#else
+ if(!m_pFocusHandler && (o->focusPolicy() == QWidget::StrongFocus))
+#endif
+ {
+ m_pFocusHandler = o;
+ }
+ }
+
+#ifdef COMPILE_USE_QT4
+ QList<QObject *> list = o->children();
+ for(QList<QObject *>::Iterator it = list.begin();it != list.end();++it)
+ {
+ QObject * c = *it;
+ if(c->isWidgetType())
+ {
+ childInserted((QWidget *)c);
+ }
+ }
+#else
+ QObjectList *list = (QObjectList *)(o->children());
+ if(list)
+ {
+ for(QObject * c = list->first();c;c = list->next())
+ {
+ if(c->isWidgetType())
+ childInserted((QWidget *)c);
+ }
+ }
+#endif
+}
+
+void KviWindow::childDestroyed()
+{
+ QWidget * s = (QWidget *)sender();
+ childRemoved(s);
+}
+
+void KviWindow::childRemoved(QWidget * o)
+{
+ //debug("CHILD REMOVED %d",o);
+ o->removeEventFilter(this);
+ if(o == m_pFocusHandler)
+ m_pFocusHandler = 0;
+ if(o == m_pLastFocusedChild)
+ m_pLastFocusedChild = 0;
+
+#ifdef COMPILE_USE_QT4
+ QList<QObject *> list = o->children();
+ for(QList<QObject *>::Iterator it = list.begin();it != list.end();++it)
+ {
+ QObject * c = *it;
+ if(c->isWidgetType())
+ {
+ childRemoved((QWidget *)c);
+ }
+ }
+#else
+ QObjectList *list = (QObjectList *)(o->children());
+ if(list)
+ {
+ for(QObject * c = list->first();c;c = list->next())
+ {
+ if(c->isWidgetType())
+ childRemoved((QWidget *)c);
+ }
+ } //else debug("The removed object has no children");
+#endif
+}
+
+void KviWindow::childEvent(QChildEvent *e)
+{
+ if(e->child()->isWidgetType())
+ {
+ if(e->removed())
+ childRemoved((QWidget *)(e->child()));
+ else
+ childInserted((QWidget *)(e->child()));
+ }
+ QWidget::childEvent(e);
+}
+
+void KviWindow::wheelEvent(QWheelEvent *e)
+{
+ /* NOTHING HERE FOR NOW (FIXME) */
+}
+
+
+void KviWindow::childrenTreeChanged(QWidget * widgetAdded)
+{
+ // if(widgetAdded && m_pFocusHandler)setFocusHandler(m_pFocusHandler,widgetAdded);
+ // FIXME: This might be useless
+ QResizeEvent * e = new QResizeEvent(size(),size());
+ resizeEvent(e);
+ delete e;
+}
+
+
+void KviWindow::updateBackgrounds(QObject * obj)
+{
+ if(!obj)
+ obj = this;
+#ifdef COMPILE_USE_QT4
+ QList<QObject *> list = obj->children();
+ if (list.count())
+ {
+
+ for(QList<QObject *>::Iterator it = list.begin();it != list.end();++it)
+ {
+ QObject * child = *it;
+ if(child->metaObject()->indexOfProperty("TransparencyCapable") != -1){
+ // if (child->isWidgetType())
+ ((QWidget *)child)->update();
+ }
+ updateBackgrounds(child);
+ }
+ }
+#else
+ QObjectList * list = (QObjectList *)(obj->children());
+ if(list)
+ {
+ for(unsigned int i=0;i<list->count();i++)
+ {
+ QObject * child = list->at(i);
+#if QT_VERSION >= 300
+ // FIXME: check if this code can work with qt < 3.0.0 too
+ if(child->metaObject()->findProperty("TransparencyCapable",true) != -1)
+ ((QWidget *)child)->update();
+#else
+
+ QVariant v = list->at(i)->property("TransparencyCapable");
+ if(v.isValid())
+ ((QWidget *)child)->update();
+#endif
+
+ updateBackgrounds(child);
+ }
+ }
+#endif
+}
+
+void KviWindow::moveEvent(QMoveEvent *e)
+{
+#ifdef COMPILE_PSEUDO_TRANSPARENCY
+ updateBackgrounds();
+#endif
+
+ QWidget::moveEvent(e);
+}
+
+void KviWindow::minimize()
+{
+ if(mdiParent())
+ {
+ if(!isMinimized())
+ mdiParent()->minimize();
+ }
+ else
+ showMinimized();
+}
+
+void KviWindow::maximize()
+{
+ if(mdiParent())
+ {
+ if(!isMaximized())
+ mdiParent()->maximize();
+ }
+ else
+ showMaximized();
+ autoRaise();
+}
+
+bool KviWindow::isMinimized()
+{
+ if(mdiParent())
+ return (mdiParent()->state() == KviMdiChild::Minimized);
+ else
+ return QWidget::isMinimized();
+}
+
+bool KviWindow::isMaximized()
+{
+ if(mdiParent())
+ return (mdiParent()->state() == KviMdiChild::Maximized);
+ // Heh...how to check it ?
+ // Empirical check
+ int wdth = (g_pApp->desktop()->width() * 75) / 100;
+ int hght = (g_pApp->desktop()->height() * 75) / 100;
+
+ return ((x() <= 1)&&(y() <= 1)&&(width() >= wdth)&&(height() >= hght));
+}
+
+void KviWindow::restore()
+{
+ if(mdiParent())
+ {
+ if(isMinimized()||isMaximized())
+ mdiParent()->restore();
+ }
+ else
+ showNormal();
+ autoRaise();
+}
+
+QRect KviWindow::externalGeometry()
+{
+#ifndef Q_OS_MACX
+ return mdiParent() ? mdiParent()->restoredGeometry() : frameGeometry();
+#else
+ return mdiParent() ? mdiParent()->restoredGeometry() : geometry();
+#endif
+}
+
+void KviWindow::applyOptions()
+{
+ updateCaption();
+ if(m_pIrcView)m_pIrcView->applyOptions();
+ if(m_pInput)m_pInput->applyOptions();
+
+ // trick: relayout
+ resize(width() - 1,height() - 1);
+ resize(width() + 1,height() + 1);
+}
+
+KviWindow * KviWindow::outputProxy()
+{
+ return 0;
+}
+
+void KviWindow::lostUserFocus()
+{
+ if(!m_pIrcView)return;
+ if(m_pIrcView->hasLineMark())m_pIrcView->clearLineMark(true);
+}
+
+
+void KviWindow::internalOutput(KviIrcView * pView,int msg_type,const kvi_wchar_t * pText,int iFlags)
+{
+ // all roads lead to Rome :)
+
+ if(pView)
+ {
+ if((this != g_pActiveWindow) || (!isActiveWindow()))
+ {
+ if(!pView->hasLineMark())
+ {
+ iFlags |= KviIrcView::SetLineMark;
+ }
+ }
+ pView->appendText(msg_type,pText,iFlags);
+ } else {
+ // Redirect to the output proxy
+ KviWindow *wnd = outputProxy();
+ if(wnd)wnd->outputNoFmt(msg_type,pText,iFlags);
+ }
+
+ if(!m_pTaskBarItem) {
+ return;
+ }
+
+ // if this option is checked we dont highlight other than channel msg
+ if(KVI_OPTION_BOOL(KviOption_boolHighlightOnlyNormalMsg))
+ {
+ if((msg_type != KVI_OUT_CHANPRIVMSG) && (msg_type != KVI_OUT_CHANPRIVMSGCRYPTED))
+ {
+ if(!(
+ (
+ KVI_OPTION_BOOL(KviOption_boolHighlightOnlyNormalMsgQueryToo) &&
+ (
+ (msg_type == KVI_OUT_QUERYPRIVMSG) || (msg_type == KVI_OUT_QUERYTRACE) ||
+ (msg_type == KVI_OUT_QUERYPRIVMSGCRYPTED) || (msg_type == KVI_OUT_QUERYNOTICE) || (msg_type == KVI_OUT_QUERYNOTICECRYPTED)
+ )
+ )
+ ||
+ (
+ KVI_OPTION_BOOL(KviOption_boolHighlightOnlyNormalMsgHighlightInChanToo) && (msg_type == KVI_OUT_HIGHLIGHT)
+ )
+ )
+ )
+ return;
+ }
+ }
+
+ if(KVI_OPTION_BOOL(KviOption_boolHighlightOnlyAtCostumHighlightLevel) &&
+ (KVI_OPTION_MSGTYPE(msg_type).level() < ((int)(KVI_OPTION_UINT(KviOption_uintMinHighlightLevel)))))
+ {
+ return;
+ }
+
+ m_pTaskBarItem->highlight(KVI_OPTION_MSGTYPE(msg_type).level());
+}
+
+void KviWindow::output(int msg_type,const char *format,...)
+{
+ QString szFmt(format);
+ kvi_va_list l;
+ kvi_va_start(l,format);
+ QString szBuf;
+ KviQString::vsprintf(szBuf,szFmt,l);
+ kvi_va_end(l);
+ preprocessMessage(szBuf);
+ const QChar * pC = KviQString::nullTerminatedArray(szBuf);
+ if(!pC)return;
+ internalOutput(m_pIrcView,msg_type,(kvi_wchar_t *)pC);
+}
+
+void KviWindow::output(int msg_type,const QString &szFmt,...)
+{
+ kvi_va_list l;
+ kvi_va_start_by_reference(l,szFmt);
+ QString szBuf;
+ KviQString::vsprintf(szBuf,szFmt,l);
+ kvi_va_end(l);
+ preprocessMessage(szBuf);
+ const QChar * pC = KviQString::nullTerminatedArray(szBuf);
+ if(!pC)return;
+ internalOutput(m_pIrcView,msg_type,(kvi_wchar_t *)pC);
+}
+
+void KviWindow::output(int msg_type,const kvi_wchar_t *format,...)
+{
+ QString szFmt=QString::fromUtf8(KviStr(format).ptr());
+ kvi_va_list l;
+ kvi_va_start(l,format);
+ QString szBuf;
+ KviQString::vsprintf(szBuf,szFmt,l);
+ kvi_va_end(l);
+ preprocessMessage(szBuf);
+ const QChar * pC = KviQString::nullTerminatedArray(szBuf);
+ if(!pC)return;
+ internalOutput(m_pIrcView,msg_type,(kvi_wchar_t *)pC);
+}
+
+void KviWindow::outputNoFmt(int msg_type,const char * text,int iFlags)
+{
+ QString szText(text);
+ preprocessMessage(szText);
+ const QChar * pC = KviQString::nullTerminatedArray(szText);
+ if(!pC)return;
+ internalOutput(m_pIrcView,msg_type,(kvi_wchar_t *)pC,iFlags);
+}
+
+void KviWindow::outputNoFmt(int msg_type,const QString &szText,int iFlags)
+{
+ QString szBuf(szText);
+ preprocessMessage(szBuf);
+ const QChar * pC = KviQString::nullTerminatedArray(szBuf);
+ if(!pC)return;
+ internalOutput(m_pIrcView,msg_type,(kvi_wchar_t *)pC,iFlags);
+}
+
+void KviWindow::unhighlight()
+{
+ if(!m_pTaskBarItem)return;
+ m_pTaskBarItem->unhighlight();
+}
+
+/* This messes up a bit: for example it breaks the WHOIS output where
+ escapes are already present (checking for them here would be an overkill).
+ This should be eventually done ONLY for remote user message texts
+ in the server parser.
+
+ Fixed
+*/
+
+void KviWindow::preprocessMessage(QString & szMessage)
+{
+ // slow
+#ifdef COMPILE_USE_QT4
+ QStringList strings = szMessage.split(" ");
+#else
+ QStringList strings = QStringList::split(" ",szMessage, TRUE);
+#endif
+ for ( QStringList::Iterator it = strings.begin(); it != strings.end(); ++it ) {
+ QString tmp(*it);
+ if(tmp.contains('\r')) continue;
+ tmp = KviMircCntrl::stripControlBytes(tmp);
+ tmp.stripWhiteSpace();
+ if(m_pConsole)
+ if(m_pConsole->connection())
+ if(m_pConsole->connection()->serverInfo()->supportedChannelTypes().contains(tmp[0]))
+ if((*it)==tmp)
+ *it=QString("\r!c\r%1\r").arg(*it);
+ else
+ {
+ *it=QString("\r!c%1\r%2\r").arg(tmp).arg(*it);
+ }
+ }
+ szMessage=strings.join(" ");
+}
+
+
+#include "kvi_window.moc"
diff --git a/src/kvirc/ui/kvi_window.h b/src/kvirc/ui/kvi_window.h
new file mode 100644
index 0000000..419096f
--- /dev/null
+++ b/src/kvirc/ui/kvi_window.h
@@ -0,0 +1,393 @@
+#ifndef _KVI_WINDOW_H_
+#define _KVI_WINDOW_H_
+//=============================================================================
+//
+// File : kvi_window.h
+// Creation date : Tue Jul 6 1999 14:52:20 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2004 Szymon Stefanek (pragma at kvirc dot net)
+//
+// 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 opinion) 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, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_string.h"
+#include "kvi_qstring.h"
+#include "kvi_qcstring.h"
+#include "kvi_settings.h"
+
+#ifdef COMPILE_ON_WINDOWS
+ // The brain-damaged MSVC compiler can't instantiate QList templates without a destructor definition
+ #include "kvi_mdichild.h"
+#else
+ class KviMdiChild;
+#endif
+
+#include <qframe.h>
+
+class KviFrame;
+class KviTaskBarItem;
+class KviConfig;
+class KviIrcView;
+class KviInput;
+class KviConsole;
+class KviIrcContext;
+class KviIrcConnection;
+class KviWindowToolPageButton;
+
+class KviTalPopupMenu;
+class QPixmap;
+class QSplitter;
+class KviTalHBox;
+class QToolButton;
+class QTextCodec;
+class KviTalWidgetStack;
+
+#include "kvi_tal_hbox.h"
+#include "kvi_tal_widgetstack.h"
+#include "kvi_accel.h"
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ class KviCryptController;
+ class KviCryptSessionInfo;
+#endif
+
+#include <qwidget.h>
+
+//
+// Window types
+//
+// There are KVI_WINDOW_NUM_TYPES predefined
+// window types: these are used by the KVIrc core and distributed modules
+// If you add a new def, increase KVI_WINDOW_NUM_TYPES
+//
+
+#define KVI_WINDOW_TYPE_CONSOLE 0
+#define KVI_WINDOW_TYPE_CHANNEL 1
+#define KVI_WINDOW_TYPE_QUERY 2
+#define KVI_WINDOW_TYPE_HELP 3
+#define KVI_WINDOW_TYPE_TERM 4
+#define KVI_WINDOW_TYPE_EDITOR 5
+#define KVI_WINDOW_TYPE_DCCCHAT 6
+#define KVI_WINDOW_TYPE_DCCSEND 7
+#define KVI_WINDOW_TYPE_SOCKETSPY 8
+#define KVI_WINDOW_TYPE_LINKS 9
+#define KVI_WINDOW_TYPE_TOOL 10
+#define KVI_WINDOW_TYPE_GNUTELLA 11
+#define KVI_WINDOW_TYPE_DIRBROWSER 12
+#define KVI_WINDOW_TYPE_DCCCANVAS 13
+#define KVI_WINDOW_TYPE_DCCVOICE 14
+#define KVI_WINDOW_TYPE_LIST 15
+#define KVI_WINDOW_TYPE_OFFER 16
+#define KVI_WINDOW_TYPE_LOGVIEW 17
+#define KVI_WINDOW_TYPE_DEADCHANNEL 18
+#define KVI_WINDOW_TYPE_DEADQUERY 19
+#define KVI_WINDOW_TYPE_SCRIPTEDITOR 20
+#define KVI_WINDOW_TYPE_SCRIPTOBJECT 21
+#define KVI_WINDOW_TYPE_USERWINDOW 22
+#define KVI_WINDOW_TYPE_DEBUG 23
+
+
+#define KVI_WINDOW_NUM_TYPES 24
+
+
+#define KVI_WINDOW_TYPE_USER 10000
+
+
+
+
+#define KVI_ACTIVITY_NONE 0
+#define KVI_ACTIVITY_VERYLOW 1
+#define KVI_ACTIVITY_LOW 2
+#define KVI_ACTIVITY_MEDIUM 3
+#define KVI_ACTIVITY_HIGH 4
+#define KVI_ACTIVITY_VERYHIGH 5
+
+#define KVI_ACTIVITY_ICE 0
+#define KVI_ACTIVITY_VERYCOLD 1
+#define KVI_ACTIVITY_COLD 2
+#define KVI_ACTIVITY_UNDEFINED 3
+#define KVI_ACTIVITY_HOT 4
+#define KVI_ACTIVITY_VERYHOT 5
+#define KVI_ACTIVITY_FIRE 6
+
+#ifdef COMPILE_USE_QT4
+ class QPushButton;
+ #define BUTTON_CLASS QPushButton
+#else
+ #define BUTTON_CLASS QToolButton
+#endif
+
+
+class KVIRC_API KviWindow : public QWidget
+{
+ friend class KviInput;
+ friend class KviFrame;
+ friend class KviTaskBarItem;
+ friend class KviTaskBarButton;
+ friend class KviTreeTaskBarItem;
+ friend class KviTreeTaskBar;
+ Q_PROPERTY(int KviProperty_ChildFocusOwner READ type)
+ Q_OBJECT
+public:
+ KviWindow(int type,KviFrame * lpFrm,const QString &name,KviConsole * pConsole = 0);
+ virtual ~KviWindow();
+protected: // almost private: don't touch :D
+ QString m_szName; // the current window name (usually also the target)
+ KviFrame * m_pFrm;
+ KviConsole * m_pConsole;
+ KviIrcContext * m_pContext;
+
+ int m_iType;
+
+ KviTaskBarItem * m_pTaskBarItem;
+ QWidget * m_pFocusHandler;
+ QString m_szPlainTextCaption;
+ QString m_szHtmlActiveCaption;
+ QString m_szHtmlInactiveCaption;
+ KviIrcView * m_pIrcView;
+ KviInput * m_pInput;
+ QSplitter * m_pSplitter;
+ KviTalHBox * m_pButtonBox;
+ unsigned long int m_uId;
+ QString m_szTextEncoding;
+#ifdef COMPILE_CRYPT_SUPPORT
+ KviWindowToolPageButton * m_pCryptControllerButton;
+ KviCryptController * m_pCryptController;
+ KviCryptSessionInfo * m_pCryptSessionInfo;
+#endif
+ BUTTON_CLASS * m_pTextEncodingButton;
+ QToolButton * m_pHideToolsButton;
+ QWidget * m_pLastFocusedChild;
+ KviAccel * m_pAccel;
+ static const char * m_typeTable[KVI_WINDOW_NUM_TYPES + 1];
+ // text encoding and decoding
+ //unsigned int m_uTextEncoding;
+ QTextCodec * m_pTextCodec;
+// KviToolWindowsContainer * m_pEditorsContainer;
+public:
+ // The global ID of this window: unique in the application
+ QString id(){ return QString("%1").arg(m_uId); };
+ unsigned long int numericId(){ return m_uId; };
+public:
+ // THIS is the function that should be used
+ const QString & windowName(){ return m_szName; };
+ void setWindowName(const QString &szName);
+ // force QT to set our UNICODE name too... FIXME: this should be removed later...
+ virtual void setName(const char * szName);
+
+ // Window type management
+ int type() const { return m_iType; };
+ // This returns a descriptive name of the window type
+ // if the window is an user window, the typeString returned
+ // by THIS implementation is "unknown"
+ virtual const char * typeString();
+
+ QTextCodec * textCodec(){ return m_pTextCodec ? m_pTextCodec : defaultTextCodec(); };
+ void forceTextCodec(QTextCodec * c);
+
+ // The frame that this window belongs to
+ // It is always non-null and never changes
+ KviFrame * frame() const { return m_pFrm; };
+ // The KviIrcView of this window: may be NULL if the window has no KviIrcView (and thus supports no direct output)
+ KviIrcView * view() const { return m_pIrcView; };
+ // The mdiParent widget: may be nulll if the window is undocked
+ KviMdiChild * mdiParent(){ return (KviMdiChild *)parent(); };
+ // The console that this window belongs to: may be null for windows that aren't bound to irc contexts
+ KviConsole * console(){ return m_pConsole; };
+ // same as above
+ KviIrcContext * context(){ return m_pContext; };
+ // the current IRC connection (if any)
+ KviIrcConnection * connection();
+ // The splitter of this window: it *shouldn't* be null... but ... well.. who knows ? :D ...better check it
+ QSplitter * splitter(){ return m_pSplitter; };
+ // The window has ALWAYS a taskbar item
+ KviTaskBarItem * taskBarItem(){ return m_pTaskBarItem; };
+ // The window *might* have a button container
+ virtual QFrame * buttonContainer(){ return (QFrame*)m_pButtonBox; };
+ virtual void toggleButtonContainer();
+ // The window *might* have an output proxy: if it has no view() for example
+ virtual KviWindow * outputProxy();
+ // The window input widget
+ KviInput * input(){ return m_pInput; };
+
+ // The target of this window: empty when it makes no sense :D
+ virtual const QString & target(){ return KviQString::empty; };
+ // The local nickname bound to this window: might be empty when a local nickname makes no sense
+ virtual const QString & localNick(){ return KviQString::empty; };
+
+#ifdef COMPILE_CRYPT_SUPPORT
+ KviCryptSessionInfo * cryptSessionInfo(){ return m_pCryptSessionInfo; };
+ void setCryptSessionInfo(KviCryptSessionInfo * i);
+#endif
+
+ virtual bool activityMeter(unsigned int * puActivityValue,unsigned int * puActivityTemperature);
+
+ void unhighlight();
+
+ virtual void getTaskBarTipText(QString &buffer);
+
+ // This is meaningful only if view() is non NULL
+ const QString & lastLineOfText();
+ const QString & lastMessageText();
+
+ const QString &textEncoding(){ return m_szTextEncoding; };
+ // returns true if the encoding could be succesfully set
+ bool setTextEncoding(const QString &szTextEncoding);
+ // this must return a default text codec suitable for this window
+ virtual QTextCodec * defaultTextCodec();
+ // encode the text from szSource by using m_uTextEncoding
+ KviQCString encodeText(const QString &szText);
+ QString decodeText(const char * szText);
+
+ void contextPopup();
+ // Raises the window (after a light delay to prevent focus pingpongs)
+ void delayedAutoRaise();
+ // Window state: might work :D
+ bool isMinimized();
+ bool isMaximized();
+ // Retrieves the default log file name: this is pre-build
+ void getDefaultLogFileName(QString &buffer);
+ // Well...the external geometry :)
+ QRect externalGeometry();
+
+ void delayedClose(); // close that jumps out of the current event loop
+
+ // Interesting overridables:
+ virtual void fillContextPopup(KviTalPopupMenu * p);
+ virtual void getConfigGroupName(QString &buf);
+// virtual void getBaseLogFileName(KviStr &buffer);
+ virtual void getBaseLogFileName(QString &buffer);
+ virtual void updateCaption();
+ virtual void applyOptions();
+ virtual void updateIcon();
+ virtual void ownMessage(const QString &text){};
+ virtual void ownAction(const QString &text){};
+ virtual const QString & plainTextCaption(){ return m_szPlainTextCaption; };
+ virtual const QString & htmlActiveCaption(){ return m_szHtmlActiveCaption; };
+ virtual const QString & htmlInactiveCaption(){ return m_szHtmlInactiveCaption; };
+ virtual void setFocus();
+
+ void internalOutput(KviIrcView * pView,int msg_type,const kvi_wchar_t * text,int iFlags=0);
+ // You *might* want to override these too.. but better don't touch them :D
+ virtual void output(int msg_type,const char * format,...);
+ virtual void outputNoFmt(int msg_type,const char * text,int iFlags=0);
+ virtual void output(int msg_type,const kvi_wchar_t * format,...);
+ virtual void outputNoFmt(int msg_type,const kvi_wchar_t * text,int iFlags=0){ internalOutput(m_pIrcView,msg_type,text,iFlags); };
+ virtual void output(int msg_type,const QString &szFmt,...);
+ virtual void outputNoFmt(int msg_type,const QString &szText,int iFlags=0); // <-- these are KviIrcView::AppendTextFlags
+ // Just helpers.. FIXME: might be redesigned in some other way
+ void updateBackgrounds(QObject * obj = 0);
+
+ void demandAttention();
+ bool hasAttention();
+
+ // This should die, probably
+ void listWindowTypes();
+
+public slots:
+ void dock();
+ void undock();
+ void autoRaise();
+ void maximize();
+ void minimize();
+ void restore();
+ void reloadImages();
+protected slots:
+ void savePropertiesAsDefault();
+ void toggleCryptController(); // This has to be here even if the crypt support is enabled...moc does not support conditionals
+ void cryptControllerFinished(); // same as above
+ void cryptSessionInfoDestroyed(); // same as above
+ void textEncodingButtonClicked();
+ void systemPopupRequest(const QPoint &pnt);
+ void systemTextEncodingPopupSmartActivated(int id);
+ void systemTextEncodingPopupSmartUtf8Activated(int id);
+ void systemTextEncodingPopupStandardActivated(int id);
+ void systemTextEncodingPopupDefault();
+ void childDestroyed();
+signals:
+ void windowNameChanged();
+protected:
+ // Loading and saving of properties
+ // Protected: only KviFrame can call these
+ virtual void saveProperties(KviConfig *cfg);
+ virtual void loadProperties(KviConfig *cfg);
+ // Creation and destruction events: overridden in windows that have script events bound to creation and destruction
+ virtual void triggerCreationEvents(){};
+ virtual void triggerDestructionEvents(){};
+ // Internal: do not touch :D (KviFrame)
+ virtual void createTaskBarItem();
+ virtual void destroyTaskBarItem();
+ // called by KviFrame
+ // either lost the active window status or the frame is no longer active (but we're still the active kvirc's subwindow)
+ virtual void lostUserFocus();
+ // Sets the progress for the taskbar item: if "progress" makes sense in your window , well , use this
+ void setProgress(int progress);
+ // call this in the constructor if your caption is fixed:
+ // it will set m_szPlainTextCaption to szCaption and it will
+ // automatically use it without the need of overriding fillCaptionBuffers
+ void setFixedCaption(const QString &szCaption);
+ // this by default calls fillSingleColorCaptionBuffer(plainTextCaption());
+ virtual void fillCaptionBuffers();
+ // protected helper
+ void fillSingleColorCaptionBuffers(const QString &szName);
+ // Virtual events that signal dock state change
+ virtual void youAreDocked();
+ virtual void youAreUndocked();
+ // Reimplement to show a special icon in the taskbar items and captions
+ virtual QPixmap * myIconPtr();
+ // Sets the type of this window: be careful with this
+ void setType(int iType);
+
+ bool eventFilter(QObject *o,QEvent *e);
+
+ // Virtuals overridden to manage the internal layouts...
+ virtual void moveEvent(QMoveEvent *e);
+ virtual void closeEvent(QCloseEvent *e);
+ virtual void wheelEvent(QWheelEvent *e);
+ virtual void childEvent(QChildEvent *e);
+ virtual void focusInEvent(QFocusEvent *e);
+
+ void childInserted(QWidget * o);
+ void childRemoved(QWidget * o);
+
+ void activateSelf();
+
+ // Internal helpers
+ void createCryptControllerButton(QWidget * par);
+ void createTextEncodingButton(QWidget * par);
+ void createSystemTextEncodingPopup();
+
+ BUTTON_CLASS * createToolButton(QWidget * par,const char * nam,int pixon,int pixoff,const QString & tooltip,bool bOn);
+ // This is called by KviInput: actually it links the widgetAdded
+ virtual void childrenTreeChanged(QWidget * widgetAdded);
+
+ virtual bool focusNextPrevChild(bool bNext);
+
+ virtual void preprocessMessage(QString & szMessage);
+};
+
+#ifndef _KVI_WINDOW_CPP_
+ // The active window:
+ // This is almost always non null
+ // The exception is the startup (when there are no windows at all)
+ // and the last phase of the destructor.
+ // You usually shouldn't care of checking this pointer for NULL unless
+ // you're running very early at startup or very late at shutdown
+ extern KVIRC_API KviWindow * g_pActiveWindow;
+#endif
+
+#endif //_KVI_WINDOW_H_
diff --git a/src/kvirc/ui/moc_kvi_actiondrawer.cpp b/src/kvirc/ui/moc_kvi_actiondrawer.cpp
new file mode 100644
index 0000000..833bc39
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_actiondrawer.cpp
@@ -0,0 +1,238 @@
+/****************************************************************************
+** KviActionDrawerPageListView meta object code from reading C++ file 'kvi_actiondrawer.h'
+**
+** Created: Mon Feb 25 00:12:20 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_actiondrawer.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviActionDrawerPageListView::className() const
+{
+ return "KviActionDrawerPageListView";
+}
+
+QMetaObject *KviActionDrawerPageListView::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviActionDrawerPageListView( "KviActionDrawerPageListView", &KviActionDrawerPageListView::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviActionDrawerPageListView::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviActionDrawerPageListView", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviActionDrawerPageListView::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviActionDrawerPageListView", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviActionDrawerPageListView::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviListView::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviActionDrawerPageListView", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviActionDrawerPageListView.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviActionDrawerPageListView::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviActionDrawerPageListView" ) )
+ return this;
+ return KviListView::qt_cast( clname );
+}
+
+bool KviActionDrawerPageListView::qt_invoke( int _id, QUObject* _o )
+{
+ return KviListView::qt_invoke(_id,_o);
+}
+
+bool KviActionDrawerPageListView::qt_emit( int _id, QUObject* _o )
+{
+ return KviListView::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviActionDrawerPageListView::qt_property( int id, int f, QVariant* v)
+{
+ return KviListView::qt_property( id, f, v);
+}
+
+bool KviActionDrawerPageListView::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviActionDrawerPage::className() const
+{
+ return "KviActionDrawerPage";
+}
+
+QMetaObject *KviActionDrawerPage::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviActionDrawerPage( "KviActionDrawerPage", &KviActionDrawerPage::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviActionDrawerPage::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviActionDrawerPage", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviActionDrawerPage::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviActionDrawerPage", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviActionDrawerPage::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QWidget::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviActionDrawerPage", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviActionDrawerPage.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviActionDrawerPage::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviActionDrawerPage" ) )
+ return this;
+ return QWidget::qt_cast( clname );
+}
+
+bool KviActionDrawerPage::qt_invoke( int _id, QUObject* _o )
+{
+ return QWidget::qt_invoke(_id,_o);
+}
+
+bool KviActionDrawerPage::qt_emit( int _id, QUObject* _o )
+{
+ return QWidget::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviActionDrawerPage::qt_property( int id, int f, QVariant* v)
+{
+ return QWidget::qt_property( id, f, v);
+}
+
+bool KviActionDrawerPage::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviActionDrawer::className() const
+{
+ return "KviActionDrawer";
+}
+
+QMetaObject *KviActionDrawer::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviActionDrawer( "KviActionDrawer", &KviActionDrawer::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviActionDrawer::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviActionDrawer", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviActionDrawer::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviActionDrawer", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviActionDrawer::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QTabWidget::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviActionDrawer", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviActionDrawer.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviActionDrawer::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviActionDrawer" ) )
+ return this;
+ return QTabWidget::qt_cast( clname );
+}
+
+bool KviActionDrawer::qt_invoke( int _id, QUObject* _o )
+{
+ return QTabWidget::qt_invoke(_id,_o);
+}
+
+bool KviActionDrawer::qt_emit( int _id, QUObject* _o )
+{
+ return QTabWidget::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviActionDrawer::qt_property( int id, int f, QVariant* v)
+{
+ return QTabWidget::qt_property( id, f, v);
+}
+
+bool KviActionDrawer::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_customtoolbar.cpp b/src/kvirc/ui/moc_kvi_customtoolbar.cpp
new file mode 100644
index 0000000..4a89b12
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_customtoolbar.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+** KviCustomToolBarSeparator meta object code from reading C++ file 'kvi_customtoolbar.h'
+**
+** Created: Mon Feb 25 00:12:23 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_customtoolbar.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviCustomToolBarSeparator::className() const
+{
+ return "KviCustomToolBarSeparator";
+}
+
+QMetaObject *KviCustomToolBarSeparator::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviCustomToolBarSeparator( "KviCustomToolBarSeparator", &KviCustomToolBarSeparator::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviCustomToolBarSeparator::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviCustomToolBarSeparator", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviCustomToolBarSeparator::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviCustomToolBarSeparator", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviCustomToolBarSeparator::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QWidget::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviCustomToolBarSeparator", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviCustomToolBarSeparator.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviCustomToolBarSeparator::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviCustomToolBarSeparator" ) )
+ return this;
+ return QWidget::qt_cast( clname );
+}
+
+bool KviCustomToolBarSeparator::qt_invoke( int _id, QUObject* _o )
+{
+ return QWidget::qt_invoke(_id,_o);
+}
+
+bool KviCustomToolBarSeparator::qt_emit( int _id, QUObject* _o )
+{
+ return QWidget::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviCustomToolBarSeparator::qt_property( int id, int f, QVariant* v)
+{
+ return QWidget::qt_property( id, f, v);
+}
+
+bool KviCustomToolBarSeparator::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviCustomToolBar::className() const
+{
+ return "KviCustomToolBar";
+}
+
+QMetaObject *KviCustomToolBar::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviCustomToolBar( "KviCustomToolBar", &KviCustomToolBar::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviCustomToolBar::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviCustomToolBar", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviCustomToolBar::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviCustomToolBar", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviCustomToolBar::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviToolBar::staticMetaObject();
+ static const QUMethod slot_0 = {"beginCustomize", 0, 0 };
+ static const QUMethod slot_1 = {"endCustomize", 0, 0 };
+ static const QUMethod slot_2 = {"filteredChildDestroyed", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "beginCustomize()", &slot_0, QMetaData::Protected },
+ { "endCustomize()", &slot_1, QMetaData::Protected },
+ { "filteredChildDestroyed()", &slot_2, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviCustomToolBar", parentObject,
+ slot_tbl, 3,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviCustomToolBar.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviCustomToolBar::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviCustomToolBar" ) )
+ return this;
+ return KviToolBar::qt_cast( clname );
+}
+
+bool KviCustomToolBar::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: beginCustomize(); break;
+ case 1: endCustomize(); break;
+ case 2: filteredChildDestroyed(); break;
+ default:
+ return KviToolBar::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviCustomToolBar::qt_emit( int _id, QUObject* _o )
+{
+ return KviToolBar::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviCustomToolBar::qt_property( int id, int f, QVariant* v)
+{
+ return KviToolBar::qt_property( id, f, v);
+}
+
+bool KviCustomToolBar::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_debugwindow.cpp b/src/kvirc/ui/moc_kvi_debugwindow.cpp
new file mode 100644
index 0000000..5e3da82
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_debugwindow.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+** KviDebugWindow meta object code from reading C++ file 'kvi_debugwindow.h'
+**
+** Created: Mon Feb 25 00:12:25 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_debugwindow.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviDebugWindow::className() const
+{
+ return "KviDebugWindow";
+}
+
+QMetaObject *KviDebugWindow::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviDebugWindow( "KviDebugWindow", &KviDebugWindow::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviDebugWindow::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviDebugWindow", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviDebugWindow::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviDebugWindow", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviDebugWindow::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviWindow::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviDebugWindow", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviDebugWindow.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviDebugWindow::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviDebugWindow" ) )
+ return this;
+ return KviWindow::qt_cast( clname );
+}
+
+bool KviDebugWindow::qt_invoke( int _id, QUObject* _o )
+{
+ return KviWindow::qt_invoke(_id,_o);
+}
+
+bool KviDebugWindow::qt_emit( int _id, QUObject* _o )
+{
+ return KviWindow::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviDebugWindow::qt_property( int id, int f, QVariant* v)
+{
+ return KviWindow::qt_property( id, f, v);
+}
+
+bool KviDebugWindow::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_htmldialog.cpp b/src/kvirc/ui/moc_kvi_htmldialog.cpp
new file mode 100644
index 0000000..62d7681
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_htmldialog.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+** KviHtmlDialog meta object code from reading C++ file 'kvi_htmldialog.h'
+**
+** Created: Mon Feb 25 00:12:27 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_htmldialog.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviHtmlDialog::className() const
+{
+ return "KviHtmlDialog";
+}
+
+QMetaObject *KviHtmlDialog::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviHtmlDialog( "KviHtmlDialog", &KviHtmlDialog::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviHtmlDialog::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviHtmlDialog", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviHtmlDialog::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviHtmlDialog", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviHtmlDialog::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QDialog::staticMetaObject();
+ static const QUMethod slot_0 = {"button1Pressed", 0, 0 };
+ static const QUMethod slot_1 = {"button2Pressed", 0, 0 };
+ static const QUMethod slot_2 = {"button3Pressed", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "button1Pressed()", &slot_0, QMetaData::Protected },
+ { "button2Pressed()", &slot_1, QMetaData::Protected },
+ { "button3Pressed()", &slot_2, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviHtmlDialog", parentObject,
+ slot_tbl, 3,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviHtmlDialog.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviHtmlDialog::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviHtmlDialog" ) )
+ return this;
+ return QDialog::qt_cast( clname );
+}
+
+bool KviHtmlDialog::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: button1Pressed(); break;
+ case 1: button2Pressed(); break;
+ case 2: button3Pressed(); break;
+ default:
+ return QDialog::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviHtmlDialog::qt_emit( int _id, QUObject* _o )
+{
+ return QDialog::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviHtmlDialog::qt_property( int id, int f, QVariant* v)
+{
+ return QDialog::qt_property( id, f, v);
+}
+
+bool KviHtmlDialog::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_imagedialog.cpp b/src/kvirc/ui/moc_kvi_imagedialog.cpp
new file mode 100644
index 0000000..be88643
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_imagedialog.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+** KviImageDialog meta object code from reading C++ file 'kvi_imagedialog.h'
+**
+** Created: Mon Feb 25 00:12:28 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_imagedialog.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviImageDialog::className() const
+{
+ return "KviImageDialog";
+}
+
+QMetaObject *KviImageDialog::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviImageDialog( "KviImageDialog", &KviImageDialog::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviImageDialog::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviImageDialog", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviImageDialog::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviImageDialog", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviImageDialog::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QDialog::staticMetaObject();
+ static const QUMethod slot_0 = {"okClicked", 0, 0 };
+ static const QUMethod slot_1 = {"cancelClicked", 0, 0 };
+ static const QUMethod slot_2 = {"heartbeat", 0, 0 };
+ static const QUParameter param_slot_3[] = {
+ { "index", &static_QUType_int, 0, QUParameter::In }
+ };
+ static const QUMethod slot_3 = {"jobTypeSelected", 1, param_slot_3 };
+ static const QUParameter param_slot_4[] = {
+ { "it", &static_QUType_ptr, "KviTalListBoxItem", QUParameter::In }
+ };
+ static const QUMethod slot_4 = {"itemDoubleClicked", 1, param_slot_4 };
+ static const QUParameter param_slot_5[] = {
+ { 0, &static_QUType_ptr, "KviDynamicToolTip", QUParameter::In },
+ { "pnt", &static_QUType_varptr, "\x0e", QUParameter::In }
+ };
+ static const QUMethod slot_5 = {"tipRequest", 2, param_slot_5 };
+ static const QMetaData slot_tbl[] = {
+ { "okClicked()", &slot_0, QMetaData::Protected },
+ { "cancelClicked()", &slot_1, QMetaData::Protected },
+ { "heartbeat()", &slot_2, QMetaData::Protected },
+ { "jobTypeSelected(int)", &slot_3, QMetaData::Protected },
+ { "itemDoubleClicked(KviTalListBoxItem*)", &slot_4, QMetaData::Protected },
+ { "tipRequest(KviDynamicToolTip*,const QPoint&)", &slot_5, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviImageDialog", parentObject,
+ slot_tbl, 6,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviImageDialog.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviImageDialog::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviImageDialog" ) )
+ return this;
+ return QDialog::qt_cast( clname );
+}
+
+bool KviImageDialog::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: okClicked(); break;
+ case 1: cancelClicked(); break;
+ case 2: heartbeat(); break;
+ case 3: jobTypeSelected((int)static_QUType_int.get(_o+1)); break;
+ case 4: itemDoubleClicked((KviTalListBoxItem*)static_QUType_ptr.get(_o+1)); break;
+ case 5: tipRequest((KviDynamicToolTip*)static_QUType_ptr.get(_o+1),(const QPoint&)*((const QPoint*)static_QUType_ptr.get(_o+2))); break;
+ default:
+ return QDialog::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviImageDialog::qt_emit( int _id, QUObject* _o )
+{
+ return QDialog::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviImageDialog::qt_property( int id, int f, QVariant* v)
+{
+ return QDialog::qt_property( id, f, v);
+}
+
+bool KviImageDialog::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_ircviewtools.cpp b/src/kvirc/ui/moc_kvi_ircviewtools.cpp
new file mode 100644
index 0000000..e44adb6
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_ircviewtools.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+** KviIrcViewToolWidget meta object code from reading C++ file 'kvi_ircviewtools.h'
+**
+** Created: Mon Feb 25 00:12:30 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_ircviewtools.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviIrcViewToolWidget::className() const
+{
+ return "KviIrcViewToolWidget";
+}
+
+QMetaObject *KviIrcViewToolWidget::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviIrcViewToolWidget( "KviIrcViewToolWidget", &KviIrcViewToolWidget::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviIrcViewToolWidget::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviIrcViewToolWidget", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviIrcViewToolWidget::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviIrcViewToolWidget", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviIrcViewToolWidget::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QFrame::staticMetaObject();
+ static const QUMethod slot_0 = {"findPrev", 0, 0 };
+ static const QUMethod slot_1 = {"findNext", 0, 0 };
+ static const QUMethod slot_2 = {"filterEnableAll", 0, 0 };
+ static const QUMethod slot_3 = {"filterEnableNone", 0, 0 };
+ static const QUMethod slot_4 = {"filterSave", 0, 0 };
+ static const QUMethod slot_5 = {"filterLoad", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "findPrev()", &slot_0, QMetaData::Protected },
+ { "findNext()", &slot_1, QMetaData::Protected },
+ { "filterEnableAll()", &slot_2, QMetaData::Protected },
+ { "filterEnableNone()", &slot_3, QMetaData::Protected },
+ { "filterSave()", &slot_4, QMetaData::Protected },
+ { "filterLoad()", &slot_5, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviIrcViewToolWidget", parentObject,
+ slot_tbl, 6,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviIrcViewToolWidget.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviIrcViewToolWidget::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviIrcViewToolWidget" ) )
+ return this;
+ return QFrame::qt_cast( clname );
+}
+
+bool KviIrcViewToolWidget::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: findPrev(); break;
+ case 1: findNext(); break;
+ case 2: filterEnableAll(); break;
+ case 3: filterEnableNone(); break;
+ case 4: filterSave(); break;
+ case 5: filterLoad(); break;
+ default:
+ return QFrame::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviIrcViewToolWidget::qt_emit( int _id, QUObject* _o )
+{
+ return QFrame::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviIrcViewToolWidget::qt_property( int id, int f, QVariant* v)
+{
+ return QFrame::qt_property( id, f, v);
+}
+
+bool KviIrcViewToolWidget::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_listview.cpp b/src/kvirc/ui/moc_kvi_listview.cpp
new file mode 100644
index 0000000..f9f6118
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_listview.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+** KviListView meta object code from reading C++ file 'kvi_listview.h'
+**
+** Created: Mon Feb 25 00:12:44 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_listview.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviListView::className() const
+{
+ return "KviListView";
+}
+
+QMetaObject *KviListView::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviListView( "KviListView", &KviListView::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviListView::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviListView", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviListView::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviListView", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviListView::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviTalListView::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviListView", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviListView.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviListView::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviListView" ) )
+ return this;
+ return KviTalListView::qt_cast( clname );
+}
+
+bool KviListView::qt_invoke( int _id, QUObject* _o )
+{
+ return KviTalListView::qt_invoke(_id,_o);
+}
+
+bool KviListView::qt_emit( int _id, QUObject* _o )
+{
+ return KviTalListView::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviListView::qt_property( int id, int f, QVariant* v)
+{
+ return KviTalListView::qt_property( id, f, v);
+}
+
+bool KviListView::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_mdicaption.cpp b/src/kvirc/ui/moc_kvi_mdicaption.cpp
new file mode 100644
index 0000000..3e027b9
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_mdicaption.cpp
@@ -0,0 +1,238 @@
+/****************************************************************************
+** KviMdiCaptionButton meta object code from reading C++ file 'kvi_mdicaption.h'
+**
+** Created: Mon Feb 25 00:12:32 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_mdicaption.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviMdiCaptionButton::className() const
+{
+ return "KviMdiCaptionButton";
+}
+
+QMetaObject *KviMdiCaptionButton::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviMdiCaptionButton( "KviMdiCaptionButton", &KviMdiCaptionButton::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviMdiCaptionButton::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMdiCaptionButton", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviMdiCaptionButton::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMdiCaptionButton", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviMdiCaptionButton::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QToolButton::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviMdiCaptionButton", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviMdiCaptionButton.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviMdiCaptionButton::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviMdiCaptionButton" ) )
+ return this;
+ return QToolButton::qt_cast( clname );
+}
+
+bool KviMdiCaptionButton::qt_invoke( int _id, QUObject* _o )
+{
+ return QToolButton::qt_invoke(_id,_o);
+}
+
+bool KviMdiCaptionButton::qt_emit( int _id, QUObject* _o )
+{
+ return QToolButton::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviMdiCaptionButton::qt_property( int id, int f, QVariant* v)
+{
+ return QToolButton::qt_property( id, f, v);
+}
+
+bool KviMdiCaptionButton::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviMenuBarToolButton::className() const
+{
+ return "KviMenuBarToolButton";
+}
+
+QMetaObject *KviMenuBarToolButton::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviMenuBarToolButton( "KviMenuBarToolButton", &KviMenuBarToolButton::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviMenuBarToolButton::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMenuBarToolButton", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviMenuBarToolButton::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMenuBarToolButton", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviMenuBarToolButton::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviStyledToolButton::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviMenuBarToolButton", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviMenuBarToolButton.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviMenuBarToolButton::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviMenuBarToolButton" ) )
+ return this;
+ return KviStyledToolButton::qt_cast( clname );
+}
+
+bool KviMenuBarToolButton::qt_invoke( int _id, QUObject* _o )
+{
+ return KviStyledToolButton::qt_invoke(_id,_o);
+}
+
+bool KviMenuBarToolButton::qt_emit( int _id, QUObject* _o )
+{
+ return KviStyledToolButton::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviMenuBarToolButton::qt_property( int id, int f, QVariant* v)
+{
+ return KviStyledToolButton::qt_property( id, f, v);
+}
+
+bool KviMenuBarToolButton::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviMdiCaption::className() const
+{
+ return "KviMdiCaption";
+}
+
+QMetaObject *KviMdiCaption::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviMdiCaption( "KviMdiCaption", &KviMdiCaption::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviMdiCaption::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMdiCaption", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviMdiCaption::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMdiCaption", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviMdiCaption::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QWidget::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviMdiCaption", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviMdiCaption.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviMdiCaption::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviMdiCaption" ) )
+ return this;
+ return QWidget::qt_cast( clname );
+}
+
+bool KviMdiCaption::qt_invoke( int _id, QUObject* _o )
+{
+ return QWidget::qt_invoke(_id,_o);
+}
+
+bool KviMdiCaption::qt_emit( int _id, QUObject* _o )
+{
+ return QWidget::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviMdiCaption::qt_property( int id, int f, QVariant* v)
+{
+ return QWidget::qt_property( id, f, v);
+}
+
+bool KviMdiCaption::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_mdichild.cpp b/src/kvirc/ui/moc_kvi_mdichild.cpp
new file mode 100644
index 0000000..3fcefcd
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_mdichild.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+** KviMdiChild meta object code from reading C++ file 'kvi_mdichild.h'
+**
+** Created: Mon Feb 25 00:12:34 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_mdichild.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviMdiChild::className() const
+{
+ return "KviMdiChild";
+}
+
+QMetaObject *KviMdiChild::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviMdiChild( "KviMdiChild", &KviMdiChild::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviMdiChild::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMdiChild", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviMdiChild::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMdiChild", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviMdiChild::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QFrame::staticMetaObject();
+ static const QUMethod slot_0 = {"maximize", 0, 0 };
+ static const QUMethod slot_1 = {"minimize", 0, 0 };
+ static const QUMethod slot_2 = {"restore", 0, 0 };
+ static const QUMethod slot_3 = {"systemPopupSlot", 0, 0 };
+ static const QUMethod slot_4 = {"closeRequest", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "maximize()", &slot_0, QMetaData::Public },
+ { "minimize()", &slot_1, QMetaData::Public },
+ { "restore()", &slot_2, QMetaData::Public },
+ { "systemPopupSlot()", &slot_3, QMetaData::Public },
+ { "closeRequest()", &slot_4, QMetaData::Public }
+ };
+ static const QUParameter param_signal_0[] = {
+ { "pnt", &static_QUType_varptr, "\x0e", QUParameter::In }
+ };
+ static const QUMethod signal_0 = {"systemPopupRequest", 1, param_signal_0 };
+ static const QMetaData signal_tbl[] = {
+ { "systemPopupRequest(const QPoint&)", &signal_0, QMetaData::Public }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviMdiChild", parentObject,
+ slot_tbl, 5,
+ signal_tbl, 1,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviMdiChild.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviMdiChild::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviMdiChild" ) )
+ return this;
+ return QFrame::qt_cast( clname );
+}
+
+#include <qobjectdefs.h>
+#include <qsignalslotimp.h>
+
+// SIGNAL systemPopupRequest
+void KviMdiChild::systemPopupRequest( const QPoint& t0 )
+{
+ if ( signalsBlocked() )
+ return;
+ QConnectionList *clist = receivers( staticMetaObject()->signalOffset() + 0 );
+ if ( !clist )
+ return;
+ QUObject o[2];
+ static_QUType_varptr.set(o+1,&t0);
+ activate_signal( clist, o );
+}
+
+bool KviMdiChild::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: maximize(); break;
+ case 1: minimize(); break;
+ case 2: restore(); break;
+ case 3: systemPopupSlot(); break;
+ case 4: closeRequest(); break;
+ default:
+ return QFrame::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviMdiChild::qt_emit( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->signalOffset() ) {
+ case 0: systemPopupRequest((const QPoint&)*((const QPoint*)static_QUType_ptr.get(_o+1))); break;
+ default:
+ return QFrame::qt_emit(_id,_o);
+ }
+ return TRUE;
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviMdiChild::qt_property( int id, int f, QVariant* v)
+{
+ return QFrame::qt_property( id, f, v);
+}
+
+bool KviMdiChild::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_mdimanager.cpp b/src/kvirc/ui/moc_kvi_mdimanager.cpp
new file mode 100644
index 0000000..fed719b
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_mdimanager.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+** KviMdiManager meta object code from reading C++ file 'kvi_mdimanager.h'
+**
+** Created: Mon Feb 25 00:12:36 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_mdimanager.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviMdiManager::className() const
+{
+ return "KviMdiManager";
+}
+
+QMetaObject *KviMdiManager::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviMdiManager( "KviMdiManager", &KviMdiManager::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviMdiManager::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMdiManager", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviMdiManager::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviMdiManager", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviMdiManager::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviTalScrollView::staticMetaObject();
+ static const QUMethod slot_0 = {"relayoutMenuButtons", 0, 0 };
+ static const QUMethod slot_1 = {"cascadeWindows", 0, 0 };
+ static const QUMethod slot_2 = {"cascadeMaximized", 0, 0 };
+ static const QUMethod slot_3 = {"expandVertical", 0, 0 };
+ static const QUMethod slot_4 = {"expandHorizontal", 0, 0 };
+ static const QUMethod slot_5 = {"minimizeAll", 0, 0 };
+ static const QUMethod slot_6 = {"tile", 0, 0 };
+ static const QUMethod slot_7 = {"toggleAutoTile", 0, 0 };
+ static const QUMethod slot_8 = {"tileAnodine", 0, 0 };
+ static const QUMethod slot_9 = {"reloadImages", 0, 0 };
+ static const QUMethod slot_10 = {"minimizeActiveChild", 0, 0 };
+ static const QUMethod slot_11 = {"restoreActiveChild", 0, 0 };
+ static const QUMethod slot_12 = {"closeActiveChild", 0, 0 };
+ static const QUMethod slot_13 = {"activeChildSystemPopup", 0, 0 };
+ static const QUParameter param_slot_14[] = {
+ { "id", &static_QUType_int, 0, QUParameter::In }
+ };
+ static const QUMethod slot_14 = {"menuActivated", 1, param_slot_14 };
+ static const QUParameter param_slot_15[] = {
+ { "id", &static_QUType_int, 0, QUParameter::In }
+ };
+ static const QUMethod slot_15 = {"tileMethodMenuActivated", 1, param_slot_15 };
+ static const QUMethod slot_16 = {"fillWindowPopup", 0, 0 };
+ static const QUMethod slot_17 = {"sdiMinimizeButtonDestroyed", 0, 0 };
+ static const QUMethod slot_18 = {"sdiRestoreButtonDestroyed", 0, 0 };
+ static const QUMethod slot_19 = {"sdiCloseButtonDestroyed", 0, 0 };
+ static const QUMethod slot_20 = {"sdiIconButtonDestroyed", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "relayoutMenuButtons()", &slot_0, QMetaData::Public },
+ { "cascadeWindows()", &slot_1, QMetaData::Public },
+ { "cascadeMaximized()", &slot_2, QMetaData::Public },
+ { "expandVertical()", &slot_3, QMetaData::Public },
+ { "expandHorizontal()", &slot_4, QMetaData::Public },
+ { "minimizeAll()", &slot_5, QMetaData::Public },
+ { "tile()", &slot_6, QMetaData::Public },
+ { "toggleAutoTile()", &slot_7, QMetaData::Public },
+ { "tileAnodine()", &slot_8, QMetaData::Public },
+ { "reloadImages()", &slot_9, QMetaData::Public },
+ { "minimizeActiveChild()", &slot_10, QMetaData::Protected },
+ { "restoreActiveChild()", &slot_11, QMetaData::Protected },
+ { "closeActiveChild()", &slot_12, QMetaData::Protected },
+ { "activeChildSystemPopup()", &slot_13, QMetaData::Protected },
+ { "menuActivated(int)", &slot_14, QMetaData::Protected },
+ { "tileMethodMenuActivated(int)", &slot_15, QMetaData::Protected },
+ { "fillWindowPopup()", &slot_16, QMetaData::Protected },
+ { "sdiMinimizeButtonDestroyed()", &slot_17, QMetaData::Protected },
+ { "sdiRestoreButtonDestroyed()", &slot_18, QMetaData::Protected },
+ { "sdiCloseButtonDestroyed()", &slot_19, QMetaData::Protected },
+ { "sdiIconButtonDestroyed()", &slot_20, QMetaData::Protected }
+ };
+ static const QUMethod signal_0 = {"enteredSdiMode", 0, 0 };
+ static const QUMethod signal_1 = {"leftSdiMode", 0, 0 };
+ static const QMetaData signal_tbl[] = {
+ { "enteredSdiMode()", &signal_0, QMetaData::Private },
+ { "leftSdiMode()", &signal_1, QMetaData::Private }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviMdiManager", parentObject,
+ slot_tbl, 21,
+ signal_tbl, 2,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviMdiManager.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviMdiManager::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviMdiManager" ) )
+ return this;
+ return KviTalScrollView::qt_cast( clname );
+}
+
+// SIGNAL enteredSdiMode
+void KviMdiManager::enteredSdiMode()
+{
+ activate_signal( staticMetaObject()->signalOffset() + 0 );
+}
+
+// SIGNAL leftSdiMode
+void KviMdiManager::leftSdiMode()
+{
+ activate_signal( staticMetaObject()->signalOffset() + 1 );
+}
+
+bool KviMdiManager::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: relayoutMenuButtons(); break;
+ case 1: cascadeWindows(); break;
+ case 2: cascadeMaximized(); break;
+ case 3: expandVertical(); break;
+ case 4: expandHorizontal(); break;
+ case 5: minimizeAll(); break;
+ case 6: tile(); break;
+ case 7: toggleAutoTile(); break;
+ case 8: tileAnodine(); break;
+ case 9: reloadImages(); break;
+ case 10: minimizeActiveChild(); break;
+ case 11: restoreActiveChild(); break;
+ case 12: closeActiveChild(); break;
+ case 13: activeChildSystemPopup(); break;
+ case 14: menuActivated((int)static_QUType_int.get(_o+1)); break;
+ case 15: tileMethodMenuActivated((int)static_QUType_int.get(_o+1)); break;
+ case 16: fillWindowPopup(); break;
+ case 17: sdiMinimizeButtonDestroyed(); break;
+ case 18: sdiRestoreButtonDestroyed(); break;
+ case 19: sdiCloseButtonDestroyed(); break;
+ case 20: sdiIconButtonDestroyed(); break;
+ default:
+ return KviTalScrollView::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviMdiManager::qt_emit( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->signalOffset() ) {
+ case 0: enteredSdiMode(); break;
+ case 1: leftSdiMode(); break;
+ default:
+ return KviTalScrollView::qt_emit(_id,_o);
+ }
+ return TRUE;
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviMdiManager::qt_property( int id, int f, QVariant* v)
+{
+ return KviTalScrollView::qt_property( id, f, v);
+}
+
+bool KviMdiManager::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_statusbar.cpp b/src/kvirc/ui/moc_kvi_statusbar.cpp
new file mode 100644
index 0000000..d3cbf9c
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_statusbar.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+** KviStatusBar meta object code from reading C++ file 'kvi_statusbar.h'
+**
+** Created: Mon Feb 25 00:12:38 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_statusbar.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviStatusBar::className() const
+{
+ return "KviStatusBar";
+}
+
+QMetaObject *KviStatusBar::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviStatusBar( "KviStatusBar", &KviStatusBar::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviStatusBar::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBar", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviStatusBar::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBar", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviStatusBar::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QStatusBar::staticMetaObject();
+ static const QUMethod slot_0 = {"messageTimerFired", 0, 0 };
+ static const QUMethod slot_1 = {"contextPopupAboutToShow", 0, 0 };
+ static const QUMethod slot_2 = {"appletsPopupAboutToShow", 0, 0 };
+ static const QUParameter param_slot_3[] = {
+ { "id", &static_QUType_int, 0, QUParameter::In }
+ };
+ static const QUMethod slot_3 = {"appletsPopupActivated", 1, param_slot_3 };
+ static const QUMethod slot_4 = {"removeClickedApplet", 0, 0 };
+ static const QUMethod slot_5 = {"setPermanentMessage", 0, 0 };
+ static const QUParameter param_slot_6[] = {
+ { "pTip", &static_QUType_ptr, "KviDynamicToolTip", QUParameter::In },
+ { "pnt", &static_QUType_varptr, "\x0e", QUParameter::In }
+ };
+ static const QUMethod slot_6 = {"tipRequest", 2, param_slot_6 };
+ static const QMetaData slot_tbl[] = {
+ { "messageTimerFired()", &slot_0, QMetaData::Protected },
+ { "contextPopupAboutToShow()", &slot_1, QMetaData::Protected },
+ { "appletsPopupAboutToShow()", &slot_2, QMetaData::Protected },
+ { "appletsPopupActivated(int)", &slot_3, QMetaData::Protected },
+ { "removeClickedApplet()", &slot_4, QMetaData::Protected },
+ { "setPermanentMessage()", &slot_5, QMetaData::Protected },
+ { "tipRequest(KviDynamicToolTip*,const QPoint&)", &slot_6, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviStatusBar", parentObject,
+ slot_tbl, 7,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviStatusBar.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviStatusBar::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviStatusBar" ) )
+ return this;
+ return QStatusBar::qt_cast( clname );
+}
+
+bool KviStatusBar::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: messageTimerFired(); break;
+ case 1: contextPopupAboutToShow(); break;
+ case 2: appletsPopupAboutToShow(); break;
+ case 3: appletsPopupActivated((int)static_QUType_int.get(_o+1)); break;
+ case 4: removeClickedApplet(); break;
+ case 5: setPermanentMessage(); break;
+ case 6: tipRequest((KviDynamicToolTip*)static_QUType_ptr.get(_o+1),(const QPoint&)*((const QPoint*)static_QUType_ptr.get(_o+2))); break;
+ default:
+ return QStatusBar::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviStatusBar::qt_emit( int _id, QUObject* _o )
+{
+ return QStatusBar::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviStatusBar::qt_property( int id, int f, QVariant* v)
+{
+ return QStatusBar::qt_property( id, f, v);
+}
+
+bool KviStatusBar::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_statusbarapplet.cpp b/src/kvirc/ui/moc_kvi_statusbarapplet.cpp
new file mode 100644
index 0000000..85eb55e
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_statusbarapplet.cpp
@@ -0,0 +1,496 @@
+/****************************************************************************
+** KviStatusBarApplet meta object code from reading C++ file 'kvi_statusbarapplet.h'
+**
+** Created: Mon Feb 25 00:12:39 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_statusbarapplet.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviStatusBarApplet::className() const
+{
+ return "KviStatusBarApplet";
+}
+
+QMetaObject *KviStatusBarApplet::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviStatusBarApplet( "KviStatusBarApplet", &KviStatusBarApplet::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviStatusBarApplet::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarApplet", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviStatusBarApplet::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarApplet", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviStatusBarApplet::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QLabel::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviStatusBarApplet", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviStatusBarApplet.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviStatusBarApplet::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviStatusBarApplet" ) )
+ return this;
+ return QLabel::qt_cast( clname );
+}
+
+bool KviStatusBarApplet::qt_invoke( int _id, QUObject* _o )
+{
+ return QLabel::qt_invoke(_id,_o);
+}
+
+bool KviStatusBarApplet::qt_emit( int _id, QUObject* _o )
+{
+ return QLabel::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviStatusBarApplet::qt_property( int id, int f, QVariant* v)
+{
+ return QLabel::qt_property( id, f, v);
+}
+
+bool KviStatusBarApplet::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviStatusBarClock::className() const
+{
+ return "KviStatusBarClock";
+}
+
+QMetaObject *KviStatusBarClock::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviStatusBarClock( "KviStatusBarClock", &KviStatusBarClock::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviStatusBarClock::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarClock", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviStatusBarClock::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarClock", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviStatusBarClock::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviStatusBarApplet::staticMetaObject();
+ static const QUMethod slot_0 = {"toggleUtc", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "toggleUtc()", &slot_0, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviStatusBarClock", parentObject,
+ slot_tbl, 1,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviStatusBarClock.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviStatusBarClock::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviStatusBarClock" ) )
+ return this;
+ return KviStatusBarApplet::qt_cast( clname );
+}
+
+bool KviStatusBarClock::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: toggleUtc(); break;
+ default:
+ return KviStatusBarApplet::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviStatusBarClock::qt_emit( int _id, QUObject* _o )
+{
+ return KviStatusBarApplet::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviStatusBarClock::qt_property( int id, int f, QVariant* v)
+{
+ return KviStatusBarApplet::qt_property( id, f, v);
+}
+
+bool KviStatusBarClock::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviStatusBarConnectionTimer::className() const
+{
+ return "KviStatusBarConnectionTimer";
+}
+
+QMetaObject *KviStatusBarConnectionTimer::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviStatusBarConnectionTimer( "KviStatusBarConnectionTimer", &KviStatusBarConnectionTimer::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviStatusBarConnectionTimer::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarConnectionTimer", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviStatusBarConnectionTimer::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarConnectionTimer", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviStatusBarConnectionTimer::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviStatusBarApplet::staticMetaObject();
+ static const QUMethod slot_0 = {"toggleTotal", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "toggleTotal()", &slot_0, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviStatusBarConnectionTimer", parentObject,
+ slot_tbl, 1,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviStatusBarConnectionTimer.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviStatusBarConnectionTimer::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviStatusBarConnectionTimer" ) )
+ return this;
+ return KviStatusBarApplet::qt_cast( clname );
+}
+
+bool KviStatusBarConnectionTimer::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: toggleTotal(); break;
+ default:
+ return KviStatusBarApplet::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviStatusBarConnectionTimer::qt_emit( int _id, QUObject* _o )
+{
+ return KviStatusBarApplet::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviStatusBarConnectionTimer::qt_property( int id, int f, QVariant* v)
+{
+ return KviStatusBarApplet::qt_property( id, f, v);
+}
+
+bool KviStatusBarConnectionTimer::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviStatusBarSeparator::className() const
+{
+ return "KviStatusBarSeparator";
+}
+
+QMetaObject *KviStatusBarSeparator::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviStatusBarSeparator( "KviStatusBarSeparator", &KviStatusBarSeparator::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviStatusBarSeparator::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarSeparator", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviStatusBarSeparator::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarSeparator", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviStatusBarSeparator::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviStatusBarApplet::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviStatusBarSeparator", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviStatusBarSeparator.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviStatusBarSeparator::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviStatusBarSeparator" ) )
+ return this;
+ return KviStatusBarApplet::qt_cast( clname );
+}
+
+bool KviStatusBarSeparator::qt_invoke( int _id, QUObject* _o )
+{
+ return KviStatusBarApplet::qt_invoke(_id,_o);
+}
+
+bool KviStatusBarSeparator::qt_emit( int _id, QUObject* _o )
+{
+ return KviStatusBarApplet::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviStatusBarSeparator::qt_property( int id, int f, QVariant* v)
+{
+ return KviStatusBarApplet::qt_property( id, f, v);
+}
+
+bool KviStatusBarSeparator::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviStatusBarAwayIndicator::className() const
+{
+ return "KviStatusBarAwayIndicator";
+}
+
+QMetaObject *KviStatusBarAwayIndicator::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviStatusBarAwayIndicator( "KviStatusBarAwayIndicator", &KviStatusBarAwayIndicator::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviStatusBarAwayIndicator::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarAwayIndicator", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviStatusBarAwayIndicator::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarAwayIndicator", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviStatusBarAwayIndicator::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviStatusBarApplet::staticMetaObject();
+ static const QUMethod slot_0 = {"updateDisplay", 0, 0 };
+ static const QUMethod slot_1 = {"toggleContext", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "updateDisplay()", &slot_0, QMetaData::Protected },
+ { "toggleContext()", &slot_1, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviStatusBarAwayIndicator", parentObject,
+ slot_tbl, 2,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviStatusBarAwayIndicator.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviStatusBarAwayIndicator::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviStatusBarAwayIndicator" ) )
+ return this;
+ return KviStatusBarApplet::qt_cast( clname );
+}
+
+bool KviStatusBarAwayIndicator::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: updateDisplay(); break;
+ case 1: toggleContext(); break;
+ default:
+ return KviStatusBarApplet::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviStatusBarAwayIndicator::qt_emit( int _id, QUObject* _o )
+{
+ return KviStatusBarApplet::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviStatusBarAwayIndicator::qt_property( int id, int f, QVariant* v)
+{
+ return KviStatusBarApplet::qt_property( id, f, v);
+}
+
+bool KviStatusBarAwayIndicator::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviStatusBarLagIndicator::className() const
+{
+ return "KviStatusBarLagIndicator";
+}
+
+QMetaObject *KviStatusBarLagIndicator::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviStatusBarLagIndicator( "KviStatusBarLagIndicator", &KviStatusBarLagIndicator::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviStatusBarLagIndicator::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarLagIndicator", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviStatusBarLagIndicator::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviStatusBarLagIndicator", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviStatusBarLagIndicator::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = KviStatusBarApplet::staticMetaObject();
+ static const QUMethod slot_0 = {"updateDisplay", 0, 0 };
+ static const QMetaData slot_tbl[] = {
+ { "updateDisplay()", &slot_0, QMetaData::Protected }
+ };
+ metaObj = QMetaObject::new_metaobject(
+ "KviStatusBarLagIndicator", parentObject,
+ slot_tbl, 1,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviStatusBarLagIndicator.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviStatusBarLagIndicator::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviStatusBarLagIndicator" ) )
+ return this;
+ return KviStatusBarApplet::qt_cast( clname );
+}
+
+bool KviStatusBarLagIndicator::qt_invoke( int _id, QUObject* _o )
+{
+ switch ( _id - staticMetaObject()->slotOffset() ) {
+ case 0: updateDisplay(); break;
+ default:
+ return KviStatusBarApplet::qt_invoke( _id, _o );
+ }
+ return TRUE;
+}
+
+bool KviStatusBarLagIndicator::qt_emit( int _id, QUObject* _o )
+{
+ return KviStatusBarApplet::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviStatusBarLagIndicator::qt_property( int id, int f, QVariant* v)
+{
+ return KviStatusBarApplet::qt_property( id, f, v);
+}
+
+bool KviStatusBarLagIndicator::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
diff --git a/src/kvirc/ui/moc_kvi_toolwindows_container.cpp b/src/kvirc/ui/moc_kvi_toolwindows_container.cpp
new file mode 100644
index 0000000..dc5a24f
--- /dev/null
+++ b/src/kvirc/ui/moc_kvi_toolwindows_container.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+** KviWindowToolWidget meta object code from reading C++ file 'kvi_toolwindows_container.h'
+**
+** Created: Mon Feb 25 00:12:41 2008
+** by: The Qt MOC ($Id: qt/moc_yacc.cpp 3.3.8 edited Feb 2 14:59 $)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#undef QT_NO_COMPAT
+#include "kvi_toolwindows_container.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+#include <private/qucomextra_p.h>
+#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
+#error "This file was generated using the moc from 3.3.8. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+const char *KviWindowToolWidget::className() const
+{
+ return "KviWindowToolWidget";
+}
+
+QMetaObject *KviWindowToolWidget::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviWindowToolWidget( "KviWindowToolWidget", &KviWindowToolWidget::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviWindowToolWidget::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviWindowToolWidget", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviWindowToolWidget::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviWindowToolWidget", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviWindowToolWidget::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = QWidget::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviWindowToolWidget", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviWindowToolWidget.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviWindowToolWidget::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviWindowToolWidget" ) )
+ return this;
+ return QWidget::qt_cast( clname );
+}
+
+bool KviWindowToolWidget::qt_invoke( int _id, QUObject* _o )
+{
+ return QWidget::qt_invoke(_id,_o);
+}
+
+bool KviWindowToolWidget::qt_emit( int _id, QUObject* _o )
+{
+ return QWidget::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviWindowToolWidget::qt_property( int id, int f, QVariant* v)
+{
+ return QWidget::qt_property( id, f, v);
+}
+
+bool KviWindowToolWidget::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES
+
+
+const char *KviWindowToolPageButton::className() const
+{
+ return "KviWindowToolPageButton";
+}
+
+QMetaObject *KviWindowToolPageButton::metaObj = 0;
+static QMetaObjectCleanUp cleanUp_KviWindowToolPageButton( "KviWindowToolPageButton", &KviWindowToolPageButton::staticMetaObject );
+
+#ifndef QT_NO_TRANSLATION
+QString KviWindowToolPageButton::tr( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviWindowToolPageButton", s, c, QApplication::DefaultCodec );
+ else
+ return QString::fromLatin1( s );
+}
+#ifndef QT_NO_TRANSLATION_UTF8
+QString KviWindowToolPageButton::trUtf8( const char *s, const char *c )
+{
+ if ( qApp )
+ return qApp->translate( "KviWindowToolPageButton", s, c, QApplication::UnicodeUTF8 );
+ else
+ return QString::fromUtf8( s );
+}
+#endif // QT_NO_TRANSLATION_UTF8
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* KviWindowToolPageButton::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ QMetaObject* parentObject = TOOL_PAGE_PARENT::staticMetaObject();
+ metaObj = QMetaObject::new_metaobject(
+ "KviWindowToolPageButton", parentObject,
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ cleanUp_KviWindowToolPageButton.setMetaObject( metaObj );
+ return metaObj;
+}
+
+void* KviWindowToolPageButton::qt_cast( const char* clname )
+{
+ if ( !qstrcmp( clname, "KviWindowToolPageButton" ) )
+ return this;
+ return TOOL_PAGE_PARENT::qt_cast( clname );
+}
+
+bool KviWindowToolPageButton::qt_invoke( int _id, QUObject* _o )
+{
+ return TOOL_PAGE_PARENT::qt_invoke(_id,_o);
+}
+
+bool KviWindowToolPageButton::qt_emit( int _id, QUObject* _o )
+{
+ return TOOL_PAGE_PARENT::qt_emit(_id,_o);
+}
+#ifndef QT_NO_PROPERTIES
+
+bool KviWindowToolPageButton::qt_property( int id, int f, QVariant* v)
+{
+ return TOOL_PAGE_PARENT::qt_property( id, f, v);
+}
+
+bool KviWindowToolPageButton::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
+#endif // QT_NO_PROPERTIES