From a6d58bb6052ac8cb01805a48c4ad2f129126116f Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 24 Feb 2010 02:13:59 +0000 Subject: Added KDE3 version of kvirc git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kvirc@1095341 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/kvirc/ui/Makefile.am | 5 + src/kvirc/ui/kvi_actiondrawer.cpp | 227 ++ src/kvirc/ui/kvi_actiondrawer.h | 107 + src/kvirc/ui/kvi_channel.cpp | 1628 ++++++++ src/kvirc/ui/kvi_channel.h | 313 ++ src/kvirc/ui/kvi_colorwin.cpp | 122 + src/kvirc/ui/kvi_colorwin.h | 47 + src/kvirc/ui/kvi_console.cpp | 1283 ++++++ src/kvirc/ui/kvi_console.h | 212 + src/kvirc/ui/kvi_cryptcontroller.cpp | 390 ++ src/kvirc/ui/kvi_cryptcontroller.h | 116 + src/kvirc/ui/kvi_ctcppagedialog.cpp | 147 + src/kvirc/ui/kvi_ctcppagedialog.h | 56 + src/kvirc/ui/kvi_customtoolbar.cpp | 670 +++ src/kvirc/ui/kvi_customtoolbar.h | 91 + src/kvirc/ui/kvi_debugwindow.cpp | 132 + src/kvirc/ui/kvi_debugwindow.h | 54 + src/kvirc/ui/kvi_dynamictooltip.cpp | 61 + src/kvirc/ui/kvi_dynamictooltip.h | 61 + src/kvirc/ui/kvi_filedialog.cpp | 229 ++ src/kvirc/ui/kvi_filedialog.h | 55 + src/kvirc/ui/kvi_frame.cpp | 1450 +++++++ src/kvirc/ui/kvi_frame.h | 259 ++ src/kvirc/ui/kvi_historywin.cpp | 255 ++ src/kvirc/ui/kvi_historywin.h | 61 + src/kvirc/ui/kvi_htmldialog.cpp | 155 + src/kvirc/ui/kvi_htmldialog.h | 87 + src/kvirc/ui/kvi_imagedialog.cpp | 367 ++ src/kvirc/ui/kvi_imagedialog.h | 109 + src/kvirc/ui/kvi_input.cpp | 2680 ++++++++++++ src/kvirc/ui/kvi_input.h | 262 ++ src/kvirc/ui/kvi_ipeditor.cpp | 453 +++ src/kvirc/ui/kvi_ipeditor.h | 62 + src/kvirc/ui/kvi_irctoolbar.cpp | 441 ++ src/kvirc/ui/kvi_irctoolbar.h | 95 + src/kvirc/ui/kvi_ircview.cpp | 5161 ++++++++++++++++++++++++ src/kvirc/ui/kvi_ircview.h | 252 ++ src/kvirc/ui/kvi_ircviewprivate.h | 164 + src/kvirc/ui/kvi_ircviewtools.cpp | 348 ++ src/kvirc/ui/kvi_ircviewtools.h | 119 + src/kvirc/ui/kvi_listview.cpp | 212 + src/kvirc/ui/kvi_listview.h | 58 + src/kvirc/ui/kvi_maskeditor.cpp | 350 ++ src/kvirc/ui/kvi_maskeditor.h | 108 + src/kvirc/ui/kvi_mdicaption.cpp | 285 ++ src/kvirc/ui/kvi_mdicaption.h | 101 + src/kvirc/ui/kvi_mdichild.cpp | 576 +++ src/kvirc/ui/kvi_mdichild.h | 122 + src/kvirc/ui/kvi_mdimanager.cpp | 1126 ++++++ src/kvirc/ui/kvi_mdimanager.h | 144 + src/kvirc/ui/kvi_menubar.cpp | 415 ++ src/kvirc/ui/kvi_menubar.h | 83 + src/kvirc/ui/kvi_modeeditor.cpp | 336 ++ src/kvirc/ui/kvi_modeeditor.h | 70 + src/kvirc/ui/kvi_modew.cpp | 175 + src/kvirc/ui/kvi_modew.h | 57 + src/kvirc/ui/kvi_msgbox.cpp | 89 + src/kvirc/ui/kvi_msgbox.h | 53 + src/kvirc/ui/kvi_optionswidget.cpp | 722 ++++ src/kvirc/ui/kvi_optionswidget.h | 163 + src/kvirc/ui/kvi_query.cpp | 659 +++ src/kvirc/ui/kvi_query.h | 95 + src/kvirc/ui/kvi_scriptbutton.cpp | 98 + src/kvirc/ui/kvi_scriptbutton.h | 79 + src/kvirc/ui/kvi_scripteditor.cpp | 139 + src/kvirc/ui/kvi_scripteditor.h | 69 + src/kvirc/ui/kvi_selectors.cpp | 839 ++++ src/kvirc/ui/kvi_selectors.h | 367 ++ src/kvirc/ui/kvi_splash.cpp | 222 + src/kvirc/ui/kvi_splash.h | 72 + src/kvirc/ui/kvi_statusbar.cpp | 643 +++ src/kvirc/ui/kvi_statusbar.h | 130 + src/kvirc/ui/kvi_statusbarapplet.cpp | 563 +++ src/kvirc/ui/kvi_statusbarapplet.h | 195 + src/kvirc/ui/kvi_styled_controls.cpp | 373 ++ src/kvirc/ui/kvi_styled_controls.h | 113 + src/kvirc/ui/kvi_taskbar.cpp | 1509 +++++++ src/kvirc/ui/kvi_taskbar.h | 312 ++ src/kvirc/ui/kvi_texticonwin.cpp | 283 ++ src/kvirc/ui/kvi_texticonwin.h | 64 + src/kvirc/ui/kvi_themedlabel.cpp | 154 + src/kvirc/ui/kvi_themedlabel.h | 62 + src/kvirc/ui/kvi_toolbar.cpp | 160 + src/kvirc/ui/kvi_toolbar.h | 52 + src/kvirc/ui/kvi_toolwindows_container.cpp | 140 + src/kvirc/ui/kvi_toolwindows_container.h | 65 + src/kvirc/ui/kvi_topicw.cpp | 834 ++++ src/kvirc/ui/kvi_topicw.h | 120 + src/kvirc/ui/kvi_userlistview.cpp | 1972 +++++++++ src/kvirc/ui/kvi_userlistview.h | 259 ++ src/kvirc/ui/kvi_window.cpp | 1518 +++++++ src/kvirc/ui/kvi_window.h | 393 ++ src/kvirc/ui/moc_kvi_actiondrawer.cpp | 238 ++ src/kvirc/ui/moc_kvi_customtoolbar.cpp | 180 + src/kvirc/ui/moc_kvi_debugwindow.cpp | 92 + src/kvirc/ui/moc_kvi_htmldialog.cpp | 107 + src/kvirc/ui/moc_kvi_imagedialog.cpp | 126 + src/kvirc/ui/moc_kvi_ircviewtools.cpp | 116 + src/kvirc/ui/moc_kvi_listview.cpp | 92 + src/kvirc/ui/moc_kvi_mdicaption.cpp | 238 ++ src/kvirc/ui/moc_kvi_mdichild.cpp | 141 + src/kvirc/ui/moc_kvi_mdimanager.cpp | 191 + src/kvirc/ui/moc_kvi_statusbar.cpp | 126 + src/kvirc/ui/moc_kvi_statusbarapplet.cpp | 496 +++ src/kvirc/ui/moc_kvi_toolwindows_container.cpp | 165 + 105 files changed, 38892 insertions(+) create mode 100644 src/kvirc/ui/Makefile.am create mode 100644 src/kvirc/ui/kvi_actiondrawer.cpp create mode 100644 src/kvirc/ui/kvi_actiondrawer.h create mode 100644 src/kvirc/ui/kvi_channel.cpp create mode 100644 src/kvirc/ui/kvi_channel.h create mode 100644 src/kvirc/ui/kvi_colorwin.cpp create mode 100644 src/kvirc/ui/kvi_colorwin.h create mode 100644 src/kvirc/ui/kvi_console.cpp create mode 100644 src/kvirc/ui/kvi_console.h create mode 100644 src/kvirc/ui/kvi_cryptcontroller.cpp create mode 100644 src/kvirc/ui/kvi_cryptcontroller.h create mode 100644 src/kvirc/ui/kvi_ctcppagedialog.cpp create mode 100644 src/kvirc/ui/kvi_ctcppagedialog.h create mode 100644 src/kvirc/ui/kvi_customtoolbar.cpp create mode 100644 src/kvirc/ui/kvi_customtoolbar.h create mode 100644 src/kvirc/ui/kvi_debugwindow.cpp create mode 100644 src/kvirc/ui/kvi_debugwindow.h create mode 100644 src/kvirc/ui/kvi_dynamictooltip.cpp create mode 100644 src/kvirc/ui/kvi_dynamictooltip.h create mode 100644 src/kvirc/ui/kvi_filedialog.cpp create mode 100644 src/kvirc/ui/kvi_filedialog.h create mode 100644 src/kvirc/ui/kvi_frame.cpp create mode 100644 src/kvirc/ui/kvi_frame.h create mode 100644 src/kvirc/ui/kvi_historywin.cpp create mode 100644 src/kvirc/ui/kvi_historywin.h create mode 100644 src/kvirc/ui/kvi_htmldialog.cpp create mode 100644 src/kvirc/ui/kvi_htmldialog.h create mode 100644 src/kvirc/ui/kvi_imagedialog.cpp create mode 100644 src/kvirc/ui/kvi_imagedialog.h create mode 100644 src/kvirc/ui/kvi_input.cpp create mode 100644 src/kvirc/ui/kvi_input.h create mode 100644 src/kvirc/ui/kvi_ipeditor.cpp create mode 100644 src/kvirc/ui/kvi_ipeditor.h create mode 100644 src/kvirc/ui/kvi_irctoolbar.cpp create mode 100644 src/kvirc/ui/kvi_irctoolbar.h create mode 100644 src/kvirc/ui/kvi_ircview.cpp create mode 100644 src/kvirc/ui/kvi_ircview.h create mode 100644 src/kvirc/ui/kvi_ircviewprivate.h create mode 100644 src/kvirc/ui/kvi_ircviewtools.cpp create mode 100644 src/kvirc/ui/kvi_ircviewtools.h create mode 100644 src/kvirc/ui/kvi_listview.cpp create mode 100644 src/kvirc/ui/kvi_listview.h create mode 100644 src/kvirc/ui/kvi_maskeditor.cpp create mode 100644 src/kvirc/ui/kvi_maskeditor.h create mode 100644 src/kvirc/ui/kvi_mdicaption.cpp create mode 100644 src/kvirc/ui/kvi_mdicaption.h create mode 100644 src/kvirc/ui/kvi_mdichild.cpp create mode 100644 src/kvirc/ui/kvi_mdichild.h create mode 100644 src/kvirc/ui/kvi_mdimanager.cpp create mode 100644 src/kvirc/ui/kvi_mdimanager.h create mode 100644 src/kvirc/ui/kvi_menubar.cpp create mode 100644 src/kvirc/ui/kvi_menubar.h create mode 100644 src/kvirc/ui/kvi_modeeditor.cpp create mode 100644 src/kvirc/ui/kvi_modeeditor.h create mode 100755 src/kvirc/ui/kvi_modew.cpp create mode 100755 src/kvirc/ui/kvi_modew.h create mode 100644 src/kvirc/ui/kvi_msgbox.cpp create mode 100644 src/kvirc/ui/kvi_msgbox.h create mode 100644 src/kvirc/ui/kvi_optionswidget.cpp create mode 100644 src/kvirc/ui/kvi_optionswidget.h create mode 100644 src/kvirc/ui/kvi_query.cpp create mode 100644 src/kvirc/ui/kvi_query.h create mode 100644 src/kvirc/ui/kvi_scriptbutton.cpp create mode 100644 src/kvirc/ui/kvi_scriptbutton.h create mode 100644 src/kvirc/ui/kvi_scripteditor.cpp create mode 100644 src/kvirc/ui/kvi_scripteditor.h create mode 100644 src/kvirc/ui/kvi_selectors.cpp create mode 100644 src/kvirc/ui/kvi_selectors.h create mode 100644 src/kvirc/ui/kvi_splash.cpp create mode 100644 src/kvirc/ui/kvi_splash.h create mode 100644 src/kvirc/ui/kvi_statusbar.cpp create mode 100644 src/kvirc/ui/kvi_statusbar.h create mode 100644 src/kvirc/ui/kvi_statusbarapplet.cpp create mode 100644 src/kvirc/ui/kvi_statusbarapplet.h create mode 100644 src/kvirc/ui/kvi_styled_controls.cpp create mode 100644 src/kvirc/ui/kvi_styled_controls.h create mode 100644 src/kvirc/ui/kvi_taskbar.cpp create mode 100644 src/kvirc/ui/kvi_taskbar.h create mode 100644 src/kvirc/ui/kvi_texticonwin.cpp create mode 100644 src/kvirc/ui/kvi_texticonwin.h create mode 100644 src/kvirc/ui/kvi_themedlabel.cpp create mode 100644 src/kvirc/ui/kvi_themedlabel.h create mode 100644 src/kvirc/ui/kvi_toolbar.cpp create mode 100644 src/kvirc/ui/kvi_toolbar.h create mode 100644 src/kvirc/ui/kvi_toolwindows_container.cpp create mode 100644 src/kvirc/ui/kvi_toolwindows_container.h create mode 100644 src/kvirc/ui/kvi_topicw.cpp create mode 100644 src/kvirc/ui/kvi_topicw.h create mode 100644 src/kvirc/ui/kvi_userlistview.cpp create mode 100644 src/kvirc/ui/kvi_userlistview.h create mode 100644 src/kvirc/ui/kvi_window.cpp create mode 100644 src/kvirc/ui/kvi_window.h create mode 100644 src/kvirc/ui/moc_kvi_actiondrawer.cpp create mode 100644 src/kvirc/ui/moc_kvi_customtoolbar.cpp create mode 100644 src/kvirc/ui/moc_kvi_debugwindow.cpp create mode 100644 src/kvirc/ui/moc_kvi_htmldialog.cpp create mode 100644 src/kvirc/ui/moc_kvi_imagedialog.cpp create mode 100644 src/kvirc/ui/moc_kvi_ircviewtools.cpp create mode 100644 src/kvirc/ui/moc_kvi_listview.cpp create mode 100644 src/kvirc/ui/moc_kvi_mdicaption.cpp create mode 100644 src/kvirc/ui/moc_kvi_mdichild.cpp create mode 100644 src/kvirc/ui/moc_kvi_mdimanager.cpp create mode 100644 src/kvirc/ui/moc_kvi_statusbar.cpp create mode 100644 src/kvirc/ui/moc_kvi_statusbarapplet.cpp create mode 100644 src/kvirc/ui/moc_kvi_toolwindows_container.cpp (limited to 'src/kvirc/ui') 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 +############################################################################### + +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 +// +// 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 +#include +//#include +#include +#include +#ifdef COMPILE_USE_QT4 + #include + #include + #include + #include +#else + #include + #include +#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 = "" + a->visibleName() + ""; + if(a->isKviUserActionNeverOverrideThis()) + t += " [" + __tr2qs("Script") + "]"; + t += "
" + a->description()+ ""; + 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 = "" + szDescription + ""; + 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 pages; + pages.setAutoDelete(false); + + KviPointerHashTable * d = KviActionManager::instance()->actions(); + if(!d)return; // ooops + + KviPointerHashTableIterator 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 +// +// 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 +#include + +#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 + +#include +#include +#include +#include + +#include +#include "kvi_tal_popupmenu.h" +#include "kvi_pointerhashtable.h" +#include +#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; + m_pBanList->setAutoDelete(true); + m_pBanExceptionList = new KviPointerList; + m_pBanExceptionList->setAutoDelete(true); + m_pInviteList = new KviPointerList; + m_pInviteList->setAutoDelete(true); + m_pActionHistory = new KviPointerList; + m_pActionHistory->setAutoDelete(true); + m_uActionHistoryHotActionCount = 0; + + m_pTmpHighLighted = new KviPointerHashTable(); + 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 tmp = m_pVertSplitter->sizes(); + KviValueList tmp2; + for(QList::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 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 *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 *)), + this,SLOT(removeMasks(KviMaskEditor *,KviPointerList *))); + //setFocusHandler(m_pInput,*ppEd); //socket it! + (*ppEd)->show(); + if(!(*ppBtn))return; + if(!((*ppBtn)->isOn()))(*ppBtn)->setOn(true); + } +} + +void KviChannel::removeMasks(KviMaskEditor *ed,KviPointerList *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 += ""; + buffer += l.first(); + buffer += ""; + buffer += " "; + buffer += bPast ? __tr2qs("said something recently") : __tr2qs("is talking"); + } else if(l.count() == 2) + { + buffer += ""; + buffer += l.first(); + buffer += " "; + buffer += __tr2qs("and"); + buffer += " "; + l.remove(l.begin()); + buffer += l.first(); + buffer += " "; + buffer += bPast ? __tr2qs("were talking recently") : __tr2qs("are talking"); + } else { + buffer += ""; + buffer += l.first(); + buffer += ", "; + l.remove(l.begin()); + buffer += l.first(); + if(l.count() == 2) + { + buffer += " "; + buffer += __tr2qs("and"); + buffer += " "; + l.remove(l.begin()); + buffer += l.first(); + buffer += ""; + } else { + // (l.count() - 1) is > 1 + buffer += " "; + 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(""); + static QString html_tab("  "); + static QString html_eofbold(" "); + static QString p5(" ("); + // p6 == p4 + static QString p7(" ("); + static QString p8(": "); + static QString p9(")"); + static QString p10("
"); + + static QString end_of_doc = ""; + static QString end_of_fontboldrow = END_TABLE_BOLD_ROW; + static QString start_of_row = ""; + static QString end_of_row = ""; + + buffer = "" \ + "" \ + ""\ + 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 += ""; + buffer += p7; + + buffer += __tr2qs("humanity"); + + buffer += p8; + buffer += html_bold; + + num.setNum(s.iAvgTemperature); + + buffer += num; + buffer += ""; + + buffer += p9; +*/ + buffer += p10; + buffer += ""; + + + + ////////////////////// + + 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 += ""; + + buffer += end_of_doc; +} + +void KviChannel::fillCaptionBuffers() +{ + static QString begin(""); + static QString endofbold(" "); + static QString end(""); + + 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 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 * 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 *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("Channel mode:"); + //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,"
%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("
Key: %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("
Limit: %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 +#include "kvi_pointerhashtable.h" +#include + +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 * m_pBanList; + KviPointerList * m_pBanExceptionList; + KviPointerList * m_pInviteList; + KviPixmap m_privateBackground; + QDateTime m_joinTime; + QString m_szNameWithUserFlag; + KviPointerHashTable * m_pTmpHighLighted; + unsigned int m_uActionHistoryHotActionCount; + KviPointerList * m_pActionHistory; + kvi_time_t m_tLastReceivedWhoReply; + KviValueList 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 *l,char flag,const char *edName); + void internalMask(const QString &mask,bool bAdd,const QString &setBy,unsigned int setAt,KviPointerList *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 * banList(){ return m_pBanList; }; + KviPointerList * banExceptionList(){ return m_pBanExceptionList; }; + KviPointerList * 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 *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 +#include +#include +#include + + +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 + +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 +#include +#include +#include +#include "kvi_tal_hbox.h" +#include "kvi_tal_popupmenu.h" +#include +#include + +#ifdef COMPILE_USE_QT4 + #include +#endif + +#define __KVI_DEBUG__ +#include "kvi_debug.h" + +#ifdef COMPILE_USE_QT4 + #include +#else + #include +#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 * 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 * 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 = "
"; + getTalkingUsersStats(buffer,cas.lWereTalkingUsers,true); + buffer += end_of_row; + } + buffer += "
"; + getTalkingUsersStats(buffer,cas.lTalkingUsers,false); + buffer += end_of_row; + } else { + if(cas.lWereTalkingUsers.count() > 0) + { + buffer += "
"; + getTalkingUsersStats(buffer,cas.lWereTalkingUsers,true); + buffer += end_of_row; + } + } + + buffer += "
"; + + 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 += "
" \ + ""; + if(u) + { + QString szComment=u->user()->getProperty("comment"); + if(!szComment.isEmpty()) + { + buffer += ""; + } + } + 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("").arg(e->avatar()->pixmap()->width()); + } + + if(e->hasRealName()) + { + buffer += ""; + } + + if(e->gender()!=KviIrcUserEntry::Unknown) + { + buffer += ""; + } + + if(u) + { + QString mask; + u->mask()->mask(mask); + buffer += ""; + } + + if(connection()) + { + QString chans; + if(connection()->getCommonChannels(nick,chans,false)) + { + buffer += ""; + } + } + + if(e->hasServer()) + { + buffer += ""; + } else { + buffer += "
" \ + "
"; + + buffer += nick; + buffer += "!"; + buffer += e->user().isEmpty() ? QString("*") : e->user(); + buffer += "@"; + buffer += e->host().isEmpty() ? QString("*") : e->host(); + + + buffer += "
("; + buffer += szComment; + buffer += ")
"; + buffer += KviMircCntrl::stripControlBytes(e->realName()); + buffer += "
"; + buffer += __tr2qs("Gender:"); + buffer += " "; + buffer += (e->gender()==KviIrcUserEntry::Male) ? __tr2qs("Male") : __tr2qs("Female"); + buffer += "
"; + buffer += __tr2qs("Registered as"); + buffer += " "; + buffer += u->user()->name(); + buffer += "; Group "; + buffer += u->user()->group(); + buffer += "
"; + buffer += __tr2qs("(Matched by"); + buffer += " "; + buffer += mask; + buffer += ")
"; + buffer += __tr2qs("On "); + buffer += chans; + buffer += "
"; + buffer += __tr2qs("Using server %1").arg(e->server()); + + if(e->hasHops()) + { + buffer += " ("; + buffer += __tr2qs("%1 hops").arg(e->hops()); + buffer += ")
"; + } + } + + if(e->isAway()) + { + buffer += ""; + buffer += __tr2qs("Probably Away"); + buffer += ""; + } +} + + +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 def; + def.append((w * 85) / 100); + def.append((w * 15) / 100); + KviValueList 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 = "<"; + szMsg += nick; + szMsg += "> "; + #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); + } + } + } + } + + // nick[!user@host]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 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(""); + static QString endofbold(" "); + static QString end(""); + + 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(""); + static QString html_tab("  "); + static QString html_eofbold(""); + static QString html_hrbr("

"); + 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("
"); + static QString html_spaceparopen(" ("); + static QString html_spaceparclosed(")"); + + buffer = "" \ + 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 += ""; + } + + 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 += ""; + } + + buffer += "
"; + 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 += "
"; + + 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 += "
"; +} + +#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 +#include + + +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 and QList + #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 + 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 * channelList(){ return connection() ? connection()->channelList() : 0; }; + KVI_DEPRECATED KviPointerList * 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 * matches); + void completeServer(const QString &word,KviPointerList * 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 + #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 * a = g_pCryptEngineManager->engineDict(); + if(a) + { + KviPointerHashTableIterator 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 = "

"; + des += eit->m_szDescription.ptr(); + des += "

"; + 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 + #include "kvi_tal_listbox.h" + #include + #include + #include + #include + #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 +#include +#include +#include + +#ifdef COMPILE_USE_QT4 + #include +#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 = "

"; + tmp += __tr2qs("You have been paged by"); + tmp += "
"; + tmp += szNick; + tmp += " ["; + tmp += szUser; + tmp += "@"; + tmp += szHost; + tmp += "]:

"; + tmp += szMsg; + tmp += "

["; + tmp += date; + tmp += "]
"; + + 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 +#include +#include + +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 +// +// 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 +#include "kvi_tal_popupmenu.h" +#include +#include +#include +#include +#include +#include + +#ifdef COMPILE_USE_QT4 + #include + #include + + #define QDragObject Q3DragObject + #define QTextDrag Q3TextDrag + #define QIconDrag Q3IconDrag + + #include +#else + #include + #include +#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; + m_pFilteredChildren->setAutoDelete(true); + // filter the events for all the children +#ifdef COMPILE_USE_QT4 + QList l = children(); + for(QList::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 l = children(); + for(QList::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 +// +// 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 * 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 +#include +#include + +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 def; + def.append((w * 80) / 100); + def.append((w * 20) / 100); + m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def)); +} + +void KviDebugWindow::fillCaptionBuffers() +{ + static QString begin(""); + static QString end(""); + + 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 + +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 +#include "kvi_tal_tooltip.h" +#include + +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.
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.
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 + + +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 +#include +#include +#include +#include + +#include +#include + +#if QT_VERSION >= 300 + #include + #include + #ifdef COMPILE_USE_QT4 + #include + #define QDockArea Q3DockArea + #else + #include + #endif +#endif + + +#ifdef COMPILE_USE_QT4 + #include + #include + #include +#else + #include +#endif + +#include + +#ifdef COMPILE_PSEUDO_TRANSPARENCY + #include + // 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; + m_pWinList->setAutoDelete(false); + + m_pModuleExtensionToolBarList = new KviPointerList; + 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+<digit>[/b], [b]F1-F12[/b], [b]Shift+(F1-F12)[/b]: Script accelerators (see [event:onaccelkeypressed]OnAccelKeyPressed[/event])[br] + [b]Shift+<F1-F12>[/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>[/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] + + 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) + +*/ + +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 = "

"; + txt += __tr2qs("There are active connections, are you sure you wish to "); + txt += __tr2qs("quit KVIrc?"); + txt += "

"; + + 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 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 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 * m_pModuleExtensionToolBarList; // the module extension toolbars + KviTaskBarBase * m_pTaskBar; // the taskbar + KviStatusBar * m_pStatusBar; + // the mdi workspace child windows + KviPointerList * 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 * 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 + +#ifdef COMPILE_USE_QT4 + #include +#endif + +#include + +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= 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 +// +// 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 +#include +#include +#include + +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 +// +// 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 +#include + +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 +#include + +#include +#include +#include + +#include + +#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; + + 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 += "

"; + 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 += "

"; + QString sz; + sz.setNum(i.width()); + tip += sz; + tip += " x "; + sz.setNum(i.height()); + tip += sz; + tip += " "; + tip += __tr2qs("pixels"); + tip += "
"; + sz.setNum(fi.size()); + tip += sz; + tip += " "; + tip += __tr2qs("bytes"); + tip += "
"; + + 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 +#include +#include "kvi_tal_listbox.h" +#include "kvi_valuelist.h" +#include +#include + +#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 * 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 +#include +#include +#include +#include "kvi_tal_popupmenu.h" +#include +#include +#include +#include "kvi_pointerlist.h" +#include +#include +#include +#include "kvi_tal_hbox.h" +#include +#include +#include + + +#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 + #undef QT_CLEAN_NAMESPACE + #else + #include + #endif +#else + #include +#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; + 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;icount()); + + 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; + 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_iSelectionEnddrawPixmap(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('&'),"&"); + szClip.replace(QChar('<'),"<"); + szClip.replace(QChar('>'),">"); + szClip.replace(QChar('\n'),"
"); + + QString label = "
"; + label += __tr2qs("Clipboard"); + label += ":
"; + label += szClip; + label += "
"; + + QString num; + num.setNum(occ); + + label += num; + label += QChar(' '); + label += (occ == 1) ? __tr2qs("line break") : __tr2qs("line breaks"); + label += "
"; + + 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 * d = g_pTextIconManager->textIconDict(); + KviPointerHashTableIterator 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 */ +// 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 , 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 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 + "<0x1d>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] + <icon escape> := character 0x1d (ASCII group separator)[br] + <icon token> := 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
+ Ctrl+K: Inserts the 'color' mIRC text control character
+ Ctrl+R: Inserts the 'reverse' mIRC text control character
+ Ctrl+U: Inserts the 'underline' mIRC text control character
+ Ctrl+O: Inserts the 'reset' mIRC text control character
+ Ctrl+P: Inserts the 'non-crypt' (plain text) KVIrc control character used to disable encryption of the current text line
+ Ctrl+C: Copies the selected text to clipboard
+ Ctrl+X: Cuts the selected text
+ Ctrl+V: Pastes the clipboard contents (same as middle mouse click)
+ Ctrl+I: Inserts the 'icon' control code and pops up the icon list box
+ Ctrl+A: Select all
+ CursorUp: Moves backward in the command history
+ CursorDown: Moves forward in the command history
+ CursorRight: Moves the cursor to the right
+ CursorLeft: Moves the cursor to the left :)
+ Shift+CursorLeft: Moves the selection to the left
+ Shift+RightCursor: Moves the selection to the right
+ Ctrl+CursorLeft: Moves the cursor one word left
+ Ctrl+CursorRight: Moves the cursor one word right
+ Ctrl+Shift+CursorLeft: Moves the selection one word left
+ Ctrl+Shift+CursorRight: Moves the selection one word right
+ Tab: Nickname, function/command, or filename completion (see below)
+ Shift+Tab: Hostmask or function/command completion (see below)
+ Alt+<numeric_sequence>: Inserts the character by ASCII/Unicode code
+ + 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) + + Also look at the global shortcuts reference.
+ If you drop a file on this widget, a /PARSE <filename> will be executed.
+ You can enable word substitution in the preferences dialog.
+ For example, if you choose to substitute "afaik" with "As far as I know",
+ 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".
+ Experiment with it :)
+ The Tab key activates the completion of the current word.
+ 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.
+ + /ec<Tab> will produce /echo<space> + /echo $loca<Tab> will produce /echo $localhost + + Multiple matches are listed in the view window and the word is completed + to the common part of all the matches.
+ + $sel<Tab;> will find multiple matches and produce $selected + + 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
<Ctrl+PageUp>")); + 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
<Ctrl+I>
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
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
<Alt+Backspace>"); + szTip += " - <Ctrl+Backspace>"; + 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.

" \ + "There is nothing wrong with it, this warning is
" \ + "here to prevent you from accidentally sending
" \ + "a really large message just because you didn't edit it
" \ + "properly after pasting text from the clipboard.

" \ + "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("; submits, ; 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
<Ctrl+PageUp>")); + 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 +#include "kvi_tal_hbox.h" +#include +#include "kvi_pointerlist.h" + +#include "kvi_string.h" + +//#include +#include + +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 * m_pStringList; +public: + void add(QString * s); + KviPointerList * 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 * 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 +#include +#include +#include +#include +#include + + +// 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;iinstallEventFilter(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 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 +#include +#include + +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 +#include +#include "kvi_tal_popupmenu.h" +#include + +#ifdef COMPILE_USE_QT4 + #include +#endif + +#ifdef COMPILE_PSEUDO_TRANSPARENCY + extern QPixmap * g_pShadedChildGlobalDesktopBackground; +#endif + +static QPixmap * g_pIccMemBuffer = 0; +static KviPointerList * g_pToolBarGraphicalAppletList = 0; + +KviToolBarGraphicalApplet::KviToolBarGraphicalApplet(QWidget * par,const char * name) +: QToolButton(par,name) +{ + if(!g_pToolBarGraphicalAppletList) + { + g_pToolBarGraphicalAppletList = new KviPointerList(); + 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 = ""; + static QString nb = ""; + static QString 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 +#include +#include "kvi_tal_widgetstack.h" +#include + +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 +// +// #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 +#include +#include +#include +#include +#include // needed +#include +#include "kvi_tal_popupmenu.h" +#include +#include +#include +#include + +//#include // 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 + #undef QT_CLEAN_NAMESPACE + #else + #include + #endif +#else + #include +#endif + +#include +#include +#include +#include +#include + +#include + +#ifdef COMPILE_USE_QT4 + #include + #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 +#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: +// +// ! +// +// ::= u <--- url link +// ::= n <--- nick link +// ::= s <--- server link +// ::= h <--- host link +// ::= [... <--- 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; + 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;iuChunkCount;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;iszText = ""; + 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 + // 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 ¬hing_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!\r\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] + + ! + ! + + [big]Escape format[/big] + The whole escape sequence format is the following:[br] + [b]![/b][br] + is the carriage return character. You can obtain it by using the [fnc]]$cr[/fnc] function.[br] + is the text that will appear as "link" when you move the mouse over it.[br] + is the description of the actions to be taken when the user interacts with the link.[br] + has the two following syntactic forms:[br] + [b] ::= [/b][br] + [b] ::= [/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 part by using the following syntax:[br] + ::= [br] + ::= [][br] + ::= [br] + ::= "[!" "]"[br] + ::= "rbt" | "mbt" | "dbl" | "txt"[br] + ::= 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 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 ), + 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 (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 = "" \ + "
"; + if(linkText.length() > 50) + { + tip += linkText.left(47); + tip += "..."; + } else { + tip += linkText; + } + tip+="
"; + QMimeSourceFactory::defaultFactory()->setPixmap("url_icon",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_URL))); + tip += __tr2qs("Double-click to open this link"); + tip += "
"; + } + break; + case 'h': // host link + { + tip = "" \ + "
"; + if(linkText.length() > 50) + { + tip += linkText.left(47); + tip += "..."; + } else { + tip += linkText; + } + tip+="
"; + 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
Right-click to view other options"); + } + tip += "
"; + } + break; + case 's': // server link + { + // FIXME: #warning "Spit out some server info...hub ?...registered ?" + + tip = "" \ + "
"; + QMimeSourceFactory::defaultFactory()->setPixmap("server_icon",*(g_pIconManager->getSmallIcon(KVI_SMALLICON_IRC))); + if(linkText.length() > 50) + { + tip += linkText.left(47); + tip += "..."; + } else { + tip += linkText; + } + tip+="
"; + + if(linkText.find('*') != -1) + { + if(linkText.length() > 1)tip += __tr2qs("Server appears to be a network hub
"); + else tip += __tr2qs("Unknown server
"); // might happen... + } + + tip.append(__tr2qs("Double-click to read the MOTD
Right-click to view other options")); + tip += "
"; + } + 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
"); + 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("mode %Q %c%c %Q"),&(m_pKviWindow->windowName()),plmn.latin1(),flag.latin1(),&linkText); + break; + default: + KviQString::appendFormatted(tip,QString("mode %Q %c%c"),&(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 = " "; + 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("<","<"); + topic.replace(">",">"); + KviIrcUrl::join(szUrl,console()->connection()->target()->server()); + szUrl.append(szChan); + KviQString::sprintf(buf,__tr2qs("%Q (" + "%Q):
+%Q (%u users)
%Q
"),&szChan,&szUrl,&chanMode, + c->count(),&topic); + } else { + KviIrcUrl::join(szUrl,console()->connection()->target()->server()); + szUrl.append(szChan); + KviQString::sprintf(buf,__tr2qs("%Q (" + "%Q)
Double-click to join %Q
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("
"); + KviQString::appendFormatted(tip,__tr2qs("Double-click:
%Q"),&dbl); + } + if(tip.isEmpty() && (!mbt.isEmpty())) + { + if(!tip.isEmpty())tip.append("
"); + KviQString::appendFormatted(tip,__tr2qs("Middle-click:
%Q"),&mbt); + } + if(tip.isEmpty() && (!rbt.isEmpty())) + { + if(!tip.isEmpty())tip.append("
"); + KviQString::appendFormatted(tip,__tr2qs("Right-click:
%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 +#include // 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 * 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 + +//========================================================================================================= +// 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 +#include +#include +#include +#include +#include +#ifdef COMPILE_USE_QT4 + #include +#else + #include +#endif +#include +#include +#include "kvi_accel.h" +#include + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// 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("Find Text"),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;iaddWidget(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;isetToolWidget(0); + m_pFilterItems[i]->setOn(true); + m_pFilterItems[i]->setToolWidget(this); + } + forceRepaint(); +} + +void KviIrcViewToolWidget::filterEnableNone() +{ + for(int i=0;isetToolWidget(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;isetToolWidget(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;irepaint(); + #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 +#include "kvi_tal_listview.h" +#include + +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 +#include + +#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 +#include +#include + +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 * 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 * l = new KviPointerList; + 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 +#include +#include +#include "kvi_tal_listview.h" +#include +#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 * 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 *); +}; + +#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 +#include +#include +#include +#include "kvi_pointerlist.h" +#include +#include +#include +#include "kvi_tal_popupmenu.h" +#ifdef COMPILE_USE_QT4 + #include + #define QSimpleRichText Q3SimpleRichText + #include +#else + #include +#endif +#include +#include + +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 +#include +#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 +#include +#include +#include +#include "kvi_pointerlist.h" +#include +#include +#include +#include "kvi_tal_popupmenu.h" +#ifndef COMPILE_USE_QT4 + #include +#endif +#include + +#ifdef Q_OS_MACX +#include "kvi_app.h" //Needed for g_pApp +#ifdef COMPILE_USE_QT4 + #include +#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(minWidthchildX(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()-(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 +#include +#include + + +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 +#include +#include +#include +#include +#include +#include + +#ifdef COMPILE_USE_QT4 + #include "kvi_tal_hbox.h" +#endif + +#ifdef COMPILE_PSEUDO_TRANSPARENCY + #include + extern QPixmap * g_pShadedParentGlobalDesktopBackground; +#endif + + + + +KviMdiManager::KviMdiManager(QWidget * parent,KviFrame * pFrm,const char * name) +: KviTalScrollView(parent) +{ + setFrameShape(NoFrame); + m_pZ = new KviPointerList; + 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;iavailableWidth)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 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 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 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 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 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 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(curColsetFocus(); + 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(numCurCol0) + { + 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 +#include +#include +#include + +#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 * 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 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; + 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 * 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 +#include + + +////////////////////////////////////////////////////////////////////// +// 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; + 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 +#include +#include +#include +#include + +#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 * 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 +#include +#include "kvi_tal_hbox.h" +#include + +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; iconnection()->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;iconnection()->serverInfo()->supportedPlainModes().contains(szText[i]) || + szText.find(szText[i])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 +#include +#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 +#else + #include +#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 = "
"; + m_szBasicTipStart += __tr2qs("This option is also available as"); + m_szBasicTipStart += "
/option "; + m_szBasicTipEnd = "
"; + + } + // 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; + m_pSelectorInterfaceList->setAutoDelete(false); +} + +KviOptionsWidget::~KviOptionsWidget() +{ + delete m_pSelectorInterfaceList; +} + +void KviOptionsWidget::mergeTip(QWidget * w,const QString &tip) +{ + static QString begin = "
"; + static QString mid = "
"; + static QString end = "
"; +#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 +#include +#include "kvi_pointerlist.h" +#include +#include +#include +#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 * 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 +#include +#include "kvi_tal_hbox.h" +#include +#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 = "" \ + "" \ + ""; + + txt += START_TABLE_BOLD_ROW; + txt += __tr2qs("Query target:"); + txt += END_TABLE_BOLD_ROW; + txt += ""; + + if(e->hasServer()) + { + txt+=""; + } + + if(e->isAway()) + { + txt+=""; + } + + txt+=""; + + txt += "
"; + + 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('&',"&"); + tmp.replace('<',"<"); + tmp.replace('>',">"); + + txt += tmp; + + txt += "
"; + 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+="
"; + txt+=__tr2qs("%1 is probably away").arg(m_szName); + txt+="
"; + tmp=__tr2qs("Common channels with %1: %2").arg(m_szName).arg(szChans); + + tmp.replace('&',"&"); + tmp.replace('<',"<"); + tmp.replace('>',">"); + + txt+=tmp; + txt +="
" \ + "" \ + ""; + } 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 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 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(""); + static QString endofbold(" "); + static QString end(""); + + 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 +#include + +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 +#include +#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 +#include +#include +#include +#include +#include +#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;uisSelected(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;uisSelected(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;utext(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;uisSelected(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;iinsertItem(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;iinsertItem(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 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 +#include "kvi_tal_hbox.h" +#include "kvi_tal_vbox.h" +#include +#include +#include "kvi_tal_scrollview.h" +#include +#include +#include +#include "kvi_tal_listbox.h" +#include "kvi_tal_listview.h" +#include +#include +#include + +#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 + +#ifdef COMPILE_USE_QT4 + #include +#endif + +#include +#include +#include + +#include + + +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 + +#include +#include +#include +#include +#include +#include + +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 +// +// 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 + +#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 +#include +#include +#include +#include +#include "kvi_tal_popupmenu.h" +#include + +#ifdef COMPILE_USE_QT4 + #include +#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 + +/* + 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; + m_pAppletDescriptors->setAutoDelete(true); + + KviStatusBarClock::selfRegister(this); + KviStatusBarAwayIndicator::selfRegister(this); + KviStatusBarLagIndicator::selfRegister(this); + KviStatusBarConnectionTimer::selfRegister(this); + KviStatusBarSeparator::selfRegister(this); + + m_pAppletList = new KviPointerList; + m_pAppletList->setAutoDelete(false); + + m_pMessageQueue = new KviPointerList; + m_pMessageQueue->setAutoDelete(true); + + m_pMessageTimer = 0; + + m_pMessageLabel = new QLabel("[x] 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;igetModule(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 = ""; + + QString szTipx = a->tipText(a->mapFromGlobal(mapToGlobal(pnt))); + if(!szTipx.isEmpty()) + { + szTip += ""; + } + + szTip += "
" + a->descriptor()->visibleName() + "
"; + szTip += szTipx; + szTip += "

"; + szTip += __tr2qs("Shift+Drag or Ctrl+Drag to move the applet around
Right click to see the other options"); + szTip += "
"; + r = QRect(a->x(),a->y(),a->width(),a->height()); + } else { + szTip = "
"; + szTip += __tr2qs("Right click to add/remove applets"); + szTip += "
"; + 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,"
%Q
",&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 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 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("" + pMsg->text() + ""); + m_pMessageTimer->start(pMsg->timeout()); +} + + +void KviStatusBar::setPermanentMessage() +{ + if(m_pMessageTimer)return; // something is being actually shown! + + KviIrcContext * c = m_pFrame->activeContext(); + + QString txt = ""; + + if(c) + { + switch(c->state()) + { + case KviIrcContext::Connected: + txt += "["; + txt += c->connection()->currentServerName(); + txt += "] "; + 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 += "["; + txt += c->connection()->currentServerName(); + txt += "] "; + txt += __tr2qs("Login in progress..."); + break; + default: + txt += __tr2qs("Not connected"); + break; + } + } else { + txt += __tr2qs("No IRC context"); + } + + txt += ""; + + 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 +// +// 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 +#include "kvi_pointerhashtable.h" +#include + +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 * m_pMessageQueue; + QTimer * m_pMessageTimer; + QLabel * m_pMessageLabel; + KviPointerList * m_pAppletList; + KviPointerHashTable * 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 +// +// 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 +#include +#include +#include +#include +#include "kvi_tal_popupmenu.h" +#include +#ifdef COMPILE_USE_QT4 + #include +#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 + +/* + 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; + 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 = "
"; + 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 += "
"; + ret += __tr2qs("Double click to leave away mode"); + } else { + ret += __tr2qs("Not away"); + ret += "
"; + ret += __tr2qs("Double click to enter away mode"); + } + ret += "
"; + return ret; + +not_connected: + ret += __tr2qs("Not connected"); + ret += ""; + 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 = "
"; + 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 += "
"; + 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 += ""; + } + } else { + ret += __tr2qs("Lag meter engine disabled"); + ret += "
"; + ret += __tr2qs("Double click to enable it"); + } + ret += "
"; + return ret; + +not_connected: + ret += __tr2qs("Not connected"); + ret += ""; + 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(""); + tmp.append(""); + } + 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 +// +// 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 +#include "kvi_pointerhashtable.h" +#include +#include +#include + +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 * 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 +#include +#include +#include +#include + + +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_iStepNumberisActive()) + { + 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; xgetBigIcon("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; xheight())/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 + #include + + #define KviStyledCheckBox QCheckBox + #define KviStyledToolButton QToolButton +#else + +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include "kvi_tal_popupmenu.h" +#include + +#ifdef COMPILE_USE_QT4 + #include +#else + #include +#endif +#include + +#ifdef COMPILE_USE_QT4 + #include +#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; + 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 +#include "kvi_tal_tooltip.h" +#include "kvi_tal_listview.h" +#include + + + +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 + +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 * 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 +#include +#include +#ifdef COMPILE_USE_QT4 + #include +#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 * d = g_pTextIconManager->textIconDict(); + KviPointerHashTableIterator 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 + +#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 + +#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 +#include "kvi_tal_popupmenu.h" + +#ifdef COMPILE_USE_QT4 + #include +#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 +#include +#include +#include +#include "kvi_tal_vbox.h" +#include +#include + +#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 +#include +#include + +#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 +#include +#include "kvi_tal_tooltip.h" +#include +#include "kvi_tal_listbox.h" +#include +#include +#include "kvi_tal_popupmenu.h" +#include + +// 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(""); + if(curUnderline) result.append(""); + + if(curFore != KVI_LABEL_DEF_FORE) + { + result.append(""); + + result.append(text.mid(start,len)); + + if( (curFore != KVI_LABEL_DEF_FORE) /*|| (curBack != KVI_LABEL_DEF_BACK)*/ ) + result.append(""); + + if(curUnderline) result.append(""); + if(curBold) result.append(""); + + } + + 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 = "" \ + "" \ + ""; + + if(!m_szTopic.isEmpty()) + { + txt += START_TABLE_BOLD_ROW; + txt += __tr2qs("Channel topic:"); + txt += END_TABLE_BOLD_ROW; + + txt += ""; + + if(!m_szSetBy.isEmpty()) + { + txt += ""; + + if(!m_szSetAt.isEmpty()) + { + txt += ""; + } + } + + txt += ""; + + } else { + txt += ""; + txt += ""; + } + + txt += "
"; + + QString tmp = m_szTopic; + + tmp.replace('&',"&"); + tmp.replace('<',"<"); + tmp.replace('>',">"); + tmp = convertToHtml(tmp); + + txt += tmp; + txt += "
"; + txt += __tr2qs("Set by") + " " + m_szSetBy + ""; + txt += "
"; + txt += __tr2qs("Set on") + " " + m_szSetAt + ""; + txt += "
"; + txt += __tr2qs("Double-click to edit..."); + txt += "
"; + txt += __tr2qs("No topic is set"); + txt += "
"; + txt += __tr2qs("Double-click to set..."); + txt += "
" \ + "" \ + ""; + + 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 +#include +#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 +#include +#include +#include +#include +#include +#include +#include "kvi_styled_controls.h" +#include + +#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(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 *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 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("[%u]",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(""); + m_pUsersLabel->setText(tmp.ptr()); + } +} + +// FIXME: this could be done really better +void KviUserListView::partAllButOne(const QString &whoNot) +{ + QStringList ll; + KviPointerHashTableIterator 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 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 += ""; + + if(it->m_joinTime != 0) + { + QDateTime dt; + dt.setTime_t(it->m_joinTime); + buffer += ""; + } + + 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 += ""; + } + buffer += "
"; + buffer += __tr2qs("Joined on %1").arg(dt.toString()); + buffer += "
"; + buffer += __tr2qs("Quiet for %1h %2m %3s").arg(hors).arg(mins).arg(secs); + buffer += "
"; + + 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 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 +#include "kvi_tal_tooltip.h" +#include +#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 * 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 * 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 * 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 +#include "kvi_tal_popupmenu.h" +#include +#include +#include +#include +#include +#include +#include + +// it looks they can't decide :D +#ifdef COMPILE_USE_QT4 + #include + #include +#else + #include +#endif + + +#include +#include +#include "kvi_tal_tooltip.h" +#include + +#ifdef COMPILE_CRYPT_SUPPORT + #include "kvi_crypt.h" + #include "kvi_cryptcontroller.h" +#endif + +#ifdef COMPILE_KDE_SUPPORT + #include + #include +#endif + +#ifdef COMPILE_ON_WINDOWS + #include +#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(""); + static QString p3(""); + + 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 list = children(); + for(QList::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 list = o->children(); + for(QList::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 list = o->children(); + for(QList::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 list = obj->children(); + if (list.count()) + { + + for(QList::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;icount();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 + +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 + +// +// 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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 +#include + +// 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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 +#include + +#include +#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 -- cgit v1.2.3